You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2021/02/18 16:10:00 UTC

[camel] branch master updated: CAMEL-16232 Fixing 2-way ssl via system properties (#5102)

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new 47be960  CAMEL-16232 Fixing 2-way ssl via system properties (#5102)
47be960 is described below

commit 47be96026778792f8bc0a2359ed4c0034496f961
Author: JiriOndrusek <on...@gmail.com>
AuthorDate: Thu Feb 18 17:09:42 2021 +0100

    CAMEL-16232 Fixing 2-way ssl via system properties (#5102)
---
 .../apache/camel/component/http/HttpComponent.java |  11 +-
 .../http/HttpProducerWithSystemPropertiesTest.java |  89 ------------
 .../HttpsProducerWithSystemPropertiesTest.java     | 150 +++++++++++++++++++++
 3 files changed, 158 insertions(+), 92 deletions(-)

diff --git a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java
index fda1d1f..5a08987 100644
--- a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java
+++ b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java
@@ -393,9 +393,11 @@ public class HttpComponent extends HttpCommonComponent implements RestProducerFa
         // need to check the parameters of maxTotalConnections and connectionsPerRoute
         final int maxTotalConnections = getAndRemoveParameter(parameters, "maxTotalConnections", int.class, 0);
         final int connectionsPerRoute = getAndRemoveParameter(parameters, "connectionsPerRoute", int.class, 0);
+        final boolean useSystemProperties = CamelContextHelper.mandatoryConvertTo(this.getCamelContext(), boolean.class,
+                parameters.get("useSystemProperties"));
 
         final Registry<ConnectionSocketFactory> connectionRegistry
-                = createConnectionRegistry(hostnameVerifier, sslContextParameters);
+                = createConnectionRegistry(hostnameVerifier, sslContextParameters, useSystemProperties);
 
         return createConnectionManager(connectionRegistry, maxTotalConnections, connectionsPerRoute);
     }
@@ -421,7 +423,8 @@ public class HttpComponent extends HttpCommonComponent implements RestProducerFa
     }
 
     protected Registry<ConnectionSocketFactory> createConnectionRegistry(
-            HostnameVerifier x509HostnameVerifier, SSLContextParameters sslContextParams)
+            HostnameVerifier x509HostnameVerifier, SSLContextParameters sslContextParams,
+            boolean useSystemProperties)
             throws GeneralSecurityException, IOException {
         // create the default connection registry to use
         RegistryBuilder<ConnectionSocketFactory> builder = RegistryBuilder.<ConnectionSocketFactory> create();
@@ -430,7 +433,9 @@ public class HttpComponent extends HttpCommonComponent implements RestProducerFa
             builder.register("https",
                     new SSLConnectionSocketFactory(sslContextParams.createSSLContext(getCamelContext()), x509HostnameVerifier));
         } else {
-            builder.register("https", new SSLConnectionSocketFactory(SSLContexts.createDefault(), x509HostnameVerifier));
+            builder.register("https", new SSLConnectionSocketFactory(
+                    useSystemProperties ? SSLContexts.createSystemDefault() : SSLContexts.createDefault(),
+                    x509HostnameVerifier));
         }
         return builder.build();
     }
