]> TLD Linux GIT Repositories - tld-ftp-admin.git/blob - modules/cmds.py
- non-integer releases are ok in TLD
[tld-ftp-admin.git] / modules / cmds.py
1 # vi: encoding=utf-8 ts=8 sts=4 sw=4 et
2
3 import os
4 import time
5 import config
6 import common
7 import hashlib
8 import ftptree
9
10
11 def parse(con):
12     if '\0' not in con.data:
13         return
14     cmds=con.data.split('\0')[:-1]
15
16     for cmd in cmds:
17         con.data=con.data[len(cmd)+1:]
18         cmdname=cmd[:4]
19         if not con.authorized and cmdname not in ('linp', 'linc', 'name'):
20             raise BailOut()
21             # TODO: log unauthorized access
22         if cmdname in cmdlist_noargs:
23             if len(cmd)==4:
24                 cmdlist_noargs[cmdname](con)
25             else:
26                 pass
27                 # TODO: log malicious msg
28         elif cmdname in cmdlist_args:
29             if len(cmd)>5:
30                 cmdlist_args[cmdname](con, cmd[5:])
31             else:
32                 pass
33                 # TODO: log malicious msg
34         else:
35             raise BailOut()
36             # TODO: log this
37
38 def lock(con, arg, hard):
39     if arg not in locks:
40         locks[arg]={'hard': hard, 'name': con.name, 'time': int(time.time())}
41         con.sock.send(bytearray("OK", encoding='utf-8'))
42     elif locks[arg]['hard']:
43         con.sock.send(bytearray("HARD", encoding='utf-8')) # Hard lock - you can go get a cup of tea
44     else:
45         con.sock.send(bytearray("SOFT", encoding='utf-8')) # Soft lock - try in a second or two
46
47 def cmd_unlock(con, arg):
48     if arg in locks:
49         del locks[arg]
50         con.sock.send(bytearray("OK", encoding='utf-8'))
51     else:
52         con.sock.send(bytearray("FAIL", encoding='utf-8'))
53
54 def cmd_lock_soft(con, arg):
55     lock(con, arg, False)
56
57 def cmd_lock_hard(con, arg):
58     lock(con, arg, True)
59
60 def cmd_show_locks(con):
61     cmd_log(con, "Dumping locks data:");
62     if len(locks):
63         res = ""
64         for lockdata in locks.items():
65             tree, data = lockdata
66             msg = "Tree: %s, Conn name: %s, Hard Lock: %s, Time: %s" % (
67                     tree, data['name'], data['hard'], time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(data['time'])))
68             cmd_log(con, msg)
69             res = res + msg
70 #        con.sock.send(bytearray("BLOB:%d" % len(res), encoding='utf-8')))
71         con.sock.send(bytearray(res, encoding='utf-8'))
72     else:
73         cmd_log(con, "No locks found.")
74         con.sock.send(bytearray("NLCK", encoding='utf-8'))
75
76 def cmd_log(con, msg):
77     logfile.write('%s [%s] -- %s\n' % (time.strftime('%Y-%m-%d %H:%M:%S'), con.name, msg))
78     logfile.flush()
79
80 def cmd_name(con, name):
81     con.name=name
82
83 def load_creds():
84     global users, cookies
85     users={}
86     cookies={}
87     if not common.fileexists(common.ftpadmdir+'/var/passwd'):
88         return
89     else:
90         f=open(common.ftpadmdir+'/var/passwd', 'r')
91         for line in f:
92             x=line.strip().split(':')
93             if len(x)>=2:
94                 users[x[0]]=x[1]
95         f.close()
96     if not common.fileexists(common.ftpadmdir+'/var/cookies'):
97         return
98     else:
99         f=open(common.ftpadmdir+'/var/cookies', 'r')
100         for line in f:
101             x=line.strip().split(':')
102             if len(x)>=2:
103                 users[x[0]]=x[1]
104         f.close()
105
106 def write_cookies():
107     f=open(common.ftpadmdir+'/var/cookies', 'w')
108     for key in cookies.keys():
109         f.write('%s:%s\n' % (key, cookies[key]))
110     f.close()
111
112 def cmd_login_passwd(con, data):
113     tmp=data.split('\n')
114     if len(tmp)!=2:
115         raise BailOut()
116     login=tmp[0]
117     passwd=tmp[1]
118     md5pass=hashlib.md5(passwd.encode('utf-8')).hexdigest()
119     if login in users and users[login] == md5pass:
120         fullpass = md5pass+salt
121         cookie=repr(time.time()).split('.')[0]+'_'+hashlib.md5(fullpass.encode('utf-8')).hexdigest()
122         cookies[cookie]=login
123         write_cookies()
124         con.username=login
125         con.authorized=True
126         con.sock.send(bytearray('OK '+cookie, encoding='utf-8'))
127     else:
128         # TODO: log this
129         con.sock.send(bytearray('FAIL', encoding='utf-8'))
130         raise BailOut()
131
132 def cmd_login_cookie(con, cookie):
133     if cookie in cookies:
134         con.cookie=cookie
135         con.authorized=True
136         con.username=cookies[cookie]
137         con.sock.send(bytearray('OK '+cookies[cookie], encoding='utf-8'))
138     else:
139         # TODO: log this (or not)
140         con.sock.send(bytearray('FAIL'))
141
142 def cmd_logout(con):
143     if con.cookie in cookies:
144         del cookies[con.cookie]
145         write_cookies()
146
147 def reloadftptree():
148     global srctree, pkglist
149     srctree=ftptree.FtpTree(config.value['default_to'], loadall=True)
150     pkglist=sorted(srctree.keys())
151
152 def cmd_gettree(con):
153     buf=''
154     for pkgnvr in pkglist:
155         # TODO: show only user's own pkgs
156         pkg=srctree[pkgnvr]
157         line=pkgnvr
158         if pkg.marked4moving:
159             line=line+'\n1'
160         else:
161             line=line+'\n0'
162         if pkg.marked4removal:
163             line=line+'\n1'
164         else:
165             line=line+'\n0'
166         buf=buf+'\0'+line
167     if buf:
168         con.sock.send(bytearray('%.6d' % (len(buf)-1), encoding='utf-8'))
169         con.sock.send(bytearray(buf[1:], encoding='utf-8'))
170     else:
171         con.sock.send(bytearray('000000', encoding='utf-8'))
172
173
174 cmdlist_args={'lcks':cmd_lock_soft, 'lckh':cmd_lock_hard, 'ulck':cmd_unlock,
175          'log1':cmd_log, 'name':cmd_name, 'linp':cmd_login_passwd,
176          'linc':cmd_login_cookie}
177
178 cmdlist_noargs={'lout':cmd_logout, 'gett':cmd_gettree, 'slck':cmd_show_locks}
179
180 # Global stuff and initializations
181
182 BailOut="BailOut"
183 locks={}
184 logfile=open(common.ftpadmdir+'/var/log', 'a')
185 load_creds()
186 reloadftptree()
187 salt=hashlib.md5(repr(time.time()).encode('utf-8')).hexdigest()
188