Repository: camel Updated Branches: refs/heads/master 9c4e9df98 -> f39ba5fee
CAMEL-9638: Introduced SNIHostName config in sslContextParameters Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/3d84bbef Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/3d84bbef Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/3d84bbef Branch: refs/heads/master Commit: 3d84bbef8879fc7a64c73ad38aae6c20099f1d73 Parents: b8f5da7 Author: Arno Noordover <anoordo...@users.noreply.github.com> Authored: Wed Jun 22 21:07:20 2016 +0200 Committer: Arno Noordover <anoordo...@users.noreply.github.com> Committed: Wed Jun 22 21:07:20 2016 +0200 ---------------------------------------------------------------------- .../util/jsse/BaseSSLContextParameters.java | 16 +++- .../util/jsse/SSLContextClientParameters.java | 16 ++++ ...ctSSLContextClientParametersFactoryBean.java | 11 ++- .../xml/util/jsse/SNIHostNamesDefinition.java | 36 +++++++++ components/camel-http4/pom.xml | 5 ++ .../component/http4/HttpSNIHostNameTest.java | 61 ++++++++++++++++ .../camel/component/http4/CamelHttp4Context.xml | 77 ++++++++++++++++++++ 7 files changed, 218 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/3d84bbef/camel-core/src/main/java/org/apache/camel/util/jsse/BaseSSLContextParameters.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/util/jsse/BaseSSLContextParameters.java b/camel-core/src/main/java/org/apache/camel/util/jsse/BaseSSLContextParameters.java index 0554067..a585fbe 100644 --- a/camel-core/src/main/java/org/apache/camel/util/jsse/BaseSSLContextParameters.java +++ b/camel-core/src/main/java/org/apache/camel/util/jsse/BaseSSLContextParameters.java @@ -34,9 +34,12 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.net.ssl.KeyManager; +import javax.net.ssl.SNIHostName; +import javax.net.ssl.SNIServerName; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContextSpi; import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLServerSocketFactory; import javax.net.ssl.SSLSessionContext; @@ -109,7 +112,10 @@ public abstract class BaseSSLContextParameters extends JsseParameters { * The optional {@link SSLSessionContext} timeout time for {@link javax.net.ssl.SSLSession}s in seconds. */ private String sessionTimeout; - + + protected List<SNIServerName> getSNIHostNames() { + return Collections.emptyList(); + } /** * Returns the optional explicitly configured cipher suites for this configuration. @@ -515,7 +521,11 @@ public abstract class BaseSSLContextParameters extends JsseParameters { @Override public SSLSocket configure(SSLSocket socket) { - + + SSLParameters sslParameters = socket.getSSLParameters(); + sslParameters.setServerNames(getSNIHostNames()); + socket.setSSLParameters(sslParameters); + Collection<String> filteredCipherSuites = BaseSSLContextParameters.this .filter(enabledCipherSuites, Arrays.asList(socket.getSSLParameters().getCipherSuites()), Arrays.asList(socket.getEnabledCipherSuites()), @@ -539,7 +549,7 @@ public abstract class BaseSSLContextParameters extends JsseParameters { Arrays.asList(socket.getEnabledProtocols()), enabledSecureSocketProtocolsPatterns, defaultEnabledSecureSocketProtocolsPatterns, !allowPassthrough); - + if (LOG.isDebugEnabled()) { LOG.debug(SSL_SOCKET_PROTOCOL_LOG_MSG, new Object[] {socket, http://git-wip-us.apache.org/repos/asf/camel/blob/3d84bbef/camel-core/src/main/java/org/apache/camel/util/jsse/SSLContextClientParameters.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/util/jsse/SSLContextClientParameters.java b/camel-core/src/main/java/org/apache/camel/util/jsse/SSLContextClientParameters.java index b8cca2f..a31fc21 100644 --- a/camel-core/src/main/java/org/apache/camel/util/jsse/SSLContextClientParameters.java +++ b/camel-core/src/main/java/org/apache/camel/util/jsse/SSLContextClientParameters.java @@ -17,9 +17,12 @@ package org.apache.camel.util.jsse; import java.security.GeneralSecurityException; +import java.util.ArrayList; import java.util.Collections; import java.util.List; +import javax.net.ssl.SNIHostName; +import javax.net.ssl.SNIServerName; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLServerSocketFactory; @@ -34,6 +37,19 @@ public class SSLContextClientParameters extends BaseSSLContextParameters { private static final Logger LOG = LoggerFactory.getLogger(SSLContextClientParameters.class); + private List<SNIServerName> sniHostNames = new ArrayList<>(); + + public void setSniHostNames(List<String> sniHostNames) { + for (String sniHostName : sniHostNames) { + this.sniHostNames.add(new SNIHostName(sniHostName)); + } + } + + @Override + protected List<SNIServerName> getSNIHostNames() { + return sniHostNames; + } + @Override protected boolean getAllowPassthrough() { return true; http://git-wip-us.apache.org/repos/asf/camel/blob/3d84bbef/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/AbstractSSLContextClientParametersFactoryBean.java ---------------------------------------------------------------------- diff --git a/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/AbstractSSLContextClientParametersFactoryBean.java b/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/AbstractSSLContextClientParametersFactoryBean.java index 0439173..55b465a 100644 --- a/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/AbstractSSLContextClientParametersFactoryBean.java +++ b/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/AbstractSSLContextClientParametersFactoryBean.java @@ -18,6 +18,7 @@ package org.apache.camel.core.xml.util.jsse; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlTransient; import org.apache.camel.util.jsse.SSLContextClientParameters; @@ -25,11 +26,15 @@ import org.apache.camel.util.jsse.SSLContextClientParameters; @XmlAccessorType(XmlAccessType.FIELD) @XmlTransient public abstract class AbstractSSLContextClientParametersFactoryBean extends AbstractBaseSSLContextParametersFactoryBean<SSLContextClientParameters> { - + + @XmlElement(name = "SNIHostNamesDefinition") + private SNIHostNamesDefinition sniHostNamesDefinition; + @Override protected SSLContextClientParameters createInstance() { SSLContextClientParameters newInstance = new SSLContextClientParameters(); newInstance.setCamelContext(getCamelContext()); + newInstance.setSniHostNames(sniHostNamesDefinition.getSniHostName()); return newInstance; } @@ -37,4 +42,8 @@ public abstract class AbstractSSLContextClientParametersFactoryBean extends Abst public Class<SSLContextClientParameters> getObjectType() { return SSLContextClientParameters.class; } + + public org.apache.camel.core.xml.util.jsse.SNIHostNamesDefinition getSniHostNamesDefinition() { + return sniHostNamesDefinition; + } } http://git-wip-us.apache.org/repos/asf/camel/blob/3d84bbef/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/SNIHostNamesDefinition.java ---------------------------------------------------------------------- diff --git a/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/SNIHostNamesDefinition.java b/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/SNIHostNamesDefinition.java new file mode 100644 index 0000000..59f3d93 --- /dev/null +++ b/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/util/jsse/SNIHostNamesDefinition.java @@ -0,0 +1,36 @@ +/** + * 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.core.xml.util.jsse; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "SNIHostNames", propOrder = {"sniHostName"}) +public class SNIHostNamesDefinition { + + @XmlElement(name = "SNIHostName") + private List<String> sniHostName; + + public List<String> getSniHostName() { + return sniHostName; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/3d84bbef/components/camel-http4/pom.xml ---------------------------------------------------------------------- diff --git a/components/camel-http4/pom.xml b/components/camel-http4/pom.xml index fa3a96e..376c917 100644 --- a/components/camel-http4/pom.xml +++ b/components/camel-http4/pom.xml @@ -53,6 +53,11 @@ <artifactId>camel-http-common</artifactId> </dependency> <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-test-spring</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>${httpclient4-version}</version> http://git-wip-us.apache.org/repos/asf/camel/blob/3d84bbef/components/camel-http4/src/test/java/org/apache/camel/component/http4/HttpSNIHostNameTest.java ---------------------------------------------------------------------- diff --git a/components/camel-http4/src/test/java/org/apache/camel/component/http4/HttpSNIHostNameTest.java b/components/camel-http4/src/test/java/org/apache/camel/component/http4/HttpSNIHostNameTest.java new file mode 100644 index 0000000..7f9ffb4 --- /dev/null +++ b/components/camel-http4/src/test/java/org/apache/camel/component/http4/HttpSNIHostNameTest.java @@ -0,0 +1,61 @@ +/** + * 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.http4; + +import org.apache.camel.CamelExecutionException; +import org.apache.camel.http.common.HttpOperationFailedException; +import org.apache.camel.test.spring.CamelSpringTestSupport; +import org.junit.Test; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import static org.hamcrest.core.Is.is; + +public class HttpSNIHostNameTest extends CamelSpringTestSupport { + + @Test + public void testMnotDotNetDoesNotReturnStatusCode421() throws Exception { + String result = template.requestBody("direct:goodSNI", null, String.class); + assertNotNull(result); + } + @Test + public void testMnotDotNetNoSniDoesReturnStatusCode403() { + try { + template.requestBody("direct:noSNI", null, String.class); + } catch (CamelExecutionException e) { + HttpOperationFailedException cause = (HttpOperationFailedException) e.getCause(); + assertThat(cause.getStatusCode(), is(403)); + } + } + + @Test + public void testMnotDotNetWrongSniDoesReturnStatusCode421() { + try { + template.requestBody("direct:wrongSNI", null, String.class); + } catch (CamelExecutionException e) { + HttpOperationFailedException cause = (HttpOperationFailedException) e.getCause(); + assertThat(cause.getStatusCode(), is(421)); + } + } + + @Override + protected AbstractApplicationContext createApplicationContext() { + ClassPathXmlApplicationContext ctx = + new ClassPathXmlApplicationContext(new String[]{"org/apache/camel/component/http4/CamelHttp4Context.xml"}); + return ctx; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/3d84bbef/components/camel-http4/src/test/resources/org/apache/camel/component/http4/CamelHttp4Context.xml ---------------------------------------------------------------------- diff --git a/components/camel-http4/src/test/resources/org/apache/camel/component/http4/CamelHttp4Context.xml b/components/camel-http4/src/test/resources/org/apache/camel/component/http4/CamelHttp4Context.xml new file mode 100644 index 0000000..b51f2f9 --- /dev/null +++ b/components/camel-http4/src/test/resources/org/apache/camel/component/http4/CamelHttp4Context.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:camel="http://camel.apache.org/schema/spring" + + xsi:schemaLocation=" + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd + "> + + <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/> + + <camel:sslContextParameters id="correctSniSslContextParameters"> + <camel:clientParameters> + <camel:SNIHostNamesDefinition> + <camel:SNIHostName>www.mnot.net</camel:SNIHostName> + </camel:SNIHostNamesDefinition> + </camel:clientParameters> + </camel:sslContextParameters> + + <camel:sslContextParameters id="noSniSslContextParameters"> + </camel:sslContextParameters> + + <camel:sslContextParameters id="wrongSniSslContextParameters"> + <camel:clientParameters> + <camel:SNIHostNamesDefinition> + <camel:SNIHostName>blabla</camel:SNIHostName> + </camel:SNIHostNamesDefinition> + </camel:clientParameters> + </camel:sslContextParameters> + + <bean id="https4" class="org.apache.camel.component.http4.HttpComponent"> + <property name="sslContextParameters" ref="correctSniSslContextParameters"/> + </bean> + + <bean id="https4-no" class="org.apache.camel.component.http4.HttpComponent"> + <property name="sslContextParameters" ref="noSniSslContextParameters"/> + </bean> + + <bean id="https4-wrong" class="org.apache.camel.component.http4.HttpComponent"> + <property name="sslContextParameters" ref="wrongSniSslContextParameters"/> + </bean> + + <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> + <route errorHandlerRef="noErrorHandler"> + <from uri="direct:goodSNI"/> + <to uri="https4://www.mnot.net?sslContextParameters=correctSniSslContextParameters"/> + </route> + <route errorHandlerRef="noErrorHandler"> + <from uri="direct:wrongSNI"/> + <to uri="https4-wrong://www.mnot.net?sslContextParameters=wrongSniSslContextParameters"/> + </route> + <route errorHandlerRef="noErrorHandler"> + <from uri="direct:noSNI"/> + <to uri="https4-no://www.mnot.net?sslContextParameters=noSniSslContextParameters"/> + </route> + </camelContext> + + <bean id="noErrorHandler" class="org.apache.camel.builder.NoErrorHandlerBuilder"/> + +</beans> \ No newline at end of file