=str Remove manual hostname verifier support, used to be included only because Java 6 (#22320)
* Remove manual hostname verifier support, used to be included only because Java 6 #21854 * Remove manual hostname verifier support, used to be included only because Java 6 #21854
This commit is contained in:
parent
b2f7c7a037
commit
021829e21e
6 changed files with 37 additions and 35 deletions
|
|
@ -471,6 +471,25 @@ class TlsSpec extends StreamSpec("akka.loglevel=INFO\nakka.actor.debug.receive=o
|
||||||
Await.result(f, 8.second).utf8String should be(scenario.output.utf8String)
|
Await.result(f, 8.second).utf8String should be(scenario.output.utf8String)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"verify hostname" in assertAllStagesStopped {
|
||||||
|
def run(hostName: String): Future[akka.Done] = {
|
||||||
|
val rhs = Flow[SslTlsInbound]
|
||||||
|
.map {
|
||||||
|
case SessionTruncated ⇒ SendBytes(ByteString.empty)
|
||||||
|
case SessionBytes(_, b) ⇒ SendBytes(b)
|
||||||
|
}
|
||||||
|
val clientTls = TLS(sslContext, None, cipherSuites, Client, EagerClose, Some((hostName, 80)))
|
||||||
|
val flow = clientTls atop serverTls(EagerClose).reversed join rhs
|
||||||
|
|
||||||
|
Source.single(SendBytes(ByteString.empty)).via(flow).runWith(Sink.ignore)
|
||||||
|
}
|
||||||
|
Await.result(run("akka-remote"), 3.seconds) // CN=akka-remote
|
||||||
|
val cause = intercept[SSLHandshakeException] {
|
||||||
|
Await.result(run("akka-stream"), 3.seconds)
|
||||||
|
}
|
||||||
|
cause.getCause.getCause.getMessage should startWith("No name matching akka-stream found")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
"A SslTlsPlacebo" must {
|
"A SslTlsPlacebo" must {
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,7 @@ private[akka] case class ActorMaterializerImpl(
|
||||||
case tls: TlsModule ⇒ // TODO solve this so TlsModule doesn't need special treatment here
|
case tls: TlsModule ⇒ // TODO solve this so TlsModule doesn't need special treatment here
|
||||||
val es = effectiveSettings(effectiveAttributes)
|
val es = effectiveSettings(effectiveAttributes)
|
||||||
val props =
|
val props =
|
||||||
TLSActor.props(es, tls.createSSLEngine, tls.verifySession, tls.closing)
|
TLSActor.props(es, tls.createSSLEngine, tls.closing)
|
||||||
val impl = actorOf(props, stageName(effectiveAttributes), es.dispatcher)
|
val impl = actorOf(props, stageName(effectiveAttributes), es.dispatcher)
|
||||||
def factory(id: Int) = new ActorPublisher[Any](impl) {
|
def factory(id: Int) = new ActorPublisher[Any](impl) {
|
||||||
override val wakeUpMsg = FanOut.SubstreamSubscribePending(id)
|
override val wakeUpMsg = FanOut.SubstreamSubscribePending(id)
|
||||||
|
|
|
||||||
|
|
@ -30,10 +30,9 @@ private[stream] object TLSActor {
|
||||||
def props(
|
def props(
|
||||||
settings: ActorMaterializerSettings,
|
settings: ActorMaterializerSettings,
|
||||||
createSSLEngine: ActorSystem ⇒ SSLEngine, // ActorSystem is only needed to support the AkkaSSLConfig legacy, see #21753
|
createSSLEngine: ActorSystem ⇒ SSLEngine, // ActorSystem is only needed to support the AkkaSSLConfig legacy, see #21753
|
||||||
verifySession: (ActorSystem, SSLSession) ⇒ Try[Unit], // ActorSystem is only needed to support the AkkaSSLConfig legacy, see #21753
|
|
||||||
closing: TLSClosing,
|
closing: TLSClosing,
|
||||||
tracing: Boolean = false): Props =
|
tracing: Boolean = false): Props =
|
||||||
Props(new TLSActor(settings, createSSLEngine, verifySession, closing, tracing)).withDeploy(Deploy.local)
|
Props(new TLSActor(settings, createSSLEngine, closing, tracing)).withDeploy(Deploy.local)
|
||||||
|
|
||||||
final val TransportIn = 0
|
final val TransportIn = 0
|
||||||
final val TransportOut = 0
|
final val TransportOut = 0
|
||||||
|
|
@ -48,7 +47,6 @@ private[stream] object TLSActor {
|
||||||
private[stream] class TLSActor(
|
private[stream] class TLSActor(
|
||||||
settings: ActorMaterializerSettings,
|
settings: ActorMaterializerSettings,
|
||||||
createSSLEngine: ActorSystem ⇒ SSLEngine, // ActorSystem is only needed to support the AkkaSSLConfig legacy, see #21753
|
createSSLEngine: ActorSystem ⇒ SSLEngine, // ActorSystem is only needed to support the AkkaSSLConfig legacy, see #21753
|
||||||
verifySession: (ActorSystem, SSLSession) ⇒ Try[Unit], // ActorSystem is only needed to support the AkkaSSLConfig legacy, see #21753
|
|
||||||
closing: TLSClosing,
|
closing: TLSClosing,
|
||||||
tracing: Boolean)
|
tracing: Boolean)
|
||||||
extends Actor with ActorLogging with Pump {
|
extends Actor with ActorLogging with Pump {
|
||||||
|
|
@ -410,15 +408,8 @@ private[stream] class TLSActor(
|
||||||
|
|
||||||
private def handshakeFinished(): Unit = {
|
private def handshakeFinished(): Unit = {
|
||||||
if (tracing) log.debug("handshake finished")
|
if (tracing) log.debug("handshake finished")
|
||||||
val session = engine.getSession
|
currentSession = engine.getSession
|
||||||
|
corkUser = false
|
||||||
verifySession(context.system, session) match {
|
|
||||||
case Success(()) ⇒
|
|
||||||
currentSession = session
|
|
||||||
corkUser = false
|
|
||||||
case Failure(ex) ⇒
|
|
||||||
fail(ex, closeTransport = true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override def receive = inputBunch.subreceive.orElse[Any, Unit](outputBunch.subreceive)
|
override def receive = inputBunch.subreceive.orElse[Any, Unit](outputBunch.subreceive)
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,10 @@ private[stream] final case class TlsModule(plainIn: Inlet[SslTlsOutbound], plain
|
||||||
cipherIn: Inlet[ByteString], cipherOut: Outlet[ByteString],
|
cipherIn: Inlet[ByteString], cipherOut: Outlet[ByteString],
|
||||||
shape: Shape, attributes: Attributes,
|
shape: Shape, attributes: Attributes,
|
||||||
createSSLEngine: ActorSystem ⇒ SSLEngine, // ActorSystem is only needed to support the AkkaSSLConfig legacy, see #21753
|
createSSLEngine: ActorSystem ⇒ SSLEngine, // ActorSystem is only needed to support the AkkaSSLConfig legacy, see #21753
|
||||||
verifySession: (ActorSystem, SSLSession) ⇒ Try[Unit], // ActorSystem is only needed to support the AkkaSSLConfig legacy, see #21753
|
|
||||||
closing: TLSClosing) extends AtomicModule {
|
closing: TLSClosing) extends AtomicModule {
|
||||||
|
|
||||||
override def withAttributes(att: Attributes): TlsModule = copy(attributes = att)
|
override def withAttributes(att: Attributes): TlsModule = copy(attributes = att)
|
||||||
override def carbonCopy: TlsModule = TlsModule(attributes, createSSLEngine, verifySession, closing)
|
override def carbonCopy: TlsModule = TlsModule(attributes, createSSLEngine, closing)
|
||||||
|
|
||||||
override def replaceShape(s: Shape) =
|
override def replaceShape(s: Shape) =
|
||||||
if (s != shape) {
|
if (s != shape) {
|
||||||
|
|
@ -40,7 +39,6 @@ private[stream] object TlsModule {
|
||||||
def apply(
|
def apply(
|
||||||
attributes: Attributes,
|
attributes: Attributes,
|
||||||
createSSLEngine: ActorSystem ⇒ SSLEngine, // ActorSystem is only needed to support the AkkaSSLConfig legacy, see #21753
|
createSSLEngine: ActorSystem ⇒ SSLEngine, // ActorSystem is only needed to support the AkkaSSLConfig legacy, see #21753
|
||||||
verifySession: (ActorSystem, SSLSession) ⇒ Try[Unit], // ActorSystem is only needed to support the AkkaSSLConfig legacy, see #21753
|
|
||||||
closing: TLSClosing): TlsModule = {
|
closing: TLSClosing): TlsModule = {
|
||||||
val name = attributes.nameOrDefault(s"StreamTls()")
|
val name = attributes.nameOrDefault(s"StreamTls()")
|
||||||
val cipherIn = Inlet[ByteString](s"$name.cipherIn")
|
val cipherIn = Inlet[ByteString](s"$name.cipherIn")
|
||||||
|
|
@ -48,6 +46,6 @@ private[stream] object TlsModule {
|
||||||
val plainIn = Inlet[SslTlsOutbound](s"$name.transportIn")
|
val plainIn = Inlet[SslTlsOutbound](s"$name.transportIn")
|
||||||
val plainOut = Outlet[SslTlsInbound](s"$name.transportOut")
|
val plainOut = Outlet[SslTlsInbound](s"$name.transportOut")
|
||||||
val shape = new BidiShape(plainIn, cipherOut, cipherIn, plainOut)
|
val shape = new BidiShape(plainIn, cipherOut, cipherIn, plainOut)
|
||||||
TlsModule(plainIn, plainOut, cipherIn, cipherOut, shape, attributes, createSSLEngine, verifySession, closing)
|
TlsModule(plainIn, plainOut, cipherIn, cipherOut, shape, attributes, createSSLEngine, closing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,12 @@ object TLS {
|
||||||
config.sslEngineConfigurator.configure(engine, sslContext)
|
config.sslEngineConfigurator.configure(engine, sslContext)
|
||||||
engine.setUseClientMode(role == Client)
|
engine.setUseClientMode(role == Client)
|
||||||
|
|
||||||
|
if (!config.config.loose.disableHostnameVerification && engine.getUseClientMode && hostInfo.isDefined) {
|
||||||
|
val parameters = engine.getSSLParameters
|
||||||
|
parameters.setEndpointIdentificationAlgorithm("HTTPS")
|
||||||
|
engine.setSSLParameters(parameters)
|
||||||
|
}
|
||||||
|
|
||||||
val finalSessionParameters =
|
val finalSessionParameters =
|
||||||
if (firstSession.sslParameters.isDefined && hostInfo.isDefined && !config.config.loose.disableSNI) {
|
if (firstSession.sslParameters.isDefined && hostInfo.isDefined && !config.config.loose.disableSNI) {
|
||||||
val newParams = TlsUtils.cloneParameters(firstSession.sslParameters.get)
|
val newParams = TlsUtils.cloneParameters(firstSession.sslParameters.get)
|
||||||
|
|
@ -99,19 +105,8 @@ object TLS {
|
||||||
TlsUtils.applySessionParameters(engine, finalSessionParameters)
|
TlsUtils.applySessionParameters(engine, finalSessionParameters)
|
||||||
engine
|
engine
|
||||||
}
|
}
|
||||||
def verifySession: (ActorSystem, SSLSession) ⇒ Try[Unit] =
|
|
||||||
hostInfo match {
|
|
||||||
case Some((hostname, _)) ⇒ { (system, session) ⇒
|
|
||||||
val hostnameVerifier = theSslConfig(system).hostnameVerifier
|
|
||||||
if (!hostnameVerifier.verify(hostname, session))
|
|
||||||
Failure(new ConnectionException(s"Hostname verification failed! Expected session to be for $hostname"))
|
|
||||||
else
|
|
||||||
Success(())
|
|
||||||
}
|
|
||||||
case None ⇒ (_, _) ⇒ Success(())
|
|
||||||
}
|
|
||||||
|
|
||||||
new scaladsl.BidiFlow(TlsModule(Attributes.none, createSSLEngine, verifySession, closing))
|
new scaladsl.BidiFlow(TlsModule(Attributes.none, createSSLEngine, closing))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -156,17 +151,13 @@ object TLS {
|
||||||
* You can specify a constructor to create an SSLEngine that must already be configured for
|
* You can specify a constructor to create an SSLEngine that must already be configured for
|
||||||
* client and server mode and with all the parameters for the first session.
|
* client and server mode and with all the parameters for the first session.
|
||||||
*
|
*
|
||||||
* You can specify a verification function that will be called after every successful handshake
|
|
||||||
* to verify additional session information.
|
|
||||||
*
|
|
||||||
* For a description of the `closing` parameter please refer to [[TLSClosing]].
|
* For a description of the `closing` parameter please refer to [[TLSClosing]].
|
||||||
*/
|
*/
|
||||||
def apply(
|
def apply(
|
||||||
createSSLEngine: () ⇒ SSLEngine, // we don't offer the internal `ActorSystem => SSLEngine` API here, see #21753
|
createSSLEngine: () ⇒ SSLEngine, // we don't offer the internal `ActorSystem => SSLEngine` API here, see #21753
|
||||||
verifySession: SSLSession ⇒ Try[Unit], // we don't offer the internal API that provides `ActorSystem` here, see #21753
|
|
||||||
closing: TLSClosing
|
closing: TLSClosing
|
||||||
): scaladsl.BidiFlow[SslTlsOutbound, ByteString, ByteString, SslTlsInbound, NotUsed] =
|
): scaladsl.BidiFlow[SslTlsOutbound, ByteString, ByteString, SslTlsInbound, NotUsed] =
|
||||||
new scaladsl.BidiFlow(TlsModule(Attributes.none, _ ⇒ createSSLEngine(), (_, session) ⇒ verifySession(session), closing))
|
new scaladsl.BidiFlow(TlsModule(Attributes.none, _ ⇒ createSSLEngine(), closing))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -394,6 +394,9 @@ object MiMa extends AutoPlugin {
|
||||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.cluster.ddata.Replicator#WriteMajority.copy"),
|
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.cluster.ddata.Replicator#WriteMajority.copy"),
|
||||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.cluster.ddata.Replicator#WriteMajority.apply"),
|
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.cluster.ddata.Replicator#WriteMajority.apply"),
|
||||||
|
|
||||||
|
// #21854 Remove manual hostname verifier support
|
||||||
|
ProblemFilters.exclude[IncompatibleMethTypeProblem]("akka.stream.scaladsl.TLS.apply"),
|
||||||
|
|
||||||
// #22277 changes to internal classes
|
// #22277 changes to internal classes
|
||||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.remote.transport.netty.TcpServerHandler.this"),
|
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.remote.transport.netty.TcpServerHandler.this"),
|
||||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.remote.transport.netty.TcpClientHandler.this"),
|
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.remote.transport.netty.TcpClientHandler.this"),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue