use of com.sun.jndi.ldap.LdapResult in project jdk8u_jdk by JetBrains.
the class LdapSasl method saslBind.
/**
* Performs SASL bind.
* Creates a SaslClient by using a default CallbackHandler
* that uses the Context.SECURITY_PRINCIPAL and Context.SECURITY_CREDENTIALS
* properties to satisfy the callbacks, and by using the
* SASL_AUTHZ_ID property as the authorization id. If the SASL_AUTHZ_ID
* property has not been set, Context.SECURITY_PRINCIPAL is used.
* If SASL_CALLBACK has been set, use that instead of the default
* CallbackHandler.
*<p>
* If bind is successful and the selected SASL mechanism has a security
* layer, set inStream and outStream to be filter streams that use
* the security layer. These will be used for subsequent communication
* with the server.
*<p>
* @param conn The non-null connection to use for sending an LDAP BIND
* @param server Non-null string name of host to connect to
* @param dn Non-null DN to bind as; also used as authentication ID
* @param pw Possibly null password; can be byte[], char[] or String
* @param authMech A non-null space-separated list of SASL authentication
* mechanisms.
* @param env The possibly null environment of the context, possibly containing
* properties for used by SASL mechanisms
* @param bindCtls The possibly null controls to accompany the bind
* @return LdapResult containing status of the bind
*/
@SuppressWarnings("unchecked")
public static LdapResult saslBind(LdapClient clnt, Connection conn, String server, String dn, Object pw, String authMech, Hashtable<?, ?> env, Control[] bindCtls) throws IOException, NamingException {
SaslClient saslClnt = null;
boolean cleanupHandler = false;
// Use supplied callback handler or create default
CallbackHandler cbh = (env != null) ? (CallbackHandler) env.get(SASL_CALLBACK) : null;
if (cbh == null) {
cbh = new DefaultCallbackHandler(dn, pw, (String) env.get(SASL_REALM));
cleanupHandler = true;
}
// Prepare parameters for creating SASL client
String authzId = (env != null) ? (String) env.get(SASL_AUTHZ_ID) : null;
String[] mechs = getSaslMechanismNames(authMech);
try {
// Create SASL client to use using SASL package
saslClnt = Sasl.createSaslClient(mechs, authzId, "ldap", server, (Hashtable<String, ?>) env, cbh);
if (saslClnt == null) {
throw new AuthenticationNotSupportedException(authMech);
}
LdapResult res;
String mechName = saslClnt.getMechanismName();
byte[] response = saslClnt.hasInitialResponse() ? saslClnt.evaluateChallenge(NO_BYTES) : null;
res = clnt.ldapBind(null, response, bindCtls, mechName, true);
while (!saslClnt.isComplete() && (res.status == LDAP_SASL_BIND_IN_PROGRESS || res.status == LDAP_SUCCESS)) {
response = saslClnt.evaluateChallenge(res.serverCreds != null ? res.serverCreds : NO_BYTES);
if (res.status == LDAP_SUCCESS) {
if (response != null) {
throw new AuthenticationException("SASL client generated response after success");
}
break;
}
res = clnt.ldapBind(null, response, bindCtls, mechName, true);
}
if (res.status == LDAP_SUCCESS) {
if (!saslClnt.isComplete()) {
throw new AuthenticationException("SASL authentication not complete despite server claims");
}
String qop = (String) saslClnt.getNegotiatedProperty(Sasl.QOP);
// If negotiated integrity or privacy,
if (qop != null && (qop.equalsIgnoreCase("auth-int") || qop.equalsIgnoreCase("auth-conf"))) {
InputStream newIn = new SaslInputStream(saslClnt, conn.inStream);
OutputStream newOut = new SaslOutputStream(saslClnt, conn.outStream);
conn.replaceStreams(newIn, newOut);
} else {
saslClnt.dispose();
}
}
return res;
} catch (SaslException e) {
NamingException ne = new AuthenticationException(authMech);
ne.setRootCause(e);
throw ne;
} finally {
if (cleanupHandler) {
((DefaultCallbackHandler) cbh).clearPassword();
}
}
}
Aggregations