Search in sources :

Example 31 with GSSCredential

use of org.ietf.jgss.GSSCredential in project zookeeper by apache.

the class SecurityUtils method createSaslClient.

/**
 * Create an instance of a SaslClient. It will return null if there is an exception.
 *
 * @param subject subject
 * @param servicePrincipal principal
 * @param protocol name of the protocol for which the authentication is being performed
 * @param serverName name of the server to authenticate to
 * @param LOG logger
 * @param entity can be either zookeeper client or quorum learner
 *
 * @return saslclient object
 * @throws SaslException
 */
public static SaslClient createSaslClient(final Subject subject, final String servicePrincipal, final String protocol, final String serverName, final Logger LOG, final String entity) throws SaslException {
    SaslClient saslClient;
    // mechanism to use: if empty, use DIGEST-MD5; otherwise, use GSSAPI.
    if (subject.getPrincipals().isEmpty()) {
        // no principals: must not be GSSAPI: use DIGEST-MD5 mechanism
        // instead.
        LOG.info("{} will use DIGEST-MD5 as SASL mechanism.", entity);
        String[] mechs = { "DIGEST-MD5" };
        String username = (String) (subject.getPublicCredentials().toArray()[0]);
        String password = (String) (subject.getPrivateCredentials().toArray()[0]);
        // 'domain' parameter is hard-wired between the server and client
        saslClient = Sasl.createSaslClient(mechs, username, protocol, serverName, null, new SaslClientCallbackHandler(password, entity));
        return saslClient;
    } else {
        // GSSAPI.
        final Object[] principals = subject.getPrincipals().toArray();
        // determine client principal from subject.
        final Principal clientPrincipal = (Principal) principals[0];
        boolean usingNativeJgss = Boolean.getBoolean("sun.security.jgss.native");
        if (usingNativeJgss) {
            // """
            try {
                GSSManager manager = GSSManager.getInstance();
                Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
                GSSCredential cred = manager.createCredential(null, GSSContext.DEFAULT_LIFETIME, krb5Mechanism, GSSCredential.INITIATE_ONLY);
                subject.getPrivateCredentials().add(cred);
                LOG.debug("Added private credential to {} principal name: '{}'", entity, clientPrincipal);
            } catch (GSSException ex) {
                LOG.warn("Cannot add private credential to subject; authentication at the server may fail", ex);
            }
        }
        final KerberosName clientKerberosName = new KerberosName(clientPrincipal.getName());
        // assume that server and client are in the same realm (by default;
        // unless the system property
        // "zookeeper.server.realm" is set).
        String serverRealm = System.getProperty("zookeeper.server.realm", clientKerberosName.getRealm());
        String modifiedServerPrincipal = servicePrincipal;
        // If service principal does not contain realm, then add it
        if (!modifiedServerPrincipal.contains("@")) {
            modifiedServerPrincipal = modifiedServerPrincipal + "@" + serverRealm;
        }
        KerberosName serviceKerberosName = new KerberosName(modifiedServerPrincipal);
        final String serviceName = serviceKerberosName.getServiceName();
        final String serviceHostname = serviceKerberosName.getHostName();
        final String clientPrincipalName = clientKerberosName.toString();
        try {
            saslClient = Subject.doAs(subject, new PrivilegedExceptionAction<SaslClient>() {

                public SaslClient run() throws SaslException {
                    LOG.info("{} will use GSSAPI as SASL mechanism.", entity);
                    String[] mechs = { "GSSAPI" };
                    LOG.debug("creating sasl client: {}={};service={};serviceHostname={}", entity, clientPrincipalName, serviceName, serviceHostname);
                    SaslClient saslClient = Sasl.createSaslClient(mechs, clientPrincipalName, serviceName, serviceHostname, null, new SaslClientCallbackHandler(null, entity));
                    return saslClient;
                }
            });
            return saslClient;
        } catch (Exception e) {
            LOG.error("Exception while trying to create SASL client", e);
            return null;
        }
    }
}
Also used : Oid(org.ietf.jgss.Oid) KerberosName(org.apache.zookeeper.server.auth.KerberosName) PrivilegedExceptionAction(java.security.PrivilegedExceptionAction) PrivilegedActionException(java.security.PrivilegedActionException) GSSException(org.ietf.jgss.GSSException) SaslException(javax.security.sasl.SaslException) SaslClient(javax.security.sasl.SaslClient) GSSException(org.ietf.jgss.GSSException) GSSCredential(org.ietf.jgss.GSSCredential) GSSManager(org.ietf.jgss.GSSManager) SaslClientCallbackHandler(org.apache.zookeeper.SaslClientCallbackHandler) Principal(java.security.Principal)

Example 32 with GSSCredential

