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 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; 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; } } 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); } /** 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) { 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;