Search in sources :

Example 1 with SaslClient

use of javax.security.sasl.SaslClient in project ats-framework by Axway.

the class InetSmtpConnection method authenticate.

// -- Authentication --
/**
     * Authenticates the connection using the specified SASL mechanism,
     * username, and password.
     * @param mechanism a SASL authentication mechanism, e.g. LOGIN, PLAIN,
     * CRAM-MD5, GSSAPI
     * @param username the authentication principal
     * @param password the authentication credentials
     * @return true if authentication was successful, false otherwise
     */
public boolean authenticate(String mechanism, String username, String password) throws IOException {
    try {
        String[] m = new String[] { mechanism };
        CallbackHandler ch = new SaslCallbackHandler(username, password);
        // Avoid lengthy callback procedure for GNU Crypto
        HashMap<String, String> p = new HashMap<String, String>();
        p.put("gnu.crypto.sasl.username", username);
        p.put("gnu.crypto.sasl.password", password);
        SaslClient sasl = Sasl.createSaslClient(m, null, "smtp", socket.getInetAddress().getHostName(), p, ch);
        if (sasl == null) {
            // Fall back to home-grown SASL clients
            if ("LOGIN".equalsIgnoreCase(mechanism)) {
                sasl = new SaslLogin(username, password);
            } else if ("PLAIN".equalsIgnoreCase(mechanism)) {
                sasl = new SaslPlain(username, password);
            } else if ("CRAM-MD5".equalsIgnoreCase(mechanism)) {
                sasl = new SaslCramMD5(username, password);
            } else {
                return false;
            }
        }
        StringBuffer cmd = new StringBuffer(AUTH);
        cmd.append(' ');
        cmd.append(mechanism);
        if (sasl.hasInitialResponse()) {
            cmd.append(' ');
            byte[] init = sasl.evaluateChallenge(new byte[0]);
            if (init.length == 0) {
                cmd.append('=');
            } else {
                cmd.append(new String(BASE64.encode(init), "US-ASCII"));
            }
        }
        send(cmd.toString());
        while (true) {
            switch(getAllResponses()) {
                case 334:
                    try {
                        byte[] c0 = response.getBytes("US-ASCII");
                        // challenge
                        byte[] c1 = BASE64.decode(c0);
                        byte[] r0 = sasl.evaluateChallenge(c1);
                        // response
                        byte[] r1 = BASE64.encode(r0);
                        out.write(r1);
                        out.write(0x0d);
                        out.flush();
                        log.trace("> " + new String(r1, "US-ASCII"));
                    } catch (SaslException e) {
                        // Error in SASL challenge evaluation - cancel exchange
                        out.write(0x2a);
                        out.write(0x0d);
                        out.flush();
                        log.trace("> *");
                    }
                    break;
                case 235:
                    String qop = (String) sasl.getNegotiatedProperty(Sasl.QOP);
                    if ("auth-int".equalsIgnoreCase(qop) || "auth-conf".equalsIgnoreCase(qop)) {
                        InputStream is = socket.getInputStream();
                        is = new BufferedInputStream(is);
                        is = new SaslInputStream(sasl, is);
                        is = new CRLFInputStream(is);
                        in = new LineInputStream(is);
                        OutputStream os = socket.getOutputStream();
                        os = new BufferedOutputStream(os);
                        os = new SaslOutputStream(sasl, os);
                        out = new CRLFOutputStream(os);
                    }
                    return true;
                default:
                    return false;
            }
        }
    } catch (SaslException e) {
        log.error(e.getMessage(), e);
        // No provider for mechanism
        return false;
    } catch (RuntimeException e) {
        log.error(e.getMessage(), e);
        // No javax.security.sasl classes
        return false;
    }
}
Also used : CallbackHandler(javax.security.auth.callback.CallbackHandler) SaslCallbackHandler(gnu.inet.util.SaslCallbackHandler) SaslInputStream(gnu.inet.util.SaslInputStream) HashMap(java.util.HashMap) CRLFInputStream(gnu.inet.util.CRLFInputStream) BufferedInputStream(java.io.BufferedInputStream) LineInputStream(gnu.inet.util.LineInputStream) SaslInputStream(gnu.inet.util.SaslInputStream) InputStream(java.io.InputStream) BufferedOutputStream(java.io.BufferedOutputStream) MessageOutputStream(gnu.inet.util.MessageOutputStream) OutputStream(java.io.OutputStream) SaslOutputStream(gnu.inet.util.SaslOutputStream) CRLFOutputStream(gnu.inet.util.CRLFOutputStream) SaslException(javax.security.sasl.SaslException) CRLFOutputStream(gnu.inet.util.CRLFOutputStream) SaslClient(javax.security.sasl.SaslClient) SaslPlain(gnu.inet.util.SaslPlain) SaslOutputStream(gnu.inet.util.SaslOutputStream) BufferedInputStream(java.io.BufferedInputStream) SaslCramMD5(gnu.inet.util.SaslCramMD5) SaslCallbackHandler(gnu.inet.util.SaslCallbackHandler) CRLFInputStream(gnu.inet.util.CRLFInputStream) LineInputStream(gnu.inet.util.LineInputStream) BufferedOutputStream(java.io.BufferedOutputStream) SaslLogin(gnu.inet.util.SaslLogin)

