View Javadoc

1   /*
2    * @(#)Login.java
3    *
4    * Copyright 2001-2002 Sun Microsystems, Inc. All Rights Reserved.
5    *
6    * Redistribution and use in source and binary forms, with or 
7    * without modification, are permitted provided that the following 
8    * conditions are met:
9    * 
10   * -Redistributions of source code must retain the above copyright  
11   * notice, this  list of conditions and the following disclaimer.
12   * 
13   * -Redistribution in binary form must reproduct the above copyright 
14   * notice, this list of conditions and the following disclaimer in 
15   * the documentation and/or other materials provided with the 
16   * distribution.
17   * 
18   * Neither the name of Sun Microsystems, Inc. or the names of 
19   * contributors may be used to endorse or promote products derived 
20   * from this software without specific prior written permission.
21   * 
22   * This software is provided "AS IS," without a warranty of any 
23   * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND 
24   * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, 
25   * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY 
26   * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY 
27   * DAMAGES OR LIABILITIES  SUFFERED BY LICENSEE AS A RESULT OF  OR 
28   * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR 
29   * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE 
30   * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, 
31   * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER 
32   * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF 
33   * THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN 
34   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
35   * 
36   * You acknowledge that Software is not designed, licensed or 
37   * intended for use in the design, construction, operation or 
38   * maintenance of any nuclear facility. 
39   */
40  
41  package no.feide.mellon.jaas.loginutility;
42  
43  
44  import javax.security.auth.login.*;
45  import javax.security.auth.Subject;
46  
47  import no.feide.mellon.jaas.callbackhandlers.CommandlineCallbackHandler;
48  
49  
50  
51  /***
52   * @author Rikke Amilde Løvlid
53   *
54   * The original class file has been modified.
55   */
56  
57  /***
58   * <p> This class authenticates a <code>Subject</code> and then
59   * executes a specified application as that <code>Subject</code>.
60   * To use this class, the java interpreter would typically be invoked as:
61   *
62   * <pre>
63   *    % java -Djava.security.manager \
64   *        Login \
65   *        <applicationclass> <applicationClass_args>
66   * </pre>
67   *
68   * <p> <i>applicationClass</i> represents the application to be executed
69   * as the authenticated <code>Subject</code>,
70   * and <i>applicationClass_args</i> are passed as arguments to
71   * <i>applicationClass</i>.
72   *
73   * <p> To perform the authentication, <code>Login</code> uses a
74   * <code>LoginContext</code>.  A <code>LoginContext</code> relies on a
75   * <code>Configuration</code> to determine the modules that should be used
76   * to perform the actual authentication.  The location of the Configuration
77   * is dependent upon each Configuration implementation.
78   * The default Configuration implementation
79   * (<code>com.sun.security.auth.login.ConfigFile</code>)
80   * allows the Configuration location to be specified (among other ways)
81   * via the <code>java.security.auth.login.config</code> system property.
82   * Therefore, the <code>Login</code> class can also be invoked as:
83   *
84   * <pre>
85   *    % java -Djava.security.manager \
86   *        -Djava.security.auth.login.config=<configuration_url> \
87   *        Login \
88   *        <your_application_class> <your_application_class_args>
89   * </pre>
90   */ 
91  
92  public class Login {
93  
94      /***
95       * <p> Instantate a <code>LoginContext</code> using the
96       * provided application classname as the index for the login
97       * <code>Configuration</code>.  Authenticate the <code>Subject</code>
98       * (three retries are allowed) and invoke
99       * <code>Subject.doAsPrivileged</code>
100      * with the authenticated <code>Subject</code> and a
101      * <code>PrivilegedExceptionAction</code>.
102      * The <code>PrivilegedExceptionAction</code> 
103      * loads the provided application class, and then invokes
104      * its public static <code>main</code> method, passing it
105      * the application arguments.
106      *
107      * <p>
108      *
109      * @param args the arguments for <code>Login</code>.  The first
110      *argument must be the class name of the application to be
111      *invoked once authentication has completed, and the
112      *subsequent arguments are the arguments to be passed
113      *to that application's public static <code>main</code> method.
114      */
115     public static void main(String[] args) {
116 
117     	// check for the application's main class
118     	if (args == null || args.length == 0) {
119     		System.err.println("Invalid arguments: " +
120     		"Did not provide name of application class.");
121     		System.exit(-1);
122     	}
123 
124     	
125     	LoginContext lc = null;
126 		try{
127 			//The name in the loginconfiguration must be the same as the application name.
128 			lc = new LoginContext(args[0], new CommandlineCallbackHandler());
129 		}
130 		catch(LoginException le){
131 			System.err.println("Cannot create Logincontext. " + le.getMessage());
132 			System.exit(-1);
133 		}
134 		catch(SecurityException se){
135 			System.err.println("Cannot create LoginContext. " + se.getMessage());
136 			System.exit(-1);
137 		}
138 
139 		//The user has 3 attempts to authenticate successfully.
140 		int attempts;
141 		for(attempts=0; attempts<3; attempts++){
142 			try{
143 				lc.login();
144 				break;
145 			}
146 			catch(LoginException le){
147 				System.err.println("Authentication failed.");
148 				System.err.println(" " + le.getMessage());
149 				try{
150 					Thread.currentThread().sleep(3000);
151 				}
152 				catch(Exception e){
153 					//ignore
154 				}
155 			}
156 			catch(Exception e){
157 				System.err.println("Unexpected Exception - unable to continue");
158 				e.printStackTrace();
159 				System.exit(-1);
160 			}
161 		}
162 
163     	// did they fail three times?
164     	if (attempts == 3) {
165     		System.err.println("Sorry");
166     		System.exit(-1);
167     	}
168     	
169     	try{
170     		Subject.doAsPrivileged(lc.getSubject(), new  MoriaAction(args), null);
171     	}
172     	catch (java.security.PrivilegedActionException pae) {
173     		pae.printStackTrace();
174     		System.exit(-1);
175     	}
176 		
177 		try{
178 			lc.logout();
179 		}
180 		catch(LoginException le){
181 			System.err.println("Logout failed");
182 			System.err.println(" " + le.getMessage());
183 		}
184 	}
185 }
186 
187 
188     	
189