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