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 2010/02/23 17:01:16 UTC

svn commit: r915401 - in /directory: apacheds/trunk/i18n/src/main/java/org/apache/directory/server/i18n/ apacheds/trunk/i18n/src/main/resources/org/apache/directory/server/i18n/ apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/lda...

Author: elecharny
Date: Tue Feb 23 16:01:15 2010
New Revision: 915401

URL: http://svn.apache.org/viewvc?rev=915401&view=rev
Log:
o Adding two BindStatus : SASL_AUTH_PENDING and SIMPLE_AUTH_PENDING, and used those status to handle the BindRequest processing
o Returned a UNWILLING_TO_PERFORM errors when a user tries to send a request while we are processing a BindRequest
o Removed the clearMaps() call done in BindRequest, as it makes it mpossible to issue two binds at the same time
o Added an error message in i18n
o Minor refactoring

Modified:
    directory/apacheds/trunk/i18n/src/main/java/org/apache/directory/server/i18n/I18n.java
    directory/apacheds/trunk/i18n/src/main/resources/org/apache/directory/server/i18n/errors.properties
    directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapServer.java
    directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapSession.java
    directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/BindHandler.java
    directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/LdapRequestHandler.java
    directory/clients/ldap/trunk/ldap-client-api/src/main/java/org/apache/directory/ldap/client/api/LdapConnection.java
    directory/clients/ldap/trunk/ldap-client-test/src/test/java/org/apache/directory/shared/client/api/operations/bind/SimpleBindRequestTest.java
    directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/message/BindStatus.java

Modified: directory/apacheds/trunk/i18n/src/main/java/org/apache/directory/server/i18n/I18n.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/i18n/src/main/java/org/apache/directory/server/i18n/I18n.java?rev=915401&r1=915400&r2=915401&view=diff
==============================================================================
--- directory/apacheds/trunk/i18n/src/main/java/org/apache/directory/server/i18n/I18n.java (original)
+++ directory/apacheds/trunk/i18n/src/main/java/org/apache/directory/server/i18n/I18n.java Tue Feb 23 16:01:15 2010
@@ -770,6 +770,7 @@
     public static String ERR_729 = "ERR_729";
     public static String ERR_730 = "ERR_730";
     public static String ERR_731 = "ERR_731";
+    public static String ERR_732 = "ERR_732";
 
 
     /**

Modified: directory/apacheds/trunk/i18n/src/main/resources/org/apache/directory/server/i18n/errors.properties
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/i18n/src/main/resources/org/apache/directory/server/i18n/errors.properties?rev=915401&r1=915400&r2=915401&view=diff
==============================================================================
--- directory/apacheds/trunk/i18n/src/main/resources/org/apache/directory/server/i18n/errors.properties (original)
+++ directory/apacheds/trunk/i18n/src/main/resources/org/apache/directory/server/i18n/errors.properties Tue Feb 23 16:01:15 2010
@@ -753,3 +753,4 @@
 ERR_729=You didn't correctly set col names
 ERR_730=Unrecognized mode.
 ERR_731=Unrecognized FilterDialog command: {0}
+ERR_732=Cannot process a Request while binding

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapServer.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapServer.java?rev=915401&r1=915400&r2=915401&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapServer.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapServer.java Tue Feb 23 16:01:15 2010
@@ -187,7 +187,7 @@
     /** The list of realms serviced by this host. */
     private List<String> saslRealms;
 
