/* ConfigFileParser.java -- JAAS Login Configuration default syntax parser
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.javax.security.auth.login;

import gnu.java.security.Configuration;

import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import javax.security.auth.login.AppConfigurationEntry;

/**
 * A parser that knows how to interpret JAAS Login Module Configuration files
 * written in the <i>default syntax</i> which is interpreted as adhering to
 * the following grammar:
 *
 * <pre>
 *   CONFIG              ::= APP_OR_OTHER_ENTRY+
 *   APP_OR_OTHER_ENTRY  ::= APP_NAME_OR_OTHER JAAS_CONFIG_BLOCK
 *   APP_NAME_OR_OTHER   ::= APP_NAME
 *                         | 'other'
 *   JAAS_CONFIG_BLOCK   ::= '{' (LOGIN_MODULE_ENTRY ';')+ '}' ';'
 *   LOGIN_MODULE_ENTRY  ::= MODULE_CLASS FLAG MODULE_OPTION* ';'
 *   FLAG                ::= 'required'
 *                         | 'requisite'
 *                         | 'sufficient'
 *                         | 'optional'
 *   MODULE_OPTION       ::= PARAM_NAME '=' PARAM_VALUE
 *
 *   APP_NAME     ::= JAVA_IDENTIFIER
 *   MODULE_CLASS ::= JAVA_IDENTIFIER ('.' JAVA_IDENTIFIER)*
 *   PARAM_NAME   ::= STRING
 *   PARAM_VALUE  ::= '"' STRING '"' | ''' STRING ''' | STRING
 * </pre>
 *
 * <p>This parser handles UTF-8 entities when used as APP_NAME and PARAM_VALUE.
 * It also checks for the use of Java identifiers used in MODULE_CLASS, thus
 * minimizing the risks of having {@link java.lang.ClassCastException}s thrown
 * at runtime due to syntactically invalid names.</p>
 *
 * <p>In the above context, a JAVA_IDENTIFIER is a sequence of tokens,
 * separated by the character '.'. Each of these tokens obeys the following:</p>
 *
 * <ol>
 *   <li>its first character yields <code>true</code> when used as an input to
 *   the {@link java.lang.Character#isJavaIdentifierStart(char)}, and</li>
 *   <li>all remaining characters, yield <code>true</code> when used as an
 *   input to {@link java.lang.Character#isJavaIdentifierPart(char)}.</li>
 * </ol>
 */
public final class ConfigFileParser
{
  private static final Logger log = Logger.getLogger(ConfigFileParser.class.getName());
  private ConfigFileTokenizer cft;
  private Map map = new HashMap();

  // default 0-arguments constructor

  /**
   * Returns the parse result as a {@link Map} where the keys are application
   * names, and the entries are {@link List}s of {@link AppConfigurationEntry}
   * entries, one for each login module entry, in the order they were
   * encountered, for that application name in the just parsed configuration
   * file.
   */
  public Map getLoginModulesMap()
  {
    return map;
  }

  /**
   * Parses the {@link Reader}'s contents assuming it is in the <i>default
   * syntax</i>.
   *
   * @param r the {@link Reader} whose contents are assumed to be a JAAS Login
   * Configuration Module file written in the <i>default syntax</i>.
   * @throws IOException if an exception occurs while parsing the input.
   */
  public void parse(Reader r) throws IOException
  {
    initParser(r);

    while (parseAppOrOtherEntry())
      {
        /* do nothing */
      }
  }

  private void initParser(Reader r) throws IOException
  {
    map.clear();

    cft = new ConfigFileTokenizer(r);
  }

  /**
   * @return <code>true</code> if an APP_OR_OTHER_ENTRY was correctly parsed.
   * Returns <code>false</code> otherwise.
   * @throws IOException if an exception occurs while parsing the input.
   */
  private boolean parseAppOrOtherEntry() throws IOException
  {
    int c = cft.nextToken();
    if (c == ConfigFileTokenizer.TT_EOF)
      return false;

    if (c != ConfigFileTokenizer.TT_WORD)
      {
        cft.pushBack();
        return false;
      }

    String appName = cft.sval;
    if (Configuration.DEBUG)
      log.fine("APP_NAME_OR_OTHER = " + appName);
    if (cft.nextToken() != '{')
      abort("Missing '{' after APP_NAME_OR_OTHER");

    List lmis = new ArrayList();
    while (parseACE(lmis))
      {
        /* do nothing */
      }

    c = cft.nextToken();
    if (c != '}')
      abort("Was expecting '}' but found " + (char) c);

    c = cft.nextToken();
    if (c != ';')
      abort("Was expecting ';' but found " + (char) c);

    List listOfACEs = (List) map.get(appName);
    if (listOfACEs == null)
      {
        listOfACEs = new ArrayList();
        map.put(appName, listOfACEs);
      }
    listOfACEs.addAll(lmis);
    return !appName.equalsIgnoreCase("other");
  }

