Kerberos: implement server side security context and token handling

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@2064 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2013-02-26 21:53:53 +00:00
parent 0dd6efaa03
commit 54d4f41f94
1 changed files with 86 additions and 0 deletions

View File

@ -135,6 +135,12 @@ public class KerberosHelper {
kerberosCallbackHandler = new KerberosCallbackHandler(principal, password);
}
/**
* Create client Kerberos context.
*
* @return Login context
* @throws LoginException on error
*/
public static LoginContext login() throws LoginException {
synchronized (LOCK) {
if (loginContext == null) {
@ -145,4 +151,84 @@ public class KerberosHelper {
}
return loginContext;
}
/**
* Create server side Kerberos login context for provided credentials
*
* @param principal server principal
* @param password server passsword
* @return LoginContext
* @throws LoginException on error
*/
public static LoginContext serverLogin(final String principal, final String password) throws LoginException {
LoginContext serverLoginContext = new LoginContext("spnego-server", new CallbackHandler() {
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof NameCallback) {
final NameCallback nameCallback = (NameCallback) callbacks[i];
nameCallback.setName(principal);
} else if (callbacks[i] instanceof PasswordCallback) {
final PasswordCallback passCallback = (PasswordCallback) callbacks[i];
passCallback.setPassword(password.toCharArray());
} else {
throw new UnsupportedCallbackException(callbacks[i]);
}
}
}
});
serverLoginContext.login();
return serverLoginContext;
}
public static class SecurityContext {
// returned token
public byte[] token;
public String principal;
}
/**
* Handle Kerberos token in server login context
*
* @param serverLoginContext server login context
* @param token Kerberos client token
* @return result with client principal and optional returned Kerberos token
* @throws GSSException on error
*/
public static SecurityContext acceptSecurityContext(LoginContext serverLoginContext, final byte[] token) throws GSSException {
Object result = Subject.doAs(serverLoginContext.getSubject(), new PrivilegedAction() {
public Object run() {
Object result;
SecurityContext securityContext = new SecurityContext();
try {
GSSManager manager = GSSManager.getInstance();
// get server credentials from context
Oid krb5oid = new Oid("1.2.840.113554.1.2.2");
GSSCredential serverCreds = manager.createCredential(null,
GSSCredential.DEFAULT_LIFETIME,
krb5oid,
GSSCredential.ACCEPT_ONLY);
GSSContext context = manager.createContext(serverCreds);
securityContext.token = context.acceptSecContext(token, 0, token.length);
if (context.isEstablished()) {
securityContext.principal = context.getSrcName().toString();
LOGGER.debug("Authenticated user: " + securityContext.principal);
}
result = securityContext;
} catch (GSSException e) {
result = e;
}
return result;
}
});
if (result instanceof GSSException) {
throw (GSSException) result;
}
return (SecurityContext) result;
}
}