/* PolicyFile.java -- policy file reader
   Copyright (C) 2004, 2005, 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.java.security;

import gnu.classpath.debug.Component;
import gnu.classpath.debug.SystemLogger;
import gnu.java.security.action.GetPropertyAction;

import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.lang.reflect.Constructor;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Policy;
import java.security.Principal;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.Security;
import java.security.UnresolvedPermission;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.logging.Logger;

/**
 * An implementation of a {@link java.security.Policy} object whose
 * permissions are specified by a <em>policy file</em>.
 *
 * <p>The approximate syntax of policy files is:</p>
 *
 * <pre>
 * policyFile ::= keystoreOrGrantEntries ;
 *
 * keystoreOrGrantEntries ::= keystoreOrGrantEntry |
 *                            keystoreOrGrantEntries keystoreOrGrantEntry |
 *                            EMPTY ;
 *
 * keystoreOrGrantEntry ::= keystoreEntry | grantEntry ;
 *
 * keystoreEntry ::= "keystore" keystoreUrl ';' |
 *                   "keystore" keystoreUrl ',' keystoreAlgorithm ';' ;
 *
 * keystoreUrl ::= URL ;
 * keystoreAlgorithm ::= STRING ;
 *
 * grantEntry ::= "grant" domainParameters '{' permissions '}' ';'
 *
 * domainParameters ::= domainParameter |
 *                      domainParameter ',' domainParameters ;
 *
 * domainParameter ::= "signedBy" signerNames |
 *                     "codeBase" codeBaseUrl |
 *                     "principal" principalClassName principalName |
 *                     "principal" principalName ;
 *
 * signerNames ::= quotedString ;
 * codeBaseUrl ::= URL ;
 * principalClassName ::= STRING ;
 * principalName ::= quotedString ;
 *
 * quotedString ::= quoteChar STRING quoteChar ;
 * quoteChar ::= '"' | '\'';
 *
 * permissions ::= permission | permissions permission ;
 *
 * permission ::= "permission" permissionClassName permissionTarget permissionAction |
 *                "permission" permissionClassName permissionTarget |
 *                "permission" permissionClassName;
 * </pre>
 *
 * <p>Comments are either form of Java comments. Keystore entries only
 * affect subsequent grant entries, so if a grant entry preceeds a
 * keystore entry, that grant entry is not affected by that keystore
 * entry. Certian instances of <code>${property-name}</code> will be
 * replaced with <code>System.getProperty("property-name")</code> in
 * quoted strings.</p>
 *
 * <p>This class will load the following files when created or
 * refreshed, in order:</p>
 *
 * <ol>
 * <li>The file <code>${java.home}/lib/security/java.policy</code>.</li>
 * <li>All URLs specified by security properties
 * <code>"policy.file.<i>n</i>"</code>, for increasing <i>n</i>
 * starting from 1. The sequence stops at the first undefined
 * property, so you must set <code>"policy.file.1"</code> if you also
 * set <code>"policy.file.2"</code>, and so on.</li>
 * <li>The URL specified by the property
 * <code>"java.security.policy"</code>.</li>
 * </ol>
 *
 * @author Casey Marshall (csm@gnu.org)
 * @see java.security.Policy
 */
public final class PolicyFile extends Policy
{

  // Constants and fields.
  // -------------------------------------------------------------------------

  protected static final Logger logger = SystemLogger.SYSTEM;
  // Added to cut redundant AccessController.doPrivileged calls
  private static GetPropertyAction prop = new GetPropertyAction("file.seperator");
  private static final String fs = (String) AccessController.doPrivileged(prop);
  
  private static final String DEFAULT_POLICY =
    (String) AccessController.doPrivileged(prop.setParameters("java.home"))
    + fs + "lib" + fs + "security" + fs + "java.policy";
  private static final String DEFAULT_USER_POLICY =
    (String) AccessController.doPrivileged(prop.setParameters("user.home")) +
    fs + ".java.policy";

  private final Map cs2pc;

  // Constructors.
  // -------------------------------------------------------------------------

  public PolicyFile()
  {
    cs2pc = new HashMap();
    refresh();
  }

  // Instance methods.
  // -------------------------------------------------------------------------

  public PermissionCollection getPermissions(CodeSource codeSource)
  {
    Permissions perms = new Permissions();
    for (Iterator it = cs2pc.entrySet().iterator(); it.hasNext(); )
      {
        Map.Entry e = (Map.Entry) it.next();
        CodeSource cs = (CodeSource) e.getKey();
        if (cs.implies(codeSource))
          {
            logger.log (Component.POLICY, "{0} -> {1}", new Object[]
              { cs, codeSource });
            PermissionCollection pc = (PermissionCollection) e.getValue();
            for (Enumeration ee = pc.elements(); ee.hasMoreElements(); )
              {
                perms.add((Permission) ee.nextElement());
              }
          }
        else
          logger.log (Component.POLICY, "{0} !-> {1}", new Object[]
            { cs, codeSource });
      }
    logger.log (Component.POLICY, "returning permissions {0} for {1}",
                new Object[] { perms, codeSource });
    return perms;
  }

