/* 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;
  }
}
