| 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); |
| } |
| } |
| } |