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