964 lines · 30.1 KB · Java
RawDownload
/* * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.security.auth; import java.io.*;import java.lang.RuntimePermission;import java.net.MalformedURLException;import java.net.SocketPermission;import java.net.URL;import java.security.GeneralSecurityException;import java.text.MessageFormat;import java.util.Enumeration;import java.util.Hashtable;import java.util.LinkedList;import java.util.ListIterator;import java.util.Vector;import java.util.StringTokenizer;import sun.security.util.PropertyExpander; /** * The policy for a Java runtime (specifying * which permissions are available for code from various principals) * is represented as a separate * persistent configuration.  The configuration may be stored as a * flat ASCII file, as a serialized binary file of * the Policy class, or as a database. <p> * * <p>The Java runtime creates one global Policy object, which is used to * represent the static policy configuration file.  It is consulted by * a ProtectionDomain when the protection domain initializes its set of * permissions. <p> * * <p>The Policy <code>init</code> method parses the policy * configuration file, and then * populates the Policy object.  The Policy object is agnostic in that * it is not involved in making policy decisions.  It is merely the * Java runtime representation of the persistent policy configuration * file. <p> * * <p>When a protection domain needs to initialize its set of * permissions, it executes code such as the following * to ask the global Policy object to populate a * Permissions object with the appropriate permissions: * <pre> *  policy = Policy.getPolicy(); *  Permissions perms = policy.getPermissions(MyCodeSource) * </pre> * * <p>The protection domain passes in a CodeSource * object, which encapsulates its codebase (URL) and public key attributes. * The Policy object evaluates the global policy in light of who the * principal is and returns an appropriate Permissions object. * * @deprecated As of JDK&nbsp;1.4, replaced by *             {@link sun.security.provider.PolicyParser}. *             This class is entirely deprecated. * * @author Roland Schemers * * @since 1.2 */@Deprecatedclass PolicyParser {     private static final java.util.ResourceBundle rb =        java.security.AccessController.doPrivileged        (new java.security.PrivilegedAction<java.util.ResourceBundle>() {            public java.util.ResourceBundle run() {                    return (java.util.ResourceBundle.getBundle                                ("sun.security.util.AuthResources"));           }        });     private Vector<GrantEntry> grantEntries;     // Convenience variables for parsing    private static final sun.security.util.Debug debug =        sun.security.util.Debug.getInstance("parser", "\t[Auth Policy Parser]");    private StreamTokenizer st;    private int lookahead;    private int linenum;    private boolean expandProp = false;    private String keyStoreUrlString = null; // unexpanded    private String keyStoreType = null;     private String expand(String value)        throws PropertyExpander.ExpandException    {        if (expandProp)            return PropertyExpander.expand(value);        else            return value;    }    /**     * Creates a PolicyParser object.     */     public PolicyParser() {        grantEntries = new Vector<GrantEntry>();    }      public PolicyParser(boolean expandProp) {        this();        this.expandProp = expandProp;    }     /**     * Reads a policy configuration into the Policy object using a     * Reader object. <p>     *     * @param policy the policy Reader object.     *     * @exception ParsingException if the policy configuration contains     *          a syntax error.     *     * @exception IOException if an error occurs while reading the policy     *          configuration.     */     public void read(Reader policy)        throws ParsingException, IOException    {        if (!(policy instanceof BufferedReader)) {            policy = new BufferedReader(policy);        }         /**         * Configure the stream tokenizer:         *      Recognize strings between "..."         *      Don't convert words to lowercase         *      Recognize both C-style and C++-style comments         *      Treat end-of-line as white space, not as a token         */        st   = new StreamTokenizer(policy);         st.resetSyntax();        st.wordChars('a', 'z');        st.wordChars('A', 'Z');        st.wordChars('.', '.');        st.wordChars('0', '9');        st.wordChars('_', '_');        st.wordChars('$', '$');        st.wordChars(128 + 32, 255);        st.whitespaceChars(0, ' ');        st.commentChar('/');        st.quoteChar('\'');        st.quoteChar('"');        st.lowerCaseMode(false);        st.ordinaryChar('/');        st.slashSlashComments(true);        st.slashStarComments(true);         /**         * The main parsing loop.  The loop is executed once         * for each entry in the config file.      The entries         * are delimited by semicolons.   Once we've read in         * the information for an entry, go ahead and try to         * add it to the policy vector.         *         */         lookahead = st.nextToken();        while (lookahead != StreamTokenizer.TT_EOF) {            if (peek("grant")) {                GrantEntry ge = parseGrantEntry();                // could be null if we couldn't expand a property                if (ge != null)                    add(ge);            } else if (peek("keystore") && keyStoreUrlString==null) {                // only one keystore entry per policy file, others will be                // ignored                parseKeyStoreEntry();            } else {                // error?            }            match(";");        }    }     public void add(GrantEntry ge)    {        grantEntries.addElement(ge);    }     public void replace(GrantEntry origGe, GrantEntry newGe)    {        grantEntries.setElementAt(newGe, grantEntries.indexOf(origGe));    }     public boolean remove(GrantEntry ge)    {        return grantEntries.removeElement(ge);    }     /**     * Returns the (possibly expanded) keystore location, or null if the     * expansion fails.     */    public String getKeyStoreUrl() {        try {            if (keyStoreUrlString!=null && keyStoreUrlString.length()!=0) {                return expand(keyStoreUrlString).replace(File.separatorChar,                                                         '/');            }        } catch (PropertyExpander.ExpandException peee) {            return null;        }        return null;    }     public void setKeyStoreUrl(String url) {        keyStoreUrlString = url;    }     public String getKeyStoreType() {        return keyStoreType;    }     public void setKeyStoreType(String type) {        keyStoreType = type;    }     /**     * Enumerate all the entries in the global policy object.     * This method is used by policy admin tools.   The tools     * should use the Enumeration methods on the returned object     * to fetch the elements sequentially.     */    public Enumeration<GrantEntry> grantElements(){        return grantEntries.elements();    }     /**     * write out the policy     */     public void write(Writer policy)    {        PrintWriter out = new PrintWriter(new BufferedWriter(policy));         Enumeration<GrantEntry> enum_ = grantElements();         out.println("/* AUTOMATICALLY GENERATED ON "+                    (new java.util.Date()) + "*/");        out.println("/* DO NOT EDIT */");        out.println();         // write the (unexpanded) keystore entry as the first entry of the        // policy file        if (keyStoreUrlString != null) {            writeKeyStoreEntry(out);        }         // write "grant" entries        while (enum_.hasMoreElements()) {            GrantEntry ge = enum_.nextElement();            ge.write(out);            out.println();        }        out.flush();    }     /**     * parses a keystore entry     */    private void parseKeyStoreEntry() throws ParsingException, IOException {        match("keystore");        keyStoreUrlString = match("quoted string");         // parse keystore type        if (!peek(",")) {            return; // default type        }        match(",");         if (peek("\"")) {            keyStoreType = match("quoted string");        } else {            throw new ParsingException(st.lineno(),                        rb.getString("expected.keystore.type"));        }    }     /**     * writes the (unexpanded) keystore entry     */    private void writeKeyStoreEntry(PrintWriter out) {        out.print("keystore \"");        out.print(keyStoreUrlString);        out.print('"');        if (keyStoreType != null && keyStoreType.length() > 0)            out.print(", \"" + keyStoreType + "\"");        out.println(";");        out.println();    }     /**     * parse a Grant entry     */    private GrantEntry parseGrantEntry()        throws ParsingException, IOException    {        GrantEntry e = new GrantEntry();        LinkedList<PrincipalEntry> principals = null;        boolean ignoreEntry = false;         match("grant");         while(!peek("{")) {             if (peekAndMatch("Codebase")) {                e.codeBase = match("quoted string");                peekAndMatch(",");            } else if (peekAndMatch("SignedBy")) {                e.signedBy = match("quoted string");                peekAndMatch(",");            } else if (peekAndMatch("Principal")) {                if (principals == null) {                    principals = new LinkedList<PrincipalEntry>();                }                 // check for principalClass wildcard                String principalClass;                if (peek("*")) {                    match("*");                    principalClass = PrincipalEntry.WILDCARD_CLASS;                } else {                    principalClass = match("principal type");                }                 // check for principalName wildcard                String principalName;                if (peek("*")) {                    match("*");                    principalName = PrincipalEntry.WILDCARD_NAME;                } else {                    principalName = match("quoted string");                }                 // disallow WILDCARD_CLASS && actual name                if (principalClass.equals(PrincipalEntry.WILDCARD_CLASS) &&                    !principalName.equals(PrincipalEntry.WILDCARD_NAME)) {                    if (debug != null)                        debug.println("disallowing principal that has " +                                "WILDCARD class but no WILDCARD name");                    throw new ParsingException                        (st.lineno(),                        rb.getString("can.not.specify.Principal.with.a." +                                     "wildcard.class.without.a.wildcard.name"));                }                 try {                    principalName = expand(principalName);                    principals.add                        (new PrincipalEntry(principalClass, principalName));                } catch (PropertyExpander.ExpandException peee) {                    // ignore the entire policy entry                    // but continue parsing all the info                    // so we can get to the next entry                    if (debug != null)                        debug.println("principal name expansion failed: " +                                        principalName);                    ignoreEntry = true;                }                peekAndMatch(",");            } else {                throw new                 ParsingException(st.lineno(),                        rb.getString("expected.codeBase.or.SignedBy"));            }        }         // disallow non principal-based grant entries        if (principals == null) {            throw new ParsingException                (st.lineno(),                rb.getString("only.Principal.based.grant.entries.permitted"));        }         e.principals = principals;        match("{");         while(!peek("}")) {            if (peek("Permission")) {                try {                    PermissionEntry pe = parsePermissionEntry();                    e.add(pe);                } catch (PropertyExpander.ExpandException peee) {                    // ignore. The add never happened                    skipEntry();  // BugId 4219343                }                match(";");            } else {                throw new                    ParsingException(st.lineno(),                    rb.getString("expected.permission.entry"));            }        }        match("}");         try {            if (e.codeBase != null)              e.codeBase = expand(e.codeBase).replace(File.separatorChar, '/');            e.signedBy = expand(e.signedBy);        } catch (PropertyExpander.ExpandException peee) {            return null;        }         return (ignoreEntry == true) ? null : e;    }     /**     * parse a Permission entry     */    private PermissionEntry parsePermissionEntry()        throws ParsingException, IOException, PropertyExpander.ExpandException    {        PermissionEntry e = new PermissionEntry();         // Permission        match("Permission");        e.permission = match("permission type");         if (peek("\"")) {            // Permission name            e.name = expand(match("quoted string"));        }         if (!peek(",")) {            return e;        }        match(",");         if (peek("\"")) {                e.action = expand(match("quoted string"));                if (!peek(",")) {                    return e;                }                match(",");        }         if (peekAndMatch("SignedBy")) {            e.signedBy = expand(match("quoted string"));        }        return e;    }     private boolean peekAndMatch(String expect)        throws ParsingException, IOException    {        if (peek(expect)) {            match(expect);            return true;        } else {            return false;        }    }     private boolean peek(String expect) {        boolean found = false;         switch (lookahead) {         case StreamTokenizer.TT_WORD:            if (expect.equalsIgnoreCase(st.sval))                found = true;            break;        case ',':            if (expect.equalsIgnoreCase(","))                found = true;            break;        case '{':            if (expect.equalsIgnoreCase("{"))                found = true;            break;        case '}':

Lines 1–500 of 964.