use of javax.security.sasl.SaslException 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:");
try {
callbackHandler.handle(new Callback[] { nameCallback });
} catch (IOException | UnsupportedCallbackException e) {
throw new SaslException("User name could not be obtained", e);
}
String username = nameCallback.getName();
String saslName = formatter.saslName(username);
this.clientFirstMessage = new ScramMessages.ClientFirstMessage(saslName, clientNonce);
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 (IOException | UnsupportedCallbackException 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;
}
}
use of javax.security.sasl.SaslException in project kafka by apache.
the class ScramSaslServer method evaluateResponse.
@Override
public byte[] evaluateResponse(byte[] response) throws SaslException {
try {
switch(state) {
case RECEIVE_CLIENT_FIRST_MESSAGE:
this.clientFirstMessage = new ClientFirstMessage(response);
serverNonce = formatter.secureRandomString();
try {
String saslName = clientFirstMessage.saslName();
this.username = formatter.username(saslName);
NameCallback nameCallback = new NameCallback("username", username);
ScramCredentialCallback credentialCallback = new ScramCredentialCallback();
callbackHandler.handle(new Callback[] { nameCallback, credentialCallback });
this.scramCredential = credentialCallback.scramCredential();
if (scramCredential == null)
throw new SaslException("Authentication failed: Invalid user credentials");
if (scramCredential.iterations() < mechanism.minIterations())
throw new SaslException("Iterations " + scramCredential.iterations() + " is less than the minimum " + mechanism.minIterations() + " for " + mechanism);
this.serverFirstMessage = new ServerFirstMessage(clientFirstMessage.nonce(), serverNonce, scramCredential.salt(), scramCredential.iterations());
setState(State.RECEIVE_CLIENT_FINAL_MESSAGE);
return serverFirstMessage.toBytes();
} catch (IOException | NumberFormatException | UnsupportedCallbackException e) {
throw new SaslException("Authentication failed: Credentials could not be obtained", e);
}
case RECEIVE_CLIENT_FINAL_MESSAGE:
try {
ClientFinalMessage clientFinalMessage = new ClientFinalMessage(response);
verifyClientProof(clientFinalMessage);
byte[] serverKey = scramCredential.serverKey();
byte[] serverSignature = formatter.serverSignature(serverKey, clientFirstMessage, serverFirstMessage, clientFinalMessage);
ServerFinalMessage serverFinalMessage = new ServerFinalMessage(null, serverSignature);
setState(State.COMPLETE);
return serverFinalMessage.toBytes();
} catch (InvalidKeyException e) {
throw new SaslException("Authentication failed: Invalid client final message", e);
}
default:
throw new IllegalSaslStateException("Unexpected challenge in Sasl server state " + state);
}
} catch (SaslException e) {
setState(State.FAILED);
throw e;
}
}
use of javax.security.sasl.SaslException in project hbase by apache.
the class BlockingRpcConnection method handleSaslConnectionFailure.
/**
* If multiple clients with the same principal try to connect to the same server at the same time,
* the server assumes a replay attack is in progress. This is a feature of kerberos. In order to
* work around this, what is done is that the client backs off randomly and tries to initiate the
* connection again. The other problem is to do with ticket expiry. To handle that, a relogin is
* attempted.
* <p>
* The retry logic is governed by the {@link #shouldAuthenticateOverKrb} method. In case when the
* user doesn't have valid credentials, we don't need to retry (from cache or ticket). In such
* cases, it is prudent to throw a runtime exception when we receive a SaslException from the
* underlying authentication implementation, so there is no retry from other high level (for eg,
* HCM or HBaseAdmin).
* </p>
*/
private void handleSaslConnectionFailure(final int currRetries, final int maxRetries, final Exception ex, final UserGroupInformation user) throws IOException, InterruptedException {
closeSocket();
user.doAs(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws IOException, InterruptedException {
if (shouldAuthenticateOverKrb()) {
if (currRetries < maxRetries) {
if (LOG.isDebugEnabled()) {
LOG.debug("Exception encountered while connecting to " + "the server : " + ex);
}
// try re-login
relogin();
disposeSasl();
// have granularity of milliseconds
// we are sleeping with the Connection lock held but since this
// connection instance is being used for connecting to the server
// in question, it is okay
Thread.sleep(ThreadLocalRandom.current().nextInt(reloginMaxBackoff) + 1);
return null;
} else {
String msg = "Couldn't setup connection for " + UserGroupInformation.getLoginUser().getUserName() + " to " + serverPrincipal;
LOG.warn(msg, ex);
throw (IOException) new IOException(msg).initCause(ex);
}
} else {
LOG.warn("Exception encountered while connecting to " + "the server : " + ex);
}
if (ex instanceof RemoteException) {
throw (RemoteException) ex;
}
if (ex instanceof SaslException) {
String msg = "SASL authentication failed." + " The most likely cause is missing or invalid credentials." + " Consider 'kinit'.";
LOG.fatal(msg, ex);
throw new RuntimeException(msg, ex);
}
throw new IOException(ex);
}
});
}
use of javax.security.sasl.SaslException in project hbase by apache.
the class CryptoAES method wrap.
/**
* Encrypts input data. The result composes of (msg, padding if needed, mac) and sequence num.
* @param data the input byte array
* @param offset the offset in input where the input starts
* @param len the input length
* @return the new encrypted byte array.
* @throws SaslException if error happens
*/
public byte[] wrap(byte[] data, int offset, int len) throws SaslException {
// mac
byte[] mac = integrity.getHMAC(data, offset, len);
integrity.incMySeqNum();
// encrypt
byte[] encrypted = new byte[len + 10];
try {
int n = encryptor.update(data, offset, len, encrypted, 0);
encryptor.update(mac, 0, 10, encrypted, n);
} catch (ShortBufferException sbe) {
// this should not happen
throw new SaslException("Error happens during encrypt data", sbe);
}
// append seqNum used for mac
byte[] wrapped = new byte[encrypted.length + 4];
System.arraycopy(encrypted, 0, wrapped, 0, encrypted.length);
System.arraycopy(integrity.getSeqNum(), 0, wrapped, encrypted.length, 4);
return wrapped;
}
use of javax.security.sasl.SaslException in project hbase by apache.
the class CryptoAES method unwrap.
/**
* Decrypts input data. The input composes of (msg, padding if needed, mac) and sequence num.
* The result is msg.
* @param data the input byte array
* @param offset the offset in input where the input starts
* @param len the input length
* @return the new decrypted byte array.
* @throws SaslException if error happens
*/
public byte[] unwrap(byte[] data, int offset, int len) throws SaslException {
// get plaintext and seqNum
byte[] decrypted = new byte[len - 4];
byte[] peerSeqNum = new byte[4];
try {
decryptor.update(data, offset, len - 4, decrypted, 0);
} catch (ShortBufferException sbe) {
// this should not happen
throw new SaslException("Error happens during decrypt data", sbe);
}
System.arraycopy(data, offset + decrypted.length, peerSeqNum, 0, 4);
// get msg and mac
byte[] msg = new byte[decrypted.length - 10];
byte[] mac = new byte[10];
System.arraycopy(decrypted, 0, msg, 0, msg.length);
System.arraycopy(decrypted, msg.length, mac, 0, 10);
// check mac integrity and msg sequence
if (!integrity.compareHMAC(mac, peerSeqNum, msg, 0, msg.length)) {
throw new SaslException("Unmatched MAC");
}
if (!integrity.comparePeerSeqNum(peerSeqNum)) {
throw new SaslException("Out of order sequencing of messages. Got: " + integrity.byteToInt(peerSeqNum) + " Expected: " + integrity.peerSeqNum);
}
integrity.incPeerSeqNum();
return msg;
}
Aggregations