def send_server_step1(socket, ident, data, key_iv, log_in_list): try: sender_name = data.Sender_name target = data.Chat_to print ("%s wants to chat with %s" %(sender_name, target)) key = key_iv[ident][0] iv = key_iv[ident][1] flag = 0 for name in log_in_list: # check name is logged in or not if name == data.Chat_to: target_port_number = log_in_list[name][1] target_ident = log_in_list[name][0] flag = 1 if flag == 0: # Offline response send_request2 = protobuf_pb2.MyProtocol() send_request2.TypeNumber = 0 send_request2.Type = "Send" send_request2.Sender_name = data.Sender_name send_request2.Chat_to = data.Chat_to send_request2.Error = "The user is off line" send_request2_en = util.aes_en(key, iv, send_request2.SerializeToString()) socket.send_multipart([ident, send_request2_en]) return 0 else: # Success response key1 = key_iv[target_ident][0] iv1 = key_iv[target_ident][1] ticket_to_client = protobuf_pb2.MyProtocol() ticket_to_client.TypeNumber = 51 ticket_to_client.Type = "ticket1" ticket_to_client.Sender_name = data.Sender_name ticket_en = util.aes_en(key1, iv1, ticket_to_client.SerializeToString()) send_request2 = protobuf_pb2.MyProtocol() send_request2.TypeNumber = 42 send_request2.Type = "Send" send_request2.Sender_name = data.Sender_name send_request2.Chat_to = data.Chat_to send_request2.Port = int(target_port_number) send_request2.Ticket = ticket_en.encode('base-64') send_request2_en = util.aes_en(key, iv, send_request2.SerializeToString()) socket.send_multipart([ident, send_request2_en]) return 1 except: # Error response send_request2 = protobuf_pb2.MyProtocol() send_request2.TypeNumber = 0 send_request2.Type = "Send" send_request2.Sender_name = data.Sender_name send_request2.Chat_to = data.Chat_to send_request2.Error = "Send Part 1 Error happen" send_request2_en = util.aes_en(key, iv, send_request2.SerializeToString()) socket.send_multipart([ident, send_request2_en]) return 0
def check_heartbeat_time(heartbeat, log_in_list, key_iv): while(True): time.sleep(300) now = time.time() for ident in heartbeat: if now - heartbeat[ident][1] > 2000: # 2000s logout_user = heartbeat[ident][0] print ("%s will expired because of lost of heartbeat" %(logout_name)) for name1 in log_in_list: # check name in list ident1 = log_in_list[name1][0] if name1 == logout_user: continue cha2 = random.randint(1,10001) logout_request.C2 = cha2 flag = 0 while flag == 0: key1 = key_iv[ident1][0] iv1 = key_iv[ident1][1] send_message = util.aes_en(key1, iv1, logout_request.SerializeToString()) socket.send_multipart([ident1, send_message]) logout_res = socket.recv_multipart() logout_res_de = util.rsa_de(logout_res[1]) logout_response = protobuf_pb2.MyProtocol() logout_response.ParseFromString(logout_res_de) if logout_response.TypeNumber == 101: if logout_response.C2 == cha2 + 1: flag = 1 del log_in_list[logout_user] print ("%s have logged off" %(data.Sender_name))
def list_server(socket, ident, data, reply, key_iv, log_in_list): try: print("%s wants to list" %(data.Sender_name)) key = key_iv[ident][0] iv = key_iv[ident][1] listname = "Logged in: " for name in log_in_list: # print log in list listname = listname + name + " " reply.TypeNumber = 32 reply.Note = listname cha2 = random.randint(1,10001) reply.C2 = cha2 s_msg = util.aes_en(key, iv, reply.SerializeToString()) socket.send_multipart([ident, s_msg]) except: # Error key = key_iv[ident][0] iv = key_iv[ident][1] reply.TypeNumber = 0 reply.Note = "List Error happen" reply.Key = "0" reply.Error = "List Error happen" s_msg = util.aes_en(key, iv, reply.SerializeToString()) socket.send_multipart([ident, s_msg]) else: # confirm receive list_rq3 = socket.recv_multipart() list_rq3_de = util.rsa_de(list_rq3[1]) list_request3 = protobuf_pb2.MyProtocol() list_request3.ParseFromString(list_rq3_de) if list_request3.C2 == cha2: print 'List complete'
def send_server_step2(socket, ident, data, key_iv, log_in_list): try: key = key_iv[ident][0] iv = key_iv[ident][1] for name in log_in_list: # get the ident of target if name == data.Chat_to: target_port_number = log_in_list[name][1] target_ident = log_in_list[name][0] key1 = key_iv[target_ident][0] # get target's key and iv iv1 = key_iv[target_ident][1] message2 = data.Note.decode('base-64') message2_de = util.aes_de(key1, iv1, message2) if message2 != False: msg2 = protobuf_pb2.MyProtocol() msg2.ParseFromString(message2_de) ticket_to_B = protobuf_pb2.MyProtocol() ticket_to_B.TypeNumber = 103 key_ab, iv_ab = util.key_xor(key, key1, iv, iv1) ticket_to_B.Key_ab = key_ab.encode('base-64') ticket_to_B.Iv_ab = iv_ab.encode('base-64') ticket_to_B.Sender_name = data.Sender_name ticket_to_B.Nb = msg2.Nb ticket = ticket_to_B.SerializeToString() ticket_en = util.aes_en(key1, iv1, ticket) send_request4 = protobuf_pb2.MyProtocol() send_request4.TypeNumber = 44 send_request4.N1 = data.N1 send_request4.Chat_to = data.Chat_to send_request4.Key_ab = key_ab.encode('base-64') send_request4.Iv_ab = iv_ab.encode('base-64') send_request4.Ticket = ticket_en.encode('base-64') send_request4_en = util.aes_en(key, iv, send_request4.SerializeToString()) socket.send_multipart([ident, send_request4_en]) except: send_request4 = protobuf_pb2.MyProtocol() send_request4.TypeNumber = 0 send_request4.Error = "Send Part 2 Error happen" send_request4_en = util.aes_en(key, iv, send_request4.SerializeToString()) socket.send_multipart([ident, send_request4_en])
def heartbeat_client(socket, name): hb = protobuf_pb2.MyProtocol() hb.TypeNumber = 1234 hb.Sender_name = name hb_en = util.rsa_en(logout_response.SerializeToString()) socket.send_multipart([util.rsa_en(logout_response.SerializeToString())]) while(True): socket.send_multipart([hb_en]) time.sleep(300) # 5 mins
def list_client(socket, name, key, iv): list_request1 = protobuf_pb2.MyProtocol() list_request1.TypeNumber = 3 list_request1.Type = "List" list_request1.Sender_name = name list_request1.C1 = random.randint(1,10001) socket.send_multipart([util.rsa_en(list_request1.SerializeToString())]) list_rq2 = socket.recv_multipart() s_msg = list_rq2[0] o_msg = util.aes_de(key, iv, s_msg) list_request2 = protobuf_pb2.MyProtocol() list_request2.ParseFromString(o_msg) print list_request2.Note list_request3 = protobuf_pb2.MyProtocol() list_request3.Note = "Confirm" list_request3.Sender_name = name list_request3.C2 = list_request2.C2 socket.send_multipart([util.rsa_en(list_request3.SerializeToString())])
socket.bind("tcp://*:%s" %(server_port)) key_iv = {} # ident:[key, iv, time] log_in_list = {} # name:[ident, port_number] black_list = [] message_attempt = {} # ident:message_received heartbeat = {} # ident:[name, time] # receive message and decrypt try: while(True): message = socket.recv_multipart() ident = message[0] #features.check_in_black_list(ident, black_list) = 1 or 0 message_de = util.rsa_de(message[1]) reply = protobuf_pb2.MyProtocol() data = protobuf_pb2.MyProtocol() data.ParseFromString(message_de) if data.TypeNumber == 1 or data.TypeNumber == 2: key_iv[ident] = [data.Key_client.decode('base-64'), data.Iv_client.decode('base-64')] print '*****************************************' if data.TypeNumber == 1: # sign up Request sign_up.sign_up_server(socket, ident, data, reply, key_iv) if data.TypeNumber == 2: # Log in Request log_in.log_in_server(socket, ident, data, reply, key_iv, log_in_list) if data.TypeNumber == 3: # List request list1.list_server(socket, ident, data, reply, key_iv, log_in_list)
def log_in_client(socket, bind_port, key, iv): flag = 1 while flag == 1: log_in_rq = protobuf_pb2.MyProtocol() name = raw_input('Please enter your username: '******'Please enter your password: '******'base-64') log_in_rq.Iv_client = iv.encode('base-64') socket.send_multipart([util.rsa_en(log_in_rq.SerializeToString())]) message = socket.recv_multipart() s_msg = message[0] s_msg_sig = message[1] if util.rsa_verify(s_msg_sig, s_msg) == True: # verify the signature from server o_msg = util.aes_de(key, iv, s_msg) log_in_resp = protobuf_pb2.MyProtocol() log_in_resp.ParseFromString(o_msg) if log_in_resp.TypeNumber == 0: # Error print log_in_resp.Error flag = 1 if log_in_resp.TypeNumber == 21: # Success print log_in_resp.Note flag = 0 if log_in_resp.C1 == cha1: log_in_3 = protobuf_pb2.MyProtocol() log_in_3.TypeNumber = 23 log_in_3.UserName = log_in_resp.UserName log_in_3.C2 = log_in_resp.C2 socket.send_multipart([util.rsa_en(log_in_3.SerializeToString())]) return name else: print 'Wrong Challenge, please try it again' log_in_3 = protobuf_pb2.MyProtocol() log_in_3.TypeNumber = 24 log_in_3.Error = "Wrong challenge" socket.send_multipart([log_in_3.SerializeToString()]) if log_in_resp.TypeNumber == 22: # Wrong password print log_in_resp.Note flag = 1 if log_in_resp.TypeNumber == 25: # Not sign up print log_in_resp.Note os._exit(0)
def log_in_server(socket, ident, data, reply, key_iv, log_in_list): try: flag = 0 print ("%s wants to log in" %(data.UserName)) key = key_iv[ident][0] iv = key_iv[ident][1] if data.UserName in log_in_list: print ("%s have already logged in" %(data.UserName)) reply.TypeNumber = 25 reply.Note = "You have already logged in, please do not try again" reply.C1 = data.C1 reply.C2 = random.randint(1,10001) s_msg = util.aes_en(key, iv, reply.SerializeToString()) s_msg_signature = util.rsa_sign(s_msg) socket.send_multipart([ident, s_msg, s_msg_signature]) return with open("sign_up.txt", 'r') as f: for line in f: log = line.split(" ") name = log[0] Hash_password = log[1] if name == data.UserName: # check username if util.bcrypt_verify(str(data.Password), Hash_password) == True: # check password log_in_list[data.UserName] = [ident, data.Port] reply.TypeNumber = 21 reply.UserName = data.UserName reply.Note = "Welcome to chat, you have already Logged in" reply.C1 = data.C1 cha2 = random.randint(1,10001) reply.C2 = cha2 s_msg = util.aes_en(key, iv, reply.SerializeToString()) s_msg_signature = util.rsa_sign(s_msg) socket.send_multipart([ident, s_msg, s_msg_signature]) message = socket.recv_multipart() message_de = util.rsa_de(message[1]) log_in_3 = protobuf_pb2.MyProtocol() log_in_3.ParseFromString(message_de) if log_in_3.C2 == cha2: print ("%s have logged in"%(log_in_3.UserName)) flag = 1 else: print 'logout the user' flag = 1 else: # wrong password reply.TypeNumber = 22 reply.Note = "Wrong password, please try again" reply.C1 = data.C1 reply.C2 = random.randint(1,10001) s_msg = util.aes_en(key, iv, reply.SerializeToString()) s_msg_signature = util.rsa_sign(s_msg) socket.send_multipart([ident, s_msg, s_msg_signature]) flag = 1 if flag == 0: # not signed up yet reply.TypeNumber = 25 reply.Note = "You have not signed up, please sign up first" reply.C1 = data.C1 reply.C2 = random.randint(1,10001) s_msg = util.aes_en(key, iv, reply.SerializeToString()) s_msg_signature = util.rsa_sign(s_msg) socket.send_multipart([ident, s_msg, s_msg_signature]) except: # Error key = key_iv[ident][0] iv = key_iv[ident][1] reply.TypeNumber = 0 reply.Error = "Log in Error happen" s_msg = util.aes_en(key, iv, reply.SerializeToString()) s_msg_signature = util.rsa_sign(s_msg) socket.send_multipart([ident, s_msg, s_msg_signature])
print_prompt(' <<< ') # start chat socket listener in sub thread chat_thread = threading.Thread( target=listener.client_socket_listener_as_server, args=(chat_socket, connect_ident, username, mutex_ident, key_client, iv_client, session_key_set, mutex_session_key)) chat_thread.start() while (True): sock = dict(poll.poll()) if socket in sock and sock[socket] == zmq.POLLIN: message = socket.recv_multipart() message_de = util.aes_de(key_client, iv_client, message[0]) msg_client = protobuf_pb2.MyProtocol() msg_client.ParseFromString(message_de) if msg_client.TypeNumber == 100: # logout request from server print("\n >>> System: %s have logged out from chat" % (msg_client.Sender_name)) print_prompt(' <<< ') if bool(connect_ident) == True: if msg_client.Sender_name in connect_ident: del connect_ident[msg_client.Sender_name] if bool(connect_socket) == True: if msg_client.Sender_name in connect_socket: del connect_socket[msg_client.Sender_name] if bool(session_key_set) == True:
def send_client(socket, name, connect_name, chat_socket, mutex, key, iv, session_key_set, mutex_session_key): send_request1 = protobuf_pb2.MyProtocol() send_request1.TypeNumber = 4 send_request1.Type = "Send" send_request1.Sender_name = name send_request1.Chat_to = connect_name socket.send_multipart([util.rsa_en(send_request1.SerializeToString())]) send_rq2 = socket.recv_multipart() send_rq2_de = util.aes_de(key, iv, send_rq2[0]) send_request2 = protobuf_pb2.MyProtocol() send_request2.ParseFromString(send_rq2_de) if send_request2.TypeNumber == 0: # Error print send_request2.Error if send_request2.TypeNumber == 42: # Success port = send_request2.Port context = zmq.Context() sub_socket = context.socket(zmq.DEALER) server = "localhost" sub_socket.connect("tcp://%s:%s" %(server, port)) mutex.acquire() chat_socket[connect_name] = sub_socket mutex.release() msg1 = protobuf_pb2.MyProtocol() msg1.TypeNumber = 10 msg1.Sender_name = name msg1.Chat_to = connect_name msg1.Ticket = send_request2.Ticket sub_socket.send_multipart([msg1.SerializeToString()]) message2 = sub_socket.recv_multipart() send_request3 = protobuf_pb2.MyProtocol() send_request3.TypeNumber = 41 send_request3.Sender_name = name send_request3.Chat_to = connect_name nonce_1 = random.randint(1,10001) send_request3.N1 = nonce_1 send_request3.Note = message2[0].encode('base-64') socket.send_multipart([util.rsa_en(send_request3.SerializeToString())]) send_rq4 = socket.recv_multipart() send_rq4_de = util.aes_de(key, iv, send_rq4[0]) send_request4 = protobuf_pb2.MyProtocol() send_request4.ParseFromString(send_rq4_de) if send_request4.TypeNumber == 0: # Error print send_request4.Error if send_request4.TypeNumber == 44: # Success ticket_to_B = send_request4.Ticket key_ab = send_request4.Key_ab.decode('base-64') iv_ab = send_request4.Iv_ab.decode('base-64') sub_socket.send_multipart([ticket_to_B.decode('base-64')]) message4 = sub_socket.recv_multipart() msg4_de = util.aes_de(key_ab, iv_ab, message4[0]) msg4 = protobuf_pb2.MyProtocol() msg4.ParseFromString(msg4_de) msg5 = protobuf_pb2.MyProtocol() msg5.TypeNumber = 105 msg5.N2 = msg4.N2 - 1 msg5_en = util.aes_en(key_ab, iv_ab, msg5.SerializeToString()) sub_socket.send_multipart([msg5_en]) message6 = sub_socket.recv_multipart() msg6_de = util.aes_de(key_ab, iv_ab, message6[0]) msg6 = protobuf_pb2.MyProtocol() msg6.ParseFromString(msg6_de) public_eckey1 = msg6.Key_ab.decode('base-64') iv1 = msg6.Iv_ab.decode('base-64') if msg6.TypeNumber == 106: # Success private_eckey2, public_eckey2, iv2 = util.generate_eckey() msg7 = protobuf_pb2.MyProtocol() msg7.TypeNumber == 107 msg7.Sender_name = name msg7.Key_ab = public_eckey2.encode('base-64') msg7.Iv_ab = iv2.encode('base-64') msg7_en = util.aes_en(key_ab, iv_ab, msg7.SerializeToString()) sub_socket.send_multipart([msg7_en]) key_ab_session, iv_ab_session = util.generate_shared_key(private_eckey2, public_eckey1, iv2, iv1) session_start_time = int(time.time()) mutex_session_key.acquire() session_key_set[connect_name] = [key_ab_session, iv_ab_session, session_start_time] mutex_session_key.release() return 1