changeset 1054:1ceeba5420f2

Make host name verification configurable. Reviewed-by: neugens Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-April/006257.html
author Severin Gehwolf <sgehwolf@redhat.com>
date Wed, 03 Apr 2013 17:40:58 +0200
parents b288a8a06f03
children 92699ccfadca
files client/command/src/main/java/com/redhat/thermostat/client/command/internal/RequestQueueImpl.java common/core/src/main/java/com/redhat/thermostat/common/ssl/SSLKeystoreConfiguration.java common/core/src/test/java/com/redhat/thermostat/common/ssl/SSLKeystoreConfigurationTest.java common/core/src/test/resources/client.properties common/core/src/test/resources/ssl.properties distribution/config/ssl.properties storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoConnection.java
diffstat 7 files changed, 54 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/client/command/src/main/java/com/redhat/thermostat/client/command/internal/RequestQueueImpl.java	Wed Apr 03 15:30:56 2013 -0400
+++ b/client/command/src/main/java/com/redhat/thermostat/client/command/internal/RequestQueueImpl.java	Wed Apr 03 17:40:58 2013 +0200
@@ -177,8 +177,8 @@
         
         // Register a future listener, since it gives us a way to
         // report an error on client side and to perform (optional) host name verification.
-        // FIXME: make hostname verification configurable
-        future.addListener(new SSLHandshakeFinishedListener(request, true, sslHandler, this));
+        boolean performHostnameCheck = !SSLKeystoreConfiguration.disableHostnameVerification();
+        future.addListener(new SSLHandshakeFinishedListener(request, performHostnameCheck, sslHandler, this));
     }
 }
 
--- a/common/core/src/main/java/com/redhat/thermostat/common/ssl/SSLKeystoreConfiguration.java	Wed Apr 03 15:30:56 2013 -0400
+++ b/common/core/src/main/java/com/redhat/thermostat/common/ssl/SSLKeystoreConfiguration.java	Wed Apr 03 17:40:58 2013 +0200
@@ -54,6 +54,7 @@
     private static final String KEYSTORE_FILE_PWD_KEY = "KEYSTORE_PASSWORD";
     private static final String CMD_CHANNEL_SSL_KEY = "COMMAND_CHANNEL_USE_SSL";
     private static final String MONGO_CONNECTION_USE_SSL_KEY = "MONGODB_CONNECTION_USE_SSL";
+    private static final String DISABLE_HOSTNAME_VERIFICATION = "DISABLE_HOSTNAME_VERIFICATION";
     private static final Logger logger = LoggingUtils.getLogger(SSLKeystoreConfiguration.class);
 
     /**
@@ -105,22 +106,9 @@
      *         been added. false otherwise.
      */
     public static boolean shouldSSLEnableCmdChannel() {
-        boolean result = false;
-        try {
-            loadClientProperties();
-        } catch (InvalidConfigurationException e) {
-            logger.log(Level.WARNING,
-                    "THERMOSTAT_HOME not set and config file attempted to be " +
-                    		"read from there! Returning false.");
-            return result;
-        }
-        String token = clientProps.getProperty(CMD_CHANNEL_SSL_KEY);
-        if (token != null) {
-            result = Boolean.parseBoolean(token);
-        }
-        return result;
+        return readBooleanProperty(CMD_CHANNEL_SSL_KEY);
     }
-    
+
     /**
      * 
      * @return true if and only if SSL should be used for mongodb connections on
@@ -128,20 +116,18 @@
      *         and proper config has been added. false otherwise.
      */
     public static boolean useSslForMongodb() {
-        boolean result = false;
-        try {
-            loadClientProperties();
-        } catch (InvalidConfigurationException e) {
-            logger.log(Level.WARNING,
-                    "THERMOSTAT_HOME not set and config file attempted to be " +
-                            "read from there! Returning false.");
-            return result;
-        }
-        String token = clientProps.getProperty(MONGO_CONNECTION_USE_SSL_KEY);
-        if (token != null) {
-            result = Boolean.parseBoolean(token);
-        }
-        return result;
+        return readBooleanProperty(MONGO_CONNECTION_USE_SSL_KEY);
+    }
+    
+    /**
+     * 
+     * @return true if and only if host name verification should not be
+     *         performed during SSL handshake. In other words if
+     *         $THERMOSTAT_HOME/etc/ssl.properties exists and proper config has
+     *         been added. false otherwise.
+     */
+    public static boolean disableHostnameVerification() {
+        return readBooleanProperty(DISABLE_HOSTNAME_VERIFICATION);
     }
 
     // testing hook
@@ -155,6 +141,23 @@
         }
     }
 