-    /** The potocol handlers */
+    /** The protocol handlers */
     private LdapRequestHandler<InternalAbandonRequest> abandonHandler;
     private LdapRequestHandler<InternalAddRequest> addHandler;
     private LdapRequestHandler<InternalBindRequest> bindHandler;

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapSession.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapSession.java?rev=915401&r1=915400&r2=915401&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapSession.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapSession.java Tue Feb 23 16:01:15 2010
@@ -135,13 +135,37 @@
     
     
     /**
-     * Check if the session is in the middle of a SASL negotiation.
+     * Check if the session is processing a BindRequest, either Simple
+     * or SASL
      * 
      * @return <code>true</code> if the session is in AuthPending state
      */
     public boolean isAuthPending()
     {
-        return bindStatus == BindStatus.AUTH_PENDING;
+        return ( bindStatus == BindStatus.SIMPLE_AUTH_PENDING ) || 
+               ( bindStatus == BindStatus.SASL_AUTH_PENDING );
+    }
+    
+    
+    /**
+     * Check if the session is processing a Simple BindRequest
+     * 
+     * @return <code>true</code> if the session is in AuthPending state
+     */
+    public boolean isSimpleAuthPending()
+    {
+        return ( bindStatus == BindStatus.SIMPLE_AUTH_PENDING );
+    }
+    
+    
+    /**
+     * Check if the session is processing a SASL BindRequest
+     * 
+     * @return <code>true</code> if the session is in AuthPending state
+     */
+    public boolean isSaslAuthPending()
+    {
+        return ( bindStatus == BindStatus.SASL_AUTH_PENDING );
     }
     
     
@@ -283,11 +307,20 @@
     
     
     /**
-     * Set the current BindStatus to authentication pending
+     * Set the current BindStatus to Simple authentication pending
+     */
+    public void setSimpleAuthPending()
+    {
+        bindStatus = BindStatus.SIMPLE_AUTH_PENDING;
+    }
+    
+    
+    /**
+     * Set the current BindStatus to SASL authentication pending
      */
-    public void setAuthPending()
+    public void setSaslAuthPending()
     {
-        bindStatus = BindStatus.AUTH_PENDING;
+        bindStatus = BindStatus.SASL_AUTH_PENDING;
     }
 
 

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/BindHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/BindHandler.java?rev=915401&r1=915400&r2=915401&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/BindHandler.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/BindHandler.java Tue Feb 23 16:01:15 2010
@@ -89,16 +89,16 @@
     public void handleSimpleAuth( LdapSession ldapSession, InternalBindRequest bindRequest ) throws Exception
     {
         // if the user is already bound, we have to unbind him
-        if ( !ldapSession.isAnonymous() )
+        if ( ldapSession.isAuthenticated() )
         {
             // We already have a bound session for this user. We have to
             // abandon it first.
             ldapSession.getCoreSession().unbind();
-
-            // Reset the status to Anonymous
-            ldapSession.setAnonymous();
         }
 
+        // Set the status to SimpleAuthPending
+        ldapSession.setSimpleAuthPending();
+
         // Now, bind the user
 
         // create a new Bind context, with a null session, as we don't have 
@@ -176,11 +176,16 @@
             // As a result, store the created session in the Core Session
             ldapSession.setCoreSession( opContext.getSession() );
 
+            // And set the current state accordingly
             if ( !ldapSession.getCoreSession().isAnonymous() )
             {
                 ldapSession.setAuthenticated();
             }
-
+            else
+            {
+                ldapSession.setAnonymous();
+            }
+            
             // Return the successful response
             sendBindSuccess( ldapSession, bindRequest, null );
         }
@@ -328,8 +333,8 @@
                 // Store the challenge
                 resp.setServerSaslCreds( tokenBytes );
 
-                // Switch to AuthPending
-                ldapSession.setAuthPending();
+                // Switch to SASLAuthPending
+                ldapSession.setSaslAuthPending();
 
                 // And write back the response
                 ldapSession.getIoSession().write( resp );

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/LdapRequestHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/LdapRequestHandler.java?rev=915401&r1=915400&r2=915401&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/LdapRequestHandler.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/LdapRequestHandler.java Tue Feb 23 16:01:15 2010
@@ -23,15 +23,19 @@
 import javax.naming.NamingException;
 
 import org.apache.directory.server.core.CoreSession;