use of org.ietf.jgss.GSSCredential in project zookeeper by apache.

the class SecurityUtils method createSaslServer.

/**
 * Create an instance of a SaslServer. It will return null if there is an exception.
 *
 * @param subject subject
 * @param protocol protocol
 * @param serverName server name
 * @param callbackHandler login callback handler
 * @param LOG logger
 * @return sasl server object
 */
public static SaslServer createSaslServer(final Subject subject, final String protocol, final String serverName, final CallbackHandler callbackHandler, final Logger LOG) {
    if (subject != null) {
        // principal name and hostname from zk server's subject.
        if (subject.getPrincipals().size() > 0) {
            try {
                final Object[] principals = subject.getPrincipals().toArray();
                final Principal servicePrincipal = (Principal) principals[0];
                // e.g. servicePrincipalNameAndHostname :=
                // "zookeeper/myhost.foo.com@FOO.COM"
                final String servicePrincipalNameAndHostname = servicePrincipal.getName();
                int indexOf = servicePrincipalNameAndHostname.indexOf("/");
                // e.g. servicePrincipalName := "zookeeper"
                final String servicePrincipalName = servicePrincipalNameAndHostname.substring(0, indexOf);
                // e.g. serviceHostnameAndKerbDomain :=
                // "myhost.foo.com@FOO.COM"
                final String serviceHostnameAndKerbDomain = servicePrincipalNameAndHostname.substring(indexOf + 1);
                indexOf = serviceHostnameAndKerbDomain.indexOf("@");
                // e.g. serviceHostname := "myhost.foo.com"
                final String serviceHostname = serviceHostnameAndKerbDomain.substring(0, indexOf);
                // TODO: should depend on zoo.cfg specified mechs, but if
                // subject is non-null, it can be assumed to be GSSAPI.
                final String mech = "GSSAPI";
                LOG.debug("serviceHostname is '{}'", serviceHostname);
                LOG.debug("servicePrincipalName is '{}'", servicePrincipalName);
                LOG.debug("SASL mechanism(mech) is '{}'", mech);
                boolean usingNativeJgss = Boolean.getBoolean("sun.security.jgss.native");
                if (usingNativeJgss) {
                    // """
                    try {
                        GSSManager manager = GSSManager.getInstance();
                        Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");
                        GSSName gssName = manager.createName(servicePrincipalName + "@" + serviceHostname, GSSName.NT_HOSTBASED_SERVICE);
                        GSSCredential cred = manager.createCredential(gssName, GSSContext.DEFAULT_LIFETIME, krb5Mechanism, GSSCredential.ACCEPT_ONLY);
                        subject.getPrivateCredentials().add(cred);
                        LOG.debug("Added private credential to service principal name: '{}', GSSCredential name: {}", servicePrincipalName, cred.getName());
                    } catch (GSSException ex) {
                        LOG.warn("Cannot add private credential to subject; clients authentication may fail", ex);
                    }
                }
                try {
                    return Subject.doAs(subject, new PrivilegedExceptionAction<SaslServer>() {

                        public SaslServer run() {
                            try {
                                SaslServer saslServer;
                                saslServer = Sasl.createSaslServer(mech, servicePrincipalName, serviceHostname, null, callbackHandler);
                                return saslServer;
                            } catch (SaslException e) {
                                LOG.error("Zookeeper Server failed to create a SaslServer to interact with a client during session initiation", e);
                                return null;
                            }
                        }
                    });
                } catch (PrivilegedActionException e) {
                    // TODO: exit server at this point(?)
                    LOG.error("Zookeeper Quorum member experienced a PrivilegedActionException exception while creating a SaslServer using a JAAS principal context", e);
                }
            } catch (IndexOutOfBoundsException e) {
                LOG.error("server principal name/hostname determination error", e);
            }
        } else {
            // TODO: use 'authMech=' value in zoo.cfg.
            try {
                SaslServer saslServer = Sasl.createSaslServer("DIGEST-MD5", protocol, serverName, null, callbackHandler);
                return saslServer;
            } catch (SaslException e) {
                LOG.error("Zookeeper Quorum member failed to create a SaslServer to interact with a client during session initiation", e);
            }
        }
    }
    return null;
}
Also used : GSSName(org.ietf.jgss.GSSName) PrivilegedActionException(java.security.PrivilegedActionException) SaslServer(javax.security.sasl.SaslServer) Oid(org.ietf.jgss.Oid) SaslException(javax.security.sasl.SaslException) GSSException(org.ietf.jgss.GSSException) GSSCredential(org.ietf.jgss.GSSCredential) GSSManager(org.ietf.jgss.GSSManager) Principal(java.security.Principal)

Example 33 with GSSCredential

