Beispiel #1
0
def process_group_management_message(
        ts: 'datetime', packet: bytes, header: bytes,
        messages_to_flask: 'Queue[Tuple[Union[bytes, str], bytes]]') -> None:
    """Parse and display group management message."""
    header_str = header.decode()
    group_id, packet = separate_header(packet, GROUP_ID_LENGTH)

    if header in [GROUP_MSG_INVITE_HEADER, GROUP_MSG_JOIN_HEADER]:
        pub_keys = split_byte_string(packet, ONION_SERVICE_PUBLIC_KEY_LENGTH)
        for onion_pub_key in pub_keys:
            others = [k for k in pub_keys if k != onion_pub_key]
            packet_str = header_str + b85encode(group_id + b''.join(others))
            queue_to_flask(packet_str, onion_pub_key, messages_to_flask, ts,
                           header)

    elif header in [GROUP_MSG_MEMBER_ADD_HEADER, GROUP_MSG_MEMBER_REM_HEADER]:
        first_list_len_b, packet = separate_header(packet,
                                                   ENCODED_INTEGER_LENGTH)
        first_list_length = bytes_to_int(first_list_len_b)
        pub_keys = split_byte_string(packet, ONION_SERVICE_PUBLIC_KEY_LENGTH)
        before_adding = remaining = pub_keys[:first_list_length]
        new_in_group = removable = pub_keys[first_list_length:]

        if header == GROUP_MSG_MEMBER_ADD_HEADER:

            packet_str = GROUP_MSG_MEMBER_ADD_HEADER.decode() + b85encode(
                group_id + b''.join(new_in_group))
            for onion_pub_key in before_adding:
                queue_to_flask(packet_str, onion_pub_key, messages_to_flask,
                               ts, header)

            for onion_pub_key in new_in_group:
                other_new = [k for k in new_in_group if k != onion_pub_key]
                packet_str = (
                    GROUP_MSG_INVITE_HEADER.decode() +
                    b85encode(group_id + b''.join(other_new + before_adding)))
                queue_to_flask(packet_str, onion_pub_key, messages_to_flask,
                               ts, header)

        elif header == GROUP_MSG_MEMBER_REM_HEADER:
            packet_str = header_str + b85encode(group_id + b''.join(removable))
            for onion_pub_key in remaining:
                queue_to_flask(packet_str, onion_pub_key, messages_to_flask,
                               ts, header)

    elif header == GROUP_MSG_EXIT_GROUP_HEADER:
        pub_keys = split_byte_string(packet, ONION_SERVICE_PUBLIC_KEY_LENGTH)
        packet_str = header_str + b85encode(group_id)
        for onion_pub_key in pub_keys:
            queue_to_flask(packet_str, onion_pub_key, messages_to_flask, ts,
                           header)
Beispiel #2
0
def src_incoming(queues:   'QueueDict',
                 gateway:  'Gateway',
                 unittest: bool = False
                 ) -> None:
    """\
    Redirect messages received from Source Computer to appropriate queues.
    """
    packets_from_sc   = queues[GATEWAY_QUEUE]
    packets_to_dc     = queues[DST_MESSAGE_QUEUE]
    commands_to_dc    = queues[DST_COMMAND_QUEUE]
    messages_to_flask = queues[M_TO_FLASK_QUEUE]
    files_to_flask    = queues[F_TO_FLASK_QUEUE]
    commands_to_relay = queues[SRC_TO_RELAY_QUEUE]

    while True:
        with ignored(EOFError, KeyboardInterrupt):
            while packets_from_sc.qsize() == 0:
                time.sleep(0.01)

            ts, packet = packets_from_sc.get()  # type: datetime, bytes
            ts_bytes   = int_to_bytes(int(ts.strftime('%Y%m%d%H%M%S%f')[:-4]))

            try:
                packet = gateway.detect_errors(packet)
            except FunctionReturn:
                continue

            header, packet = separate_header(packet, DATAGRAM_HEADER_LENGTH)

            if header == UNENCRYPTED_DATAGRAM_HEADER:
                commands_to_relay.put(packet)

            elif header in [COMMAND_DATAGRAM_HEADER, LOCAL_KEY_DATAGRAM_HEADER]:
                commands_to_dc.put(header + ts_bytes + packet)
                p_type = 'Command  ' if header == COMMAND_DATAGRAM_HEADER else 'Local key'
                rp_print(f"{p_type} to local Receiver", ts)

            elif header in [MESSAGE_DATAGRAM_HEADER, PUBLIC_KEY_DATAGRAM_HEADER]:
                onion_pub_key, payload = separate_header(packet, ONION_SERVICE_PUBLIC_KEY_LENGTH)
                packet_str             = header.decode() + b85encode(payload)
                queue_to_flask(packet_str, onion_pub_key, messages_to_flask, ts, header)
                if header == MESSAGE_DATAGRAM_HEADER:
                    packets_to_dc.put(header + ts_bytes + onion_pub_key + ORIGIN_USER_HEADER + payload)

            elif header == FILE_DATAGRAM_HEADER:
                no_contacts_b, payload = separate_header(packet, ENCODED_INTEGER_LENGTH)
                no_contacts            = bytes_to_int(no_contacts_b)
                ser_accounts, file_ct  = separate_header(payload, no_contacts * ONION_SERVICE_PUBLIC_KEY_LENGTH)
                pub_keys               = split_byte_string(ser_accounts, item_len=ONION_SERVICE_PUBLIC_KEY_LENGTH)
                for onion_pub_key in pub_keys:
                    queue_to_flask(file_ct, onion_pub_key, files_to_flask, ts, header)

            elif header in [GROUP_MSG_INVITE_HEADER, GROUP_MSG_JOIN_HEADER,
                            GROUP_MSG_MEMBER_ADD_HEADER, GROUP_MSG_MEMBER_REM_HEADER,
                            GROUP_MSG_EXIT_GROUP_HEADER]:
                process_group_management_message(ts, packet, header, messages_to_flask)

            if unittest:
                break