  public void refresh()
  {
    cs2pc.clear();
    final List policyFiles = new LinkedList();
    try
      {
        policyFiles.add (new File (DEFAULT_POLICY).toURL());
        policyFiles.add (new File (DEFAULT_USER_POLICY).toURL ());

        AccessController.doPrivileged(
          new PrivilegedExceptionAction()
          {
            public Object run() throws Exception
            {
              String allow = Security.getProperty ("policy.allowSystemProperty");
              if (allow == null || Boolean.getBoolean (allow))
                {
                  String s = System.getProperty ("java.security.policy");
                  logger.log (Component.POLICY, "java.security.policy={0}", s);
                  if (s != null)
                    {
                      boolean only = s.startsWith ("=");
                      if (only)
                        s = s.substring (1);
                      policyFiles.clear ();
                      policyFiles.add (new URL (s));
                      if (only)
                        return null;
                    }
                }
              for (int i = 1; ; i++)
                {
                  String pname = "policy.url." + i;
                  String s = Security.getProperty (pname);
                  logger.log (Component.POLICY, "{0}={1}", new Object []
                    { pname, s });
                  if (s == null)
                    break;
                  policyFiles.add (new URL (s));
                }
              return null;
            }
          });
      }
    catch (PrivilegedActionException pae)
      {
        logger.log (Component.POLICY, "reading policy properties", pae);
      }
    catch (MalformedURLException mue)
      {
        logger.log (Component.POLICY, "setting default policies", mue);
      }

    logger.log (Component.POLICY, "building policy from URLs {0}",
                policyFiles);
    for (Iterator it = policyFiles.iterator(); it.hasNext(); )
      {
        try
          {
            URL url = (URL) it.next();
            parse(url);
          }
        catch (IOException ioe)
          {
            logger.log (Component.POLICY, "reading policy", ioe);
          }
      }
  }

  public String toString()
  {
    return super.toString() + " [ " + cs2pc.toString() + " ]";
  }

  // Own methods.
  // -------------------------------------------------------------------------

  private static final int STATE_BEGIN = 0;
  private static final int STATE_GRANT = 1;
  private static final int STATE_PERMS = 2;

