directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r1465064 - in /directory/apacheds/trunk: core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/ protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/plain/ server-integ/src/test/java/org/apach...
Date Fri, 05 Apr 2013 17:42:48 GMT
Author: elecharny
Date: Fri Apr  5 17:42:47 2013
New Revision: 1465064

URL: http://svn.apache.org/r1465064
Log:
Added the support for SASL PLAIN bind

Modified:
    directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/FilteringOperationContext.java
    directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/plain/PlainSaslServer.java
    directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/bind/SaslBindIT.java

Modified: directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/FilteringOperationContext.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/FilteringOperationContext.java?rev=1465064&r1=1465063&r2=1465064&view=diff
==============================================================================
--- directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/FilteringOperationContext.java
(original)
+++ directory/apacheds/trunk/core-api/src/main/java/org/apache/directory/server/core/api/interceptor/context/FilteringOperationContext.java
Fri Apr  5 17:42:47 2013
@@ -100,7 +100,7 @@ public abstract class FilteringOperation
     public FilteringOperationContext( CoreSession session, String... returningAttributes
)
     {
         super( session );
-        
+
         setReturningAttributes( returningAttributes );
     }
 
@@ -113,7 +113,7 @@ public abstract class FilteringOperation
     public FilteringOperationContext( CoreSession session, Dn dn, String... returningAttributes
)
     {
         super( session, dn );
-        
+
         setReturningAttributes( returningAttributes );
     }
 
@@ -179,8 +179,8 @@ public abstract class FilteringOperation
     {
         return returningAttributesString;
     }
-    
-    
+
+
     /**
      * Tells if an attribute is present in the list of attribute to return
      * 
@@ -193,11 +193,11 @@ public abstract class FilteringOperation
         {
             return false;
         }
-        
+
         try
         {
             AttributeType attributeType = schemaManager.lookupAttributeTypeRegistry( attribute
);
-            
+
             return contains( schemaManager, attributeType );
         }
         catch ( LdapException le )
@@ -205,8 +205,8 @@ public abstract class FilteringOperation
             return false;
         }
     }
-    
-    
+
+
     /**
      * Tells if an attribute is present in the list of attribute to return
      * 
@@ -219,7 +219,7 @@ public abstract class FilteringOperation
         {
             return false;
         }
-        
+
         if ( ( attributeType.getUsage() == UsageEnum.USER_APPLICATIONS ) && allUserAttributes
)
         {
             return true;
@@ -235,7 +235,7 @@ public abstract class FilteringOperation
         {
             return false;
         }
-        
+
         for ( AttributeTypeOptions attributeTypeOptions : returningAttributes )
         {
             if ( attributeTypeOptions.getAttributeType().equals( attributeType ) ||
@@ -244,7 +244,7 @@ public abstract class FilteringOperation
                 return true;
             }
         }
-        
+
         return false;
     }
 
@@ -258,7 +258,7 @@ public abstract class FilteringOperation
             // AttributeTypeOptions
             returningAttributes = new HashSet<AttributeTypeOptions>();
             Set<String> attributesString = new HashSet<String>();
-            
+
             Set<AttributeTypeOptions> collectedAttributes = collectAttributeTypes(
attributeIds );
 
             // If we have valid, '*' or '+' attributes, we can get rid of the NoAttributes
flag
@@ -280,7 +280,7 @@ public abstract class FilteringOperation
                         returningAttributes.add( attributeTypeOption );
                         attributesString.add( attributeTypeOption.getAttributeType().getOid()
);
                     }
-                    
+
                     if ( attributeTypeOption.getAttributeType().isOperational() &&
!allOperationalAttributes )
                     {
                         // We can add the AttributeType in the list of returningAttributeTypes
@@ -289,17 +289,17 @@ public abstract class FilteringOperation
                     }
                 }
             }
-            
+
             if ( attributesString.size() > 0 )
             {
                 // We have some valid attributes, lt's convert it to String
                 returningAttributesString = attributesString.toArray( ArrayUtils.EMPTY_STRING_ARRAY
);
             }
-            else 
+            else
             {
                 // No valid attributes remaining, that means they were all invalid
                 returningAttributesString = ArrayUtils.EMPTY_STRING_ARRAY;
-            } 
+            }
         }
         else
         {
@@ -308,13 +308,13 @@ public abstract class FilteringOperation
             returningAttributesString = ArrayUtils.EMPTY_STRING_ARRAY;
         }
     }
-    
-    
+
+
     private Set<AttributeTypeOptions> collectAttributeTypes( String... attributesIds
)
     {
         Set<AttributeTypeOptions> collectedAttributes = new HashSet<AttributeTypeOptions>();
-        
-        if ( ( attributesIds != null ) && ( attributesIds.length != 0 ) ) 
+
+        if ( ( attributesIds != null ) && ( attributesIds.length != 0 ) )
         {
             for ( String returnAttribute : attributesIds )
             {
@@ -322,34 +322,34 @@ public abstract class FilteringOperation
                 {
                     continue;
                 }
-                
+
                 if ( returnAttribute.equals( SchemaConstants.NO_ATTRIBUTE ) )
                 {
                     noAttributes = true;
                     continue;
                 }
-    
+
                 if ( returnAttribute.equals( SchemaConstants.ALL_OPERATIONAL_ATTRIBUTES )
)
                 {
                     allOperationalAttributes = true;
                     continue;
                 }
-    
+
                 if ( returnAttribute.equals( SchemaConstants.ALL_USER_ATTRIBUTES ) )
                 {
                     allUserAttributes = true;
                     continue;
                 }
-    
+
                 try
                 {
                     String id = SchemaUtils.stripOptions( returnAttribute );
                     Set<String> options = SchemaUtils.getOptions( returnAttribute );
-    
+
                     AttributeType attributeType = session.getDirectoryService()
                         .getSchemaManager().lookupAttributeTypeRegistry( id );
                     AttributeTypeOptions attrOptions = new AttributeTypeOptions( attributeType,
options );
-    
+
                     collectedAttributes.add( attrOptions );
                 }
                 catch ( LdapNoSuchAttributeException nsae )
@@ -366,7 +366,7 @@ public abstract class FilteringOperation
                 }
             }
         }
-        
+
         return collectedAttributes;
     }
 
@@ -415,7 +415,7 @@ public abstract class FilteringOperation
         return noAttributes;
     }
 
-    
+
     /**
      * @param noAttributes the noAttributes to set
      */
@@ -442,14 +442,14 @@ public abstract class FilteringOperation
         this.typesOnly = typesOnly;
     }
 
-    
+
     /**
      * @see Object#toString()
      */
     public String toString()
     {
         StringBuilder sb = new StringBuilder();
-        
+
         sb.append( "FilteringOperationContext for Dn '" );
         sb.append( getDn().getName() ).append( "'" );
 
@@ -457,7 +457,7 @@ public abstract class FilteringOperation
         {
             sb.append( ", type only" );
         }
-        
+
         if ( allOperationalAttributes )
         {
             sb.append( ", +" );
@@ -477,7 +477,7 @@ public abstract class FilteringOperation
         {
             sb.append( ", attributes : <" );
             boolean isFirst = true;
-            
+
             for ( String returningAttribute : returningAttributesString )
             {
                 if ( isFirst )
@@ -488,11 +488,11 @@ public abstract class FilteringOperation
                 {
                     sb.append( ", " );
                 }
-                
+
                 sb.append( returningAttribute );
             }
-            
-            sb.append(  ">" );
+
+            sb.append( ">" );
         }
 
         return sb.toString();

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/plain/PlainSaslServer.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/plain/PlainSaslServer.java?rev=1465064&r1=1465063&r2=1465064&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/plain/PlainSaslServer.java
(original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/bind/plain/PlainSaslServer.java
Fri Apr  5 17:42:47 2013
@@ -25,16 +25,26 @@ import java.io.IOException;
 import javax.naming.InvalidNameException;
 import javax.security.sasl.SaslException;
 
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
 import org.apache.directory.api.ldap.model.constants.SupportedSaslMechanisms;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.entry.StringValue;
+import org.apache.directory.api.ldap.model.exception.LdapAuthenticationException;
+import org.apache.directory.api.ldap.model.filter.EqualityNode;
 import org.apache.directory.api.ldap.model.message.BindRequest;
-import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.api.ldap.model.message.SearchScope;
 import org.apache.directory.api.ldap.model.schema.PrepareString;
 import org.apache.directory.api.util.StringConstants;
 import org.apache.directory.api.util.Strings;
 import org.apache.directory.server.core.api.CoreSession;
+import org.apache.directory.server.core.api.DirectoryService;
 import org.apache.directory.server.core.api.OperationEnum;
+import org.apache.directory.server.core.api.OperationManager;
+import org.apache.directory.server.core.api.filtering.EntryFilteringCursor;
 import org.apache.directory.server.core.api.interceptor.context.BindOperationContext;
+import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
 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.bind.AbstractSaslServer;
 
@@ -241,18 +251,56 @@ public class PlainSaslServer extends Abs
 
 
     /**
-     * Try to authenticate the user against the underlying LDAP server.
+     * Try to authenticate the user against the underlying LDAP server. The SASL PLAIN
+     * authentication is based on the entry which uid is equal to the user name we received.
      */
     private CoreSession authenticate( String user, String password ) throws InvalidNameException,
Exception
     {
-        BindOperationContext bindContext = new BindOperationContext( getLdapSession().getCoreSession()
);
-        bindContext.setDn( new Dn( user ) );
-        bindContext.setCredentials( Strings.getBytesUtf8( password ) );
-        bindContext.setIoSession( getLdapSession().getIoSession() );
-        bindContext.setInterceptors( getAdminSession().getDirectoryService().getInterceptors(
OperationEnum.BIND ) );
+        LdapSession ldapSession = getLdapSession();
+        CoreSession adminSession = getAdminSession();
+        DirectoryService directoryService = adminSession.getDirectoryService();
+        LdapServer ldapServer = ldapSession.getLdapServer();
+        OperationManager operationManager = directoryService.getOperationManager();
+
+        // first, we have to find the entries which has the uid value
+        EqualityNode<String> filter = new EqualityNode<String>(
+            directoryService.getSchemaManager().getAttributeType( SchemaConstants.UID_AT
), new StringValue( user ) );
+
+        SearchOperationContext searchContext = new SearchOperationContext( directoryService.getAdminSession()
);
+        searchContext.setDn( directoryService.getDnFactory().create( ldapServer.getSearchBaseDn()
) );
+        searchContext.setScope( SearchScope.SUBTREE );
+        searchContext.setFilter( filter );
+        searchContext.setNoAttributes( true );
 
-        getAdminSession().getDirectoryService().getOperationManager().bind( bindContext );
+        EntryFilteringCursor cursor = operationManager.search( searchContext );
+        Exception bindException = new LdapAuthenticationException( "Cannot authenticate user
uid=" + user );
 
-        return bindContext.getSession();
+        while ( cursor.next() )
+        {
+            Entry entry = cursor.get();
+
+            try
+            {
+                BindOperationContext bindContext = new BindOperationContext( ldapSession.getCoreSession()
);
+                bindContext.setDn( entry.getDn() );
+                bindContext.setCredentials( Strings.getBytesUtf8( password ) );
+                bindContext.setIoSession( ldapSession.getIoSession() );
+                bindContext.setInterceptors( directoryService.getInterceptors( OperationEnum.BIND
) );
+
+                operationManager.bind( bindContext );
+
+                cursor.close();
+
+                return bindContext.getSession();
+            }
+            catch ( Exception e )
+            {
+                bindException = e;// Nothing to do here : we will try to bind with the next
user
+            }
+        }
+
+        cursor.close();
+
+        throw bindException;
     }
 }

Modified: directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/bind/SaslBindIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/bind/SaslBindIT.java?rev=1465064&r1=1465063&r2=1465064&view=diff
==============================================================================
--- directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/bind/SaslBindIT.java
(original)
+++ directory/apacheds/trunk/server-integ/src/test/java/org/apache/directory/server/operations/bind/SaslBindIT.java
Fri Apr  5 17:42:47 2013
@@ -262,24 +262,27 @@ public class SaslBindIT extends Abstract
      * Tests to make sure PLAIN-binds works
      */
     @Test
-    //@Ignore
-    // The SASL Plain mechanism is not supported
     public void testSaslBindPLAIN() throws Exception
     {
-        Dn userDn = new Dn( "uid=hnelson,ou=users,dc=example,dc=com" );
-        LdapConnection connection = new LdapNetworkConnection( "localhost", getLdapServer().getPort()
);
-        BindRequest bindReq = new BindRequestImpl();
-        bindReq.setCredentials( '\0' + "uid=hnelson,ou=users,dc=example,dc=com" + '\0' +
"secret" );
-        bindReq.setDn( userDn );
-        bindReq.setSaslMechanism( SupportedSaslMechanisms.PLAIN );
+        LdapNetworkConnection connection = new LdapNetworkConnection( "localhost", getLdapServer().getPort()
);
+        connection.setTimeOut( 0L );
 
-        BindResponse resp = connection.bind( bindReq );
+        BindResponse resp = connection.bindSaslPlain( "hnelson", "secret" );
         assertEquals( ResultCodeEnum.SUCCESS, resp.getLdapResult().getResultCode() );
 
+        Dn userDn = new Dn( "uid=hnelson,ou=users,dc=example,dc=com" );
         Entry entry = connection.lookup( userDn );
         assertEquals( "hnelson", entry.get( "uid" ).getString() );
 
         connection.close();
+
+        // Try to bind with a wrong user
+        resp = connection.bindSaslPlain( "hnelsom", "secret" );
+        assertEquals( ResultCodeEnum.INVALID_CREDENTIALS, resp.getLdapResult().getResultCode()
);
+
+        // Try to bind with a wrong password
+        resp = connection.bindSaslPlain( "hnelson", "secres" );
+        assertEquals( ResultCodeEnum.INVALID_CREDENTIALS, resp.getLdapResult().getResultCode()
);
     }
 
 



Mime
View raw message