/* * @(#)Login.java * * Copyright 2001-2002 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * -Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduct the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF * THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that Software is not designed, licensed or * intended for use in the design, construction, operation or * maintenance of any nuclear facility. */ import java.io.*; import java.lang.reflect.*; import java.util.Arrays; import javax.security.auth.callback.*; import javax.security.auth.login.*; import javax.security.auth.Subject; import com.sun.security.auth.callback.TextCallbackHandler; /** *

This class authenticates a Subject and then * executes a specified application as that Subject. * To use this class, the java interpreter would typically be invoked as: * *

 *    % java -Djava.security.manager \
 *        Login \
 *         
 * 
* *

applicationClass represents the application to be executed * as the authenticated Subject, * and applicationClass_args are passed as arguments to * applicationClass. * *

To perform the authentication, Login uses a * LoginContext. A LoginContext relies on a * Configuration to determine the modules that should be used * to perform the actual authentication. The location of the Configuration * is dependent upon each Configuration implementation. * The default Configuration implementation * (com.sun.security.auth.login.ConfigFile) * allows the Configuration location to be specified (among other ways) * via the java.security.auth.login.config system property. * Therefore, the Login class can also be invoked as: * *

 *    % java -Djava.security.manager \
 *        -Djava.security.auth.login.config= \
 *        Login \
 *         
 * 
*/ public class Login { /** *

Instantate a LoginContext using the * provided application classname as the index for the login * Configuration. Authenticate the Subject * (three retries are allowed) and invoke * Subject.doAsPrivileged * with the authenticated Subject and a * PrivilegedExceptionAction. * The PrivilegedExceptionAction * loads the provided application class, and then invokes * its public static main method, passing it * the application arguments. * *

* * @param args the arguments for Login. The first * argument must be the class name of the application to be * invoked once authentication has completed, and the * subsequent arguments are the arguments to be passed * to that application's public static main method. */ public static void main(String[] args) { // check for the application's main class if (args == null || args.length == 0) { System.err.println("Invalid arguments: " + "Did not provide name of application class."); System.exit(-1); } LoginContext lc = null; try { lc = new LoginContext(args[0], new TextCallbackHandler()); } catch (LoginException le) { System.err.println("Cannot create LoginContext. " + le.getMessage()); System.exit(-1); } catch (SecurityException se) { System.err .println("Cannot create LoginContext. " + se.getMessage()); System.exit(-1); } // the user has 3 attempts to authenticate successfully int i; for (i = 0; i < 3; i++) { try { // attempt authentication lc.login(); // if we return with no exception, authentication succeeded break; } catch (AccountExpiredException aee) { System.err.println("Your account has expired. " + "Please notify your administrator."); System.exit(-1); } catch (CredentialExpiredException cee) { System.err.println("Your credentials have expired."); System.exit(-1); } catch (FailedLoginException fle) { System.err.println("Authentication Failed"); try { Thread.currentThread().sleep(3000); } catch (Exception e) { // ignore } } catch (Exception e) { System.err.println("Unexpected Exception - unable to continue"); e.printStackTrace(); System.exit(-1); } } // did they fail three times? if (i == 3) { System.err.println("Sorry"); System.exit(-1); } // push the subject into the current ACC try { Subject.doAsPrivileged(lc.getSubject(), new MyAction(args), null); } catch (java.security.PrivilegedActionException pae) { pae.printStackTrace(); System.exit(-1); } System.exit(0); } } class MyAction implements java.security.PrivilegedExceptionAction { String[] origArgs; public MyAction(String[] origArgs) { this.origArgs = (String[])origArgs.clone(); } public Object run() throws Exception { // get the ContextClassLoader ClassLoader cl = Thread.currentThread().getContextClassLoader(); try { // get the application class's main method Class c = Class.forName(origArgs[0], true, cl); Class[] PARAMS = { origArgs.getClass() }; java.lang.reflect.Method mainMethod = c.getMethod("main", PARAMS); // invoke the main method with the remaining args String[] appArgs = new String[origArgs.length - 1]; System.arraycopy(origArgs, 1, appArgs, 0, origArgs.length - 1); Object[] args = { appArgs }; mainMethod.invoke(null /*ignored*/, args); } catch (Exception e) { throw new java.security.PrivilegedActionException(e); } // successful completion return null; } }