Skip to content

Instantly share code, notes, and snippets.

Created November 18, 2014 11:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/728431fe467a36caac4a to your computer and use it in GitHub Desktop.
Save anonymous/728431fe467a36caac4a to your computer and use it in GitHub Desktop.
import java.io.File
import javax.net.ssl.SSLHandshakeException
import com.typesafe.scalalogging.Logger
import org.jboss.netty.channel._
import org.jboss.netty.channel.group.ChannelGroup
import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder
import org.jboss.netty.handler.codec.string.{StringDecoder, StringEncoder}
import org.jboss.netty.handler.ssl.SslHandler
import org.slf4j.LoggerFactory
class ServerPipelineFactory(channels: ChannelGroup, certFileDir: String, password: String) extends ChannelPipelineFactory {
def getPipeline = {
val pipeline = Channels.pipeline
val serverKeyStore = new File(s"$certFileDir/server.keystore")
val serverTrustStore = new File(s"$certFileDir/server.truststore")
val sslManager = new SslManager(serverKeyStore, serverTrustStore, password, password)
val engine = sslManager.createSSLEngine(client = false)
pipeline.addLast("ssl", new SslHandler(engine))
pipeline.addLast("framer", new LineBasedFrameDecoder(8192, true, false))
pipeline.addLast("decoder", new StringDecoder)
pipeline.addLast("encoder", new StringEncoder)
pipeline.addLast("handler", new ServerHandler(channels))
pipeline
}
}
class ServerHandler(channels: ChannelGroup) extends SimpleChannelUpstreamHandler {
val logger = Logger(LoggerFactory.getLogger("server"))
override def handleUpstream(ctx: ChannelHandlerContext, e: ChannelEvent) {
super.handleUpstream(ctx, e)
}
override def channelConnected(ctx: ChannelHandlerContext, e: ChannelStateEvent) {
val sslHandler: SslHandler = ctx.getPipeline.get(classOf[SslHandler])
val handshakeFuture: ChannelFuture = sslHandler.handshake
handshakeFuture.addListener(new SecureConnectionEstablishedListener())
}
override def channelDisconnected(ctx: ChannelHandlerContext, e: ChannelStateEvent) {
logger.info(s"channel from ${ctx.getChannel.getRemoteAddress} disconnected")
channels.remove(e.getChannel)
}
override def exceptionCaught(ctx: ChannelHandlerContext, e: ExceptionEvent) {
e.getCause match {
case ssl: SSLHandshakeException =>
logger.warn(s"failed to establish secure connection with message: ${ssl.getMessage}")
case oe =>
logger.warn("exception caught", oe)
}
e.getChannel.close()
}
class SecureConnectionEstablishedListener extends ChannelFutureListener {
def operationComplete(future: ChannelFuture) {
if (future.isSuccess) {
logger.info(s"channel from ${future.getChannel.getRemoteAddress} connected")
channels.add(future.getChannel)
}
else {
// SSLException handled in exceptionCaught
future.getChannel.close()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment