You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2008/08/05 00:38:09 UTC
svn commit: r682532 - in /directory/apacheds/branches/bigbang:
protocol-newldap/src/main/java/org/apache/directory/server/newldap/
protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/
protocol-newldap/src/main/java/org/apache/di...
Author: elecharny
Date: Mon Aug 4 15:38:08 2008
New Revision: 682532
URL: http://svn.apache.org/viewvc?rev=682532&view=rev
Log:
Fixed DIGEST-MD5
Modified:
directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/LdapSession.java
directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/NewBindHandler.java
directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/AbstractSaslCallbackHandler.java
directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/SaslConstants.java
directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/SaslFilter.java
directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/cramMD5/CramMd5CallbackHandler.java
directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/cramMD5/CramMd5MechanismHandler.java
directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/digestMD5/DigestMd5CallbackHandler.java
directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/digestMD5/DigestMd5MechanismHandler.java
directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/ntlm/NtlmMechanismHandler.java
directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/ntlm/NtlmSaslServer.java
directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/plain/PlainMechanismHandler.java
directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/plain/PlainSaslServer.java
directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/SaslBindITest.java
directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/operations/bind/SaslBindITest.java
Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/LdapSession.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/LdapSession.java?rev=682532&r1=682531&r2=682532&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/LdapSession.java (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/LdapSession.java Mon Aug 4 15:38:08 2008
@@ -308,27 +308,39 @@
/**
- * @return The SASL properties
- */
- public Map<String, Object> getSaslProperties()
- {
- return saslProperties;
- }
-
-
- /**
* Add a Sasl property and value
*
* @param property the property to add
* @param value the value for this property
*/
- public void putSaslProperties( String property, Object value )
+ public void putSaslProperty( String property, Object value )
{
saslProperties.put( property, value );
}
/**
+ * Get a Sasl property's value
+ *
+ * @param property the property to get
+ * @return the associated value, or null if we don't have such a property
+ */
+ public Object getSaslProperty( String property )
+ {
+ return saslProperties.get( property );
+ }
+
+
+ /**
+ * Clear all the Sasl values stored into the Map
+ */
+ public void clearSaslProperties()
+ {
+ saslProperties.clear();
+ }
+
+
+ /**
* Remove a property from the SaslProperty map
*
* @param property the property to remove
Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/NewBindHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/NewBindHandler.java?rev=682532&r1=682531&r2=682532&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/NewBindHandler.java (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/NewBindHandler.java Mon Aug 4 15:38:08 2008
@@ -42,8 +42,10 @@
import org.apache.directory.server.newldap.LdapSession;
import org.apache.directory.server.newldap.handlers.bind.MechanismHandler;
import org.apache.directory.server.newldap.handlers.bind.SaslConstants;
+import org.apache.directory.server.newldap.handlers.bind.SaslFilter;
import org.apache.directory.server.protocol.shared.ServiceConfigurationException;
import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.constants.SupportedSaslMechanisms;
import org.apache.directory.shared.ldap.exception.LdapAuthenticationException;
import org.apache.directory.shared.ldap.exception.LdapException;
import org.apache.directory.shared.ldap.message.BindRequest;
@@ -53,6 +55,8 @@
import org.apache.directory.shared.ldap.name.LdapDN;
import org.apache.directory.shared.ldap.util.ExceptionUtils;
import org.apache.directory.shared.ldap.util.StringTools;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -207,6 +211,13 @@
}
+ /**
+ * For challenge/response exchange, generate the challenge
+ *
+ * @param ldapSession
+ * @param ss
+ * @param bindRequest
+ */
private void generateSaslChallenge( LdapSession ldapSession, SaslServer ss, BindRequest bindRequest )
{
LdapResult result = bindRequest.getResultResponse().getLdapResult();
@@ -232,7 +243,7 @@
* so it will be returned in a SUCCESS message, after an LdapContext
* has been initialized for the client.
*/
- ldapSession.getSaslProperties().put( SaslConstants.SASL_CREDS, tokenBytes );
+ ldapSession.putSaslProperty( SaslConstants.SASL_CREDS, tokenBytes );
}
// Return the successful response
@@ -254,7 +265,7 @@
ldapSession.setAuthPending();
// Store the current mechanism, as the C/R is not finished
- ldapSession.getSaslProperties().put( SaslConstants.SASL_MECH, bindRequest.getSaslMechanism() );
+ ldapSession.putSaslProperty( SaslConstants.SASL_MECH, bindRequest.getSaslMechanism() );
// And write back the response
ldapSession.getIoSession().write( resp );
@@ -268,7 +279,7 @@
result.setErrorMessage( se.getMessage() );
// Reinitialize the state to Anonymous and clear the sasl properties
- ldapSession.getSaslProperties().clear();
+ ldapSession.clearSaslProperties();
ldapSession.setAnonymous();
// Write back the error response
@@ -277,11 +288,14 @@
}
+ /**
+ * Send back an AUTH-METH-NOT-SUPPORTED error message to the client
+ */
private void sendAuthMethNotSupported( LdapSession ldapSession, BindRequest bindRequest )
{
// First, reinit the state to Anonymous, and clear the
// saslProperty map
- ldapSession.getSaslProperties().clear();
+ ldapSession.clearSaslProperties();
ldapSession.setAnonymous();
// And send the response to the client
@@ -296,16 +310,27 @@
}
- private void sendInvalidCredentials( LdapSession ldapSession, BindRequest bindRequest, SaslException se )
+ /**
+ * Send back an INVALID-CREDENTIAL error message to the user. If we have an exception
+ * as a third argument, then send back the associated message to the client.
+ */
+ private void sendInvalidCredentials( LdapSession ldapSession, BindRequest bindRequest, Exception e )
{
LdapResult result = bindRequest.getResultResponse().getLdapResult();
- LOG.error( se.getMessage() );
+ String message = "";
+
+ if ( e != null )
+ {
+ message = e.getMessage();
+ }
+
+ LOG.error( message );
result.setResultCode( ResultCodeEnum.INVALID_CREDENTIALS );
- result.setErrorMessage( se.getMessage() );
+ result.setErrorMessage( message );
// Reinitialize the state to Anonymous and clear the sasl properties
- ldapSession.getSaslProperties().clear();
+ ldapSession.clearSaslProperties();
ldapSession.setAnonymous();
// Write back the error response
@@ -313,6 +338,9 @@
}
+ /**
+ * Send a SUCCESS message back to the client.
+ */
private void sendBindSuccess( LdapSession ldapSession, BindRequest bindRequest, byte[] tokenBytes )
{
// Return the successful response
@@ -332,7 +360,12 @@
}
// Clean the SaslProperties, we don't need them anymore
- ldapSession.getSaslProperties().clear();
+ // except the saslCreds and saslServer which will be used
+ // by the DIGEST-MD5 mech.
+ ldapSession.removeSaslProperty( SaslConstants.SASL_MECH );
+ ldapSession.removeSaslProperty( SaslConstants.SASL_HOST );
+ ldapSession.removeSaslProperty( SaslConstants.SASL_AUTHENT_USER );
+ ldapSession.removeSaslProperty( SaslConstants.SASL_USER_BASE_DN );
ldapSession.getIoSession().write( response );
@@ -345,7 +378,7 @@
// First, check that we have the same mechanism
String saslMechanism = bindRequest.getSaslMechanism();
- if ( !ldapSession.getSaslProperties().get( SaslConstants.SASL_MECH ).equals( saslMechanism ) )
+ if ( !ldapSession.getSaslProperty( SaslConstants.SASL_MECH ).equals( saslMechanism ) )
{
sendAuthMethNotSupported( ldapSession, bindRequest );
return;
@@ -384,13 +417,13 @@
* so it will be returned in a SUCCESS message, after an LdapContext
* has been initialized for the client.
*/
- ldapSession.getSaslProperties().put( SaslConstants.SASL_CREDS, tokenBytes );
+ ldapSession.putSaslProperty( SaslConstants.SASL_CREDS, tokenBytes );
}
// Create the user's coreSession
try
{
- ServerEntry userEntry = (ServerEntry)ldapSession.getSaslProperties().get( SaslConstants.SASL_AUTHENT_USER );
+ ServerEntry userEntry = (ServerEntry)ldapSession.getSaslProperty( SaslConstants.SASL_AUTHENT_USER );
CoreSession userSession = ds.getSession( userEntry.getDn(), userEntry.get( SchemaConstants.USER_PASSWORD_AT ).getBytes(), saslMechanism, null );
@@ -399,10 +432,30 @@
// Mark the user as authenticated
ldapSession.setAuthenticated();
- // Clean the Sasl Properties so that we don't have the user password
- // stored in memory forever
- ldapSession.getSaslProperties().clear();
-
+ /*
+ * If the SASL mechanism is DIGEST-MD5 or GSSAPI, we insert a SASLFilter.
+ */
+ if ( saslMechanism.equals( SupportedSaslMechanisms.DIGEST_MD5 ) ||
+ saslMechanism.equals( SupportedSaslMechanisms.GSSAPI ) )
+ {
+ LOG.debug( "Inserting SaslFilter to engage negotiated security layer." );
+ IoSession ioSession = ldapSession.getIoSession();
+
+ IoFilterChain chain = ioSession.getFilterChain();
+
+ if ( !chain.contains( "SASL_FILTER" ) )
+ {
+ SaslServer saslServer = ( SaslServer ) ldapSession.getSaslProperty( SaslConstants.SASL_SERVER );
+ chain.addBefore( "codec", "SASL_FILTER", new SaslFilter( saslServer ) );
+ }
+
+ /*
+ * We disable the SASL security layer once, to write the outbound SUCCESS
+ * message without SASL security layer processing.
+ */
+ ioSession.setAttribute( SaslFilter.DISABLE_SECURITY_LAYER_ONCE, Boolean.TRUE );
+ }
+
// And send a Success response
sendBindSuccess( ldapSession, bindRequest, tokenBytes );
}
@@ -457,7 +510,7 @@
ldapSession.setAnonymous();
// Clean the sasl properties
- ldapSession.getSaslProperties().clear();
+ ldapSession.clearSaslProperties();
// Now we can continue as if the client was Anonymous from the beginning
}
@@ -477,8 +530,13 @@
}
// Store the mechanism in the ldap session
- ldapSession.getSaslProperties().put( SaslConstants.SASL_MECH, saslMechanism );
+ ldapSession.putSaslProperty( SaslConstants.SASL_MECH, saslMechanism );
+
+ // Store the host in the ldap session
+ String saslHost = getLdapServer().getSaslHost();
+ ldapSession.putSaslProperty( SaslConstants.SASL_HOST, saslHost );
+
// Get the handler for this mechanism
MechanismHandler mechanismHandler = handlers.get( saslMechanism );
Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/AbstractSaslCallbackHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/AbstractSaslCallbackHandler.java?rev=682532&r1=682531&r2=682532&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/AbstractSaslCallbackHandler.java (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/AbstractSaslCallbackHandler.java Mon Aug 4 15:38:08 2008
@@ -21,7 +21,9 @@
import org.apache.directory.server.constants.ServerDNConstants;
+import org.apache.directory.server.core.CoreSession;
import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.newldap.LdapSession;
import org.apache.directory.shared.ldap.constants.AuthenticationLevel;
import org.apache.directory.shared.ldap.entry.EntryAttribute;
import org.apache.directory.shared.ldap.exception.LdapException;
@@ -67,7 +69,13 @@
private String username;
private String realm;
+
+ /** The reference on the user ldap session */
+ protected LdapSession ldapSession;
+ /** The admin core session */
+ protected CoreSession adminSession;
+
/** A reference on the DirectoryService instance */
protected final DirectoryService directoryService;
Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/SaslConstants.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/SaslConstants.java?rev=682532&r1=682531&r2=682532&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/SaslConstants.java (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/SaslConstants.java Mon Aug 4 15:38:08 2008
@@ -67,4 +67,22 @@
* A key constant for storing the evaluated credentials
*/
public static final String SASL_CREDS = "saslCreds";
+
+
+ /**
+ * A key constant for storing the Quality Of Protection
+ */
+ public static final String SASL_QOP = "saslQop";
+
+
+ /**
+ * A key constant for storing the realm
+ */
+ public static final String SASL_REALM = "saslRealm";
+
+
+ /**
+ * A key constant representing the SASL IoFilter
+ */
+ public static final String SASL_FILTER = "SASL_FILTER";
}
Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/SaslFilter.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/SaslFilter.java?rev=682532&r1=682531&r2=682532&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/SaslFilter.java (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/SaslFilter.java Mon Aug 4 15:38:08 2008
@@ -58,7 +58,7 @@
*/
public static final String DISABLE_SECURITY_LAYER_ONCE = SaslFilter.class.getName() + ".DisableSecurityLayerOnce";
- private SaslServer context;
+ private SaslServer saslServer;
/**
@@ -69,14 +69,14 @@
*
* @param context The initialized SASL context.
*/
- public SaslFilter( SaslServer context )
+ public SaslFilter( SaslServer saslServer )
{
- if ( context == null )
+ if ( saslServer == null )
{
throw new IllegalStateException();
}
- this.context = context;
+ this.saslServer = saslServer;
}
@@ -87,7 +87,7 @@
/*
* Unwrap the data for mechanisms that support QoP (DIGEST-MD5, GSSAPI).
*/
- String qop = ( String ) context.getNegotiatedProperty( Sasl.QOP );
+ String qop = ( String ) saslServer.getNegotiatedProperty( Sasl.QOP );
boolean hasSecurityLayer = ( qop != null && ( qop.equals( SaslQoP.QOP_AUTH_INT ) || qop.equals( SaslQoP.QOP_AUTH_CONF ) ) );
if ( hasSecurityLayer )
@@ -101,7 +101,7 @@
buf.get( bufferBytes );
log.debug( "Will use SASL to unwrap received message of length: {}", bufferLength );
- byte[] token = context.unwrap( bufferBytes, 0, bufferBytes.length );
+ byte[] token = saslServer.unwrap( bufferBytes, 0, bufferBytes.length );
nextFilter.messageReceived( session, ByteBuffer.wrap( token ) );
}
else
@@ -131,7 +131,7 @@
/*
* Wrap the data for mechanisms that support QoP (DIGEST-MD5, GSSAPI).
*/
- String qop = ( String ) context.getNegotiatedProperty( Sasl.QOP );
+ String qop = ( String ) saslServer.getNegotiatedProperty( Sasl.QOP );
boolean hasSecurityLayer = ( qop != null && ( qop.equals( SaslQoP.QOP_AUTH_INT ) || qop.equals( SaslQoP.QOP_AUTH_CONF ) ) );
ByteBuffer saslLayerBuffer = null;
@@ -148,7 +148,7 @@
log.debug( "Will use SASL to wrap message of length: {}", bufferLength );
- byte[] saslLayer = context.wrap( bufferBytes, 0, bufferBytes.length );
+ byte[] saslLayer = saslServer.wrap( bufferBytes, 0, bufferBytes.length );
/*
* Prepend 4 byte length.
Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/cramMD5/CramMd5CallbackHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/cramMD5/CramMd5CallbackHandler.java?rev=682532&r1=682531&r2=682532&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/cramMD5/CramMd5CallbackHandler.java (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/cramMD5/CramMd5CallbackHandler.java Mon Aug 4 15:38:08 2008
@@ -55,10 +55,6 @@
{
private static final Logger LOG = LoggerFactory.getLogger( CramMd5CallbackHandler.class );
- private LdapSession ldapSession;
-
- private CoreSession adminSession;
-
private String bindDn;
//private String userPassword;
@@ -87,7 +83,7 @@
AttributeType passwordAT = adminSession.getDirectoryService().getRegistries().getAttributeTypeRegistry().lookup( SchemaConstants.USER_PASSWORD_AT );
returningAttributes.add( new AttributeTypeOptions( passwordAT) );
- bindDn = (String)ldapSession.getSaslProperties().get( SaslConstants.SASL_USER_BASE_DN );
+ bindDn = (String)ldapSession.getSaslProperty( SaslConstants.SASL_USER_BASE_DN );
LdapDN baseDn = new LdapDN( bindDn );
@@ -105,7 +101,7 @@
while ( cursor.next() )
{
entry = cursor.get();
- ldapSession.getSaslProperties().put( SaslConstants.SASL_AUTHENT_USER, entry );
+ ldapSession.putSaslProperty( SaslConstants.SASL_AUTHENT_USER, entry );
}
return entry.get( passwordAT );
@@ -124,7 +120,7 @@
LOG.debug( "Converted username " + getUsername() + " to DN " + bindDn );
}
- ldapSession.getSaslProperties().put( Context.SECURITY_PRINCIPAL, bindDn );
+ ldapSession.putSaslProperty( Context.SECURITY_PRINCIPAL, bindDn );
authorizeCB.setAuthorizedID( bindDn );
authorizeCB.setAuthorized( true );
Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/cramMD5/CramMd5MechanismHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/cramMD5/CramMd5MechanismHandler.java?rev=682532&r1=682531&r2=682532&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/cramMD5/CramMd5MechanismHandler.java (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/cramMD5/CramMd5MechanismHandler.java Mon Aug 4 15:38:08 2008
@@ -21,6 +21,7 @@
import org.apache.directory.server.core.CoreSession;
+import org.apache.directory.server.newldap.LdapServer;
import org.apache.directory.server.newldap.LdapSession;
import org.apache.directory.server.newldap.handlers.bind.MechanismHandler;
import org.apache.directory.server.newldap.handlers.bind.SaslConstants;
@@ -45,22 +46,21 @@
{
public SaslServer handleMechanism( LdapSession ldapSession, CoreSession adminSession, BindRequest bindRequest ) throws Exception
{
- SaslServer ss = (SaslServer)ldapSession.getSaslProperties().get( SaslConstants.SASL_SERVER );
+ SaslServer ss = (SaslServer)ldapSession.getSaslProperty( SaslConstants.SASL_SERVER );
// TODO - don't use session properties anymore
if ( ss == null )
{
String saslHost = ldapSession.getLdapServer().getSaslHost();
String userBaseDn = ldapSession.getLdapServer().getSearchBaseDn();
- ldapSession.getSaslProperties().put( SaslConstants.SASL_HOST, saslHost );
- ldapSession.getSaslProperties().put( SaslConstants.SASL_USER_BASE_DN, userBaseDn );
-
-
+ ldapSession.putSaslProperty( SaslConstants.SASL_HOST, saslHost );
+ ldapSession.putSaslProperty( SaslConstants.SASL_USER_BASE_DN, userBaseDn );
Map<String, String> saslProps = new HashMap<String, String>();
+
CallbackHandler callbackHandler = new CramMd5CallbackHandler( ldapSession, adminSession, bindRequest );
ss = Sasl.createSaslServer( SupportedSaslMechanisms.CRAM_MD5, SaslConstants.LDAP_PROTOCOL, saslHost, saslProps, callbackHandler );
- ldapSession.putSaslProperties( SaslConstants.SASL_SERVER, ss );
+ ldapSession.putSaslProperty( SaslConstants.SASL_SERVER, ss );
}
return ss;
Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/digestMD5/DigestMd5CallbackHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/digestMD5/DigestMd5CallbackHandler.java?rev=682532&r1=682531&r2=682532&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/digestMD5/DigestMd5CallbackHandler.java (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/digestMD5/DigestMd5CallbackHandler.java Mon Aug 4 15:38:08 2008
@@ -20,11 +20,25 @@
package org.apache.directory.server.newldap.handlers.bind.digestMD5;
-import org.apache.directory.server.core.DirectoryService;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.directory.server.core.CoreSession;
+import org.apache.directory.server.core.entry.ClonedServerEntry;
+import org.apache.directory.server.core.filtering.EntryFilteringCursor;
+import org.apache.directory.server.newldap.LdapSession;
import org.apache.directory.server.newldap.handlers.bind.AbstractSaslCallbackHandler;
-import org.apache.directory.shared.ldap.NotImplementedException;
+import org.apache.directory.server.newldap.handlers.bind.SaslConstants;
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
import org.apache.directory.shared.ldap.entry.EntryAttribute;
+import org.apache.directory.shared.ldap.filter.ExprNode;
+import org.apache.directory.shared.ldap.filter.FilterParser;
+import org.apache.directory.shared.ldap.filter.SearchScope;
+import org.apache.directory.shared.ldap.message.AliasDerefMode;
import org.apache.directory.shared.ldap.message.BindRequest;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.shared.ldap.schema.AttributeType;
+import org.apache.directory.shared.ldap.schema.AttributeTypeOptions;
import org.apache.mina.common.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -54,17 +68,51 @@
* @param bindRequest the bind message
* @param directoryService the directory service core
*/
- public DigestMd5CallbackHandler( DirectoryService directoryService, BindRequest bindRequest )
+ public DigestMd5CallbackHandler( LdapSession ldapSession, CoreSession adminSession, BindRequest bindRequest )
{
- super( directoryService, bindRequest );
+ super( adminSession.getDirectoryService(), bindRequest );
+ this.ldapSession = ldapSession;
+ this.adminSession = adminSession;
}
// TODO - should return not be a byte[]
protected EntryAttribute lookupPassword( String username, String realm )
{
- // TODO - Use realm with multi-realm support.
- throw new NotImplementedException();
+ try
+ {
+ ExprNode filter = FilterParser.parse( "(uid=" + username + ")" );
+ Set<AttributeTypeOptions> returningAttributes = new HashSet<AttributeTypeOptions>();
+
+ AttributeType passwordAT = adminSession.getDirectoryService().getRegistries().getAttributeTypeRegistry().lookup( SchemaConstants.USER_PASSWORD_AT );
+ returningAttributes.add( new AttributeTypeOptions( passwordAT) );
+ bindDn = (String)ldapSession.getSaslProperty( SaslConstants.SASL_USER_BASE_DN );
+
+ LdapDN baseDn = new LdapDN( bindDn );
+
+ EntryFilteringCursor cursor = adminSession.search(
+ baseDn,
+ SearchScope.SUBTREE,
+ filter,
+ AliasDerefMode.DEREF_ALWAYS,
+ returningAttributes );
+
+ cursor.beforeFirst();
+
+ ClonedServerEntry entry = null;
+
+ while ( cursor.next() )
+ {
+ entry = cursor.get();
+ ldapSession.putSaslProperty( SaslConstants.SASL_AUTHENT_USER, entry );
+ }
+
+ return entry.get( passwordAT );
+ }
+ catch ( Exception e )
+ {
+ return null;
+ }
}
@@ -75,7 +123,7 @@
LOG.debug( "Converted username " + getUsername() + " to DN " + bindDn + " with password " + userPassword + "." );
}
- session.setAttribute( Context.SECURITY_PRINCIPAL, bindDn );
+ ldapSession.putSaslProperty( Context.SECURITY_PRINCIPAL, bindDn );
authorizeCB.setAuthorizedID( bindDn );
authorizeCB.setAuthorized( true );
Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/digestMD5/DigestMd5MechanismHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/digestMD5/DigestMd5MechanismHandler.java?rev=682532&r1=682531&r2=682532&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/digestMD5/DigestMd5MechanismHandler.java (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/digestMD5/DigestMd5MechanismHandler.java Mon Aug 4 15:38:08 2008
@@ -21,6 +21,7 @@
import org.apache.directory.server.core.CoreSession;
+import org.apache.directory.server.newldap.LdapServer;
import org.apache.directory.server.newldap.LdapSession;
import org.apache.directory.server.newldap.handlers.bind.MechanismHandler;
import org.apache.directory.server.newldap.handlers.bind.SaslConstants;
@@ -30,6 +31,8 @@
import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslServer;
+
+import java.util.HashMap;
import java.util.Map;
@@ -42,24 +45,55 @@
*/
public class DigestMd5MechanismHandler implements MechanismHandler
{
- public SaslServer handleMechanism( LdapSession session, CoreSession adminSession, BindRequest bindRequest ) throws Exception
+ /**
+ * Create a list of all the configured realms.
+ *
+ * @param ldapServer the LdapServer for which we want to get the realms
+ * @return a list of realms, separated by spaces
+ */
+ private String getActiveRealms( LdapServer ldapServer )
{
- SaslServer ss;
+ StringBuilder realms = new StringBuilder();
+ boolean isFirst = true;
- if ( session.getIoSession().containsAttribute( SaslConstants.SASL_SERVER ) )
+ for ( String realm:ldapServer.getSaslRealms() )
{
- ss = ( SaslServer ) session.getIoSession().getAttribute( SaslConstants.SASL_SERVER );
+ if ( isFirst )
+ {
+ isFirst = false;
+ }
+ else
+ {
+ realms.append( ' ' );
+ }
+
+ realms.append( realm );
}
- else
+
+ return realms.toString();
+ }
+
+
+
+ public SaslServer handleMechanism( LdapSession ldapSession, CoreSession adminSession, BindRequest bindRequest ) throws Exception
+ {
+ SaslServer ss = (SaslServer)ldapSession.getSaslProperty( SaslConstants.SASL_SERVER );
+
+ if ( ss == null )
{
- String saslHost = ( String ) session.getIoSession().getAttribute( "saslHost" );
- Map<String, String> saslProps = ( Map<String, String> ) session.getIoSession().getAttribute( "saslProps" );
+ String saslHost = ldapSession.getLdapServer().getSaslHost();
+ String userBaseDn = ldapSession.getLdapServer().getSearchBaseDn();
+ ldapSession.putSaslProperty( SaslConstants.SASL_HOST, saslHost );
+ ldapSession.putSaslProperty( SaslConstants.SASL_USER_BASE_DN, userBaseDn );
+
+ Map<String, String> saslProps = new HashMap<String, String>();
+ saslProps.put( Sasl.QOP, ldapSession.getLdapServer().getSaslQopString() );
+ saslProps.put( "com.sun.security.sasl.digest.realm", getActiveRealms( ldapSession.getLdapServer() ) );
- CallbackHandler callbackHandler = new DigestMd5CallbackHandler(
- session.getCoreSession().getDirectoryService(), bindRequest );
+ CallbackHandler callbackHandler = new DigestMd5CallbackHandler( ldapSession, adminSession, bindRequest );
ss = Sasl.createSaslServer( SupportedSaslMechanisms.DIGEST_MD5, SaslConstants.LDAP_PROTOCOL, saslHost, saslProps, callbackHandler );
- session.getIoSession().setAttribute( SaslConstants.SASL_SERVER, ss );
+ ldapSession.putSaslProperty( SaslConstants.SASL_SERVER, ss );
}
return ss;
Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/ntlm/NtlmMechanismHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/ntlm/NtlmMechanismHandler.java?rev=682532&r1=682531&r2=682532&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/ntlm/NtlmMechanismHandler.java (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/ntlm/NtlmMechanismHandler.java Mon Aug 4 15:38:08 2008
@@ -58,13 +58,9 @@
public SaslServer handleMechanism( LdapSession ldapSession, CoreSession adminSession, BindRequest bindRequest ) throws Exception
{
- SaslServer ss;
+ SaslServer ss = ( SaslServer ) ldapSession.getSaslProperty( SaslConstants.SASL_SERVER );
- if ( ldapSession.getIoSession().containsAttribute( SaslConstants.SASL_SERVER ) )
- {
- ss = ( SaslServer ) ldapSession.getIoSession().getAttribute( SaslConstants.SASL_SERVER );
- }
- else
+ if ( ss == null )
{
if ( provider == null )
{
@@ -72,7 +68,7 @@
}
ss = new NtlmSaslServer( provider, bindRequest, ldapSession );
- ldapSession.getIoSession().setAttribute( SaslConstants.SASL_SERVER, ss );
+ ldapSession.putSaslProperty( SaslConstants.SASL_SERVER, ss );
}
return ss;
Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/ntlm/NtlmSaslServer.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/ntlm/NtlmSaslServer.java?rev=682532&r1=682531&r2=682532&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/ntlm/NtlmSaslServer.java (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/ntlm/NtlmSaslServer.java Mon Aug 4 15:38:08 2008
@@ -39,8 +39,10 @@
*/
public class NtlmSaslServer extends AbstractSaslServer
{
+ /** The different states during a NTLM negotiation */
enum NegotiationState { INITIALIZED, TYPE_1_RECEIVED, TYPE_2_SENT, TYPE_3_RECEIVED, COMPLETED }
+ /** The current state */
private NegotiationState state = NegotiationState.INITIALIZED;
private final NtlmProvider provider;
@@ -68,13 +70,17 @@
case INITIALIZED:
state = NegotiationState.TYPE_1_RECEIVED;
break;
+
case TYPE_1_RECEIVED:
throw new IllegalStateException( "Cannot receive NTLM message before sending Type 2 challenge." );
+
case TYPE_2_SENT:
state = NegotiationState.TYPE_3_RECEIVED;
break;
+
case TYPE_3_RECEIVED:
throw new IllegalStateException( "Cannot receive NTLM message after Type 3 has been received." );
+
case COMPLETED:
throw new IllegalStateException( "Sasl challenge response already completed." );
}
@@ -87,14 +93,18 @@
{
case INITIALIZED:
throw new IllegalStateException( "Cannot send Type 2 challenge before Type 1 response." );
+
case TYPE_1_RECEIVED:
state = NegotiationState.TYPE_2_SENT;
break;
+
case TYPE_2_SENT:
throw new IllegalStateException( "Cannot send Type 2 after it's already sent." );
+
case TYPE_3_RECEIVED:
state = NegotiationState.COMPLETED;
break;
+
case COMPLETED:
throw new IllegalStateException( "Sasl challenge response already completed." );
}
@@ -130,7 +140,9 @@
{
throw new SaslException( "There was a failure during NTLM Type 1 message handling.", e );
}
+
break;
+
case TYPE_3_RECEIVED:
boolean result;
try
@@ -147,8 +159,10 @@
{
throw new SaslException( "Authentication occurred but the credentials were invalid." );
}
+
break;
- }
+ }
+
responseSent();
return retval;
}
Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/plain/PlainMechanismHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/plain/PlainMechanismHandler.java?rev=682532&r1=682531&r2=682532&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/plain/PlainMechanismHandler.java (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/plain/PlainMechanismHandler.java Mon Aug 4 15:38:08 2008
@@ -44,13 +44,13 @@
*/
public SaslServer handleMechanism( LdapSession ldapSession, CoreSession adminSession, BindRequest bindRequest ) throws Exception
{
- SaslServer ss = ( SaslServer ) ldapSession.getSaslProperties().get( SaslConstants.SASL_SERVER );
+ SaslServer ss = ( SaslServer ) ldapSession.getSaslProperty( SaslConstants.SASL_SERVER );
if ( ss == null )
{
ss = new PlainSaslServer( ldapSession, adminSession, bindRequest );
- ldapSession.getSaslProperties().put( SaslConstants.SASL_SERVER, ss );
+ ldapSession.putSaslProperty( SaslConstants.SASL_SERVER, ss );
}
return ss;
Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/plain/PlainSaslServer.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/plain/PlainSaslServer.java?rev=682532&r1=682531&r2=682532&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/plain/PlainSaslServer.java (original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/plain/PlainSaslServer.java Mon Aug 4 15:38:08 2008
@@ -94,9 +94,9 @@
state = NegotiationState.INITIALIZED;
// Reinitialize the SASL properties
- getLdapSession().getSaslProperties().remove( SASL_PLAIN_AUTHZID );
- getLdapSession().getSaslProperties().remove( SASL_PLAIN_AUTHCID );
- getLdapSession().getSaslProperties().remove( SASL_PLAIN_PASSWORD );
+ getLdapSession().removeSaslProperty( SASL_PLAIN_AUTHZID );
+ getLdapSession().removeSaslProperty( SASL_PLAIN_AUTHCID );
+ getLdapSession().removeSaslProperty( SASL_PLAIN_PASSWORD );
}
Modified: directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/SaslBindITest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/SaslBindITest.java?rev=682532&r1=682531&r2=682532&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/SaslBindITest.java (original)
+++ directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/SaslBindITest.java Mon Aug 4 15:38:08 2008
@@ -234,114 +234,6 @@
- /**
- * Tests to make sure DIGEST-MD5 binds below the RootDSE work.
- *
- @Test
- public void testSaslDigestMd5Bind() throws Exception
- {
- Hashtable<String, String> env = new Hashtable<String, String>();
- env.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" );
- env.put( Context.PROVIDER_URL, "ldap://localhost:" + port );
-
- env.put( Context.SECURITY_AUTHENTICATION, "DIGEST-MD5" );
- env.put( Context.SECURITY_PRINCIPAL, "hnelson" );
- env.put( Context.SECURITY_CREDENTIALS, "secret" );
-
- // Specify realm
- env.put( "java.naming.security.sasl.realm", "example.com" );
-
- // Request privacy protection
- env.put( "javax.security.sasl.qop", "auth-conf" );
-
- DirContext context = new InitialDirContext( env );
-
- String[] attrIDs =
- { "uid" };
-
- Attributes attrs = context.getAttributes( "uid=hnelson,ou=users,dc=example,dc=com", attrIDs );
-
- String uid = null;
-
- if ( attrs.get( "uid" ) != null )
- {
- uid = ( String ) attrs.get( "uid" ).get();
- }
-
- assertEquals( uid, "hnelson" );
- }
-
-
- /**
- * Tests to make sure DIGEST-MD5 binds below the RootDSE fail if the realm is bad.
- *
- @Test
- public void testSaslDigestMd5BindBadRealm()
- {
- try
- {
- Hashtable<String, String> env = new Hashtable<String, String>();
- env.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" );
- env.put( Context.PROVIDER_URL, "ldap://localhost:" + port );
-
- env.put( Context.SECURITY_AUTHENTICATION, "DIGEST-MD5" );
- env.put( Context.SECURITY_PRINCIPAL, "hnelson" );
- env.put( Context.SECURITY_CREDENTIALS, "secret" );
-
- // Bad realm
- env.put( "java.naming.security.sasl.realm", "badrealm.com" );
-
- // Request privacy protection
- env.put( "javax.security.sasl.qop", "auth-conf" );
-
- DirContext context = new InitialDirContext( env );
-
- String[] attrIDs =
- { "uid" };
-
- context.getAttributes( "uid=hnelson,ou=users,dc=example,dc=com", attrIDs );
-
- fail( "Should have thrown exception." );
- }
- catch ( NamingException e )
- {
- assertTrue( e.getMessage().contains( "Nonexistent realm" ) );
- }
- }
-
-
- /**
- * Tests to make sure DIGEST-MD5 binds below the RootDSE fail if the password is bad.
- *
- @Test
- public void testSaslDigestMd5BindBadPassword()
- {
- try
- {
- Hashtable<String, String> env = new Hashtable<String, String>();
- env.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" );
- env.put( Context.PROVIDER_URL, "ldap://localhost:" + port );
-
- env.put( Context.SECURITY_AUTHENTICATION, "DIGEST-MD5" );
- env.put( Context.SECURITY_PRINCIPAL, "hnelson" );
- env.put( Context.SECURITY_CREDENTIALS, "badsecret" );
-
- DirContext context = new InitialDirContext( env );
-
- String[] attrIDs =
- { "uid" };
-
- context.getAttributes( "uid=hnelson,ou=users,dc=example,dc=com", attrIDs );
-
- fail( "Should have thrown exception." );
- }
- catch ( NamingException e )
- {
- assertTrue( e.getMessage().contains( "digest response format violation" ) );
- }
- }
-
-
/**
Modified: directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/operations/bind/SaslBindITest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/operations/bind/SaslBindITest.java?rev=682532&r1=682531&r2=682532&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/operations/bind/SaslBindITest.java (original)
+++ directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/operations/bind/SaslBindITest.java Mon Aug 4 15:38:08 2008
@@ -395,4 +395,110 @@
assertTrue( e.getMessage().contains( "Invalid response" ) );
}
}
+ /**
+ * Tests to make sure DIGEST-MD5 binds below the RootDSE work.
+ */
+ @Test
+ public void testSaslDigestMd5Bind() throws Exception
+ {
+ Hashtable<String, String> env = new Hashtable<String, String>();
+ env.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" );
+ env.put( Context.PROVIDER_URL, "ldap://localhost:" + port );
+
+ env.put( Context.SECURITY_AUTHENTICATION, "DIGEST-MD5" );
+ env.put( Context.SECURITY_PRINCIPAL, "hnelson" );
+ env.put( Context.SECURITY_CREDENTIALS, "secret" );
+
+ // Specify realm
+ env.put( "java.naming.security.sasl.realm", "example.com" );
+
+ // Request privacy protection
+ env.put( "javax.security.sasl.qop", "auth-conf" );
+
+ DirContext context = new InitialDirContext( env );
+
+ String[] attrIDs =
+ { "uid" };
+
+ Attributes attrs = context.getAttributes( "uid=hnelson,ou=users,dc=example,dc=com", attrIDs );
+
+ String uid = null;
+
+ if ( attrs.get( "uid" ) != null )
+ {
+ uid = ( String ) attrs.get( "uid" ).get();
+ }
+
+ assertEquals( uid, "hnelson" );
+ }
+
+
+ /**
+ * Tests to make sure DIGEST-MD5 binds below the RootDSE fail if the realm is bad.
+ */
+ @Test
+ public void testSaslDigestMd5BindBadRealm()
+ {
+ try
+ {
+ Hashtable<String, String> env = new Hashtable<String, String>();
+ env.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" );
+ env.put( Context.PROVIDER_URL, "ldap://localhost:" + port );
+
+ env.put( Context.SECURITY_AUTHENTICATION, "DIGEST-MD5" );
+ env.put( Context.SECURITY_PRINCIPAL, "hnelson" );
+ env.put( Context.SECURITY_CREDENTIALS, "secret" );
+
+ // Bad realm
+ env.put( "java.naming.security.sasl.realm", "badrealm.com" );
+
+ // Request privacy protection
+ env.put( "javax.security.sasl.qop", "auth-conf" );
+
+ DirContext context = new InitialDirContext( env );
+
+ String[] attrIDs =
+ { "uid" };
+
+ context.getAttributes( "uid=hnelson,ou=users,dc=example,dc=com", attrIDs );
+
+ fail( "Should have thrown exception." );
+ }
+ catch ( NamingException e )
+ {
+ assertTrue( e.getMessage().contains( "Nonexistent realm" ) );
+ }
+ }
+
+
+ /**
+ * Tests to make sure DIGEST-MD5 binds below the RootDSE fail if the password is bad.
+ */
+ @Test
+ public void testSaslDigestMd5BindBadPassword()
+ {
+ try
+ {
+ Hashtable<String, String> env = new Hashtable<String, String>();
+ env.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" );
+ env.put( Context.PROVIDER_URL, "ldap://localhost:" + port );
+
+ env.put( Context.SECURITY_AUTHENTICATION, "DIGEST-MD5" );
+ env.put( Context.SECURITY_PRINCIPAL, "hnelson" );
+ env.put( Context.SECURITY_CREDENTIALS, "badsecret" );
+
+ DirContext context = new InitialDirContext( env );
+
+ String[] attrIDs =
+ { "uid" };
+
+ context.getAttributes( "uid=hnelson,ou=users,dc=example,dc=com", attrIDs );
+
+ fail( "Should have thrown exception." );
+ }
+ catch ( NamingException e )
+ {
+ assertTrue( e.getMessage().contains( "digest response format violation" ) );
+ }
+ }
}