  /**
   * Parse a policy file, incorporating the permission definitions
   * described therein.
   *
   * @param url The URL of the policy file to read.
   * @throws IOException if an I/O error occurs, or if the policy file
   * cannot be parsed.
   */
  private void parse(final URL url) throws IOException
  {
    logger.log (Component.POLICY, "reading policy file from {0}", url);
    final StreamTokenizer in = new StreamTokenizer(new InputStreamReader(url.openStream()));
    in.resetSyntax();
    in.slashSlashComments(true);
    in.slashStarComments(true);
    in.wordChars('A', 'Z');
    in.wordChars('a', 'z');
    in.wordChars('0', '9');
    in.wordChars('.', '.');
    in.wordChars('_', '_');
    in.wordChars('$', '$');
    in.whitespaceChars(' ', ' ');
    in.whitespaceChars('\t', '\t');
    in.whitespaceChars('\f', '\f');
    in.whitespaceChars('\n', '\n');
    in.whitespaceChars('\r', '\r');
    in.quoteChar('\'');
    in.quoteChar('"');

    int tok;
    int state = STATE_BEGIN;
    List keystores = new LinkedList();
    URL currentBase = null;
    List currentCerts = new LinkedList();
    Permissions currentPerms = new Permissions();
    while ((tok = in.nextToken()) != StreamTokenizer.TT_EOF)
      {
        switch (tok)
          {
          case '{':
            if (state != STATE_GRANT)
              error(url, in, "spurious '{'");
            state = STATE_PERMS;
            tok = in.nextToken();
            break;
          case '}':
            if (state != STATE_PERMS)
              error(url, in, "spurious '}'");
            state = STATE_BEGIN;
            currentPerms.setReadOnly();
            Certificate[] c = null;
            if (!currentCerts.isEmpty())
              c = (Certificate[]) currentCerts.toArray(new Certificate[currentCerts.size()]);
            cs2pc.put(new CodeSource(currentBase, c), currentPerms);
            currentCerts.clear();
            currentPerms = new Permissions();
            currentBase = null;
            tok = in.nextToken();
            if (tok != ';')
              in.pushBack();
            continue;
          }
        if (tok != StreamTokenizer.TT_WORD)
          {
            error(url, in, "expecting word token");
          }

        // keystore "<keystore-path>" [',' "<keystore-type>"] ';'
        if (in.sval.equalsIgnoreCase("keystore"))
          {
            String alg = KeyStore.getDefaultType();
            tok = in.nextToken();
            if (tok != '"' && tok != '\'')
              error(url, in, "expecting key store URL");
            String store = in.sval;
            tok = in.nextToken();
            if (tok == ',')
              {
                tok = in.nextToken();
                if (tok != '"' && tok != '\'')
                  error(url, in, "expecting key store type");
                alg = in.sval;
                tok = in.nextToken();
              }
            if (tok != ';')
              error(url, in, "expecting semicolon");
            try
              {
                KeyStore keystore = KeyStore.getInstance(alg);
                keystore.load(new URL(url, store).openStream(), null);
                keystores.add(keystore);
              }
            catch (Exception x)
              {
                error(url, in, x.toString());
              }
          }
        else if (in.sval.equalsIgnoreCase("grant"))
          {
            if (state != STATE_BEGIN)
              error(url, in, "extraneous grant keyword");
            state = STATE_GRANT;
          }
        else if (in.sval.equalsIgnoreCase("signedBy"))
          {
            if (state != STATE_GRANT && state != STATE_PERMS)
              error(url, in, "spurious 'signedBy'");
            if (keystores.isEmpty())
              error(url, in, "'signedBy' with no keystores");
            tok = in.nextToken();
            if (tok != '"' && tok != '\'')
              error(url, in, "expecting signedBy name");
            StringTokenizer st = new StringTokenizer(in.sval, ",");
            while (st.hasMoreTokens())
              {
                String alias = st.nextToken();
                for (Iterator it = keystores.iterator(); it.hasNext(); )
                  {
                    KeyStore keystore = (KeyStore) it.next();
                    try
                      {
                        if (keystore.isCertificateEntry(alias))
                          currentCerts.add(keystore.getCertificate(alias));
                      }
                    catch (KeyStoreException kse)
                      {
                        error(url, in, kse.toString());
                      }
                  }
              }
            tok = in.nextToken();
            if (tok != ',')
              {
                if (state != STATE_GRANT)
                  error(url, in, "spurious ','");
                in.pushBack();
              }
          }
        else if (in.sval.equalsIgnoreCase("codeBase"))
          {
            if (state != STATE_GRANT)
              error(url, in, "spurious 'codeBase'");
            tok = in.nextToken();
            if (tok != '"' && tok != '\'')
              error(url, in, "expecting code base URL");
            String base = expand(in.sval);
            if (File.separatorChar != '/')
              base = base.replace(File.separatorChar, '/');
            try
              {
                currentBase = new URL(base);
              }
            catch (MalformedURLException mue)
              {
                error(url, in, mue.toString());
              }
            tok = in.nextToken();
            if (tok != ',')
              in.pushBack();
          }
        else if (in.sval.equalsIgnoreCase("principal"))
          {
            if (state != STATE_GRANT)
              error(url, in, "spurious 'principal'");
            tok = in.nextToken();
            if (tok == StreamTokenizer.TT_WORD)
              {
                tok = in.nextToken();
                if (tok != '"' && tok != '\'')
                  error(url, in, "expecting principal name");
                String name = in.sval;
                Principal p = null;
                try
                  {
                    Class pclass = Class.forName(in.sval);
                    Constructor c =
                      pclass.getConstructor(new Class[] { String.class });
                    p = (Principal) c.newInstance(new Object[] { name });
                  }
                catch (Exception x)
                  {
                    error(url, in, x.toString());
                  }
                for (Iterator it = keystores.iterator(); it.hasNext(); )
                  {
                    KeyStore ks = (KeyStore) it.next();
                    try
                      {
                        for (Enumeration e = ks.aliases(); e.hasMoreElements(); )
                          {
                            String alias = (String) e.nextElement();
                            if (ks.isCertificateEntry(alias))
                              {
                                Certificate cert = ks.getCertificate(alias);
                                if (!(cert instanceof X509Certificate))
                                  continue;
                                if (p.equals(((X509Certificate) cert).getSubjectDN()) ||
                                    p.equals(((X509Certificate) cert).getSubjectX500Principal()))
                                  currentCerts.add(cert);
                              }
                          }
                      }
                    catch (KeyStoreException kse)
                      {
                        error(url, in, kse.toString());
                      }
                  }
              }
            else if (tok == '"' || tok == '\'')
              {
                String alias = in.sval;
                for (Iterator it = keystores.iterator(); it.hasNext(); )
                  {
                    KeyStore ks = (KeyStore) it.next();
                    try
                      {
                        if (ks.isCertificateEntry(alias))
                          currentCerts.add(ks.getCertificate(alias));
                      }
                    catch (KeyStoreException kse)
                      {
                        error(url, in, kse.toString());
                      }
                  }
              }
            else
              error(url, in, "expecting principal");
            tok = in.nextToken();
            if (tok != ',')
              in.pushBack();
          }
        else if (in.sval.equalsIgnoreCase("permission"))
          {
            if (state != STATE_PERMS)
              error(url, in, "spurious 'permission'");
            tok = in.nextToken();
            if (tok != StreamTokenizer.TT_WORD)
              error(url, in, "expecting permission class name");
            String className = in.sval;
            Class clazz = null;
            try
              {
                clazz = Class.forName(className);
              }
            catch (ClassNotFoundException cnfe)
              {
              }
            tok = in.nextToken();
            if (tok == ';')
              {
                if (clazz == null)
                  {
                    currentPerms.add(new UnresolvedPermission(className,
		      null, null, (Certificate[]) currentCerts.toArray(new Certificate[currentCerts.size()])));
                    continue;
                  }
                try
                  {
                    currentPerms.add((Permission) clazz.newInstance());
                  }
                catch (Exception x)
                  {
                    error(url, in, x.toString());
                  }
                continue;
              }
            if (tok != '"' && tok != '\'')
              error(url, in, "expecting permission target");
            String target = expand(in.sval);
            tok = in.nextToken();
            if (tok == ';')
              {
                if (clazz == null)
                  {
                    currentPerms.add(new UnresolvedPermission(className,
		      target, null, (Certificate[]) currentCerts.toArray(new Certificate[currentCerts.size()])));
                    continue;
                  }
                try
                  {
                    Constructor c =
                      clazz.getConstructor(new Class[] { String.class });
                    currentPerms.add((Permission) c.newInstance(
                      new Object[] { target }));
                  }
                catch (Exception x)
                  {
                    error(url, in, x.toString());
                  }
                continue;
              }
            if (tok != ',')
              error(url, in, "expecting ','");
            tok = in.nextToken();
            if (tok == StreamTokenizer.TT_WORD)
              {
                if (!in.sval.equalsIgnoreCase("signedBy"))
                  error(url, in, "expecting 'signedBy'");
                try
                  {
                    Constructor c =
                      clazz.getConstructor(new Class[] { String.class });
                    currentPerms.add((Permission) c.newInstance(
                      new Object[] { target }));
                  }
                catch (Exception x)
                  {
                    error(url, in, x.toString());
                  }
                in.pushBack();
                continue;
              }
            if (tok != '"' && tok != '\'')
              error(url, in, "expecting permission action");
            String action = in.sval;
            if (clazz == null)
              {
                currentPerms.add(new UnresolvedPermission(className,
		  target, action, (Certificate[]) currentCerts.toArray(new Certificate[currentCerts.size()])));
                continue;
              }
            else
              {
                try
                  {
                    Constructor c = clazz.getConstructor(
                      new Class[] { String.class, String.class });
                    currentPerms.add((Permission) c.newInstance(
                      new Object[] { target, action }));
                  }
                catch (Exception x)
                  {
                    error(url, in, x.toString());
                  }
              }
            tok = in.nextToken();
            if (tok != ';' && tok != ',')
              error(url, in, "expecting ';' or ','");
          }
      }
  }

