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