You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by tr...@apache.org on 2006/01/04 12:32:16 UTC

svn commit: r365895 - in /directory/sandbox/trustin/ldaps: ./ apacheds-build/ apacheds-core-unit/ apacheds-plugin/ apacheds-server-main/ apacheds-server-unit/ apacheds-server/ apacheds-server/src/main/java/org/apache/ldap/server/configuration/ apacheds...

Author: trustin
Date: Wed Jan  4 03:31:44 2006
New Revision: 365895

URL: http://svn.apache.org/viewcvs?rev=365895&view=rev
Log:
Branched again from the new trunk.


Added:
    directory/sandbox/trustin/ldaps/
      - copied from r365831, directory/trunk/
    directory/sandbox/trustin/ldaps/README.txt
      - copied unchanged from r365894, directory/trunk/README.txt
    directory/sandbox/trustin/ldaps/apacheds/
      - copied from r365894, directory/trunk/apacheds/
    directory/sandbox/trustin/ldaps/apacheds-build/
      - copied from r365894, directory/trunk/apacheds-build/
    directory/sandbox/trustin/ldaps/apacheds-core-unit/
      - copied from r365894, directory/trunk/apacheds-core-unit/
    directory/sandbox/trustin/ldaps/apacheds-plugin/
      - copied from r365894, directory/trunk/apacheds-plugin/
    directory/sandbox/trustin/ldaps/apacheds-server/
      - copied from r365894, directory/trunk/apacheds-server/
    directory/sandbox/trustin/ldaps/apacheds-server-main/
      - copied from r365894, directory/trunk/apacheds-server-main/
    directory/sandbox/trustin/ldaps/apacheds-server-unit/
      - copied from r365894, directory/trunk/apacheds-server-unit/
    directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/jndi/support/
    directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/jndi/support/ServerX509TrustManager.java   (with props)
    directory/sandbox/trustin/ldaps/apacheds-shared/
      - copied from r365894, directory/trunk/apacheds-shared/
    directory/sandbox/trustin/ldaps/asn1/
      - copied from r365894, directory/trunk/asn1/
    directory/sandbox/trustin/ldaps/changepw-protocol/
      - copied from r365894, directory/trunk/changepw-protocol/
    directory/sandbox/trustin/ldaps/codesize.sh
      - copied unchanged from r365894, directory/trunk/codesize.sh
    directory/sandbox/trustin/ldaps/dhcp-protocol/
      - copied from r365894, directory/trunk/dhcp-protocol/
    directory/sandbox/trustin/ldaps/dns-protocol/
      - copied from r365894, directory/trunk/dns-protocol/
    directory/sandbox/trustin/ldaps/kerberos-common/
      - copied from r365894, directory/trunk/kerberos-common/
    directory/sandbox/trustin/ldaps/kerberos-protocol/
      - copied from r365894, directory/trunk/kerberos-protocol/
    directory/sandbox/trustin/ldaps/ldap-common/
      - copied from r365894, directory/trunk/ldap-common/
    directory/sandbox/trustin/ldaps/ldap-protocol/
      - copied from r365894, directory/trunk/ldap-protocol/
    directory/sandbox/trustin/ldaps/mina/
      - copied from r365894, directory/trunk/mina/
    directory/sandbox/trustin/ldaps/mina-asn1/
      - copied from r365894, directory/trunk/mina-asn1/
    directory/sandbox/trustin/ldaps/mina-build/
      - copied from r365894, directory/trunk/mina-build/
    directory/sandbox/trustin/ldaps/mina-examples/
      - copied from r365894, directory/trunk/mina-examples/
    directory/sandbox/trustin/ldaps/mina-spring/
      - copied from r365894, directory/trunk/mina-spring/
    directory/sandbox/trustin/ldaps/mina-ssl/
      - copied from r365894, directory/trunk/mina-ssl/
    directory/sandbox/trustin/ldaps/ntp-protocol/
      - copied from r365894, directory/trunk/ntp-protocol/
    directory/sandbox/trustin/ldaps/pom.xml
      - copied unchanged from r365894, directory/trunk/pom.xml
    directory/sandbox/trustin/ldaps/protocol-common/
      - copied from r365894, directory/trunk/protocol-common/
    directory/sandbox/trustin/ldaps/todo.txt
      - copied unchanged from r365894, directory/trunk/todo.txt
