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

pjfanning pushed a commit to branch 1.3.x
in repository https://gitbox.apache.org/repos/asf/pekko-grpc.git


The following commit(s) were added to refs/heads/1.3.x by this push:
     new b88f8e6d Revert verify-hostname support on 1.3.x (#858)
b88f8e6d is described below

commit b88f8e6dfdc6e075bfa75df005a35233b6ea5e78
Author: PJ Fanning <[email protected]>
AuthorDate: Sun Aug 23 16:37:30 2026 +0100

    Revert verify-hostname support on 1.3.x (#858)
    
    Motivation:
    The backport of #820 (#845) makes 1.3.x less secure than 1.2.x for the
    pekko-http client backend.
    
    `ConnectionContext.httpsClient(SSLContext)`, which 1.2.x uses, already sets
    both client mode and the `https` endpoint identification algorithm in
    pekko-http 1.1.0, the version this branch depends on. Hostname verification
    was therefore never absent. #845 moved to the
    `httpsClient((host, port) => ...)` overload, which pekko-http marks
    `@ApiMayChange` and documents as leaving SNI and hostname verification to
    the caller, and set the endpoint identification algorithm only when
    `verifyHostname` is true. `reference.conf` on this branch defaults
    `verify-hostname` to false, and the follow-up that flipped that default to
    true on main (#830) was not backported.
    
    The result is that a pekko-http backend client with TLS accepts any
    certificate its trust store chains to, regardless of the host it was issued
    for. Upgrading 1.2.x to 1.3.0 would silently lose hostname verification
    without any configuration change.
    
    Modification:
    Restore the three source files touched by #845 to their pre-backport state:
    reference.conf, GrpcClientSettings and PekkoHttpClientUtils. The unrelated
    GitHub Actions changes that #845 also carried are kept, so this is not a
    revert of the whole commit.
    
    `verifyHostname` and `withVerifyHostname` have never appeared in a release,
    so removing them moves the public API back towards the MiMa baseline rather
    than away from it. The backport added no MiMa excludes, so none are left
    dangling.
    
    Result:
    1.3.x verifies the server hostname against its certificate again, matching
    1.2.x. The import reordering that #845 incidentally applied to
    PekkoHttpClientUtils is reverted along with it, so the file matches 1.2.x.
    
    Tests:
    - sbt "runtime/test" - 110 tests passed
    - sbt "runtime/mimaReportBinaryIssues" - passed
    - sbt scalafmtCheckAll scalafmtSbtCheck - passed
    
    References:
    Refs #820, Refs #845, Refs #830
---
 runtime/src/main/resources/reference.conf          |  6 ----
 .../org/apache/pekko/grpc/GrpcClientSettings.scala | 22 +++---------
 .../pekko/grpc/internal/PekkoHttpClientUtils.scala | 41 +++++++---------------
 3 files changed, 16 insertions(+), 53 deletions(-)

diff --git a/runtime/src/main/resources/reference.conf 
b/runtime/src/main/resources/reference.conf
index 89a84f85..99fcc62a 100644
--- a/runtime/src/main/resources/reference.conf
+++ b/runtime/src/main/resources/reference.conf
@@ -38,12 +38,6 @@ pekko.grpc.client."*" {
   # leave empty to auto-detect, or configure 'jdk' or 'openssl'.
   ssl-provider = ""
 
-  # Whether to verify the server's hostname against its TLS certificate (RFC 
2818).
-  # When false (the default), the client accepts any valid certificate 
regardless
-  # of hostname. This is insecure for production and should only be used for 
testing.
-  # Only effective for the pekko-http backend; the netty backend always 
verifies.
-  verify-hostname = false
-
   # TODO: Enforce HTTP/2 TLS restrictions: 
https://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-9.2
 
   # The number of times to try connecting before giving up.
diff --git 
a/runtime/src/main/scala/org/apache/pekko/grpc/GrpcClientSettings.scala 
b/runtime/src/main/scala/org/apache/pekko/grpc/GrpcClientSettings.scala
index 116b3188..11c6eef1 100644
--- a/runtime/src/main/scala/org/apache/pekko/grpc/GrpcClientSettings.scala
+++ b/runtime/src/main/scala/org/apache/pekko/grpc/GrpcClientSettings.scala
@@ -158,8 +158,7 @@ object GrpcClientSettings {
       getOptionalString(clientConfiguration, "user-agent"),
       clientConfiguration.getBoolean("use-tls"),
       getOptionalString(clientConfiguration, "load-balancing-policy"),
-      clientConfiguration.getString("backend"),
-      verifyHostname = clientConfiguration.getBoolean("verify-hostname"))
+      clientConfiguration.getString("backend"))
 
   private def getOptionalString(config: Config, path: String): Option[String] =
     config.getString(path) match {
@@ -207,8 +206,7 @@ final class GrpcClientSettings private (
     val useTls: Boolean,
     val loadBalancingPolicy: Option[String],
     val backend: String,
-    val channelBuilderOverrides: NettyChannelBuilder => NettyChannelBuilder = 
identity,
-    val verifyHostname: Boolean) {
+    val channelBuilderOverrides: NettyChannelBuilder => NettyChannelBuilder = 
identity) {
   require(
     sslContext.isEmpty || trustManager.isEmpty,
     "Configuring the sslContext or the trustManager is mutually exclusive")
@@ -296,16 +294,6 @@ final class GrpcClientSettings private (
   def withBackend(value: String): GrpcClientSettings =
     copy(backend = value)
 
-  /**
-   * Whether to verify the server's hostname against its TLS certificate (RFC 
2818).
-   * When false (the default), the client accepts any valid certificate 
regardless
-   * of hostname. This is insecure for production and should only be used for 
testing.
-   * Only effective for the pekko-http backend; the netty backend always 
verifies.
-   * @since 2.0.0
-   */
-  def withVerifyHostname(value: Boolean): GrpcClientSettings =
-    copy(verifyHostname = value)
-
   private def copy(
       serviceName: String = serviceName,
       servicePortName: Option[String] = servicePortName,
@@ -323,8 +311,7 @@ final class GrpcClientSettings private (
       connectionAttempts: Option[Int] = connectionAttempts,
       loadBalancingPolicy: Option[String] = loadBalancingPolicy,
       backend: String = backend,
-      channelBuilderOverrides: NettyChannelBuilder => NettyChannelBuilder = 
channelBuilderOverrides,
-      verifyHostname: Boolean = verifyHostname)
+      channelBuilderOverrides: NettyChannelBuilder => NettyChannelBuilder = 
channelBuilderOverrides)
       : GrpcClientSettings =
     new GrpcClientSettings(
       callCredentials = callCredentials,
@@ -344,6 +331,5 @@ final class GrpcClientSettings private (
       connectionAttempts = connectionAttempts,
       loadBalancingPolicy = loadBalancingPolicy,
       backend = backend,
-      channelBuilderOverrides = channelBuilderOverrides,
-      verifyHostname = verifyHostname)
+      channelBuilderOverrides = channelBuilderOverrides)
 }
diff --git 
a/runtime/src/main/scala/org/apache/pekko/grpc/internal/PekkoHttpClientUtils.scala
 
b/runtime/src/main/scala/org/apache/pekko/grpc/internal/PekkoHttpClientUtils.scala
index efd16b53..3567bf1e 100644
--- 
a/runtime/src/main/scala/org/apache/pekko/grpc/internal/PekkoHttpClientUtils.scala
+++ 
b/runtime/src/main/scala/org/apache/pekko/grpc/internal/PekkoHttpClientUtils.scala
@@ -16,7 +16,7 @@ package org.apache.pekko.grpc.internal
 import java.net.InetSocketAddress
 import java.security.SecureRandom
 import java.util.concurrent.CompletionStage
-
+import scala.concurrent.duration._
 import org.apache.pekko
 import pekko.{ Done, NotUsed }
 import pekko.actor.ClassicActorSystemProvider
@@ -27,7 +27,6 @@ import pekko.grpc.{ GrpcClientSettings, GrpcResponseMetadata, 
GrpcSingleResponse
 import pekko.http.scaladsl.model.HttpEntity.{ Chunk, Chunked, LastChunk, 
Strict }
 import pekko.http.scaladsl.{ ClientTransport, ConnectionContext, Http }
 import pekko.http.scaladsl.model._
-import pekko.http.scaladsl.model.StatusCodes
 import pekko.http.scaladsl.model.headers.RawHeader
 import pekko.http.scaladsl.settings.ClientConnectionSettings
 import pekko.stream.{ Materializer, OverflowStrategy }
@@ -39,8 +38,8 @@ import io.grpc.{ CallOptions, MethodDescriptor, Status, 
StatusRuntimeException }
 import javax.net.ssl.{ KeyManager, SSLContext, TrustManager }
 import scala.collection.immutable
 import scala.concurrent.{ ExecutionContext, Future, Promise }
-import scala.concurrent.duration._
 import scala.util.{ Failure, Success }
+import pekko.http.scaladsl.model.StatusCodes
 
 /**
  * INTERNAL API
@@ -95,34 +94,18 @@ object PekkoHttpClientUtils {
 
     val http2client =
       if (settings.useTls) {
-        if (!settings.verifyHostname) {
-          log.warning(
-            "TLS hostname verification is disabled for pekko-http client '{}'. 
" +
-            "This is insecure and should only be used for testing. " +
-            "Enable it with verify-hostname = true in your configuration. " +
-            "Note: the netty backend always verifies hostnames.",
-            settings.serviceName)
-        }
-        val sslContext =
-          settings.sslContext.getOrElse {
-            settings.trustManager match {
-              case None => SSLContext.getDefault
-              case Some(trustManager) =>
-                val ctx: SSLContext = SSLContext.getInstance("TLS")
-                ctx.init(Array[KeyManager](), 
Array[TrustManager](trustManager), new SecureRandom)
-                ctx
-            }
-          }
         val connectionContext =
-          ConnectionContext.httpsClient((hostname, port) => {
-            val engine = sslContext.createSSLEngine(hostname, port)
-            if (settings.verifyHostname) {
-              val sslParams = engine.getSSLParameters
-              sslParams.setEndpointIdentificationAlgorithm("HTTPS")
-              engine.setSSLParameters(sslParams)
+          ConnectionContext.httpsClient {
+            settings.sslContext.getOrElse {
+              settings.trustManager match {
+                case None => SSLContext.getDefault
+                case Some(trustManager) =>
+                  val sslContext: SSLContext = SSLContext.getInstance("TLS")
+                  sslContext.init(Array[KeyManager](), 
Array[TrustManager](trustManager), new SecureRandom)
+                  sslContext
+              }
             }
-            engine
-          })
+          }
 
         
builder.withCustomHttpsConnectionContext(connectionContext).managedPersistentHttp2()
       } else {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to