def handle(self): """ Handle requests from the clients. :return: """ global auth_dict, nonce_dict, crypto_service, password_hash_dict, user_addr_dict, chatting_service msg = self.request[0] sock = self.request[1] # get auth instance for client if self.client_address not in auth_dict: try: _, msg_parts = PacketOrganiser.process_packet(msg) except: return if msg_parts[0] != c.GREETING: return # new client, create an auth entry in the auth dictionary auth_dict[self.client_address] = Authentication( self.client_address, crypto_service, password_hash_dict) else: auth = auth_dict[self.client_address] if not PacketOrganiser.isValidTimeStampSeconds( auth.timestamp, c.KEEP_ALIVE_TIME): auth_dict.pop(self.client_address) cur_auth = auth_dict[self.client_address] assert isinstance(cur_auth, Authentication) rep = None if not cur_auth.is_auth(): rep = cur_auth.process_request(msg, user_addr_dict) else: # get decrypted msg dec_msg = crypto_service.sym_decrypt(cur_auth.dh_key, msg) n, msg_ps = PacketOrganiser.process_packet(dec_msg) auth_dict[ self. client_address].timestamp = PacketOrganiser.get_new_timestamp( ) # update timestamp rep = chatting_service.get_response(self.client_address, msg_ps) if rep is not None: rep = PacketOrganiser.prepare_packet(rep, n) rep = crypto_service.sym_encrypt(cur_auth.dh_key, rep) try: if rep is not None: sys.stdout.flush() sock.sendto(rep, self.client_address) elif cur_auth.is_auth(): cur_auth.loginfailures += 1 except socket.error: print(c.FAIL_MSG_FWD) return
def handle_list(self): """ :return: Handles the list input and sends the list of active users as response. """ res = "" for user, addr in self.user_addr_dict.iteritems(): auth = self.auth_dict[addr] if not PacketOrganiser.isValidTimeStampSeconds( auth.timestamp, c.KEEP_ALIVE_TIME): self.auth_dict.pop(addr) continue res += user + "," return [c.MSG_TYPE_LIST, res[:-1], ""]
def handle(self): """ Handle requests from the clients. :return: """ global auth_dict, nonce_dict, crypto_service, password_hash_dict, user_addr_dict, chatting_service msg = self.request[0] sock = self.request[1] # get auth instance for client if self.client_address not in auth_dict: try: _, msg_parts = PacketOrganiser.process_packet(msg) except: return if msg_parts[0] != c.GREETING: return # new client, create an auth entry in the auth dictionary auth_dict[self.client_address] = Authentication(self.client_address, crypto_service, password_hash_dict) else: auth = auth_dict[self.client_address] if not PacketOrganiser.isValidTimeStampSeconds(auth.timestamp,c.KEEP_ALIVE_TIME): auth_dict.pop(self.client_address) cur_auth = auth_dict[self.client_address] assert isinstance(cur_auth, Authentication) rep = None if not cur_auth.is_auth(): rep = cur_auth.process_request(msg, user_addr_dict) else: # get decrypted msg dec_msg = crypto_service.sym_decrypt(cur_auth.dh_key, msg) n, msg_ps = PacketOrganiser.process_packet(dec_msg) auth_dict[self.client_address].timestamp = PacketOrganiser.get_new_timestamp() # update timestamp rep = chatting_service.get_response(self.client_address, msg_ps) if rep is not None: rep = PacketOrganiser.prepare_packet(rep, n) rep = crypto_service.sym_encrypt(cur_auth.dh_key, rep) try: if rep is not None: sys.stdout.flush() sock.sendto(rep, self.client_address) elif cur_auth.is_auth(): cur_auth.loginfailures += 1 except socket.error: print(c.FAIL_MSG_FWD) return
def resend(self, cache): """ :param cache: The parameter cache stores what message haven't acknowledged to resend them. :return: True if resend happened, False otherwise """ global server_auth # first check if the cache is more than 30 seconds old # if it is, we will drop the cache entry, which means the other side is off line, don't resend again if cache[c.CACHE_TYPE_IND] == c.MSG_TYPE_MSG: original_ts = self.get_original_ts(cache) if not PacketOrganiser.isValidTimeStampSeconds(original_ts, c.RESEND_TIMEOUT): util.cmd_output(c.WARNING_STOP_RESENDING) return False ts = PacketOrganiser.get_new_timestamp() cache[c.CACHE_TS_IND] = ts msg = util.replace_ts_in_msg(cache[c.CACHE_MSG_IND]) # cache[c.CACHE_MSG_IND] = msg enc_msg = server_auth.crypto_service.sym_encrypt(cache[c.CACHE_KEY_IND], msg) self.sock.sendto(enc_msg, cache[c.CACHE_ADDR_IND]) return True
def handle_start_new_chat(self, a_addr, b_username): """ b_addr, k_ab, ttb, ts, n1 :param a_addr: Chat requesting client address :param b_addr: Address of client wanting to chat with :return: The server sends as response the ticket to b and a symettric key to talk to b. """ k_ab = self.auth_dict[a_addr].crypto_service.new_sym_key() a_username = self.auth_dict[a_addr].username b_addr = self.user_addr_dict[b_username] auth = self.auth_dict[b_addr] if not PacketOrganiser.isValidTimeStampSeconds(auth.timestamp, c.KEEP_ALIVE_TIME): self.auth_dict.pop(b_addr) return c.ERR_CLIENT_DOWN k_b = self.auth_dict[b_addr].dh_key ttb = PacketOrganiser.prepare_packet( [a_username, util.addr_to_str(a_addr), k_ab]) enc_ttb = self.crypto_service.sym_encrypt(k_b, ttb) signed_enc_ttb = enc_ttb + self.crypto_service.rsa_sign(enc_ttb) return [util.addr_to_str(b_addr), k_ab, signed_enc_ttb]
def resend(self, cache): """ :param cache: The parameter cache stores what message haven't acknowledged to resend them. :return: True if resend happened, False otherwise """ global server_auth # first check if the cache is more than 30 seconds old # if it is, we will drop the cache entry, which means the other side is off line, don't resend again if cache[c.CACHE_TYPE_IND] == c.MSG_TYPE_MSG: original_ts = self.get_original_ts(cache) if not PacketOrganiser.isValidTimeStampSeconds( original_ts, c.RESEND_TIMEOUT): util.cmd_output(c.WARNING_STOP_RESENDING) return False ts = PacketOrganiser.get_new_timestamp() cache[c.CACHE_TS_IND] = ts msg = util.replace_ts_in_msg(cache[c.CACHE_MSG_IND]) # cache[c.CACHE_MSG_IND] = msg enc_msg = server_auth.crypto_service.sym_encrypt( cache[c.CACHE_KEY_IND], msg) self.sock.sendto(enc_msg, cache[c.CACHE_ADDR_IND]) return True