Example 2 with SaslClient

use of javax.security.sasl.SaslClient in project drill by apache.

the class UserClient method authenticate.

private CheckedFuture<Void, SaslException> authenticate(final DrillProperties properties) {
    final Map<String, String> propertiesMap = properties.stringPropertiesAsMap();
    // Set correct QOP property and Strength based on server needs encryption or not.
    // If ChunkMode is enabled then negotiate for buffer size equal to wrapChunkSize,
    // If ChunkMode is disabled then negotiate for MAX_WRAPPED_SIZE buffer size.
    propertiesMap.putAll(SaslProperties.getSaslProperties(connection.isEncryptionEnabled(), connection.getMaxWrappedSize()));
    // use handleAuthFailure to setException
    final SettableFuture<Void> authSettable = SettableFuture.create();
    final CheckedFuture<Void, SaslException> authFuture = new AbstractCheckedFuture<Void, SaslException>(authSettable) {

        @Override
        protected SaslException mapException(Exception e) {
            if (e instanceof ExecutionException) {
                final Throwable cause = Throwables.getRootCause(e);
                if (cause instanceof SaslException) {
                    return new SaslException(String.format("Authentication failed. [Details: %s, Error %s]", connection.getEncryptionCtxtString(), cause.getMessage()), cause);
                }
            }
            return new SaslException(String.format("Authentication failed unexpectedly. [Details: %s, Error %s]", connection.getEncryptionCtxtString(), e.getMessage()), e);
        }
    };
    final AuthenticatorFactory factory;
    final String mechanismName;
    final UserGroupInformation ugi;
    final SaslClient saslClient;
    try {
        factory = getAuthenticatorFactory(properties);
        mechanismName = factory.getSimpleName();
        logger.trace("Will try to authenticate to server using {} mechanism with encryption context {}", mechanismName, connection.getEncryptionCtxtString());
        ugi = factory.createAndLoginUser(propertiesMap);
        saslClient = factory.createSaslClient(ugi, propertiesMap);
        if (saslClient == null) {
            throw new SaslException(String.format("Cannot initiate authentication using %s mechanism. Insufficient " + "credentials or selected mechanism doesn't support configured security layers?", factory.getSimpleName()));
        }
        connection.setSaslClient(saslClient);
    } catch (final IOException e) {
        authSettable.setException(e);
        return authFuture;
    }
    logger.trace("Initiating SASL exchange.");
    new AuthenticationOutcomeListener<>(this, connection, RpcType.SASL_MESSAGE, ugi, new RpcOutcomeListener<Void>() {

        @Override
        public void failed(RpcException ex) {
            authSettable.setException(ex);
        }

        @Override
        public void success(Void value, ByteBuf buffer) {
            authComplete = true;
            authSettable.set(null);
        }

        @Override
        public void interrupted(InterruptedException e) {
            authSettable.setException(e);
        }
    }).initiate(mechanismName);
    return authFuture;
}
Also used : IOException(java.io.IOException) AbstractCheckedFuture(com.google.common.util.concurrent.AbstractCheckedFuture) SaslException(javax.security.sasl.SaslException) AuthenticatorFactory(org.apache.drill.exec.rpc.security.AuthenticatorFactory) ByteBuf(io.netty.buffer.ByteBuf) RpcException(org.apache.drill.exec.rpc.RpcException) SaslException(javax.security.sasl.SaslException) NonTransientRpcException(org.apache.drill.exec.rpc.NonTransientRpcException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) SaslClient(javax.security.sasl.SaslClient) RpcException(org.apache.drill.exec.rpc.RpcException) NonTransientRpcException(org.apache.drill.exec.rpc.NonTransientRpcException) ExecutionException(java.util.concurrent.ExecutionException) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) RpcOutcomeListener(org.apache.drill.exec.rpc.RpcOutcomeListener)

Example 3 with SaslClient

use of javax.security.sasl.SaslClient in project drill by apache.

