]> git.pld-linux.org Git - projects/pld-ftp-admin.git/blobdiff - modules/cmds.py
Send and receive bytes over sockets (python3 compat)
[projects/pld-ftp-admin.git] / modules / cmds.py
index 46bb55b286bcadc746246305615841229700164e..e7dc879a474800700082832dca2810f0e4251982 100644 (file)
@@ -2,8 +2,11 @@
 
 import os
 import time
+import config
+import common
+import md5
+import ftptree
 
-CmdError="CmdError"
 
 def parse(con):
     if '\0' not in con.data:
@@ -13,27 +16,40 @@ def parse(con):
     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)
@@ -41,16 +57,132 @@ def cmd_lock_soft(con, arg):
 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()
 
This page took 0.098628 seconds and 4 git commands to generate.