From 54e1e9b5c808882a4029eee6cd4aec05ec66edee Mon Sep 17 00:00:00 2001 From: trollhase Date: Wed, 21 Aug 2013 05:24:38 +0200 Subject: [PATCH] Fakeftp server --- fakeftp.py | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 fakeftp.py diff --git a/fakeftp.py b/fakeftp.py new file mode 100644 index 0000000..8930886 --- /dev/null +++ b/fakeftp.py @@ -0,0 +1,117 @@ +import SocketServer + +class FTPMessage: + def __init__(self,cmd,parameter): + self.cmd = cmd + self.parameter = parameter + + def generate(self): + return "%s %s\r\n" % (self.cmd.upper(), self.parameter) + + def __str__(self): + return self.generate() + + @staticmethod + def parse(line): + pos = line.find(" ") + if pos == -1: + cmd = line + param = None + else: + cmd = line[:pos] + param = line[pos+1:] + return FTPMessage(cmd.upper(),param) + +class GeneralState: + @staticmethod + def handle(self, message): + if message.cmd == "QUIT": + self.debug("Client wants to quit") + self.send(FTPMessage("221","Goodbye.")) + self.handler.running = False + else: + self.debug("Unknown command %s" % message.cmd) + self.send(FTPMessage("500", "%s not understood" % message.cmd )) + +class UserState: + @staticmethod + def handle(self, message): + if message.cmd == "USER": + self.debug("Initiating login for user %s" % message.parameter) + self.send(FTPMessage("331","Password required for %s" % message.parameter)) + self.state = PassState + else: + GeneralState.handle(self, message) + +class PassState: + @staticmethod + def handle(self, message): + if message.cmd == "PASS": + self.debug("Denying access with password %s" % message.parameter) + self.send(FTPMessage("530","Login incorrect.")) + self.state = UserState + else: + GeneralState.handle(self, message) + +class FTPMessageHandler: + def __init__(self, handler): + self.state = UserState + self.handler = handler + + def send(self,data): + return self.handler.request.send( str(data) ) + + def debug(self,text): + self.handler.debug(text) + + def handle(self, message): + self.state.handle(self, message) + +class LineReader: + def __init__(self): + self.buf = "" + + def push(self,data): + self.buf += data + + def get_lines(self): + pos = self.buf.find("\n") + while pos != -1: + line = self.buf[:pos] + if line[-1] == "\r": + line = line[:-2] + yield line + self.buf = self.buf[pos+1:] + pos = self.buf.find("\n") + +class FTPHandler(SocketServer.BaseRequestHandler): + def debug(self, text): + print ("[%s] " % self.client_address[0]) + text + + def handle(self): + self.messagehandler = FTPMessageHandler(self) + + self.debug("Client connected"); + + self.request.send(FTPMessage("220","FTP Server ready").generate()) + + linereader = LineReader() + + self.running = True + + while self.running: + data = self.request.recv(1024) + if len(data) == 0: + break + + linereader.push(data) + + for line in linereader.get_lines(): + message = FTPMessage.parse(line) + self.messagehandler.handle(message) + + self.debug("Client disconnected") + +server = SocketServer.ThreadingTCPServer(("",1234),FTPHandler) + +server.serve_forever() \ No newline at end of file