Modified:
    directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/configuration/MutableServerStartupConfiguration.java
    directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/configuration/ServerStartupConfiguration.java
    directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/jndi/ServerContextFactory.java

Modified: directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/configuration/MutableServerStartupConfiguration.java
URL: http://svn.apache.org/viewcvs/directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/configuration/MutableServerStartupConfiguration.java?rev=365895&r1=365894&r2=365895&view=diff
==============================================================================
--- directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/configuration/MutableServerStartupConfiguration.java (original)
+++ directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/configuration/MutableServerStartupConfiguration.java Wed Jan  4 03:31:44 2006
@@ -125,4 +125,19 @@
     {
         super.setLdifFilters( ldifFilters );
     }
+    
+    public void setEnableLdaps( boolean enableLdaps )
+    {
+        super.setEnableLdaps( enableLdaps );
+    }
+
+    public void setLdapsCertificateFile( File ldapsCertificateFile )
+    {
+        super.setLdapsCertificateFile( ldapsCertificateFile );
+    }
+
+    public void setLdapsCertificatePassword( String ldapsCertificatePassword )
+    {
+        super.setLdapsCertificatePassword( ldapsCertificatePassword );
+    }
 }

Modified: directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/configuration/ServerStartupConfiguration.java
URL: http://svn.apache.org/viewcvs/directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/configuration/ServerStartupConfiguration.java?rev=365895&r1=365894&r2=365895&view=diff
==============================================================================
--- directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/configuration/ServerStartupConfiguration.java (original)
+++ directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/configuration/ServerStartupConfiguration.java Wed Jan  4 03:31:44 2006
@@ -44,6 +44,12 @@
     private ServiceRegistry minaServiceRegistry = new SimpleServiceRegistry();
     private int ldapPort = 389;
     private int ldapsPort = 636;
+    private File ldapsCertificateFile = new File(
+            this.getWorkingDirectory().getPath() + File.separator +
+            "certificates" + File.separator +
+            "server.cert" );
+    private String ldapsCertificatePassword = "changeit";
+    private boolean enableLdaps = false;
     private boolean enableKerberos = false;
     private boolean enableChangePassword = false;
     private boolean enableNtp = false;
