]>
Commit | Line | Data |
---|---|---|
e3aced8e MM |
1 | # vi: encoding=utf-8 ts=8 sts=4 sw=4 et |
2 | ||
459e7d48 MM |
3 | import os |
4 | import time | |
88d4cb67 MM |
5 | import config |
6 | import common | |
27e913d5 | 7 | import hashlib |
08b49edd | 8 | import ftptree |
459e7d48 | 9 | |
459e7d48 | 10 | |
e3aced8e MM |
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] | |
08b49edd | 19 | if not con.authorized and cmdname not in ('linp', 'linc', 'name'): |
9c170c61 | 20 | raise BailOut() |
5fcf3f9a | 21 | # TODO: log unauthorized access |
6992b18d MM |
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 | |
e3aced8e | 34 | else: |
9c170c61 | 35 | raise BailOut() |
e3aced8e MM |
36 | # TODO: log this |
37 | ||
e3aced8e MM |
38 | def lock(con, arg, hard): |
39 | if arg not in locks: | |
135e7889 | 40 | locks[arg]={'hard': hard, 'name': con.name, 'time': int(time.time())} |
8d9e1014 | 41 | con.sock.send(bytearray("OK", encoding='utf-8')) |
135e7889 | 42 | elif locks[arg]['hard']: |
8d9e1014 | 43 | con.sock.send(bytearray("HARD", encoding='utf-8')) # Hard lock - you can go get a cup of tea |
e3aced8e | 44 | else: |
8d9e1014 | 45 | con.sock.send(bytearray("SOFT", encoding='utf-8')) # Soft lock - try in a second or two |
461bc5ab | 46 | |
b55905f2 | 47 | def cmd_unlock(con, arg): |
e3aced8e MM |
48 | if arg in locks: |
49 | del locks[arg] | |
8d9e1014 | 50 | con.sock.send(bytearray("OK", encoding='utf-8')) |
6b4b841a | 51 | else: |
8d9e1014 | 52 | con.sock.send(bytearray("FAIL", encoding='utf-8')) |
e3aced8e | 53 | |
b55905f2 | 54 | def cmd_lock_soft(con, arg): |
e3aced8e MM |
55 | lock(con, arg, False) |
56 | ||
b55905f2 | 57 | def cmd_lock_hard(con, arg): |
e3aced8e MM |
58 | lock(con, arg, True) |
59 | ||
6b4b841a AM |
60 | def cmd_show_locks(con): |
61 | cmd_log(con, "Dumping locks data:"); | |
62 | if len(locks): | |
461bc5ab | 63 | res = "" |
2ec96333 | 64 | for lockdata in locks.items(): |
6b4b841a | 65 | tree, data = lockdata |
461bc5ab ER |
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 | |
8d9e1014 JR |
70 | # con.sock.send(bytearray("BLOB:%d" % len(res), encoding='utf-8'))) |
71 | con.sock.send(bytearray(res, encoding='utf-8')) | |
6b4b841a | 72 | else: |
8d9e1014 JR |
73 | cmd_log(con, "No locks found.") |
74 | con.sock.send(bytearray("NLCK", encoding='utf-8')) | |
459e7d48 | 75 | |
b55905f2 | 76 | def cmd_log(con, msg): |
461bc5ab | 77 | logfile.write('%s [%s] -- %s\n' % (time.strftime('%Y-%m-%d %H:%M:%S'), con.name, msg)) |
459e7d48 | 78 | logfile.flush() |
e3aced8e | 79 | |
b55905f2 MM |
80 | def cmd_name(con, name): |
81 | con.name=name | |
82 | ||
88d4cb67 MM |
83 | def load_creds(): |
84 | global users, cookies | |
85 | users={} | |
86 | cookies={} | |
304fcc79 | 87 | if not common.fileexists(common.ftpadmdir+'/var/passwd'): |
88d4cb67 MM |
88 | return |
89 | else: | |
304fcc79 | 90 | f=open(common.ftpadmdir+'/var/passwd', 'r') |
f09b8024 | 91 | for line in f: |
88d4cb67 MM |
92 | x=line.strip().split(':') |
93 | if len(x)>=2: | |
94 | users[x[0]]=x[1] | |
95 | f.close() | |
304fcc79 | 96 | if not common.fileexists(common.ftpadmdir+'/var/cookies'): |
88d4cb67 MM |
97 | return |
98 | else: | |
304fcc79 | 99 | f=open(common.ftpadmdir+'/var/cookies', 'r') |
f09b8024 | 100 | for line in f: |
88d4cb67 MM |
101 | x=line.strip().split(':') |
102 | if len(x)>=2: | |
103 | users[x[0]]=x[1] | |
104 | f.close() | |
105 | ||
106 | def write_cookies(): | |
304fcc79 | 107 | f=open(common.ftpadmdir+'/var/cookies', 'w') |
88d4cb67 MM |
108 | for key in cookies.keys(): |
109 | f.write('%s:%s\n' % (key, cookies[key])) | |
110 | f.close() | |
111 | ||
6992b18d MM |
112 | def cmd_login_passwd(con, data): |
113 | tmp=data.split('\n') | |
114 | if len(tmp)!=2: | |
9c170c61 | 115 | raise BailOut() |
6992b18d MM |
116 | login=tmp[0] |
117 | passwd=tmp[1] | |
27e913d5 JR |
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() | |
88d4cb67 MM |
122 | cookies[cookie]=login |
123 | write_cookies() | |
08b49edd | 124 | con.username=login |
88d4cb67 | 125 | con.authorized=True |
8d9e1014 | 126 | con.sock.send(bytearray('OK '+cookie, encoding='utf-8')) |
6992b18d MM |
127 | else: |
128 | # TODO: log this | |
8d9e1014 | 129 | con.sock.send(bytearray('FAIL', encoding='utf-8')) |
9c170c61 | 130 | raise BailOut() |
6992b18d MM |
131 | |
132 | def cmd_login_cookie(con, cookie): | |
88d4cb67 MM |
133 | if cookie in cookies: |
134 | con.cookie=cookie | |
135 | con.authorized=True | |
08b49edd | 136 | con.username=cookies[cookie] |
8d9e1014 | 137 | con.sock.send(bytearray('OK '+cookies[cookie], encoding='utf-8')) |
6992b18d MM |
138 | else: |
139 | # TODO: log this (or not) | |
8d9e1014 | 140 | con.sock.send(bytearray('FAIL')) |
6992b18d MM |
141 | |
142 | def cmd_logout(con): | |
88d4cb67 MM |
143 | if con.cookie in cookies: |
144 | del cookies[con.cookie] | |
145 | write_cookies() | |
08b49edd MM |
146 | |
147 | def reloadftptree(): | |
148 | global srctree, pkglist | |
149 | srctree=ftptree.FtpTree(config.value['default_to'], loadall=True) | |
f09b8024 | 150 | pkglist=sorted(srctree.keys()) |
08b49edd MM |
151 | |
152 | def cmd_gettree(con): | |
153 | buf='' | |
85f3481a | 154 | for pkgnvr in pkglist: |
08b49edd | 155 | # TODO: show only user's own pkgs |
85f3481a MM |
156 | pkg=srctree[pkgnvr] |
157 | line=pkgnvr | |
5d490a9c MM |
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 | |
08b49edd | 167 | if buf: |
8d9e1014 JR |
168 | con.sock.send(bytearray('%.6d' % (len(buf)-1), encoding='utf-8')) |
169 | con.sock.send(bytearray(buf[1:], encoding='utf-8')) | |
08b49edd | 170 | else: |
8d9e1014 | 171 | con.sock.send(bytearray('000000', encoding='utf-8')) |
08b49edd | 172 | |
6992b18d MM |
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 | ||
6b4b841a | 178 | cmdlist_noargs={'lout':cmd_logout, 'gett':cmd_gettree, 'slck':cmd_show_locks} |
6992b18d | 179 | |
88d4cb67 MM |
180 | # Global stuff and initializations |
181 | ||
182 | BailOut="BailOut" | |
183 | locks={} | |
304fcc79 | 184 | logfile=open(common.ftpadmdir+'/var/log', 'a') |
88d4cb67 | 185 | load_creds() |
08b49edd | 186 | reloadftptree() |
27e913d5 | 187 | salt=hashlib.md5(repr(time.time()).encode('utf-8')).hexdigest() |
e3aced8e | 188 |