Search in sources :

Example 1 with ScramExtensionsCallback

use of org.apache.kafka.common.security.scram.ScramExtensionsCallback in project apache-kafka-on-k8s by banzaicloud.

the class SaslClientCallbackHandler method handle.

@Override
public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
    for (Callback callback : callbacks) {
        if (callback instanceof NameCallback) {
            NameCallback nc = (NameCallback) callback;
            if (!isKerberos && subject != null && !subject.getPublicCredentials(String.class).isEmpty()) {
                nc.setName(subject.getPublicCredentials(String.class).iterator().next());
            } else
                nc.setName(nc.getDefaultName());
        } else if (callback instanceof PasswordCallback) {
            if (!isKerberos && subject != null && !subject.getPrivateCredentials(String.class).isEmpty()) {
                char[] password = subject.getPrivateCredentials(String.class).iterator().next().toCharArray();
                ((PasswordCallback) callback).setPassword(password);
            } else {
                String errorMessage = "Could not login: the client is being asked for a password, but the Kafka" + " client code does not currently support obtaining a password from the user.";
                if (isKerberos) {
                    errorMessage += " Make sure -Djava.security.auth.login.config property passed to JVM and" + " the client is configured to use a ticket cache (using" + " the JAAS configuration setting 'useTicketCache=true)'. Make sure you are using" + " FQDN of the Kafka broker you are trying to connect to.";
                }
                throw new UnsupportedCallbackException(callback, errorMessage);
            }
        } else if (callback instanceof RealmCallback) {
            RealmCallback rc = (RealmCallback) callback;
            rc.setText(rc.getDefaultText());
        } else if (callback instanceof AuthorizeCallback) {
            AuthorizeCallback ac = (AuthorizeCallback) callback;
            String authId = ac.getAuthenticationID();
            String authzId = ac.getAuthorizationID();
            ac.setAuthorized(authId.equals(authzId));
            if (ac.isAuthorized())
                ac.setAuthorizedID(authzId);
        } else if (callback instanceof ScramExtensionsCallback) {
            ScramExtensionsCallback sc = (ScramExtensionsCallback) callback;
            if (!isKerberos && subject != null && !subject.getPublicCredentials(Map.class).isEmpty()) {
                sc.extensions((Map<String, String>) subject.getPublicCredentials(Map.class).iterator().next());
            }
        } else {
            throw new UnsupportedCallbackException(callback, "Unrecognized SASL ClientCallback");
        }
    }
}
Also used : RealmCallback(javax.security.sasl.RealmCallback) PasswordCallback(javax.security.auth.callback.PasswordCallback) NameCallback(javax.security.auth.callback.NameCallback) ScramExtensionsCallback(org.apache.kafka.common.security.scram.ScramExtensionsCallback) AuthorizeCallback(javax.security.sasl.AuthorizeCallback) Callback(javax.security.auth.callback.Callback) NameCallback(javax.security.auth.callback.NameCallback) ScramExtensionsCallback(org.apache.kafka.common.security.scram.ScramExtensionsCallback) PasswordCallback(javax.security.auth.callback.PasswordCallback) UnsupportedCallbackException(javax.security.auth.callback.UnsupportedCallbackException) Map(java.util.Map) AuthorizeCallback(javax.security.sasl.AuthorizeCallback) RealmCallback(javax.security.sasl.RealmCallback)

Example 2 with ScramExtensionsCallback

use of org.apache.kafka.common.security.scram.ScramExtensionsCallback in project kafka by apache.

the class ScramSaslClient method evaluateChallenge.

@Override
public byte[] evaluateChallenge(byte[] challenge) throws SaslException {
    try {
        switch(state) {
            case SEND_CLIENT_FIRST_MESSAGE:
                if (challenge != null && challenge.length != 0)
                    throw new SaslException("Expected empty challenge");
                clientNonce = formatter.secureRandomString();
                NameCallback nameCallback = new NameCallback("Name:");
                ScramExtensionsCallback extensionsCallback = new ScramExtensionsCallback();
                try {
                    callbackHandler.handle(new Callback[] { nameCallback });
                    try {
                        callbackHandler.handle(new Callback[] { extensionsCallback });
                    } catch (UnsupportedCallbackException e) {
                        log.debug("Extensions callback is not supported by client callback handler {}, no extensions will be added", callbackHandler);
                    }
                } catch (Throwable e) {
                    throw new SaslException("User name or extensions could not be obtained", e);
                }
                String username = nameCallback.getName();
                String saslName = ScramFormatter.saslName(username);
                Map<String, String> extensions = extensionsCallback.extensions();
                this.clientFirstMessage = new ScramMessages.ClientFirstMessage(saslName, clientNonce, extensions);
                setState(State.RECEIVE_SERVER_FIRST_MESSAGE);
                return clientFirstMessage.toBytes();
            case RECEIVE_SERVER_FIRST_MESSAGE:
                this.serverFirstMessage = new ServerFirstMessage(challenge);
                if (!serverFirstMessage.nonce().startsWith(clientNonce))
                    throw new SaslException("Invalid server nonce: does not start with client nonce");
                if (serverFirstMessage.iterations() < mechanism.minIterations())
                    throw new SaslException("Requested iterations " + serverFirstMessage.iterations() + " is less than the minimum " + mechanism.minIterations() + " for " + mechanism);
                PasswordCallback passwordCallback = new PasswordCallback("Password:", false);
                try {
                    callbackHandler.handle(new Callback[] { passwordCallback });
                } catch (Throwable e) {
                    throw new SaslException("User name could not be obtained", e);
                }
                this.clientFinalMessage = handleServerFirstMessage(passwordCallback.getPassword());
                setState(State.RECEIVE_SERVER_FINAL_MESSAGE);
                return clientFinalMessage.toBytes();
            case RECEIVE_SERVER_FINAL_MESSAGE:
                ServerFinalMessage serverFinalMessage = new ServerFinalMessage(challenge);
                if (serverFinalMessage.error() != null)
                    throw new SaslException("Sasl authentication using " + mechanism + " failed with error: " + serverFinalMessage.error());
                handleServerFinalMessage(serverFinalMessage.serverSignature());
                setState(State.COMPLETE);
                return null;
            default:
                throw new IllegalSaslStateException("Unexpected challenge in Sasl client state " + state);
        }
    } catch (SaslException e) {
        setState(State.FAILED);
        throw e;
    }
}
Also used : IllegalSaslStateException(org.apache.kafka.common.errors.IllegalSaslStateException) SaslException(javax.security.sasl.SaslException) NameCallback(javax.security.auth.callback.NameCallback) ScramExtensionsCallback(org.apache.kafka.common.security.scram.ScramExtensionsCallback) ServerFinalMessage(org.apache.kafka.common.security.scram.internals.ScramMessages.ServerFinalMessage) PasswordCallback(javax.security.auth.callback.PasswordCallback) ServerFirstMessage(org.apache.kafka.common.security.scram.internals.ScramMessages.ServerFirstMessage) UnsupportedCallbackException(javax.security.auth.callback.UnsupportedCallbackException)

Example 3 with ScramExtensionsCallback

use of org.apache.kafka.common.security.scram.ScramExtensionsCallback in project kafka by apache.

the class SaslClientCallbackHandler method handle.