@@ -151,6 +157,69 @@
     {
         ConfigurationUtil.validatePortNumber( ldapsPort );
         this.ldapsPort = ldapsPort;
+    }
+    
+    /**
+     * Returns <tt>true</tt> if LDAPS is enabled.
+     */
+    public boolean isEnableLdaps()
+    {
+        return enableLdaps;
+    }
+
+    /**
+     * Sets if LDAPS is enabled or not.
+     */
+    protected void setEnableLdaps( boolean enableLdaps )
+    {
+        this.enableLdaps = enableLdaps;
+    }
+    
+    /**
+     * Returns the path of the X509 (or JKS) certificate file for LDAPS.
+     * The default value is <tt>"&lt;WORKDIR&gt;/certificates/server.cert"</tt>. 
+     * @return
+     */
+    public File getLdapsCertificateFile()
+    {
+        return ldapsCertificateFile;
+    }
+    
+    /**
+     * Sets the path of the SunX509 certificate file (either PKCS12 or JKS format)
+     * for LDAPS.
+     */
+    protected void setLdapsCertificateFile( File ldapsCertificateFile )
+    {
+        if( ldapsCertificateFile == null )
+        {
+            throw new ConfigurationException( "LdapsCertificateFile cannot be null." );
+        }
+        this.ldapsCertificateFile = ldapsCertificateFile;
+    }
+    
+    /**
+     * Returns the password which is used to load the the SunX509 certificate file
+     * (either PKCS12 or JKS format).
+     * The default value is <tt>"changeit"</tt>.  This is the same value with what
+     * <a href="http://jakarta.apache.org/tomcat/">Apache Jakarta Tomcat</a> uses by
+     * default.
+     */
+    public String getLdapsCertificatePassword()
+    {
+        return ldapsCertificatePassword;
+    }
+    
+    /**
+     * Sets the password which is used to load the LDAPS certificate file.
+     */
+    protected void setLdapsCertificatePassword( String ldapsCertificatePassword )
+    {
+        if( ldapsCertificatePassword == null )
+        {
+            throw new ConfigurationException( "LdapsCertificatePassword cannot be null." );
+        }
+        this.ldapsCertificatePassword = ldapsCertificatePassword;
     }
 
     /**

Modified: directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/jndi/ServerContextFactory.java
URL: http://svn.apache.org/viewcvs/directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/jndi/ServerContextFactory.java?rev=365895&r1=365894&r2=365895&view=diff
==============================================================================
--- directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/jndi/ServerContextFactory.java (original)
+++ directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/jndi/ServerContextFactory.java Wed Jan  4 03:31:44 2006
@@ -17,38 +17,52 @@
 package org.apache.ldap.server.jndi;
 
 
-import java.io.IOException;
-import java.io.FileFilter;
 import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.IOException;
 import java.net.InetSocketAddress;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
 import java.util.Hashtable;
 import java.util.Iterator;
 
-import javax.naming.NamingException;
 import javax.naming.Context;
-import javax.naming.directory.DirContext;
+import javax.naming.NamingException;
 import javax.naming.directory.Attributes;
 import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
 
+import org.apache.changepw.ChangePasswordConfiguration;
+import org.apache.changepw.ChangePasswordServer;
+import org.apache.commons.lang.StringUtils;
 import org.apache.kerberos.kdc.KdcConfiguration;
 import org.apache.kerberos.kdc.KerberosServer;
 import org.apache.kerberos.store.JndiPrincipalStoreImpl;
 import org.apache.kerberos.store.PrincipalStore;
 import org.apache.ldap.common.exception.LdapConfigurationException;
+import org.apache.ldap.common.exception.LdapNamingException;
 import org.apache.ldap.server.DirectoryService;
 import org.apache.ldap.server.configuration.ServerStartupConfiguration;
+import org.apache.ldap.server.jndi.support.ServerX509TrustManager;
 import org.apache.ldap.server.protocol.ExtendedOperationHandler;
 import org.apache.ldap.server.protocol.LdapProtocolProvider;
+import org.apache.mina.common.DefaultIoFilterChainBuilder;
+import org.apache.mina.common.IoFilterChainBuilder;
 import org.apache.mina.common.TransportType;
+import org.apache.mina.filter.SSLFilter;
 import org.apache.mina.registry.Service;
 import org.apache.mina.registry.ServiceRegistry;
-import org.apache.ntp.NtpServer;
 import org.apache.ntp.NtpConfiguration;
+import org.apache.ntp.NtpServer;
 import org.apache.protocol.common.LoadStrategy;
 import org.apache.protocol.common.store.LdifFileLoader;
-import org.apache.changepw.ChangePasswordServer;
-import org.apache.changepw.ChangePasswordConfiguration;
-import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -67,6 +81,7 @@
     private static final String LDIF_FILES_DN = "ou=loadedLdifFiles,ou=configuration,ou=system";
 
     private static Service ldapService;
+    private static Service ldapsService;
     private static KerberosServer kdcServer;
     private static ChangePasswordServer changePasswordServer;
     private static NtpServer ntpServer;
@@ -93,6 +108,16 @@
                 ldapService = null;
             }
 
+            if ( ldapsService != null )
+            {
+                minaRegistry.unbind( ldapsService );
+                if ( log.isInfoEnabled() )
+                {
+                    log.info( "Unbind of LDAPS Service complete: " + ldapService );
+                }
+                ldapsService = null;
+            }
+
             if ( kdcServer != null )
             {
                 kdcServer.destroy();
@@ -137,48 +162,11 @@
         if ( cfg.isEnableNetworking() )
         {
             setupRegistry( cfg );
-            startLdapProtocol( cfg, env );
-
-            if ( cfg.isEnableKerberos() )
-            {
-                try
-                {
-                    KdcConfiguration kdcConfiguration = new KdcConfiguration( env, LoadStrategy.PROPS );
-                    PrincipalStore kdcStore = new JndiPrincipalStoreImpl( kdcConfiguration, this );
-                    kdcServer = new KerberosServer( kdcConfiguration, minaRegistry, kdcStore );
-                }
-                catch ( Throwable t )
-                {
-                    log.error( "Failed to start the Kerberos service", t );
-                }
-            }
-
-            if ( cfg.isEnableChangePassword() )
-            {
-                try
-                {
-                    ChangePasswordConfiguration changePasswordConfiguration = new ChangePasswordConfiguration( env, LoadStrategy.PROPS );
-                    PrincipalStore store = new JndiPrincipalStoreImpl( changePasswordConfiguration, this );
-                    changePasswordServer = new ChangePasswordServer( changePasswordConfiguration, minaRegistry, store );
-                }
-                catch ( Throwable t )
-                {
-                    log.error( "Failed to start the Change Password service", t );
-                }
-            }
-
-            if ( cfg.isEnableNtp() )
-            {
-                try
-                {
-                    NtpConfiguration ntpConfig = new NtpConfiguration( env, LoadStrategy.PROPS );
-                    ntpServer = new NtpServer( ntpConfig, minaRegistry );
-                }
-                catch ( Throwable t )
-                {
-                    log.error( "Failed to start the NTP service", t );
-                }
-            }
+            startLDAP( cfg, env );
+            startLDAPS( cfg, env );
+            startKerberos(cfg, env);
+            startChangePassword(cfg, env);
+            startNTP(cfg, env);
         }
     }
 
@@ -359,11 +347,106 @@
      *
      * @throws NamingException if there are problems starting the LDAP provider
      */