+import org.apache.directory.server.i18n.I18n;
 import org.apache.directory.server.ldap.LdapServer;
 import org.apache.directory.server.ldap.LdapSession;
 import org.apache.directory.server.ldap.handlers.extended.StartTlsHandler;
 import org.apache.directory.shared.ldap.exception.LdapException;
 import org.apache.directory.shared.ldap.exception.LdapReferralException;
+import org.apache.directory.shared.ldap.message.BindRequestImpl;
+import org.apache.directory.shared.ldap.message.BindResponseImpl;
 import org.apache.directory.shared.ldap.message.ReferralImpl;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.message.internal.InternalAbandonRequest;
 import org.apache.directory.shared.ldap.message.internal.InternalBindRequest;
+import org.apache.directory.shared.ldap.message.internal.InternalBindResponse;
 import org.apache.directory.shared.ldap.message.internal.InternalExtendedRequest;
 import org.apache.directory.shared.ldap.message.internal.InternalLdapResult;
 import org.apache.directory.shared.ldap.message.internal.InternalReferral;
@@ -117,12 +121,33 @@
         return;
     }
 
-
+    /**
+     *{@inheritDoc} 
+     */
     public final void handleMessage( IoSession session, T message ) throws Exception
     {
         LdapSession ldapSession = ldapServer.getLdapSessionManager().getLdapSession( session );
         
-        //handle( ldapSession, message );
+        // First check that the client hasn't issued a previous BindRequest, unless it
+        // was a SASL BindRequest
+        if ( ldapSession.isAuthPending() )
+        {
+            // Only SASL BinRequest are allowed if we already are handling a 
+            // SASL BindRequest
+            if ( !( message instanceof BindRequestImpl ) || 
+                 ((BindRequestImpl)message).isSimple() ||
+                 ldapSession.isSimpleAuthPending() )
+            {
+                LOG.error( I18n.err( I18n.ERR_732 ) );
+                InternalBindResponse bindResponse = new BindResponseImpl( message.getMessageId() );
+                InternalLdapResult bindResult = bindResponse.getLdapResult();
+                bindResult.setResultCode( ResultCodeEnum.UNWILLING_TO_PERFORM );
+                bindResult.setErrorMessage( I18n.err( I18n.ERR_732 ) );
+                ldapSession.getIoSession().write( bindResponse );
+                return;
+            }
+        }
+        
         // TODO - session you get from LdapServer should have the ldapServer 
         // member already set no?  Should remove these lines where ever they
         // may be if that's the case.
@@ -135,6 +160,7 @@
             {
                 // Reject all extended operations except StartTls  
                 InternalExtendedRequest req = ( InternalExtendedRequest ) message;
+                
                 if ( ! req.getID().equals( StartTlsHandler.EXTENSION_OID ) )
                 {
                     rejectWithoutConfidentiality( session, req.getResultResponse() );

Modified: directory/clients/ldap/trunk/ldap-client-api/src/main/java/org/apache/directory/ldap/client/api/LdapConnection.java
URL: http://svn.apache.org/viewvc/directory/clients/ldap/trunk/ldap-client-api/src/main/java/org/apache/directory/ldap/client/api/LdapConnection.java?rev=915401&r1=915400&r2=915401&view=diff
==============================================================================
--- directory/clients/ldap/trunk/ldap-client-api/src/main/java/org/apache/directory/ldap/client/api/LdapConnection.java (original)
+++ directory/clients/ldap/trunk/ldap-client-api/src/main/java/org/apache/directory/ldap/client/api/LdapConnection.java Tue Feb 23 16:01:15 2010
@@ -1249,7 +1249,7 @@
         BindRequestCodec bindRequestCodec = new BindRequestCodec();
 
         // clear the mappings if any (in case of a second call to bind() without calling unBind())
-        clearMaps();
+        //clearMaps();
         
         // Set the new messageId
         int newId = messageId.incrementAndGet();

Modified: directory/clients/ldap/trunk/ldap-client-test/src/test/java/org/apache/directory/shared/client/api/operations/bind/SimpleBindRequestTest.java
URL: http://svn.apache.org/viewvc/directory/clients/ldap/trunk/ldap-client-test/src/test/java/org/apache/directory/shared/client/api/operations/bind/SimpleBindRequestTest.java?rev=915401&r1=915400&r2=915401&view=diff
==============================================================================
--- directory/clients/ldap/trunk/ldap-client-test/src/test/java/org/apache/directory/shared/client/api/operations/bind/SimpleBindRequestTest.java (original)
+++ directory/clients/ldap/trunk/ldap-client-test/src/test/java/org/apache/directory/shared/client/api/operations/bind/SimpleBindRequestTest.java Tue Feb 23 16:01:15 2010
@@ -37,9 +37,13 @@
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
 import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.apache.directory.server.core.interceptor.BaseInterceptor;
+import org.apache.directory.server.core.interceptor.NextInterceptor;
+import org.apache.directory.server.core.interceptor.context.BindOperationContext;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -97,7 +101,6 @@
     @Test
     public void testSyncBindRequest() throws Exception
     {
-        System.out.println( "testSyncBindRequest" );
         BindResponse bindResponse = connection.bind( "uid=admin,ou=system", "secret" );
         
         assertNotNull( bindResponse );
@@ -114,7 +117,6 @@
     @Test
     public void testAsyncBindRequest() throws Exception
     {
-        System.out.println( "testAsyncBindRequest" );
         int i = 0;
         int nbLoop = 10;
 
@@ -123,7 +125,6 @@
             BindRequest bindRequest = new BindRequest();
             bindRequest.setName( "uid=admin,ou=system" );
             bindRequest.setCredentials( "secret" );
-            final int messageId = i+1;
             
             BindFuture bindFuture = connection.bindAsync( bindRequest );
             
@@ -149,7 +150,6 @@
     @Test
     public void testSimpleBindAnonymous() throws Exception
     {
-        System.out.println( "testSimpleBindAnonymous" );
         // Try with no parameters
         BindResponse bindResponse = connection.bind();
         
@@ -194,7 +194,6 @@
     @Test
     public void testSimpleBindNoNamePassword() throws Exception
     {
-        System.out.println( "testSimpleBindNoNamePassword" );
         BindResponse response = connection.bind((String)null, "abc" );
         LdapResult ldapResult = response.getLdapResult();
         assertEquals( ResultCodeEnum.INVALID_CREDENTIALS, ldapResult.getResultCode() );
@@ -210,7 +209,6 @@
     @Test
     public void testSimpleBindUnauthenticated() throws Exception
     {
-        System.out.println( "testSimpleBindUnauthenticated" );
         BindResponse response = connection.bind( "uid=admin,ou=system", (String)null );
         LdapResult ldapResult = response.getLdapResult();
         assertEquals( ResultCodeEnum.UNWILLING_TO_PERFORM, ldapResult.getResultCode() );
@@ -226,7 +224,6 @@
     @Test
     public void testSimpleBindValid() throws Exception
     {
-        System.out.println( "testSimpleBindValid" );
         BindResponse response = connection.bind( "uid=admin,ou=system", "secret" );
         LdapResult ldapResult = response.getLdapResult();
         assertEquals( ResultCodeEnum.SUCCESS, ldapResult.getResultCode() );
@@ -241,7 +238,6 @@
     @Test
     public void testSimpleBindValidUserWrongPassword() throws Exception
     {
-        System.out.println( "testSimpleBindValidUserWrongPassword" );
         BindResponse response = connection.bind( "uid=admin,ou=system", "badpassword" );
         LdapResult ldapResult = response.getLdapResult();
         assertEquals( ResultCodeEnum.INVALID_CREDENTIALS, ldapResult.getResultCode() );
@@ -249,4 +245,94 @@
         assertFalse( connection.isAuthenticated() );
         assertTrue( connection.isConnected() );
     }
+
+    
+    /**
+     * Test a bind with an invalid user
+     */
+    @Test
+    public void testSimpleBindInvalidUser() throws Exception
+    {
+        BindResponse response = connection.bind( "uid=wrong,ou=system", "secret" );
+        LdapResult ldapResult = response.getLdapResult();
+        assertEquals( ResultCodeEnum.INVALID_CREDENTIALS, ldapResult.getResultCode() );
+        assertEquals( 1, response.getMessageId() );
+        assertFalse( connection.isAuthenticated() );
+        assertTrue( connection.isConnected() );
+    }
+
+    
+    /**
+     * Test a valid bind followed by another valid bind
+     */
+    @Test
+    @Ignore
+    public void testDoubleSimpleBindValid() throws Exception
+    {
+        BindResponse response = connection.bind( "uid=admin,ou=system", "secret" );
+        LdapResult ldapResult = response.getLdapResult();
+        assertEquals( ResultCodeEnum.SUCCESS, ldapResult.getResultCode() );
+        assertEquals( 1, response.getMessageId() );
+        assertTrue( connection.isAuthenticated() );
+        
+        BindResponse response2 = connection.bind( "uid=admin,ou=system", "secret" );
+        LdapResult ldapResult2 = response.getLdapResult();
+        assertEquals( ResultCodeEnum.SUCCESS, ldapResult2.getResultCode() );
+        assertEquals( 1, response2.getMessageId() );
+        assertTrue( connection.isAuthenticated() );
+    }
+
+    
+    /**
+     * Test that we can't send another request until the BindResponse arrives
+     */
+    @Test
+    public void testRequestWhileBinding() throws Exception
+    {
+        // Inject the interceptor that waits 1 second when binding 
+        // in order to be able to send a request before we get the response
+        service.getInterceptorChain().addFirst( new BaseInterceptor()
+            {
+            /**
+             * Wait 1 second before going any further
+             */
+            public void bind( NextInterceptor next, BindOperationContext opContext ) throws Exception
+            {
+                // Wait 1 second
+                Thread.sleep( 1000 );
+                
+                next.bind( opContext );
+            }
+        } );
+        
+        // Send another BindRequest
+        BindRequest bindRequest = new BindRequest();
+        bindRequest.setName( "uid=admin,ou=system" );
+        bindRequest.setCredentials( "secret" );
+        
+        BindFuture bindFuture = connection.bindAsync( bindRequest );
+        
+        // Wait a bit to be sure the server is processing the bind request
+        Thread.sleep( 200 );
+        
+        // It will take 1 seconds to bind, let's send another bind request : it should fail
+        BindResponse response = connection.bind( "uid=admin,ou=system", "secret" );
+        
+        assertFalse( connection.isAuthenticated() );
+        assertEquals( ResultCodeEnum.UNWILLING_TO_PERFORM, response.getLdapResult().getResultCode() );
+        
+        // Now get back the BindResponse
+        try
+        {
+            BindResponse bindResponse = bindFuture.get( 2000, TimeUnit.MILLISECONDS );
+            
+            assertNotNull( bindResponse );
+            assertEquals( ResultCodeEnum.SUCCESS, bindResponse.getLdapResult().getResultCode() );
+            assertTrue( connection.isAuthenticated() );
+        }
+        catch ( TimeoutException toe )
+        {
+            fail();
+        }
+    }
 }

Modified: directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/message/BindStatus.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/message/BindStatus.java?rev=915401&r1=915400&r2=915401&view=diff
==============================================================================
--- directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/message/BindStatus.java (original)
+++ directory/shared/trunk/ldap/src/main/java/org/apache/directory/shared/ldap/message/BindStatus.java Tue Feb 23 16:01:15 2010
@@ -35,9 +35,14 @@
     ANONYMOUS,
     
     /**
-     * We have received a BindRequest
+     * We have received a Simple BindRequest
      */
-    AUTH_PENDING,
+    SIMPLE_AUTH_PENDING,
+    
+    /**
+     * We have received a SASL BindRequest
+     */
+    SASL_AUTH_PENDING,
     
     /**
      * The user has been authenticated