the class ControlClient method validateHandshake.

@Override
protected void validateHandshake(BitControlHandshake handshake) throws RpcException {
    if (handshake.getRpcVersion() != ControlRpcConfig.RPC_VERSION) {
        throw new RpcException(String.format("Invalid rpc version.  Expected %d, actual %d.", handshake.getRpcVersion(), ControlRpcConfig.RPC_VERSION));
    }
    if (handshake.getAuthenticationMechanismsCount() != 0) {
        // remote requires authentication
        final SaslClient saslClient;
        try {
            final Map<String, String> saslProperties = SaslProperties.getSaslProperties(connection.isEncryptionEnabled(), connection.getMaxWrappedSize());
            saslClient = config.getAuthFactory(handshake.getAuthenticationMechanismsList()).createSaslClient(UserGroupInformation.getLoginUser(), config.getSaslClientProperties(remoteEndpoint, saslProperties));
        } catch (final IOException e) {
            throw new RpcException(String.format("Failed to initiate authenticate to %s", remoteEndpoint.getAddress()), e);
        }
        if (saslClient == null) {
            throw new RpcException("Unexpected failure. Could not initiate SASL exchange.");
        }
        connection.setSaslClient(saslClient);
    } else {
        if (config.getAuthMechanismToUse() != null) {
            // local requires authentication
            throw new RpcException(String.format("Drillbit (%s) does not require auth, but auth is enabled.", remoteEndpoint.getAddress()));
        }
    }
}
Also used : RpcException(org.apache.drill.exec.rpc.RpcException) IOException(java.io.IOException) SaslClient(javax.security.sasl.SaslClient)

Example 4 with SaslClient

use of javax.security.sasl.SaslClient in project drill by apache.

the class AuthenticationOutcomeListener method handleSuccess.

private static <CC extends ClientConnection> void handleSuccess(SaslChallengeContext<CC> context) throws SaslException {
    final CC connection = context.connection;
    final SaslClient saslClient = connection.getSaslClient();
    try {
        // Check if connection was marked for being secure then verify for negotiated QOP value for
        // correctness.
        final String negotiatedQOP = saslClient.getNegotiatedProperty(Sasl.QOP).toString();
        final String expectedQOP = connection.isEncryptionEnabled() ? SaslProperties.QualityOfProtection.PRIVACY.getSaslQop() : SaslProperties.QualityOfProtection.AUTHENTICATION.getSaslQop();
        if (!(negotiatedQOP.equals(expectedQOP))) {
            throw new SaslException(String.format("Mismatch in negotiated QOP value: %s and Expected QOP value: %s", negotiatedQOP, expectedQOP));
        }
        // negotiated size of buffer.
        if (connection.isEncryptionEnabled()) {
            final int negotiatedRawSendSize = Integer.parseInt(saslClient.getNegotiatedProperty(Sasl.RAW_SEND_SIZE).toString());
            if (negotiatedRawSendSize <= 0) {
                throw new SaslException(String.format("Negotiated rawSendSize: %d is invalid. Please check the configured " + "value of encryption.sasl.max_wrapped_size. It might be configured to a very small value.", negotiatedRawSendSize));
            }
            connection.setWrapSizeLimit(negotiatedRawSendSize);
        }
    } catch (Exception e) {
        throw new SaslException(String.format("Unexpected failure while retrieving negotiated property values (%s)", e.getMessage()), e);
    }
    if (connection.isEncryptionEnabled()) {
        connection.addSecurityHandlers();
    } else {
        // Encryption is not required hence we don't need to hold on to saslClient object.
        connection.disposeSaslClient();
    }
}
Also used : ByteString(com.google.protobuf.ByteString) SaslException(javax.security.sasl.SaslException) RpcException(org.apache.drill.exec.rpc.RpcException) IOException(java.io.IOException) SaslException(javax.security.sasl.SaslException) UndeclaredThrowableException(java.lang.reflect.UndeclaredThrowableException) SaslClient(javax.security.sasl.SaslClient)

Example 5 with SaslClient

use of javax.security.sasl.SaslClient in project zookeeper by apache.

the class ZooKeeperSaslClient method createSaslClient.