Beispiel #3
0
def process_add_or_group_remove_member(ts: 'datetime', header: bytes,
                                       buf_key: bytes, header_str: str,
                                       group_id: bytes, remaining: List[bytes],
                                       removable: List[bytes]) -> None:
    """Process group add or remove member packet."""
    packet_str = header_str + b85encode(group_id + b"".join(removable))
    for onion_pub_key in remaining:
        buffer_to_flask(packet_str, onion_pub_key, ts, header, buf_key)
Beispiel #4
0
def process_group_management_message(
    ts: 'datetime',
    packet: bytes,
    header: bytes,
    buf_key: bytes,
) -> None:
    """Parse and display group management message."""
    header_str = header.decode()
    group_id, packet = separate_header(packet, GROUP_ID_LENGTH)

    if header in [GROUP_MSG_INVITE_HEADER, GROUP_MSG_JOIN_HEADER]:
        pub_keys = split_byte_string(packet, ONION_SERVICE_PUBLIC_KEY_LENGTH)
        for onion_pub_key in pub_keys:
            others = [k for k in pub_keys if k != onion_pub_key]
            packet_str = header_str + b85encode(group_id + b''.join(others))
            buffer_to_flask(packet_str, onion_pub_key, ts, header, buf_key)

    elif header in [GROUP_MSG_MEMBER_ADD_HEADER, GROUP_MSG_MEMBER_REM_HEADER]:
        first_list_len_b, packet = separate_header(packet,
                                                   ENCODED_INTEGER_LENGTH)
        first_list_length = bytes_to_int(first_list_len_b)
        pub_keys = split_byte_string(packet, ONION_SERVICE_PUBLIC_KEY_LENGTH)
        before_adding = remaining = pub_keys[:first_list_length]
        new_in_group = removable = pub_keys[first_list_length:]

        if header == GROUP_MSG_MEMBER_ADD_HEADER:

            process_add_or_group_remove_member(ts, header, buf_key, header_str,
                                               group_id, before_adding,
                                               new_in_group)

            for onion_pub_key in new_in_group:
                other_new = [k for k in new_in_group if k != onion_pub_key]
                packet_str = (
                    GROUP_MSG_INVITE_HEADER.decode() +
                    b85encode(group_id + b''.join(other_new + before_adding)))
                buffer_to_flask(packet_str, onion_pub_key, ts, header, buf_key)

        elif header == GROUP_MSG_MEMBER_REM_HEADER:
            process_add_or_group_remove_member(ts, header, buf_key, header_str,
                                               group_id, remaining, removable)

    elif header == GROUP_MSG_EXIT_GROUP_HEADER:
        process_group_exit_header(ts, packet, header, buf_key, header_str,
                                  group_id)
Beispiel #5
0
def process_add_or_group_remove_member(
        ts: 'datetime', header: bytes, header_str: str, group_id: bytes,
        messages_to_flask: 'Queue[Tuple[Union[bytes, str], bytes]]',
        remaining: List[bytes], removable: List[bytes]) -> None:
    """Process group add or remove member packet."""
    packet_str = header_str + b85encode(group_id + b"".join(removable))
    for onion_pub_key in remaining:
        queue_to_flask(packet_str, onion_pub_key, messages_to_flask, ts,
                       header)
Beispiel #6
0
def process_group_exit_header(
        ts: 'datetime', packet: bytes, header: bytes, header_str: str,
        group_id: bytes,
        messages_to_flask: 'Queue[Tuple[Union[bytes, str], bytes]]') -> None:
    """Process group exit packet."""
    pub_keys = split_byte_string(packet, ONION_SERVICE_PUBLIC_KEY_LENGTH)
    packet_str = header_str + b85encode(group_id)
    for onion_pub_key in pub_keys:
        queue_to_flask(packet_str, onion_pub_key, messages_to_flask, ts,
                       header)
Beispiel #7
0
def process_group_exit_header(
    ts: 'datetime',
    packet: bytes,
    header: bytes,
    buf_key: bytes,
    header_str: str,
    group_id: bytes,
) -> None:
    """Process group exit packet."""
    pub_keys = split_byte_string(packet, ONION_SERVICE_PUBLIC_KEY_LENGTH)
    packet_str = header_str + b85encode(group_id)
    for onion_pub_key in pub_keys:
        buffer_to_flask(packet_str, onion_pub_key, ts, header, buf_key)
Beispiel #8
0
def process_message_datagram(ts: 'datetime', packet: bytes, header: bytes,
                             buf_key: bytes, queues: 'QueueDict') -> None:
    """Process message or public key datagram."""
    packets_to_dst = queues[DST_MESSAGE_QUEUE]

    onion_pub_key, payload = separate_header(packet,
                                             ONION_SERVICE_PUBLIC_KEY_LENGTH)
    packet_str = header.decode() + b85encode(payload)
    ts_bytes = int_to_bytes(int(ts.strftime("%Y%m%d%H%M%S%f")[:-4]))

    buffer_to_flask(packet_str, onion_pub_key, ts, header, buf_key)

    if header == MESSAGE_DATAGRAM_HEADER:
        packets_to_dst.put(header + ts_bytes + onion_pub_key +
                           ORIGIN_USER_HEADER + payload)
Beispiel #9
0
 def test_b85encode(self):
     message = os.urandom(100)
     self.assertEqual(b85encode(message),
                      base64.b85encode(message).decode())