mirror of
https://github.com/moparisthebest/davmail
synced 2024-12-21 06:58:51 -05:00
Kerberos: make sure access to client login context is synchronized
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@2280 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
1ea2466575
commit
f81f31f740
@ -150,11 +150,41 @@ public class KerberosHelper {
|
|||||||
* @throws LoginException on error
|
* @throws LoginException on error
|
||||||
*/
|
*/
|
||||||
public static byte[] initSecurityContext(final String protocol, 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 " + protocol + "/" + host + " " + token.length + " bytes token");
|
LOGGER.debug("KerberosHelper.initSecurityContext " + protocol + '/' + host + ' ' + token.length + " bytes token");
|
||||||
|
|
||||||
synchronized (LOCK) {
|
synchronized (LOCK) {
|
||||||
|
// check cached TGT
|
||||||
|
if (clientLoginContext != null) {
|
||||||
|
for (Object ticket : clientLoginContext.getSubject().getPrivateCredentials(KerberosTicket.class)) {
|
||||||
|
KerberosTicket kerberosTicket = (KerberosTicket) ticket;
|
||||||
|
if (kerberosTicket.getServer().getName().startsWith("krbtgt") && !kerberosTicket.isCurrent()) {
|
||||||
|
LOGGER.debug("KerberosHelper.clientLogin cached TGT expired, try to relogin");
|
||||||
|
clientLoginContext = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// create client login context
|
// create client login context
|
||||||
clientLogin();
|
if (clientLoginContext == null) {
|
||||||
|
final LoginContext localLoginContext = new LoginContext("spnego-client", KERBEROS_CALLBACK_HANDLER);
|
||||||
|
localLoginContext.login();
|
||||||
|
clientLoginContext = localLoginContext;
|
||||||
|
}
|
||||||
|
// try to renew almost expired tickets
|
||||||
|
for (Object ticket : clientLoginContext.getSubject().getPrivateCredentials(KerberosTicket.class)) {
|
||||||
|
KerberosTicket kerberosTicket = (KerberosTicket) ticket;
|
||||||
|
LOGGER.debug("KerberosHelper.clientLogin ticket for " + kerberosTicket.getServer().getName() + " expires at " + kerberosTicket.getEndTime());
|
||||||
|
if (kerberosTicket.getEndTime().getTime() < System.currentTimeMillis() + 10000) {
|
||||||
|
if (kerberosTicket.isRenewable()) {
|
||||||
|
try {
|
||||||
|
kerberosTicket.refresh();
|
||||||
|
} catch (RefreshFailedException e) {
|
||||||
|
LOGGER.debug("KerberosHelper.clientLogin failed to renew ticket " + kerberosTicket.toString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOGGER.debug("KerberosHelper.clientLogin ticket is not renewable");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Object result = internalInitSecContext(protocol, host, delegatedCredentials, token);
|
Object result = internalInitSecContext(protocol, host, delegatedCredentials, token);
|
||||||
if (result instanceof GSSException) {
|
if (result instanceof GSSException) {
|
||||||
@ -175,7 +205,7 @@ public class KerberosHelper {
|
|||||||
GSSContext context = null;
|
GSSContext context = null;
|
||||||
try {
|
try {
|
||||||
GSSManager manager = GSSManager.getInstance();
|
GSSManager manager = GSSManager.getInstance();
|
||||||
GSSName serverName = manager.createName(protocol + "/" + 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");
|
||||||
|
|
||||||
@ -202,45 +232,6 @@ public class KerberosHelper {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create client Kerberos context.
|
|
||||||
*
|
|
||||||
* @throws LoginException on error
|
|
||||||
*/
|
|
||||||
protected static void clientLogin() throws LoginException {
|
|
||||||
if (clientLoginContext != null) {
|
|
||||||
// check cached TGT
|
|
||||||
for (Object ticket : clientLoginContext.getSubject().getPrivateCredentials(KerberosTicket.class)) {
|
|
||||||
KerberosTicket kerberosTicket = (KerberosTicket) ticket;
|
|
||||||
if (kerberosTicket.getServer().getName().startsWith("krbtgt") && !kerberosTicket.isCurrent()) {
|
|
||||||
LOGGER.debug("KerberosHelper.clientLogin cached TGT expired, try to relogin");
|
|
||||||
clientLoginContext = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (clientLoginContext == null) {
|
|
||||||
final LoginContext localLoginContext = new LoginContext("spnego-client", KERBEROS_CALLBACK_HANDLER);
|
|
||||||
localLoginContext.login();
|
|
||||||
clientLoginContext = localLoginContext;
|
|
||||||
}
|
|
||||||
// try to renew almost expired tickets
|
|
||||||
for (Object ticket : clientLoginContext.getSubject().getPrivateCredentials(KerberosTicket.class)) {
|
|
||||||
KerberosTicket kerberosTicket = (KerberosTicket) ticket;
|
|
||||||
LOGGER.debug("KerberosHelper.clientLogin ticket for " + kerberosTicket.getServer().getName() + " expires at " + kerberosTicket.getEndTime());
|
|
||||||
if (kerberosTicket.getEndTime().getTime() < System.currentTimeMillis() + 10000) {
|
|
||||||
if (kerberosTicket.isRenewable()) {
|
|
||||||
try {
|
|
||||||
kerberosTicket.refresh();
|
|
||||||
} catch (RefreshFailedException e) {
|
|
||||||
LOGGER.debug("KerberosHelper.clientLogin failed to renew ticket " + kerberosTicket.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOGGER.debug("KerberosHelper.clientLogin ticket is not renewable");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create server side Kerberos login context for provided credentials.
|
* Create server side Kerberos login context for provided credentials.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user