  /**
   * Expand all instances of <code>"${property-name}"</code> into
   * <code>System.getProperty("property-name")</code>.
   */
  private static String expand(final String s)
  {
    final StringBuffer result = new StringBuffer();
    final StringBuffer prop = new StringBuffer();
    int state = 0;
    for (int i = 0; i < s.length(); i++)
      {
        switch (state)
          {
          case 0:
            if (s.charAt(i) == '$')
              state = 1;
            else
              result.append(s.charAt(i));
            break;
          case 1:
            if (s.charAt(i) == '{')
              state = 2;
            else
              {
                state = 0;
                result.append('$').append(s.charAt(i));
              }
            break;
          case 2:
            if (s.charAt(i) == '}')
              {
                String p = prop.toString();
                if (p.equals("/"))
                  p = "file.separator";
                p = System.getProperty(p);
                if (p == null)
                  p = "";
                result.append(p);
                prop.setLength(0);
                state = 0;
              }
            else
              prop.append(s.charAt(i));
            break;
          }
      }
    if (state != 0)
      result.append('$').append('{').append(prop);
    return result.toString();
  }

  /**
   * I miss macros.
   */
  private static void error(URL base, StreamTokenizer in, String msg)
    throws IOException
  {
    throw new IOException(base+":"+in.lineno()+": "+msg);
  }
}
