From cca1c2fa9d23aaa1cdda626282d6c36675ab4e77 Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Sun, 25 Apr 2010 20:32:52 +0200 Subject: [PATCH 01/14] Initial code for SSL remote actors --- .../src/main/scala/remote/RemoteClient.scala | 26 ++++++++--- .../src/main/scala/remote/RemoteServer.scala | 44 ++++++++++++++++++- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/akka-core/src/main/scala/remote/RemoteClient.scala b/akka-core/src/main/scala/remote/RemoteClient.scala index 4c18dcc6c8..60cbfbdd36 100644 --- a/akka-core/src/main/scala/remote/RemoteClient.scala +++ b/akka-core/src/main/scala/remote/RemoteClient.scala @@ -19,6 +19,7 @@ import org.jboss.netty.handler.codec.compression.{ZlibDecoder, ZlibEncoder} import org.jboss.netty.handler.codec.protobuf.{ProtobufDecoder, ProtobufEncoder} import org.jboss.netty.handler.timeout.ReadTimeoutHandler import org.jboss.netty.util.{TimerTask, Timeout, HashedWheelTimer} +import org.jboss.netty.handler.ssl.SslHandler import java.net.{SocketAddress, InetSocketAddress} import java.util.concurrent.{TimeUnit, Executors, ConcurrentMap, ConcurrentHashMap, ConcurrentSkipListSet} @@ -249,6 +250,10 @@ class RemoteClientPipelineFactory(name: String, timer: HashedWheelTimer, client: RemoteClient) extends ChannelPipelineFactory { def getPipeline: ChannelPipeline = { + val engine = RemoteServerSslContext.client.createSSLEngine() + engine.setUseClientMode(true) + + val ssl = new SslHandler(engine) val timeout = new ReadTimeoutHandler(timer, RemoteClient.READ_TIMEOUT) val lenDec = new LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4) val lenPrep = new LengthFieldPrepender(4) @@ -262,8 +267,8 @@ class RemoteClientPipelineFactory(name: String, val remoteClient = new RemoteClientHandler(name, futures, supervisors, bootstrap, remoteAddress, timer, client) val stages: Array[ChannelHandler] = - zipCodec.map(codec => Array(timeout, codec.decoder, lenDec, protobufDec, codec.encoder, lenPrep, protobufEnc, remoteClient)) - .getOrElse(Array(timeout, lenDec, protobufDec, lenPrep, protobufEnc, remoteClient)) + zipCodec.map(codec => Array(ssl, timeout, codec.decoder, lenDec, protobufDec, codec.encoder, lenPrep, protobufEnc, remoteClient)) + .getOrElse(Array(ssl, timeout, lenDec, protobufDec, lenPrep, protobufEnc, remoteClient)) new StaticChannelPipeline(stages: _*) } } @@ -342,9 +347,20 @@ class RemoteClientHandler(val name: String, } override def channelConnected(ctx: ChannelHandlerContext, event: ChannelStateEvent) = { - client.listeners.toArray.foreach(l => - l.asInstanceOf[ActorRef] ! RemoteClientConnected(client.hostname, client.port)) - log.debug("Remote client connected to [%s]", ctx.getChannel.getRemoteAddress) + +// client.listeners.toArray.foreach(l => +// l.asInstanceOf[ActorRef] ! RemoteClientConnected(client.hostname, client.port)) +// log.debug("Remote client connected to [%s]", ctx.getChannel.getRemoteAddress) + + val sslHandler : SslHandler = ctx.getPipeline.get(classOf[SslHandler]) + sslHandler.handshake().addListener( new ChannelFutureListener { + def operationComplete(future : ChannelFuture) : Unit = { + if(future.isSuccess) { + client.listeners.toArray.foreach(l => l.asInstanceOf[ActorRef] ! RemoteClientConnected(client.hostname, client.port)) + log.debug("Remote client connected to [%s]", ctx.getChannel.getRemoteAddress) + } + } + }) } override def channelDisconnected(ctx: ChannelHandlerContext, event: ChannelStateEvent) = { diff --git a/akka-core/src/main/scala/remote/RemoteServer.scala b/akka-core/src/main/scala/remote/RemoteServer.scala index 28d087b3e1..08c402f15a 100644 --- a/akka-core/src/main/scala/remote/RemoteServer.scala +++ b/akka-core/src/main/scala/remote/RemoteServer.scala @@ -22,6 +22,8 @@ import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory import org.jboss.netty.handler.codec.frame.{LengthFieldBasedFrameDecoder, LengthFieldPrepender} import org.jboss.netty.handler.codec.protobuf.{ProtobufDecoder, ProtobufEncoder} import org.jboss.netty.handler.codec.compression.{ZlibEncoder, ZlibDecoder} +import org.jboss.netty.handler.ssl.SslHandler + import scala.collection.mutable.Map @@ -279,6 +281,32 @@ class RemoteServer extends Logging { case class Codec(encoder: ChannelHandler, decoder: ChannelHandler) +object RemoteServerSslContext { + import java.security.{KeyStore,Security} + import javax.net.ssl.{KeyManager,KeyManagerFactory,SSLContext,TrustManagerFactory} + + val (client,server) = { + val protocol = "TLS" + val algorithm = Option(Security.getProperty("ssl.KeyManagerFactory.algorithm")).getOrElse("SunX509") + val store = KeyStore.getInstance("JKS") + store.load(getClass.getResourceAsStream("keystore"),"keystorepassword".toCharArray) + + val keyMan = KeyManagerFactory.getInstance(algorithm) + keyMan.init(store, "certificatepassword".toCharArray) + + val trustMan = TrustManagerFactory.getInstance("SunX509"); + trustMan.init(store) //TODO safe to use same keystore? Or should use it's own keystore? + + val s = SSLContext.getInstance(protocol) + s.init(keyMan.getKeyManagers, null, null) + + val c = SSLContext.getInstance(protocol) + c.init(null, trustMan.getTrustManagers, null) + + (c,s) + } +} + /** * @author Jonas Bonér */ @@ -291,6 +319,10 @@ class RemoteServerPipelineFactory( import RemoteServer._ def getPipeline: ChannelPipeline = { + val engine = RemoteServerSslContext.server.createSSLEngine() + engine.setUseClientMode(false) + + val ssl = new SslHandler(engine) val lenDec = new LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4) val lenPrep = new LengthFieldPrepender(4) val protobufDec = new ProtobufDecoder(RemoteRequestProtocol.getDefaultInstance) @@ -303,8 +335,8 @@ class RemoteServerPipelineFactory( val remoteServer = new RemoteServerHandler(name, openChannels, loader, actors, activeObjects) val stages: Array[ChannelHandler] = - zipCodec.map(codec => Array(codec.decoder, lenDec, protobufDec, codec.encoder, lenPrep, protobufEnc, remoteServer)) - .getOrElse(Array(lenDec, protobufDec, lenPrep, protobufEnc, remoteServer)) + zipCodec.map(codec => Array(ssl,codec.decoder, lenDec, protobufDec, codec.encoder, lenPrep, protobufEnc, remoteServer)) + .getOrElse(Array(ssl,lenDec, protobufDec, lenPrep, protobufEnc, remoteServer)) new StaticChannelPipeline(stages: _*) } } @@ -330,6 +362,14 @@ class RemoteServerHandler( override def channelOpen(ctx: ChannelHandlerContext, event: ChannelStateEvent) { openChannels.add(ctx.getChannel) } + + override def channelConnected(ctx : ChannelHandlerContext, e : ChannelStateEvent) { + val sslHandler : SslHandler = ctx.getPipeline.get(classOf[SslHandler]) + + // Begin handshake. + sslHandler.handshake() + } + override def handleUpstream(ctx: ChannelHandlerContext, event: ChannelEvent) = { if (event.isInstanceOf[ChannelStateEvent] && From cf802252294fa86a7c64a57fe37b2902bd16b113 Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Sun, 25 Apr 2010 20:40:47 +0200 Subject: [PATCH 02/14] Adding SSL code to RemoteServer --- akka-core/src/main/scala/remote/RemoteServer.scala | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/akka-core/src/main/scala/remote/RemoteServer.scala b/akka-core/src/main/scala/remote/RemoteServer.scala index 08c402f15a..2cd5a6dd4f 100644 --- a/akka-core/src/main/scala/remote/RemoteServer.scala +++ b/akka-core/src/main/scala/remote/RemoteServer.scala @@ -367,7 +367,14 @@ class RemoteServerHandler( val sslHandler : SslHandler = ctx.getPipeline.get(classOf[SslHandler]) // Begin handshake. - sslHandler.handshake() + sslHandler.handshake().addListener( new ChannelFutureListener { + def operationComplete(future : ChannelFuture) : Unit = { + if(future.isSuccess) + openChannels.add(future.getChannel) + else + future.getChannel.close + } + }) } From b976591fb1a79b15d8fd133ee764333724b1beea Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Sun, 25 Apr 2010 21:16:16 +0200 Subject: [PATCH 03/14] Added some Dummy SSL config to assist in proof-of-concept --- .../main/scala/remote/DummySSLConfig.scala | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 akka-core/src/main/scala/remote/DummySSLConfig.scala diff --git a/akka-core/src/main/scala/remote/DummySSLConfig.scala b/akka-core/src/main/scala/remote/DummySSLConfig.scala new file mode 100644 index 0000000000..ddb743cf3f --- /dev/null +++ b/akka-core/src/main/scala/remote/DummySSLConfig.scala @@ -0,0 +1,19 @@ +package se.scalablesolutions.akka.remote + +import java.security.KeyStore +import java.security.cert.X509Certificate +import javax.net.ssl.{ManagerFactoryParameters,TrustManager,TrustManagerFactorySpi,X509TrustManager}; + +object DummyTrustManagerFactory extends TrustManagerFactorySpi { + private val DUMMY_TRUST_MANAGER : TrustManager = new X509TrustManager { + def getAcceptedIssuers() = Array[X509Certificate]() + def checkClientTrusted(chain : Array[X509Certificate], authType : String) = println("UNKNOWN CLIENT CERTIFICATE: " + chain(0).getSubjectDN) + def checkServerTrusted(chain : Array[X509Certificate], authType : String) = println("UNKNOWN SERVER CERTIFICATE: " + chain(0).getSubjectDN) + } + + def getTrustManagers = Array(DUMMY_TRUST_MANAGER) + + protected override def engineGetTrustManagers = getTrustManagers + protected override def engineInit(keystore:KeyStore) = () + protected override def engineInit(managerFactoryParameters : ManagerFactoryParameters) = () +} From ca6013222d3fb0eb666738c0806b9960fcb7bbc2 Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Sun, 25 Apr 2010 23:11:28 +0200 Subject: [PATCH 04/14] Tests pass with Dummy SSL config! --- akka-core/src/main/scala/remote/RemoteClient.scala | 1 + akka-core/src/main/scala/remote/RemoteServer.scala | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/akka-core/src/main/scala/remote/RemoteClient.scala b/akka-core/src/main/scala/remote/RemoteClient.scala index 60cbfbdd36..5e90f3585b 100644 --- a/akka-core/src/main/scala/remote/RemoteClient.scala +++ b/akka-core/src/main/scala/remote/RemoteClient.scala @@ -251,6 +251,7 @@ class RemoteClientPipelineFactory(name: String, client: RemoteClient) extends ChannelPipelineFactory { def getPipeline: ChannelPipeline = { val engine = RemoteServerSslContext.client.createSSLEngine() + engine.setEnabledCipherSuites(engine.getSupportedCipherSuites) //TODO is this sensible? engine.setUseClientMode(true) val ssl = new SslHandler(engine) diff --git a/akka-core/src/main/scala/remote/RemoteServer.scala b/akka-core/src/main/scala/remote/RemoteServer.scala index 2cd5a6dd4f..1b646e1fe9 100644 --- a/akka-core/src/main/scala/remote/RemoteServer.scala +++ b/akka-core/src/main/scala/remote/RemoteServer.scala @@ -289,19 +289,19 @@ object RemoteServerSslContext { val protocol = "TLS" val algorithm = Option(Security.getProperty("ssl.KeyManagerFactory.algorithm")).getOrElse("SunX509") val store = KeyStore.getInstance("JKS") - store.load(getClass.getResourceAsStream("keystore"),"keystorepassword".toCharArray) + store.load(DummyKeyStore.asInputStream,DummyKeyStore.getKeyStorePassword) //TODO replace with getResourceAsStream + config-pass val keyMan = KeyManagerFactory.getInstance(algorithm) - keyMan.init(store, "certificatepassword".toCharArray) + keyMan.init(store, DummyKeyStore.getCertificatePassword) //TODO replace with config-pass - val trustMan = TrustManagerFactory.getInstance("SunX509"); - trustMan.init(store) //TODO safe to use same keystore? Or should use it's own keystore? + //val trustMan = TrustManagerFactory.getInstance("SunX509"); + //trustMan.init(store) //TODO safe to use same keystore? Or should use it's own keystore? val s = SSLContext.getInstance(protocol) s.init(keyMan.getKeyManagers, null, null) val c = SSLContext.getInstance(protocol) - c.init(null, trustMan.getTrustManagers, null) + c.init(null, DummyTrustManagerFactory.getTrustManagers, null) //TODO replace with TrustManagerFactory (c,s) } @@ -320,6 +320,7 @@ class RemoteServerPipelineFactory( def getPipeline: ChannelPipeline = { val engine = RemoteServerSslContext.server.createSSLEngine() + engine.setEnabledCipherSuites(engine.getSupportedCipherSuites) //TODO is this sensible? engine.setUseClientMode(false) val ssl = new SslHandler(engine) From 9cd36f1299639b34e2c5c2efc1fe4ce2850a7b45 Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Mon, 26 Apr 2010 21:47:20 +0200 Subject: [PATCH 05/14] ... --- .../main/scala/remote/DummySSLConfig.scala | 266 ++++++++++++++++++ 1 file changed, 266 insertions(+) diff --git a/akka-core/src/main/scala/remote/DummySSLConfig.scala b/akka-core/src/main/scala/remote/DummySSLConfig.scala index ddb743cf3f..2a24ead57b 100644 --- a/akka-core/src/main/scala/remote/DummySSLConfig.scala +++ b/akka-core/src/main/scala/remote/DummySSLConfig.scala @@ -1,5 +1,6 @@ package se.scalablesolutions.akka.remote +import java.io.{ByteArrayInputStream,InputStream} import java.security.KeyStore import java.security.cert.X509Certificate import javax.net.ssl.{ManagerFactoryParameters,TrustManager,TrustManagerFactorySpi,X509TrustManager}; @@ -17,3 +18,268 @@ object DummyTrustManagerFactory extends TrustManagerFactorySpi { protected override def engineInit(keystore:KeyStore) = () protected override def engineInit(managerFactoryParameters : ManagerFactoryParameters) = () } + +object DummyKeyStore { + def asInputStream : InputStream = new ByteArrayInputStream(for(d <- DATA) yield d.toByte) + def getCertificatePassword = "secret".toCharArray + def getKeyStorePassword = "secret".toCharArray + private val DATA = Array[Short]( + 0xfe, 0xed, 0xfe, 0xed, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x00, 0x00, 0x01, 0x1a, 0x9f, 0x57, 0xa5, + 0x27, 0x00, 0x00, 0x01, 0x9a, 0x30, 0x82, 0x01, + 0x96, 0x30, 0x0e, 0x06, 0x0a, 0x2b, 0x06, 0x01, + 0x04, 0x01, 0x2a, 0x02, 0x11, 0x01, 0x01, 0x05, + 0x00, 0x04, 0x82, 0x01, 0x82, 0x48, 0x6d, 0xcf, + 0x16, 0xb5, 0x50, 0x95, 0x36, 0xbf, 0x47, 0x27, + 0x50, 0x58, 0x0d, 0xa2, 0x52, 0x7e, 0x25, 0xab, + 0x14, 0x1a, 0x26, 0x5e, 0x2d, 0x8a, 0x23, 0x90, + 0x60, 0x7f, 0x12, 0x20, 0x56, 0xd1, 0x43, 0xa2, + 0x6b, 0x47, 0x5d, 0xed, 0x9d, 0xd4, 0xe5, 0x83, + 0x28, 0x89, 0xc2, 0x16, 0x4c, 0x76, 0x06, 0xad, + 0x8e, 0x8c, 0x29, 0x1a, 0x9b, 0x0f, 0xdd, 0x60, + 0x4b, 0xb4, 0x62, 0x82, 0x9e, 0x4a, 0x63, 0x83, + 0x2e, 0xd2, 0x43, 0x78, 0xc2, 0x32, 0x1f, 0x60, + 0xa9, 0x8a, 0x7f, 0x0f, 0x7c, 0xa6, 0x1d, 0xe6, + 0x92, 0x9e, 0x52, 0xc7, 0x7d, 0xbb, 0x35, 0x3b, + 0xaa, 0x89, 0x73, 0x4c, 0xfb, 0x99, 0x54, 0x97, + 0x99, 0x28, 0x6e, 0x66, 0x5b, 0xf7, 0x9b, 0x7e, + 0x6d, 0x8a, 0x2f, 0xfa, 0xc3, 0x1e, 0x71, 0xb9, + 0xbd, 0x8f, 0xc5, 0x63, 0x25, 0x31, 0x20, 0x02, + 0xff, 0x02, 0xf0, 0xc9, 0x2c, 0xdd, 0x3a, 0x10, + 0x30, 0xab, 0xe5, 0xad, 0x3d, 0x1a, 0x82, 0x77, + 0x46, 0xed, 0x03, 0x38, 0xa4, 0x73, 0x6d, 0x36, + 0x36, 0x33, 0x70, 0xb2, 0x63, 0x20, 0xca, 0x03, + 0xbf, 0x5a, 0xf4, 0x7c, 0x35, 0xf0, 0x63, 0x1a, + 0x12, 0x33, 0x12, 0x58, 0xd9, 0xa2, 0x63, 0x6b, + 0x63, 0x82, 0x41, 0x65, 0x70, 0x37, 0x4b, 0x99, + 0x04, 0x9f, 0xdd, 0x5e, 0x07, 0x01, 0x95, 0x9f, + 0x36, 0xe8, 0xc3, 0x66, 0x2a, 0x21, 0x69, 0x68, + 0x40, 0xe6, 0xbc, 0xbb, 0x85, 0x81, 0x21, 0x13, + 0xe6, 0xa4, 0xcf, 0xd3, 0x67, 0xe3, 0xfd, 0x75, + 0xf0, 0xdf, 0x83, 0xe0, 0xc5, 0x36, 0x09, 0xac, + 0x1b, 0xd4, 0xf7, 0x2a, 0x23, 0x57, 0x1c, 0x5c, + 0x0f, 0xf4, 0xcf, 0xa2, 0xcf, 0xf5, 0xbd, 0x9c, + 0x69, 0x98, 0x78, 0x3a, 0x25, 0xe4, 0xfd, 0x85, + 0x11, 0xcc, 0x7d, 0xef, 0xeb, 0x74, 0x60, 0xb1, + 0xb7, 0xfb, 0x1f, 0x0e, 0x62, 0xff, 0xfe, 0x09, + 0x0a, 0xc3, 0x80, 0x2f, 0x10, 0x49, 0x89, 0x78, + 0xd2, 0x08, 0xfa, 0x89, 0x22, 0x45, 0x91, 0x21, + 0xbc, 0x90, 0x3e, 0xad, 0xb3, 0x0a, 0xb4, 0x0e, + 0x1c, 0xa1, 0x93, 0x92, 0xd8, 0x72, 0x07, 0x54, + 0x60, 0xe7, 0x91, 0xfc, 0xd9, 0x3c, 0xe1, 0x6f, + 0x08, 0xe4, 0x56, 0xf6, 0x0b, 0xb0, 0x3c, 0x39, + 0x8a, 0x2d, 0x48, 0x44, 0x28, 0x13, 0xca, 0xe9, + 0xf7, 0xa3, 0xb6, 0x8a, 0x5f, 0x31, 0xa9, 0x72, + 0xf2, 0xde, 0x96, 0xf2, 0xb1, 0x53, 0xb1, 0x3e, + 0x24, 0x57, 0xfd, 0x18, 0x45, 0x1f, 0xc5, 0x33, + 0x1b, 0xa4, 0xe8, 0x21, 0xfa, 0x0e, 0xb2, 0xb9, + 0xcb, 0xc7, 0x07, 0x41, 0xdd, 0x2f, 0xb6, 0x6a, + 0x23, 0x18, 0xed, 0xc1, 0xef, 0xe2, 0x4b, 0xec, + 0xc9, 0xba, 0xfb, 0x46, 0x43, 0x90, 0xd7, 0xb5, + 0x68, 0x28, 0x31, 0x2b, 0x8d, 0xa8, 0x51, 0x63, + 0xf7, 0x53, 0x99, 0x19, 0x68, 0x85, 0x66, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x05, 0x58, 0x2e, 0x35, + 0x30, 0x39, 0x00, 0x00, 0x02, 0x3a, 0x30, 0x82, + 0x02, 0x36, 0x30, 0x82, 0x01, 0xe0, 0xa0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x04, 0x48, 0x59, 0xf1, + 0x92, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, + 0x30, 0x81, 0xa0, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4b, 0x52, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0a, 0x4b, 0x79, 0x75, 0x6e, 0x67, + 0x67, 0x69, 0x2d, 0x64, 0x6f, 0x31, 0x14, 0x30, + 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0b, + 0x53, 0x65, 0x6f, 0x6e, 0x67, 0x6e, 0x61, 0x6d, + 0x2d, 0x73, 0x69, 0x31, 0x1a, 0x30, 0x18, 0x06, + 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x54, 0x68, + 0x65, 0x20, 0x4e, 0x65, 0x74, 0x74, 0x79, 0x20, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x31, + 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x13, 0x0f, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x73, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x27, 0x73, 0x65, 0x63, 0x75, + 0x72, 0x65, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x65, + 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x6e, + 0x65, 0x74, 0x74, 0x79, 0x2e, 0x67, 0x6c, 0x65, + 0x61, 0x6d, 0x79, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x6e, 0x65, 0x74, 0x30, 0x20, 0x17, 0x0d, 0x30, + 0x38, 0x30, 0x36, 0x31, 0x39, 0x30, 0x35, 0x34, + 0x31, 0x33, 0x38, 0x5a, 0x18, 0x0f, 0x32, 0x31, + 0x38, 0x37, 0x31, 0x31, 0x32, 0x34, 0x30, 0x35, + 0x34, 0x31, 0x33, 0x38, 0x5a, 0x30, 0x81, 0xa0, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x4b, 0x52, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, + 0x4b, 0x79, 0x75, 0x6e, 0x67, 0x67, 0x69, 0x2d, + 0x64, 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, + 0x55, 0x04, 0x07, 0x13, 0x0b, 0x53, 0x65, 0x6f, + 0x6e, 0x67, 0x6e, 0x61, 0x6d, 0x2d, 0x73, 0x69, + 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x11, 0x54, 0x68, 0x65, 0x20, 0x4e, + 0x65, 0x74, 0x74, 0x79, 0x20, 0x50, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x31, 0x18, 0x30, 0x16, + 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0f, 0x45, + 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x73, 0x31, 0x30, + 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x27, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x63, + 0x68, 0x61, 0x74, 0x2e, 0x65, 0x78, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x2e, 0x6e, 0x65, 0x74, 0x74, + 0x79, 0x2e, 0x67, 0x6c, 0x65, 0x61, 0x6d, 0x79, + 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x65, 0x74, + 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, + 0x00, 0xc3, 0xe3, 0x5e, 0x41, 0xa7, 0x87, 0x11, + 0x00, 0x42, 0x2a, 0xb0, 0x4b, 0xed, 0xb2, 0xe0, + 0x23, 0xdb, 0xb1, 0x3d, 0x58, 0x97, 0x35, 0x60, + 0x0b, 0x82, 0x59, 0xd3, 0x00, 0xea, 0xd4, 0x61, + 0xb8, 0x79, 0x3f, 0xb6, 0x3c, 0x12, 0x05, 0x93, + 0x2e, 0x9a, 0x59, 0x68, 0x14, 0x77, 0x3a, 0xc8, + 0x50, 0x25, 0x57, 0xa4, 0x49, 0x18, 0x63, 0x41, + 0xf0, 0x2d, 0x28, 0xec, 0x06, 0xfb, 0xb4, 0x9f, + 0xbf, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, + 0x65, 0x6c, 0x30, 0x01, 0xc2, 0x8e, 0x3e, 0xcb, + 0xb3, 0x77, 0x48, 0xe9, 0x66, 0x61, 0x9a, 0x40, + 0x86, 0xaf, 0xf6, 0x03, 0xeb, 0xba, 0x6a, 0xf2, + 0xfd, 0xe2, 0xaf, 0x36, 0x5e, 0x7b, 0xaa, 0x22, + 0x04, 0xdd, 0x2c, 0x20, 0xc4, 0xfc, 0xdd, 0xd0, + 0x82, 0x20, 0x1c, 0x3d, 0xd7, 0x9e, 0x5e, 0x5c, + 0x92, 0x5a, 0x76, 0x71, 0x28, 0xf5, 0x07, 0x7d, + 0xa2, 0x81, 0xba, 0x77, 0x9f, 0x2a, 0xd9, 0x44, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x6d, 0x79, + 0x6b, 0x65, 0x79, 0x00, 0x00, 0x01, 0x1a, 0x9f, + 0x5b, 0x56, 0xa0, 0x00, 0x00, 0x01, 0x99, 0x30, + 0x82, 0x01, 0x95, 0x30, 0x0e, 0x06, 0x0a, 0x2b, + 0x06, 0x01, 0x04, 0x01, 0x2a, 0x02, 0x11, 0x01, + 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x81, 0x29, + 0xa8, 0xb6, 0x08, 0x0c, 0x85, 0x75, 0x3e, 0xdd, + 0xb5, 0xe5, 0x1a, 0x87, 0x68, 0xd1, 0x90, 0x4b, + 0x29, 0x31, 0xee, 0x90, 0xbc, 0x9d, 0x73, 0xa0, + 0x3f, 0xe9, 0x0b, 0xa4, 0xef, 0x30, 0x9b, 0x36, + 0x9a, 0xb2, 0x54, 0x77, 0x81, 0x07, 0x4b, 0xaa, + 0xa5, 0x77, 0x98, 0xe1, 0xeb, 0xb5, 0x7c, 0x4e, + 0x48, 0xd5, 0x08, 0xfc, 0x2c, 0x36, 0xe2, 0x65, + 0x03, 0xac, 0xe5, 0xf3, 0x96, 0xb7, 0xd0, 0xb5, + 0x3b, 0x92, 0xe4, 0x14, 0x05, 0x7a, 0x6a, 0x92, + 0x56, 0xfe, 0x4e, 0xab, 0xd3, 0x0e, 0x32, 0x04, + 0x22, 0x22, 0x74, 0x47, 0x7d, 0xec, 0x21, 0x99, + 0x30, 0x31, 0x64, 0x46, 0x64, 0x9b, 0xc7, 0x13, + 0xbf, 0xbe, 0xd0, 0x31, 0x49, 0xe7, 0x3c, 0xbf, + 0xba, 0xb1, 0x20, 0xf9, 0x42, 0xf4, 0xa9, 0xa9, + 0xe5, 0x13, 0x65, 0x32, 0xbf, 0x7c, 0xcc, 0x91, + 0xd3, 0xfd, 0x24, 0x47, 0x0b, 0xe5, 0x53, 0xad, + 0x50, 0x30, 0x56, 0xd1, 0xfa, 0x9c, 0x37, 0xa8, + 0xc1, 0xce, 0xf6, 0x0b, 0x18, 0xaa, 0x7c, 0xab, + 0xbd, 0x1f, 0xdf, 0xe4, 0x80, 0xb8, 0xa7, 0xe0, + 0xad, 0x7d, 0x50, 0x74, 0xf1, 0x98, 0x78, 0xbc, + 0x58, 0xb9, 0xc2, 0x52, 0xbe, 0xd2, 0x5b, 0x81, + 0x94, 0x83, 0x8f, 0xb9, 0x4c, 0xee, 0x01, 0x2b, + 0x5e, 0xc9, 0x6e, 0x9b, 0xf5, 0x63, 0x69, 0xe4, + 0xd8, 0x0b, 0x47, 0xd8, 0xfd, 0xd8, 0xe0, 0xed, + 0xa8, 0x27, 0x03, 0x74, 0x1e, 0x5d, 0x32, 0xe6, + 0x5c, 0x63, 0xc2, 0xfb, 0x3f, 0xee, 0xb4, 0x13, + 0xc6, 0x0e, 0x6e, 0x74, 0xe0, 0x22, 0xac, 0xce, + 0x79, 0xf9, 0x43, 0x68, 0xc1, 0x03, 0x74, 0x2b, + 0xe1, 0x18, 0xf8, 0x7f, 0x76, 0x9a, 0xea, 0x82, + 0x3f, 0xc2, 0xa6, 0xa7, 0x4c, 0xfe, 0xae, 0x29, + 0x3b, 0xc1, 0x10, 0x7c, 0xd5, 0x77, 0x17, 0x79, + 0x5f, 0xcb, 0xad, 0x1f, 0xd8, 0xa1, 0xfd, 0x90, + 0xe1, 0x6b, 0xb2, 0xef, 0xb9, 0x41, 0x26, 0xa4, + 0x0b, 0x4f, 0xc6, 0x83, 0x05, 0x6f, 0xf0, 0x64, + 0x40, 0xe1, 0x44, 0xc4, 0xf9, 0x40, 0x2b, 0x3b, + 0x40, 0xdb, 0xaf, 0x35, 0xa4, 0x9b, 0x9f, 0xc4, + 0x74, 0x07, 0xe5, 0x18, 0x60, 0xc5, 0xfe, 0x15, + 0x0e, 0x3a, 0x25, 0x2a, 0x11, 0xee, 0x78, 0x2f, + 0xb8, 0xd1, 0x6e, 0x4e, 0x3c, 0x0a, 0xb5, 0xb9, + 0x40, 0x86, 0x27, 0x6d, 0x8f, 0x53, 0xb7, 0x77, + 0x36, 0xec, 0x5d, 0xed, 0x32, 0x40, 0x43, 0x82, + 0xc3, 0x52, 0x58, 0xc4, 0x26, 0x39, 0xf3, 0xb3, + 0xad, 0x58, 0xab, 0xb7, 0xf7, 0x8e, 0x0e, 0xba, + 0x8e, 0x78, 0x9d, 0xbf, 0x58, 0x34, 0xbd, 0x77, + 0x73, 0xa6, 0x50, 0x55, 0x00, 0x60, 0x26, 0xbf, + 0x6d, 0xb4, 0x98, 0x8a, 0x18, 0x83, 0x89, 0xf8, + 0xcd, 0x0d, 0x49, 0x06, 0xae, 0x51, 0x6e, 0xaf, + 0xbd, 0xe2, 0x07, 0x13, 0xd8, 0x64, 0xcc, 0xbf, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x58, 0x2e, + 0x35, 0x30, 0x39, 0x00, 0x00, 0x02, 0x34, 0x30, + 0x82, 0x02, 0x30, 0x30, 0x82, 0x01, 0xda, 0xa0, + 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x48, 0x59, + 0xf2, 0x84, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, + 0x00, 0x30, 0x81, 0x9d, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4b, + 0x52, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x13, 0x0a, 0x4b, 0x79, 0x75, 0x6e, + 0x67, 0x67, 0x69, 0x2d, 0x64, 0x6f, 0x31, 0x14, + 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, + 0x0b, 0x53, 0x65, 0x6f, 0x6e, 0x67, 0x6e, 0x61, + 0x6d, 0x2d, 0x73, 0x69, 0x31, 0x1a, 0x30, 0x18, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x54, + 0x68, 0x65, 0x20, 0x4e, 0x65, 0x74, 0x74, 0x79, + 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x13, 0x0c, 0x43, 0x6f, 0x6e, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x73, 0x31, + 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x27, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x63, 0x68, 0x61, 0x74, 0x2e, 0x65, 0x78, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x6e, 0x65, 0x74, + 0x74, 0x79, 0x2e, 0x67, 0x6c, 0x65, 0x61, 0x6d, + 0x79, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x65, + 0x74, 0x30, 0x20, 0x17, 0x0d, 0x30, 0x38, 0x30, + 0x36, 0x31, 0x39, 0x30, 0x35, 0x34, 0x35, 0x34, + 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x38, 0x37, + 0x31, 0x31, 0x32, 0x33, 0x30, 0x35, 0x34, 0x35, + 0x34, 0x30, 0x5a, 0x30, 0x81, 0x9d, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x4b, 0x52, 0x31, 0x13, 0x30, 0x11, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x4b, 0x79, + 0x75, 0x6e, 0x67, 0x67, 0x69, 0x2d, 0x64, 0x6f, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, + 0x07, 0x13, 0x0b, 0x53, 0x65, 0x6f, 0x6e, 0x67, + 0x6e, 0x61, 0x6d, 0x2d, 0x73, 0x69, 0x31, 0x1a, + 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x11, 0x54, 0x68, 0x65, 0x20, 0x4e, 0x65, 0x74, + 0x74, 0x79, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, + 0x55, 0x04, 0x0b, 0x13, 0x0c, 0x43, 0x6f, 0x6e, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, + 0x73, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x27, 0x73, 0x65, 0x63, 0x75, + 0x72, 0x65, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x65, + 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x6e, + 0x65, 0x74, 0x74, 0x79, 0x2e, 0x67, 0x6c, 0x65, + 0x61, 0x6d, 0x79, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x6e, 0x65, 0x74, 0x30, 0x5c, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, + 0x48, 0x02, 0x41, 0x00, 0x95, 0xb3, 0x47, 0x17, + 0x95, 0x0f, 0x57, 0xcf, 0x66, 0x72, 0x0a, 0x7e, + 0x5b, 0x54, 0xea, 0x8c, 0x6f, 0x79, 0xde, 0x94, + 0xac, 0x0b, 0x5a, 0xd4, 0xd6, 0x1b, 0x58, 0x12, + 0x1a, 0x16, 0x3d, 0xfe, 0xdf, 0xa5, 0x2b, 0x86, + 0xbc, 0x64, 0xd4, 0x80, 0x1e, 0x3f, 0xf9, 0xe2, + 0x04, 0x03, 0x79, 0x9b, 0xc1, 0x5c, 0xf0, 0xf1, + 0xf3, 0xf1, 0xe3, 0xbf, 0x3f, 0xc0, 0x1f, 0xdd, + 0xdb, 0xc0, 0x5b, 0x21, 0x02, 0x03, 0x01, 0x00, + 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, + 0x03, 0x41, 0x00, 0x02, 0xd7, 0xdd, 0xbd, 0x0c, + 0x8e, 0x21, 0x20, 0xef, 0x9e, 0x4f, 0x1f, 0xf5, + 0x49, 0xf1, 0xae, 0x58, 0x9b, 0x94, 0x3a, 0x1f, + 0x70, 0x33, 0xf0, 0x9b, 0xbb, 0xe9, 0xc0, 0xf3, + 0x72, 0xcb, 0xde, 0xb6, 0x56, 0x72, 0xcc, 0x1c, + 0xf0, 0xd6, 0x5a, 0x2a, 0xbc, 0xa1, 0x7e, 0x23, + 0x83, 0xe9, 0xe7, 0xcf, 0x9e, 0xa5, 0xf9, 0xcc, + 0xc2, 0x61, 0xf4, 0xdb, 0x40, 0x93, 0x1d, 0x63, + 0x8a, 0x50, 0x4c, 0x11, 0x39, 0xb1, 0x91, 0xc1, + 0xe6, 0x9d, 0xd9, 0x1a, 0x62, 0x1b, 0xb8, 0xd3, + 0xd6, 0x9a, 0x6d, 0xb9, 0x8e, 0x15, 0x51 ) +} From d748bd5e9ed50415e2adbed3afe7ad2510364ae8 Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Thu, 15 Jul 2010 21:33:44 +0200 Subject: [PATCH 06/14] Initial code, ble to turn ssl on/off, not verified --- .../main/scala/remote/DummySSLConfig.scala | 285 ------------------ .../src/main/scala/remote/RemoteClient.scala | 47 +-- .../src/main/scala/remote/RemoteServer.scala | 95 +++--- config/akka-reference.conf | 17 ++ 4 files changed, 100 insertions(+), 344 deletions(-) delete mode 100644 akka-core/src/main/scala/remote/DummySSLConfig.scala diff --git a/akka-core/src/main/scala/remote/DummySSLConfig.scala b/akka-core/src/main/scala/remote/DummySSLConfig.scala deleted file mode 100644 index 2a24ead57b..0000000000 --- a/akka-core/src/main/scala/remote/DummySSLConfig.scala +++ /dev/null @@ -1,285 +0,0 @@ -package se.scalablesolutions.akka.remote - -import java.io.{ByteArrayInputStream,InputStream} -import java.security.KeyStore -import java.security.cert.X509Certificate -import javax.net.ssl.{ManagerFactoryParameters,TrustManager,TrustManagerFactorySpi,X509TrustManager}; - -object DummyTrustManagerFactory extends TrustManagerFactorySpi { - private val DUMMY_TRUST_MANAGER : TrustManager = new X509TrustManager { - def getAcceptedIssuers() = Array[X509Certificate]() - def checkClientTrusted(chain : Array[X509Certificate], authType : String) = println("UNKNOWN CLIENT CERTIFICATE: " + chain(0).getSubjectDN) - def checkServerTrusted(chain : Array[X509Certificate], authType : String) = println("UNKNOWN SERVER CERTIFICATE: " + chain(0).getSubjectDN) - } - - def getTrustManagers = Array(DUMMY_TRUST_MANAGER) - - protected override def engineGetTrustManagers = getTrustManagers - protected override def engineInit(keystore:KeyStore) = () - protected override def engineInit(managerFactoryParameters : ManagerFactoryParameters) = () -} - -object DummyKeyStore { - def asInputStream : InputStream = new ByteArrayInputStream(for(d <- DATA) yield d.toByte) - def getCertificatePassword = "secret".toCharArray - def getKeyStorePassword = "secret".toCharArray - private val DATA = Array[Short]( - 0xfe, 0xed, 0xfe, 0xed, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, - 0x65, 0x00, 0x00, 0x01, 0x1a, 0x9f, 0x57, 0xa5, - 0x27, 0x00, 0x00, 0x01, 0x9a, 0x30, 0x82, 0x01, - 0x96, 0x30, 0x0e, 0x06, 0x0a, 0x2b, 0x06, 0x01, - 0x04, 0x01, 0x2a, 0x02, 0x11, 0x01, 0x01, 0x05, - 0x00, 0x04, 0x82, 0x01, 0x82, 0x48, 0x6d, 0xcf, - 0x16, 0xb5, 0x50, 0x95, 0x36, 0xbf, 0x47, 0x27, - 0x50, 0x58, 0x0d, 0xa2, 0x52, 0x7e, 0x25, 0xab, - 0x14, 0x1a, 0x26, 0x5e, 0x2d, 0x8a, 0x23, 0x90, - 0x60, 0x7f, 0x12, 0x20, 0x56, 0xd1, 0x43, 0xa2, - 0x6b, 0x47, 0x5d, 0xed, 0x9d, 0xd4, 0xe5, 0x83, - 0x28, 0x89, 0xc2, 0x16, 0x4c, 0x76, 0x06, 0xad, - 0x8e, 0x8c, 0x29, 0x1a, 0x9b, 0x0f, 0xdd, 0x60, - 0x4b, 0xb4, 0x62, 0x82, 0x9e, 0x4a, 0x63, 0x83, - 0x2e, 0xd2, 0x43, 0x78, 0xc2, 0x32, 0x1f, 0x60, - 0xa9, 0x8a, 0x7f, 0x0f, 0x7c, 0xa6, 0x1d, 0xe6, - 0x92, 0x9e, 0x52, 0xc7, 0x7d, 0xbb, 0x35, 0x3b, - 0xaa, 0x89, 0x73, 0x4c, 0xfb, 0x99, 0x54, 0x97, - 0x99, 0x28, 0x6e, 0x66, 0x5b, 0xf7, 0x9b, 0x7e, - 0x6d, 0x8a, 0x2f, 0xfa, 0xc3, 0x1e, 0x71, 0xb9, - 0xbd, 0x8f, 0xc5, 0x63, 0x25, 0x31, 0x20, 0x02, - 0xff, 0x02, 0xf0, 0xc9, 0x2c, 0xdd, 0x3a, 0x10, - 0x30, 0xab, 0xe5, 0xad, 0x3d, 0x1a, 0x82, 0x77, - 0x46, 0xed, 0x03, 0x38, 0xa4, 0x73, 0x6d, 0x36, - 0x36, 0x33, 0x70, 0xb2, 0x63, 0x20, 0xca, 0x03, - 0xbf, 0x5a, 0xf4, 0x7c, 0x35, 0xf0, 0x63, 0x1a, - 0x12, 0x33, 0x12, 0x58, 0xd9, 0xa2, 0x63, 0x6b, - 0x63, 0x82, 0x41, 0x65, 0x70, 0x37, 0x4b, 0x99, - 0x04, 0x9f, 0xdd, 0x5e, 0x07, 0x01, 0x95, 0x9f, - 0x36, 0xe8, 0xc3, 0x66, 0x2a, 0x21, 0x69, 0x68, - 0x40, 0xe6, 0xbc, 0xbb, 0x85, 0x81, 0x21, 0x13, - 0xe6, 0xa4, 0xcf, 0xd3, 0x67, 0xe3, 0xfd, 0x75, - 0xf0, 0xdf, 0x83, 0xe0, 0xc5, 0x36, 0x09, 0xac, - 0x1b, 0xd4, 0xf7, 0x2a, 0x23, 0x57, 0x1c, 0x5c, - 0x0f, 0xf4, 0xcf, 0xa2, 0xcf, 0xf5, 0xbd, 0x9c, - 0x69, 0x98, 0x78, 0x3a, 0x25, 0xe4, 0xfd, 0x85, - 0x11, 0xcc, 0x7d, 0xef, 0xeb, 0x74, 0x60, 0xb1, - 0xb7, 0xfb, 0x1f, 0x0e, 0x62, 0xff, 0xfe, 0x09, - 0x0a, 0xc3, 0x80, 0x2f, 0x10, 0x49, 0x89, 0x78, - 0xd2, 0x08, 0xfa, 0x89, 0x22, 0x45, 0x91, 0x21, - 0xbc, 0x90, 0x3e, 0xad, 0xb3, 0x0a, 0xb4, 0x0e, - 0x1c, 0xa1, 0x93, 0x92, 0xd8, 0x72, 0x07, 0x54, - 0x60, 0xe7, 0x91, 0xfc, 0xd9, 0x3c, 0xe1, 0x6f, - 0x08, 0xe4, 0x56, 0xf6, 0x0b, 0xb0, 0x3c, 0x39, - 0x8a, 0x2d, 0x48, 0x44, 0x28, 0x13, 0xca, 0xe9, - 0xf7, 0xa3, 0xb6, 0x8a, 0x5f, 0x31, 0xa9, 0x72, - 0xf2, 0xde, 0x96, 0xf2, 0xb1, 0x53, 0xb1, 0x3e, - 0x24, 0x57, 0xfd, 0x18, 0x45, 0x1f, 0xc5, 0x33, - 0x1b, 0xa4, 0xe8, 0x21, 0xfa, 0x0e, 0xb2, 0xb9, - 0xcb, 0xc7, 0x07, 0x41, 0xdd, 0x2f, 0xb6, 0x6a, - 0x23, 0x18, 0xed, 0xc1, 0xef, 0xe2, 0x4b, 0xec, - 0xc9, 0xba, 0xfb, 0x46, 0x43, 0x90, 0xd7, 0xb5, - 0x68, 0x28, 0x31, 0x2b, 0x8d, 0xa8, 0x51, 0x63, - 0xf7, 0x53, 0x99, 0x19, 0x68, 0x85, 0x66, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x05, 0x58, 0x2e, 0x35, - 0x30, 0x39, 0x00, 0x00, 0x02, 0x3a, 0x30, 0x82, - 0x02, 0x36, 0x30, 0x82, 0x01, 0xe0, 0xa0, 0x03, - 0x02, 0x01, 0x02, 0x02, 0x04, 0x48, 0x59, 0xf1, - 0x92, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, - 0x30, 0x81, 0xa0, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4b, 0x52, - 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, - 0x08, 0x13, 0x0a, 0x4b, 0x79, 0x75, 0x6e, 0x67, - 0x67, 0x69, 0x2d, 0x64, 0x6f, 0x31, 0x14, 0x30, - 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0b, - 0x53, 0x65, 0x6f, 0x6e, 0x67, 0x6e, 0x61, 0x6d, - 0x2d, 0x73, 0x69, 0x31, 0x1a, 0x30, 0x18, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x54, 0x68, - 0x65, 0x20, 0x4e, 0x65, 0x74, 0x74, 0x79, 0x20, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x31, - 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 0x0f, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, - 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x73, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x27, 0x73, 0x65, 0x63, 0x75, - 0x72, 0x65, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x65, - 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x6e, - 0x65, 0x74, 0x74, 0x79, 0x2e, 0x67, 0x6c, 0x65, - 0x61, 0x6d, 0x79, 0x6e, 0x6f, 0x64, 0x65, 0x2e, - 0x6e, 0x65, 0x74, 0x30, 0x20, 0x17, 0x0d, 0x30, - 0x38, 0x30, 0x36, 0x31, 0x39, 0x30, 0x35, 0x34, - 0x31, 0x33, 0x38, 0x5a, 0x18, 0x0f, 0x32, 0x31, - 0x38, 0x37, 0x31, 0x31, 0x32, 0x34, 0x30, 0x35, - 0x34, 0x31, 0x33, 0x38, 0x5a, 0x30, 0x81, 0xa0, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, - 0x06, 0x13, 0x02, 0x4b, 0x52, 0x31, 0x13, 0x30, - 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, - 0x4b, 0x79, 0x75, 0x6e, 0x67, 0x67, 0x69, 0x2d, - 0x64, 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, - 0x55, 0x04, 0x07, 0x13, 0x0b, 0x53, 0x65, 0x6f, - 0x6e, 0x67, 0x6e, 0x61, 0x6d, 0x2d, 0x73, 0x69, - 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x11, 0x54, 0x68, 0x65, 0x20, 0x4e, - 0x65, 0x74, 0x74, 0x79, 0x20, 0x50, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x31, 0x18, 0x30, 0x16, - 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0f, 0x45, - 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x41, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x73, 0x31, 0x30, - 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, - 0x27, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x63, - 0x68, 0x61, 0x74, 0x2e, 0x65, 0x78, 0x61, 0x6d, - 0x70, 0x6c, 0x65, 0x2e, 0x6e, 0x65, 0x74, 0x74, - 0x79, 0x2e, 0x67, 0x6c, 0x65, 0x61, 0x6d, 0x79, - 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x65, 0x74, - 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, - 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, - 0x00, 0xc3, 0xe3, 0x5e, 0x41, 0xa7, 0x87, 0x11, - 0x00, 0x42, 0x2a, 0xb0, 0x4b, 0xed, 0xb2, 0xe0, - 0x23, 0xdb, 0xb1, 0x3d, 0x58, 0x97, 0x35, 0x60, - 0x0b, 0x82, 0x59, 0xd3, 0x00, 0xea, 0xd4, 0x61, - 0xb8, 0x79, 0x3f, 0xb6, 0x3c, 0x12, 0x05, 0x93, - 0x2e, 0x9a, 0x59, 0x68, 0x14, 0x77, 0x3a, 0xc8, - 0x50, 0x25, 0x57, 0xa4, 0x49, 0x18, 0x63, 0x41, - 0xf0, 0x2d, 0x28, 0xec, 0x06, 0xfb, 0xb4, 0x9f, - 0xbf, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, - 0x65, 0x6c, 0x30, 0x01, 0xc2, 0x8e, 0x3e, 0xcb, - 0xb3, 0x77, 0x48, 0xe9, 0x66, 0x61, 0x9a, 0x40, - 0x86, 0xaf, 0xf6, 0x03, 0xeb, 0xba, 0x6a, 0xf2, - 0xfd, 0xe2, 0xaf, 0x36, 0x5e, 0x7b, 0xaa, 0x22, - 0x04, 0xdd, 0x2c, 0x20, 0xc4, 0xfc, 0xdd, 0xd0, - 0x82, 0x20, 0x1c, 0x3d, 0xd7, 0x9e, 0x5e, 0x5c, - 0x92, 0x5a, 0x76, 0x71, 0x28, 0xf5, 0x07, 0x7d, - 0xa2, 0x81, 0xba, 0x77, 0x9f, 0x2a, 0xd9, 0x44, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x6d, 0x79, - 0x6b, 0x65, 0x79, 0x00, 0x00, 0x01, 0x1a, 0x9f, - 0x5b, 0x56, 0xa0, 0x00, 0x00, 0x01, 0x99, 0x30, - 0x82, 0x01, 0x95, 0x30, 0x0e, 0x06, 0x0a, 0x2b, - 0x06, 0x01, 0x04, 0x01, 0x2a, 0x02, 0x11, 0x01, - 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x81, 0x29, - 0xa8, 0xb6, 0x08, 0x0c, 0x85, 0x75, 0x3e, 0xdd, - 0xb5, 0xe5, 0x1a, 0x87, 0x68, 0xd1, 0x90, 0x4b, - 0x29, 0x31, 0xee, 0x90, 0xbc, 0x9d, 0x73, 0xa0, - 0x3f, 0xe9, 0x0b, 0xa4, 0xef, 0x30, 0x9b, 0x36, - 0x9a, 0xb2, 0x54, 0x77, 0x81, 0x07, 0x4b, 0xaa, - 0xa5, 0x77, 0x98, 0xe1, 0xeb, 0xb5, 0x7c, 0x4e, - 0x48, 0xd5, 0x08, 0xfc, 0x2c, 0x36, 0xe2, 0x65, - 0x03, 0xac, 0xe5, 0xf3, 0x96, 0xb7, 0xd0, 0xb5, - 0x3b, 0x92, 0xe4, 0x14, 0x05, 0x7a, 0x6a, 0x92, - 0x56, 0xfe, 0x4e, 0xab, 0xd3, 0x0e, 0x32, 0x04, - 0x22, 0x22, 0x74, 0x47, 0x7d, 0xec, 0x21, 0x99, - 0x30, 0x31, 0x64, 0x46, 0x64, 0x9b, 0xc7, 0x13, - 0xbf, 0xbe, 0xd0, 0x31, 0x49, 0xe7, 0x3c, 0xbf, - 0xba, 0xb1, 0x20, 0xf9, 0x42, 0xf4, 0xa9, 0xa9, - 0xe5, 0x13, 0x65, 0x32, 0xbf, 0x7c, 0xcc, 0x91, - 0xd3, 0xfd, 0x24, 0x47, 0x0b, 0xe5, 0x53, 0xad, - 0x50, 0x30, 0x56, 0xd1, 0xfa, 0x9c, 0x37, 0xa8, - 0xc1, 0xce, 0xf6, 0x0b, 0x18, 0xaa, 0x7c, 0xab, - 0xbd, 0x1f, 0xdf, 0xe4, 0x80, 0xb8, 0xa7, 0xe0, - 0xad, 0x7d, 0x50, 0x74, 0xf1, 0x98, 0x78, 0xbc, - 0x58, 0xb9, 0xc2, 0x52, 0xbe, 0xd2, 0x5b, 0x81, - 0x94, 0x83, 0x8f, 0xb9, 0x4c, 0xee, 0x01, 0x2b, - 0x5e, 0xc9, 0x6e, 0x9b, 0xf5, 0x63, 0x69, 0xe4, - 0xd8, 0x0b, 0x47, 0xd8, 0xfd, 0xd8, 0xe0, 0xed, - 0xa8, 0x27, 0x03, 0x74, 0x1e, 0x5d, 0x32, 0xe6, - 0x5c, 0x63, 0xc2, 0xfb, 0x3f, 0xee, 0xb4, 0x13, - 0xc6, 0x0e, 0x6e, 0x74, 0xe0, 0x22, 0xac, 0xce, - 0x79, 0xf9, 0x43, 0x68, 0xc1, 0x03, 0x74, 0x2b, - 0xe1, 0x18, 0xf8, 0x7f, 0x76, 0x9a, 0xea, 0x82, - 0x3f, 0xc2, 0xa6, 0xa7, 0x4c, 0xfe, 0xae, 0x29, - 0x3b, 0xc1, 0x10, 0x7c, 0xd5, 0x77, 0x17, 0x79, - 0x5f, 0xcb, 0xad, 0x1f, 0xd8, 0xa1, 0xfd, 0x90, - 0xe1, 0x6b, 0xb2, 0xef, 0xb9, 0x41, 0x26, 0xa4, - 0x0b, 0x4f, 0xc6, 0x83, 0x05, 0x6f, 0xf0, 0x64, - 0x40, 0xe1, 0x44, 0xc4, 0xf9, 0x40, 0x2b, 0x3b, - 0x40, 0xdb, 0xaf, 0x35, 0xa4, 0x9b, 0x9f, 0xc4, - 0x74, 0x07, 0xe5, 0x18, 0x60, 0xc5, 0xfe, 0x15, - 0x0e, 0x3a, 0x25, 0x2a, 0x11, 0xee, 0x78, 0x2f, - 0xb8, 0xd1, 0x6e, 0x4e, 0x3c, 0x0a, 0xb5, 0xb9, - 0x40, 0x86, 0x27, 0x6d, 0x8f, 0x53, 0xb7, 0x77, - 0x36, 0xec, 0x5d, 0xed, 0x32, 0x40, 0x43, 0x82, - 0xc3, 0x52, 0x58, 0xc4, 0x26, 0x39, 0xf3, 0xb3, - 0xad, 0x58, 0xab, 0xb7, 0xf7, 0x8e, 0x0e, 0xba, - 0x8e, 0x78, 0x9d, 0xbf, 0x58, 0x34, 0xbd, 0x77, - 0x73, 0xa6, 0x50, 0x55, 0x00, 0x60, 0x26, 0xbf, - 0x6d, 0xb4, 0x98, 0x8a, 0x18, 0x83, 0x89, 0xf8, - 0xcd, 0x0d, 0x49, 0x06, 0xae, 0x51, 0x6e, 0xaf, - 0xbd, 0xe2, 0x07, 0x13, 0xd8, 0x64, 0xcc, 0xbf, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x58, 0x2e, - 0x35, 0x30, 0x39, 0x00, 0x00, 0x02, 0x34, 0x30, - 0x82, 0x02, 0x30, 0x30, 0x82, 0x01, 0xda, 0xa0, - 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x48, 0x59, - 0xf2, 0x84, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x30, 0x81, 0x9d, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4b, - 0x52, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, - 0x04, 0x08, 0x13, 0x0a, 0x4b, 0x79, 0x75, 0x6e, - 0x67, 0x67, 0x69, 0x2d, 0x64, 0x6f, 0x31, 0x14, - 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, - 0x0b, 0x53, 0x65, 0x6f, 0x6e, 0x67, 0x6e, 0x61, - 0x6d, 0x2d, 0x73, 0x69, 0x31, 0x1a, 0x30, 0x18, - 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x54, - 0x68, 0x65, 0x20, 0x4e, 0x65, 0x74, 0x74, 0x79, - 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, - 0x0b, 0x13, 0x0c, 0x43, 0x6f, 0x6e, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x73, 0x31, - 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x27, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, - 0x63, 0x68, 0x61, 0x74, 0x2e, 0x65, 0x78, 0x61, - 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x6e, 0x65, 0x74, - 0x74, 0x79, 0x2e, 0x67, 0x6c, 0x65, 0x61, 0x6d, - 0x79, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6e, 0x65, - 0x74, 0x30, 0x20, 0x17, 0x0d, 0x30, 0x38, 0x30, - 0x36, 0x31, 0x39, 0x30, 0x35, 0x34, 0x35, 0x34, - 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x38, 0x37, - 0x31, 0x31, 0x32, 0x33, 0x30, 0x35, 0x34, 0x35, - 0x34, 0x30, 0x5a, 0x30, 0x81, 0x9d, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x4b, 0x52, 0x31, 0x13, 0x30, 0x11, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x4b, 0x79, - 0x75, 0x6e, 0x67, 0x67, 0x69, 0x2d, 0x64, 0x6f, - 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, - 0x07, 0x13, 0x0b, 0x53, 0x65, 0x6f, 0x6e, 0x67, - 0x6e, 0x61, 0x6d, 0x2d, 0x73, 0x69, 0x31, 0x1a, - 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x11, 0x54, 0x68, 0x65, 0x20, 0x4e, 0x65, 0x74, - 0x74, 0x79, 0x20, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, - 0x55, 0x04, 0x0b, 0x13, 0x0c, 0x43, 0x6f, 0x6e, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, - 0x73, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x27, 0x73, 0x65, 0x63, 0x75, - 0x72, 0x65, 0x63, 0x68, 0x61, 0x74, 0x2e, 0x65, - 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x6e, - 0x65, 0x74, 0x74, 0x79, 0x2e, 0x67, 0x6c, 0x65, - 0x61, 0x6d, 0x79, 0x6e, 0x6f, 0x64, 0x65, 0x2e, - 0x6e, 0x65, 0x74, 0x30, 0x5c, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, - 0x48, 0x02, 0x41, 0x00, 0x95, 0xb3, 0x47, 0x17, - 0x95, 0x0f, 0x57, 0xcf, 0x66, 0x72, 0x0a, 0x7e, - 0x5b, 0x54, 0xea, 0x8c, 0x6f, 0x79, 0xde, 0x94, - 0xac, 0x0b, 0x5a, 0xd4, 0xd6, 0x1b, 0x58, 0x12, - 0x1a, 0x16, 0x3d, 0xfe, 0xdf, 0xa5, 0x2b, 0x86, - 0xbc, 0x64, 0xd4, 0x80, 0x1e, 0x3f, 0xf9, 0xe2, - 0x04, 0x03, 0x79, 0x9b, 0xc1, 0x5c, 0xf0, 0xf1, - 0xf3, 0xf1, 0xe3, 0xbf, 0x3f, 0xc0, 0x1f, 0xdd, - 0xdb, 0xc0, 0x5b, 0x21, 0x02, 0x03, 0x01, 0x00, - 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, - 0x03, 0x41, 0x00, 0x02, 0xd7, 0xdd, 0xbd, 0x0c, - 0x8e, 0x21, 0x20, 0xef, 0x9e, 0x4f, 0x1f, 0xf5, - 0x49, 0xf1, 0xae, 0x58, 0x9b, 0x94, 0x3a, 0x1f, - 0x70, 0x33, 0xf0, 0x9b, 0xbb, 0xe9, 0xc0, 0xf3, - 0x72, 0xcb, 0xde, 0xb6, 0x56, 0x72, 0xcc, 0x1c, - 0xf0, 0xd6, 0x5a, 0x2a, 0xbc, 0xa1, 0x7e, 0x23, - 0x83, 0xe9, 0xe7, 0xcf, 0x9e, 0xa5, 0xf9, 0xcc, - 0xc2, 0x61, 0xf4, 0xdb, 0x40, 0x93, 0x1d, 0x63, - 0x8a, 0x50, 0x4c, 0x11, 0x39, 0xb1, 0x91, 0xc1, - 0xe6, 0x9d, 0xd9, 0x1a, 0x62, 0x1b, 0xb8, 0xd3, - 0xd6, 0x9a, 0x6d, 0xb9, 0x8e, 0x15, 0x51 ) -} diff --git a/akka-core/src/main/scala/remote/RemoteClient.scala b/akka-core/src/main/scala/remote/RemoteClient.scala index 5e90f3585b..c90d472c09 100644 --- a/akka-core/src/main/scala/remote/RemoteClient.scala +++ b/akka-core/src/main/scala/remote/RemoteClient.scala @@ -250,26 +250,27 @@ class RemoteClientPipelineFactory(name: String, timer: HashedWheelTimer, client: RemoteClient) extends ChannelPipelineFactory { def getPipeline: ChannelPipeline = { + def join(ch: ChannelHandler*) = Array[ChannelHandler](ch:_*) + val engine = RemoteServerSslContext.client.createSSLEngine() engine.setEnabledCipherSuites(engine.getSupportedCipherSuites) //TODO is this sensible? engine.setUseClientMode(true) - val ssl = new SslHandler(engine) - val timeout = new ReadTimeoutHandler(timer, RemoteClient.READ_TIMEOUT) - val lenDec = new LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4) - val lenPrep = new LengthFieldPrepender(4) + val ssl = if(RemoteServer.SECURE) join(new SslHandler(engine)) else join() + val timeout = new ReadTimeoutHandler(timer, RemoteClient.READ_TIMEOUT) + val lenDec = new LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4) + val lenPrep = new LengthFieldPrepender(4) val protobufDec = new ProtobufDecoder(RemoteReplyProtocol.getDefaultInstance) val protobufEnc = new ProtobufEncoder - val zipCodec = RemoteServer.COMPRESSION_SCHEME match { - case "zlib" => Some(Codec(new ZlibEncoder(RemoteServer.ZLIB_COMPRESSION_LEVEL), new ZlibDecoder)) - //case "lzf" => Some(Codec(new LzfEncoder, new LzfDecoder)) - case _ => None + val(enc,dec) = RemoteServer.COMPRESSION_SCHEME match { + case "zlib" => (join(new ZlibEncoder(RemoteServer.ZLIB_COMPRESSION_LEVEL)),join(new ZlibDecoder)) + case _ => (join(),join()) } + val remoteClient = new RemoteClientHandler(name, futures, supervisors, bootstrap, remoteAddress, timer, client) - val stages: Array[ChannelHandler] = - zipCodec.map(codec => Array(ssl, timeout, codec.decoder, lenDec, protobufDec, codec.encoder, lenPrep, protobufEnc, remoteClient)) - .getOrElse(Array(ssl, timeout, lenDec, protobufDec, lenPrep, protobufEnc, remoteClient)) + val stages = ssl ++ join(timeout) ++ dec ++ join(lenDec, protobufDec) ++ enc ++ join(lenPrep, protobufEnc, remoteClient) + new StaticChannelPipeline(stages: _*) } } @@ -348,20 +349,24 @@ class RemoteClientHandler(val name: String, } override def channelConnected(ctx: ChannelHandlerContext, event: ChannelStateEvent) = { + def connect = { + client.listeners.toArray.foreach(l => l.asInstanceOf[ActorRef] ! RemoteClientConnected(client.hostname, client.port)) + log.debug("Remote client connected to [%s]", ctx.getChannel.getRemoteAddress) + } -// client.listeners.toArray.foreach(l => -// l.asInstanceOf[ActorRef] ! RemoteClientConnected(client.hostname, client.port)) -// log.debug("Remote client connected to [%s]", ctx.getChannel.getRemoteAddress) - - val sslHandler : SslHandler = ctx.getPipeline.get(classOf[SslHandler]) - sslHandler.handshake().addListener( new ChannelFutureListener { + if(RemoteServer.SECURE){ + val sslHandler : SslHandler = ctx.getPipeline.get(classOf[SslHandler]) + sslHandler.handshake().addListener( new ChannelFutureListener { def operationComplete(future : ChannelFuture) : Unit = { - if(future.isSuccess) { - client.listeners.toArray.foreach(l => l.asInstanceOf[ActorRef] ! RemoteClientConnected(client.hostname, client.port)) - log.debug("Remote client connected to [%s]", ctx.getChannel.getRemoteAddress) - } + if(future.isSuccess) + connect + //else + //FIXME: What is the correct action here? } }) + } else { + connect + } } override def channelDisconnected(ctx: ChannelHandlerContext, event: ChannelStateEvent) = { diff --git a/akka-core/src/main/scala/remote/RemoteServer.scala b/akka-core/src/main/scala/remote/RemoteServer.scala index 1b646e1fe9..93386311f2 100644 --- a/akka-core/src/main/scala/remote/RemoteServer.scala +++ b/akka-core/src/main/scala/remote/RemoteServer.scala @@ -75,6 +75,32 @@ object RemoteServer { level } + val SECURE = { + if(config.getBool("akka.remote.ssl.service",false)){ + + val properties = List( + ("key-store-type" ,"keyStoreType"), + ("key-store" ,"keyStore"), + ("key-store-pass" ,"keyStorePassword"), + ("trust-store-type","trustStoreType"), + ("trust-store" ,"trustStore"), + ("trust-store-pass","trustStorePassword") + ).map(x => ("akka.remote.ssl." + x._1,"javax.net.ssl."+x._2)) + + //If property is not set, and we have a value from our akka.conf, use that value + for{ p <- properties if System.getProperty(p._2) eq null + c <- config.getString(p._1) + } System.setProperty(p._2,c) + + if(config.getBool("akka.remote.ssl.debug",false)) + System.setProperty("javax.net.debug","ssl") + + true + } + else + false + } + object Address { def apply(hostname: String, port: Int) = new Address(hostname, port) } @@ -279,30 +305,20 @@ class RemoteServer extends Logging { } } -case class Codec(encoder: ChannelHandler, decoder: ChannelHandler) - object RemoteServerSslContext { - import java.security.{KeyStore,Security} - import javax.net.ssl.{KeyManager,KeyManagerFactory,SSLContext,TrustManagerFactory} + import javax.net.ssl.SSLContext val (client,server) = { val protocol = "TLS" - val algorithm = Option(Security.getProperty("ssl.KeyManagerFactory.algorithm")).getOrElse("SunX509") - val store = KeyStore.getInstance("JKS") - store.load(DummyKeyStore.asInputStream,DummyKeyStore.getKeyStorePassword) //TODO replace with getResourceAsStream + config-pass - - val keyMan = KeyManagerFactory.getInstance(algorithm) - keyMan.init(store, DummyKeyStore.getCertificatePassword) //TODO replace with config-pass - - //val trustMan = TrustManagerFactory.getInstance("SunX509"); - //trustMan.init(store) //TODO safe to use same keystore? Or should use it's own keystore? + //val algorithm = Option(Security.getProperty("ssl.KeyManagerFactory.algorithm")).getOrElse("SunX509") + //val store = KeyStore.getInstance("JKS") val s = SSLContext.getInstance(protocol) - s.init(keyMan.getKeyManagers, null, null) + s.init(null,null,null) val c = SSLContext.getInstance(protocol) - c.init(null, DummyTrustManagerFactory.getTrustManagers, null) //TODO replace with TrustManagerFactory - + c.init(null,null,null) + (c,s) } } @@ -319,25 +335,26 @@ class RemoteServerPipelineFactory( import RemoteServer._ def getPipeline: ChannelPipeline = { + def join(ch: ChannelHandler*) = Array[ChannelHandler](ch:_*) + val engine = RemoteServerSslContext.server.createSSLEngine() engine.setEnabledCipherSuites(engine.getSupportedCipherSuites) //TODO is this sensible? engine.setUseClientMode(false) - val ssl = new SslHandler(engine) - val lenDec = new LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4) - val lenPrep = new LengthFieldPrepender(4) - val protobufDec = new ProtobufDecoder(RemoteRequestProtocol.getDefaultInstance) - val protobufEnc = new ProtobufEncoder - val zipCodec = RemoteServer.COMPRESSION_SCHEME match { - case "zlib" => Some(Codec(new ZlibEncoder(RemoteServer.ZLIB_COMPRESSION_LEVEL), new ZlibDecoder)) - //case "lzf" => Some(Codec(new LzfEncoder, new LzfDecoder)) - case _ => None + val ssl = if(RemoteServer.SECURE) join(new SslHandler(engine)) else join() + val lenDec = new LengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4) + val lenPrep = new LengthFieldPrepender(4) + val protobufDec = new ProtobufDecoder(RemoteRequestProtocol.getDefaultInstance) + val protobufEnc = new ProtobufEncoder + val(enc,dec) = RemoteServer.COMPRESSION_SCHEME match { + case "zlib" => (join(new ZlibEncoder(RemoteServer.ZLIB_COMPRESSION_LEVEL)),join(new ZlibDecoder)) + case _ => (join(),join()) } + val remoteServer = new RemoteServerHandler(name, openChannels, loader, actors, activeObjects) - val stages: Array[ChannelHandler] = - zipCodec.map(codec => Array(ssl,codec.decoder, lenDec, protobufDec, codec.encoder, lenPrep, protobufEnc, remoteServer)) - .getOrElse(Array(ssl,lenDec, protobufDec, lenPrep, protobufEnc, remoteServer)) + val stages = ssl ++ dec ++ join(lenDec, protobufDec) ++ enc ++ join(lenPrep, protobufEnc, remoteServer) + new StaticChannelPipeline(stages: _*) } } @@ -365,17 +382,19 @@ class RemoteServerHandler( } override def channelConnected(ctx : ChannelHandlerContext, e : ChannelStateEvent) { - val sslHandler : SslHandler = ctx.getPipeline.get(classOf[SslHandler]) + if(RemoteServer.SECURE) { + val sslHandler : SslHandler = ctx.getPipeline.get(classOf[SslHandler]) - // Begin handshake. - sslHandler.handshake().addListener( new ChannelFutureListener { - def operationComplete(future : ChannelFuture) : Unit = { - if(future.isSuccess) - openChannels.add(future.getChannel) - else - future.getChannel.close - } - }) + // Begin handshake. + sslHandler.handshake().addListener( new ChannelFutureListener { + def operationComplete(future : ChannelFuture) : Unit = { + if(future.isSuccess) + openChannels.add(future.getChannel) + else + future.getChannel.close + } + }) + } } diff --git a/config/akka-reference.conf b/config/akka-reference.conf index e20a745ca1..c96782406b 100644 --- a/config/akka-reference.conf +++ b/config/akka-reference.conf @@ -64,6 +64,23 @@ compression-scheme = "zlib" # Options: "zlib" (lzf to come), leave out for no compression zlib-compression-level = 6 # Options: 0-9 (1 being fastest and 9 being the most compressed), default is 6 + + service = off #on / off + + #You can either use java command-line options or use the settings below + + #key-store-type = "pkcs12" #Same as -Djavax.net.ssl.keyStoreType=pkcs12 + #key-store = "yourcertificate.p12" #Same as -Djavax.net.ssl.keyStore=yourcertificate.p12 + #key-store-pass = "$PASS" #Same as -Djavax.net.ssl.keyStorePassword=$PASS + + #trust-store-type = "jks" #Same as -Djavax.net.ssl.trustStoreType=jks + #trust-store = "your.keystore" #Same as -Djavax.net.ssl.trustStore=your.keystore + #trust-store-pass = "$PASS" #-Djavax.net.ssl.trustStorePassword=$PASS + + #This can be useful for debugging + debug = off #if on, very verbose debug, same as -Djavax.net.debug=ssl + + service = on name = "default" # The name of the cluster From f9750d8dc6bcee22ea0a31c6e9f2f674f03ddb82 Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Tue, 3 Aug 2010 11:25:09 +0200 Subject: [PATCH 07/14] Closing ticket 352 --- .../src/main/scala/actor/ActorRegistry.scala | 41 +++++++++---------- .../test/scala/misc/ActorRegistrySpec.scala | 11 +++++ .../src/main/scala/akka/SimpleService.scala | 4 +- .../src/main/scala/SimpleService.scala | 8 ++-- .../src/main/scala/SimpleService.scala | 4 +- 5 files changed, 39 insertions(+), 29 deletions(-) diff --git a/akka-core/src/main/scala/actor/ActorRegistry.scala b/akka-core/src/main/scala/actor/ActorRegistry.scala index aea37432b7..953540fc70 100644 --- a/akka-core/src/main/scala/actor/ActorRegistry.scala +++ b/akka-core/src/main/scala/actor/ActorRegistry.scala @@ -31,7 +31,6 @@ case class ActorUnregistered(actor: ActorRef) extends ActorRegistryEvent object ActorRegistry extends ListenerManagement { private val actorsByUUID = new ConcurrentHashMap[String, ActorRef] private val actorsById = new ConcurrentHashMap[String, JSet[ActorRef]] - private val actorsByClassName = new ConcurrentHashMap[String, JSet[ActorRef]] /** * Returns all actors in the system. @@ -46,6 +45,21 @@ object ActorRegistry extends ListenerManagement { while (elements.hasMoreElements) f(elements.nextElement) } + /** + * Invokes the function on all known actors until it returns Some + * Returns None if the function never returns Some + */ + def find[T](f: (ActorRef) => Option[T]) : Option[T] = { + val elements = actorsByUUID.elements + while (elements.hasMoreElements) { + val result = f(elements.nextElement) + + if(result.isDefined) + return result + } + None + } + /** * Finds all actors that are subtypes of the class passed in as the Manifest argument and supproting passed message. */ @@ -71,22 +85,20 @@ object ActorRegistry extends ListenerManagement { * Finds all actors that are subtypes of the class passed in as the Manifest argument. */ def actorsFor[T <: Actor](implicit manifest: Manifest[T]): List[ActorRef] = - filter(a => manifest.erasure.isAssignableFrom(a.actor.getClass)) + actorsFor[T](manifest.erasure.asInstanceOf[Class[T]]) /** * Finds any actor that matches T. + * FIXME: Improve performance by breaking out after the first match */ def actorFor[T <: Actor](implicit manifest: Manifest[T]): Option[ActorRef] = actorsFor[T](manifest).headOption /** - * Finds all actors of the exact type specified by the class passed in as the Class argument. + * Finds all actors of type or sub-type specified by the class passed in as the Class argument. */ - def actorsFor[T <: Actor](clazz: Class[T]): List[ActorRef] = { - if (actorsByClassName.containsKey(clazz.getName)) { - actorsByClassName.get(clazz.getName).toArray.toList.asInstanceOf[List[ActorRef]] - } else Nil - } + def actorsFor[T <: Actor](clazz: Class[T]): List[ActorRef] = + filter(a => clazz.isAssignableFrom(a.actor.getClass)) /** * Finds all actors that has a specific id. @@ -122,15 +134,6 @@ object ActorRegistry extends ListenerManagement { actorsById.put(id, set) } - // Class name - val className = actor.actorClassName - if (actorsByClassName.containsKey(className)) actorsByClassName.get(className).add(actor) - else { - val set = new ConcurrentSkipListSet[ActorRef] - set.add(actor) - actorsByClassName.put(className, set) - } - // notify listeners foreachListener(_ ! ActorRegistered(actor)) } @@ -144,9 +147,6 @@ object ActorRegistry extends ListenerManagement { val id = actor.id if (actorsById.containsKey(id)) actorsById.get(id).remove(actor) - val className = actor.actorClassName - if (actorsByClassName.containsKey(className)) actorsByClassName.get(className).remove(actor) - // notify listeners foreachListener(_ ! ActorUnregistered(actor)) } @@ -159,7 +159,6 @@ object ActorRegistry extends ListenerManagement { foreach(_.stop) actorsByUUID.clear actorsById.clear - actorsByClassName.clear log.info("All actors have been shut down and unregistered from ActorRegistry") } } diff --git a/akka-core/src/test/scala/misc/ActorRegistrySpec.scala b/akka-core/src/test/scala/misc/ActorRegistrySpec.scala index 6914472e2c..d6fc463a65 100644 --- a/akka-core/src/test/scala/misc/ActorRegistrySpec.scala +++ b/akka-core/src/test/scala/misc/ActorRegistrySpec.scala @@ -76,6 +76,17 @@ class ActorRegistrySpec extends JUnitSuite { actor.stop } + @Test def shouldFindThingsFromActorRegistry { + ActorRegistry.shutdownAll + val actor = actorOf[TestActor] + actor.start + val found = ActorRegistry.find(a => if(a.actor.isInstanceOf[TestActor]) Some(a) else None) + assert(found.isDefined) + assert(found.get.actor.isInstanceOf[TestActor]) + assert(found.get.id === "MyID") + actor.stop + } + @Test def shouldGetActorsByIdFromActorRegistry { ActorRegistry.shutdownAll val actor1 = actorOf[TestActor] diff --git a/akka-samples/akka-sample-lift/src/main/scala/akka/SimpleService.scala b/akka-samples/akka-sample-lift/src/main/scala/akka/SimpleService.scala index b361fbb16b..d5358a7d89 100644 --- a/akka-samples/akka-sample-lift/src/main/scala/akka/SimpleService.scala +++ b/akka-samples/akka-sample-lift/src/main/scala/akka/SimpleService.scala @@ -64,7 +64,7 @@ object SimpleRestService extends RestHelper { case Get("liftcount" :: _, req) => //Fetch the first actor of type SimpleServiceActor //Send it the "Tick" message and expect a Node back - val result = for( a <- ActorRegistry.actorsFor(classOf[SimpleServiceActor]).headOption; + val result = for( a <- ActorRegistry.actorFor[SimpleServiceActor]; r <- (a !! "Tick").as[Node] ) yield r //Return either the resulting NodeSeq or a default one @@ -85,7 +85,7 @@ object SimpleRestService extends RestHelper { case Get("persistentliftcount" :: _, req) => //Fetch the first actor of type SimpleServiceActor //Send it the "Tick" message and expect a Node back - val result = for( a <- ActorRegistry.actorsFor(classOf[PersistentServiceActor]).headOption; + val result = for( a <- ActorRegistry.actorFor[PersistentServiceActor]; r <- (a !! "Tick").as[Node] ) yield r //Return either the resulting NodeSeq or a default one diff --git a/akka-samples/akka-sample-rest-scala/src/main/scala/SimpleService.scala b/akka-samples/akka-sample-rest-scala/src/main/scala/SimpleService.scala index fc96bba182..c3b71a3fdf 100644 --- a/akka-samples/akka-sample-rest-scala/src/main/scala/SimpleService.scala +++ b/akka-samples/akka-sample-rest-scala/src/main/scala/SimpleService.scala @@ -16,7 +16,7 @@ import java.lang.Integer import java.nio.ByteBuffer import javax.ws.rs.core.MultivaluedMap import javax.ws.rs.{GET, POST, Path, Produces, WebApplicationException, Consumes,PathParam} -import se.scalablesolutions.akka.actor.ActorRegistry.actorsFor +import se.scalablesolutions.akka.actor.ActorRegistry.actorFor import org.atmosphere.annotation.{Broadcast, Suspend,Cluster} import org.atmosphere.util.XSSHtmlFilter import org.atmosphere.cpr.{Broadcaster, BroadcastFilter} @@ -53,7 +53,7 @@ class SimpleService { def count = { //Fetch the first actor of type SimpleServiceActor //Send it the "Tick" message and expect a NodeSeq back - val result = for{a <- actorsFor(classOf[SimpleServiceActor]).headOption + val result = for{a <- actorFor[SimpleServiceActor] r <- (a !! "Tick").as[NodeSeq]} yield r //Return either the resulting NodeSeq or a default one result getOrElse Error in counter @@ -108,7 +108,7 @@ class PersistentSimpleService { def count = { //Fetch the first actor of type PersistentSimpleServiceActor //Send it the "Tick" message and expect a NodeSeq back - val result = for{a <- actorsFor(classOf[PersistentSimpleServiceActor]).headOption + val result = for{a <- actorFor[PersistentSimpleServiceActor] r <- (a !! "Tick").as[NodeSeq]} yield r //Return either the resulting NodeSeq or a default one result getOrElse Error in counter @@ -155,7 +155,7 @@ class Chat { val msg = ChatMsg(form.getFirst("name"),form.getFirst("action"),form.getFirst("message")) //Fetch the first actor of type ChatActor //Send it the "Tick" message and expect a NodeSeq back - val result = for{a <- actorsFor(classOf[ChatActor]).headOption + val result = for{a <- actorFor[ChatActor] r <- (a !! msg).as[String]} yield r //Return either the resulting String or a default one result getOrElse "System__error" diff --git a/akka-samples/akka-sample-security/src/main/scala/SimpleService.scala b/akka-samples/akka-sample-security/src/main/scala/SimpleService.scala index e5c8029eb8..02af6174c6 100644 --- a/akka-samples/akka-sample-security/src/main/scala/SimpleService.scala +++ b/akka-samples/akka-sample-security/src/main/scala/SimpleService.scala @@ -10,7 +10,7 @@ import se.scalablesolutions.akka.config.ScalaConfig._ import se.scalablesolutions.akka.util.Logging import se.scalablesolutions.akka.security.{BasicAuthenticationActor,BasicCredentials,SpnegoAuthenticationActor,DigestAuthenticationActor, UserInfo} import se.scalablesolutions.akka.stm.TransactionalMap -import se.scalablesolutions.akka.actor.ActorRegistry.actorsFor +import se.scalablesolutions.akka.actor.ActorRegistry.actorFor class Boot { val factory = SupervisorFactory( @@ -122,7 +122,7 @@ class SecureTickService { def tick = { //Fetch the first actor of type PersistentSimpleServiceActor //Send it the "Tick" message and expect a NdeSeq back - val result = for{a <- actorsFor(classOf[SecureTickActor]).headOption + val result = for{a <- actorFor[SecureTickActor] r <- (a !! "Tick").as[Integer]} yield r //Return either the resulting NodeSeq or a default one result match { From 80a325ef3465d9b0bc415a973bb81158681b06ce Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Tue, 3 Aug 2010 14:42:42 +0200 Subject: [PATCH 08/14] Closing ticket 355 --- .../main/scala/component/ActorComponent.scala | 5 ++-- .../src/main/scala/actor/ActorRegistry.scala | 23 ++++++++++--------- .../akka/actor/SampleUntypedActor.java | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/akka-camel/src/main/scala/component/ActorComponent.scala b/akka-camel/src/main/scala/component/ActorComponent.scala index 1cd29ced00..7ef8e0750c 100644 --- a/akka-camel/src/main/scala/component/ActorComponent.scala +++ b/akka-camel/src/main/scala/component/ActorComponent.scala @@ -148,9 +148,8 @@ class ActorProducer(val ep: ActorEndpoint) extends DefaultProducer(ep) with Asyn else targetByUuid(ep.uuid.get) private def targetById(id: String) = ActorRegistry.actorsFor(id) match { - case Nil => None - case actor :: Nil => Some(actor) - case actors => Some(actors.head) + case actors if actors.length == 0 => None + case actors => Some(actors(0)) } private def targetByUuid(uuid: String) = ActorRegistry.actorFor(uuid) diff --git a/akka-core/src/main/scala/actor/ActorRegistry.scala b/akka-core/src/main/scala/actor/ActorRegistry.scala index 953540fc70..63ddb939c7 100644 --- a/akka-core/src/main/scala/actor/ActorRegistry.scala +++ b/akka-core/src/main/scala/actor/ActorRegistry.scala @@ -32,10 +32,12 @@ object ActorRegistry extends ListenerManagement { private val actorsByUUID = new ConcurrentHashMap[String, ActorRef] private val actorsById = new ConcurrentHashMap[String, JSet[ActorRef]] + private val Naught = Array[ActorRef]() //Nil for Arrays + /** * Returns all actors in the system. */ - def actors: List[ActorRef] = filter(_ => true) + def actors: Array[ActorRef] = filter(_ => true) /** * Invokes a function for all actors. @@ -63,13 +65,13 @@ object ActorRegistry extends ListenerManagement { /** * Finds all actors that are subtypes of the class passed in as the Manifest argument and supproting passed message. */ - def actorsFor[T <: Actor](message: Any)(implicit manifest: Manifest[T] ): List[ActorRef] = + def actorsFor[T <: Actor](message: Any)(implicit manifest: Manifest[T] ): Array[ActorRef] = filter(a => manifest.erasure.isAssignableFrom(a.actor.getClass) && a.isDefinedAt(message)) /** * Finds all actors that satisfy a predicate. */ - def filter(p: ActorRef => Boolean): List[ActorRef] = { + def filter(p: ActorRef => Boolean): Array[ActorRef] = { val all = new ListBuffer[ActorRef] val elements = actorsByUUID.elements while (elements.hasMoreElements) { @@ -78,35 +80,34 @@ object ActorRegistry extends ListenerManagement { all += actorId } } - all.toList + all.toArray } /** * Finds all actors that are subtypes of the class passed in as the Manifest argument. */ - def actorsFor[T <: Actor](implicit manifest: Manifest[T]): List[ActorRef] = + def actorsFor[T <: Actor](implicit manifest: Manifest[T]): Array[ActorRef] = actorsFor[T](manifest.erasure.asInstanceOf[Class[T]]) /** * Finds any actor that matches T. - * FIXME: Improve performance by breaking out after the first match */ def actorFor[T <: Actor](implicit manifest: Manifest[T]): Option[ActorRef] = - actorsFor[T](manifest).headOption + find(a => if(manifest.erasure.isAssignableFrom(a.actor.getClass)) Some(a) else None) /** * Finds all actors of type or sub-type specified by the class passed in as the Class argument. */ - def actorsFor[T <: Actor](clazz: Class[T]): List[ActorRef] = + def actorsFor[T <: Actor](clazz: Class[T]): Array[ActorRef] = filter(a => clazz.isAssignableFrom(a.actor.getClass)) /** * Finds all actors that has a specific id. */ - def actorsFor(id: String): List[ActorRef] = { + def actorsFor(id: String): Array[ActorRef] = { if (actorsById.containsKey(id)) { - actorsById.get(id).toArray.toList.asInstanceOf[List[ActorRef]] - } else Nil + actorsById.get(id).toArray(Naught) + } else Naught } /** diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/SampleUntypedActor.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SampleUntypedActor.java index 8040e1394f..ed8a67ab13 100644 --- a/akka-core/src/test/java/se/scalablesolutions/akka/actor/SampleUntypedActor.java +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/SampleUntypedActor.java @@ -36,7 +36,7 @@ public class SampleUntypedActor extends UntypedActor { } else if (msg.equals("ForwardMessage")) { // Retreive an actor from the ActorRegistry by ID and get an ActorRef back - ActorRef actorRef = ActorRegistry.actorsFor("some-actor-id").head(); + ActorRef actorRef = ActorRegistry.actorsFor("some-actor-id")[0]; // Wrap the ActorRef in an UntypedActorRef and forward the message to this actor UntypedActorRef.wrap(actorRef).forward(msg, self); From 774424afe31a3389382d39013aad396f807ee819 Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Tue, 3 Aug 2010 16:13:19 +0200 Subject: [PATCH 09/14] Closing ticket 367 --- project/build/AkkaProject.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/project/build/AkkaProject.scala b/project/build/AkkaProject.scala index e63bfc573f..02f72d7f0e 100644 --- a/project/build/AkkaProject.scala +++ b/project/build/AkkaProject.scala @@ -347,6 +347,8 @@ class AkkaParentProject(info: ProjectInfo) extends DefaultProject(info) { // testing val junit = Dependencies.junit val scalatest = Dependencies.scalatest + + override def bndImportPackage = "javax.transaction;version=1.1" :: super.bndImportPackage.toList } // ------------------------------------------------------------------------------------------------------------------- From 573c0bf1d5117bbdb12f393b7034a47930d42d4e Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Wed, 4 Aug 2010 10:45:29 +0200 Subject: [PATCH 10/14] Closing ticket 368 --- .../src/main/java/sample/rest/java/Boot.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/Boot.java b/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/Boot.java index cd382ae6ec..d9b41cd136 100644 --- a/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/Boot.java +++ b/akka-samples/akka-sample-rest-java/src/main/java/sample/rest/java/Boot.java @@ -15,10 +15,12 @@ public class Boot { new Component[] { new Component( SimpleService.class, + SimpleServiceImpl.class, new LifeCycle(new Permanent()), 1000), new Component( PersistentSimpleService.class, + PersistentSimpleServiceImpl.class, new LifeCycle(new Permanent()), 1000) }).supervise(); From 5168bb5caeb0cee3b855b6f4d85eef0ba998bfcd Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Wed, 4 Aug 2010 13:31:41 +0200 Subject: [PATCH 11/14] Uncommenting SSL support --- akka-core/src/main/scala/remote/RemoteServer.scala | 5 ++--- config/akka-reference.conf | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/akka-core/src/main/scala/remote/RemoteServer.scala b/akka-core/src/main/scala/remote/RemoteServer.scala index 5d25d81b75..db4490761b 100644 --- a/akka-core/src/main/scala/remote/RemoteServer.scala +++ b/akka-core/src/main/scala/remote/RemoteServer.scala @@ -76,8 +76,7 @@ object RemoteServer { } val SECURE = { - //TODO: Remove this when SSL is in working condition - /*if(config.getBool("akka.remote.ssl.service",false)){ + if(config.getBool("akka.remote.ssl.service",false)){ val properties = List( ("key-store-type" ,"keyStoreType"), @@ -98,7 +97,7 @@ object RemoteServer { true } - else */ + else false } diff --git a/config/akka-reference.conf b/config/akka-reference.conf index 33806c1d3d..3b80953fe6 100644 --- a/config/akka-reference.conf +++ b/config/akka-reference.conf @@ -76,7 +76,7 @@ akka { zlib-compression-level = 6 # Options: 0-9 (1 being fastest and 9 being the most compressed), default is 6 ssl { - service = off #on / off (THIS FEATURE IS NOT ACTIVATED YET, STAY TUNED) + service = off #on / off #You can either use java command-line options or use the settings below From e58e9b9fa2d459e27208f6155187b2becd48d04b Mon Sep 17 00:00:00 2001 From: rossputin Date: Wed, 4 Aug 2010 14:57:36 +0100 Subject: [PATCH 12/14] update run-akka script to use 2.8.0 final --- scripts/run_akka.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/run_akka.sh b/scripts/run_akka.sh index 2d87a08148..f2ededd90f 100755 --- a/scripts/run_akka.sh +++ b/scripts/run_akka.sh @@ -1,6 +1,6 @@ #!/bin/bash cd $AKKA_HOME -VERSION=akka_2.8.0.RC3-0.10 +VERSION=akka_2.8.0-0.10 TARGET_DIR=dist/$VERSION/$1 shift 1 VMARGS=$@ From c2a156d514d78ef486b7e643978b8fa142ebd06f Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Thu, 5 Aug 2010 12:04:32 +0200 Subject: [PATCH 13/14] Race condition should be patched now --- .../src/main/scala/actor/ActorRegistry.scala | 34 +++++++++++++------ .../ExecutorBasedEventDrivenDispatcher.scala | 2 +- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/akka-core/src/main/scala/actor/ActorRegistry.scala b/akka-core/src/main/scala/actor/ActorRegistry.scala index 63ddb939c7..905d1e7f2e 100644 --- a/akka-core/src/main/scala/actor/ActorRegistry.scala +++ b/akka-core/src/main/scala/actor/ActorRegistry.scala @@ -122,19 +122,30 @@ object ActorRegistry extends ListenerManagement { * Registers an actor in the ActorRegistry. */ def register(actor: ActorRef) = { - // UUID - actorsByUUID.put(actor.uuid, actor) - // ID val id = actor.id if (id eq null) throw new IllegalActorStateException("Actor.id is null " + actor) - if (actorsById.containsKey(id)) actorsById.get(id).add(actor) - else { - val set = new ConcurrentSkipListSet[ActorRef] - set.add(actor) - actorsById.put(id, set) + + //Tries to avoid a race-condition + def registerById(attemptNo: Int = 0,maxAttempts: Int = 10) { + if(attemptNo >= maxAttempts) + throw new IllegalStateException("Tried to add %s to the ActorRegistry %d times but failed.".format(actor,maxAttempts)) + val set = actorsById.get(id) + if(set ne null) + set.add(actor) + else { + val newSet = new ConcurrentSkipListSet[ActorRef] + newSet.add(actor) + if(actorsById.putIfAbsent(id,newSet) ne null) + registerById(attemptNo+1) + } } + registerById() + + // UUID + actorsByUUID.put(actor.uuid, actor) + // notify listeners foreachListener(_ ! ActorRegistered(actor)) } @@ -145,8 +156,11 @@ object ActorRegistry extends ListenerManagement { def unregister(actor: ActorRef) = { actorsByUUID remove actor.uuid - val id = actor.id - if (actorsById.containsKey(id)) actorsById.get(id).remove(actor) + val set = actorsById.get(actor.id) + if (set ne null) + set remove actor + + //FIXME: safely remove set if empty, leaks memory // notify listeners foreachListener(_ ! ActorUnregistered(actor)) diff --git a/akka-core/src/main/scala/dispatch/ExecutorBasedEventDrivenDispatcher.scala b/akka-core/src/main/scala/dispatch/ExecutorBasedEventDrivenDispatcher.scala index 836dc0ea86..1f03c1eba2 100644 --- a/akka-core/src/main/scala/dispatch/ExecutorBasedEventDrivenDispatcher.scala +++ b/akka-core/src/main/scala/dispatch/ExecutorBasedEventDrivenDispatcher.scala @@ -82,7 +82,7 @@ class ExecutorBasedEventDrivenDispatcher(_name: String, throughput: Int = Dispat override def register(actorRef: ActorRef) = { // The actor will need a ConcurrentLinkedDeque based mailbox - if( actorRef.mailbox == null ) { + if( actorRef.mailbox eq null ) { actorRef.mailbox = new ConcurrentLinkedDeque[MessageInvocation]() } super.register(actorRef) From 88053cf39a877134e175afeda5e3135de57dc6fb Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Thu, 5 Aug 2010 17:28:07 +0200 Subject: [PATCH 14/14] Added unit test to test for race-condition in ActorRegistry --- .../test/scala/misc/ActorRegistrySpec.scala | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/akka-core/src/test/scala/misc/ActorRegistrySpec.scala b/akka-core/src/test/scala/misc/ActorRegistrySpec.scala index d6fc463a65..61626e9db3 100644 --- a/akka-core/src/test/scala/misc/ActorRegistrySpec.scala +++ b/akka-core/src/test/scala/misc/ActorRegistrySpec.scala @@ -3,6 +3,7 @@ package se.scalablesolutions.akka.actor import org.scalatest.junit.JUnitSuite import org.junit.Test import Actor._ +import java.util.concurrent.{CyclicBarrier, TimeUnit, CountDownLatch} object ActorRegistrySpec { var record = "" @@ -214,4 +215,41 @@ class ActorRegistrySpec extends JUnitSuite { ActorRegistry.unregister(actor2) assert(ActorRegistry.actors.size === 0) } + + @Test def shouldBeAbleToRegisterActorsConcurrently { + ActorRegistry.shutdownAll + + val latch = new CountDownLatch(3) + val barrier = new CyclicBarrier(3) + + def mkTestActor(i:Int) = actorOf( new Actor { + self.id = i.toString + def receive = { case _ => } + }) + + def mkTestActors = for(i <- 1 to 10;j <- 1 to 1000) yield mkTestActor(i) + + def mkThread(actors: Iterable[ActorRef]) = new Thread { + start + override def run { + barrier.await + actors foreach { _.start } + latch.countDown + } + } + + val testActors1 = mkTestActors + val testActors2 = mkTestActors + val testActors3 = mkTestActors + + mkThread(testActors1) + mkThread(testActors2) + mkThread(testActors3) + + assert(latch.await(30,TimeUnit.SECONDS) === true) + + for(i <- 1 to 10) { + assert(ActorRegistry.actorsFor(i.toString).length === 3000) + } + } }