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
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
15 def get_bytes(num_bytes):
\r
17 for n in xrange(num_bytes):
\r
18 ret.append( chr(random.randint(0,255)) )
\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
29 expected_response = md5.new(users[username] + challenge).digest()
\r
30 if response != expected_response:
\r
36 def login(chan, username, password):
\r
38 challenge = chan.recv()
\r
39 response = md5.new(password + challenge).digest()
\r
41 return chan.recv() == "OKAY"
\r