mirror of
https://github.com/moparisthebest/davmail
synced 2025-01-08 04:08:12 -05:00
Kerberos: Handle client context timeout, try to recreate context
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@2070 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
6a455d0a8c
commit
5b08df4bc2
@ -71,6 +71,9 @@ public class KerberosHelper {
|
|||||||
// TODO: get username and password from dialog
|
// TODO: get username and password from dialog
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (principal == null) {
|
||||||
|
throw new IOException("KerberosCallbackHandler: failed to retrieve principal");
|
||||||
|
}
|
||||||
((NameCallback) callbacks[i]).setName(principal);
|
((NameCallback) callbacks[i]).setName(principal);
|
||||||
|
|
||||||
} else if (callbacks[i] instanceof PasswordCallback) {
|
} else if (callbacks[i] instanceof PasswordCallback) {
|
||||||
@ -83,6 +86,9 @@ public class KerberosHelper {
|
|||||||
password = inReader.readLine();
|
password = inReader.readLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (password == null) {
|
||||||
|
throw new IOException("KerberosCallbackHandler: failed to retrieve password");
|
||||||
|
}
|
||||||
((PasswordCallback) callbacks[i]).setPassword(password.toCharArray());
|
((PasswordCallback) callbacks[i]).setPassword(password.toCharArray());
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -92,17 +98,26 @@ public class KerberosHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setPrincipal(String principal) {
|
||||||
|
KERBEROS_CALLBACK_HANDLER.principal = principal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setPassword(String password) {
|
||||||
|
KERBEROS_CALLBACK_HANDLER.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get response Kerberos token for host with provided token.
|
* Get response Kerberos token for host with provided token.
|
||||||
*
|
*
|
||||||
|
* @param protocol target protocol
|
||||||
* @param host target host
|
* @param host target host
|
||||||
* @param token input token
|
* @param token input token
|
||||||
* @return response token
|
* @return response token
|
||||||
* @throws GSSException on error
|
* @throws GSSException on error
|
||||||
* @throws LoginException on error
|
* @throws LoginException on error
|
||||||
*/
|
*/
|
||||||
public static byte[] initSecurityContext(final String host, final byte[] token) throws GSSException, LoginException {
|
public static byte[] initSecurityContext(final String protocol, final String host, final byte[] token) throws GSSException, LoginException {
|
||||||
return initSecurityContext(host, null, token);
|
return initSecurityContext(protocol, host, null, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,6 +125,7 @@ public class KerberosHelper {
|
|||||||
* Used to authenticate with target host on a gateway server with client credentials,
|
* Used to authenticate with target host on a gateway server with client credentials,
|
||||||
* gateway must have its own principal authorized for delegation
|
* gateway must have its own principal authorized for delegation
|
||||||
*
|
*
|
||||||
|
* @param protocol target protocol
|
||||||
* @param host target host
|
* @param host target host
|
||||||
* @param delegatedCredentials client delegated credentials
|
* @param delegatedCredentials client delegated credentials
|
||||||
* @param token input token
|
* @param token input token
|
||||||
@ -117,20 +133,38 @@ public class KerberosHelper {
|
|||||||
* @throws GSSException on error
|
* @throws GSSException on error
|
||||||
* @throws LoginException on error
|
* @throws LoginException on error
|
||||||
*/
|
*/
|
||||||
public static byte[] initSecurityContext(final String host, final GSSCredential delegatedCredentials, final byte[] token) throws GSSException, LoginException {
|
public static byte[] initSecurityContext(final String protocol, final String host, final GSSCredential delegatedCredentials, final byte[] token) throws GSSException, LoginException {
|
||||||
LOGGER.debug("KerberosHelper.initSecurityContext " + host + " " + token.length + " bytes token");
|
LOGGER.debug("KerberosHelper.initSecurityContext " + protocol + "/" + host + " " + token.length + " bytes token");
|
||||||
|
|
||||||
// TODO: handle ticket expiration ?
|
|
||||||
// create client login context
|
// create client login context
|
||||||
clientLogin();
|
clientLogin();
|
||||||
|
|
||||||
Object result = Subject.doAs(clientLoginContext.getSubject(), new PrivilegedAction() {
|
Object result = internalInitSecContext(protocol, host, delegatedCredentials, token);
|
||||||
|
if (result instanceof GSSException) {
|
||||||
|
LOGGER.info("KerberosHelper.initSecurityContext exception code " + ((GSSException) result).getMajor() + " minor code " + ((GSSException) result).getMinor() + " message " + ((GSSException) result).getMessage());
|
||||||
|
|
||||||
|
// recreate login context
|
||||||
|
clientReLogin();
|
||||||
|
result = internalInitSecContext(protocol, host, delegatedCredentials, token);
|
||||||
|
|
||||||
|
if (result instanceof GSSException) {
|
||||||
|
LOGGER.info("KerberosHelper.initSecurityContext exception code " + ((GSSException) result).getMajor() + " minor code " + ((GSSException) result).getMinor() + " message " + ((GSSException) result).getMessage());
|
||||||
|
throw (GSSException) result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.debug("KerberosHelper.initSecurityContext return " + ((byte[]) result).length + " bytes token");
|
||||||
|
return (byte[]) result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static Object internalInitSecContext(final String protocol, final String host, final GSSCredential delegatedCredentials, final byte[] token) {
|
||||||
|
return Subject.doAs(clientLoginContext.getSubject(), new PrivilegedAction() {
|
||||||
|
|
||||||
public Object run() {
|
public Object run() {
|
||||||
Object result;
|
Object result;
|
||||||
try {
|
try {
|
||||||
GSSManager manager = GSSManager.getInstance();
|
GSSManager manager = GSSManager.getInstance();
|
||||||
GSSName serverName = manager.createName("HTTP/" + host, null);
|
GSSName serverName = manager.createName(protocol + "/" + host, null);
|
||||||
// Kerberos v5 OID
|
// Kerberos v5 OID
|
||||||
Oid krb5Oid = new Oid("1.2.840.113554.1.2.2");
|
Oid krb5Oid = new Oid("1.2.840.113554.1.2.2");
|
||||||
|
|
||||||
@ -148,15 +182,6 @@ public class KerberosHelper {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (result instanceof GSSException) {
|
|
||||||
// TODO: manage error codes
|
|
||||||
LOGGER.info("KerberosHelper.initSecurityContext exception code " + ((GSSException) result).getMajor() + " message" + ((GSSException) result).getMessage());
|
|
||||||
|
|
||||||
throw (GSSException) result;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGGER.debug("KerberosHelper.initSecurityContext return " + ((byte[]) result).length + " bytes token");
|
|
||||||
return (byte[]) result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -174,6 +199,18 @@ public class KerberosHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recreate client Kerberos context.
|
||||||
|
*
|
||||||
|
* @throws LoginException on error
|
||||||
|
*/
|
||||||
|
public static void clientReLogin() throws LoginException {
|
||||||
|
synchronized (LOCK) {
|
||||||
|
clientLoginContext = null;
|
||||||
|
clientLogin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create server side Kerberos login context for provided credentials.
|
* Create server side Kerberos login context for provided credentials.
|
||||||
*
|
*
|
||||||
|
@ -187,11 +187,11 @@ public class SpNegoScheme implements AuthScheme {
|
|||||||
try {
|
try {
|
||||||
if (this.state == INITIATED || this.state == FAILED) {
|
if (this.state == INITIATED || this.state == FAILED) {
|
||||||
// send initial token to server
|
// send initial token to server
|
||||||
response = EncodingUtil.getAsciiString(Base64.encodeBase64(KerberosHelper.initSecurityContext(host, new byte[0])));
|
response = EncodingUtil.getAsciiString(Base64.encodeBase64(KerberosHelper.initSecurityContext("HTTP", host, new byte[0])));
|
||||||
this.state = TYPE1_MSG_GENERATED;
|
this.state = TYPE1_MSG_GENERATED;
|
||||||
} else {
|
} else {
|
||||||
// send challenge response
|
// send challenge response
|
||||||
response = EncodingUtil.getAsciiString(Base64.encodeBase64(KerberosHelper.initSecurityContext(host, serverToken)));
|
response = EncodingUtil.getAsciiString(Base64.encodeBase64(KerberosHelper.initSecurityContext("HTTP", host, serverToken)));
|
||||||
this.state = TYPE3_MSG_GENERATED;
|
this.state = TYPE3_MSG_GENERATED;
|
||||||
}
|
}
|
||||||
} catch (GSSException gsse) {
|
} catch (GSSException gsse) {
|
||||||
|
Loading…
Reference in New Issue
Block a user