/* * @(#)Configuration.java 1.57 03/12/19 * * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package javax.security.auth.login; import javax.security.auth.AuthPermission; import java.io.*; import java.util.*; import java.net.URL; import java.security.PrivilegedActionException; /** *

This is an abstract class for representing the configuration of * LoginModules under an application. The Configuration specifies * which LoginModules should be used for a particular application, and in what * order the LoginModules should be invoked. * This abstract class needs to be subclassed to provide an implementation * which reads and loads the actual Configuration. * *

A login configuration contains the following information. * Note that this example only represents the default syntax for the * Configuration. Subclass implementations of this class * may implement alternative syntaxes and may retrieve the * Configuration from any source such as files, databases, * or servers. * *

 *      Name {
 *	      ModuleClass  Flag    ModuleOptions;
 *	      ModuleClass  Flag    ModuleOptions;
 *	      ModuleClass  Flag    ModuleOptions;
 *      };
 *      Name {
 *	      ModuleClass  Flag    ModuleOptions;
 *	      ModuleClass  Flag    ModuleOptions;
 *      };
 *      other {
 *	      ModuleClass  Flag    ModuleOptions;
 *	      ModuleClass  Flag    ModuleOptions;
 *      };
 * 
* *

Each entry in the Configuration is indexed via an * application name, Name, and contains a list of * LoginModules configured for that application. Each LoginModule * is specified via its fully qualified class name. * Authentication proceeds down the module list in the exact order specified. * If an application does not have specific entry, * it defaults to the specific entry for "other". * *

The Flag value controls the overall behavior as authentication * proceeds down the stack. The following represents a description of the * valid values for Flag and their respective semantics: * *

 *      1) Required     - The LoginModule is required to succeed.
 *			If it succeeds or fails, authentication still continues
 *			to proceed down the LoginModule list.
 *
 *      2) Requisite    - The LoginModule is required to succeed.
 *			If it succeeds, authentication continues down the
 *			LoginModule list.  If it fails,
 *			control immediately returns to the application
 *			(authentication does not proceed down the
 *			LoginModule list).
 *
 *      3) Sufficient   - The LoginModule is not required to
 *			succeed.  If it does succeed, control immediately
 *			returns to the application (authentication does not
 *			proceed down the LoginModule list).
 *			If it fails, authentication continues down the
 *			LoginModule list.
 *
 *      4) Optional     - The LoginModule is not required to
 *			succeed.  If it succeeds or fails,
 *			authentication still continues to proceed down the
 *			LoginModule list.
 * 
* *

The overall authentication succeeds only if all Required and * Requisite LoginModules succeed. If a Sufficient * LoginModule is configured and succeeds, * then only the Required and Requisite LoginModules prior to * that Sufficient LoginModule need to have succeeded for * the overall authentication to succeed. If no Required or * Requisite LoginModules are configured for an application, * then at least one Sufficient or Optional * LoginModule must succeed. * *

ModuleOptions is a space separated list of * LoginModule-specific values which are passed directly to * the underlying LoginModules. Options are defined by the * LoginModule itself, and control the behavior within it. * For example, a LoginModule may define options to support * debugging/testing capabilities. The correct way to specify options in the * Configuration is by using the following key-value pairing: * debug="true". The key and value should be separated by an * 'equals' symbol, and the value should be surrounded by double quotes. * If a String in the form, ${system.property}, occurs in the value, * it will be expanded to the value of the system property. * Note that there is no limit to the number of * options a LoginModule may define. * *

The following represents an example Configuration entry * based on the syntax above: * *

 * Login {
 *   com.sun.security.auth.module.UnixLoginModule required;
 *   com.sun.security.auth.module.Krb5LoginModule optional
 *                   useTicketCache="true"
 *                   ticketCache="${user.home}${/}tickets";
 * };
 * 
* *

This Configuration specifies that an application named, * "Login", requires users to first authenticate to the * com.sun.security.auth.module.UnixLoginModule, which is * required to succeed. Even if the UnixLoginModule * authentication fails, the * com.sun.security.auth.module.Krb5LoginModule * still gets invoked. This helps hide the source of failure. * Since the Krb5LoginModule is Optional, the overall * authentication succeeds only if the UnixLoginModule * (Required) succeeds. * *

Also note that the LoginModule-specific options, * useTicketCache="true" and * ticketCache=${user.home}${/}tickets", * are passed to the Krb5LoginModule. * These options instruct the Krb5LoginModule to * use the ticket cache at the specified location. * The system properties, user.home and / * (file.separator), are expanded to their respective values. * *

The default Configuration implementation can be changed by setting the * value of the "login.configuration.provider" security property (in the Java * security properties file) to the fully qualified name of * the desired Configuration implementation class. * The Java security properties file is located in the file named * <JAVA_HOME>/lib/security/java.security, where <JAVA_HOME> * refers to the directory where the JDK was installed. * * @version 1.57, 12/19/03 * @see javax.security.auth.login.LoginContext */ public abstract class Configuration { private static Configuration configuration; private static ClassLoader contextClassLoader; static { contextClassLoader = (ClassLoader)java.security.AccessController.doPrivileged (new java.security.PrivilegedAction() { public Object run() { return Thread.currentThread().getContextClassLoader(); } }); }; /** * Sole constructor. (For invocation by subclass constructors, typically * implicit.) */ protected Configuration() { } /** * Get the Login Configuration. * *

* * @return the login Configuration. If a Configuration object was set * via the Configuration.setConfiguration method, * then that object is returned. Otherwise, a default * Configuration object is returned. * * @exception SecurityException if the caller does not have permission * to retrieve the Configuration. * * @see #setConfiguration */ public static synchronized Configuration getConfiguration() { SecurityManager sm = System.getSecurityManager(); if (sm != null) sm.checkPermission(new AuthPermission("getLoginConfiguration")); if (configuration == null) { String config_class = null; config_class = (String) java.security.AccessController.doPrivileged (new java.security.PrivilegedAction() { public Object run() { return java.security.Security.getProperty ("login.configuration.provider"); } }); if (config_class == null) { config_class = "com.sun.security.auth.login.ConfigFile"; } try { final String finalClass = config_class; configuration = (Configuration) java.security.AccessController.doPrivileged (new java.security.PrivilegedExceptionAction() { public Object run() throws ClassNotFoundException, InstantiationException, IllegalAccessException { return Class.forName (finalClass, true, contextClassLoader).newInstance(); } }); } catch (PrivilegedActionException e) { Exception ee = e.getException(); if (ee instanceof InstantiationException) { throw (SecurityException) new SecurityException ("Configuration error:" + ee.getCause().getMessage() + "\n").initCause(ee.getCause()); } else { throw (SecurityException) new SecurityException ("Configuration error: " + ee.toString() + "\n").initCause(ee); } } } return configuration; } /** * Set the Login Configuration. * *

* * @param configuration the new Configuration * * @exception SecurityException if the current thread does not have * Permission to set the Configuration. * * @see #getConfiguration */ public static void setConfiguration(Configuration configuration) { SecurityManager sm = System.getSecurityManager(); if (sm != null) sm.checkPermission(new AuthPermission("setLoginConfiguration")); Configuration.configuration = configuration; } /** * Retrieve the AppConfigurationEntries for the specified name * from this Configuration. * *

* * @param name the name used to index the Configuration. * * @return an array of AppConfigurationEntries for the specified name * from this Configuration, or null if there are no entries * for the specified name */ public abstract AppConfigurationEntry[] getAppConfigurationEntry (String name); /** * Refresh and reload the Configuration. * *

This method causes this Configuration object to refresh/reload its * contents in an implementation-dependent manner. * For example, if this Configuration object stores its entries in a file, * calling refresh may cause the file to be re-read. * *

* * @exception SecurityException if the caller does not have permission * to refresh its Configuration. */ public abstract void refresh(); }