diff --git a/components/camel-http/src/test/java/org/apache/camel/component/http/HttpProducerWithSystemPropertiesTest.java b/components/camel-http/src/test/java/org/apache/camel/component/http/HttpProducerWithSystemPropertiesTest.java
deleted file mode 100644
index 28f9bd2..0000000
--- a/components/camel-http/src/test/java/org/apache/camel/component/http/HttpProducerWithSystemPropertiesTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.camel.component.http;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.camel.Exchange;
-import org.apache.camel.component.http.handler.HeaderValidationHandler;
-import org.apache.http.impl.bootstrap.HttpServer;
-import org.apache.http.impl.bootstrap.ServerBootstrap;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-public class HttpProducerWithSystemPropertiesTest extends BaseHttpTest {
-
-    private static Object defaultSystemHttpAgent;
-    private HttpServer localServer;
-
-    @BeforeAll
-    public static void setUpHttpAgentSystemProperty() throws Exception {
-        // the 'http.agent' java system-property corresponds to the http 'User-Agent' header
-        defaultSystemHttpAgent = System.setProperty("http.agent", "myCoolCamelCaseAgent");
-    }
-
-    @AfterAll
-    public static void resetHttpAgentSystemProperty() throws Exception {
-        if (defaultSystemHttpAgent != null) {
-            System.setProperty("http.agent", String.valueOf(defaultSystemHttpAgent));
-        } else {
-            System.clearProperty("http.agent");
-        }
-    }
-
-    @BeforeEach
-    @Override
-    public void setUp() throws Exception {
-        Map<String, String> expectedHeaders = new HashMap<>();
-        expectedHeaders.put("User-Agent", "myCoolCamelCaseAgent");
-
-        localServer = ServerBootstrap.bootstrap().setHttpProcessor(getBasicHttpProcessor())
-                .setConnectionReuseStrategy(getConnectionReuseStrategy()).setResponseFactory(getHttpResponseFactory())
-                .setExpectationVerifier(getHttpExpectationVerifier()).setSslContext(getSSLContext())
-                .registerHandler("*", new HeaderValidationHandler("GET", null, null, getExpectedContent(), expectedHeaders))
-                .create();
-        localServer.start();
-
-        super.setUp();
-    }
-
-    @AfterEach
-    @Override
-    public void tearDown() throws Exception {
-        super.tearDown();
-
-        if (localServer != null) {
-            localServer.stop();
-        }
-    }
-
-    @Test
-    public void httpGetWithProxyFromSystemProperties() throws Exception {
-
-        String endpointUri = "http://" + localServer.getInetAddress().getHostName() + ":" + localServer.getLocalPort()
-                             + "?useSystemProperties=true";
-        Exchange exchange = template.request(endpointUri, exchange1 -> {
-        });
-
-        assertExchange(exchange);
-    }
-
-}
diff --git a/components/camel-http/src/test/java/org/apache/camel/component/http/HttpsProducerWithSystemPropertiesTest.java b/components/camel-http/src/test/java/org/apache/camel/component/http/HttpsProducerWithSystemPropertiesTest.java
new file mode 100644
index 0000000..3f9852d
--- /dev/null
+++ b/components/camel-http/src/test/java/org/apache/camel/component/http/HttpsProducerWithSystemPropertiesTest.java
@@ -0,0 +1,150 @@
+/*
+ * 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.camel.component.http;
+
+import java.io.File;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.net.ssl.SSLContext;
+
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.Exchange;
+import org.apache.camel.component.http.handler.BasicValidationHandler;
+import org.apache.camel.component.http.handler.HeaderValidationHandler;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.impl.bootstrap.HttpServer;
+import org.apache.http.impl.bootstrap.ServerBootstrap;
+import org.apache.http.ssl.SSLContexts;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.camel.component.http.HttpMethods.GET;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * If SSLContext is created via system properties, is is cached. Automatically created next sslContext (with different
+ * system properties) contains values from the first creation. Therefore it is not possible to create different test,
+ * which uses systemProperties without forked JVM.
+ */
+public class HttpsProducerWithSystemPropertiesTest extends BaseHttpTest {
+
+    private static Object defaultSystemHttpAgent;
+
+    @BindToRegistry("x509HostnameVerifier")
+    private NoopHostnameVerifier hostnameVerifier = new NoopHostnameVerifier();
+
+    private HttpServer localServer;
+
+    @BeforeAll
+    public static void setUpHttpAgentSystemProperty() throws Exception {
+        // the 'http.agent' java system-property corresponds to the http 'User-Agent' header
+        defaultSystemHttpAgent = System.setProperty("http.agent", "myCoolCamelCaseAgent");
+
+        final URL storeResourceUrl = HttpsServerTestSupport.class.getResource("/localhost.p12");
+
+        System.setProperty("javax.net.ssl.keyStore", new File(storeResourceUrl.toURI()).getAbsolutePath());
+        System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
+        System.setProperty("javax.net.ssl.trustStore", new File(storeResourceUrl.toURI()).getAbsolutePath());
+        System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
+    }
+
+    @AfterAll
+    public static void resetHttpAgentSystemProperty() throws Exception {
+        if (defaultSystemHttpAgent != null) {
+            System.setProperty("http.agent", String.valueOf(defaultSystemHttpAgent));
+        } else {
+            System.clearProperty("http.agent");
+        }
+        System.clearProperty("javax.net.ssl.trustStorePassword");
+        System.clearProperty("javax.net.ssl.trustStore");
+        System.clearProperty("javax.net.ssl.keyStorePassword");
+        System.clearProperty("javax.net.ssl.keyStore");
+    }
+
+    @BeforeEach
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        URL serverKeystoreUurl = HttpsServerTestSupport.class.getResource("/localhost.p12");
+        URL serverTrustStoreUrl = HttpsServerTestSupport.class.getResource("/localhost.p12");
+        SSLContext sslcontext = SSLContexts.custom()
+                .loadKeyMaterial(serverKeystoreUurl, "changeit".toCharArray(), "changeit".toCharArray())
+                .loadTrustMaterial(serverTrustStoreUrl, "changeit".toCharArray())
+                .build();
+
+        Map<String, String> expectedHeaders = new HashMap<>();
+        expectedHeaders.put("User-Agent", "myCoolCamelCaseAgent");
+
+        localServer = ServerBootstrap.bootstrap().setHttpProcessor(getBasicHttpProcessor())
+                .setConnectionReuseStrategy(getConnectionReuseStrategy()).setResponseFactory(getHttpResponseFactory())
+                .setExpectationVerifier(getHttpExpectationVerifier()).setSslContext(sslcontext)
+                .setSslSetupHandler(socket -> socket.setNeedClientAuth(true))
+                .registerHandler("/mail/", new BasicValidationHandler(GET.name(), null, null, getExpectedContent()))
+                .registerHandler("/header/",
+                        new HeaderValidationHandler(GET.name(), null, null, getExpectedContent(), expectedHeaders))
+                .create();
+        localServer.start();
+
+    }
+
+    @AfterEach
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+
+        if (localServer != null) {
+            localServer.stop();
+        }
+    }
+
+    @Test
+    public void httpGetWithProxyFromSystemProperties() throws Exception {
+
+        String endpointUri = "https://" + localServer.getInetAddress().getHostName() + ":" + localServer.getLocalPort()
+                             + "/header/?x509HostnameVerifier=x509HostnameVerifier&useSystemProperties=true";
+        Exchange exchange = template.request(endpointUri, exchange1 -> {
+        });
+
+        assertExchange(exchange);
+    }
+
+    @Test
+    public void testTwoWaySuccessfull() throws Exception {
+        Exchange exchange = template.request("https://127.0.0.1:" + localServer.getLocalPort()
+                                             + "/mail/?x509HostnameVerifier=x509HostnameVerifier&useSystemProperties=true",
+                exchange1 -> {
+                });
+
+        assertExchange(exchange);
+    }
+
+    @Test
+    public void testTwoWayFailure() throws Exception {
+        Exchange exchange = template.request("https://127.0.0.1:" + localServer.getLocalPort()
+                                             + "/mail/?x509HostnameVerifier=x509HostnameVerifier",
+                exchange1 -> {
+                });
+        //exchange does not have response code, because it was rejected
+        assertTrue(exchange.getMessage().getHeaders().isEmpty());
+    }
+}