def replace_ts_in_msg(msg):
    """

    :param msg:
    :return:
    """
    msg_without_ts = msg[:-c.TS_LEN]
    new_msg = msg_without_ts + PacketOrganiser.get_new_timestamp()
    return new_msg
def replace_ts_in_msg(msg):
    """

    :param msg:
    :return:
    """
    msg_without_ts = msg[:-c.TS_LEN]
    new_msg = msg_without_ts + PacketOrganiser.get_new_timestamp()
    return new_msg
def display_user_message(raw_msg, username):
    """

    :param raw_msg:
    :param username:
    :return:
    """
    ts = PacketOrganiser.get_new_timestamp()
    msg = "{} <{}>: {}".format(username, ts, raw_msg)
    cmd_output(msg)
def display_user_message(raw_msg, username):
    """

    :param raw_msg:
    :param username:
    :return:
    """
    ts = PacketOrganiser.get_new_timestamp()
    msg = "{} <{}>: {}".format(username, ts, raw_msg)
    cmd_output(msg)
 def _authenticate_and_send_msg(self, username, chat_msg):
     # start peer authentication
     nonce = util.get_good_nonce(self.request_cache)
     new_auth = ClientClientAuthentication(username, self.auth.crypto_service, chat_msg)
     new_auth.timestamp = PacketOrganiser.get_new_timestamp()  # timestamp when created, for packet resend
     key = self.auth.dh_key
     msg_to_send = PacketOrganiser.prepare_packet([c.MSG_TYPE_START_NEW_CHAT, username, ""], nonce=nonce)
     util.add_to_request_cache(
         self.request_cache, nonce, c.MSG_TYPE_START_NEW_CHAT, key, msg_to_send, self.auth.server_addr, new_auth
     )  # add to cache
     return username, self.auth.server_addr, self.serv.sym_encrypt(key, msg_to_send)
    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(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 add_to_request_cache(cache, nonce, type, key, msg, addr, auth=None):
    """

    :param cache:
    :param nonce:
    :param type:
    :param key:
    :param msg:
    :param addr:
    :param auth:
    :return:
    """
    if nonce in cache:
        raise Exception(c.WARNING_EXISTED_NONCE)
    cache[nonce] = [type, key, msg, addr, PacketOrganiser.get_new_timestamp()]
    if auth:
        cache[nonce].append(auth)
def add_to_request_cache(cache, nonce, type, key, msg, addr, auth=None):
    """

    :param cache:
    :param nonce:
    :param type:
    :param key:
    :param msg:
    :param addr:
    :param auth:
    :return:
    """
    if nonce in cache:
        raise Exception(c.WARNING_EXISTED_NONCE)
    cache[nonce] = [type, key, msg, addr, PacketOrganiser.get_new_timestamp()]
    if auth:
        cache[nonce].append(auth)
    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 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