From dc33ffd3f743a887168b0274e86b0a33fafb87d2 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 17 Jul 2013 11:05:11 -0400
Subject: [PATCH] Fixed token authentication problem on RHEL.

The CryptoManager.initialize() and CryptoToken.login() invocation has been
moved into the main program as a workaround for the authentication problem
on RHEL and to ensure proper initialization in general.

Bugzilla #985111
---
 .../src/com/netscape/certsrv/client/PKIClient.java | 44 ----------------------
 .../com/netscape/certsrv/client/PKIConnection.java | 23 +++++------
 .../src/com/netscape/cmstools/cli/MainCLI.java     | 44 +++++++++++++++++++---
 3 files changed, 49 insertions(+), 62 deletions(-)

diff --git a/base/common/src/com/netscape/certsrv/client/PKIClient.java b/base/common/src/com/netscape/certsrv/client/PKIClient.java
index f03ebf68df9a0b97836cbe753c9c49c7ce3487dd..3b316ceb3355cd6d653143b29ef78f4d16d1f6ef 100644
--- a/base/common/src/com/netscape/certsrv/client/PKIClient.java
+++ b/base/common/src/com/netscape/certsrv/client/PKIClient.java
@@ -4,7 +4,6 @@ import java.io.File;
 import java.io.IOException;
 import java.net.URISyntaxException;
 import java.net.URL;
-import java.security.GeneralSecurityException;
 import java.security.cert.CertificateEncodingException;
 
 import javax.xml.parsers.DocumentBuilder;
@@ -12,13 +11,10 @@ import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 
 import org.jboss.resteasy.client.ClientResponse;
-import org.mozilla.jss.CertDatabaseException;
 import org.mozilla.jss.CryptoManager;
 import org.mozilla.jss.CryptoManager.NicknameConflictException;
 import org.mozilla.jss.CryptoManager.NotInitializedException;
 import org.mozilla.jss.CryptoManager.UserCertConflictException;
-import org.mozilla.jss.KeyDatabaseException;
-import org.mozilla.jss.crypto.AlreadyInitializedException;
 import org.mozilla.jss.crypto.CryptoToken;
 import org.mozilla.jss.crypto.InternalCertificate;
 import org.mozilla.jss.crypto.NoSuchItemOnTokenException;
@@ -26,8 +22,6 @@ import org.mozilla.jss.crypto.ObjectNotFoundException;
 import org.mozilla.jss.crypto.TokenCertificate;
 import org.mozilla.jss.crypto.TokenException;
 import org.mozilla.jss.crypto.X509Certificate;
-import org.mozilla.jss.util.IncorrectPasswordException;
-import org.mozilla.jss.util.Password;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
@@ -51,44 +45,6 @@ public class PKIClient {
         connection = new PKIConnection(this);
     }
 
-    public void initCertDatabase() throws KeyDatabaseException,
-        CertDatabaseException, AlreadyInitializedException,
-        GeneralSecurityException, NotInitializedException,
-        TokenException, IncorrectPasswordException {
-
-        if (config.getCertDatabase() == null) {
-            certDatabase = new File(
-                    System.getProperty("user.home") + File.separator +
-                    ".dogtag" + File.separator + "nssdb");
-
-            certDatabase.mkdirs();
-
-        } else {
-            certDatabase = new File(config.getCertDatabase());
-        }
-
-        if (verbose) System.out.println("Certificate database: "+certDatabase.getAbsolutePath());
-
-        CryptoManager.initialize(certDatabase.getAbsolutePath());
-
-        // If password is specified, use password to access client database
-        if (config.getCertPassword() != null) {
-            CryptoManager manager = CryptoManager.getInstance();
-            CryptoToken token = manager.getInternalKeyStorageToken();
-            Password password = new Password(config.getCertPassword().toCharArray());
-
-            try {
-                token.login(password);
-
-            } catch (IncorrectPasswordException e) {
-                System.out.println("Error: "+e.getClass().getSimpleName()+": "+e.getMessage());
-                // The original exception doesn't contain a message.
-                throw new IncorrectPasswordException("Incorrect certificate database password.");
-            }
-
-        }
-    }
-
     public <T> T createProxy(Class<T> clazz) throws URISyntaxException {
         return connection.createProxy(clazz);
     }
diff --git a/base/common/src/com/netscape/certsrv/client/PKIConnection.java b/base/common/src/com/netscape/certsrv/client/PKIConnection.java
index 1b9c8edc58c761797f27a522499bc79300ff99e3..397e7ca91f288a3ad01edb97d532da9b2c597739 100644
--- a/base/common/src/com/netscape/certsrv/client/PKIConnection.java
+++ b/base/common/src/com/netscape/certsrv/client/PKIConnection.java
@@ -39,8 +39,8 @@ import org.apache.http.auth.params.AuthPNames;
 import org.apache.http.client.methods.HttpUriRequest;
 import org.apache.http.client.params.AuthPolicy;
 import org.apache.http.client.params.HttpClientParams;
