package com.tylerstonge.honeypot.ftp import akka.actor.{Actor, ActorRef, Props} import akka.event.{Logging, LoggingAdapter} import akka.io.Tcp.{PeerClosed, Received, Write} import akka.util.ByteString import com.tylerstonge.honeypot.messages.{MFoundPassword, MFoundUsername} import scala.util.Random object FtpHandler { def props(client: ActorRef): Props = Props(new FtpHandler(client)) } class FtpHandler(client: ActorRef) extends Actor { val log: LoggingAdapter = Logging(context.system, this) var fileReceiver: ActorRef = ActorRef.noSender override def receive: Receive = { case Received(data) => client ! Write(ByteString.apply(parse(sanitize(data)))) case PeerClosed => log.debug("peer closed connection") context.stop(self) } def parse(msg: Array[String]): String = msg(0) match { case "user" => log.debug("attempted login with username: {}", msg(1)) context.system.eventStream.publish(MFoundUsername(msg(1))) "331 Please specify password.\n" case "pass" => log.debug("attempted login with password: {}", msg(1)) context.system.eventStream.publish(MFoundPassword(msg(1))) "230 Login successful.\n" case "pwd" => "257 \"/\" is the current directory\n" case "quit" => "221 Goodbye.\n" case "pasv" => log.debug("entering passive mode") val r = new Random() val p1 = r.nextInt(200) val p2 = r.nextInt(200) fileReceiver = context.actorOf(FtpFileReceiver.props(p1 * 256 + p2, client), name = "passive-connection-" + (p1 * 256 + p2)) Thread.sleep(256) "227 entering passive mode (127,0,0,1," + p1 + "," + p2 + ")\n" case "stor" => log.debug("stor: {}", msg(1)) fileReceiver ! SetName(msg(1)) "150 File status okay; about to open data connection.\n" case _ => log.debug("unsupported command received: {}", msg.mkString(" ")) "451 Requested action aborted. Local error in processing.\n" } def sanitize(data: ByteString): Array[String] = { data.utf8String.trim.toLowerCase().split(" ") } def getHostname(msg: String): String = { val split = msg.split(",") split.slice(0, 4).mkString(".") } def getPort(msg: String): Int = { val split = msg.split(",") split(4).toInt * 256 + split(5).toInt } }