@Override
public void handle(Callback[] callbacks) throws UnsupportedCallbackException {
    Subject subject = Subject.getSubject(AccessController.getContext());
    for (Callback callback : callbacks) {
        if (callback instanceof NameCallback) {
            NameCallback nc = (NameCallback) callback;
            if (subject != null && !subject.getPublicCredentials(String.class).isEmpty()) {
                nc.setName(subject.getPublicCredentials(String.class).iterator().next());
            } else
                nc.setName(nc.getDefaultName());
        } else if (callback instanceof PasswordCallback) {
            if (subject != null && !subject.getPrivateCredentials(String.class).isEmpty()) {
                char[] password = subject.getPrivateCredentials(String.class).iterator().next().toCharArray();
                ((PasswordCallback) callback).setPassword(password);
            } else {
                String errorMessage = "Could not login: the client is being asked for a password, but the Kafka" + " client code does not currently support obtaining a password from the user.";
                throw new UnsupportedCallbackException(callback, errorMessage);
            }
        } else if (callback instanceof RealmCallback) {
            RealmCallback rc = (RealmCallback) callback;
            rc.setText(rc.getDefaultText());
        } else if (callback instanceof AuthorizeCallback) {
            AuthorizeCallback ac = (AuthorizeCallback) callback;
            String authId = ac.getAuthenticationID();
            String authzId = ac.getAuthorizationID();
            ac.setAuthorized(authId.equals(authzId));
            if (ac.isAuthorized())
                ac.setAuthorizedID(authzId);
        } else if (callback instanceof ScramExtensionsCallback) {
            if (ScramMechanism.isScram(mechanism) && subject != null && !subject.getPublicCredentials(Map.class).isEmpty()) {
                @SuppressWarnings("unchecked") Map<String, String> extensions = (Map<String, String>) subject.getPublicCredentials(Map.class).iterator().next();
                ((ScramExtensionsCallback) callback).extensions(extensions);
            }
        } else if (callback instanceof SaslExtensionsCallback) {
            if (!SaslConfigs.GSSAPI_MECHANISM.equals(mechanism) && subject != null && !subject.getPublicCredentials(SaslExtensions.class).isEmpty()) {
                SaslExtensions extensions = subject.getPublicCredentials(SaslExtensions.class).iterator().next();
                ((SaslExtensionsCallback) callback).extensions(extensions);
            }
        } else {
            throw new UnsupportedCallbackException(callback, "Unrecognized SASL ClientCallback");
        }
    }
}
Also used : Subject(javax.security.auth.Subject) AuthorizeCallback(javax.security.sasl.AuthorizeCallback) SaslExtensionsCallback(org.apache.kafka.common.security.auth.SaslExtensionsCallback) RealmCallback(javax.security.sasl.RealmCallback) PasswordCallback(javax.security.auth.callback.PasswordCallback) ScramExtensionsCallback(org.apache.kafka.common.security.scram.ScramExtensionsCallback) SaslExtensionsCallback(org.apache.kafka.common.security.auth.SaslExtensionsCallback) NameCallback(javax.security.auth.callback.NameCallback) AuthorizeCallback(javax.security.sasl.AuthorizeCallback) Callback(javax.security.auth.callback.Callback) NameCallback(javax.security.auth.callback.NameCallback) ScramExtensionsCallback(org.apache.kafka.common.security.scram.ScramExtensionsCallback) SaslExtensions(org.apache.kafka.common.security.auth.SaslExtensions) PasswordCallback(javax.security.auth.callback.PasswordCallback) UnsupportedCallbackException(javax.security.auth.callback.UnsupportedCallbackException) Map(java.util.Map) RealmCallback(javax.security.sasl.RealmCallback)

Aggregations

NameCallback (javax.security.auth.callback.NameCallback)3 PasswordCallback (javax.security.auth.callback.PasswordCallback)3 UnsupportedCallbackException (javax.security.auth.callback.UnsupportedCallbackException)3 ScramExtensionsCallback (org.apache.kafka.common.security.scram.ScramExtensionsCallback)3 Map (java.util.Map)2 Callback (javax.security.auth.callback.Callback)2 AuthorizeCallback (javax.security.sasl.AuthorizeCallback)2 RealmCallback (javax.security.sasl.RealmCallback)2 Subject (javax.security.auth.Subject)1 SaslException (javax.security.sasl.SaslException)1 IllegalSaslStateException (org.apache.kafka.common.errors.IllegalSaslStateException)1 SaslExtensions (org.apache.kafka.common.security.auth.SaslExtensions)1 SaslExtensionsCallback (org.apache.kafka.common.security.auth.SaslExtensionsCallback)1 ServerFinalMessage (org.apache.kafka.common.security.scram.internals.ScramMessages.ServerFinalMessage)1 ServerFirstMessage (org.apache.kafka.common.security.scram.internals.ScramMessages.ServerFirstMessage)1