From 00a142b5609b04689d6d53a0a941a84d950a150c Mon Sep 17 00:00:00 2001
From: jansupol
Date: Thu, 21 Apr 2022 16:00:37 +0200
Subject: [PATCH 1/2] Support null PROXY_USERNAME Support SSL Hostname
verification Update request host and port in SSL Context Correct order of TLS
handler vs Proxy handler
Co-authored-by: olotenko
---
.../connector/NettyClientProperties.java | 2 +
.../netty/connector/NettyConnector.java | 37 ++++++++++++++-----
2 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java
index 17e55a937a..84b8da56fb 100644
--- a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java
@@ -53,4 +53,6 @@ public class NettyClientProperties {
*
*/
public static final String MAX_CONNECTIONS = "jersey.config.client.maxConnections";
+
+ public static final String ENABLE_SSL_HOSTNAME_VERIFICATION = "jersey.config.client.tls.enableHostnameVerification";
}
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java
index 056ef31802..e2d4d35514 100644
--- a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java
@@ -32,6 +32,9 @@
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLParameters;
+
import javax.ws.rs.ProcessingException;
import javax.ws.rs.client.Client;
import javax.ws.rs.core.Configuration;
@@ -60,6 +63,7 @@
import io.netty.handler.proxy.HttpProxyHandler;
import io.netty.handler.ssl.ClientAuth;
import io.netty.handler.ssl.JdkSslContext;
+import io.netty.handler.ssl.SslHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
@@ -216,15 +220,9 @@ protected CompletableFuture execute(final ClientRequest jerseyRe
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
- // Enable HTTPS if necessary.
- if ("https".equals(requestUri.getScheme())) {
- // making client authentication optional for now; it could be extracted to configurable property
- JdkSslContext jdkSslContext = new JdkSslContext(client.getSslContext(), true, ClientAuth.NONE);
- p.addLast(jdkSslContext.newHandler(ch.alloc()));
- }
+ Configuration config = jerseyRequest.getConfiguration();
// http proxy
- Configuration config = jerseyRequest.getConfiguration();
final Object proxyUri = config.getProperties().get(ClientProperties.PROXY_URI);
if (proxyUri != null) {
final URI u = getProxyUri(proxyUri);
@@ -234,9 +232,28 @@ protected void initChannel(SocketChannel ch) throws Exception {
final String password = ClientProperties.getValue(
config.getProperties(), ClientProperties.PROXY_PASSWORD, String.class);
- p.addLast(new HttpProxyHandler(new InetSocketAddress(u.getHost(),
- u.getPort() == -1 ? 8080 : u.getPort()),
- userName, password));
+ InetSocketAddress proxyAddr = new InetSocketAddress(u.getHost(),
+ u.getPort() == -1 ? 8080 : u.getPort());
+ p.addLast(userName == null ? new HttpProxyHandler(proxyAddr)
+ : new HttpProxyHandler(proxyAddr, userName, password));
+ }
+
+ // Enable HTTPS if necessary.
+ if ("https".equals(requestUri.getScheme())) {
+ // making client authentication optional for now; it could be extracted to configurable property
+ JdkSslContext jdkSslContext = new JdkSslContext(client.getSslContext(), true, ClientAuth.NONE);
+ int port = requestUri.getPort();
+ SslHandler sslHandler = jdkSslContext.newHandler(ch.alloc(), requestUri.getHost(),
+ port <= 0 ? 443 : port, executorService);
+ if (ClientProperties.getValue(config.getProperties(),
+ NettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION, true)) {
+ SSLEngine sslEngine = sslHandler.engine();
+ SSLParameters sslParameters = sslEngine.getSSLParameters();
+ sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
+ sslEngine.setSSLParameters(sslParameters);
+ }
+
+ p.addLast(sslHandler);
}
p.addLast(new HttpClientCodec());
From 422068af87b6cb9d81f97db39e8bb516b5a84562 Mon Sep 17 00:00:00 2001
From: jansupol
Date: Thu, 21 Apr 2022 16:36:07 +0200
Subject: [PATCH 2/2] Add javadoc to Netty ENABLE_SSL_HOSTNAME_VERIFICATION
configuration property
Signed-off-by: jansupol
---
.../netty/connector/NettyClientProperties.java | 15 ++++++++++++++-
.../jersey/netty/connector/NettyConnector.java | 15 +++++++++++++--
2 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java
index 84b8da56fb..bf34699708 100644
--- a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -54,5 +54,18 @@ public class NettyClientProperties {
*/
public static final String MAX_CONNECTIONS = "jersey.config.client.maxConnections";
+ /**
+ *
+ * Sets the endpoint identification algorithm to HTTPS.
+ *
+ *
+ * The default value is {@code true} (for HTTPS uri scheme).
+ *
+ *
+ * The name of the configuration property is {@value}.
+ *
+ * @since 2.35
+ * @see javax.net.ssl.SSLParameters#setEndpointIdentificationAlgorithm(String)
+ */
public static final String ENABLE_SSL_HOSTNAME_VERIFICATION = "jersey.config.client.tls.enableHostnameVerification";
}
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java
index e2d4d35514..c97ea2e16c 100644
--- a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -61,7 +61,9 @@
import io.netty.handler.codec.http.HttpUtil;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.proxy.HttpProxyHandler;
+import io.netty.handler.ssl.ApplicationProtocolConfig;
import io.netty.handler.ssl.ClientAuth;
+import io.netty.handler.ssl.IdentityCipherSuiteFilter;
import io.netty.handler.ssl.JdkSslContext;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
@@ -241,7 +243,16 @@ protected void initChannel(SocketChannel ch) throws Exception {
// Enable HTTPS if necessary.
if ("https".equals(requestUri.getScheme())) {
// making client authentication optional for now; it could be extracted to configurable property
- JdkSslContext jdkSslContext = new JdkSslContext(client.getSslContext(), true, ClientAuth.NONE);
+ JdkSslContext jdkSslContext = new JdkSslContext(
+ client.getSslContext(),
+ true,
+ (Iterable) null,
+ IdentityCipherSuiteFilter.INSTANCE,
+ (ApplicationProtocolConfig) null,
+ ClientAuth.NONE,
+ (String[]) null, /* enable default protocols */
+ false /* true if the first write request shouldn't be encrypted */
+ );
int port = requestUri.getPort();
SslHandler sslHandler = jdkSslContext.newHandler(ch.alloc(), requestUri.getHost(),
port <= 0 ? 443 : port, executorService);