def request_authentication(username, sock, sip, sport): a = util.get_random_number() A = util.get_public_ephemeral(a) msg = encrypt_message(username, A) #print("A: %s, a: %s, msg: %s") %(A, a, msg) # start a thread that only handles receipt of messages #start_new_thread(receiveMessages, (sock,)) send_msg_to_server(sock, msg, sip, sport) '''
def get_params(uname, A, s): try: if uname and A: b = util.get_random_number() p = client_store[uname] x = util.H(s, uname, p) N, g = util.get_ng() v = pow(g, x, N) k = util.get_K() B = (k*v + pow(g, b, N)) % N return B, v, b else: print(' Please enter valid username and password ') except Exception as e: print(' Invalid username password entered... ')
def request_authentication(username, sock, sip, sport, password): a = util.get_random_number() A = util.get_public_ephemeral(a) message = {} message.update({'username': username}) message.update({'A': A}) try: msg = util.encrypt_message_PSK(message, SERVER_KEY) except Exception as e: print "An error occured while encrypting the text message - ", message, "! %s" %e try: #start_new_thread(receiveMessages, (sock,)) sock.connect((sip, int(sport))) send_message(sock, msg, sip, sport) progress[username] = 1 t1 = Thread(target=receiveMessages, args=(sock, username, sip, sport, A, password, a)) t1.start() t1.join() if(EXIT_IN_ERROR): sys.exit() except ServerConnectionBroken: print 'Connection broken !!' sys.exit()
def non_blocking_listen(server, current_username): global USERNAME_TO_PORT global CHAT_NONCE global shared_key global g global p global a global df_keys global message_tracker global IV_tracker global df_progress global port_tracker udp_socket = create_udp_socket() udp_socket.bind(server.getsockname()) read_sockets = [server, sys.stdin, udp_socket] write_sockets = [] message_queue = {} timeout = 30 try: while(read_sockets): #print("Waiting for read/write event...") readable, writable, exceptional = select.select(read_sockets, write_sockets, read_sockets, timeout) for s in readable: if s == sys.stdin: command = s.readline().strip() if command.lower() == 'list' or command.lower() == 'logout': global ACTION_NONCE ACTION_NONCE = util.get_random_number() message = {} message.update({'ACTION': command.upper()}) message.update({'username': current_username}) message.update({'NONCE': ACTION_NONCE}) try: final_kas = util.MD5_HASH(shared_key) to_send = util.encrypt_message_KAS(message, final_kas, GENERATED_IV) except Exception as e: print "An error occured while encrypting the text message for ACTION. ", message, "! %s" %e send_message(server, to_send, sip, sport) # you are A if command.split(" ")[0] == "send": chat_text = command.split(" ")[1:] sender_username = chat_text[0] message_tracker[sender_username] = ' '.join(chat_text) #udp_socket.sendto(' '.join(chat_text[1:]),('localhost',int(USERNAME_TO_PORT[sender_username]))) # update CHAT_NONCE = util.get_random_number() message = {} message.update({'ACTION': 'CHAT'}) message.update({'A': current_username}) message.update({'B': sender_username}) message.update({'NONCE': CHAT_NONCE}) try: final_kas = util.MD5_HASH(shared_key) to_send = util.encrypt_message_KAS(message, final_kas, GENERATED_IV) except Exception as e: print "An error occured while encrypting the text message for ACTION. ", message, "! %s" %e send_message(server, to_send, sip, sport) # update ends if s is server and s != sys.stdin: data = s.recv(40960) if data: pickled_data = pickle.loads(data) #print("Received data - %s from %s" %(pickled_data, s.getpeername())) hash_shared_key = util.MD5_HASH(shared_key) response = util.decrypt_using_Kas(pickled_data, hash_shared_key, GENERATED_IV) d = ast.literal_eval(response) valid = False if(str(d['ACTION']).strip() == 'LIST'): list_message = d['MESSAGE'] list_of_users = [] if type(list_message) == str: print list_message else: print "~~~~~~~~~~~~~ Online Users ~~~~~~~~~~~~~" for item in list_message: username = item[0] portip = item[1] port = portip.split(":")[1] USERNAME_TO_PORT.update({username:int(port)}) print username print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" valid = True if(str(d['ACTION']).strip() == 'LOGOUT'): received_nonce = d['MESSAGE'] if(long(received_nonce) + 1 == ACTION_NONCE): print "Confirming logout" valid = True if valid: challenge_nonce = d['NONCE'] decrement_nonce = long(challenge_nonce) - 1 try: final_kas = util.MD5_HASH(shared_key) to_send = util.encrypt_message_KAS(decrement_nonce, final_kas, GENERATED_IV) except Exception as e: print "An error occured while encrypting the text message for ACTION. ", message, "! %s" %e send_message(server, to_send, sip, sport) if(str(d['ACTION']).strip() == 'LOGOUT'): server.close() for s in read_sockets: if s != sys.stdin: s.close() for s in write_sockets: s.close() #sys.exit() #message_queue[s].put(pickled_data) # update starts # you are A if(str(d['ACTION']).strip() == 'CHAT'): ticket = d['TICKET'] b_port = d['B_PORT'] b_ip = d['B_IP'] b_pk = d['B_PK'] b_iv = d['B_IV'] b = d['B'] IV_tracker[b] = b_iv port_tracker[b] = int(b_port) nonce = d['NONCE'] new_challenge = d['CHALLENGE'] if(long(nonce) + 1 == long(CHAT_NONCE)): message = {} message.update({'TICKET': ticket}) message.update({'NONCE': new_challenge}) a = random.randint(1, 9) A = (g**a) % p message.update({'A': A}) message.update({'g': g}) message.update({'p': p}) try: msg = util.encrypt_with_PSK(message, b_pk) #pickled_msg = pickle.dumps(msg) except Exception as e: print "An error occured while encrypting the text message - ", message, "! %s" %e protocol_identity = {} protocol_identity.update({'CIPHER': msg}) protocol_identity.update({'PROTOCOL': 'PUBLIC_KEY'}) pickled_msg = pickle.dumps(protocol_identity) udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 18000) udp_socket.sendto(pickled_msg,('localhost',int(b_port))) # update ends else: print("Connection closed") if s in write_sockets: write_sockets.remove(s) read_sockets.remove(s) close_socket(s) del message_queue[s] elif s == udp_socket: # update begins msg = s.recvfrom(30000) if msg: pickled_data = pickle.loads(msg[0]) protocol = pickled_data['PROTOCOL'] cipher = pickled_data['CIPHER'] if(protocol == 'PUBLIC_KEY'): # You are user B cipher2, e_iv , e_sym_key = extract_cipher_data(cipher) decrypted_data = decrypt(cipher2, e_iv, e_sym_key) if(decrypted_data.has_key('A')): A = long(decrypted_data['A']) g = long(decrypted_data['g']) p = long(decrypted_data['p']) ticket = decrypted_data['TICKET'] nonce = decrypted_data['NONCE'] b = random.randint(100, 999) B = (g**b) % p b_shared_key = (A**b) % p hash_shared_key = util.MD5_HASH(shared_key) response = util.decrypt_using_Kas(ticket, hash_shared_key, GENERATED_IV) d = ast.literal_eval(response) message = {} message.update({'B': B}) # B's username message.update({'username': current_username}) a_pk = d['A_PK'] a_ip = d['A_IP'] a_port = d['A_PORT'] # A's username username = d['A'] ticket_nonce = d['NONCE'] if long(nonce) == long(ticket_nonce): df_keys[username] = str(b_shared_key) df_progress[current_username] = (2, username) try: msg = util.encrypt_with_PSK(message, a_pk) #pickled_msg = pickle.dumps(msg) except Exception as e: print "An error occured while encrypting the text message - ", message, "! %s" %e protocol_identity = {} protocol_identity.update({'PROTOCOL': 'PUBLIC_KEY'}) protocol_identity.update({'CIPHER': msg}) pickled_msg = pickle.dumps(protocol_identity) #udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 20000) udp_socket.sendto(pickled_msg,('localhost',int(a_port))) else: # you are user A if(decrypted_data.has_key('B')): B = long(decrypted_data['B']) # B's username username = decrypted_data['username'] ds_shared_key = (B ** a) % p df_keys[username] = str(ds_shared_key) B_IV = IV_tracker[username] B_port = port_tracker[username] message_to_send = message_tracker[username] hmac_msg = util.get_hmac(message_to_send, B_IV) to_send_dict = {} to_send_dict.update({'MESSAGE': message_to_send}) to_send_dict.update({'HMAC': hmac_msg}) try: final_kas = util.MD5_HASH(df_keys[username]) to_send = util.encrypt_message_KAS(to_send_dict, final_kas, B_IV) except Exception as e: print "An error occured while encrypting the text message for CHAT. ", message, "! %s" %e protocol_identity = {} protocol_identity.update({'PROTOCOL': 'SESSION_KEY'}) protocol_identity.update({'CIPHER': to_send}) pickled_msg = pickle.dumps(protocol_identity) udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 20000) udp_socket.sendto(pickled_msg,('localhost',int(B_port))) if(protocol == 'SESSION_KEY'): # you are user B progress_tuple = df_progress[current_username] if (progress_tuple[0] == 2): b_username = progress_tuple[1] hash_shared_key = util.MD5_HASH(str(df_keys[b_username])) response = util.decrypt_using_Kas(cipher, hash_shared_key, GENERATED_IV) d = ast.literal_eval(response) msg_received = d['MESSAGE'] msg_hmac = d['HMAC'] util.verify_with_hmac(msg_received, msg_hmac, GENERATED_IV) print msg_received del df_progress[current_username] # update ends for s in writable: try: next_msg = message_queue[s].get_nowait() to_send = pickle.dumps(next_msg) except Queue.Empty: print("Queue Empty") write_sockets.remove(s) else: print("Sending message - %s to %s" %(to_send, s.getpeername())) s.send(to_send) for s in exceptional: print("Exceptional condition occurred for user - %s" %(s.getpeername())) read_sockets.remove(s) if s in write_sockets: write_sockets.remove(s) close_socket(s) del message_queue[s] except KeyboardInterrupt: "Inside KeyboardInterrupt!!!!!!!!" server.close() for s in read_sockets: if s != sys.stdin: s.close() for s in write_sockets: s.close() sys.exit() except: print 'Closing client .....' server.close() for s in read_sockets: if s != sys.stdin: s.close() for s in write_sockets: s.close() sys.exit()
def receiveMessages(sock, username, sip, sport, A, password, a): while(1): try: # try to receive messages from the server msg = sock.recv(40960) # changed here akshay if msg != '': msg1 = pickle.loads(msg) #print("Received message:%s" %(msg1)) status = progress[username] if(status == 1): if(msg1 == 'ERROR'): global EXIT_IN_ERROR EXIT_IN_ERROR = True sys.exit() value = find_value_from_hash(msg1) send_message(sock, value, sip, sport) progress[username] = 2 if(status == 2): challenge_pk_data = {} data_for_kas = {} final_to_server = {} global shared_key shared_key = compute_shared_key(A, msg1, username, password, a) final_kas = util.MD5_HASH(shared_key) challenge = util.get_random_number() global NONCE_SENT NONCE_SENT = challenge data_for_kas.update({'CHALLENGE': challenge , 'PK_CLIENT': CLIENT_PUBLIC_KEY_STR}) Kas_encrypted_data = util.encrypt_message_KAS(data_for_kas, final_kas, GENERATED_IV) # add IV here challenge_pk_data.update({'CHALLENGE_PK': Kas_encrypted_data, 'CHALLENGE': challenge, 'IV': GENERATED_IV}) data_to_server = util.encrypt_message_PSK(challenge_pk_data, SERVER_KEY) send_message(sock, data_to_server, sip, sport) progress[username] = 3 if(status == 3): hash_shared_key = util.MD5_HASH(shared_key) nonce = util.decrypt_using_Kas(msg1, hash_shared_key, GENERATED_IV) incremented_nonce = long(nonce) + 1 if incremented_nonce == NONCE_SENT: print ("Login Success !") return True else: print("Authentication pending!") return False else: print("Connection with server is broken...") sys.exit() except KeyboardInterrupt: sock.close() # handling socket errors except socket.error, s_error: sock.close() error_code = s_error[0] error_message = s_error[1] print('Error in reading messages: ', error_code, ' - ', error_message) except Exception as e: print('Error occured:', e) sock.close() sys.exit()
def non_blocking_listen(server): server.listen(5) read_sockets = [server] write_sockets = [] message_queue = {} timeout = 30 load_client_vault() try: while(read_sockets): readable, writable, exceptional = select.select(read_sockets, write_sockets, read_sockets, timeout) for s in readable: if s is server: conn, client_address = s.accept() print("Received connection - %s from %s" %(conn, client_address)) conn.setblocking(0) read_sockets.append(conn) message_queue[conn] = Queue.Queue() client_progress[conn] = (1,) else: data = s.recv(40960) if data: pickled_data = pickle.loads(data) status = client_progress[s] if(status[0] == 1): #A, username = parse_data(pickled_data) cipher, e_iv , e_sym_key = extract_cipher_data(pickled_data) decrypted_data = decrypt(cipher, e_iv, e_sym_key) A = str(decrypted_data["A"]) username = str(decrypted_data["username"]) if(not logged_users.has_key(username)): num = util.get_random_challenge() hashed_num = util.get_hash(num) message_queue[s].put(hashed_num) # num is added so u can check in the next step that value sent by client is same as num client_progress[s] = (2, A, username, num) else: print 'User: %s is already logged in!' %(username) message_queue[s].put('ERROR') if(status[0] == 2): salt = util.get_random_number() #Salt user_tuple = client_progress[s] username = user_tuple[2] numCheck = user_tuple[3] if user_tuple[1] and user_tuple[2] and pickled_data == numCheck: salt_and_B_dict = {} A = user_tuple[1] B, v, b = get_params(user_tuple[2], user_tuple[1], salt) u = util.H(A,B) signed_salt = util.sign_document(private_key, str(salt).encode()) signed_B = util.sign_document(private_key, str(B).encode()) salt_and_B_dict.update({'SALT': salt}) salt_and_B_dict.update({'SIGNED_SALT': signed_salt}) salt_and_B_dict.update({'B': B}) salt_and_B_dict.update({'SIGNED_B': signed_B}) message_queue[s].put(salt_and_B_dict) Kas = util.get_server_shared_key(A, v, u, b) client_progress[s] = (3, util.MD5_HASH(Kas), username) if(status[0] == 3): user_tuple = client_progress[s] cipher, e_iv , e_sym_key = extract_cipher_data(pickled_data) decrypted_data = decrypt(cipher, e_iv, e_sym_key) Challenge_PK = decrypted_data['CHALLENGE_PK'] IV = decrypted_data['IV'] final_decrypted_data = util.decrypt_using_Kas(Challenge_PK, user_tuple[1], IV) d= ast.literal_eval(final_decrypted_data) if str(d['CHALLENGE']) == str(decrypted_data['CHALLENGE']): print 'Challenge matches' #global logged_users client_ip = s.getpeername()[0] client_port = s.getpeername()[1] ip_port = str(client_ip) + ":" + str(client_port) logged_users[username] = (user_tuple[1], s, d['PK_CLIENT'],ip_port, IV) # ................. else: print 'Challenge does not match' nonce = d['CHALLENGE'] subtracted_nonce = long(nonce) - 1 #iv = os.urandom(16) encrypted_nonce = util.encrypt_message_KAS(str(subtracted_nonce), user_tuple[1], IV) message_queue[s].put(encrypted_nonce) client_progress[s] = (4, util.MD5_HASH(Kas), username, IV) if(status[0] == 4): user_tuple = client_progress[s] IV = user_tuple[3] final_decrypted_data = util.decrypt_using_Kas(pickled_data, user_tuple[1], IV) d= ast.literal_eval(final_decrypted_data) if(type(d) != long): valid = False if(action_progress.has_key(s)): action_status = action_progress[s] status_2 = action_status[1] valid = (status_2 == 3) else: valid = True if (valid): if(d['ACTION'] == 'LIST'): A_ip_port = '' all_users = [] for username, value in logged_users.items(): if not username == d['username']: A_ip_port = value[3] all_users.append((username, A_ip_port)) if len(all_users) == 0: all_users = 'No user is online currently' action_challenge = util.get_random_number() user_list = {} user_list.update({'MESSAGE': all_users}) user_list.update({'NONCE': action_challenge}) user_list.update({'ACTION': 'LIST'}) final_kas = user_tuple[1] try: to_send = util.encrypt_message_KAS(user_list, final_kas, IV) except: print "An error occured while encrypting the text message for ACTION. ", message, "! %s" %e message_queue[s].put(to_send) action_progress[s] = ('LIST', 2, action_challenge) if(d['ACTION'] == 'LOGOUT'): user_to_remove = d['username'] challenge_received = d['NONCE'] decrement_nonce = long(challenge_received) - 1 new_nonce = util.get_random_number() user_list = {} user_list.update({'MESSAGE': decrement_nonce}) user_list.update({'NONCE': new_nonce}) user_list.update({'ACTION': 'LOGOUT'}) final_kas = user_tuple[1] try: to_send = util.encrypt_message_KAS(user_list, final_kas, IV) except: print "An error occured while encrypting the text message for ACTION. ", message, "! %s" %e message_queue[s].put(to_send) action_progress[s] = ('LOGOUT', 2, new_nonce) # UPDATE START if(d['ACTION'] == 'CHAT'): A_ipport = '' B_ipport = '' A_PK = '' B_PK = '' Kbs = '' Kas = '' for username, value in logged_users.items(): if username == d['A']: A_ipport = value[3] Kas = value[0] A_PK = str(value[2]) if username == d['B']: B_ipport = value[3] Kbs = value[0] B_PK = value[2] A_IP = A_ipport.split(":")[0] A_PORT = A_ipport.split(":")[1] username_A = d['A'] N6 = util.get_random_number() TICKET = {} ticket_and_stuff = {} TICKET.update({'A_PORT':A_PORT}) TICKET.update({'A_IP':A_IP}) TICKET.update({'A_PK':A_PK}) TICKET.update({'A':username_A}) TICKET.update({'NONCE':N6}) final_kas = user_tuple[1] username_B = str(d['B']) # use B's IV login_tuple = logged_users[username_B] B_IV = login_tuple[4] Kbs_encrypted_ticket = util.encrypt_message_KAS(TICKET, Kbs, B_IV) N4 = d['NONCE'] B_IP = B_ipport.split(":")[0] B_PORT = B_ipport.split(":")[1] N4_minus_1 = long(N4) - 1 ticket_and_stuff.update({'TICKET':Kbs_encrypted_ticket}) ticket_and_stuff.update({'B_PORT':B_PORT}) ticket_and_stuff.update({'B_IP':B_IP}) ticket_and_stuff.update({'B_PK':B_PK}) ticket_and_stuff.update({'NONCE':N4_minus_1}) ticket_and_stuff.update({'CHALLENGE':N6}) ticket_and_stuff.update({'ACTION':'CHAT'}) ticket_and_stuff.update({'B_IV': B_IV}) ticket_and_stuff.update({'B': username_B}) Kas_final_encrypt = util.encrypt_message_KAS(ticket_and_stuff, Kas, IV) message_queue[s].put(Kas_final_encrypt) #UPDATE END else: action_status = action_progress[s] if(action_status[1] == 2 and action_status[0] == 'LIST'): action_progress[s] = (action_status[0], 3) if(action_status[1] == 2 and action_status[0] == 'LOGOUT'): earlier_nonce = action_status[2] if(long(final_decrypted_data) == long(earlier_nonce) - 1): print ' deleting user info ' del logged_users[user_to_remove] print 'Deleting user: '******' Did not receive logout confirmation ' else: print 'Message ignored' #message_queue[s].put(pickled_data) if s not in write_sockets: write_sockets.append(s) else: if (client_progress.has_key(s)): client_status = client_progress[s] if(client_status[0] > 1): print("Connection closed ...... !") del logged_users[client_status[2]] print 'Deleting user: '******'Closing server .....' server.close() for s in read_sockets: s.close() for s in write_sockets: s.close()