# MFR 0.5 # (c) 2006 ruxkor [at] sf.net # Released under the MIT Licence. For more info go to http://mfr.sf.net # prework import time #wg time.asctime() <-- uhrzeit import os import string import re from twisted.internet import reactor from twisted.internet.protocol import Protocol, Factory, ClientCreator #globals servers = {} users = {} class Inifile(object): def __init__(self): self.infos = {} self.actserverlist = [] def readini(self,myini): try: daini = open(myini) rawinidata = daini.read() daini.close() return rawinidata except IOError: return None def parseini(self,myini='mfr.ini'): theini = self.readini(myini) inilist = [] if theini != None: inilist = theini.splitlines() for i in inilist: if i[:13] == 'remactserver=': self.actserverlist.append(i[13:]) elif i[:1] == '#' or i == '': pass elif i.find('=') != -1: whats, data = i.split('=',1) self.infos[whats] = data else: raise 'invalid data found in ini: '+i else: raise 'no ini found!' class FakeFTP(Protocol): def __init__(self): self.whostring = '' self.remserver = '' self.remuname = '' self.rempasswd = '' self.clientip = '' self.clientport = 0 self.curdir = '/' self.dirlisting = '' self.portcmdstring = '' self.proxymode = False def sendMessage(self,msg): self.transport.write(msg+'\r\n') print self,'sent:',msg def connectionMade(self): print 'Got connection from', self.transport.client self.transport.write('220 '+theini.infos['servername']+"\r\n") def connectionLost(self, reason): print self.transport.client, 'disconnected' #einbringen: disconnecten vom server! def dataReceived(self, data): print self,'received:',data,'proxymode:',self.proxymode if self.proxymode == False: self.parseftpdata(data) else: #proxymodus servers[self.remserver].sendMessage(self.whostring+' '+data) def parseftpdata(self,ftpdata): for data in ftpdata.splitlines(): if data != '': try: command, rest = data.split(' ',1) except: data += ' ' command, rest = data.split(' ',1) rest = rest.strip() if command == 'USER': self.remuname = rest self.sendMessage('331 gotcha, but i need a password.') elif command == 'PASS': self.rempasswd = rest self.sendMessage('230 logged in.') elif command == 'SYST': self.sendMessage('215 UNIX Type: L8') elif command == 'PWD': self.sendMessage('257 "'+self.curdir+'" is the current directory.') elif command == 'PASV': self.sendMessage('500 not good passive won\'t work afterwards either..') elif command == 'TYPE': self.sendMessage('200 yeah.. whatever.') elif command == 'PORT': self.sendMessage('200 yeah now THIS is the right thing to do.') self.clientip = '' self.portcmdstring = rest pos = rest.rfind(',',0,rest.rfind(',')) for i in rest[:pos].split(','): self.clientip += i+'.' self.clientip = self.clientip[:-1] arest = rest[pos+1:] tmplist = arest.split(',') self.clientport = int(tmplist[0])*256+int(tmplist[1]) elif command == 'LIST': if self.clientip == '': self.sendMessage('500 need a PORT command from you first. Please change to ACTIVE.') else: self.sendMessage('150 Listing Directory.') self.sendfakedirlist() elif command == 'CWD': self.sendMessage('200 Switching to Proxy Mode: Trying to access '+rest) self.remserver = rest if self.enterproxymode(rest) == True: self.sendMessage('200 Now in Proxy Mode with '+rest+'. Awaiting Authentication Response.') else: self.sendMessage('500 Proxy Mode failed.') else: self.sendMessage('500 command not implemented. you sent: command sent:"'+command+'", parameter(s): "'+rest+'".') def enterproxymode(self,remserver): try: ip, port = self.transport.client self.whostring = self.remuname+'@'+ip users[self.whostring] = self servers[remserver].sendMessage(self.whostring+' CONNECT '+self.remuname+' '+self.rempasswd+' '+self.portcmdstring) except: return False return True def sendfakedirlist(self): cip=self.clientip cport=self.clientport print cip,cport self.dirlisting = '' for name in servers: self.dirlisting += 'drwxr-xr-x 21 0 0 4096 Jan 05 10:01 '+name+'\r\n' c = ClientCreator(reactor, FileLister) c.connectTCP(cip, cport).addCallback(self.gotProtocol) def gotProtocol(self,p): p.sendMessage(self.dirlisting+'\n') #p.transport.loseConnection() self.sendMessage('226 Directory send OK.') def proxymodus(self,data): pass class FileLister(Protocol): def sendMessage(self,msg): #msg = 'drwxrwxr-x 21 1000 100 768 Mar 29 15:47 ahaha\n' self.transport.write(msg+'\r\n') self.transport.loseConnection() class ClientListener(Protocol): def connectionMade(self): print 'Server Connection from', self.transport.client def sendMessage(self,msg): self.transport.write(msg+'\r\n') print self,'sent:',msg def connectionLost(self, reason): print 'Server', self.transport.client, 'disconnected!' #einbringen: disconnecten vom server! def dataReceived(self, data): for i in data.splitlines(): if i.strip() != '': #data = data.splitlines()[0] print self,'received:',i who, command = i.split(' ',1) if who == 'MYSELF': comm, rest = command.split(' ',1) if comm == 'IAM': servers[rest] = self print 'added new server: ', servers else: if command == 'LOGIN OK': users[who].sendMessage('220 Proxymode successfully enabled. Please refresh.') users[who].proxymode = True elif command == 'ERROR': users[who].sendMessage('500 Some Error. Proxymode disabled. Please reconnect.') users[who].proxymode = False else: users[who].sendMessage(command) #main thing connectedclients = {} theini = Inifile() theini.parseini() print theini.infos,"\n",theini.actserverlist fakeftpfac = Factory() listenerfac = Factory() fakeftpfac.protocol = FakeFTP listenerfac.protocol = ClientListener reactor.listenTCP(int(theini.infos['pubftpport']), fakeftpfac) reactor.listenTCP(int(theini.infos['clientconport']), listenerfac) reactor.run()