one-file-projects/fakeftp.py
2013-08-21 05:24:38 +02:00

117 lines
2.6 KiB
Python

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()