  /**
   * @return <code>true</code> if a LOGIN_MODULE_ENTRY was correctly parsed.
   * Returns <code>false</code> otherwise.
   * @throws IOException if an exception occurs while parsing the input.
   */
  private boolean parseACE(List listOfACEs) throws IOException
  {
    int c = cft.nextToken();
    if (c != ConfigFileTokenizer.TT_WORD)
      {
        cft.pushBack();
        return false;
      }

    String clazz = validateClassName(cft.sval);
    if (Configuration.DEBUG)
      log.fine("MODULE_CLASS = " + clazz);

    if (cft.nextToken() != ConfigFileTokenizer.TT_WORD)
      abort("Was expecting FLAG but found none");

    String flag = cft.sval;
    if (Configuration.DEBUG)
      log.fine("DEBUG: FLAG = " + flag);
    AppConfigurationEntry.LoginModuleControlFlag f = null;
    if (flag.equalsIgnoreCase("required"))
      f = AppConfigurationEntry.LoginModuleControlFlag.REQUIRED;
    else if (flag.equalsIgnoreCase("requisite"))
      f = AppConfigurationEntry.LoginModuleControlFlag.REQUISITE;
    else if (flag.equalsIgnoreCase("sufficient"))
      f = AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT;
    else if (flag.equalsIgnoreCase("optional"))
      f = AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL;
    else
      abort("Unknown Flag: " + flag);

    Map options = new HashMap();
    String paramName, paramValue;
    c = cft.nextToken();
    while (c != ';')
      {
        if (c != ConfigFileTokenizer.TT_WORD)
          abort("Was expecting PARAM_NAME but got '" + ((char) c) + "'");

        paramName = cft.sval;
        if (Configuration.DEBUG)
          log.fine("PARAM_NAME = " + paramName);
        if (cft.nextToken() != '=')
          abort("Missing '=' after PARAM_NAME");

        c = cft.nextToken();
        if (c != '"' && c != '\'')
          {
          if (Configuration.DEBUG)
            log.fine("Was expecting a quoted string but got no quote character."
                     + " Assume unquoted string");
          }
        paramValue = expandParamValue(cft.sval);
        if (Configuration.DEBUG)
          log.fine("PARAM_VALUE = " + paramValue);
        options.put(paramName, paramValue);

        c = cft.nextToken();
      }
    AppConfigurationEntry ace = new AppConfigurationEntry(clazz, f, options);
    if (Configuration.DEBUG)
      log.fine("LOGIN_MODULE_ENTRY = " + ace);
    listOfACEs.add(ace);
    return true;
  }

  private void abort(String m) throws IOException
  {
    if (Configuration.DEBUG)
      {
        log.fine(m);
        log.fine("Map (so far) = " + String.valueOf(map));
      }
    throw new IOException(m);
  }

  private String validateClassName(String cn) throws IOException
  {
    if (cn.startsWith(".") || cn.endsWith("."))
      abort("MODULE_CLASS MUST NOT start or end with a '.'");

    String[] tokens = cn.split("\\.");
    for (int i = 0; i < tokens.length; i++)
      {
        String t = tokens[i];
        if (! Character.isJavaIdentifierStart(t.charAt(0)))
          abort("Class name [" + cn
                + "] contains an invalid sub-package identifier: " + t);

        // we dont check the rest of the characters for isJavaIdentifierPart()
        // because that's what the tokenizer does.
      }

    return cn;
  }

  /**
   * The documentation of the {@link javax.security.auth.login.Configuration}
   * states that: <i>"...If a String in the form, ${system.property}, occurs in
   * the value, it will be expanded to the value of the system property."</i>.
   * This method ensures this is the case. If such a string can not be expanded
   * then it is left AS IS, assuming the LoginModule knows what to do with it.
   *
   * <p><b>IMPORTANT</b>: This implementation DOES NOT handle embedded ${}
   * constructs.
   *
   * @param s the raw parameter value, incl. eventually strings of the form
   * <code>${system.property}</code>.
   * @return the input string with every occurence of
   * <code>${system.property}</code> replaced with the value of the
   * corresponding System property at the time of this method invocation. If
   * the string is not a known System property name, then the complete sequence
   * (incl. the ${} characters are passed AS IS.
   */
  private String expandParamValue(String s)
  {
    String result = s;
    try
      {
        int searchNdx = 0;
        while (searchNdx < result.length())
          {
            int i = s.indexOf("${", searchNdx);
            if (i == -1)
              break;

            int j = s.indexOf("}", i + 2);
            if (j == -1)
              {
                if (Configuration.DEBUG)
                  log.fine("Found a ${ prefix with no } suffix. Ignore");
                break;
              }

            String sysPropName = s.substring(i + 2, j);
            if (Configuration.DEBUG)
              log.fine("Found a reference to System property " + sysPropName);
            String sysPropValue = System.getProperty(sysPropName);
            if (Configuration.DEBUG)
              log.fine("Resolved " + sysPropName + " to '" + sysPropValue + "'");
            if (sysPropValue != null)
              {
                result = s.substring(0, i) + sysPropValue + s.substring(j + 1);
                searchNdx = i + sysPropValue.length();
              }
            else
              searchNdx = j + 1;
          }
      }
    catch (Exception x)
      {
        if (Configuration.DEBUG)
          log.fine("Exception (ignored) while expanding " + s + ": " + x);
      }

    return result;
  }
}
