1. /*
  2. * @(#)Configuration.java 1.55 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.security.auth.login;
  8. import javax.security.auth.AuthPermission;
  9. import java.io.*;
  10. import java.util.*;
  11. import java.net.URL;
  12. import java.security.PrivilegedActionException;
  13. /**
  14. * <p> This is an abstract class for representing the configuration of
  15. * LoginModules under an application. The <code>Configuration</code> specifies
  16. * which LoginModules should be used for a particular application, and in what
  17. * order the LoginModules should be invoked.
  18. * This abstract class needs to be subclassed to provide an implementation
  19. * which reads and loads the actual <code>Configuration</code>.
  20. *
  21. * <p> When the <code>LoginContext</code> needs to read the Configuration
  22. * to determine which LoginModules are configured for a particular
  23. * application, <i>appName</i>, it makes the following calls:
  24. * <pre>
  25. * config = Configuration.getConfiguration();
  26. * entries = config.getAppConfigurationEntry(appName);
  27. * </pre>
  28. *
  29. * <p> A login configuration contains the following information.
  30. * Note that this example only represents the default syntax for the
  31. * <code>Configuration</code>. Subclass implementations of this class
  32. * may implement alternative syntaxes and may retrieve the
  33. * <code>Configuration</code> from any source such as files, databases,
  34. * or servers.
  35. *
  36. * <pre>
  37. * Application {
  38. * ModuleClass Flag ModuleOptions;
  39. * ModuleClass Flag ModuleOptions;
  40. * ModuleClass Flag ModuleOptions;
  41. * };
  42. * Application {
  43. * ModuleClass Flag ModuleOptions;
  44. * ModuleClass Flag ModuleOptions;
  45. * };
  46. * other {
  47. * ModuleClass Flag ModuleOptions;
  48. * ModuleClass Flag ModuleOptions;
  49. * };
  50. * </pre>
  51. *
  52. * <p> Each entry in the <code>Configuration</code> is indexed via an
  53. * application name, <i>Application</i>, and contains a list of
  54. * LoginModules configured for that application. Each <code>LoginModule</code>
  55. * is specified via its fully qualified class name.
  56. * Authentication proceeds down the module list in the exact order specified.
  57. * If an application does not have specific entry,
  58. * it defaults to the specific entry for "<i>other</i>".
  59. *
  60. * <p> The <i>Flag</i> value controls the overall behavior as authentication
  61. * proceeds down the stack. The following represents a description of the
  62. * valid values for <i>Flag</i> and their respective semantics:
  63. *
  64. * <pre>
  65. * 1) Required - The <code>LoginModule</code> is required to succeed.
  66. * If it succeeds or fails, authentication still continues
  67. * to proceed down the <code>LoginModule</code> list.
  68. *
  69. * 2) Requisite - The <code>LoginModule</code> is required to succeed.
  70. * If it succeeds, authentication continues down the
  71. * <code>LoginModule</code> list. If it fails,
  72. * control immediately returns to the application
  73. * (authentication does not proceed down the
  74. * <code>LoginModule</code> list).
  75. *
  76. * 3) Sufficient - The <code>LoginModule</code> is not required to
  77. * succeed. If it does succeed, control immediately
  78. * returns to the application (authentication does not
  79. * proceed down the <code>LoginModule</code> list).
  80. * If it fails, authentication continues down the
  81. * <code>LoginModule</code> list.
  82. *
  83. * 4) Optional - The <code>LoginModule</code> is not required to
  84. * succeed. If it succeeds or fails,
  85. * authentication still continues to proceed down the
  86. * <code>LoginModule</code> list.
  87. * </pre>
  88. *
  89. * <p> The overall authentication succeeds only if all <i>Required</i> and
  90. * <i>Requisite</i> LoginModules succeed. If a <i>Sufficient</i>
  91. * <code>LoginModule</code> is configured and succeeds,
  92. * then only the <i>Required</i> and <i>Requisite</i> LoginModules prior to
  93. * that <i>Sufficient</i> <code>LoginModule</code> need to have succeeded for
  94. * the overall authentication to succeed. If no <i>Required</i> or
  95. * <i>Requisite</i> LoginModules are configured for an application,
  96. * then at least one <i>Sufficient</i> or <i>Optional</i>
  97. * <code>LoginModule</code> must succeed.
  98. *
  99. * <p> <i>ModuleOptions</i> is a space separated list of
  100. * <code>LoginModule</code>-specific values which are passed directly to
  101. * the underlying LoginModules. Options are defined by the
  102. * <code>LoginModule</code> itself, and control the behavior within it.
  103. * For example, a <code>LoginModule</code> may define options to support
  104. * debugging/testing capabilities. The correct way to specify options in the
  105. * <code>Configuration</code> is by using the following key-value pairing:
  106. * <i>debug="true"</i>. The key and value should be separated by an
  107. * 'equals' symbol, and the value should be surrounded by double quotes.
  108. * If a String in the form, ${system.property}, occurs in the value,
  109. * it will be expanded to the value of the system property.
  110. * Note that there is no limit to the number of
  111. * options a <code>LoginModule</code> may define.
  112. *
  113. * <p> The following represents an example <code>Configuration</code> entry
  114. * based on the syntax above:
  115. *
  116. * <pre>
  117. * Login {
  118. * com.sun.security.auth.module.UnixLoginModule required;
  119. * com.sun.security.auth.module.Krb5LoginModule optional
  120. * useTicketCache="true"
  121. * ticketCache="${user.home}${/}tickets";
  122. * };
  123. * </pre>
  124. *
  125. * <p> This <code>Configuration</code> specifies that an application named,
  126. * "Login", requires users to first authenticate to the
  127. * <i>com.sun.security.auth.module.UnixLoginModule</i>, which is
  128. * required to succeed. Even if the <i>UnixLoginModule</i>
  129. * authentication fails, the
  130. * <i>com.sun.security.auth.module.Krb5LoginModule</i>
  131. * still gets invoked. This helps hide the source of failure.
  132. * Since the <i>Krb5LoginModule</i> is <i>Optional</i>, the overall
  133. * authentication succeeds only if the <i>UnixLoginModule</i>
  134. * (<i>Required</i>) succeeds.
  135. *
  136. * <p> Also note that the LoginModule-specific options,
  137. * <i>useTicketCache="true"</i> and
  138. * <i>ticketCache=${user.home}${/}tickets"</i>,
  139. * are passed to the <i>Krb5LoginModule</i>.
  140. * These options instruct the <i>Krb5LoginModule</i> to
  141. * use the ticket cache at the specified location.
  142. * The system properties, <i>user.home</i> and <i>/</i>
  143. * (file.separator), are expanded to their respective values.
  144. *
  145. * <p> The default Configuration implementation can be changed by setting the
  146. * value of the "login.configuration.provider" security property (in the Java
  147. * security properties file) to the fully qualified name of
  148. * the desired Configuration implementation class.
  149. * The Java security properties file is located in the file named
  150. * <JAVA_HOME>/lib/security/java.security, where <JAVA_HOME>
  151. * refers to the directory where the JDK was installed.
  152. *
  153. * @version 1.55, 01/23/03
  154. * @see javax.security.auth.login.LoginContext
  155. */
  156. public abstract class Configuration {
  157. private static Configuration configuration;
  158. private static ClassLoader contextClassLoader;
  159. static {
  160. contextClassLoader =
  161. (ClassLoader)java.security.AccessController.doPrivileged
  162. (new java.security.PrivilegedAction() {
  163. public Object run() {
  164. return Thread.currentThread().getContextClassLoader();
  165. }
  166. });
  167. };
  168. /**
  169. * Sole constructor. (For invocation by subclass constructors, typically
  170. * implicit.)
  171. */
  172. protected Configuration() { }
  173. /**
  174. * Get the current Login Configuration.
  175. *
  176. * <p>
  177. *
  178. * @return the current Login Configuration.
  179. *
  180. * @exception SecurityException if the caller does not have permission
  181. * to retrieve the Configuration.
  182. *
  183. * @see #setConfiguration
  184. */
  185. public static synchronized Configuration getConfiguration() {
  186. SecurityManager sm = System.getSecurityManager();
  187. if (sm != null)
  188. sm.checkPermission(new AuthPermission("getLoginConfiguration"));
  189. if (configuration == null) {
  190. String config_class = null;
  191. config_class = (String)
  192. java.security.AccessController.doPrivileged
  193. (new java.security.PrivilegedAction() {
  194. public Object run() {
  195. return java.security.Security.getProperty
  196. ("login.configuration.provider");
  197. }
  198. });
  199. if (config_class == null) {
  200. config_class = "com.sun.security.auth.login.ConfigFile";
  201. }
  202. try {
  203. final String finalClass = config_class;
  204. configuration = (Configuration)
  205. java.security.AccessController.doPrivileged
  206. (new java.security.PrivilegedExceptionAction() {
  207. public Object run() throws ClassNotFoundException,
  208. InstantiationException,
  209. IllegalAccessException {
  210. return Class.forName
  211. (finalClass,
  212. true,
  213. contextClassLoader).newInstance();
  214. }
  215. });
  216. } catch (PrivilegedActionException e) {
  217. Exception ee = e.getException();
  218. if (ee instanceof InstantiationException) {
  219. throw (SecurityException) new
  220. SecurityException
  221. ("Configuration error:" +
  222. ee.getCause().getMessage() +
  223. "\n").initCause(ee.getCause());
  224. } else {
  225. throw (SecurityException) new
  226. SecurityException
  227. ("Configuration error: " +
  228. ee.toString() +
  229. "\n").initCause(ee);
  230. }
  231. }
  232. }
  233. return configuration;
  234. }
  235. /**
  236. * Set the current Login <code>Configuration</code>.
  237. *
  238. * <p>
  239. *
  240. * @param configuration the new <code>Configuration</code>
  241. *
  242. * @exception SecurityException if the current thread does not have
  243. * Permission to set the <code>Configuration</code>.
  244. *
  245. * @see #getConfiguration
  246. */
  247. public static void setConfiguration(Configuration configuration) {
  248. SecurityManager sm = System.getSecurityManager();
  249. if (sm != null)
  250. sm.checkPermission(new AuthPermission("setLoginConfiguration"));
  251. Configuration.configuration = configuration;
  252. }
  253. /**
  254. * Retrieve an array of AppConfigurationEntries which corresponds to
  255. * the configuration of LoginModules for this application.
  256. *
  257. * <p>
  258. *
  259. * @param applicationName the name used to index the Configuration.
  260. *
  261. * @return an array of AppConfigurationEntries which corresponds to
  262. * the configuration of LoginModules for this
  263. * application, or null if this application has no configured
  264. * LoginModules.
  265. */
  266. public abstract AppConfigurationEntry[] getAppConfigurationEntry
  267. (String applicationName);
  268. /**
  269. * Refresh and reload the Configuration.
  270. *
  271. * <p> This method causes this object to refresh/reload its current
  272. * Configuration. This is implementation-dependent.
  273. * For example, if the Configuration object is stored
  274. * a file, calling <code>refresh</code> will cause the file to be re-read.
  275. *
  276. * <p>
  277. *
  278. * @exception SecurityException if the caller does not have permission
  279. * to refresh the Configuration.
  280. */
  281. public abstract void refresh();
  282. }