blob: 9433bf570668551ef56054796c7b4ad1897f7fdb [file] [log] [blame]
package org.apache.kerby.kerberos.kerb.gss.impl;
import org.ietf.jgss.GSSException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.security.jgss.GSSCaller;
import javax.security.auth.Subject;
import javax.security.auth.kerberos.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Set;
/**
* Utility functions to deal with credentials in Context
*/
public class CredUtils {
private static final Logger LOG = LoggerFactory.getLogger(CredUtils.class);
public static <T> Set<T> getContextPrivateCredentials(Class<T> credentialType, AccessControlContext acc) {
Subject subject = Subject.getSubject(acc);
Set<T> creds = subject.getPrivateCredentials(credentialType);
return creds;
}
public static <T> Set<T> getContextCredentials(final Class<T> credentialType) throws GSSException {
final AccessControlContext acc = AccessController.getContext();
try {
return AccessController.doPrivileged(
new PrivilegedExceptionAction<Set<T>>() {
public Set<T> run() throws Exception {
return CredUtils.getContextPrivateCredentials(credentialType, acc);
}
});
} catch (PrivilegedActionException e) {
throw new GSSException(GSSException.NO_CRED, -1, "Get credential from context failed");
}
}
public static Set<KerberosKey> getKerberosKeysFromContext(GSSCaller caller,
final String clientName,
final String serverName) throws GSSException {
return getContextCredentials(KerberosKey.class);
}
public static KerberosTicket getKerberosTicketFromContext(GSSCaller caller,
final String clientName,
final String serverName) throws GSSException {
Set<KerberosTicket> tickets = getContextCredentials(KerberosTicket.class);
for (KerberosTicket ticket : tickets) {
if (ticket.isCurrent() && (serverName == null || ticket.getServer().getName().equals(serverName))
&& (clientName == null || ticket.getClient().getName().equals(clientName))) {
return ticket;
}
}
return null;
}
public static KeyTab getKeyTabFromContext(KerberosPrincipal principal) throws GSSException {
Set<KeyTab> tabs = getContextCredentials(KeyTab.class);
for (KeyTab tab : tabs) {
// Use the supplied principal
KerberosPrincipal princ = principal;
if (princ == null) {
// fall back to the principal of the KeyTab (if JDK 1.8) if none is supplied
try {
Method m = tab.getClass().getDeclaredMethod("getPrincipal");
princ = (KerberosPrincipal) m.invoke(tab);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException e) {
LOG.info("Can't get a principal from the keytab", e);
}
}
if (princ != null) {
KerberosKey[] keys = tab.getKeys(princ);
if (keys != null && keys.length > 0) {
return tab;
}
}
}
return null;
}
public static void addCredentialToSubject(final KerberosTicket ticket) throws GSSException {
final AccessControlContext acc = AccessController.getContext();
final Subject subject = AccessController.doPrivileged(
new java.security.PrivilegedAction<Subject>() {
public Subject run() {
return Subject.getSubject(acc);
}
});
AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
subject.getPrivateCredentials().add(ticket);
return null;
}
});
}
public static void checkPrincipalPermission(String principalName, String action) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ServicePermission sp = new ServicePermission(principalName, action);
sm.checkPermission(sp);
}
}
}