import os
import time
+import config
+import common
+import md5
+import ftptree
-CmdError="CmdError"
def parse(con):
if '\0' not in con.data:
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:
- locks[arg]=hard
- con.sock.send("OK")
- elif locks[arg]:
- con.sock.send("HARD") # Hard lock - you can go get a cup of tea
- else:
- con.sock.send("SOFT") # Soft lock - try in a second or two
-
-
+ 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)
-logfile=open(os.environ['HOME']+'/pld-ftp-admin/var/log', 'a')
+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.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
-cmdlist={'lcks':cmd_lock_soft, 'lckh':cmd_lock_hard, 'ulck':cmd_unlock,
- 'log1':cmd_log, 'name':cmd_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(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=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(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=md5.new(`time.time()`).hexdigest()