0N/A/*
3261N/A * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage javax.security.auth.login;
0N/A
0N/Aimport javax.security.auth.AuthPermission;
0N/A
0N/Aimport java.io.*;
0N/Aimport java.util.*;
0N/Aimport java.net.URI;
0N/Aimport java.security.AccessController;
0N/Aimport java.security.PrivilegedAction;
0N/Aimport java.security.PrivilegedExceptionAction;
0N/Aimport java.security.PrivilegedActionException;
0N/Aimport java.security.NoSuchAlgorithmException;
0N/Aimport java.security.NoSuchProviderException;
0N/Aimport java.security.Provider;
0N/Aimport java.security.Security;
0N/Aimport java.security.SecurityPermission;
0N/A
0N/Aimport sun.security.jca.GetInstance;
0N/A
2507N/A/**
0N/A * A Configuration object is responsible for specifying which LoginModules
0N/A * should be used for a particular application, and in what order the
0N/A * LoginModules should be invoked.
0N/A *
0N/A * <p> A login configuration contains the following information.
0N/A * Note that this example only represents the default syntax for the
0N/A * <code>Configuration</code>. Subclass implementations of this class
0N/A * may implement alternative syntaxes and may retrieve the
0N/A * <code>Configuration</code> from any source such as files, databases,
0N/A * or servers.
0N/A *
0N/A * <pre>
0N/A * Name {
0N/A * ModuleClass Flag ModuleOptions;
0N/A * ModuleClass Flag ModuleOptions;
0N/A * ModuleClass Flag ModuleOptions;
0N/A * };
0N/A * Name {
0N/A * ModuleClass Flag ModuleOptions;
0N/A * ModuleClass Flag ModuleOptions;
0N/A * };
0N/A * other {
0N/A * ModuleClass Flag ModuleOptions;
0N/A * ModuleClass Flag ModuleOptions;
0N/A * };
0N/A * </pre>
0N/A *
0N/A * <p> Each entry in the <code>Configuration</code> is indexed via an
0N/A * application name, <i>Name</i>, and contains a list of
0N/A * LoginModules configured for that application. Each <code>LoginModule</code>
0N/A * is specified via its fully qualified class name.
0N/A * Authentication proceeds down the module list in the exact order specified.
0N/A * If an application does not have specific entry,
0N/A * it defaults to the specific entry for "<i>other</i>".
0N/A *
0N/A * <p> The <i>Flag</i> value controls the overall behavior as authentication
0N/A * proceeds down the stack. The following represents a description of the
0N/A * valid values for <i>Flag</i> and their respective semantics:
0N/A *
0N/A * <pre>
0N/A * 1) Required - The <code>LoginModule</code> is required to succeed.
0N/A * If it succeeds or fails, authentication still continues
0N/A * to proceed down the <code>LoginModule</code> list.
0N/A *
0N/A * 2) Requisite - The <code>LoginModule</code> is required to succeed.
0N/A * If it succeeds, authentication continues down the
0N/A * <code>LoginModule</code> list. If it fails,
0N/A * control immediately returns to the application
0N/A * (authentication does not proceed down the
0N/A * <code>LoginModule</code> list).
0N/A *
0N/A * 3) Sufficient - The <code>LoginModule</code> is not required to
0N/A * succeed. If it does succeed, control immediately
0N/A * returns to the application (authentication does not
0N/A * proceed down the <code>LoginModule</code> list).
0N/A * If it fails, authentication continues down the
0N/A * <code>LoginModule</code> list.
0N/A *
0N/A * 4) Optional - The <code>LoginModule</code> is not required to
0N/A * succeed. If it succeeds or fails,
0N/A * authentication still continues to proceed down the
0N/A * <code>LoginModule</code> list.
0N/A * </pre>
0N/A *
0N/A * <p> The overall authentication succeeds only if all <i>Required</i> and
0N/A * <i>Requisite</i> LoginModules succeed. If a <i>Sufficient</i>
0N/A * <code>LoginModule</code> is configured and succeeds,
0N/A * then only the <i>Required</i> and <i>Requisite</i> LoginModules prior to
0N/A * that <i>Sufficient</i> <code>LoginModule</code> need to have succeeded for
0N/A * the overall authentication to succeed. If no <i>Required</i> or
0N/A * <i>Requisite</i> LoginModules are configured for an application,
0N/A * then at least one <i>Sufficient</i> or <i>Optional</i>
2507N/A * <code>LoginModule</code> must succeed.
0N/A *
0N/A * <p> <i>ModuleOptions</i> is a space separated list of
0N/A * <code>LoginModule</code>-specific values which are passed directly to
0N/A * the underlying LoginModules. Options are defined by the
0N/A * <code>LoginModule</code> itself, and control the behavior within it.
0N/A * For example, a <code>LoginModule</code> may define options to support
0N/A * debugging/testing capabilities. The correct way to specify options in the
0N/A * <code>Configuration</code> is by using the following key-value pairing:
0N/A * <i>debug="true"</i>. The key and value should be separated by an
0N/A * 'equals' symbol, and the value should be surrounded by double quotes.
0N/A * If a String in the form, ${system.property}, occurs in the value,
0N/A * it will be expanded to the value of the system property.
0N/A * Note that there is no limit to the number of
0N/A * options a <code>LoginModule</code> may define.
0N/A *
0N/A * <p> The following represents an example <code>Configuration</code> entry
0N/A * based on the syntax above:
0N/A *
0N/A * <pre>
0N/A * Login {
0N/A * com.sun.security.auth.module.UnixLoginModule required;
0N/A * com.sun.security.auth.module.Krb5LoginModule optional
0N/A * useTicketCache="true"
0N/A * ticketCache="${user.home}${/}tickets";
0N/A * };
0N/A * </pre>
0N/A *
0N/A * <p> This <code>Configuration</code> specifies that an application named,
0N/A * "Login", requires users to first authenticate to the
0N/A * <i>com.sun.security.auth.module.UnixLoginModule</i>, which is
0N/A * required to succeed. Even if the <i>UnixLoginModule</i>
0N/A * authentication fails, the
0N/A * <i>com.sun.security.auth.module.Krb5LoginModule</i>
0N/A * still gets invoked. This helps hide the source of failure.
0N/A * Since the <i>Krb5LoginModule</i> is <i>Optional</i>, the overall
0N/A * authentication succeeds only if the <i>UnixLoginModule</i>
0N/A * (<i>Required</i>) succeeds.
0N/A *
0N/A * <p> Also note that the LoginModule-specific options,
0N/A * <i>useTicketCache="true"</i> and
0N/A * <i>ticketCache=${user.home}${/}tickets"</i>,
0N/A * are passed to the <i>Krb5LoginModule</i>.
0N/A * These options instruct the <i>Krb5LoginModule</i> to
0N/A * use the ticket cache at the specified location.
0N/A * The system properties, <i>user.home</i> and <i>/</i>
0N/A * (file.separator), are expanded to their respective values.
0N/A *
0N/A * <p> There is only one Configuration object installed in the runtime at any
0N/A * given time. A Configuration object can be installed by calling the
0N/A * <code>setConfiguration</code> method. The installed Configuration object
0N/A * can be obtained by calling the <code>getConfiguration</code> method.
0N/A *
0N/A * <p> If no Configuration object has been installed in the runtime, a call to
0N/A * <code>getConfiguration</code> installs an instance of the default
0N/A * Configuration implementation (a default subclass implementation of this
0N/A * abstract class).
0N/A * The default Configuration implementation can be changed by setting the value
0N/A * of the "login.configuration.provider" security property (in the Java
0N/A * security properties file) to the fully qualified name of the desired
0N/A * Configuration subclass implementation. The Java security properties file
0N/A * is located in the file named &lt;JAVA_HOME&gt;/lib/security/java.security.
0N/A * &lt;JAVA_HOME&gt; refers to the value of the java.home system property,
0N/A * and specifies the directory where the JRE is installed.
0N/A *
0N/A * <p> Application code can directly subclass Configuration to provide a custom
0N/A * implementation. In addition, an instance of a Configuration object can be
0N/A * constructed by invoking one of the <code>getInstance</code> factory methods
0N/A * with a standard type. The default policy type is "JavaLoginConfig".
0N/A * See the Configuration section in the <a href=
0N/A * "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
0N/A * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
0N/A * for a list of standard Configuration types.
0N/A *
0N/A * @see javax.security.auth.login.LoginContext
0N/A */
0N/Apublic abstract class Configuration {
0N/A
0N/A private static Configuration configuration;
0N/A private static ClassLoader contextClassLoader;
0N/A
0N/A static {
0N/A contextClassLoader = AccessController.doPrivileged
0N/A (new PrivilegedAction<ClassLoader>() {
0N/A public ClassLoader run() {
0N/A return Thread.currentThread().getContextClassLoader();
0N/A }
0N/A });
0N/A };
0N/A
0N/A private static void checkPermission(String type) {
0N/A SecurityManager sm = System.getSecurityManager();
0N/A if (sm != null) {
0N/A sm.checkPermission(new AuthPermission
0N/A ("createLoginConfiguration." + type));
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Sole constructor. (For invocation by subclass constructors, typically
0N/A * implicit.)
0N/A */
0N/A protected Configuration() { }
0N/A
0N/A /**
0N/A * Get the installed login Configuration.
0N/A *
0N/A * <p>
0N/A *
0N/A * @return the login Configuration. If a Configuration object was set
0N/A * via the <code>Configuration.setConfiguration</code> method,
0N/A * then that object is returned. Otherwise, a default
0N/A * Configuration object is returned.
0N/A *
0N/A * @exception SecurityException if the caller does not have permission
0N/A * to retrieve the Configuration.
0N/A *
0N/A * @see #setConfiguration
0N/A */
0N/A public static Configuration getConfiguration() {
0N/A
0N/A SecurityManager sm = System.getSecurityManager();
0N/A if (sm != null)
0N/A sm.checkPermission(new AuthPermission("getLoginConfiguration"));
0N/A
0N/A synchronized (Configuration.class) {
0N/A if (configuration == null) {
0N/A String config_class = null;
0N/A config_class = AccessController.doPrivileged
0N/A (new PrivilegedAction<String>() {
0N/A public String run() {
0N/A return java.security.Security.getProperty
0N/A ("login.configuration.provider");
0N/A }
0N/A });
0N/A if (config_class == null) {
0N/A config_class = "com.sun.security.auth.login.ConfigFile";
0N/A }
0N/A
0N/A try {
0N/A final String finalClass = config_class;
0N/A configuration = AccessController.doPrivileged
0N/A (new PrivilegedExceptionAction<Configuration>() {
0N/A public Configuration run() throws ClassNotFoundException,
0N/A InstantiationException,
0N/A IllegalAccessException {
0N/A return (Configuration)Class.forName
0N/A (finalClass,
0N/A true,
0N/A contextClassLoader).newInstance();
0N/A }
0N/A });
0N/A } catch (PrivilegedActionException e) {
0N/A Exception ee = e.getException();
0N/A if (ee instanceof InstantiationException) {
0N/A throw (SecurityException) new
0N/A SecurityException
0N/A ("Configuration error:" +
0N/A ee.getCause().getMessage() +
0N/A "\n").initCause(ee.getCause());
0N/A } else {
0N/A throw (SecurityException) new
0N/A SecurityException
0N/A ("Configuration error: " +
0N/A ee.toString() +
0N/A "\n").initCause(ee);
0N/A }
0N/A }
0N/A }
0N/A return configuration;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Set the login <code>Configuration</code>.
0N/A *
0N/A * <p>
0N/A *
0N/A * @param configuration the new <code>Configuration</code>
0N/A *
0N/A * @exception SecurityException if the current thread does not have
0N/A * Permission to set the <code>Configuration</code>.
0N/A *
0N/A * @see #getConfiguration
0N/A */
0N/A public static void setConfiguration(Configuration configuration) {
0N/A SecurityManager sm = System.getSecurityManager();
0N/A if (sm != null)
0N/A sm.checkPermission(new AuthPermission("setLoginConfiguration"));
0N/A Configuration.configuration = configuration;
0N/A }
0N/A
0N/A /**
0N/A * Returns a Configuration object of the specified type.
0N/A *
0N/A * <p> This method traverses the list of registered security providers,
0N/A * starting with the most preferred Provider.
0N/A * A new Configuration object encapsulating the
0N/A * ConfigurationSpi implementation from the first
0N/A * Provider that supports the specified type is returned.
0N/A *
0N/A * <p> Note that the list of registered providers may be retrieved via
0N/A * the {@link Security#getProviders() Security.getProviders()} method.
0N/A *
0N/A * @param type the specified Configuration type. See the Configuration
0N/A * section in the <a href=
0N/A * "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
0N/A * Java Cryptography Architecture Standard Algorithm Name
0N/A * Documentation</a> for a list of standard Configuration types.
0N/A *
0N/A * @param params parameters for the Configuration, which may be null.
0N/A *
0N/A * @return the new Configuration object.
0N/A *
0N/A * @exception SecurityException if the caller does not have permission
0N/A * to get a Configuration instance for the specified type.
0N/A *
0N/A * @exception NullPointerException if the specified type is null.
0N/A *
0N/A * @exception IllegalArgumentException if the specified parameters
0N/A * are not understood by the ConfigurationSpi implementation
0N/A * from the selected Provider.
0N/A *
0N/A * @exception NoSuchAlgorithmException if no Provider supports a
0N/A * ConfigurationSpi implementation for the specified type.
0N/A *
0N/A * @see Provider
0N/A * @since 1.6
0N/A */
0N/A public static Configuration getInstance(String type,
0N/A Configuration.Parameters params)
0N/A throws NoSuchAlgorithmException {
0N/A
0N/A checkPermission(type);
0N/A try {
0N/A GetInstance.Instance instance = GetInstance.getInstance
0N/A ("Configuration",
0N/A ConfigurationSpi.class,
0N/A type,
0N/A params);
0N/A return new ConfigDelegate((ConfigurationSpi)instance.impl,
0N/A instance.provider,
0N/A type,
0N/A params);
0N/A } catch (NoSuchAlgorithmException nsae) {
0N/A return handleException (nsae);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns a Configuration object of the specified type.
0N/A *
0N/A * <p> A new Configuration object encapsulating the
0N/A * ConfigurationSpi implementation from the specified provider
0N/A * is returned. The specified provider must be registered
0N/A * in the provider list.
0N/A *
0N/A * <p> Note that the list of registered providers may be retrieved via
0N/A * the {@link Security#getProviders() Security.getProviders()} method.
0N/A *
0N/A * @param type the specified Configuration type. See the Configuration
0N/A * section in the <a href=
0N/A * "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
0N/A * Java Cryptography Architecture Standard Algorithm Name
0N/A * Documentation</a> for a list of standard Configuration types.
0N/A *
0N/A * @param params parameters for the Configuration, which may be null.
0N/A *
0N/A * @param provider the provider.
0N/A *
0N/A * @return the new Configuration object.
0N/A *
0N/A * @exception SecurityException if the caller does not have permission
0N/A * to get a Configuration instance for the specified type.
0N/A *
0N/A * @exception NullPointerException if the specified type is null.
0N/A *
0N/A * @exception IllegalArgumentException if the specified provider
0N/A * is null or empty,
0N/A * or if the specified parameters are not understood by
0N/A * the ConfigurationSpi implementation from the specified provider.
0N/A *
0N/A * @exception NoSuchProviderException if the specified provider is not
0N/A * registered in the security provider list.
0N/A *
0N/A * @exception NoSuchAlgorithmException if the specified provider does not
0N/A * support a ConfigurationSpi implementation for the specified
0N/A * type.
0N/A *
0N/A * @see Provider
0N/A * @since 1.6
0N/A */
0N/A public static Configuration getInstance(String type,
0N/A Configuration.Parameters params,
0N/A String provider)
0N/A throws NoSuchProviderException, NoSuchAlgorithmException {
0N/A
0N/A if (provider == null || provider.length() == 0) {
0N/A throw new IllegalArgumentException("missing provider");
0N/A }
0N/A
0N/A checkPermission(type);
0N/A try {
0N/A GetInstance.Instance instance = GetInstance.getInstance
0N/A ("Configuration",
0N/A ConfigurationSpi.class,
0N/A type,
0N/A params,
0N/A provider);
0N/A return new ConfigDelegate((ConfigurationSpi)instance.impl,
0N/A instance.provider,
0N/A type,
0N/A params);
0N/A } catch (NoSuchAlgorithmException nsae) {
0N/A return handleException (nsae);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns a Configuration object of the specified type.
0N/A *
0N/A * <p> A new Configuration object encapsulating the
0N/A * ConfigurationSpi implementation from the specified Provider
0N/A * object is returned. Note that the specified Provider object
0N/A * does not have to be registered in the provider list.
0N/A *
0N/A * @param type the specified Configuration type. See the Configuration
0N/A * section in the <a href=
0N/A * "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
0N/A * Java Cryptography Architecture Standard Algorithm Name
0N/A * Documentation</a> for a list of standard Configuration types.
0N/A *
0N/A * @param params parameters for the Configuration, which may be null.
0N/A *
0N/A * @param provider the Provider.
0N/A *
0N/A * @return the new Configuration object.
0N/A *
0N/A * @exception SecurityException if the caller does not have permission
0N/A * to get a Configuration instance for the specified type.
0N/A *
0N/A * @exception NullPointerException if the specified type is null.
0N/A *
0N/A * @exception IllegalArgumentException if the specified Provider is null,
0N/A * or if the specified parameters are not understood by
0N/A * the ConfigurationSpi implementation from the specified Provider.
0N/A *
0N/A * @exception NoSuchAlgorithmException if the specified Provider does not
0N/A * support a ConfigurationSpi implementation for the specified
0N/A * type.
0N/A *
0N/A * @see Provider
0N/A * @since 1.6
0N/A */
0N/A public static Configuration getInstance(String type,
0N/A Configuration.Parameters params,
0N/A Provider provider)
0N/A throws NoSuchAlgorithmException {
0N/A
0N/A if (provider == null) {
0N/A throw new IllegalArgumentException("missing provider");
0N/A }
0N/A
0N/A checkPermission(type);
0N/A try {
0N/A GetInstance.Instance instance = GetInstance.getInstance
0N/A ("Configuration",
0N/A ConfigurationSpi.class,
0N/A type,
0N/A params,
0N/A provider);
0N/A return new ConfigDelegate((ConfigurationSpi)instance.impl,
0N/A instance.provider,
0N/A type,
0N/A params);
0N/A } catch (NoSuchAlgorithmException nsae) {
0N/A return handleException (nsae);
0N/A }
0N/A }
0N/A
0N/A private static Configuration handleException(NoSuchAlgorithmException nsae)
0N/A throws NoSuchAlgorithmException {
0N/A Throwable cause = nsae.getCause();
0N/A if (cause instanceof IllegalArgumentException) {
0N/A throw (IllegalArgumentException)cause;
0N/A }
0N/A throw nsae;
0N/A }
0N/A
0N/A /**
0N/A * Return the Provider of this Configuration.
0N/A *
0N/A * <p> This Configuration instance will only have a Provider if it
0N/A * was obtained via a call to <code>Configuration.getInstance</code>.
0N/A * Otherwise this method returns null.
0N/A *
0N/A * @return the Provider of this Configuration, or null.
0N/A *
0N/A * @since 1.6
0N/A */
0N/A public Provider getProvider() {
0N/A return null;
0N/A }
0N/A
0N/A /**
0N/A * Return the type of this Configuration.
0N/A *
0N/A * <p> This Configuration instance will only have a type if it
0N/A * was obtained via a call to <code>Configuration.getInstance</code>.
0N/A * Otherwise this method returns null.
0N/A *
0N/A * @return the type of this Configuration, or null.
0N/A *
0N/A * @since 1.6
0N/A */
0N/A public String getType() {
0N/A return null;
0N/A }
0N/A
0N/A /**
0N/A * Return Configuration parameters.
0N/A *
0N/A * <p> This Configuration instance will only have parameters if it
0N/A * was obtained via a call to <code>Configuration.getInstance</code>.
0N/A * Otherwise this method returns null.
0N/A *
0N/A * @return Configuration parameters, or null.
0N/A *
0N/A * @since 1.6
0N/A */
0N/A public Configuration.Parameters getParameters() {
0N/A return null;
0N/A }
0N/A
0N/A /**
0N/A * Retrieve the AppConfigurationEntries for the specified <i>name</i>
0N/A * from this Configuration.
0N/A *
0N/A * <p>
0N/A *
0N/A * @param name the name used to index the Configuration.
0N/A *
0N/A * @return an array of AppConfigurationEntries for the specified <i>name</i>
0N/A * from this Configuration, or null if there are no entries
0N/A * for the specified <i>name</i>
0N/A */
0N/A public abstract AppConfigurationEntry[] getAppConfigurationEntry
0N/A (String name);
0N/A
0N/A /**
0N/A * Refresh and reload the Configuration.
0N/A *
0N/A * <p> This method causes this Configuration object to refresh/reload its
0N/A * contents in an implementation-dependent manner.
0N/A * For example, if this Configuration object stores its entries in a file,
0N/A * calling <code>refresh</code> may cause the file to be re-read.
0N/A *
0N/A * <p> The default implementation of this method does nothing.
0N/A * This method should be overridden if a refresh operation is supported
0N/A * by the implementation.
0N/A *
0N/A * @exception SecurityException if the caller does not have permission
0N/A * to refresh its Configuration.
0N/A */
0N/A public void refresh() { }
0N/A
0N/A /**
0N/A * This subclass is returned by the getInstance calls. All Configuration
0N/A * calls are delegated to the underlying ConfigurationSpi.
0N/A */
0N/A private static class ConfigDelegate extends Configuration {
0N/A
0N/A private ConfigurationSpi spi;
0N/A private Provider p;
0N/A private String type;
0N/A private Configuration.Parameters params;
0N/A
0N/A private ConfigDelegate(ConfigurationSpi spi, Provider p,
0N/A String type, Configuration.Parameters params) {
0N/A this.spi = spi;
0N/A this.p = p;
0N/A this.type = type;
0N/A this.params = params;
0N/A }
0N/A
0N/A public String getType() { return type; }
0N/A
0N/A public Configuration.Parameters getParameters() { return params; }
0N/A
0N/A public Provider getProvider() { return p; }
0N/A
0N/A public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
0N/A return spi.engineGetAppConfigurationEntry(name);
0N/A }
0N/A
0N/A public void refresh() {
0N/A spi.engineRefresh();
0N/A }
0N/A }
2507N/A
0N/A /**
0N/A * This represents a marker interface for Configuration parameters.
0N/A *
0N/A * @since 1.6
0N/A */
0N/A public static interface Parameters { }
0N/A}
0N/A