You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2008/03/19 21:47:45 UTC
svn commit: r639006 - in /directory: apacheds/branches/bigbang/core/
apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/
apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/
apacheds/branch...
Author: akarasulu
Date: Wed Mar 19 13:47:36 2008
New Revision: 639006
URL: http://svn.apache.org/viewvc?rev=639006&view=rev
Log:
Adding zero conf StartTLS extended operation and zero conf LDAPS feature ...
o Uses DIT for KeyStore
- special schema elements added to apache schema to specifically handle the
server keys and certificates which are assigned to the administrative user
- special KeyStore implementation used
o Generates key on first start to automatically enable StartTLS with zero conf
o Uses BouncyCastle to generate self signed certificate on first start
o LDAPS feature modified to use same DIT based KeyStore and the same self
signed certificate and RSA keys generated or replaced by administrator
o Reduced configuration without need to include KeyStore file path and passwd
o Administrators can now update the keys and certificates directly from the DIT
Added:
directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/
directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/CoreKeyStoreSpi.java
directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/TlsKeyGenerator.java
directory/apacheds/branches/bigbang/core/src/test/java/org/apache/directory/server/core/security/
directory/apacheds/branches/bigbang/core/src/test/java/org/apache/directory/server/core/security/TlsKeyGeneratorTest.java
directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/StartTlsHandler.java
directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/StartTlsITest.java
directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DummySSLSocketFactory.java
Modified:
directory/apacheds/branches/bigbang/core/pom.xml
directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java
directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/PartitionNexus.java
directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapServer.java
directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/ssl/LdapsInitializer.java
directory/apacheds/branches/bigbang/schema-bootstrap/src/main/schema/apache.schema
directory/apacheds/branches/bigbang/server-unit/src/main/java/org/apache/directory/server/unit/AbstractServerTest.java
directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/StoredProcedureExecutionITest.java
directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/LdapsITest.java
directory/apacheds/branches/bigbang/server-xml/src/main/resources/server.xml
directory/installers/branches/bigbang/apacheds-noarch/ (props changed)
directory/installers/branches/bigbang/apacheds-noarch/log4j.properties
directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixTransformer.java
directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DirectoryClassUtils.java
Modified: directory/apacheds/branches/bigbang/core/pom.xml
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/pom.xml?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core/pom.xml (original)
+++ directory/apacheds/branches/bigbang/core/pom.xml Wed Mar 19 13:47:36 2008
@@ -100,6 +100,12 @@
<version>${pom.version}</version>
<scope>test</scope>
</dependency>
+
+ <dependency>
+ <groupId>bouncycastle</groupId>
+ <artifactId>bcprov-jdk15</artifactId>
+ </dependency>
+
</dependencies>
<build>
Modified: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java (original)
+++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java Wed Mar 19 13:47:36 2008
@@ -61,6 +61,7 @@
import org.apache.directory.server.core.schema.SchemaOperationControl;
import org.apache.directory.server.core.schema.SchemaPartitionDao;
import org.apache.directory.server.core.schema.SchemaService;
+import org.apache.directory.server.core.security.TlsKeyGenerator;
import org.apache.directory.server.core.subtree.SubentryInterceptor;
import org.apache.directory.server.core.trigger.TriggerInterceptor;
import org.apache.directory.server.schema.SerializableComparator;
@@ -992,6 +993,7 @@
serverEntry.put( SchemaConstants.CREATE_TIMESTAMP_AT, DateUtils.getGeneralizedTime() );
serverEntry.put( SchemaConstants.DISPLAY_NAME_AT, "Directory Superuser" );
+ TlsKeyGenerator.addKeyPair( serverEntry );
partitionNexus.add( new AddOperationContext( registries, PartitionNexus.getAdminName(), serverEntry ) );
}
Modified: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/PartitionNexus.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/PartitionNexus.java?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/PartitionNexus.java (original)
+++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/partition/PartitionNexus.java Wed Mar 19 13:47:36 2008
@@ -57,7 +57,7 @@
public abstract class PartitionNexus implements Partition
{
/** the admin super user uid */
- public final static String ADMIN_UID = "admin";
+ public static final String ADMIN_UID = "admin";
/** the initial admin passwd set on startup */
public static final String ADMIN_PASSWORD_STRING = "secret";
Added: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/CoreKeyStoreSpi.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/CoreKeyStoreSpi.java?rev=639006&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/CoreKeyStoreSpi.java (added)
+++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/CoreKeyStoreSpi.java Wed Mar 19 13:47:36 2008
@@ -0,0 +1,332 @@
+/*
+ * 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.core.security;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.Key;
+import java.security.KeyPair;
+import java.security.KeyStoreException;
+import java.security.KeyStoreSpi;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.NotImplementedException;
+import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.core.authn.LdapPrincipal;
+import org.apache.directory.server.core.entry.ServerEntry;
+import org.apache.directory.server.core.entry.ServerEntryUtils;
+import org.apache.directory.server.core.partition.PartitionNexus;
+import org.apache.directory.shared.ldap.constants.AuthenticationLevel;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.shared.ldap.util.SingletonEnumeration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A read only key store facility designed specifically for TLS/CA operations.
+ * It is only intended for accessing the 'apacheds' private/public key pairs
+ * as well as the self signed certificate.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class CoreKeyStoreSpi extends KeyStoreSpi
+{
+ private static final String APACHEDS_ALIAS = "apacheds";
+
+ private static final Logger LOG = LoggerFactory.getLogger( CoreKeyStoreSpi.class );
+
+ private DirectoryService directoryService;
+
+
+ /**
+ * Creates a new instance of LocalKeyStore.
+ */
+ public CoreKeyStoreSpi( DirectoryService directoryService )
+ {
+ LOG.debug( "Constructor called." );
+ this.directoryService = directoryService;
+ }
+
+
+ private ServerEntry getTlsEntry() throws NamingException
+ {
+ LdapDN adminDn = PartitionNexus.getAdminName();
+ LdapPrincipal principal = new LdapPrincipal( adminDn, AuthenticationLevel.SIMPLE );
+ Attributes attrs = directoryService.getJndiContext( principal ).getAttributes( adminDn );
+ return ServerEntryUtils.toServerEntry( attrs, adminDn, directoryService.getRegistries() );
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.security.KeyStoreSpi#engineAliases()
+ */
+ @Override
+ public Enumeration<String> engineAliases()
+ {
+ LOG.debug( "engineAliases() called." );
+ return new SingletonEnumeration<String>( APACHEDS_ALIAS );
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.security.KeyStoreSpi#engineContainsAlias(java.lang.String)
+ */
+ @Override
+ public boolean engineContainsAlias( String alias )
+ {
+ LOG.debug( "engineContainsAlias({}) called.", alias );
+
+ if ( alias.equalsIgnoreCase( APACHEDS_ALIAS ) )
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.security.KeyStoreSpi#engineDeleteEntry(java.lang.String)
+ */
+ @Override
+ public void engineDeleteEntry( String alias ) throws KeyStoreException
+ {
+ LOG.debug( "engineDeleteEntry({}) called.", alias );
+ throw new UnsupportedOperationException();
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.security.KeyStoreSpi#engineGetCertificate(java.lang.String)
+ */
+ @Override
+ public Certificate engineGetCertificate( String alias )
+ {
+ LOG.debug( "engineGetCertificate({}) called.", alias );
+ if ( alias.equalsIgnoreCase( APACHEDS_ALIAS ) )
+ {
+ try
+ {
+ ServerEntry entry = getTlsEntry();
+ return TlsKeyGenerator.getCertificate( entry );
+ }
+ catch ( NamingException e )
+ {
+ LOG.error( "Failed to access certificate in DIT.", e );
+ }
+ }
+
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.security.KeyStoreSpi#engineGetCertificateAlias(java.security.cert.Certificate)
+ */
+ @Override
+ public String engineGetCertificateAlias( Certificate cert )
+ {
+ LOG.debug( "engineGetCertificateAlias({}) called.", cert );
+
+ if ( cert instanceof X509Certificate )
+ {
+ LOG.debug( "Certificate in alias request is X.509 based." );
+ X509Certificate xcert = ( X509Certificate ) cert;
+ if ( xcert.getSubjectDN().toString().equals( TlsKeyGenerator.CERTIFICATE_PRINCIPAL_DN ) )
+ {
+ return APACHEDS_ALIAS;
+ }
+ }
+
+ try
+ {
+ ServerEntry entry = getTlsEntry();
+ if ( ArrayUtils.isEquals( cert.getEncoded(), entry.get( TlsKeyGenerator.USER_CERTIFICATE_AT ).getBytes() ) )
+ {
+ return APACHEDS_ALIAS;
+ }
+ }
+ catch ( Exception e )
+ {
+ LOG.error( "Failed on attempt to compare certificate bytes to determine alias.", e );
+ }
+
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.security.KeyStoreSpi#engineGetCertificateChain(java.lang.String)
+ */
+ @Override
+ public Certificate[] engineGetCertificateChain( String alias )
+ {
+ LOG.debug( "engineGetCertificateChain({}) called.", alias );
+ try
+ {
+ ServerEntry entry = getTlsEntry();
+ LOG.debug( "Entry:\n{}", entry );
+ return new Certificate[] { TlsKeyGenerator.getCertificate( entry ) };
+ }
+ catch ( Exception e )
+ {
+ LOG.error( "Failed on attempt to compare certificate bytes to determine alias.", e );
+ }
+
+ return new Certificate[0];
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.security.KeyStoreSpi#engineGetCreationDate(java.lang.String)
+ */
+ @Override
+ public Date engineGetCreationDate( String alias )
+ {
+ LOG.debug( "engineGetCreationDate({}) called.", alias );
+ return new Date();
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.security.KeyStoreSpi#engineGetKey(java.lang.String, char[])
+ */
+ @Override
+ public Key engineGetKey( String alias, char[] password ) throws NoSuchAlgorithmException, UnrecoverableKeyException
+ {
+ LOG.debug( "engineGetKey({}, {}) called.", alias, password );
+
+ try
+ {
+ ServerEntry entry = getTlsEntry();
+ KeyPair keyPair = TlsKeyGenerator.getKeyPair( entry );
+ return keyPair.getPrivate();
+ }
+ catch ( Exception e )
+ {
+ LOG.error( "Failed on attempt to extract key.", e );
+ }
+
+ return null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.security.KeyStoreSpi#engineIsCertificateEntry(java.lang.String)
+ */
+ @Override
+ public boolean engineIsCertificateEntry( String alias )
+ {
+ LOG.debug( "engineIsCertificateEntry({}) called.", alias );
+ return false;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.security.KeyStoreSpi#engineIsKeyEntry(java.lang.String)
+ */
+ @Override
+ public boolean engineIsKeyEntry( String alias )
+ {
+ LOG.debug( "engineIsKeyEntry({}) called.", alias );
+ return true;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.security.KeyStoreSpi#engineLoad(java.io.InputStream, char[])
+ */
+ @Override
+ public void engineLoad( InputStream stream, char[] password ) throws IOException, NoSuchAlgorithmException,
+ CertificateException
+ {
+ LOG.debug( "engineLoad({}, {}) called.", stream, password );
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.security.KeyStoreSpi#engineSetCertificateEntry(java.lang.String, java.security.cert.Certificate)
+ */
+ @Override
+ public void engineSetCertificateEntry( String alias, Certificate cert ) throws KeyStoreException
+ {
+ LOG.debug( "engineSetCertificateEntry({}, {}) called.", alias, cert );
+ throw new NotImplementedException();
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.security.KeyStoreSpi#engineSetKeyEntry(java.lang.String, byte[], java.security.cert.Certificate[])
+ */
+ @Override
+ public void engineSetKeyEntry( String alias, byte[] key, Certificate[] chain ) throws KeyStoreException
+ {
+ LOG.debug( "engineSetKeyEntry({}, key, {}) called.", alias, chain );
+ throw new NotImplementedException();
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.security.KeyStoreSpi#engineSetKeyEntry(java.lang.String, java.security.Key, char[], java.security.cert.Certificate[])
+ */
+ @Override
+ public void engineSetKeyEntry( String alias, Key key, char[] password, Certificate[] chain )
+ throws KeyStoreException
+ {
+ LOG.debug( "engineSetKeyEntry({}, key, {}, chain) called.", alias, new String( password ) );
+ throw new NotImplementedException();
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.security.KeyStoreSpi#engineSize()
+ */
+ @Override
+ public int engineSize()
+ {
+ LOG.debug( "engineSize() called." );
+ return 1;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.security.KeyStoreSpi#engineStore(java.io.OutputStream, char[])
+ */
+ @Override
+ public void engineStore( OutputStream stream, char[] password ) throws IOException, NoSuchAlgorithmException,
+ CertificateException
+ {
+ LOG.debug( "engineStore(stream, {}) called.", new String( password ) );
+ }
+}
Added: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/TlsKeyGenerator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/TlsKeyGenerator.java?rev=639006&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/TlsKeyGenerator.java (added)
+++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/security/TlsKeyGenerator.java Wed Mar 19 13:47:36 2008
@@ -0,0 +1,264 @@
+/*
+ * 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.core.security;
+
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Security;
+import java.util.Date;
+
+import javax.naming.NamingException;
+import javax.security.auth.x500.X500Principal;
+
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.EncodedKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+import org.apache.directory.server.core.entry.ServerAttribute;
+import org.apache.directory.server.core.entry.ServerEntry;
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.x509.X509V1CertificateGenerator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Generates the default RSA key pair for the server.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class TlsKeyGenerator
+{
+ private static final Logger LOG = LoggerFactory.getLogger( TlsKeyGenerator.class );
+
+ public static final String TLS_KEY_INFO_OC = "tlsKeyInfo";
+ public static final String PRIVATE_KEY_AT = "privateKey";
+ public static final String PUBLIC_KEY_AT = "publicKey";
+ public static final String KEY_ALGORITHM_AT = "keyAlgorithm";
+ public static final String PRIVATE_KEY_FORMAT_AT = "privateKeyFormat";
+ public static final String PUBLIC_KEY_FORMAT_AT = "publicKeyFormat";
+ public static final String USER_CERTIFICATE_AT = "userCertificate";
+
+ public static final String CERTIFICATE_PRINCIPAL_DN =
+ "CN=ApacheDS, OU=Directory, O=ASF, C=US";
+ private static final String ALGORITHM = "RSA";
+ private static final int KEY_SIZE = 1024;
+ private static final long YEAR_MILLIS = 365*24*3600*1000;
+
+
+ static
+ {
+ Security.addProvider( new BouncyCastleProvider() );
+ }
+
+
+ /**
+ * Gets the certificate associated with the self signed TLS private/public
+ * key pair.
+ *
+ * @param entry the TLS key/cert entry
+ * @return the X509 certificate associated with that entry
+ * @throws NamingException if there are problems accessing or decoding
+ */
+ public static X509Certificate getCertificate( ServerEntry entry ) throws NamingException
+ {
+ X509Certificate cert = null;
+ CertificateFactory certFactory = null;
+
+ try
+ {
+ certFactory = CertificateFactory.getInstance( "X.509", "BC" );
+ }
+ catch ( Exception e )
+ {
+ NamingException ne = new NamingException( "Failed to get BC Certificate factory for algorithm: X.509" );
+ ne.setRootCause( e );
+ throw ne;
+ }
+
+ byte[] certBytes = entry.get( USER_CERTIFICATE_AT ).getBytes();
+ InputStream in = new ByteArrayInputStream( certBytes );
+
+ try
+ {
+ cert = ( X509Certificate ) certFactory.generateCertificate( in );
+ }
+ catch ( CertificateException e )
+ {
+ NamingException ne = new NamingException( "Bad certificate format." );
+ ne.setRootCause( e );
+ throw ne;
+ }
+
+ return cert;
+ }
+
+
+ /**
+ * Extracts the public private key pair from the tlsKeyInfo entry.
+ *
+ * @param entry an entry of the tlsKeyInfo objectClass
+ * @return the private and public key pair
+ * @throws NamingException if there are format or access issues
+ */
+ public static KeyPair getKeyPair( ServerEntry entry ) throws NamingException
+ {
+ PublicKey publicKey = null;
+ PrivateKey privateKey = null;
+
+ KeyFactory keyFactory = null;
+ try
+ {
+ keyFactory = KeyFactory.getInstance( ALGORITHM );
+ }
+ catch ( Exception e )
+ {
+ NamingException ne = new NamingException( "Failed to get key factory for algorithm: " + ALGORITHM );
+ ne.setRootCause( e );
+ throw ne;
+ }
+
+ EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec( entry.get( PRIVATE_KEY_AT ).getBytes() );
+ try
+ {
+ privateKey = keyFactory.generatePrivate( privateKeySpec );
+ }
+ catch ( Exception e )
+ {
+ NamingException ne = new NamingException( "Bad private key format." );
+ ne.setRootCause( e );
+ throw ne;
+ }
+
+ EncodedKeySpec publicKeySpec = new X509EncodedKeySpec( entry.get( PUBLIC_KEY_AT ).getBytes() );
+ try
+ {
+ publicKey = keyFactory.generatePublic( publicKeySpec );
+ }
+ catch ( InvalidKeySpecException e )
+ {
+ NamingException ne = new NamingException( "Bad public key format." );
+ ne.setRootCause( e );
+ throw ne;
+ }
+
+ return new KeyPair( publicKey, privateKey );
+ }
+
+
+ /**
+ * Adds a private key pair along with a self signed certificate to an
+ * entry making sure it contains the objectClasses and attributes needed
+ * to support the additions. This function is intended for creating a TLS
+ * key value pair and self signed certificate for use by the server to
+ * authenticate itself during SSL handshakes in the course of establishing
+ * an LDAPS connection or a secure LDAP connection using StartTLS. Usually
+ * this information is added to the administrator user's entry so the
+ * administrator (effectively the server) can manage these security
+ * concerns.
+ *
+ * @param entry the entry to add security attributes to
+ * @throws NamingException on problems generating the content in the entry
+ */
+ public static void addKeyPair( ServerEntry entry ) throws NamingException
+ {
+ ServerAttribute objectClass = entry.get( SchemaConstants.OBJECT_CLASS_AT );
+ if ( objectClass == null )
+ {
+ entry.put( SchemaConstants.OBJECT_CLASS_AT, TLS_KEY_INFO_OC, SchemaConstants.INET_ORG_PERSON_OC );
+ }
+ else
+ {
+ objectClass.add( TLS_KEY_INFO_OC, SchemaConstants.INET_ORG_PERSON_OC );
+ }
+
+ KeyPairGenerator generator = null;
+ try
+ {
+ generator = KeyPairGenerator.getInstance( ALGORITHM );
+ }
+ catch ( NoSuchAlgorithmException e )
+ {
+ NamingException ne = new NamingException( "Cannot generate key pair for TLS" );
+ ne.setRootCause( e );
+ throw ne;
+ }
+
+ generator.initialize( KEY_SIZE );
+ KeyPair keypair = generator.genKeyPair();
+ entry.put( KEY_ALGORITHM_AT, ALGORITHM );
+
+ // Generate the private key attributes
+ PrivateKey privateKey = keypair.getPrivate();
+ entry.put( PRIVATE_KEY_AT, privateKey.getEncoded() );
+ entry.put( PRIVATE_KEY_FORMAT_AT, privateKey.getFormat() );
+ LOG.debug( "PrivateKey: {}", privateKey );
+
+ PublicKey publicKey = keypair.getPublic();
+ entry.put( PUBLIC_KEY_AT, publicKey.getEncoded() );
+ entry.put( PUBLIC_KEY_FORMAT_AT, publicKey.getFormat() );
+ LOG.debug( "PublicKey: {}", publicKey );
+
+ // Generate the self-signed certificate
+ Date startDate = new Date();
+ Date expiryDate = new Date( System.currentTimeMillis() + YEAR_MILLIS );
+ BigInteger serialNumber = BigInteger.valueOf( System.currentTimeMillis() );
+
+ X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
+ X500Principal dnName = new X500Principal( CERTIFICATE_PRINCIPAL_DN );
+
+ certGen.setSerialNumber( serialNumber );
+ certGen.setIssuerDN( dnName );
+ certGen.setNotBefore( startDate );
+ certGen.setNotAfter( expiryDate );
+ certGen.setSubjectDN( dnName );
+ certGen.setPublicKey( publicKey );
+ certGen.setSignatureAlgorithm( "SHA1With" + ALGORITHM );
+
+ try
+ {
+ X509Certificate cert = certGen.generate( privateKey, "BC" );
+ entry.put( USER_CERTIFICATE_AT, cert.getEncoded() );
+ LOG.debug( "X509 Certificate: {}", cert );
+ }
+ catch ( Exception e )
+ {
+ NamingException ne = new NamingException( "Cannot generate self signed certificate." );
+ ne.setRootCause( e );
+ throw ne;
+ }
+
+ LOG.info( "Keys and self signed certificate successfully generated." );
+ }
+}
Added: directory/apacheds/branches/bigbang/core/src/test/java/org/apache/directory/server/core/security/TlsKeyGeneratorTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/test/java/org/apache/directory/server/core/security/TlsKeyGeneratorTest.java?rev=639006&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/core/src/test/java/org/apache/directory/server/core/security/TlsKeyGeneratorTest.java (added)
+++ directory/apacheds/branches/bigbang/core/src/test/java/org/apache/directory/server/core/security/TlsKeyGeneratorTest.java Wed Mar 19 13:47:36 2008
@@ -0,0 +1,111 @@
+/*
+ * 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.core.security;
+
+
+import static org.junit.Assert.*;
+
+import java.io.FileInputStream;
+import java.security.KeyPair;
+import java.security.KeyStore;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.naming.NamingException;
+
+import org.apache.directory.server.core.entry.DefaultServerEntry;
+import org.apache.directory.server.schema.bootstrap.ApacheSchema;
+import org.apache.directory.server.schema.bootstrap.ApachemetaSchema;
+import org.apache.directory.server.schema.bootstrap.BootstrapSchemaLoader;
+import org.apache.directory.server.schema.bootstrap.CoreSchema;
+import org.apache.directory.server.schema.bootstrap.CosineSchema;
+import org.apache.directory.server.schema.bootstrap.InetorgpersonSchema;
+import org.apache.directory.server.schema.bootstrap.Schema;
+import org.apache.directory.server.schema.bootstrap.SystemSchema;
+import org.apache.directory.server.schema.registries.DefaultOidRegistry;
+import org.apache.directory.server.schema.registries.DefaultRegistries;
+import org.apache.directory.server.schema.registries.OidRegistry;
+import org.apache.directory.server.schema.registries.Registries;
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Test for the TlsKeyGenerator class.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class TlsKeyGeneratorTest
+{
+ private static final Logger LOG = LoggerFactory.getLogger( TlsKeyGeneratorTest.class );
+ private static BootstrapSchemaLoader loader;
+ private static Registries registries;
+ private static OidRegistry oidRegistry;
+
+
+ /**
+ * Initialize the registries once for the whole test suite
+ */
+ @BeforeClass
+ public static void setup() throws NamingException
+ {
+ loader = new BootstrapSchemaLoader();
+ oidRegistry = new DefaultOidRegistry();
+ registries = new DefaultRegistries( "bootstrap", loader, oidRegistry );
+
+ // load essential bootstrap schemas
+ Set<Schema> bootstrapSchemas = new HashSet<Schema>();
+ bootstrapSchemas.add( new ApachemetaSchema() );
+ bootstrapSchemas.add( new ApacheSchema() );
+ bootstrapSchemas.add( new CoreSchema() );
+ bootstrapSchemas.add( new SystemSchema() );
+ bootstrapSchemas.add( new InetorgpersonSchema() );
+ bootstrapSchemas.add( new CosineSchema() );
+ loader.loadWithDependencies( bootstrapSchemas, registries );
+
+ }
+
+
+ /**
+ * Test method for all methods in one.
+ */
+ @Test
+ public void testAll() throws NamingException
+ {
+ DefaultServerEntry entry = new DefaultServerEntry( registries, new LdapDN() );
+ TlsKeyGenerator.addKeyPair( entry );
+ LOG.debug( "Entry: {}", entry );
+ assertTrue( entry.contains( SchemaConstants.OBJECT_CLASS_AT, TlsKeyGenerator.TLS_KEY_INFO_OC ) );
+
+ KeyPair keyPair = TlsKeyGenerator.getKeyPair( entry );
+ assertNotNull( keyPair );
+
+ X509Certificate cert = TlsKeyGenerator.getCertificate( entry );
+ assertNotNull( cert );
+ }
+}
Modified: directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapServer.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapServer.java?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapServer.java (original)
+++ directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/LdapServer.java Wed Mar 19 13:47:36 2008
@@ -20,9 +20,11 @@
package org.apache.directory.server.ldap;
-import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
+import java.security.KeyStore;
+import java.security.Provider;
+import java.security.Security;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
@@ -38,6 +40,7 @@
import org.apache.directory.server.core.DirectoryService;
import org.apache.directory.server.core.partition.PartitionNexus;
+import org.apache.directory.server.core.security.CoreKeyStoreSpi;
import org.apache.directory.server.ldap.support.AbandonHandler;
import org.apache.directory.server.ldap.support.AddHandler;
import org.apache.directory.server.ldap.support.BindHandler;
@@ -60,7 +63,6 @@
import org.apache.directory.server.ldap.support.UnbindHandler;
import org.apache.directory.server.ldap.support.ssl.LdapsInitializer;
import org.apache.directory.server.protocol.shared.DirectoryBackedService;
-import org.apache.directory.server.protocol.shared.ServiceConfigurationException;
import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
import org.apache.directory.shared.asn1.codec.Asn1CodecDecoder;
import org.apache.directory.shared.asn1.codec.Asn1CodecEncoder;
@@ -166,13 +168,6 @@
/** Whether to allow anonymous access. */
private boolean allowAnonymousAccess = true; // allow by default
- /** The path to the certificate file. */
- private File ldapsCertificateFile = new File( "server-work" + File.separator + "certificates" + File.separator
- + "server.cert" );
-
- /** The certificate password. */
- private String ldapsCertificatePassword = "changeit";
-
/** The extended operation handlers. */
private final Collection<ExtendedOperationHandler> extendedOperationHandlers = new ArrayList<ExtendedOperationHandler>();
@@ -321,9 +316,19 @@
if ( isEnableLdaps() )
{
- char[] certPasswordChars = getLdapsCertificatePassword().toCharArray();
- String storePath = getLdapsCertificateFile().getPath();
- chain = LdapsInitializer.init( certPasswordChars, storePath );
+ Provider provider = Security.getProvider( "SUN" );
+ LOG.debug( "provider = {}", provider );
+ CoreKeyStoreSpi coreKeyStoreSpi = new CoreKeyStoreSpi( getDirectoryService() );
+ KeyStore keyStore = new KeyStore( coreKeyStoreSpi, provider, "JKS" ) {};
+ try
+ {
+ keyStore.load( null, null );
+ }
+ catch ( Exception e )
+ {
+ // nothing really happens with this keystore
+ }
+ chain = LdapsInitializer.init( keyStore );
}
else
{
@@ -475,6 +480,10 @@
*/
public void addExtendedOperationHandler( ExtendedOperationHandler eoh )
{
+ if ( extendedHandler == null )
+ {
+ setExtendedHandler( new DefaultExtendedHandler() );
+ }
extendedHandler.addHandler( eoh );
}
@@ -537,64 +546,6 @@
public void setEnableLdaps( boolean enableLdaps )
{
this.enableLdaps = enableLdaps;
- }
-
-
- /**
- * Returns the path of the X509 (or JKS) certificate file for LDAPS.
- * The default value is <tt>"<WORKDIR>/certificates/server.cert"</tt>.
- *
- * @return The LDAPS certificate file.
- */
- public File getLdapsCertificateFile()
- {
- return ldapsCertificateFile;
- }
-
-
- /**
- * Sets the path of the SunX509 certificate file (either PKCS12 or JKS format)
- * for LDAPS.
- *
- * @param ldapsCertificateFile The path to the SunX509 certificate.
- */
- public void setLdapsCertificateFile( File ldapsCertificateFile )
- {
- if ( ldapsCertificateFile == null )
- {
- throw new ServiceConfigurationException( "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.
- *
- * @return The LDAPS certificate password.
- */
- public String getLdapsCertificatePassword()
- {
- return ldapsCertificatePassword;
- }
-
-
- /**
- * Sets the password which is used to load the LDAPS certificate file.
- *
- * @param ldapsCertificatePassword The certificate password.
- */
- public void setLdapsCertificatePassword( String ldapsCertificatePassword )
- {
- if ( ldapsCertificatePassword == null )
- {
- throw new ServiceConfigurationException( "LdapsCertificatePassword cannot be null." );
- }
- this.ldapsCertificatePassword = ldapsCertificatePassword;
}
Added: directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/StartTlsHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/StartTlsHandler.java?rev=639006&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/StartTlsHandler.java (added)
+++ directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/extended/StartTlsHandler.java Wed Mar 19 13:47:36 2008
@@ -0,0 +1,197 @@
+/*
+ * 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.ldap.support.extended;
+
+
+import java.security.KeyStore;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.directory.server.core.security.CoreKeyStoreSpi;
+import org.apache.directory.server.ldap.ExtendedOperationHandler;
+import org.apache.directory.server.ldap.LdapServer;
+import org.apache.directory.server.ldap.SessionRegistry;
+import org.apache.directory.shared.ldap.message.ExtendedRequest;
+import org.apache.directory.shared.ldap.message.ExtendedResponse;
+import org.apache.directory.shared.ldap.message.ExtendedResponseImpl;
+import org.apache.directory.shared.ldap.message.LdapResult;
+import org.apache.directory.shared.ldap.message.ResultCodeEnum;
+import org.apache.mina.common.IoFilterChain;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.filter.SSLFilter;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Handler for the StartTLS extended operation.
+ *
+ * @org.apache.xbean.XBean
+ * @see <a href="http://www.ietf.org/rfc/rfc2830.txt">RFC 2830</a>
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class StartTlsHandler implements ExtendedOperationHandler
+{
+ public static final String EXTENSION_OID = "1.3.6.1.4.1.1466.20037";
+
+ private static final Set<String> EXTENSION_OIDS;
+ private static final Logger LOG = LoggerFactory.getLogger( StartTlsHandler.class );
+
+ private SSLContext sslContext;
+
+
+ static
+ {
+ Set<String> set = new HashSet<String>( 3 );
+ set.add( EXTENSION_OID );
+ EXTENSION_OIDS = Collections.unmodifiableSet( set );
+ }
+
+
+ public void handleExtendedOperation( IoSession session, SessionRegistry registry, ExtendedRequest req ) throws Exception
+ {
+ LOG.info( "Handling StartTLS request." );
+
+ IoFilterChain chain = session.getFilterChain();
+ SSLFilter sslFilter = ( SSLFilter ) chain.get( "sslFilter" );
+ if( sslFilter == null )
+ {
+ sslFilter = new SSLFilter( sslContext );
+ chain.addFirst( "sslFilter", sslFilter );
+ }
+ else
+ {
+ sslFilter.startSSL( session );
+ }
+
+ ExtendedResponse res = new ExtendedResponseImpl( req.getMessageId() );
+ LdapResult result = res.getLdapResult();
+ result.setResultCode( ResultCodeEnum.SUCCESS );
+ res.setResponseName( EXTENSION_OID );
+ res.setResponse( new byte[ 0 ] );
+
+ // Send a response.
+ session.setAttribute( SSLFilter.DISABLE_ENCRYPTION_ONCE );
+ session.write( res );
+ }
+
+
+ class ServerX509TrustManager implements X509TrustManager
+ {
+ public void checkClientTrusted( X509Certificate[] chain, String authType ) throws CertificateException
+ {
+ LOG.debug( "checkClientTrusted() called" );
+ }
+
+ public void checkServerTrusted( X509Certificate[] chain, String authType ) throws CertificateException
+ {
+ LOG.debug( "checkServerTrusted() called" );
+ }
+
+ public X509Certificate[] getAcceptedIssuers()
+ {
+ LOG.debug( "getAcceptedIssuers() called" );
+ return new X509Certificate[0];
+ }
+ }
+
+
+ public final Set<String> getExtensionOids()
+ {
+ return EXTENSION_OIDS;
+ }
+
+
+ public final String getOid()
+ {
+ return EXTENSION_OID;
+ }
+
+
+ public void setLdapProvider( LdapServer ldapServer )
+ {
+ LOG.debug( "Setting LDAP Service" );
+ Provider provider = Security.getProvider( "SUN" );
+ LOG.debug( "provider = {}", provider );
+ CoreKeyStoreSpi coreKeyStoreSpi = new CoreKeyStoreSpi( ldapServer.getDirectoryService() );
+ KeyStore keyStore = new KeyStore( coreKeyStoreSpi, provider, "JKS" ) {};
+
+ try
+ {
+ keyStore.load( null, null );
+ }
+ catch ( Exception e1 )
+ {
+ throw new RuntimeException( "Failed on keystore load which should never really happen." );
+ }
+
+ KeyManagerFactory keyManagerFactory = null;
+ try
+ {
+ keyManagerFactory = KeyManagerFactory.getInstance( "SunX509" );
+ }
+ catch ( Exception e )
+ {
+ throw new RuntimeException( "Failed to create KeyManagerFactory", e );
+ }
+
+ try
+ {
+ keyManagerFactory.init( keyStore, null );
+ }
+ catch ( Exception e )
+ {
+ throw new RuntimeException( "Failed to initialize KeyManagerFactory", e );
+ }
+
+ try
+ {
+ sslContext = SSLContext.getInstance( "TLS" );
+ }
+ catch ( Exception e )
+ {
+ throw new RuntimeException( "Failed to create SSLContext", e );
+ }
+
+ try
+ {
+ sslContext.init( keyManagerFactory.getKeyManagers(),
+ new TrustManager[] { new ServerX509TrustManager() },
+ new SecureRandom() );
+ }
+ catch ( Exception e )
+ {
+ throw new RuntimeException( "Failed to initialize SSLContext", e );
+ }
+ }
+}
Modified: directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/ssl/LdapsInitializer.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/ssl/LdapsInitializer.java?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/ssl/LdapsInitializer.java (original)
+++ directory/apacheds/branches/bigbang/protocol-ldap/src/main/java/org/apache/directory/server/ldap/support/ssl/LdapsInitializer.java Wed Mar 19 13:47:36 2008
@@ -20,14 +20,9 @@
package org.apache.directory.server.ldap.support.ssl;
-import java.io.FileInputStream;
-import java.io.IOException;
import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;
-import java.security.cert.CertificateException;
import javax.naming.NamingException;
import javax.net.ssl.KeyManagerFactory;
@@ -49,26 +44,8 @@
*/
public class LdapsInitializer
{
- public static IoFilterChainBuilder init( char[] certPasswordChars, String storePath ) throws NamingException
+ public static IoFilterChainBuilder init( KeyStore ks ) throws NamingException
{
- 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
{
@@ -79,7 +56,7 @@
algorithm = "SunX509";
}
KeyManagerFactory kmf = KeyManagerFactory.getInstance( algorithm );
- kmf.init( ks, certPasswordChars );
+ kmf.init( ks, null );
// Initialize the SSLContext to work with our key managers.
sslCtx = SSLContext.getInstance( "TLS" );
@@ -94,33 +71,5 @@
DefaultIoFilterChainBuilder chain = new DefaultIoFilterChainBuilder();
chain.addLast( "SSL", new SSLFilter( sslCtx ) );
return chain;
- }
-
-
- private static 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 )
- {
- }
- }
- }
}
}
Modified: directory/apacheds/branches/bigbang/schema-bootstrap/src/main/schema/apache.schema
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/schema-bootstrap/src/main/schema/apache.schema?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/schema-bootstrap/src/main/schema/apache.schema (original)
+++ directory/apacheds/branches/bigbang/schema-bootstrap/src/main/schema/apache.schema Wed Mar 19 13:47:36 2008
@@ -421,3 +421,46 @@
# END Schema Subentry Modification Attribute Schema
# =================================================
+# =============================================
+# SSL/TLS Key Management for LDAPS and StartTLS
+# =============================================
+
+attributetype ( 1.3.6.1.4.1.18060.0.4.1.2.38
+ NAME 'privateKeyFormat'
+ DESC 'The format of the private key used for TLS'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.18060.0.4.1.2.41
+ NAME 'publicKeyFormat'
+ DESC 'The format of the public key used for TLS'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.18060.0.4.1.2.39
+ NAME 'keyAlgorithm'
+ DESC 'The algorithm used for the key/pair used by the server for TLS'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.18060.0.4.1.2.40
+ NAME 'privateKey'
+ DESC 'The private key material used for TLS'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.18060.0.4.1.2.42
+ NAME 'publicKey'
+ DESC 'The public key material used for TLS'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE )
+
+objectclass ( 1.3.6.1.4.1.18060.0.4.1.3.11
+ NAME 'tlsKeyInfo'
+ SUP top
+ AUXILIARY
+ MUST ( privateKeyFormat $ keyAlgorithm $ privateKey $
+ publicKeyFormat $ publicKey ) )
+
+# =================================================
+# END SSL/TLS Key Management for LDAPS and StartTLS
+# =================================================
+
\ No newline at end of file
Modified: directory/apacheds/branches/bigbang/server-unit/src/main/java/org/apache/directory/server/unit/AbstractServerTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-unit/src/main/java/org/apache/directory/server/unit/AbstractServerTest.java?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/server-unit/src/main/java/org/apache/directory/server/unit/AbstractServerTest.java (original)
+++ directory/apacheds/branches/bigbang/server-unit/src/main/java/org/apache/directory/server/unit/AbstractServerTest.java Wed Mar 19 13:47:36 2008
@@ -28,6 +28,8 @@
import org.apache.directory.server.core.DirectoryService;
import org.apache.directory.server.core.jndi.CoreContextFactory;
import org.apache.directory.server.ldap.LdapServer;
+import org.apache.directory.server.ldap.support.extended.StartTlsHandler;
+import org.apache.directory.server.ldap.support.extended.StoredProcedureExtendedOperationHandler;
import org.apache.directory.server.protocol.shared.SocketAcceptor;
import org.apache.directory.shared.ldap.exception.LdapConfigurationException;
import org.apache.directory.shared.ldap.ldif.LdifEntry;
@@ -235,6 +237,8 @@
directoryService.startup();
configureLdapServer();
+ ldapServer.addExtendedOperationHandler( new StartTlsHandler() );
+ ldapServer.addExtendedOperationHandler( new StoredProcedureExtendedOperationHandler() );
ldapServer.start();
setContexts( ServerDNConstants.ADMIN_SYSTEM_DN, "secret" );
}
Modified: directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/StoredProcedureExecutionITest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/StoredProcedureExecutionITest.java?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/StoredProcedureExecutionITest.java (original)
+++ directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/StoredProcedureExecutionITest.java Wed Mar 19 13:47:36 2008
@@ -58,9 +58,8 @@
@Before public void setUp() throws Exception
{
-
super.setUp();
-
+
Hashtable<String, Object> env = new Hashtable<String, Object>();
env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
env.put( "java.naming.provider.url", "ldap://localhost:" + port + "/ou=system" );
@@ -73,6 +72,7 @@
spContainer.get( "objectClass" ).add( "organizationalUnit" );
spContainer.put( "ou", "Stored Procedures" );
spCtx = ( LdapContext ) ctx.createSubcontext( "ou=Stored Procedures", spContainer );
+ assertNotNull( spCtx );
// Initialize OIDs maps for normalization
oids = new HashMap<String, OidNormalizer>();
Modified: directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/LdapsITest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/LdapsITest.java?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/LdapsITest.java (original)
+++ directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/LdapsITest.java Wed Mar 19 13:47:36 2008
@@ -30,9 +30,6 @@
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.IOException;
import java.util.Hashtable;
@@ -77,34 +74,6 @@
protected void configureLdapServer()
{
ldapServer.setEnableLdaps( true );
- ldapServer.setLdapsCertificatePassword( "boguspw" );
-// ldapServer.setIpPort( ldapsPort );
-
- // Copy the bogus certificate to the certificates directory.
- InputStream in = getClass().getResourceAsStream( "/bogus.cert" );
- ldapServer.getLdapsCertificateFile().getParentFile().mkdirs();
-
- try
- {
- FileOutputStream out = new FileOutputStream( ldapServer.getLdapsCertificateFile() );
-
- for ( ;; )
- {
- int c = in.read();
- if ( c < 0 )
- {
- break;
- }
- out.write( c );
- }
-
- in.close();
- out.close();
- } catch ( IOException e )
- {
- throw new RuntimeException( e );
- }
-
}
/**
Added: directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/StartTlsITest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/StartTlsITest.java?rev=639006&view=auto
==============================================================================
--- directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/StartTlsITest.java (added)
+++ directory/apacheds/branches/bigbang/server-unit/src/test/java/org/apache/directory/server/ssl/StartTlsITest.java Wed Mar 19 13:47:36 2008
@@ -0,0 +1,85 @@
+/*
+ * 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.util.Hashtable;
+
+import javax.naming.Context;
+import javax.naming.directory.Attributes;
+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.util.DummySSLSocketFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Test case for StartTls.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class StartTlsITest extends AbstractServerTest
+{
+ private static final Logger LOG = LoggerFactory.getLogger( StartTlsITest.class );
+
+
+ public void testStartTls() throws Exception
+ {
+// // 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" );
+// env.put( "java.naming.ldap.factory.socket", DummySSLSocketFactory.class.getName() );
+//
+// // 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.error( "About to get initial context" );
+// LdapContext ctx = new InitialLdapContext( env, null );
+//
+// // Start TLS
+// LOG.error( "About send startTls extended operation" );
+// StartTlsResponse tls = ( StartTlsResponse ) ctx.extendedOperation( new StartTlsRequest() );
+// LOG.error( "Extended operation issued" );
+// tls.setHostnameVerifier( new HostnameVerifier() {
+// public boolean verify( String hostname, SSLSession session )
+// {
+// return true;
+// }
+// } );
+// LOG.error( "TLS negotion about to begin" );
+// SSLSession session = tls.negotiate( new DummySSLSocketFactory() );
+//
+// ctx.addToEnvironment( "java.naming.security.principal", "uid=admin,ou=system" );
+// ctx.addToEnvironment( "java.naming.security.credentials", "secret" );
+// ctx.addToEnvironment( "java.naming.security.authentication", "simple" );
+//
+// Attributes attrs = ctx.getAttributes( "ou=system" );
+// System.out.println( attrs.toString() );
+ }
+}
Modified: directory/apacheds/branches/bigbang/server-xml/src/main/resources/server.xml
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-xml/src/main/resources/server.xml?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/server-xml/src/main/resources/server.xml (original)
+++ directory/apacheds/branches/bigbang/server-xml/src/main/resources/server.xml Wed Mar 19 13:47:36 2008
@@ -134,10 +134,9 @@
</dnsServer>
-->
-<!-- no certificate -->
<ldapServer id="ldapsServer"
- enabled="false"
- ipPort="60636"
+ enabled="true"
+ ipPort="10636"
enableLdaps="true">
<directoryService>#directoryService</directoryService>
<socketAcceptor>#socketAcceptor</socketAcceptor>
@@ -177,7 +176,7 @@
<!-- the collection of extended operation handlers to install -->
<extendedOperationHandlers>
- <!--startTlsHandler/-->
+ <startTlsHandler/>
<gracefulShutdownHandler/>
<launchDiagnosticUiHandler/>
<!-- The Stored Procedure Extended Operation is not stable yet and it may cause security risks.-->
Propchange: directory/installers/branches/bigbang/apacheds-noarch/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Wed Mar 19 13:47:36 2008
@@ -1,4 +1,5 @@
server.xml
+*.log.*
work
META-INF
server-work
Modified: directory/installers/branches/bigbang/apacheds-noarch/log4j.properties
URL: http://svn.apache.org/viewvc/directory/installers/branches/bigbang/apacheds-noarch/log4j.properties?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/installers/branches/bigbang/apacheds-noarch/log4j.properties (original)
+++ directory/installers/branches/bigbang/apacheds-noarch/log4j.properties Wed Mar 19 13:47:36 2008
@@ -40,4 +40,5 @@
# Remove me when the unbind problem has gone away:
# https://issues.apache.org/jira/browse/DIRSERVER-1047
log4j.logger.org.apache.directory.server.ldap.support.UnbindHandler=OFF
+log4j.logger.org.apache.directory.server.schema.registries=WARN
Modified: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixTransformer.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixTransformer.java?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixTransformer.java (original)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixTransformer.java Wed Mar 19 13:47:36 2008
@@ -302,7 +302,7 @@
private Message transformExtendedRequest( LdapMessage twixMessage, int messageId )
{
ExtendedRequest extendedRequest = twixMessage.getExtendedRequest();
- ExtendedRequestImpl snickersMessage = null;
+ ExtendedRequestImpl snickersMessage;
if ( extendedRequest.getRequestName().equals( GracefulShutdownRequest.EXTENSION_OID ) )
{
Modified: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DirectoryClassUtils.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DirectoryClassUtils.java?rev=639006&r1=639005&r2=639006&view=diff
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DirectoryClassUtils.java (original)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DirectoryClassUtils.java Wed Mar 19 13:47:36 2008
@@ -20,6 +20,9 @@
package org.apache.directory.shared.ldap.util;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.lang.reflect.Method;
import java.util.Arrays;
@@ -29,9 +32,10 @@
*/
public class DirectoryClassUtils
{
+ private static final Logger LOG = LoggerFactory.getLogger( DirectoryClassUtils.class );
/**
- * A replacement for {@link java.lang.Class.getMethod} with extended capability.
+ * A replacement for {@link java.lang.Class#getMethod} with extended capability.
*
* <p>
* This method returns parameter-list assignment-compatible method as well as
@@ -41,13 +45,31 @@
* @param candidateMethodName Name of the method been looked for.
* @param candidateParameterTypes Types of the parameters in the signature of the method being loooked for.
* @return The Method found.
- * @throws NoSuchMethodException
+ * @throws NoSuchMethodException when the method cannot be found
*/
public static Method getAssignmentCompatibleMethod( Class<?> clazz,
String candidateMethodName,
Class<?>[] candidateParameterTypes
) throws NoSuchMethodException
{
+ if ( LOG.isDebugEnabled() )
+ {
+ StringBuilder buf = new StringBuilder();
+ buf.append( "call to getAssignmentCompatibleMethod(): \n\tclazz = " );
+ buf.append( clazz.getName() );
+ buf.append( "\n\tcandidateMethodName = " );
+ buf.append( candidateMethodName );
+ buf.append( "\n\tcandidateParameterTypes = " );
+
+ for ( Class<?> argClass : candidateParameterTypes )
+ {
+ buf.append( "\n\t\t" );
+ buf.append( argClass.getName() );
+ }
+
+ LOG.debug( buf.toString() );
+ }
+
try
{
// Look for exactly the same signature.
@@ -58,9 +80,12 @@
return exactMethod;
}
}
- catch ( SecurityException e ) { }
- catch ( NoSuchMethodException e ) { }
-
+ catch ( Exception e )
+ {
+ LOG.info( "Could not find accessible exact match for candidateMethod {}", candidateMethodName, e );
+ }
+
+
/**
* Look for the assignment-compatible signature.
*/
@@ -103,6 +128,7 @@
return methods[ mx ];
}
- throw new NoSuchMethodException( clazz.getName() + "." + candidateMethodName + "(" + Arrays.toString( candidateParameterTypes ) + ")" );
+ throw new NoSuchMethodException( clazz.getName() + "." + candidateMethodName
+ + "(" + Arrays.toString( candidateParameterTypes ) + ")" );
}
}
Added: directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DummySSLSocketFactory.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DummySSLSocketFactory.java?rev=639006&view=auto
==============================================================================
--- directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DummySSLSocketFactory.java (added)
+++ directory/shared/branches/bigbang/ldap/src/main/java/org/apache/directory/shared/ldap/util/DummySSLSocketFactory.java Wed Mar 19 13:47:36 2008
@@ -0,0 +1,213 @@
+/*
+ * 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.shared.ldap.util;
+
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+
+/**
+ * A SSLSocketFactory that accepts every certificat without validation.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class DummySSLSocketFactory extends SSLSocketFactory
+{
+
+ /** The default instance. */
+ private static SocketFactory instance;
+
+
+ /**
+ * Gets the default instance.
+ *
+ * Note: This method is invoked from the JNDI framework when
+ * creating a ldaps:// connection.
+ *
+ * @return the default instance
+ */
+ public static SocketFactory getDefault()
+ {
+ if ( instance == null )
+ {
+ instance = new DummySSLSocketFactory();
+ }
+ return instance;
+ }
+
+ /** The delegate. */
+ private SSLSocketFactory delegate;
+
+
+ /**
+ * Creates a new instance of DummySSLSocketFactory.
+ */
+ public DummySSLSocketFactory()
+ {
+ try
+ {
+ TrustManager tm = new X509TrustManager()
+ {
+ public X509Certificate[] getAcceptedIssuers()
+ {
+ return new X509Certificate[0];
+ }
+
+
+ public void checkClientTrusted( X509Certificate[] arg0, String arg1 ) throws CertificateException
+ {
+ }
+
+
+ public void checkServerTrusted( X509Certificate[] arg0, String arg1 ) throws CertificateException
+ {
+ }
+ };
+ TrustManager[] tma =
+ { tm };
+ SSLContext sc = SSLContext.getInstance( "TLS" ); //$NON-NLS-1$
+ sc.init( null, tma, new SecureRandom() );
+ delegate = sc.getSocketFactory();
+ }
+ catch ( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+
+ /**
+ * @see javax.net.ssl.SSLSocketFactory#getDefaultCipherSuites()
+ */
+ public String[] getDefaultCipherSuites()
+ {
+ return delegate.getDefaultCipherSuites();
+ }
+
+
+ /**
+ * @see javax.net.ssl.SSLSocketFactory#getSupportedCipherSuites()
+ */
+ public String[] getSupportedCipherSuites()
+ {
+ return delegate.getSupportedCipherSuites();
+ }
+
+
+ /**
+ * @see javax.net.ssl.SSLSocketFactory#createSocket(java.net.Socket, java.lang.String, int, boolean)
+ */
+ public Socket createSocket( Socket arg0, String arg1, int arg2, boolean arg3 ) throws IOException
+ {
+ try
+ {
+ return delegate.createSocket( arg0, arg1, arg2, arg3 );
+ }
+ catch ( IOException e )
+ {
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+
+ /**
+ * @see javax.net.SocketFactory#createSocket(java.lang.String, int)
+ */
+ public Socket createSocket( String arg0, int arg1 ) throws IOException, UnknownHostException
+ {
+ try
+ {
+ return delegate.createSocket( arg0, arg1 );
+ }
+ catch ( IOException e )
+ {
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+
+ /**
+ * @see javax.net.SocketFactory#createSocket(java.net.InetAddress, int)
+ */
+ public Socket createSocket( InetAddress arg0, int arg1 ) throws IOException
+ {
+ try
+ {
+ return delegate.createSocket( arg0, arg1 );
+ }
+ catch ( IOException e )
+ {
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+
+ /**
+ * @see javax.net.SocketFactory#createSocket(java.lang.String, int, java.net.InetAddress, int)
+ */
+ public Socket createSocket( String arg0, int arg1, InetAddress arg2, int arg3 ) throws IOException,
+ UnknownHostException
+ {
+ try
+ {
+ return delegate.createSocket( arg0, arg1, arg2, arg3 );
+ }
+ catch ( IOException e )
+ {
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+
+ /**
+ * @see javax.net.SocketFactory#createSocket(java.net.InetAddress, int, java.net.InetAddress, int)
+ */
+ public Socket createSocket( InetAddress arg0, int arg1, InetAddress arg2, int arg3 ) throws IOException
+ {
+ try
+ {
+ return delegate.createSocket( arg0, arg1, arg2, arg3 );
+ }
+ catch ( IOException e )
+ {
+ e.printStackTrace();
+ throw e;
+ }
+ }
+
+}