package com.tylerstonge.honeypot.ftp import java.io.File import java.net.InetSocketAddress import java.nio.file.{Files, Paths, StandardOpenOption} import java.util.UUID import akka.actor.{Actor, ActorRef, Props} import akka.event.{Logging, LoggingAdapter} import akka.io.Tcp._ import akka.io.{IO, Tcp} import akka.util.{ByteString, ByteStringBuilder} object FtpFileReceiver { def props(port: Int, controller: ActorRef): Props = Props(new FtpFileReceiver(port, controller)) } class FtpFileReceiver(port: Int, controller: ActorRef) extends Actor { val log: LoggingAdapter = Logging(context.system, this) IO(Tcp)(context.system) ! Bind(self, new InetSocketAddress("127.0.0.1", port)) val fileData: ByteStringBuilder = ByteString.newBuilder val name: String = UUID.randomUUID().toString override def postStop { log.debug("shutting down") } override def receive: Receive = { case Bound(localAddress) => log.info("listening on {}", localAddress) case CommandFailed(_: Bind) => context.stop(self) case Connected(_, _) => val connection = sender() connection ! Register(self) context.become { case Received(data) => log.info("read {} bytes", data.length) fileData.addAll(data) case PeerClosed => log.debug("peer closed connection, writing file to disk") val out = Files.newByteChannel(new File("C:\\Users\\dropkick\\Documents\\dev\\honeypot\\" + this.name).toPath, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE) out.write(fileData.result().toByteBuffer) out.close() controller.tell(Write(ByteString.apply("226 File transferred.\n")), context.parent) context.stop(self) case msg@_ => log.warning("unknown message: {}", msg) } } }