in ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdapNetworkConnection.java [5094:5286]
public BindFuture bindSasl( SaslRequest saslRequest ) throws LdapException
{
// First switch to anonymous state
authenticated.set( false );
// try to connect, if we aren't already connected.
connect();
// If the session has not been establish, or is closed, we get out immediately
checkSession();
BindRequest bindRequest = createBindRequest( ( String ) null, null,
saslRequest.getSaslMechanism(), saslRequest.getControls() );
// Update the messageId
int newId = messageId.incrementAndGet();
bindRequest.setMessageId( newId );
if ( LOG.isDebugEnabled() )
{
LOG.debug( I18n.msg( I18n.MSG_04104_SENDING_REQUEST, bindRequest ) );
}
// Create a future for this Bind operation
BindFuture bindFuture = new BindFuture( this, newId );
// Store it in the future Map
addToFutureMap( newId, bindFuture );
try
{
BindResponse bindResponse;
byte[] response;
ResultCodeEnum result;
// Creating a map for SASL properties
Map<String, Object> properties = new HashMap<>();
// Quality of Protection SASL property
if ( saslRequest.getQualityOfProtection() != null )
{
properties.put( Sasl.QOP, saslRequest.getQualityOfProtection().getValue() );
}
// Security Strength SASL property
if ( saslRequest.getSecurityStrength() != null )
{
properties.put( Sasl.STRENGTH, saslRequest.getSecurityStrength().getValue() );
}
// Mutual Authentication SASL property
if ( saslRequest.isMutualAuthentication() )
{
properties.put( Sasl.SERVER_AUTH, "true" );
}
// Creating a SASL Client
SaslClient sc = Sasl.createSaslClient(
new String[]
{ bindRequest.getSaslMechanism() },
saslRequest.getAuthorizationId(),
"ldap",
config.getLdapHost(),
properties,
new SaslCallbackHandler( saslRequest ) );
// If the SaslClient wasn't created, that means we can't create the SASL client
// for the requested mechanism. We then produce an Exception
if ( sc == null )
{
String message = I18n.err( I18n.ERR_04158_CANNOT_FIND_SASL_FACTORY_FOR_MECH, bindRequest.getSaslMechanism() );
LOG.error( message );
throw new LdapException( message );
}
// Corner case : the SASL mech might send an initial challenge, and we have to
// deal with it immediately.
if ( sc.hasInitialResponse() )
{
byte[] challengeResponse = sc.evaluateChallenge( Strings.EMPTY_BYTES );
// Stores the challenge's response, and send it to the server
bindRequest.setCredentials( challengeResponse );
writeRequest( bindRequest );
// Get the server's response, blocking
bindResponse = bindFuture.get( connectTimeout, TimeUnit.MILLISECONDS );
if ( bindResponse == null )
{
// We didn't received anything : this is an error
if ( LOG.isErrorEnabled() )
{
LOG.error( I18n.err( I18n.ERR_04112_OP_FAILED_TIMEOUT, "Bind" ) );
}
throw new LdapException( TIME_OUT_ERROR );
}
result = bindResponse.getLdapResult().getResultCode();
}
else
{
// Copy the bindRequest without setting the credentials
BindRequest bindRequestCopy = new BindRequestImpl();
bindRequestCopy.setMessageId( newId );
bindRequestCopy.setName( bindRequest.getName() );
bindRequestCopy.setSaslMechanism( bindRequest.getSaslMechanism() );
bindRequestCopy.setSimple( bindRequest.isSimple() );
bindRequestCopy.setVersion3( bindRequest.getVersion3() );
bindRequestCopy.addAllControls( bindRequest.getControls().values().toArray( new Control[0] ) );
writeRequest( bindRequestCopy );
bindResponse = bindFuture.get( connectTimeout, TimeUnit.MILLISECONDS );
if ( bindResponse == null )
{
// We didn't received anything : this is an error
if ( LOG.isErrorEnabled() )
{
LOG.error( I18n.err( I18n.ERR_04112_OP_FAILED_TIMEOUT, "Bind" ) );
}
throw new LdapException( TIME_OUT_ERROR );
}
result = bindResponse.getLdapResult().getResultCode();
}
while ( !sc.isComplete()
&& ( ( result == ResultCodeEnum.SASL_BIND_IN_PROGRESS ) || ( result == ResultCodeEnum.SUCCESS ) ) )
{
response = sc.evaluateChallenge( bindResponse.getServerSaslCreds() );
if ( result == ResultCodeEnum.SUCCESS )
{
if ( response != null )
{
throw new LdapException( I18n.err( I18n.ERR_04159_PROTOCOL_ERROR ) );
}
}
else
{
newId = messageId.incrementAndGet();
bindRequest.setMessageId( newId );
bindRequest.setCredentials( response );
addToFutureMap( newId, bindFuture );
writeRequest( bindRequest );
bindResponse = bindFuture.get( connectTimeout, TimeUnit.MILLISECONDS );
if ( bindResponse == null )
{
// We didn't received anything : this is an error
if ( LOG.isErrorEnabled() )
{
LOG.error( I18n.err( I18n.ERR_04112_OP_FAILED_TIMEOUT, "Bind" ) );
}
throw new LdapException( TIME_OUT_ERROR );
}
result = bindResponse.getLdapResult().getResultCode();
}
}
/*
* Install the SASL filter when the SASL auth is complete.
* This adds the security layer if it was negotiated.
*/
if ( sc.isComplete() )
{
addSaslFilter( sc );
}
bindFuture.set( bindResponse );
return bindFuture;
}
catch ( LdapException e )
{
throw e;
}
catch ( Exception e )
{
LOG.error( e.getMessage() );
throw new LdapException( e );
}
}