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