use of org.ietf.jgss.GSSCredential in project tomcat by apache.

the class SpnegoAuthenticator method doAuthenticate.

@Override
protected boolean doAuthenticate(Request request, HttpServletResponse response) throws IOException {
    if (checkForCachedAuthentication(request, response, true)) {
        return true;
    }
    MessageBytes authorization = request.getCoyoteRequest().getMimeHeaders().getValue("authorization");
    if (authorization == null) {
        if (log.isDebugEnabled()) {
            log.debug(sm.getString("authenticator.noAuthHeader"));
        }
        response.setHeader(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_NEGOTIATE);
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        return false;
    }
    authorization.toBytes();
    ByteChunk authorizationBC = authorization.getByteChunk();
    if (!authorizationBC.startsWithIgnoreCase("negotiate ", 0)) {
        if (log.isDebugEnabled()) {
            log.debug(sm.getString("spnegoAuthenticator.authHeaderNotNego"));
        }
        response.setHeader(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_NEGOTIATE);
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        return false;
    }
    authorizationBC.setOffset(authorizationBC.getOffset() + 10);
    byte[] decoded = Base64.decodeBase64(authorizationBC.getBuffer(), authorizationBC.getOffset(), authorizationBC.getLength());
    if (getApplyJava8u40Fix()) {
        SpnegoTokenFixer.fix(decoded);
    }
    if (decoded.length == 0) {
        if (log.isDebugEnabled()) {
            log.debug(sm.getString("spnegoAuthenticator.authHeaderNoToken"));
        }
        response.setHeader(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_NEGOTIATE);
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        return false;
    }
    LoginContext lc = null;
    GSSContext gssContext = null;
    byte[] outToken = null;
    Principal principal = null;
    try {
        try {
            lc = new LoginContext(getLoginConfigName());
            lc.login();
        } catch (LoginException e) {
            log.error(sm.getString("spnegoAuthenticator.serviceLoginFail"), e);
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return false;
        }
        Subject subject = lc.getSubject();
        // Assume the GSSContext is stateless
        // TODO: Confirm this assumption
        final GSSManager manager = GSSManager.getInstance();
        // IBM JDK only understands indefinite lifetime
        final int credentialLifetime;
        if (JreVendor.IS_IBM_JVM) {
            credentialLifetime = GSSCredential.INDEFINITE_LIFETIME;
        } else {
            credentialLifetime = GSSCredential.DEFAULT_LIFETIME;
        }
        final PrivilegedExceptionAction<GSSCredential> action = () -> manager.createCredential(null, credentialLifetime, new Oid("1.3.6.1.5.5.2"), GSSCredential.ACCEPT_ONLY);
        gssContext = manager.createContext(Subject.doAs(subject, action));
        outToken = Subject.doAs(lc.getSubject(), new AcceptAction(gssContext, decoded));
        if (outToken == null) {
            if (log.isDebugEnabled()) {
                log.debug(sm.getString("spnegoAuthenticator.ticketValidateFail"));
            }
            // Start again
            response.setHeader(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_NEGOTIATE);
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }
        principal = Subject.doAs(subject, new AuthenticateAction(context.getRealm(), gssContext, storeDelegatedCredential));
    } catch (GSSException e) {
        if (log.isDebugEnabled()) {
            log.debug(sm.getString("spnegoAuthenticator.ticketValidateFail"), e);
        }
        response.setHeader(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_NEGOTIATE);
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        return false;
    } catch (PrivilegedActionException e) {
        Throwable cause = e.getCause();
        if (cause instanceof GSSException) {
            if (log.isDebugEnabled()) {
                log.debug(sm.getString("spnegoAuthenticator.serviceLoginFail"), e);
            }
        } else {
            log.error(sm.getString("spnegoAuthenticator.serviceLoginFail"), e);
        }
        response.setHeader(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_NEGOTIATE);
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        return false;
    } finally {
        if (gssContext != null) {
            try {
                gssContext.dispose();
            } catch (GSSException e) {
            // Ignore
            }
        }
        if (lc != null) {
            try {
                lc.logout();
            } catch (LoginException e) {
            // Ignore
            }
        }
    }
    // Send response token on success and failure
    response.setHeader(AUTH_HEADER_NAME, AUTH_HEADER_VALUE_NEGOTIATE + " " + Base64.encodeBase64String(outToken));
    if (principal != null) {
        register(request, response, principal, Constants.SPNEGO_METHOD, principal.getName(), null);
        Pattern p = noKeepAliveUserAgents;
        if (p != null) {
            MessageBytes ua = request.getCoyoteRequest().getMimeHeaders().getValue("user-agent");
            if (ua != null && p.matcher(ua.toString()).matches()) {
                response.setHeader("Connection", "close");
            }
        }
        return true;
    }
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
    return false;
}
Also used : Pattern(java.util.regex.Pattern) ByteChunk(org.apache.tomcat.util.buf.ByteChunk) PrivilegedActionException(java.security.PrivilegedActionException) MessageBytes(org.apache.tomcat.util.buf.MessageBytes) Oid(org.ietf.jgss.Oid) Subject(javax.security.auth.Subject) LoginContext(javax.security.auth.login.LoginContext) GSSException(org.ietf.jgss.GSSException) GSSCredential(org.ietf.jgss.GSSCredential) GSSContext(org.ietf.jgss.GSSContext) GSSManager(org.ietf.jgss.GSSManager) LoginException(javax.security.auth.login.LoginException) Principal(java.security.Principal)

