# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+import os
+import time
+import config
+import common
+import md5
+import ftptree
+
+
def parse(con):
if '\0' not in con.data:
return
for cmd in cmds:
con.data=con.data[len(cmd)+1:]
cmdname=cmd[:4]
- if cmdname in cmdlist:
- cmdlist[cmdname](con, cmd[5:])
+ 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 CmdError
+ raise BailOut
# TODO: log this
-locks={}
def lock(con, arg, hard):
if arg not in locks:
con.sock.send("SOFT") # Soft lock - try in a second or two
-def unlock(con, arg):
+def cmd_unlock(con, arg):
if arg in locks:
del locks[arg]
-def lock_soft(con, arg):
+def cmd_lock_soft(con, arg):
lock(con, arg, False)
-def lock_hard(con, arg):
+def cmd_lock_hard(con, arg):
lock(con, arg, True)
-CmdError="CmdError"
-cmdlist={'lcks':lock_soft, 'lckh':lock_hard, 'ulck':unlock}
+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.xreadlines():
+ 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.xreadlines():
+ 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=md5.new(passwd).hexdigest()
+ if login in users and users[login]==md5pass:
+ cookie=`time.time()`.split('.')[0]+'_'+md5.new(md5pass+salt).hexdigest()
+ cookies[cookie]=login
+ write_cookies()
+ con.username=login
+ con.authorized=True
+ con.sock.send('OK '+cookie)
+ else:
+ # TODO: log this
+ con.sock.send('FAIL')
+ 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('OK '+cookies[cookie])
+ else:
+ # TODO: log this (or not)
+ con.sock.send('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=srctree.keys()
+ pkglist.sort()
+
+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('%.6d' % (len(buf)-1))
+ con.sock.send(buf[1:])
+ else:
+ con.sock.send('000000')
+
+
+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}
+
+# Global stuff and initializations
+
+BailOut="BailOut"
+locks={}
+logfile=open(common.ftpadmdir+'var/log', 'a')
+load_creds()
+reloadftptree()
+salt=md5.new(`time.time()`).hexdigest()