-    private void startLdapProtocol( ServerStartupConfiguration cfg, Hashtable env ) throws NamingException
+    private void startLDAP( ServerStartupConfiguration cfg, Hashtable env ) throws NamingException
     {
+        // Skip if disabled
         int port = cfg.getLdapPort();
-        Service service = new Service( "ldap", TransportType.SOCKET, new InetSocketAddress( port ) );
+        if( port < 0 )
+        {
+            return;
+        }
+        
+        Service service = new Service( "LDAP", TransportType.SOCKET, new InetSocketAddress( port ) );
+        startLDAP0( cfg, env, service, new DefaultIoFilterChainBuilder() );
+    }
 
+    /**
+     * Starts up the LDAPS protocol provider to service LDAPS requests
+     *
+     * @throws NamingException if there are problems starting the LDAPS provider
+     */
+    private void startLDAPS( ServerStartupConfiguration cfg, Hashtable env ) throws NamingException
+    {
+        // Skip if disabled
+        int port = cfg.getLdapsPort();
+        if( port < 0 )
+        {
+            return;
+        }
+        
+        // Load the certificate
+        char[] certPasswdChars = cfg.getLdapsCertificatePassword().toCharArray();
+        String storePath = cfg.getLdapsCertificateFile().getPath();
+        
+        KeyStore ks = null;
+        try
+        {
+            ks = loadKeyStore( storePath, "PKCS12" );
+        }
+        catch( Exception e )
+        {
+            try
+            {
+                ks = loadKeyStore( storePath, "JKS" );
+            }
+            catch( Exception e2 )
+            {
+                throw ( NamingException ) new NamingException( "Failed to load a certificate: " + storePath ).initCause( e );
+            }
+        }
+
+        SSLContext sslCtx;
+        try
+        {
+            // Set up key manager factory to use our key store
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance( "SunX509" );
+            kmf.init( ks, certPasswdChars );
+    
+            // Initialize the SSLContext to work with our key managers.
+            sslCtx = SSLContext.getInstance( "TLS" );
+            sslCtx.init( kmf.getKeyManagers(),
+                    new TrustManager[] { new ServerX509TrustManager() }, new SecureRandom() );
+        }
+        catch( Exception e )
+        {
+            throw ( NamingException ) new NamingException( "Failed to create a SSL context." ).initCause( e );
+        }
+        
+        Service service = new Service( "LDAPS", TransportType.SOCKET, new InetSocketAddress( port ) );
+        DefaultIoFilterChainBuilder chain = new DefaultIoFilterChainBuilder();
+        chain.addLast( "SSL", new SSLFilter( sslCtx ) );
+        startLDAP0( cfg, env, service, chain );
+    }
+
+    private KeyStore loadKeyStore( String storePath, String storeType ) throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException
+    {
+        FileInputStream in = null;
+        // Create keystore
+        KeyStore ks = KeyStore.getInstance( storeType );
+        try
+        {
+            in = new FileInputStream( storePath );
+            ks.load( in, null );
+            return ks;
+        }
+        finally
+        {
+            if( in != null )
+            {
+                try
+                {
+                    in.close();
+                }
+                catch( IOException ignored )
+                {
+                }
+            }
+        }
+    }
+
+    private void startLDAP0( ServerStartupConfiguration cfg, Hashtable env, Service service, IoFilterChainBuilder chainBuilder )
+            throws LdapNamingException, LdapConfigurationException
+    {
         // Register all extended operation handlers.
         LdapProtocolProvider protocolProvider = new LdapProtocolProvider( ( Hashtable ) env.clone() );
         
@@ -376,21 +459,71 @@
         
         try
         {
-            minaRegistry.bind( service, protocolProvider.getHandler() );
+            minaRegistry.bind( service, protocolProvider.getHandler(), chainBuilder );
             ldapService = service;
             
             if ( log.isInfoEnabled() )
             {
-                log.info( "Successful bind of LDAP Service completed: " + ldapService );
+                log.info( "Successful bind of " + service.getName() + " Service completed: " + ldapService );
             }
         }
         catch ( IOException e )
         {
-            String msg = "Failed to bind the LDAP protocol service to the service registry: " + service;
+            String msg = "Failed to bind the " + service.getName() + " protocol service to the service registry: " + service;
             LdapConfigurationException lce = new LdapConfigurationException( msg );
             lce.setRootCause( e );
             log.error( msg, e );
             throw lce;
+        }
+    }
+
+
+    private void startKerberos(ServerStartupConfiguration cfg, Hashtable env) {
+        if ( cfg.isEnableKerberos() )
+        {
+            try
+            {
+                KdcConfiguration kdcConfiguration = new KdcConfiguration( env, LoadStrategy.PROPS );
+                PrincipalStore kdcStore = new JndiPrincipalStoreImpl( kdcConfiguration, this );
+                kdcServer = new KerberosServer( kdcConfiguration, minaRegistry, kdcStore );
+            }
+            catch ( Throwable t )
+            {
+                log.error( "Failed to start the Kerberos service", t );
+            }
+        }
+    }
+
+
+    private void startChangePassword(ServerStartupConfiguration cfg, Hashtable env) {
+        if ( cfg.isEnableChangePassword() )
+        {
+            try
+            {
+                ChangePasswordConfiguration changePasswordConfiguration = new ChangePasswordConfiguration( env, LoadStrategy.PROPS );
+                PrincipalStore store = new JndiPrincipalStoreImpl( changePasswordConfiguration, this );
+                changePasswordServer = new ChangePasswordServer( changePasswordConfiguration, minaRegistry, store );
+            }
+            catch ( Throwable t )
+            {
+                log.error( "Failed to start the Change Password service", t );
+            }
+        }
+    }
+
+
+    private void startNTP(ServerStartupConfiguration cfg, Hashtable env) {
+        if ( cfg.isEnableNtp() )
+        {
+            try
+            {
+                NtpConfiguration ntpConfig = new NtpConfiguration( env, LoadStrategy.PROPS );
+                ntpServer = new NtpServer( ntpConfig, minaRegistry );
+            }
+            catch ( Throwable t )
+            {
+                log.error( "Failed to start the NTP service", t );
+            }
         }
     }
 }

