Fakeftp server
This commit is contained in:
commit
54e1e9b5c8
1 changed files with 117 additions and 0 deletions
117
fakeftp.py
Normal file
117
fakeftp.py
Normal file
|
@ -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()
|
Loading…
Reference in a new issue