directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From akaras...@apache.org
Subject svn commit: r669253 - in /directory/apacheds/trunk: protocol-ldap/src/main/java/org/apache/directory/server/ldap/ protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/ protocol-ldap/src/main/java/org/apache/directory/server/ldap/handle...
Date Wed, 18 Jun 2008 18:53:31 GMT
Author: akarasulu
Date: Wed Jun 18 11:53:31 2008
New Revision: 669253

URL: http://svn.apache.org/viewvc?rev=669253&view=rev
Log:
Adding confidentiality required feature for LdapServer along with tests: see DIRSERVER-1189

Added:
    directory/apacheds/trunk/server-unit/src/test/java/org/apache/directory/server/ssl/ConfidentialityRequiredITest.java
Removed:
    directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/starttls/
Modified:
    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/handlers/AbstractLdapHandler.java
    directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultAddHandler.java
    directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultBindHandler.java
    directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultCompareHandler.java
    directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultDeleteHandler.java
    directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultExtendedHandler.java
    directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultModifyDnHandler.java
    directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultModifyHandler.java
    directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultSearchHandler.java

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=669253&r1=669252&r2=669253&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
Wed Jun 18 11:53:31 2008
@@ -158,8 +158,14 @@
     /** Whether LDAPS is enabled. */
     private boolean enableLdaps;
 
-    /** Whether to allow anonymous access. */
-    private boolean allowAnonymousAccess = true; // allow by default
+    /** Whether to allow anonymous access: allowed by default */
+    private boolean allowAnonymousAccess = true;
+    
+    /** 
+     * Whether or not confidentiality (TLS secured connection) is required: 
+     * disabled by default. 
+     */
+    private boolean confidentialityRequired;
 
     /** The extended operation handlers. */
     private final Collection<ExtendedOperationHandler> extendedOperationHandlers =