+    private static boolean readBooleanProperty(final String property) {
+        boolean result = false;
+        try {
+            loadClientProperties();
+        } catch (InvalidConfigurationException e) {
+            logger.log(Level.WARNING,
+                    "THERMOSTAT_HOME not set and config file attempted to be " +
+                    		"read from there! Returning false.");
+            return result;
+        }
+        String token = clientProps.getProperty(property);
+        if (token != null) {
+            result = Boolean.parseBoolean(token);
+        }
+        return result;
+    }
+
     private static void loadClientProperties()
             throws InvalidConfigurationException {
         if (clientProps == null) {
--- a/common/core/src/test/java/com/redhat/thermostat/common/ssl/SSLKeystoreConfigurationTest.java	Wed Apr 03 15:30:56 2013 -0400
+++ b/common/core/src/test/java/com/redhat/thermostat/common/ssl/SSLKeystoreConfigurationTest.java	Wed Apr 03 17:40:58 2013 +0200
@@ -72,10 +72,12 @@
         SSLKeystoreConfiguration.initClientProperties(clientProps);
         assertTrue(SSLKeystoreConfiguration.shouldSSLEnableCmdChannel());
         assertTrue(SSLKeystoreConfiguration.useSslForMongodb());
+        assertTrue(SSLKeystoreConfiguration.disableHostnameVerification());
         clientProps = new File(this.getClass().getResource("/ssl.properties").getFile());
         SSLKeystoreConfiguration.initClientProperties(clientProps);
         assertFalse(SSLKeystoreConfiguration.shouldSSLEnableCmdChannel());
         assertFalse(SSLKeystoreConfiguration.useSslForMongodb());
+        assertFalse(SSLKeystoreConfiguration.disableHostnameVerification());
     }
 }
 
--- a/common/core/src/test/resources/client.properties	Wed Apr 03 15:30:56 2013 -0400
+++ b/common/core/src/test/resources/client.properties	Wed Apr 03 17:40:58 2013 +0200
@@ -2,4 +2,5 @@
 KEYSTORE_FILE=/path/to/thermostat.keystore
 KEYSTORE_PASSWORD=some password
 COMMAND_CHANNEL_USE_SSL=true
-MONGODB_CONNECTION_USE_SSL=true
\ No newline at end of file
+MONGODB_CONNECTION_USE_SSL=true
+DISABLE_HOSTNAME_VERIFICATION=true
\ No newline at end of file
--- a/common/core/src/test/resources/ssl.properties	Wed Apr 03 15:30:56 2013 -0400
+++ b/common/core/src/test/resources/ssl.properties	Wed Apr 03 17:40:58 2013 +0200
@@ -1,1 +1,3 @@
-COMMAND_CHANNEL_USE_SSL=somethingNotABoolean
\ No newline at end of file
+COMMAND_CHANNEL_USE_SSL=somethingNotABoolean
+# this does not parse as a boolean
+DISABLE_HOSTNAME_VERIFICATION=yes
\ No newline at end of file
--- a/distribution/config/ssl.properties	Wed Apr 03 15:30:56 2013 -0400
+++ b/distribution/config/ssl.properties	Wed Apr 03 17:40:58 2013 +0200
@@ -1,10 +1,8 @@
-# This file is only used in a Web storage setup and is entirely optional.
-# It allows for a user to specify a thermostat specific keystore to be used
-# for TLS certificate validation in addition to the default as described in:
-# http://docs.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#X509TrustManager
-
-# If you'd like to use a keystore file in addition to defaults uncomment the
-# following line:
+# This file is used as source for key material if SSL should be enabled
+# for the command channel. It may also be used in order to configure thermostat
+# so as to trust some self-signed certificate.
+# More information available at:
+# http://icedtea.classpath.org/wiki/Thermostat/SecurityConsiderations
 #KEYSTORE_FILE=/path/to/thermostat.keystore
 
 # The password for the keystore file. If none is provided the empty password
@@ -22,3 +20,8 @@
 # needs to do a SSL handshake with mongodb storage. See SSL_ENABLE in
 # $THERMOSTAT_HOME/storage/db.properties). 
 #MONGODB_CONNECTION_USE_SSL=true
+
+# Uncomment the following line if host name checking should be disabled during
+# SSL handshakes. It is not recommended to turn this off. NOTE: Host names will
+# always be verified for https:// connection URLs regardless of this config.
+#DISABLE_HOSTNAME_VERIFICATION=true
--- a/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoConnection.java	Wed Apr 03 15:30:56 2013 -0400
+++ b/storage/mongo/src/main/java/com/redhat/thermostat/storage/mongodb/internal/MongoConnection.java	Wed Apr 03 17:40:58 2013 +0200
@@ -143,8 +143,9 @@
         }
         SSLParameters params = SSLContextFactory.getSSLParameters(ctxt);
         // Perform HTTPS compatible host name checking.
-        // FIXME: make hostname verification configurable
-        params.setEndpointIdentificationAlgorithm("HTTPS");
+        if (!SSLKeystoreConfiguration.disableHostnameVerification()) {
+            params.setEndpointIdentificationAlgorithm("HTTPS");
+        }
         SSLSocketFactory factory = SSLContextFactory.wrapSSLFactory(
                 ctxt.getSocketFactory(), params);
         logger.log(Level.FINE, "factory is: " + factory.getClass().getName());