From 2fcf1d613593b70af7613af3e31165b9519ca60a Mon Sep 17 00:00:00 2001
From: lutoff <lutoff@localhost>
Date: Mon, 18 Jun 2007 13:47:34 +0000
Subject: [PATCH] Add the following global options in dsservice to handle client keystore Also modify ads.util package for this purpose.

---
 opendj-sdk/opends/src/ads/org/opends/admin/ads/util/ConnectionUtils.java                |   16 ++-
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java                  |    2 
 opendj-sdk/opends/src/ads/org/opends/admin/ads/util/ServerLoader.java                   |    2 
 opendj-sdk/opends/src/ads/org/opends/admin/ads/util/TrustedSocketFactory.java           |  116 ++++++++++++++++++++---
 opendj-sdk/opends/src/server/org/opends/server/admin/client/cli/DsServiceCliMain.java   |    2 
 opendj-sdk/opends/src/server/org/opends/server/admin/client/cli/DsServiceCliParser.java |  123 ++++++++++++++++++++++--
 6 files changed, 225 insertions(+), 36 deletions(-)

diff --git a/opendj-sdk/opends/src/ads/org/opends/admin/ads/util/ConnectionUtils.java b/opendj-sdk/opends/src/ads/org/opends/admin/ads/util/ConnectionUtils.java
index 6d006d2..1831427 100644
--- a/opendj-sdk/opends/src/ads/org/opends/admin/ads/util/ConnectionUtils.java
+++ b/opendj-sdk/opends/src/ads/org/opends/admin/ads/util/ConnectionUtils.java
@@ -44,6 +44,7 @@
 import javax.naming.ldap.StartTlsRequest;
 import javax.naming.ldap.StartTlsResponse;
 import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.KeyManager;
 import javax.net.ssl.TrustManager;
 
 /**
@@ -150,7 +151,8 @@
    * @param env           null or additional environment properties.
    * @param trustManager  null or the trust manager to be invoked during SSL
    * negociation.
-   *
+   * @param keyManager    null or the key manager to be invoked during SSL
+   * negociation.
    * @return the established connection with the given parameters.
    *
    * @throws NamingException the exception thrown when instantiating
@@ -162,7 +164,7 @@
    */
   public static InitialLdapContext createLdapsContext(String ldapsURL,
       String dn, String pwd, int timeout, Hashtable<String, String> env,
-      TrustManager trustManager) throws NamingException {
+      TrustManager trustManager, KeyManager keyManager) throws NamingException {
     if (env != null)
     { // We clone 'env' so that we can modify it freely
       env = new Hashtable<String, String>(env);
@@ -195,11 +197,13 @@
     final Object[] pair = new Object[] {null, null};
     final Hashtable fEnv = env;
     final TrustManager fTrustManager = trustManager;
+    final KeyManager   fKeyManage    = keyManager;
 
     Thread t = new Thread(new Runnable() {
       public void run() {
         try {
-          TrustedSocketFactory.setCurrentThreadTrustManager(fTrustManager);
+          TrustedSocketFactory.setCurrentThreadTrustManager(fTrustManager,
+              fKeyManage);
           pair[0] = new InitialLdapContext(fEnv, null);
 
         } catch (NamingException ne) {
@@ -292,7 +296,7 @@
           tls.setHostnameVerifier(fVerifier);
           try
           {
-            tls.negotiate(new TrustedSocketFactory(fTrustManager));
+            tls.negotiate(new TrustedSocketFactory(fTrustManager,null));
           }
           catch(IOException x) {
             NamingException xx;
@@ -367,7 +371,9 @@
       throw new IllegalStateException("Unexpected throwable.", t);
     }
     return canConnectAsAdministrativeUser;
-  }/**
+  }
+
+  /**
    * This is just a commodity method used to try to get an InitialLdapContext.
    * @param t the Thread to be used to create the InitialLdapContext.
    * @param pair an Object[] array that contains the InitialLdapContext and the
diff --git a/opendj-sdk/opends/src/ads/org/opends/admin/ads/util/ServerLoader.java b/opendj-sdk/opends/src/ads/org/opends/admin/ads/util/ServerLoader.java
index 23b49ce..f4a7514 100644
--- a/opendj-sdk/opends/src/ads/org/opends/admin/ads/util/ServerLoader.java
+++ b/opendj-sdk/opends/src/ads/org/opends/admin/ads/util/ServerLoader.java
@@ -256,7 +256,7 @@
     else
     {
       ctx = ConnectionUtils.createLdapsContext(lastLdapUrl, dn, pwd,
-          ConnectionUtils.getDefaultLDAPTimeout(), null, trustManager);
+          ConnectionUtils.getDefaultLDAPTimeout(), null, trustManager, null);
     }
 
     return ctx;
diff --git a/opendj-sdk/opends/src/ads/org/opends/admin/ads/util/TrustedSocketFactory.java b/opendj-sdk/opends/src/ads/org/opends/admin/ads/util/TrustedSocketFactory.java
index 88668bf..04be117 100644
--- a/opendj-sdk/opends/src/ads/org/opends/admin/ads/util/TrustedSocketFactory.java
+++ b/opendj-sdk/opends/src/ads/org/opends/admin/ads/util/TrustedSocketFactory.java
@@ -38,6 +38,7 @@
 import java.security.GeneralSecurityException;
 
 import javax.net.SocketFactory;
+import javax.net.ssl.KeyManager;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSocketFactory;
 import javax.net.ssl.SSLKeyException;
@@ -52,29 +53,43 @@
     Logger.getLogger(TrustedSocketFactory.class.getName());
   private static Map<Thread, TrustManager> hmTrustManager =
     new HashMap<Thread, TrustManager>();
-  private static Map<TrustManager, SocketFactory> hmDefaultFactory =
+  private static Map<Thread, KeyManager> hmKeyManager =
+    new HashMap<Thread, KeyManager>();
+
+  private static Map<TrustManager, SocketFactory> hmDefaultFactoryTm =
     new HashMap<TrustManager, SocketFactory>();
+  private static Map<KeyManager, SocketFactory> hmDefaultFactoryKm =
+    new HashMap<KeyManager, SocketFactory>();
 
   private SSLSocketFactory innerFactory;
   private TrustManager trustManager;
+  private KeyManager   keyManager;
 
   /**
    * Constructor of the TrustedSocketFactory.
    * @param trustManager the trust manager to use.
+   * @param keyManager   the key manager to use.
    */
-  public TrustedSocketFactory(TrustManager trustManager)
+  public TrustedSocketFactory(TrustManager trustManager, KeyManager keyManager)
   {
     this.trustManager = trustManager;
+    this.keyManager   = keyManager;
   }
 
   /**
-   * Sets the provided trust manager for the operations in the current thread.
-   * @param trustManager the trust manager to use.
+   * Sets the provided trust and key manager for the operations in the
+   * current thread.
+   *
+   * @param trustManager
+   *          the trust manager to use.
+   * @param keyManager
+   *          the key manager to use.
    */
   public static synchronized void setCurrentThreadTrustManager(
-      TrustManager trustManager)
+      TrustManager trustManager, KeyManager keyManager)
   {
     setThreadTrustManager(trustManager, Thread.currentThread());
+    setThreadKeyManager  (keyManager, Thread.currentThread());
   }
 
   /**
@@ -87,7 +102,7 @@
   {
     TrustManager currentTrustManager = hmTrustManager.get(thread);
     if (currentTrustManager != null) {
-      hmDefaultFactory.remove(currentTrustManager);
+      hmDefaultFactoryTm.remove(currentTrustManager);
       hmTrustManager.remove(thread);
     }
     if (trustManager != null) {
@@ -95,6 +110,24 @@
     }
   }
 
+  /**
+   * Sets the provided key manager for the operations in the provided thread.
+   * @param keyManager the key manager to use.
+   * @param thread the thread where we want to use the provided key manager.
+   */
+  public static synchronized void setThreadKeyManager(
+      KeyManager keyManager, Thread thread)
+  {
+    KeyManager currentKeyManager = hmKeyManager.get(thread);
+    if (currentKeyManager != null) {
+      hmDefaultFactoryKm.remove(currentKeyManager);
+      hmKeyManager.remove(thread);
+    }
+    if (keyManager != null) {
+      hmKeyManager.put(thread, keyManager);
+    }
+  }
+
   //
   // SocketFactory implementation
   //
@@ -112,21 +145,63 @@
   {
     Thread currentThread = Thread.currentThread();
     TrustManager trustManager = hmTrustManager.get(currentThread);
+    KeyManager   keyManager   = hmKeyManager.get(currentThread);
     SocketFactory result;
 
     if (trustManager == null)
     {
       LOG.log(Level.SEVERE, "Can't find a trust manager associated to thread " +
           currentThread);
-      result = new TrustedSocketFactory(null);
+      if (keyManager == null)
+      {
+        LOG.log(Level.SEVERE, "Can't find a key manager associated to thread " +
+            currentThread);
+        result = new TrustedSocketFactory(null,null);
+      }
+      else
+      {
+        result = hmDefaultFactoryKm.get(keyManager);
+        if (result == null)
+        {
+          result = new TrustedSocketFactory(null,keyManager);
+          hmDefaultFactoryKm.put(keyManager, result);
+        }
+      }
     }
     else
     {
-      result = hmDefaultFactory.get(trustManager);
-      if (result == null)
+      if (keyManager == null)
       {
-        result = new TrustedSocketFactory(trustManager);
-        hmDefaultFactory.put(trustManager, result);
+        LOG.log(Level.SEVERE,
+            "Can't find a key manager associated to thread " + currentThread);
+        result = hmDefaultFactoryTm.get(trustManager);
+        if (result == null)
+        {
+          result = new TrustedSocketFactory(trustManager, null);
+          hmDefaultFactoryTm.put(trustManager, result);
+        }
+      }
+      else
+      {
+        SocketFactory tmsf = hmDefaultFactoryTm.get(trustManager);
+        SocketFactory kmsf = hmDefaultFactoryKm.get(keyManager);
+        if ( tmsf == null || kmsf == null)
+        {
+          result = new TrustedSocketFactory(trustManager, keyManager);
+          hmDefaultFactoryTm.put(trustManager, result);
+          hmDefaultFactoryKm.put(keyManager, result);
+        }
+        else
+        if ( !tmsf.equals(kmsf) )
+        {
+          result = new TrustedSocketFactory(trustManager, keyManager);
+          hmDefaultFactoryTm.put(trustManager, result);
+          hmDefaultFactoryKm.put(keyManager, result);
+        }
+        else
+        {
+          result = tmsf ;
+        }
       }
     }
 
@@ -216,18 +291,28 @@
     {
       String algorithm = "TLSv1";
       SSLKeyException xx;
+      KeyManager[] km = null;
+      TrustManager[] tm = null;
 
       try {
         SSLContext sslCtx = SSLContext.getInstance(algorithm);
         if (trustManager == null)
         {
           LOG.log(Level.SEVERE, "Warning : no trust for this factory");
-          sslCtx.init(null, null, null); // No certif -> no SSL connection
         }
-        else {
-          sslCtx.init(null, new TrustManager[] { trustManager }, null
-          );
+        else
+        {
+          tm = new TrustManager[] { trustManager };
         }
+        if (keyManager == null)
+        {
+          LOG.log(Level.SEVERE, "Warning : no key for this factory");
+        }
+        else
+        {
+          km = new KeyManager[] { keyManager };
+        }
+        sslCtx.init(km, tm, new java.security.SecureRandom() );
         innerFactory = sslCtx.getSocketFactory();
       }
       catch(GeneralSecurityException x) {
@@ -237,7 +322,6 @@
         throw xx;
       }
     }
-
     return innerFactory;
   }
 }
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
index 136389c..06b08e3 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
@@ -902,7 +902,7 @@
       String dn, String pwd, int timeout, Hashtable<String, String> env,
       TrustManager trustManager) throws NamingException {
     return ConnectionUtils.createLdapsContext(ldapsURL, dn, pwd, timeout, env,
-        trustManager);
+        trustManager, null);
   }
 
   /**
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/cli/DsServiceCliMain.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/cli/DsServiceCliMain.java
index d524df2..3ca7af5 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/cli/DsServiceCliMain.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/cli/DsServiceCliMain.java
@@ -232,7 +232,7 @@
       {
         ctx = ConnectionUtils.createLdapsContext(ldapsUrl,
             dn, pwd, ConnectionUtils.getDefaultLDAPTimeout(), null,
-             argParser.getTrustManager());
+             argParser.getTrustManager(), argParser.getKeyManager());
       }
       catch (NamingException e)
       {
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/cli/DsServiceCliParser.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/cli/DsServiceCliParser.java
index fa1e865..8e904fa 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/cli/DsServiceCliParser.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/cli/DsServiceCliParser.java
@@ -47,6 +47,7 @@
 
 import org.opends.admin.ads.ADSContext;
 import org.opends.admin.ads.ADSContextException;
+import org.opends.admin.ads.util.ApplicationKeyManager;
 import org.opends.admin.ads.util.ApplicationTrustManager;
 import org.opends.server.admin.client.cli.DsServiceCliReturnCode.ReturnCode;
 import org.opends.server.loggers.debug.DebugTracer;
@@ -127,6 +128,21 @@
   private FileBasedArgument trustStorePasswordFileArg = null;
 
   /**
+   * The 'keyStore' global argument.
+   */
+  private StringArgument keyStorePathArg = null;
+
+  /**
+   * The 'keyStorePassword' global argument.
+   */
+  private StringArgument keyStorePasswordArg = null;
+
+  /**
+   * The 'keyStorePasswordFile' global argument.
+   */
+  private FileBasedArgument keyStorePasswordFileArg = null;
+
+  /**
    * The Logger.
    */
   static private final Logger LOG =
@@ -255,6 +271,24 @@
         MSGID_DESCRIPTION_TRUSTSTOREPASSWORD_FILE);
     addGlobalArgument(trustStorePasswordFileArg);
 
+    keyStorePathArg = new StringArgument("keyStorePath",
+        OPTION_SHORT_KEYSTOREPATH, OPTION_LONG_KEYSTOREPATH, false, false,
+        true, OPTION_VALUE_KEYSTOREPATH, null, null,
+        MSGID_DESCRIPTION_KEYSTOREPATH);
+    addGlobalArgument(keyStorePathArg);
+
+    keyStorePasswordArg = new StringArgument("keyStorePassword", null,
+        OPTION_LONG_KEYSTORE_PWD, false, false, true,
+        OPTION_VALUE_KEYSTORE_PWD, null, null,
+        MSGID_DESCRIPTION_KEYSTOREPASSWORD);
+    addGlobalArgument(keyStorePasswordArg);
+
+    keyStorePasswordFileArg = new FileBasedArgument("keystorepasswordfile",
+        OPTION_SHORT_KEYSTORE_PWD_FILE, OPTION_LONG_KEYSTORE_PWD_FILE, false,
+        false, OPTION_VALUE_KEYSTORE_PWD_FILE, null, null,
+        MSGID_DESCRIPTION_KEYSTOREPASSWORD_FILE);
+    addGlobalArgument(keyStorePasswordFileArg);
+
     verboseArg = new BooleanArgument("verbose", 'v', "verbose",
         MSGID_DESCRIPTION_VERBOSE);
     addGlobalArgument(verboseArg);
@@ -457,8 +491,8 @@
    */
   public ApplicationTrustManager getTrustManager()
   {
-    ApplicationTrustManager trustStore = null ;
-    KeyStore keyStore = null ;
+    ApplicationTrustManager truststoreManager = null ;
+    KeyStore truststore = null ;
     if (trustStorePathArg.isPresent())
     {
       try
@@ -473,55 +507,120 @@
         {
           trustStorePasswordValue = trustStorePasswordFileArg.getValue();
         }
-        keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
-        keyStore.load(fos, trustStorePasswordValue.toCharArray());
+        truststore = KeyStore.getInstance(KeyStore.getDefaultType());
+        truststore.load(fos, trustStorePasswordValue.toCharArray());
       }
       catch (KeyStoreException e)
       {
         // Nothing to do: if this occurs we will systematically refuse the
         // certificates.  Maybe we should avoid this and be strict, but we are
         // in a best effor mode.
-        LOG.log(Level.WARNING, "Error with the keystore", e);
+        LOG.log(Level.WARNING, "Error with the truststore", e);
       }
       catch (NoSuchAlgorithmException e)
       {
         // Nothing to do: if this occurs we will systematically refuse the
         // certificates.  Maybe we should avoid this and be strict, but we are
         // in a best effor mode.
-        LOG.log(Level.WARNING, "Error with the keystore", e);
+        LOG.log(Level.WARNING, "Error with the truststore", e);
       }
       catch (CertificateException e)
       {
         // Nothing to do: if this occurs we will systematically refuse the
         // certificates.  Maybe we should avoid this and be strict, but we are
         // in a best effor mode.
-        LOG.log(Level.WARNING, "Error with the keystore", e);
+        LOG.log(Level.WARNING, "Error with the truststore", e);
       }
       catch (IOException e)
       {
         // Nothing to do: if this occurs we will systematically refuse the
         // certificates.  Maybe we should avoid this and be strict, but we are
         // in a best effor mode.
+        LOG.log(Level.WARNING, "Error with the truststore", e);
+      }
+    }
+    truststoreManager = new ApplicationTrustManager(truststore);
+    truststoreManager.setHost(getHostName());
+    return truststoreManager;
+  }
+
+  /**
+   * Handle KeyStore.
+   *
+   * @return The keyStore manager to be used for the command.
+   */
+  public ApplicationKeyManager getKeyManager()
+  {
+    KeyStore keyStore = null;
+    String keyStorePasswordValue = null;
+    if (keyStorePathArg.isPresent())
+    {
+      try
+      {
+        FileInputStream fos = new FileInputStream(keyStorePathArg.getValue());
+        if (keyStorePasswordArg.isPresent())
+        {
+          keyStorePasswordValue = keyStorePasswordArg.getValue();
+        }
+        else if (keyStorePasswordFileArg.isPresent())
+        {
+          keyStorePasswordValue = keyStorePasswordFileArg.getValue();
+        }
+        keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+        keyStore.load(fos, keyStorePasswordValue.toCharArray());
+      }
+      catch (KeyStoreException e)
+      {
+        // Nothing to do: if this occurs we will systematically refuse
+        // the
+        // certificates. Maybe we should avoid this and be strict, but
+        // we are
+        // in a best effor mode.
+        LOG.log(Level.WARNING, "Error with the keystore", e);
+      }
+      catch (NoSuchAlgorithmException e)
+      {
+        // Nothing to do: if this occurs we will systematically refuse
+        // the
+        // certificates. Maybe we should avoid this and be strict, but
+        // we are
+        // in a best effor mode.
+        LOG.log(Level.WARNING, "Error with the keystore", e);
+      }
+      catch (CertificateException e)
+      {
+        // Nothing to do: if this occurs we will systematically refuse
+        // the
+        // certificates. Maybe we should avoid this and be strict, but
+        // we are
+        // in a best effor mode.
+        LOG.log(Level.WARNING, "Error with the keystore", e);
+      }
+      catch (IOException e)
+      {
+        // Nothing to do: if this occurs we will systematically refuse
+        // the
+        // certificates. Maybe we should avoid this and be strict, but
+        // we are
+        // in a best effor mode.
         LOG.log(Level.WARNING, "Error with the keystore", e);
       }
     }
-    trustStore = new ApplicationTrustManager(keyStore);
-    trustStore.setHost(getHostName());
-    return trustStore ;
+    return new ApplicationKeyManager(keyStore, keyStorePasswordValue
+        .toCharArray());
   }
 
   /**
    * Indication if provided global options are validate.
    *
    * @param err the stream to be used to print error message.
-   *
    * @return return code.
    */
   public int validateGlobalOption(PrintStream err)
   {
     ReturnCode returnCode = ReturnCode.SUCCESSFUL_NOP;
 
-    // Couldn't have at the same time bindPassword and bibdPasswordFile
+    // Couldn't have at the same time bindPassword and bindPasswordFile
     if(bindPasswordArg.isPresent() && bindPasswordFileArg.isPresent())
     {
       int    msgID   = MSGID_TOOL_CONFLICTING_ARGS;

--
Gitblit v1.10.0