private SaslClient createSaslClient(final String servicePrincipal, final String loginContext) throws LoginException {
    try {
        if (!initializedLogin) {
            synchronized (this) {
                if (login == null) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("JAAS loginContext is: " + loginContext);
                    }
                    // note that the login object is static: it's shared amongst all zookeeper-related connections.
                    // in order to ensure the login is initialized only once, it must be synchronized the code snippet.
                    login = new Login(loginContext, new ClientCallbackHandler(null), clientConfig);
                    login.startThreadIfNeeded();
                    initializedLogin = true;
                }
            }
        }
        Subject subject = login.getSubject();
        SaslClient saslClient;
        // 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("Client will use DIGEST-MD5 as SASL mechanism.");
            String[] mechs = { "DIGEST-MD5" };
            String username = (String) (subject.getPublicCredentials().toArray()[0]);
            String password = (String) (subject.getPrivateCredentials().toArray()[0]);
            // "zk-sasl-md5" is a hard-wired 'domain' parameter shared with zookeeper server code (see ServerCnxnFactory.java)
            saslClient = Sasl.createSaslClient(mechs, username, "zookeeper", "zk-sasl-md5", null, new ClientCallbackHandler(password));
            return saslClient;
        } else {
            // GSSAPI.
            boolean usingNativeJgss = clientConfig.getBoolean(ZKConfig.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);
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Added private credential to subject: " + cred);
                    }
                } catch (GSSException ex) {
                    LOG.warn("Cannot add private credential to subject; " + "authentication at the server may fail", ex);
                }
            }
            final Object[] principals = subject.getPrincipals().toArray();
            // determine client principal from subject.
            final Principal clientPrincipal = (Principal) principals[0];
            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 = clientConfig.getProperty(ZKClientConfig.ZOOKEEPER_SERVER_REALM, clientKerberosName.getRealm());
            KerberosName serviceKerberosName = new KerberosName(servicePrincipal + "@" + serverRealm);
            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("Client will use GSSAPI as SASL mechanism.");
                        String[] mechs = { "GSSAPI" };
                        LOG.debug("creating sasl client: client=" + clientPrincipalName + ";service=" + serviceName + ";serviceHostname=" + serviceHostname);
                        SaslClient saslClient = Sasl.createSaslClient(mechs, clientPrincipalName, serviceName, serviceHostname, null, new ClientCallbackHandler(null));
                        return saslClient;
                    }
                });
                return saslClient;
            } catch (Exception e) {
                LOG.error("Exception while trying to create SASL client", e);
                e.printStackTrace();
                return null;
            }
        }
    } catch (LoginException e) {
        // We throw LoginExceptions...
        throw e;
    } catch (Exception e) {
        // ..but consume (with a log message) all other types of exceptions.
        LOG.error("Exception while trying to create SASL client: " + e);
        return null;
    }
}
Also used : Login(org.apache.zookeeper.Login) Oid(org.ietf.jgss.Oid) KerberosName(org.apache.zookeeper.server.auth.KerberosName) PrivilegedExceptionAction(java.security.PrivilegedExceptionAction) Subject(javax.security.auth.Subject) LoginException(javax.security.auth.login.LoginException) UnsupportedCallbackException(javax.security.auth.callback.UnsupportedCallbackException) SaslException(javax.security.sasl.SaslException) PrivilegedActionException(java.security.PrivilegedActionException) IOException(java.io.IOException) GSSException(org.ietf.jgss.GSSException) SaslClient(javax.security.sasl.SaslClient) GSSException(org.ietf.jgss.GSSException) GSSCredential(org.ietf.jgss.GSSCredential) GSSManager(org.ietf.jgss.GSSManager) LoginException(javax.security.auth.login.LoginException) Principal(java.security.Principal)

Aggregations

SaslClient (javax.security.sasl.SaslClient)12 SaslException (javax.security.sasl.SaslException)9 IOException (java.io.IOException)8 RpcException (org.apache.drill.exec.rpc.RpcException)5 UndeclaredThrowableException (java.lang.reflect.UndeclaredThrowableException)3 UnsupportedCallbackException (javax.security.auth.callback.UnsupportedCallbackException)3 ByteString (com.google.protobuf.ByteString)2 PrivilegedExceptionAction (java.security.PrivilegedExceptionAction)2 HashMap (java.util.HashMap)2 Subject (javax.security.auth.Subject)2 CallbackHandler (javax.security.auth.callback.CallbackHandler)2 LoginException (javax.security.auth.login.LoginException)2 SaslServer (javax.security.sasl.SaslServer)2 GSSException (org.ietf.jgss.GSSException)2 AbstractCheckedFuture (com.google.common.util.concurrent.AbstractCheckedFuture)1 MongoCredential (com.mongodb.MongoCredential)1 MongoSecurityException (com.mongodb.MongoSecurityException)1 CRLFInputStream (gnu.inet.util.CRLFInputStream)1 CRLFOutputStream (gnu.inet.util.CRLFOutputStream)1 LineInputStream (gnu.inet.util.LineInputStream)1