675 lines · 24.8 KB · Java
RawDownload
/* * Copyright (c) 2000, 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.login; import javax.security.auth.AuthPermission;import javax.security.auth.login.AppConfigurationEntry;import java.io.*;import java.util.*;import java.net.URI;import java.net.URL;import java.net.MalformedURLException;import java.text.MessageFormat;import sun.security.util.Debug;import sun.security.util.ResourcesMgr;import sun.security.util.PropertyExpander; /** * This class represents a default implementation for * <code>javax.security.auth.login.Configuration</code>. * * <p> This object stores the runtime login configuration representation, * and is the amalgamation of multiple static login * configurations that resides in files. * The algorithm for locating the login configuration file(s) and reading their * information into this <code>Configuration</code> object is: * * <ol> * <li> *   Loop through the <code>java.security.Security</code> properties, *   <i>login.config.url.1</i>, <i>login.config.url.2</i>, ..., *   <i>login.config.url.X</i>.  These properties are set *   in the Java security properties file, which is located in the file named *   &lt;JAVA_HOME&gt;/lib/security/java.security. *   &lt;JAVA_HOME&gt; refers to the value of the java.home system property, *   and specifies the directory where the JRE is installed. *   Each property value specifies a <code>URL</code> pointing to a *   login configuration file to be loaded.  Read in and load *   each configuration. * * <li> *   The <code>java.lang.System</code> property *   <i>java.security.auth.login.config</i> *   may also be set to a <code>URL</code> pointing to another *   login configuration file *   (which is the case when a user uses the -D switch at runtime). *   If this property is defined, and its use is allowed by the *   security property file (the Security property, *   <i>policy.allowSystemProperty</i> is set to <i>true</i>), *   also load that login configuration. * * <li> *   If the <i>java.security.auth.login.config</i> property is defined using *   "==" (rather than "="), then ignore all other specified *   login configurations and only load this configuration. * * <li> *   If no system or security properties were set, try to read from the file, *   ${user.home}/.java.login.config, where ${user.home} is the value *   represented by the "user.home" System property. * </ol> * * <p> The configuration syntax supported by this implementation * is exactly that syntax specified in the * <code>javax.security.auth.login.Configuration</code> class. * * @see javax.security.auth.login.LoginContext */public class ConfigFile extends javax.security.auth.login.Configuration {     private StreamTokenizer st;    private int lookahead;    private int linenum;    private HashMap<String, LinkedList<AppConfigurationEntry>> configuration;    private boolean expandProp = true;    private URL url;     private static Debug debugConfig = Debug.getInstance("configfile");    private static Debug debugParser = Debug.getInstance("configparser");     /**     * Create a new <code>Configuration</code> object.     */    public ConfigFile() {        try {            init(url);        } catch (IOException ioe) {            throw (SecurityException)                new SecurityException(ioe.getMessage()).initCause(ioe);        }    }     /**     * Create a new <code>Configuration</code> object from the specified URI.     *     * @param uri Create a new Configuration object from this URI.     */    public ConfigFile(URI uri) {        // only load config from the specified URI        try {            url = uri.toURL();            init(url);        } catch (MalformedURLException mue) {            throw (SecurityException)                new SecurityException(mue.getMessage()).initCause(mue);        } catch (IOException ioe) {            throw (SecurityException)                new SecurityException(ioe.getMessage()).initCause(ioe);        }    }     /**     * Read and initialize the entire login Configuration.     *     * <p>     *     * @exception IOException if the Configuration can not be initialized. <p>     * @exception SecurityException if the caller does not have permission     *                          to initialize the Configuration.     */    private void init(URL url) throws IOException {         boolean initialized = false;        FileReader fr = null;        String sep = File.separator;         if ("false".equals(System.getProperty("policy.expandProperties"))) {            expandProp = false;        }         // new configuration        HashMap<String, LinkedList<AppConfigurationEntry>> newConfig =                new HashMap<>();         if (url != null) {             /**             * If the caller specified a URI via Configuration.getInstance,             * we only read from that URI             */            if (debugConfig != null) {                debugConfig.println("reading " + url);            }            init(url, newConfig);            configuration = newConfig;            return;        }         /**         * Caller did not specify URI via Configuration.getInstance.         * Read from URLs listed in the java.security properties file.         */         String allowSys = java.security.Security.getProperty                                                ("policy.allowSystemProperty");         if ("true".equalsIgnoreCase(allowSys)) {            String extra_config = System.getProperty                                        ("java.security.auth.login.config");            if (extra_config != null) {                boolean overrideAll = false;                if (extra_config.startsWith("=")) {                    overrideAll = true;                    extra_config = extra_config.substring(1);                }                try {                    extra_config = PropertyExpander.expand(extra_config);                } catch (PropertyExpander.ExpandException peee) {                    MessageFormat form = new MessageFormat                        (ResourcesMgr.getString                                ("Unable.to.properly.expand.config",                                "sun.security.util.AuthResources"));                    Object[] source = {extra_config};                    throw new IOException(form.format(source));                }                 URL configURL = null;                try {                    configURL = new URL(extra_config);                } catch (java.net.MalformedURLException mue) {                    File configFile = new File(extra_config);                    if (configFile.exists()) {                        configURL = configFile.toURI().toURL();                    } else {                        MessageFormat form = new MessageFormat                            (ResourcesMgr.getString                                ("extra.config.No.such.file.or.directory.",                                "sun.security.util.AuthResources"));                        Object[] source = {extra_config};                        throw new IOException(form.format(source));                    }                }                 if (debugConfig != null) {                    debugConfig.println("reading "+configURL);                }                init(configURL, newConfig);                initialized = true;                if (overrideAll) {                    if (debugConfig != null) {                        debugConfig.println("overriding other policies!");                    }                    configuration = newConfig;                    return;                }            }        }         int n = 1;        String config_url;        while ((config_url = java.security.Security.getProperty                                        ("login.config.url."+n)) != null) {            try {                config_url = PropertyExpander.expand                        (config_url).replace(File.separatorChar, '/');                if (debugConfig != null) {                    debugConfig.println("\tReading config: " + config_url);                }                init(new URL(config_url), newConfig);                initialized = true;            } catch (PropertyExpander.ExpandException peee) {                MessageFormat form = new MessageFormat                        (ResourcesMgr.getString                                ("Unable.to.properly.expand.config",                                "sun.security.util.AuthResources"));                Object[] source = {config_url};                throw new IOException(form.format(source));            }            n++;        }         if (initialized == false && n == 1 && config_url == null) {             // get the config from the user's home directory            if (debugConfig != null) {                debugConfig.println("\tReading Policy " +                                "from ~/.java.login.config");            }            config_url = System.getProperty("user.home");            String userConfigFile = config_url +                      File.separatorChar + ".java.login.config";             // No longer throws an exception when there's no config file            // at all. Returns an empty Configuration instead.            if (new File(userConfigFile).exists()) {                init(new File(userConfigFile).toURI().toURL(),                    newConfig);            }        }         configuration = newConfig;    }     private void init(URL config,        HashMap<String, LinkedList<AppConfigurationEntry>> newConfig)        throws IOException {         InputStreamReader isr = null;        try {            isr = new InputStreamReader(getInputStream(config), "UTF-8");            readConfig(isr, newConfig);        } catch (FileNotFoundException fnfe) {            if (debugConfig != null) {                debugConfig.println(fnfe.toString());            }            throw new IOException(ResourcesMgr.getString                    ("Configuration.Error.No.such.file.or.directory",                    "sun.security.util.AuthResources"));        } finally {            if (isr != null) {                isr.close();            }        }    }     /**     * Retrieve an entry from the Configuration using an application name     * as an index.     *     * <p>     *     * @param applicationName the name used to index the Configuration.     * @return an array of AppConfigurationEntries which correspond to     *          the stacked configuration of LoginModules for this     *          application, or null if this application has no configured     *          LoginModules.     */    public AppConfigurationEntry[] getAppConfigurationEntry    (String applicationName) {         LinkedList<AppConfigurationEntry> list = null;        synchronized (configuration) {            list = configuration.get(applicationName);        }         if (list == null || list.size() == 0)            return null;         AppConfigurationEntry[] entries =                                new AppConfigurationEntry[list.size()];        Iterator<AppConfigurationEntry> iterator = list.iterator();        for (int i = 0; iterator.hasNext(); i++) {            AppConfigurationEntry e = iterator.next();            entries[i] = new AppConfigurationEntry(e.getLoginModuleName(),                                                e.getControlFlag(),                                                e.getOptions());        }        return entries;    }     /**     * Refresh and reload the Configuration by re-reading all of the     * login configurations.     *     * <p>     *     * @exception SecurityException if the caller does not have permission     *                          to refresh the Configuration.     */    public synchronized void refresh() {         java.lang.SecurityManager sm = System.getSecurityManager();        if (sm != null)            sm.checkPermission(new AuthPermission("refreshLoginConfiguration"));         java.security.AccessController.doPrivileged            (new java.security.PrivilegedAction<Void>() {            public Void run() {                try {                    init(url);                } catch (java.io.IOException ioe) {                    throw (SecurityException) new SecurityException                                (ioe.getLocalizedMessage()).initCause(ioe);                }                return null;            }        });    }     private void readConfig(Reader reader,        HashMap<String, LinkedList<AppConfigurationEntry>> newConfig)        throws IOException {         int linenum = 1;         if (!(reader instanceof BufferedReader))            reader = new BufferedReader(reader);         st = new StreamTokenizer(reader);        st.quoteChar('"');        st.wordChars('$', '$');        st.wordChars('_', '_');        st.wordChars('-', '-');        st.lowerCaseMode(false);        st.slashSlashComments(true);        st.slashStarComments(true);        st.eolIsSignificant(true);         lookahead = nextToken();        while (lookahead != StreamTokenizer.TT_EOF) {            parseLoginEntry(newConfig);        }    }     private void parseLoginEntry(        HashMap<String, LinkedList<AppConfigurationEntry>> newConfig)        throws IOException {         String appName;        String moduleClass;        String sflag;        AppConfigurationEntry.LoginModuleControlFlag controlFlag;        LinkedList<AppConfigurationEntry> configEntries = new LinkedList<>();         // application name        appName = st.sval;        lookahead = nextToken();         if (debugParser != null) {            debugParser.println("\tReading next config entry: " + appName);        }         match("{");         // get the modules        while (peek("}") == false) {            // get the module class name            moduleClass = match("module class name");             // controlFlag (required, optional, etc)            sflag = match("controlFlag");            if (sflag.equalsIgnoreCase("REQUIRED"))                controlFlag =                        AppConfigurationEntry.LoginModuleControlFlag.REQUIRED;            else if (sflag.equalsIgnoreCase("REQUISITE"))                controlFlag =                        AppConfigurationEntry.LoginModuleControlFlag.REQUISITE;            else if (sflag.equalsIgnoreCase("SUFFICIENT"))                controlFlag =                        AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT;            else if (sflag.equalsIgnoreCase("OPTIONAL"))                controlFlag =                        AppConfigurationEntry.LoginModuleControlFlag.OPTIONAL;            else {                MessageFormat form = new MessageFormat(ResourcesMgr.getString                        ("Configuration.Error.Invalid.control.flag.flag",                        "sun.security.util.AuthResources"));                Object[] source = {sflag};                throw new IOException(form.format(source));            }             // get the args            HashMap<String, String> options = new HashMap<>();            String key;            String value;            while (peek(";") == false) {                key = match("option key");                match("=");                try {                    value = expand(match("option value"));                } catch (PropertyExpander.ExpandException peee) {                    throw new IOException(peee.getLocalizedMessage());                }                options.put(key, value);            }             lookahead = nextToken();             // create the new element            if (debugParser != null) {                debugParser.println("\t\t" + moduleClass + ", " + sflag);                java.util.Iterator<String> i = options.keySet().iterator();                while (i.hasNext()) {                    key = i.next();                    debugParser.println("\t\t\t" +                                        key +                                        "=" +                                        options.get(key));                }            }            AppConfigurationEntry entry = new AppConfigurationEntry                                                        (moduleClass,                                                        controlFlag,                                                        options);            configEntries.add(entry);        }         match("}");        match(";");         // add this configuration entry        if (newConfig.containsKey(appName)) {            MessageFormat form = new MessageFormat(ResourcesMgr.getString                ("Configuration.Error.Can.not.specify.multiple.entries.for.appName",                "sun.security.util.AuthResources"));            Object[] source = {appName};            throw new IOException(form.format(source));        }        newConfig.put(appName, configEntries);    }     private String match(String expect) throws IOException {         String value = null;         switch(lookahead) {        case StreamTokenizer.TT_EOF:             MessageFormat form1 = new MessageFormat(ResourcesMgr.getString                ("Configuration.Error.expected.expect.read.end.of.file.",                "sun.security.util.AuthResources"));            Object[] source1 = {expect};            throw new IOException(form1.format(source1));         case '"':        case StreamTokenizer.TT_WORD:             if (expect.equalsIgnoreCase("module class name") ||

Lines 1–500 of 675.