Example 34 with GSSCredential

use of org.ietf.jgss.GSSCredential in project ranger by apache.

the class CredentialsProviderUtil method getKerberosCredentials.

public static KerberosCredentialsProvider getKerberosCredentials(String user, String password) {
    KerberosCredentialsProvider credentialsProvider = new KerberosCredentialsProvider();
    final GSSManager gssManager = GSSManager.getInstance();
    try {
        final GSSName gssUserPrincipalName = gssManager.createName(user, GSSName.NT_USER_NAME);
        Subject subject = login(user, password);
        final AccessControlContext acc = AccessController.getContext();
        final GSSCredential credential = doAsPrivilegedWrapper(subject, (PrivilegedExceptionAction<GSSCredential>) () -> gssManager.createCredential(gssUserPrincipalName, GSSCredential.DEFAULT_LIFETIME, SPNEGO_OID, GSSCredential.INITIATE_ONLY), acc);
        credentialsProvider.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM, AuthSchemes.SPNEGO), new KerberosCredentials(credential));
    } catch (GSSException e) {
        logger.error("GSSException:", e);
        throw new RuntimeException(e);
    } catch (PrivilegedActionException e) {
        logger.error("PrivilegedActionException:", e);
        throw new RuntimeException(e);
    }
    return credentialsProvider;
}
Also used : KerberosCredentialsProvider(org.apache.ranger.authorization.credutils.kerberos.KerberosCredentialsProvider) GSSName(org.ietf.jgss.GSSName) AccessControlContext(java.security.AccessControlContext) GSSException(org.ietf.jgss.GSSException) GSSCredential(org.ietf.jgss.GSSCredential) PrivilegedActionException(java.security.PrivilegedActionException) GSSManager(org.ietf.jgss.GSSManager) AuthScope(org.apache.http.auth.AuthScope) KerberosCredentials(org.apache.http.auth.KerberosCredentials) Subject(javax.security.auth.Subject)

Example 35 with GSSCredential

use of org.ietf.jgss.GSSCredential in project knox by apache.

the class SpnegoAuthInterceptor method createCredentialSession.

private GSSCredentialSession createCredentialSession() throws GSSException {
    Principal clientPrincipal = subject.getPrincipals().iterator().next();
    GSSCredential clientCredential = doAs(subject, () -> GSS_MANAGER.createCredential(GSS_MANAGER.createName(clientPrincipal.getName(), NT_USER_NAME), DEFAULT_LIFETIME, KERBEROS_OID, INITIATE_ONLY));
    return new GSSCredentialSession(clientCredential);
}
Also used : GSSCredential(org.ietf.jgss.GSSCredential) Principal(java.security.Principal)

Aggregations

GSSCredential (org.ietf.jgss.GSSCredential)66 GSSManager (org.ietf.jgss.GSSManager)38 Oid (org.ietf.jgss.Oid)36 GSSName (org.ietf.jgss.GSSName)34 GSSException (org.ietf.jgss.GSSException)33 GSSContext (org.ietf.jgss.GSSContext)28 Subject (javax.security.auth.Subject)22 Principal (java.security.Principal)19 PrivilegedActionException (java.security.PrivilegedActionException)19 IOException (java.io.IOException)9 LoginContext (javax.security.auth.login.LoginContext)9 LoginException (javax.security.auth.login.LoginException)9 PrivilegedExceptionAction (java.security.PrivilegedExceptionAction)8 KerberosCredentials (org.apache.http.auth.KerberosCredentials)7 KerberosTicket (javax.security.auth.kerberos.KerberosTicket)6 SaslException (javax.security.sasl.SaslException)6 SPNegoSchemeFactory (org.apache.http.impl.auth.SPNegoSchemeFactory)4 BasicCredentialsProvider (org.apache.http.impl.client.BasicCredentialsProvider)4 Test (org.junit.Test)4 ExtendedGSSContext (com.sun.security.jgss.ExtendedGSSContext)3