Added: directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/jndi/support/ServerX509TrustManager.java
URL: http://svn.apache.org/viewcvs/directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/jndi/support/ServerX509TrustManager.java?rev=365895&view=auto
==============================================================================
--- directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/jndi/support/ServerX509TrustManager.java (added)
+++ directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/jndi/support/ServerX509TrustManager.java Wed Jan  4 03:31:44 2006
@@ -0,0 +1,51 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.ldap.server.jndi.support;
+
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * An {@link X509TrustManager} for LDAP server.
+ *
+ * @author Trustin Lee
+ * @version $Rev$, $Date$
+ */
+public class ServerX509TrustManager implements X509TrustManager
+{
+    public ServerX509TrustManager()
+    {
+    }
+
+    public void checkClientTrusted( X509Certificate[] arg0, String arg1 ) throws CertificateException
+    {
+        // We don't check clients at all right now.
+        // XXX: Do we need a client-side certificates?
+    }
+
+    public void checkServerTrusted( X509Certificate[] arg0, String arg1 ) throws CertificateException
+    {
+        // It is server-side trust manager, so we don't need to check the server itself.
+    }
+
+    public X509Certificate[] getAcceptedIssuers()
+    {
+        return null;
+    }
+}

Propchange: directory/sandbox/trustin/ldaps/apacheds-server/src/main/java/org/apache/ldap/server/jndi/support/ServerX509TrustManager.java
------------------------------------------------------------------------------
    svn:keywords = HeadURL Id LastChangedBy LastChangedDate LastChangedRevision