# vi: encoding=utf-8 ts=8 sts=4 sw=4 et import os import time import config import common import hashlib import ftptree def parse(con): if '\0' not in con.data: return cmds=con.data.split('\0')[:-1] for cmd in cmds: con.data=con.data[len(cmd)+1:] cmdname=cmd[:4] if not con.authorized and cmdname not in ('linp', 'linc', 'name'): raise BailOut() # TODO: log unauthorized access if cmdname in cmdlist_noargs: if len(cmd)==4: cmdlist_noargs[cmdname](con) else: pass # TODO: log malicious msg elif cmdname in cmdlist_args: if len(cmd)>5: cmdlist_args[cmdname](con, cmd[5:]) else: pass # TODO: log malicious msg else: raise BailOut() # TODO: log this def lock(con, arg, hard): if arg not in locks: locks[arg]={'hard': hard, 'name': con.name, 'time': int(time.time())} con.sock.send(bytearray("OK", encoding='utf-8')) elif locks[arg]['hard']: con.sock.send(bytearray("HARD", encoding='utf-8')) # Hard lock - you can go get a cup of tea else: con.sock.send(bytearray("SOFT", encoding='utf-8')) # Soft lock - try in a second or two def cmd_unlock(con, arg): if arg in locks: del locks[arg] con.sock.send(bytearray("OK", encoding='utf-8')) else: con.sock.send(bytearray("FAIL", encoding='utf-8')) def cmd_lock_soft(con, arg): lock(con, arg, False) def cmd_lock_hard(con, arg): lock(con, arg, True) def cmd_show_locks(con): cmd_log(con, "Dumping locks data:"); if len(locks): res = "" for lockdata in locks.items(): tree, data = lockdata msg = "Tree: %s, Conn name: %s, Hard Lock: %s, Time: %s" % ( tree, data['name'], data['hard'], time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(data['time']))) cmd_log(con, msg) res = res + msg # con.sock.send(bytearray("BLOB:%d" % len(res), encoding='utf-8'))) con.sock.send(bytearray(res, encoding='utf-8')) else: cmd_log(con, "No locks found.") con.sock.send(bytearray("NLCK", encoding='utf-8')) def cmd_log(con, msg): logfile.write('%s [%s] -- %s\n' % (time.strftime('%Y-%m-%d %H:%M:%S'), con.name, msg)) logfile.flush() def cmd_name(con, name): con.name=name def load_creds(): global users, cookies users={} cookies={} if not common.fileexists(common.ftpadmdir+'/var/passwd'): return else: f=open(common.ftpadmdir+'/var/passwd', 'r') for line in f: x=line.strip().split(':') if len(x)>=2: users[x[0]]=x[1] f.close() if not common.fileexists(common.ftpadmdir+'/var/cookies'): return else: f=open(common.ftpadmdir+'/var/cookies', 'r') for line in f: x=line.strip().split(':') if len(x)>=2: users[x[0]]=x[1] f.close() def write_cookies(): f=open(common.ftpadmdir+'/var/cookies', 'w') for key in cookies.keys(): f.write('%s:%s\n' % (key, cookies[key])) f.close() def cmd_login_passwd(con, data): tmp=data.split('\n') if len(tmp)!=2: raise BailOut() login=tmp[0] passwd=tmp[1] md5pass=hashlib.md5(passwd.encode('utf-8')).hexdigest() if login in users and users[login] == md5pass: fullpass = md5pass+salt cookie=repr(time.time()).split('.')[0]+'_'+hashlib.md5(fullpass.encode('utf-8')).hexdigest() cookies[cookie]=login write_cookies() con.username=login con.authorized=True con.sock.send(bytearray('OK '+cookie, encoding='utf-8')) else: # TODO: log this con.sock.send(bytearray('FAIL', encoding='utf-8')) raise BailOut() def cmd_login_cookie(con, cookie): if cookie in cookies: con.cookie=cookie con.authorized=True con.username=cookies[cookie] con.sock.send(bytearray('OK '+cookies[cookie], encoding='utf-8')) else: # TODO: log this (or not) con.sock.send(bytearray('FAIL')) def cmd_logout(con): if con.cookie in cookies: del cookies[con.cookie] write_cookies() def reloadftptree(): global srctree, pkglist srctree=ftptree.FtpTree(config.value['default_to'], loadall=True) pkglist=sorted(srctree.keys()) def cmd_gettree(con): buf='' for pkgnvr in pkglist: # TODO: show only user's own pkgs pkg=srctree[pkgnvr] line=pkgnvr if pkg.marked4moving: line=line+'\n1' else: line=line+'\n0' if pkg.marked4removal: line=line+'\n1' else: line=line+'\n0' buf=buf+'\0'+line if buf: con.sock.send(bytearray('%.6d' % (len(buf)-1), encoding='utf-8')) con.sock.send(bytearray(buf[1:], encoding='utf-8')) else: con.sock.send(bytearray('000000', encoding='utf-8')) cmdlist_args={'lcks':cmd_lock_soft, 'lckh':cmd_lock_hard, 'ulck':cmd_unlock, 'log1':cmd_log, 'name':cmd_name, 'linp':cmd_login_passwd, 'linc':cmd_login_cookie} cmdlist_noargs={'lout':cmd_logout, 'gett':cmd_gettree, 'slck':cmd_show_locks} # Global stuff and initializations BailOut="BailOut" locks={} logfile=open(common.ftpadmdir+'/var/log', 'a') load_creds() reloadftptree() salt=hashlib.md5(repr(time.time()).encode('utf-8')).hexdigest()