Initial import of Rpyc library. License is public domain, so it's no problem.
[monitor.git] / Rpyc / Authentication.py
1 """\r
2 Challenge-Response authentication algorithm over channels: the client sends the\r
3 username, recvs a challenge, generates a response based on the challenge and \r
4 password, sends it back to the server, which also calculates the expected response.\r
5 the server returns "WRONG" or "OKAY". this way the password is never sent over\r
6 the wire.\r
7 \r
8 * servers should call the accept function over a channel, with a dict of \r
9 (username, password) pairs.\r
10 * clients should call login over a channel, with the username and password\r
11 """\r
12 import md5\r
13 import random\r
14 \r
15 def get_bytes(num_bytes):\r
16         ret = []\r
17         for n in xrange(num_bytes):\r
18                 ret.append( chr(random.randint(0,255)) )\r
19         return ''.join(ret)\r
20 \r
21 def accept(chan, users):\r
22     username = chan.recv()\r
23     challenge = get_bytes(16)\r
24     chan.send(challenge)\r
25     response = chan.recv()\r
26     if username not in users:\r
27         chan.send("WRONG")\r
28         return False\r
29     expected_response = md5.new(users[username] + challenge).digest()\r
30     if response != expected_response:\r
31         chan.send("WRONG")\r
32         return False\r
33     chan.send("OKAY")\r
34     return True\r
35 \r
36 def login(chan, username, password):\r
37     chan.send(username)\r
38     challenge = chan.recv()\r
39     response = md5.new(password + challenge).digest()\r
40     chan.send(response)\r
41     return chan.recv() == "OKAY"\r
42 \r