-import org.apache.http.conn.scheme.LayeredSchemeSocketFactory;
 import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeLayeredSocketFactory;
 import org.apache.http.conn.scheme.SchemeSocketFactory;
 import org.apache.http.entity.BufferedHttpEntity;
 import org.apache.http.impl.client.ClientParamsStack;
@@ -61,7 +61,8 @@ import org.jboss.resteasy.client.core.BaseClientResponse;
 import org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor;
 import org.jboss.resteasy.client.core.extractors.ClientErrorHandler;
 import org.jboss.resteasy.spi.ResteasyProviderFactory;
-import org.mozilla.jss.crypto.AlreadyInitializedException;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.CryptoManager.NotInitializedException;
 import org.mozilla.jss.crypto.X509Certificate;
 import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
 import org.mozilla.jss.ssl.SSLSocket;
@@ -431,7 +432,7 @@ public class PKIConnection {
         }
     }
 
-    private class JSSProtocolSocketFactory implements SchemeSocketFactory, LayeredSchemeSocketFactory {
+    private class JSSProtocolSocketFactory implements SchemeSocketFactory, SchemeLayeredSocketFactory {
 
         @Override
         public Socket createSocket(HttpParams params) throws IOException {
@@ -447,17 +448,13 @@ public class PKIConnection {
                 UnknownHostException,
                 ConnectTimeoutException {
 
-            // Make sure certificate database is initialized
-            // before using SSLSocket, otherwise it will throw
-            // UnsatisfiedLinkError.
+            // Make sure certificate database is already initialized,
+            // otherwise SSLSocket will throw UnsatisfiedLinkError.
             try {
-                client.initCertDatabase();
+                CryptoManager.getInstance();
 
-            } catch (AlreadyInitializedException e) {
-                // ignore
-
-            } catch (Exception e) {
-                throw new Error(e);
+            } catch (NotInitializedException e) {
+                throw new IOException(e);
             }
 
             String hostName = null;
@@ -504,7 +501,7 @@ public class PKIConnection {
         }
 
         @Override
-        public Socket createLayeredSocket(Socket socket, String target, int port, boolean autoClose)
+        public Socket createLayeredSocket(Socket socket, String target, int port, HttpParams params)
                 throws IOException, UnknownHostException {
             // This method implementation is required to get SSL working.
             return null;
diff --git a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
index 50095b173c5b9a4d43c320cc5e81b9dcc25555c2..d1352d7047465cb8488dfa51837365ed24a1b09b 100644
--- a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
@@ -29,7 +29,11 @@ import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
 import org.apache.commons.lang.StringUtils;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoToken;
 import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
+import org.mozilla.jss.util.IncorrectPasswordException;
+import org.mozilla.jss.util.Password;
 
 import com.netscape.certsrv.account.AccountClient;
 import com.netscape.certsrv.client.ClientConfig;
@@ -230,6 +234,41 @@ public class MainCLI extends CLI {
 
     public void init() throws Exception {
 
+        if (config.getCertDatabase() == null) {
+            // Create a default certificate database
+            certDatabase = new File(
+                    System.getProperty("user.home") + File.separator +
+                    ".dogtag" + File.separator + "nssdb");
+
+            certDatabase.mkdirs();
+
+        } else {
+            // Use existing certificate database
+            certDatabase = new File(config.getCertDatabase());
+        }
+
+        if (verbose) System.out.println("Certificate database: "+certDatabase.getAbsolutePath());
+
+        // Main program should initialize certificate database
+        CryptoManager.initialize(certDatabase.getAbsolutePath());
+
+        // If password is specified, use password to access client database
+        if (config.getCertPassword() != null) {
+            CryptoManager manager = CryptoManager.getInstance();
+            CryptoToken token = manager.getInternalKeyStorageToken();
+            Password password = new Password(config.getCertPassword().toCharArray());
+
+            try {
+                token.login(password);
+
+            } catch (IncorrectPasswordException e) {
+                System.out.println("Error: "+e.getClass().getSimpleName()+": "+e.getMessage());
+                // The original exception doesn't contain a message.
+                throw new IncorrectPasswordException("Incorrect certificate database password.");
+            }
+
+        }
+
         client = new PKIClient(config);
         client.setVerbose(verbose);
 
@@ -244,11 +283,6 @@ public class MainCLI extends CLI {
         }
 
         accountClient = new AccountClient(client);
-
-        // initialize certificate database if specified
-        if (config.getCertDatabase() != null) {
-            client.initCertDatabase();
-        }
     }
 
     public void execute(String[] args) throws Exception {
-- 
1.8.1.4

