/* * @(#)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=*/ public class Login { /** *\ * 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;
}
}