2018-10-29 17:19:37 +08:00
|
|
|
/*
|
2019-01-02 18:55:26 +08:00
|
|
|
* Copyright (C) 2009-2019 Lightbend Inc. <https://www.lightbend.com>
|
2012-10-04 17:58:15 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package akka.remote
|
|
|
|
|
|
2013-11-06 14:34:07 +01:00
|
|
|
import scala.concurrent.duration._
|
2012-10-04 17:58:15 -07:00
|
|
|
import com.typesafe.config.ConfigFactory
|
2013-11-06 14:34:07 +01:00
|
|
|
import akka.actor.Actor
|
|
|
|
|
import akka.actor.ActorIdentity
|
|
|
|
|
import akka.actor.ActorRef
|
|
|
|
|
import akka.actor.ActorSystem
|
|
|
|
|
import akka.actor.Deploy
|
2012-10-04 17:58:15 -07:00
|
|
|
import akka.actor.ExtendedActorSystem
|
2013-11-06 14:34:07 +01:00
|
|
|
import akka.actor.Identify
|
|
|
|
|
import akka.actor.PoisonPill
|
|
|
|
|
import akka.actor.Props
|
2012-10-04 17:58:15 -07:00
|
|
|
import akka.actor.RootActorPath
|
2013-11-06 14:34:07 +01:00
|
|
|
import akka.actor.Terminated
|
|
|
|
|
import akka.testkit.AkkaSpec
|
|
|
|
|
import akka.testkit.ImplicitSender
|
|
|
|
|
import akka.testkit.TestProbe
|
|
|
|
|
import akka.actor.ActorSelection
|
2012-10-04 17:58:15 -07:00
|
|
|
import akka.testkit.TestEvent
|
|
|
|
|
import akka.event.Logging
|
2013-11-06 14:34:07 +01:00
|
|
|
import akka.testkit.EventFilter
|
|
|
|
|
|
|
|
|
|
object UntrustedSpec {
|
2014-03-07 13:20:01 +01:00
|
|
|
final case class IdentifyReq(path: String)
|
|
|
|
|
final case class StopChild(name: String)
|
2013-11-06 14:34:07 +01:00
|
|
|
|
|
|
|
|
class Receptionist(testActor: ActorRef) extends Actor {
|
|
|
|
|
context.actorOf(Props(classOf[Child], testActor), "child1")
|
|
|
|
|
context.actorOf(Props(classOf[Child], testActor), "child2")
|
|
|
|
|
context.actorOf(Props(classOf[FakeUser], testActor), "user")
|
|
|
|
|
|
|
|
|
|
def receive = {
|
2019-02-09 15:25:39 +01:00
|
|
|
case IdentifyReq(path) => context.actorSelection(path).tell(Identify(None), sender())
|
2019-03-11 10:38:24 +01:00
|
|
|
case StopChild(name) => context.child(name).foreach(context.stop)
|
|
|
|
|
case msg => testActor.forward(msg)
|
2013-11-06 14:34:07 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class Child(testActor: ActorRef) extends Actor {
|
|
|
|
|
override def postStop(): Unit = {
|
|
|
|
|
testActor ! s"${self.path.name} stopped"
|
|
|
|
|
}
|
|
|
|
|
def receive = {
|
2019-03-11 10:38:24 +01:00
|
|
|
case msg => testActor.forward(msg)
|
2013-11-06 14:34:07 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class FakeUser(testActor: ActorRef) extends Actor {
|
|
|
|
|
context.actorOf(Props(classOf[Child], testActor), "receptionist")
|
|
|
|
|
def receive = {
|
2019-03-11 10:38:24 +01:00
|
|
|
case msg => testActor.forward(msg)
|
2013-11-06 14:34:07 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2012-10-04 17:58:15 -07:00
|
|
|
|
|
|
|
|
class UntrustedSpec extends AkkaSpec("""
|
2016-06-10 15:04:13 +02:00
|
|
|
akka.actor.provider = remote
|
2012-10-04 17:58:15 -07:00
|
|
|
akka.remote.untrusted-mode = on
|
2013-11-06 14:34:07 +01:00
|
|
|
akka.remote.trusted-selection-paths = ["/user/receptionist", ]
|
2013-01-17 16:19:31 +01:00
|
|
|
akka.remote.netty.tcp.port = 0
|
2018-04-24 07:33:34 +01:00
|
|
|
akka.loglevel = DEBUG # test verifies debug
|
2012-10-04 17:58:15 -07:00
|
|
|
""") with ImplicitSender {
|
|
|
|
|
|
2013-11-06 14:34:07 +01:00
|
|
|
import UntrustedSpec._
|
|
|
|
|
|
2019-03-11 10:38:24 +01:00
|
|
|
val client = ActorSystem("UntrustedSpec-client",
|
|
|
|
|
ConfigFactory.parseString("""
|
2016-06-10 15:04:13 +02:00
|
|
|
akka.actor.provider = remote
|
2013-01-17 16:19:31 +01:00
|
|
|
akka.remote.netty.tcp.port = 0
|
2012-11-23 10:15:19 +01:00
|
|
|
"""))
|
2017-08-08 19:18:56 +08:00
|
|
|
val address = system.asInstanceOf[ExtendedActorSystem].provider.getDefaultAddress
|
2013-11-06 14:34:07 +01:00
|
|
|
|
|
|
|
|
val receptionist = system.actorOf(Props(classOf[Receptionist], testActor), "receptionist")
|
|
|
|
|
|
|
|
|
|
lazy val remoteDaemon = {
|
|
|
|
|
{
|
|
|
|
|
val p = TestProbe()(client)
|
2017-08-08 19:18:56 +08:00
|
|
|
client.actorSelection(RootActorPath(address) / receptionist.path.elements).tell(IdentifyReq("/remote"), p.ref)
|
2013-11-06 14:34:07 +01:00
|
|
|
p.expectMsgType[ActorIdentity].ref.get
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lazy val target2 = {
|
|
|
|
|
val p = TestProbe()(client)
|
2019-03-11 10:38:24 +01:00
|
|
|
client.actorSelection(RootActorPath(address) / receptionist.path.elements).tell(IdentifyReq("child2"), p.ref)
|
2013-11-06 14:34:07 +01:00
|
|
|
p.expectMsgType[ActorIdentity].ref.get
|
|
|
|
|
}
|
2012-10-04 17:58:15 -07:00
|
|
|
|
2018-07-25 20:38:27 +09:00
|
|
|
override def afterTermination(): Unit = {
|
2013-11-06 14:34:07 +01:00
|
|
|
shutdown(client)
|
2012-12-20 12:54:43 +01:00
|
|
|
}
|
|
|
|
|
|
2012-10-04 17:58:15 -07:00
|
|
|
// need to enable debug log-level without actually printing those messages
|
|
|
|
|
system.eventStream.publish(TestEvent.Mute(EventFilter.debug()))
|
|
|
|
|
|
|
|
|
|
"UntrustedMode" must {
|
|
|
|
|
|
2013-11-06 14:34:07 +01:00
|
|
|
"allow actor selection to configured white list" in {
|
2017-08-08 19:18:56 +08:00
|
|
|
val sel = client.actorSelection(RootActorPath(address) / receptionist.path.elements)
|
2013-11-06 14:34:07 +01:00
|
|
|
sel ! "hello"
|
|
|
|
|
expectMsg("hello")
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-04 17:58:15 -07:00
|
|
|
"discard harmful messages to /remote" in {
|
2013-11-06 14:34:07 +01:00
|
|
|
val logProbe = TestProbe()
|
|
|
|
|
// but instead install our own listener
|
|
|
|
|
system.eventStream.subscribe(system.actorOf(Props(new Actor {
|
|
|
|
|
import Logging._
|
|
|
|
|
def receive = {
|
2019-02-09 15:25:39 +01:00
|
|
|
case d @ Debug(_, _, msg: String) if msg contains "dropping" => logProbe.ref ! d
|
2019-03-11 10:38:24 +01:00
|
|
|
case _ =>
|
2013-11-06 14:34:07 +01:00
|
|
|
}
|
|
|
|
|
}).withDeploy(Deploy.local), "debugSniffer"), classOf[Logging.Debug])
|
|
|
|
|
|
|
|
|
|
remoteDaemon ! "hello"
|
|
|
|
|
logProbe.expectMsgType[Logging.Debug]
|
2012-10-04 17:58:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"discard harmful messages to testActor" in {
|
2013-11-06 14:34:07 +01:00
|
|
|
target2 ! Terminated(remoteDaemon)(existenceConfirmed = true, addressTerminated = false)
|
2012-10-04 17:58:15 -07:00
|
|
|
target2 ! PoisonPill
|
2013-11-06 14:34:07 +01:00
|
|
|
client.stop(target2)
|
2012-10-04 17:58:15 -07:00
|
|
|
target2 ! "blech"
|
|
|
|
|
expectMsg("blech")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"discard watch messages" in {
|
2013-11-06 14:34:07 +01:00
|
|
|
client.actorOf(Props(new Actor {
|
2012-10-04 17:58:15 -07:00
|
|
|
context.watch(target2)
|
|
|
|
|
def receive = {
|
2019-03-11 10:38:24 +01:00
|
|
|
case x => testActor.forward(x)
|
2012-10-04 17:58:15 -07:00
|
|
|
}
|
2013-05-29 16:13:10 +02:00
|
|
|
}).withDeploy(Deploy.local))
|
2013-11-06 14:34:07 +01:00
|
|
|
receptionist ! StopChild("child2")
|
|
|
|
|
expectMsg("child2 stopped")
|
|
|
|
|
// no Terminated msg, since watch was discarded
|
2018-04-24 07:33:34 +01:00
|
|
|
expectNoMessage(1.second)
|
2013-11-06 14:34:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"discard actor selection" in {
|
2017-08-08 19:18:56 +08:00
|
|
|
val sel = client.actorSelection(RootActorPath(address) / testActor.path.elements)
|
2013-11-06 14:34:07 +01:00
|
|
|
sel ! "hello"
|
2018-04-24 07:33:34 +01:00
|
|
|
expectNoMessage(1.second)
|
2013-11-06 14:34:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"discard actor selection with non root anchor" in {
|
|
|
|
|
val p = TestProbe()(client)
|
2019-03-11 10:38:24 +01:00
|
|
|
client.actorSelection(RootActorPath(address) / receptionist.path.elements).tell(Identify(None), p.ref)
|
2013-11-06 14:34:07 +01:00
|
|
|
val clientReceptionistRef = p.expectMsgType[ActorIdentity].ref.get
|
|
|
|
|
|
2014-01-08 17:51:18 +01:00
|
|
|
val sel = ActorSelection(clientReceptionistRef, receptionist.path.toStringWithoutAddress)
|
2013-11-06 14:34:07 +01:00
|
|
|
sel ! "hello"
|
2018-04-24 07:33:34 +01:00
|
|
|
expectNoMessage(1.second)
|
2013-11-06 14:34:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"discard actor selection to child of matching white list" in {
|
2017-08-08 19:18:56 +08:00
|
|
|
val sel = client.actorSelection(RootActorPath(address) / receptionist.path.elements / "child1")
|
2013-11-06 14:34:07 +01:00
|
|
|
sel ! "hello"
|
2018-04-24 07:33:34 +01:00
|
|
|
expectNoMessage(1.second)
|
2013-11-06 14:34:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"discard actor selection with wildcard" in {
|
2017-08-08 19:18:56 +08:00
|
|
|
val sel = client.actorSelection(RootActorPath(address) / receptionist.path.elements / "*")
|
2013-11-06 14:34:07 +01:00
|
|
|
sel ! "hello"
|
2018-04-24 07:33:34 +01:00
|
|
|
expectNoMessage(1.second)
|
2013-11-06 14:34:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"discard actor selection containing harmful message" in {
|
2017-08-08 19:18:56 +08:00
|
|
|
val sel = client.actorSelection(RootActorPath(address) / receptionist.path.elements)
|
2013-11-06 14:34:07 +01:00
|
|
|
sel ! PoisonPill
|
2018-04-24 07:33:34 +01:00
|
|
|
expectNoMessage(1.second)
|
2012-10-04 17:58:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-09 01:47:48 +01:00
|
|
|
}
|