@@ -1044,6 +1050,31 @@
 
 
     /**
+     * Sets the mode for this LdapServer to accept requests with or without a
+     * TLS secured connection via either StartTLS extended operations or using
+     * LDAPS.
+     * 
+     * @param confidentialityRequired true to require confidentiality
+     */
+    public void setConfidentialityRequired( boolean confidentialityRequired ) 
+    {
+		this.confidentialityRequired = confidentialityRequired;
+	}
+
+
+    /**
+     * Gets whether or not TLS secured connections are required to perform 
+     * operations on this LdapServer.
+     * 
+     * @return true if TLS secured connections are required, false otherwise
+     */
+	public boolean isConfidentialityRequired() 
+	{
+		return confidentialityRequired;
+	}
+
+
+	/**
      * A snickers based BER Decoder factory.
      */
     private static final class ProtocolCodecFactoryImpl implements ProtocolCodecFactory

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/AbstractLdapHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/AbstractLdapHandler.java?rev=669253&r1=669252&r2=669253&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/AbstractLdapHandler.java
(original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/AbstractLdapHandler.java
Wed Jun 18 11:53:31 2008
@@ -24,6 +24,9 @@
 import org.apache.directory.server.ldap.SessionRegistry;
 import org.apache.directory.shared.ldap.message.Message;
 import org.apache.directory.shared.ldap.message.MutableControl;
+import org.apache.directory.shared.ldap.message.ResultCodeEnum;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoSession;
 import org.apache.mina.handler.demux.MessageHandler;
 
 import javax.naming.NamingException;
@@ -51,6 +54,33 @@
     {
         this.ldapServer = provider;
     }
+    
+    
+    /**
+     * Checks to see if confidentiality requirements are met.  If the 
+     * LdapServer requires confidentiality and the SSLFilter is engaged
+     * this will return true.  If confidentiality is not required this 
+     * will return true.  If confidentially is required and the SSLFilter
+     * is not engaged in the IoFilterChain this will return false.
+     * 
+     * This method is used by handlers to determine whether to send back
+     * {@link ResultCodeEnum#CONFIDENTIALITY_REQUIRED} error responses back
+     * to clients.
+     * 
+     * @param session the MINA IoSession to check for TLS security
+     * @return true if confidentiality requirement is met, false otherwise
+     */
+    public final boolean isConfidentialityRequirementSatisfied( IoSession session )
+    {
+    	
+    	if ( ! ldapServer.isConfidentialityRequired() )
+    	{
+    		return true;
+    	}
+    	
+        IoFilterChain chain = session.getFilterChain();
+        return chain.contains( "sslFilter" );
+    }
 
 
     public final SessionRegistry getSessionRegistry()

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultAddHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultAddHandler.java?rev=669253&r1=669252&r2=669253&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultAddHandler.java
(original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultAddHandler.java
Wed Jun 18 11:53:31 2008
@@ -65,6 +65,15 @@
 
         try
         {
+            // protect against insecure conns when confidentiality is required 
+            if ( ! isConfidentialityRequirementSatisfied( session ) )
+            {
+            	result.setResultCode( ResultCodeEnum.CONFIDENTIALITY_REQUIRED );
+            	result.setErrorMessage( "Confidentiality (TLS secured connection) is required."
);
+            	session.write( req.getResultResponse() );
+            	return;
+            }
+            
             LdapContext ctx = getSessionRegistry().getLdapContext( session, null, true );
 
             if ( req.getControls().containsKey( ManageDsaITControl.CONTROL_OID ) )

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultBindHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultBindHandler.java?rev=669253&r1=669252&r2=669253&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultBindHandler.java
(original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultBindHandler.java
Wed Jun 18 11:53:31 2008
@@ -721,7 +721,17 @@
                 LOG.debug( "Using SASL authentication with mechanism:  {}", bindRequest.getSaslMechanism()
);
             }
         }
-
+        
+        // protect against insecure conns when confidentiality is required 
+        if ( ! isConfidentialityRequirementSatisfied( session ) )
+        {
+        	LdapResult result = bindRequest.getResultResponse().getLdapResult();
+        	result.setResultCode( ResultCodeEnum.CONFIDENTIALITY_REQUIRED );
+        	result.setErrorMessage( "Confidentiality (TLS secured connection) is required."
);
+        	session.write( bindRequest.getResultResponse() );
+        	return;
+        }
+        
         // Guard clause:  LDAP version 3
         if ( !bindRequest.getVersion3() )
         {

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultCompareHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultCompareHandler.java?rev=669253&r1=669252&r2=669253&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultCompareHandler.java
(original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultCompareHandler.java
Wed Jun 18 11:53:31 2008
@@ -58,6 +58,15 @@
 
         try
         {
+            // protect against insecure conns when confidentiality is required 
+            if ( ! isConfidentialityRequirementSatisfied( session ) )
+            {
+            	result.setResultCode( ResultCodeEnum.CONFIDENTIALITY_REQUIRED );
+            	result.setErrorMessage( "Confidentiality (TLS secured connection) is required."
);
+            	session.write( req.getResultResponse() );
+            	return;
+            }
+            
             LdapContext ctx = getSessionRegistry().getLdapContext( session, null, true );
             ServerLdapContext newCtx = ( ServerLdapContext ) ctx.lookup( "" );
 

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultDeleteHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultDeleteHandler.java?rev=669253&r1=669252&r2=669253&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultDeleteHandler.java
(original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultDeleteHandler.java
Wed Jun 18 11:53:31 2008
@@ -58,6 +58,15 @@
 
         try
         {
+            // protect against insecure conns when confidentiality is required 
+            if ( ! isConfidentialityRequirementSatisfied( session ) )
+            {
+            	result.setResultCode( ResultCodeEnum.CONFIDENTIALITY_REQUIRED );
+            	result.setErrorMessage( "Confidentiality (TLS secured connection) is required."
);
+            	session.write( req.getResultResponse() );
+            	return;
+            }
+            
             LdapContext ctx = getSessionRegistry().getLdapContext( session, null, true );
             if ( req.getControls().containsKey( ManageDsaITControl.CONTROL_OID ) )
             {

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultExtendedHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultExtendedHandler.java?rev=669253&r1=669252&r2=669253&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultExtendedHandler.java
(original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultExtendedHandler.java
Wed Jun 18 11:53:31 2008
@@ -21,6 +21,7 @@
 
 
 import org.apache.directory.server.ldap.ExtendedOperationHandler;
+import org.apache.directory.server.ldap.handlers.extended.StartTlsHandler;
 import org.apache.directory.shared.ldap.message.ExtendedRequest;
 import org.apache.directory.shared.ldap.message.ExtendedResponse;
 import org.apache.directory.shared.ldap.message.LdapResult;
@@ -55,6 +56,19 @@
         {
             try
             {
+            	if ( ! req.getOid().equals( StartTlsHandler.EXTENSION_OID ) )
+            	{
+	                // protect against insecure conns when confidentiality is required 
+	                if ( ! isConfidentialityRequirementSatisfied( session ) )
+	                {
+	                	LdapResult result = req.getResultResponse().getLdapResult();
+	                	result.setResultCode( ResultCodeEnum.CONFIDENTIALITY_REQUIRED );
+	                	result.setErrorMessage( "Confidentiality (TLS secured connection) is required."
);
+	                	session.write( req.getResultResponse() );
+	                	return;
+	                }
+            	}
+                
                 handler.handleExtendedOperation( session, getSessionRegistry(), req );
             }
             catch ( Exception e )

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultModifyDnHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultModifyDnHandler.java?rev=669253&r1=669252&r2=669253&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultModifyDnHandler.java
(original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultModifyDnHandler.java
Wed Jun 18 11:53:31 2008
@@ -89,6 +89,15 @@
         {
             try
             {
+                // protect against insecure conns when confidentiality is required 
+                if ( ! isConfidentialityRequirementSatisfied( session ) )
+                {
+                	result.setResultCode( ResultCodeEnum.CONFIDENTIALITY_REQUIRED );
+                	result.setErrorMessage( "Confidentiality (TLS secured connection) is required."
);
+                	session.write( req.getResultResponse() );
+                	return;
+                }
+                
                 LdapContext ctx = getSessionRegistry().getLdapContext( session, null, true
);
 
                 if ( req.getControls().containsKey( ManageDsaITControl.CONTROL_OID ) )

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultModifyHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultModifyHandler.java?rev=669253&r1=669252&r2=669253&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultModifyHandler.java
(original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultModifyHandler.java
Wed Jun 18 11:53:31 2008
@@ -58,6 +58,15 @@
 
         try
         {
+            // protect against insecure conns when confidentiality is required 
+            if ( ! isConfidentialityRequirementSatisfied( session ) )
+            {
+            	result.setResultCode( ResultCodeEnum.CONFIDENTIALITY_REQUIRED );
+            	result.setErrorMessage( "Confidentiality (TLS secured connection) is required."
);
+            	session.write( req.getResultResponse() );
+            	return;
+            }
+        	
             LdapContext ctx = getSessionRegistry().getLdapContext( session, null, true );
             if ( req.getControls().containsKey( ManageDsaITControl.CONTROL_OID ) )
             {

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultSearchHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultSearchHandler.java?rev=669253&r1=669252&r2=669253&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultSearchHandler.java
(original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/handlers/DefaultSearchHandler.java
Wed Jun 18 11:53:31 2008
@@ -250,6 +250,16 @@
 
         try
         {
+            // protect against insecure conns when confidentiality is required 
+            if ( ! isConfidentialityRequirementSatisfied( session ) )
+            {
+            	LdapResult result = req.getResultResponse().getLdapResult();
+            	result.setResultCode( ResultCodeEnum.CONFIDENTIALITY_REQUIRED );
+            	result.setErrorMessage( "Confidentiality (TLS secured connection) is required."
);
+            	session.write( req.getResultResponse() );
+            	return;
+            }
+
             // ===============================================================
             // Find session context
             // ===============================================================

Added: directory/apacheds/trunk/server-unit/src/test/java/org/apache/directory/server/ssl/ConfidentialityRequiredITest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/server-unit/src/test/java/org/apache/directory/server/ssl/ConfidentialityRequiredITest.java?rev=669253&view=auto
==============================================================================
--- directory/apacheds/trunk/server-unit/src/test/java/org/apache/directory/server/ssl/ConfidentialityRequiredITest.java
(added)
+++ directory/apacheds/trunk/server-unit/src/test/java/org/apache/directory/server/ssl/ConfidentialityRequiredITest.java
Wed Jun 18 11:53:31 2008
@@ -0,0 +1,276 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.directory.server.ssl;
+
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+
+import javax.naming.AuthenticationNotSupportedException;
+import javax.naming.Context;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import javax.naming.ldap.InitialLdapContext;
+import javax.naming.ldap.LdapContext;
+import javax.naming.ldap.StartTlsRequest;
+import javax.naming.ldap.StartTlsResponse;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSession;
+
+import org.apache.directory.server.unit.AbstractServerTest;
+import org.apache.directory.shared.ldap.message.AttributeImpl;
+import org.apache.directory.shared.ldap.message.AttributesImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Test case to verify proper operation of confidentiality requirements as 
+ * specified in https://issues.apache.org/jira/browse/DIRSERVER-1189.  
+ * 
+ * Starts up the server binds via SUN JNDI provider to perform various 
+ * operations on entries which should be rejected when a TLS secured 
+ * connection is not established.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev: 639006 $
+ */
+public class ConfidentialityRequiredITest extends AbstractServerTest 
+{
+    private static final Logger LOG = LoggerFactory.getLogger( ConfidentialityRequiredITest.class
);
+    private File ksFile;
+    
+    
+    /**
+     * Sets up the key store and installs the self signed certificate for the 
+     * server (created on first startup) which is to be used by the StartTLS 
+     * JDNDI client that will connect.  The key store is created from scratch
+     * programmatically and whipped on each run.  The certificate is acquired 
+     * by pulling down the bytes for administrator's userCertificate from 
+     * uid=admin,ou=system.  We use sysRoot direct context instead of one over
+     * the wire since the server is configured to prevent connections without
+     * TLS secured connections.
+     */
+    public void setUp() throws Exception
+    {
+    	super.setUp();
+    	
+    	if ( ksFile != null && ksFile.exists() )
+    	{
+    		ksFile.delete();
+    	}
+    	
+    	ksFile = File.createTempFile( "testStore", "ks" );
+
+        Attributes adminEntry = sysRoot.getAttributes( "uid=admin" );
+    	Attribute userCertificateAttr = adminEntry.get( "userCertificate" );
+    	
+    	assertNotNull( userCertificateAttr );
+    	byte[] userCertificate = ( byte[] ) userCertificateAttr.get();
+    	assertNotNull( userCertificate );
+    	ByteArrayInputStream in = new ByteArrayInputStream( userCertificate );
+    	
+    	CertificateFactory factory = CertificateFactory.getInstance( "X.509" );
+    	Certificate cert = factory.generateCertificate( in );
+    	KeyStore ks = KeyStore.getInstance( KeyStore.getDefaultType() );
+    	ks.load( null, null );
+    	ks.setCertificateEntry( "apacheds", cert );
+    	ks.store( new FileOutputStream( ksFile ), "changeit".toCharArray() );
+    	LOG.debug( "Keystore file installed: {}", ksFile.getAbsolutePath() );
+    }
+    
+    
+    /**
+     * Just deletes the generated key store file.
+     */
+    public void tearDown() throws Exception
+    {
+    	if ( ksFile != null && ksFile.exists() )
+    	{
+    		ksFile.delete();
+    	}
+    	
+    	LOG.debug( "Keystore file deleted: {}", ksFile.getAbsolutePath() );
+    	super.tearDown();
+    }
+    
+
+    /**
+     * Setup confidentiality to be required.
+     */
+    protected void configureLdapServer()
+    {
+    	super.configureLdapServer();
+    	ldapServer.setConfidentialityRequired( true );
+    }
+
+    
+    private LdapContext getSecuredContext() throws Exception
+    {
+    	System.setProperty ( "javax.net.ssl.trustStore", ksFile.getAbsolutePath() );
+    	System.setProperty ( "javax.net.ssl.keyStore", ksFile.getAbsolutePath() );
+    	System.setProperty ( "javax.net.ssl.keyStorePassword", "changeit" );
+    	LOG.debug( "testStartTls() test starting ... " );
+    	
+    	// Set up environment for creating initial context
+    	Hashtable<String, Object> env = new Hashtable<String,Object>();
+        env.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" );
+        
+        // Must use the name of the server that is found in its certificate?
+        env.put( Context.PROVIDER_URL, "ldap://localhost:" + port );
+
+        // Create initial context
+        LOG.debug( "About to get initial context" );
+        LdapContext ctx = new InitialLdapContext( env, null );
+
+        // Start TLS
+        LOG.debug( "About send startTls extended operation" );
+        StartTlsResponse tls = ( StartTlsResponse ) ctx.extendedOperation( new StartTlsRequest()
);
+        LOG.debug( "Extended operation issued" );
+        tls.setHostnameVerifier( new HostnameVerifier() {
+            public boolean verify( String hostname, SSLSession session )
+            {
+                return true;
+            } 
+        } );
+        LOG.debug( "TLS negotion about to begin" );
+        tls.negotiate();
+        return ctx;
+    }
+    
+
+    /**
+     * Checks to make sure insecure binds fail while secure binds succeed.
+     */
+    public void testConfidentiality() throws Exception
+    {
+    	// -------------------------------------------------------------------
+    	// Unsecured bind should fail
+    	// -------------------------------------------------------------------
+
+    	try
+    	{
+    		getWiredContext();
+    		fail( "Should not get here due to violation of confidentiality requirements" );
+    	}
+    	catch( AuthenticationNotSupportedException e )
+    	{
+    	}
+    	
+    	// -------------------------------------------------------------------
+    	// get anonymous connection with StartTLS (no bind request sent)
+    	// -------------------------------------------------------------------
+
+    	LdapContext ctx = getSecuredContext();
+    	assertNotNull( ctx );
+    	
+    	// -------------------------------------------------------------------
+    	// upgrade connection via bind request (same physical connection - TLS)
+    	// -------------------------------------------------------------------
+
+    	ctx.addToEnvironment( Context.SECURITY_PRINCIPAL, "uid=admin,ou=system" );
+    	ctx.addToEnvironment( Context.SECURITY_CREDENTIALS, "secret" );
+    	ctx.addToEnvironment( Context.SECURITY_AUTHENTICATION, "simple" );
+    	ctx.reconnect( null );
+    	
+    	// -------------------------------------------------------------------
+    	// do a search and confirm
+    	// -------------------------------------------------------------------
+
+    	NamingEnumeration<SearchResult> results = ctx.search( "ou=system", "(objectClass=*)",
new SearchControls() );
+    	Set<String> names = new HashSet<String>();
+    	while( results.hasMore() )
+    	{
+    		names.add( results.next().getName() );
+    	}
+    	results.close();
+    	assertTrue( names.contains( "prefNodeName=sysPrefRoot" ) );
+    	assertTrue( names.contains( "ou=users" ) );
+    	assertTrue( names.contains( "ou=configuration" ) );
+    	assertTrue( names.contains( "uid=admin" ) );
+    	assertTrue( names.contains( "ou=groups" ) );
+    	
+    	// -------------------------------------------------------------------
+    	// do add and confirm
+    	// -------------------------------------------------------------------
+
+    	AttributesImpl attrs = new AttributesImpl( "objectClass", "person", true );
+    	attrs.put( "sn", "foo" );
+    	attrs.put( "cn", "foo bar" );
+    	ctx.createSubcontext( "cn=foo bar,ou=system", attrs );
+    	assertNotNull( ctx.lookup( "cn=foo bar,ou=system" ) );
+    	
+    	// -------------------------------------------------------------------
+    	// do modify and confirm
+    	// -------------------------------------------------------------------
+
+    	ModificationItem[] mods = new ModificationItem[] {
+    			new ModificationItem( DirContext.ADD_ATTRIBUTE, new AttributeImpl( "cn", "fbar" )
)
+    	};
+    	ctx.modifyAttributes( "cn=foo bar,ou=system", mods );
+    	Attributes reread = ( Attributes ) ctx.getAttributes( "cn=foo bar,ou=system" );
+    	assertTrue( reread.get( "cn" ).contains( "fbar" ) );
+    	
+    	// -------------------------------------------------------------------
+    	// do rename and confirm 
+    	// -------------------------------------------------------------------
+
+    	ctx.rename( "cn=foo bar,ou=system", "cn=fbar,ou=system" );
+    	try
+    	{
+    		ctx.getAttributes( "cn=foo bar,ou=system" );
+    		fail( "old name of renamed entry should not be found" );
+    	}
+    	catch ( NameNotFoundException e )
+    	{
+    	}
+    	reread = ( Attributes ) ctx.getAttributes( "cn=fbar,ou=system" );
+    	assertTrue( reread.get( "cn" ).contains( "fbar" ) );
+    	
+    	// -------------------------------------------------------------------
+    	// do delete and confirm
+    	// -------------------------------------------------------------------
+
+    	ctx.destroySubcontext( "cn=fbar,ou=system" );
+    	try
+    	{
+    		ctx.getAttributes( "cn=fbar,ou=system" );
+    		fail( "deleted entry should not be found" );
+    	}
+    	catch ( NameNotFoundException e )
+    	{
+    	}
+    	
+    	ctx.close();
+    }
+}



Mime
View raw message