Some fixes :3

This commit is contained in:
trollhase 2013-08-23 07:45:53 +02:00
parent c968cf1e64
commit aa0a319234

View file

@ -23,13 +23,24 @@ def mask(rights):
return m
def _r( (u,g,o) ):
return ( (u&7) << 6 ) + ( (g&7) << 3 ) + (o&7)
class FSNode:
def __init__(self,name,owner="nobody",group="nobody",rights=384,size=0, iun=1):
def __init__(self,name,owner="nobody",group="nobody",rights=(6,4,4),size=0, iun=1):
self.name = name
self.owner = owner
self.group = group
self.rights = rights
if type(rights) == tuple and len(rights) == 3:
self.rights = _r( rights )
elif type(rights) == int:
self.rights = rights
else:
self.rights = _r( (6,4,4) )
self.size = size
self.parent = None
self.iun = iun
@ -95,7 +106,7 @@ class FSNode:
return p
class Directory(FSNode):
def __init__(self,name,owner="nobody",group="nobody",rights=384,size=4096,files=[]):
def __init__(self,name,owner="nobody",group="nobody",rights=(6,4,4),size=4096,files=[]):
FSNode.__init__(self, name=name, owner=owner, group=group,rights=rights, size=size, iun=randint(2,10))
self.files = files
@ -258,8 +269,12 @@ class WelcomeMessage(FTPMessage):
FTPMessage.__init__(self,"220","FTP Server ready")
class EnteringPassiveModeMessage(FTPMessage):
def __init__(self,addrtuple):
FTPMessage.__init__(self,"227","Entering Passive Mode %s." % addrtuple)
def __init__(self,(ip,port)):
addr = ip.split(".")
addr.append( str( (port >> 8) & 0xFF ) )
addr.append( str( port & 0xFF ) )
FTPMessage.__init__(self,"227","Entering Passive Mode (%s)." % (",".join(addr) ) )
class BeginDirectoryListingMessage(FTPMessage):
def __init__(self):
@ -309,6 +324,22 @@ class EndFileRetrieve(FTPMessage):
def __init__(self):
FTPMessage.__init__(self,"226","Transfer complete")
class UnableToBuildConnectionMessage(FTPMessage):
def __init__(self):
FTPMessage.__init__(self,"425","Unable to build data connection")
class CommandNotAllowedInAscii(FTPMessage):
def __init__(self,cmd):
FTPMessage.__init__(self,"550","%s not allowed in ASCII mode")
class AbortSuccessfulMessage(FTPMessage):
def __init__(self):
FTPMessage.__init__(self,"226","Abort successful")
class SystemTypeMessage(FTPMessage):
def __init__(self, sys="UNIX",typ="L8"):
FTPMessage.__init__(self,"215","%s Type: %s" % ( sys.upper(), typ ))
# Data Connection Handler
class NListHandler:
def __init__(self, directory, handler):
@ -358,6 +389,7 @@ class State:
class MainState(State):
def process(self, handler, message):
if message.cmd == "QUIT":
handler.debug( "Quitting" )
handler.send( QuitMessage() )
handler.running = False
else:
@ -366,6 +398,7 @@ class MainState(State):
class NonAuthorizedState(MainState):
def process(self, handler, message):
if message.cmd == "USER":
handler.debug("Setting user to %s" % message.parameter)
handler.user = message.parameter
handler.state = AuthorizingState()
handler.send( PasswordRequiredMessage(handler.user) )
@ -374,69 +407,81 @@ class NonAuthorizedState(MainState):
class AuthorizingState(MainState):
def process(self, handler, message):
if message.cmd == "PASS":
if message.cmd == "USER":
handler.debug("Changing user to %s" % message.parameter)
handler.user = message.parameter
handler.send( PasswordRequiredMessage(handler.user) )
elif message.cmd == "PASS":
password = message.parameter
if handler.authorizer.authorize(handler.user, password, handler):
handler.debug("User login %s successful" % handler.user)
handler.debug("User login %s successful using password %s" % (handler.user,password))
handler.state = AuthorizedState()
handler.send( AuthorizationSuccessfulMessage() )
else:
handler.debug("User login %s failed" % handler.user)
handler.debug("User login %s failed using password %s" % (handler.user, password) )
handler.state = NonAuthorizedState()
handler.send( AuthorizationFailedMessage() )
else:
MainState.process(self, handler, message)
class AuthorizedState(MainState):
def addrtuple(self, ip, port):
b = ip.split(".")
b.append( str( (port >> 8) & 0xFF ) )
b.append( str( port & 0xFF ) )
return "(" + ",".join(b)+ ")"
def process(self, handler, message):
if message.cmd == "PASV":
port = handler.createPassiveDataConnection()
addr = handler.createPassiveDataConnection()
handler.debug("Created passive data connection")
handler.send( EnteringPassiveModeMessage( self.addrtuple("127.0.0.1",port) ) )
elif message.cmd in ["DELE","RMD","RNFR","RNTO","STOR"]:
handler.send( EnteringPassiveModeMessage( addr ) )
elif message.cmd == "DELE":
handler.debug( "Attempt to delete file %s" % message.parameter )
handler.send( OperationNotPermittedMessage() )
elif message.cmd == "RMD":
handler.debug( "Attempt to delete directory %s" % message.parameter )
handler.send( OperationNotPermittedMessage() )
elif message.cmd == "RNFR":
handler.debug( "Attempt to rename %s" % message.parameter )
handler.send( OperationNotPermittedMessage() )
elif message.cmd == "RNTO":
handler.debug( "Attempt to rename to %s" % message.parameter )
handler.send( OperationNotPermittedMessage() )
elif message.cmd == "STOR":
handler.debug( "Attempt to store a file %s" % message.parameter )
handler.send( OperationNotPermittedMessage() )
elif message.cmd == "RETR":
node = handler.get_node(message.parameter)
if node.is_file():
handler.runDataConnection( RetrieveHandler(node, handler) )
if handler.runDataConnection( RetrieveHandler(node, handler) ):
handler.debug( "Retrieving file %s" % message.parameter )
else:
handler.send( UnableToBuildConnectionMessage() )
else:
handler.send( OperationNotPermittedMessage() )
elif message.cmd == "PORT":
hp = message.parameter.split(",")
if len(hp) != 6:
handler.debug( "Invalid port information" )
handler.send( InvalidParametersMessage() )
return
if int(hp[0]) == 10 or int(hp[0]) == 127 or int(hp[0]) == 192: #Prevent local scanning
handler.debug( "Attempt to port to local network." )
handler.send( InvalidPortCommandMessage() )
return
addr = ( ".".join(hp[:4]), int(hp[4])<<8+int(hp[5]) )
handler.createActiveDataConnection(addr)
handler.debug( "Creating active data connection to %s:%d" % addr )
handler.debug("Created active data connection to %s:%d" % addr)
handler.createActiveDataConnection(addr)
handler.send( CommandSuccessfulMessage("PORT") )
elif message.cmd == "LIST":
handler.debug("Listing current directory")
if handler.runDataConnection(ListHandler(handler.currentDirectory, handler)):
handler.debug("successful")
handler.debug("Listing current directory")
else:
handler.debug("failed")
handler.send( UnableToBuildConnectionMessage() )
elif message.cmd == "NLST":
handler.debug("Listing current directory (simple)")
if handler.runDataConnection(NListHandler(handler.currentDirectory)):
handler.debug("successful")
handler.debug("Listing current directory (simple)")
else:
handler.debug("failed")
handler.send( UnableToBuildConnectionMessage() )
elif message.cmd == "CWD":
node = handler.get_node(message.parameter)
if node is None or not node.is_dir():
@ -449,20 +494,33 @@ class AuthorizedState(MainState):
elif message.cmd == "CDUP":
node = handler.currentDirectory.get_parent_directory()
if node is None or not node.is_dir():
handler.debug("Error trying to switch to parent directory")
handler.debug("Error trying to switch to non-existent parent directory")
else:
handler.debug("Changed working directory to "+node.get_absolute_path())
handler.currentDirectory = node
handler.send( ChangeDirectorySuccessfulMessage() )
elif message.cmd == "PWD":
handler.debug( "Printing working directory" )
handler.send( WorkingDirectoryMessage(handler.currentDirectory.get_absolute_path()) )
elif message.cmd == "TYPE":
if message.parameter == "A":
handler.debug("Setting type to ASCII")
handler.send( TypeSetMessage(message.parameter) )
else:
handler.debug("Unrecognized type %s" % message.parameter)
handler.send( InvalidCommandMessage("TYPE") )
elif message.cmd == "NOOP":
handler.debug("No operation")
handler.send( CommandSuccessfulMessage("NOOP") )
elif message.cmd == "SIZE":
handler.debug("Requested size of %s" % message.parameter)
handler.send( CommandNotAllowedInAscii("SIZE") )
elif message.cmd == "ABOR":
handler.debug("Aborting data connection")
handler.send( AbortSuccessfulMessage() )
elif message.cmd == "SYST":
handler.debug("Requested system type")
handler.send( SystemTypeMessage() )
else:
MainState.process(self, handler, message)
@ -488,14 +546,13 @@ class FTPHandler(SocketServer.BaseRequestHandler):
print ("[%s] " % self.client_address[0]) + text
def send(self, message):
line = str(message)
self.debug("< "+line)
self.request.send( line )
self.request.send( str(message) )
def createPassiveDataConnection(self):
port = randint(60000,63000)
self.connection = PassiveDataConnection(port)
return port
myaddr = self.request.getsockname()
return (myaddr[0],port)
def createActiveDataConnection(self,addr):
self.connection = ActiveDataConnection(addr)
@ -553,7 +610,6 @@ class FTPHandler(SocketServer.BaseRequestHandler):
linereader.push(data)
for line in linereader.get_lines():
self.debug("> "+line)
message = FTPMessage.parse(line)
self.state.process(self,message)