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/06 13:15:25 UTC
svn commit: r683225 - in /directory/apacheds/branches/bigbang:
core/src/main/java/org/apache/directory/server/core/
protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/ntlm/
server-unit/src/test/java/org/apache/directory/se...
Author: elecharny
Date: Wed Aug 6 04:15:24 2008
New Revision: 683225
URL: http://svn.apache.org/viewvc?rev=683225&view=rev
Log:
o Added the sasl mechanism in the context session, to avoid an exception when binding using NTLM
o Made the two last tests for SASL (NtlmBind and SpnegoBind) happy
Modified:
directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java
directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/bind/ntlm/NtlmSaslServer.java
directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/operations/bind/SaslBindITest.java
Modified: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java?rev=683225&r1=683224&r2=683225&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java (original)
+++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java Wed Aug 6 04:15:24 2008
@@ -618,6 +618,7 @@
BindOperationContext bindContext = new BindOperationContext( null );
bindContext.setCredentials( credentials );
bindContext.setDn( principalDn );
+ bindContext.setSaslMechanism( saslMechanism );
operationManager.bind( bindContext );
return bindContext.getSession();
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=683225&r1=683224&r2=683225&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 Wed Aug 6 04:15:24 2008
@@ -21,10 +21,12 @@
import org.apache.directory.server.core.CoreSession;
+import org.apache.directory.server.core.authn.LdapPrincipal;
import org.apache.directory.server.core.interceptor.context.BindOperationContext;
import org.apache.directory.server.newldap.LdapSession;
import org.apache.directory.server.newldap.handlers.bind.AbstractSaslServer;
import org.apache.directory.server.newldap.handlers.bind.SaslConstants;
+import org.apache.directory.shared.ldap.constants.AuthenticationLevel;
import org.apache.directory.shared.ldap.constants.SupportedSaslMechanisms;
import org.apache.directory.shared.ldap.message.BindRequest;
import org.apache.directory.shared.ldap.name.LdapDN;
@@ -154,7 +156,10 @@
try
{
result = provider.authenticate( getLdapSession().getIoSession(), response );
-
+ LdapDN dn = getBindRequest().getName();
+ dn.normalize( getLdapSession().getLdapServer().getDirectoryService().getRegistries().getAttributeTypeRegistry().getNormalizerMapping() );
+ LdapPrincipal ldapPrincipal = new LdapPrincipal( dn, AuthenticationLevel.STRONG );
+ getLdapSession().putSaslProperty( SaslConstants.SASL_AUTHENT_USER, ldapPrincipal );
getLdapSession().putSaslProperty( Context.SECURITY_PRINCIPAL, getBindRequest().getName().toString() );
}
catch ( Exception e )
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=683225&r1=683224&r2=683225&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 Wed Aug 6 04:15:24 2008
@@ -33,22 +33,34 @@
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
+import org.apache.commons.net.SocketClient;
import org.apache.directory.server.core.entry.DefaultServerEntry;
import org.apache.directory.server.core.entry.ServerEntry;
import org.apache.directory.server.core.partition.Partition;
import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmIndex;
import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmPartition;
import org.apache.directory.server.newldap.handlers.bind.ntlm.NtlmMechanismHandler;
+import org.apache.directory.server.newldap.handlers.bind.ntlm.NtlmProvider;
import org.apache.directory.server.newldap.handlers.bind.plain.PlainMechanismHandler;
import org.apache.directory.server.unit.AbstractServerTest;
import org.apache.directory.server.xdbm.Index;
import org.apache.directory.shared.ldap.constants.SupportedSaslMechanisms;
import org.apache.directory.shared.ldap.message.AttributeImpl;
import org.apache.directory.shared.ldap.message.AttributesImpl;
+import org.apache.directory.shared.ldap.message.BindRequestImpl;
+import org.apache.directory.shared.ldap.message.BindResponse;
+import org.apache.directory.shared.ldap.message.MessageDecoder;
+import org.apache.directory.shared.ldap.message.MessageEncoder;
+import org.apache.directory.shared.ldap.message.ResultCodeEnum;
+import org.apache.directory.shared.ldap.message.spi.BinaryAttributeDetector;
import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.shared.ldap.util.ArrayUtils;
+import org.apache.mina.common.IoSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
@@ -60,7 +72,9 @@
public class SaslBindITest extends AbstractServerTest
{
private DirContext ctx;
- //private BogusNtlmProvider provider;
+
+ /** The NTLM fake provider */
+ private BogusNtlmProvider provider;
/**
* Set up a partition for EXAMPLE.COM and add a user to
@@ -69,7 +83,7 @@
@Before
public void setUp() throws Exception
{
- //provider = new BogusNtlmProvider();
+ provider = new BogusNtlmProvider();
super.setUp();
directoryService.setAllowAnonymousAccess( true );
@@ -125,7 +139,7 @@
ldapServer.setSaslHost( "localhost" );
NtlmMechanismHandler ntlmMechanismHandler = new NtlmMechanismHandler();
- //ntlmMechanismHandler.setNtlmProvider( provider );
+ ntlmMechanismHandler.setNtlmProvider( provider );
// Inject the NTLM MechanismHandler
ldapServer.removeSaslMechanismHandler( SupportedSaslMechanisms.NTLM );
@@ -501,4 +515,184 @@
assertTrue( e.getMessage().contains( "digest response format violation" ) );
}
}
+
+
+ /**
+ * Tests that the plumbing for NTLM bind works.
+ */
+ @Test
+ public void testNtlmBind() throws Exception
+ {
+ NtlmSaslBindClient client = new NtlmSaslBindClient( SupportedSaslMechanisms.NTLM );
+ BindResponse type2response = client.bindType1( "type1_test".getBytes() );
+ assertEquals( 1, type2response.getMessageId() );
+ assertEquals( ResultCodeEnum.SASL_BIND_IN_PROGRESS, type2response.getLdapResult().getResultCode() );
+ assertTrue( ArrayUtils.isEquals( "type1_test".getBytes(), provider.getType1Response() ) );
+ assertTrue( ArrayUtils.isEquals( "challenge".getBytes(), type2response.getServerSaslCreds() ) );
+
+ BindResponse finalResponse = client.bindType3( "type3_test".getBytes() );
+ assertEquals( 2, finalResponse.getMessageId() );
+ assertEquals( ResultCodeEnum.SUCCESS, finalResponse.getLdapResult().getResultCode() );
+ assertTrue( ArrayUtils.isEquals( "type3_test".getBytes(), provider.getType3Response() ) );
+ }
+
+
+ /**
+ * Tests that the plumbing for NTLM bind works.
+ */
+ @Test
+ public void testGssSpnegoBind() throws Exception
+ {
+ NtlmSaslBindClient client = new NtlmSaslBindClient( SupportedSaslMechanisms.GSS_SPNEGO );
+ BindResponse type2response = client.bindType1( "type1_test".getBytes() );
+ assertEquals( 1, type2response.getMessageId() );
+ assertEquals( ResultCodeEnum.SASL_BIND_IN_PROGRESS, type2response.getLdapResult().getResultCode() );
+ assertTrue( ArrayUtils.isEquals( "type1_test".getBytes(), provider.getType1Response() ) );
+ assertTrue( ArrayUtils.isEquals( "challenge".getBytes(), type2response.getServerSaslCreds() ) );
+
+ BindResponse finalResponse = client.bindType3( "type3_test".getBytes() );
+ assertEquals( 2, finalResponse.getMessageId() );
+ assertEquals( ResultCodeEnum.SUCCESS, finalResponse.getLdapResult().getResultCode() );
+ assertTrue( ArrayUtils.isEquals( "type3_test".getBytes(), provider.getType3Response() ) );
+ }
+
+
+ /**
+ * A fake implementation of the NtlmProvider. We can't use a real one because
+ * its license is not ASL 2.0 compatible.
+ */
+ class BogusNtlmProvider implements NtlmProvider
+ {
+ private byte[] type1response;
+ private byte[] type3response;
+
+
+ public boolean authenticate( IoSession session, byte[] type3response ) throws Exception
+ {
+ this.type3response = type3response;
+ return true;
+ }
+
+
+ public byte[] generateChallenge( IoSession session, byte[] type1reponse ) throws Exception
+ {
+ this.type1response = type1reponse;
+ return "challenge".getBytes();
+ }
+
+
+ public byte[] getType1Response()
+ {
+ return type1response;
+ }
+
+
+ public byte[] getType3Response()
+ {
+ return type3response;
+ }
+ }
+
+
+ /**
+ * A NTLM client
+ */
+ class NtlmSaslBindClient extends SocketClient
+ {
+ private final Logger LOG = LoggerFactory.getLogger( NtlmSaslBindClient.class );
+
+ private final String mechanism;
+
+
+ NtlmSaslBindClient( String mechanism ) throws Exception
+ {
+ this.mechanism = mechanism;
+ setDefaultPort( port );
+ connect( "localhost", port );
+ setTcpNoDelay( false );
+
+ LOG.debug( "isConnected() = {}", _isConnected_ );
+ LOG.debug( "LocalPort = {}", getLocalPort() );
+ LOG.debug( "LocalAddress = {}", getLocalAddress() );
+ LOG.debug( "RemotePort = {}", getRemotePort() );
+ LOG.debug( "RemoteAddress = {}", getRemoteAddress() );
+ }
+
+
+ BindResponse bindType1( byte[] type1response ) throws Exception
+ {
+ if ( ! isConnected() )
+ {
+ throw new IllegalStateException( "Client is not connected." );
+ }
+
+ // Setup the bind request
+ BindRequestImpl request = new BindRequestImpl( 1 ) ;
+ request.setName( new LdapDN( "uid=admin,ou=system" ) ) ;
+ request.setSimple( false ) ;
+ request.setCredentials( type1response ) ;
+ request.setSaslMechanism( mechanism );
+ request.setVersion3( true ) ;
+
+ // Setup the ASN1 Enoder and Decoder
+ MessageEncoder encoder = new MessageEncoder();
+ MessageDecoder decoder = new MessageDecoder( new BinaryAttributeDetector() {
+ public boolean isBinary( String attributeId )
+ {
+ return false;
+ }
+ } );
+
+ // Send encoded request to server
+ encoder.encodeBlocking( null, _output_, request );
+ _output_.flush();
+
+ while ( _input_.available() <= 0 )
+ {
+ Thread.sleep( 100 );
+ }
+
+ // Retrieve the response back from server to my last request.
+ return ( BindResponse ) decoder.decode( null, _input_ );
+ }
+
+
+ BindResponse bindType3( byte[] type3response ) throws Exception
+ {
+ if ( ! isConnected() )
+ {
+ throw new IllegalStateException( "Client is not connected." );
+ }
+
+ // Setup the bind request
+ BindRequestImpl request = new BindRequestImpl( 2 ) ;
+ request.setName( new LdapDN( "uid=admin,ou=system" ) ) ;
+ request.setSimple( false ) ;
+ request.setCredentials( type3response ) ;
+ request.setSaslMechanism( mechanism );
+ request.setVersion3( true ) ;
+
+ // Setup the ASN1 Enoder and Decoder
+ MessageEncoder encoder = new MessageEncoder();
+ MessageDecoder decoder = new MessageDecoder( new BinaryAttributeDetector() {
+ public boolean isBinary( String attributeId )
+ {
+ return false;
+ }
+ } );
+
+ // Send encoded request to server
+ encoder.encodeBlocking( null, _output_, request );
+
+ _output_.flush();
+
+ while ( _input_.available() <= 0 )
+ {
+ Thread.sleep( 100 );
+ }
+
+ // Retrieve the response back from server to my last request.
+ return ( BindResponse ) decoder.decode( null, _input_ );
+ }
+ }
}