Exemplo n.º 1
0
 def setUp(self):
     """Pre-test actions."""
     self.settings = Settings()
     self.unit_test_dir = cd_unit_test()
     self.gateway = Gateway()
     self.rs = RSCodec(2 * self.gateway.settings.serial_error_correction)
     self.ts = datetime.now()
     self.queues = gen_queue_dict()
     self.args = self.queues, self.gateway
Exemplo n.º 2
0
 def setUp(self) -> None:
     """Pre-test actions."""
     self.settings = Settings()
     self.unit_test_dir = cd_unit_test()
     self.gateway = Gateway()
     self.rs = RSCodec(2 * self.gateway.settings.serial_error_correction)
     self.ts = datetime.now()
     self.queues = gen_queue_dict()
     self.args = self.queues, self.gateway
     self.queues[TX_BUF_KEY_QUEUE].put(SYMMETRIC_KEY_LENGTH * b'a')
Exemplo n.º 3
0
def transmit(packet: bytes, settings: 'Settings', gateway: 'Gateway') -> None:
    """Add Reed-Solomon erasure code and output packet via gateway."""
    rs     = RSCodec(2 * settings.session_ec_ratio)
    packet = rs.encode(packet)
    gateway.write(packet)

    if not settings.session_trickle:
        if settings.long_packet_rand_d:
            random_delay = random.SystemRandom().uniform(0, settings.max_val_for_rand_d)
            time.sleep(random_delay)
Exemplo n.º 4
0
Arquivo: tcb.py Projeto: barleyj/tfc
def txm_incoming(settings: 'Settings', q_to_tip: 'Queue', q_to_rxm: 'Queue',
                 q_to_im: 'Queue', q_to_nh: 'Queue') -> None:
    """Load messages from TxM and forward them to appropriate process via queue."""
    rs = RSCodec(2 * settings.session_ec_ratio)

    while True:
        try:
            if q_to_tip.empty():
                time.sleep(0.001)
            packet = q_to_tip.get()

            try:
                packet = bytes(rs.decode(packet))
            except ReedSolomonError:
                box_print(
                    ["Warning! Failed to correct errors in received packet."],
                    head=1,
                    tail=1)
                continue

            ts = datetime.datetime.now().strftime(settings.t_fmt)
            header = packet[:1]

            if header == UNENCRYPTED_PACKET_HEADER:
                q_to_nh.put(packet[1:])

            elif header in [LOCAL_KEY_PACKET_HEADER, COMMAND_PACKET_HEADER]:
                p_type = 'local key' if header == LOCAL_KEY_PACKET_HEADER else 'command'
                print("{} - {} TxM > RxM".format(ts, p_type))
                q_to_rxm.put(packet)

            elif header in [MESSAGE_PACKET_HEADER, PUBLIC_KEY_PACKET_HEADER]:
                payload_len, p_type = (
                    32, 'pub key') if header == PUBLIC_KEY_PACKET_HEADER else (
                        344, 'message')
                payload = packet[1:1 + payload_len]
                trailer = packet[1 + payload_len:]
                user, contact = trailer.split(US_BYTE)

                print("{} - {} TxM > {} > {}".format(ts, p_type, user.decode(),
                                                     contact.decode()))
                q_to_im.put((header, payload, user, contact))
                q_to_rxm.put(header + payload + ORIGIN_USER_HEADER + contact)

            elif header == EXPORTED_FILE_CT_HEADER:
                payload = packet[1:]
                file_name = os.urandom(16).hex()
                with open(file_name, 'wb+') as f:
                    f.write(payload)
                print("{} - Exported file from TxM as {}".format(
                    ts, file_name))

        except (EOFError, KeyboardInterrupt):
            pass
Exemplo n.º 5
0
 def setUp(self):
     self.settings  = Settings()
     self.rs        = RSCodec(2 * self.settings.serial_error_correction)
     self.o_urandom = os.urandom
     self.queues    = {TXM_INCOMING_QUEUE: Queue(),
                       RXM_OUTGOING_QUEUE: Queue(),
                       TXM_TO_IM_QUEUE:    Queue(),
                       TXM_TO_NH_QUEUE:    Queue(),
                       TXM_TO_RXM_QUEUE:   Queue(),
                       NH_TO_IM_QUEUE:     Queue(),
                       EXIT_QUEUE:         Queue()}
Exemplo n.º 6
0
 def test_check(self) -> None:
     rs         = RSCodec()
     msg        = bytearray("hello world " * 10, "latin1")
     enc        = rs.encode(msg)
     rmsg, renc = rs.decode(enc)
     self.assertEqual(rs.check(enc), [True])
     self.assertEqual(rs.check(renc), [True])
     for i in [27, -3, -9, 7, 0]:
         enc[i]     = 99
         rmsg, renc = rs.decode(enc)
         self.assertEqual(rs.check(enc), [False])
         self.assertEqual(rs.check(renc), [True])
Exemplo n.º 7
0
 def test_correction(self) -> None:
     rs         = RSCodec()
     msg        = bytearray("hello world " * 10, "latin1")
     enc        = rs.encode(msg)
     rmsg, renc = rs.decode(enc)
     self.assertEqual(rmsg, msg)
     self.assertEqual(renc, enc)
     for i in [27, -3, -9, 7, 0]:
         enc[i]     = 99
         rmsg, renc = rs.decode(enc)
         self.assertEqual(rmsg, msg)
     enc[82] = 99
     self.assertRaises(ReedSolomonError, rs.decode, enc)
Exemplo n.º 8
0
 def test_long(self) -> None:
     rs           = RSCodec()
     msg          = bytearray("a" * 10000, "latin1")
     enc          = rs.encode(msg)
     dec, dec_enc = rs.decode(enc)
     self.assertEqual(dec, msg)
     self.assertEqual(dec_enc, enc)
     enc2           = list(enc)
     enc2[177]      = 99
     enc2[2212]     = 88
     dec2, dec_enc2 = rs.decode(bytes(enc2))
     self.assertEqual(dec2, msg)
     self.assertEqual(dec_enc2, enc)
Exemplo n.º 9
0
Arquivo: tcb.py Projeto: barleyj/tfc
def rxm_outgoing(settings: 'Settings', q_to_rxm: 'Queue',
                 gateway: 'Gateway') -> None:
    """Output packets from RxM-queue to RxM."""
    rs = RSCodec(2 * settings.session_ec_ratio)
    while True:
        try:
            if q_to_rxm.empty():
                time.sleep(0.001)
                continue
            from_q = q_to_rxm.get()
            packet = rs.encode(bytearray(from_q))
            gateway.write(packet)
        except (EOFError, KeyboardInterrupt):
            pass
Exemplo n.º 10
0
    def test_add_error_correction(self, *_) -> None:
        gateway = Gateway(operation=RX, local_test=False, dd_sockets=False, qubes=False)
        packet = b"packet"

        # Test BLAKE2b based checksum
        gateway.settings.session_serial_error_correction = 0
        self.assertEqual(gateway.add_error_correction(packet),
                         packet + blake2b(packet, digest_size=PACKET_CHECKSUM_LENGTH))

        # Test Reed-Solomon erasure code
        gateway.settings.session_serial_error_correction = 5
        gateway.rs = RSCodec(gateway.settings.session_serial_error_correction)
        self.assertEqual(gateway.add_error_correction(packet),
                         gateway.rs.encode(packet))
Exemplo n.º 11
0
    def test_detect_errors(self, *_: Any) -> None:
        gateway = Gateway(operation=RX,
                          local_test=False,
                          dd_sockets=False,
                          qubes=False)
        packet = b'packet'

        # Test BLAKE2b based checksum
        gateway.settings.session_serial_error_correction = 0
        self.assertEqual(
            gateway.detect_errors(gateway.add_error_correction(packet)),
            packet)

        # Test unrecoverable error raises SoftError
        self.assert_se("Warning! Received packet had an invalid checksum.",
                       gateway.detect_errors, 300 * b'a')

        # Test Reed-Solomon erasure code
        gateway.settings.session_serial_error_correction = 5
        gateway.rs = RSCodec(gateway.settings.session_serial_error_correction)
        self.assertEqual(
            gateway.detect_errors(gateway.add_error_correction(packet)),
            packet)

        # Test unrecoverable error raises SoftError
        self.assert_se(
            "Error: Reed-Solomon failed to correct errors in the received packet.",
            gateway.detect_errors, 300 * b'a')

        # Qubes

        # Test with B58 encoding
        gateway.settings.qubes = True
        packet_with_error_correction = base64.b85encode(
            gateway.add_error_correction(packet))
        self.assertEqual(gateway.detect_errors(packet_with_error_correction),
                         packet)

        # Test invalid B85 encoding raises SoftError
        packet_with_error_correction = base64.b85encode(
            gateway.add_error_correction(packet))
        packet_with_error_correction += b'\x00'
        self.assert_se("Error: Received packet had invalid Base85 encoding.",
                       gateway.detect_errors, packet_with_error_correction)
        gateway.settings.qubes = False
Exemplo n.º 12
0
def calculate_race_condition_delay(settings: Union['Settings', 'NHSettings'], txm: bool = False) -> float:
    """Calculate NH race condition delay.

    This value is the max time it takes for NH to deliver
    command received from TxM all the way to RxM.

    :param settings: Settings object
    :param txm:      When True, allocate time for command delivery from TxM to NH
    :return:         Time to wait to prevent race condition
    """
    rs                 = RSCodec(2 * settings.session_serial_error_correction)
    max_account_length = 254
    max_message_length = PACKET_LENGTH + 2 * max_account_length
    command_length     = 365*2 if txm else 365
    max_bytes          = (len(rs.encode(os.urandom(max_message_length)))
                          + len(rs.encode(os.urandom(command_length))))

    return (max_bytes * BAUDS_PER_BYTE) / settings.serial_baudrate
Exemplo n.º 13
0
    def update_delivery_time(self) -> None:
        """Calculate transmission time.

        Transmission time is based on average delays and settings.
        """
        no_packets = self.count_number_of_packets()

        if self.settings.session_traffic_masking:
            avg_delay = self.settings.traffic_masking_static_delay + (
                self.settings.traffic_masking_random_delay / 2)
            if self.settings.multi_packet_random_delay:
                avg_delay += (self.settings.max_duration_of_random_delay / 2)

            total_time = len(self.window) * no_packets * avg_delay
            total_time *= 2  # Accommodate command packets between file packets
            total_time += no_packets * TRAFFIC_MASKING_QUEUE_CHECK_DELAY

        else:
            # Determine total data to be transmitted over serial
            rs = RSCodec(2 * self.settings.session_serial_error_correction)
            total_data = 0
            for c in self.window:
                data = os.urandom(PACKET_LENGTH) + c.rx_account.encode(
                ) + c.tx_account.encode()
                enc_data = rs.encode(data)
                total_data += no_packets * len(enc_data)

            # Determine time required to send all data
            total_time = 0.0
            if self.settings.local_testing_mode:
                total_time += no_packets * LOCAL_TESTING_PACKET_DELAY
            else:
                total_bauds = total_data * BAUDS_PER_BYTE
                total_time += total_bauds / self.settings.session_serial_baudrate
                total_time += no_packets * self.settings.txm_inter_packet_delay

            if self.settings.multi_packet_random_delay:
                total_time += no_packets * (
                    self.settings.max_duration_of_random_delay / 2)

        # Update delivery time
        self.time_bytes = int_to_bytes(int(total_time))
        self.time_print = str(datetime.timedelta(seconds=int(total_time)))
Exemplo n.º 14
0
    def test_receiver_loop(self) -> None:
        # Setup
        gateway = Gateway(local_test=False)
        rs = RSCodec(2 * gateway.settings.serial_error_correction)
        queues = {
            MESSAGE_DATAGRAM_HEADER: Queue(),
            FILE_DATAGRAM_HEADER: Queue(),
            COMMAND_DATAGRAM_HEADER: Queue(),
            LOCAL_KEY_DATAGRAM_HEADER: Queue()
        }

        all_q = dict(queues)
        all_q.update({GATEWAY_QUEUE: Queue()})

        ts = datetime.now()
        ts_bytes = int_to_bytes(int(ts.strftime('%Y%m%d%H%M%S%f')[:-4]))

        for key in queues:
            packet = key + ts_bytes + bytes(ONION_SERVICE_PUBLIC_KEY_LENGTH)
            encoded = rs.encode(packet)
            broken_p = key + bytes.fromhex('df9005313af4136d') + bytes(
                ONION_SERVICE_PUBLIC_KEY_LENGTH)
            broken_p += rs.encode(b'a')

            def queue_delayer() -> None:
                """Place datagrams into queue after delay."""
                time.sleep(0.01)
                all_q[GATEWAY_QUEUE].put(
                    (datetime.now(), rs.encode(8 * b'1' + b'undecodable')))
                all_q[GATEWAY_QUEUE].put((datetime.now(), broken_p))
                all_q[GATEWAY_QUEUE].put((datetime.now(), encoded))

            threading.Thread(target=queue_delayer).start()

            # Test
            self.assertIsNone(receiver_loop(all_q, gateway, unit_test=True))
            time.sleep(0.01)
            self.assertEqual(queues[key].qsize(), 1)

            # Teardown
            tear_queue(queues[key])
Exemplo n.º 15
0
def transmit(packet:   bytes,
             settings: 'Settings',
             gateway:  'Gateway',
             delay:    bool = True) -> None:
    """Add Reed-Solomon erasure code and output packet via gateway.

    Note that random.SystemRandom() uses Kernel CSPRNG (/dev/urandom),
    not Python's weak RNG based on Mersenne Twister:
        https://docs.python.org/2/library/random.html#random.SystemRandom
    """
    rs     = RSCodec(2 * settings.session_serial_error_correction)
    packet = rs.encode(packet)
    gateway.write(packet)

    if settings.local_testing_mode:
        time.sleep(LOCAL_TESTING_PACKET_DELAY)

    if not settings.session_traffic_masking:
        if settings.multi_packet_random_delay and delay:
            random_delay = random.SystemRandom().uniform(0, settings.max_duration_of_random_delay)
            time.sleep(random_delay)
Exemplo n.º 16
0
def calculate_race_condition_delay(serial_error_correction: int,
                                   serial_baudrate: int) -> float:
    """\
    Calculate the delay required to prevent Relay Program race condition.

    When Transmitter Program outputs a command to exit or wipe data,
    Relay program will also receive a copy of the command. If the Relay
    Program acts on the command too early, the Receiver Program will not
    receive the exit/wipe command at all.

    This function calculates the delay Transmitter Program should wait
    before outputting command to the Relay Program, to ensure the
    Receiver Program has received its encrypted command.
    """
    rs = RSCodec(2 * serial_error_correction)
    message_length = PACKET_LENGTH + ONION_ADDRESS_LENGTH
    enc_msg_length = len(rs.encode(os.urandom(message_length)))
    enc_cmd_length = len(rs.encode(os.urandom(COMMAND_LENGTH)))
    max_bytes = enc_msg_length + (2 * enc_cmd_length)

    return (max_bytes * BAUDS_PER_BYTE) / serial_baudrate
Exemplo n.º 17
0
    def test_detect_errors(self, *_):
        gateway = Gateway(operation=RX, local_test=False, dd_sockets=False)
        packet  = b'packet'

        # Test BLAKE2b based checksum
        gateway.settings.session_serial_error_correction = 0
        self.assertEqual(gateway.detect_errors(gateway.add_error_correction(packet)),
                         packet)

        # Test unrecoverable error raises FR
        self.assert_fr("Warning! Received packet had an invalid checksum.",
                       gateway.detect_errors, 300 * b'a')

        # Test Reed-Solomon erasure code
        gateway.settings.session_serial_error_correction = 5
        gateway.rs = RSCodec(gateway.settings.session_serial_error_correction)
        self.assertEqual(gateway.detect_errors(gateway.add_error_correction(packet)),
                         packet)

        # Test unrecoverable error raises FR
        self.assert_fr("Error: Reed-Solomon failed to correct errors in the received packet.",
                       gateway.detect_errors, 300 * b'a')
Exemplo n.º 18
0
    def __init__(self, operation: str, local_test: bool,
                 dd_sockets: bool) -> None:
        """Create a new Gateway object."""
        self.settings = GatewaySettings(operation, local_test, dd_sockets)
        self.tx_serial = None  # type: Optional[serial.Serial]
        self.rx_serial = None  # type: Optional[serial.Serial]
        self.rx_socket = None  # type: Optional[multiprocessing.connection.Connection]
        self.tx_socket = None  # type: Optional[multiprocessing.connection.Connection]

        # Initialize Reed-Solomon erasure code handler
        self.rs = RSCodec(2 * self.settings.session_serial_error_correction)

        # Set True when the serial interface is initially found so that
        # further interface searches know to announce disconnection.
        self.init_found = False

        if self.settings.local_testing_mode:
            if self.settings.software_operation in [TX, NC]:
                self.client_establish_socket()
            if self.settings.software_operation in [NC, RX]:
                self.server_establish_socket()
        else:
            self.establish_serial()
Exemplo n.º 19
0
def receiver_loop(queues: Dict[bytes, 'Queue'],
                  settings: 'Settings',
                  unittest: bool = False) -> None:
    """Decode received packets and forward them to packet queues.

    This function also determines the timestamp for received message.
    """
    rs = RSCodec(2 * settings.session_serial_error_correction)
    gw_queue = queues[GATEWAY_QUEUE]

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

            packet = gw_queue.get()
            timestamp = datetime.now()

            try:
                packet = bytes(rs.decode(packet))
            except ReedSolomonError:
                box_print(
                    "Error: Failed to correct errors in received packet.",
                    head=1,
                    tail=1)
                continue

            p_header = packet[:1]
            if p_header in [
                    PUBLIC_KEY_PACKET_HEADER, MESSAGE_PACKET_HEADER,
                    LOCAL_KEY_PACKET_HEADER, COMMAND_PACKET_HEADER,
                    IMPORTED_FILE_HEADER
            ]:
                queues[p_header].put((timestamp, packet))

            if unittest:
                break
Exemplo n.º 20
0
    def test_prim_fcr_long(self):
        nn = 48
        kk = 34
        tt = nn - kk
        rs = RSCodec(tt, fcr=120, prim=0x187)
        hexencmsg = ('08faa123555555c000000354064432c0280e1b4d090cfc04'
                     '887400000003500000000e1985ff9c6b33066ca9f43d12e8')
        strf = str
        encmsg = bytearray.fromhex(strf(hexencmsg))
        decmsg = encmsg[:kk]
        tem = rs.encode(decmsg)
        self.assertEqual(encmsg, tem, msg="encoded does not match expected")

        tdm, rtem = rs.decode(tem)
        self.assertEqual(tdm, decmsg, msg="decoded does not match original")
        self.assertEqual(rtem,
                         tem,
                         msg="decoded mesecc does not match original")

        tem1 = bytearray(tem)
        numerrs = tt >> 1
        for i in sample(range(nn), numerrs):
            tem1[i] ^= 0xff
        tdm, rtem = rs.decode(tem1)
        self.assertEqual(tdm,
                         decmsg,
                         msg="decoded with errors does not match original")
        self.assertEqual(
            rtem,
            tem,
            msg="decoded mesecc with errors does not match original")

        tem1 = bytearray(tem)
        numerrs += 1
        for i in sample(range(nn), numerrs):
            tem1[i] ^= 0xff
        self.assertRaises(ReedSolomonError, rs.decode, tem1)
Exemplo n.º 21
0
    def test_receiver_loop(self):
        # Setup
        settings = Settings()
        rs = RSCodec(2 * settings.serial_error_correction)
        queues = {
            LOCAL_KEY_PACKET_HEADER: Queue(),
            PUBLIC_KEY_PACKET_HEADER: Queue(),
            MESSAGE_PACKET_HEADER: Queue(),
            COMMAND_PACKET_HEADER: Queue(),
            IMPORTED_FILE_HEADER: Queue()
        }

        all_q = dict(queues)
        all_q.update({GATEWAY_QUEUE: Queue()})

        for key in queues:
            packet = key + bytes(KEY_LENGTH)
            encoded = rs.encode(packet)

            def queue_delayer():
                time.sleep(0.1)
                all_q[GATEWAY_QUEUE].put(b'undecodable')
                all_q[GATEWAY_QUEUE].put(encoded)

            threading.Thread(target=queue_delayer).start()

            # Test
            self.assertIsNone(receiver_loop(all_q, settings, unittest=True))
            time.sleep(0.1)
            self.assertEqual(queues[key].qsize(), 1)

            # Teardown
            while not queues[key].empty():
                queues[key].get()
            time.sleep(0.1)
            queues[key].close()
Exemplo n.º 22
0
    def test_prim_fcr_basic(self):
        nn = 30
        kk = 18
        tt = nn - kk
        rs = RSCodec(tt, fcr=120, prim=0x187)
        hexencmsg = ('00faa123555555c000000354064432'
                     'c02800fe97c434e1ff5365cf8fafe4')
        strf = str
        encmsg = bytearray.fromhex(strf(hexencmsg))
        decmsg = encmsg[:kk]
        tem = rs.encode(decmsg)
        self.assertEqual(encmsg, tem, msg="encoded does not match expected")

        tdm, rtem = rs.decode(tem)
        self.assertEqual(tdm, decmsg, msg="decoded does not match original")
        self.assertEqual(rtem,
                         tem,
                         msg="decoded mesecc does not match original")

        tem1 = bytearray(tem)  # Clone a copy

        # Encoding and decoding intact message seem OK, so test errors
        numerrs = tt >> 1  # Inject tt/2 errors (expected to recover fully)
        for i in sample(range(nn), numerrs):  # inject errors in random places
            tem1[i] ^= 0xff  # flip all 8 bits
        tdm, _ = rs.decode(tem1)
        self.assertEqual(tdm,
                         decmsg,
                         msg="decoded with errors does not match original")

        tem1 = bytearray(tem)  # Clone another copy
        numerrs += 1  # Inject tt/2 + 1 errors (expected to fail and detect it)
        for i in sample(range(nn), numerrs):  # Inject errors in random places
            tem1[i] ^= 0xff  # Flip all 8 bits
        # If this fails, it means excessive errors not detected
        self.assertRaises(ReedSolomonError, rs.decode, tem1)
Exemplo n.º 23
0
Arquivo: files.py Projeto: barleyj/tfc
    def update_delivery_time(self) -> None:
        """Calculate transmission time.

        Transmission time is based on average delays and settings.
        """
        packet_data = US_BYTE.join(
            [self.name, self.size, self.time_l, self.data])

        if len(packet_data) < 255:
            no_packets = 1
        else:
            packet_data = bytes(8) + packet_data
            packet_data = byte_padding(packet_data)
            no_packets = len(split_byte_string(packet_data, item_len=255))

        no_recipients = len(self.window)

        if self.settings.session_trickle:
            avg_delay = self.settings.trickle_stat_delay + (
                self.settings.trickle_rand_delay / 2)

            if self.settings.long_packet_rand_d:
                avg_delay += (self.settings.max_val_for_rand_d / 2)

            # Multiply by two as trickle sends a command packet between every file packet.
            total_time = 2 * no_recipients * no_packets * avg_delay

            # Add constant time queue load time
            total_time += no_packets * TRICKLE_QUEUE_CHECK_DELAY

        else:
            total_data = 0
            rs = RSCodec(2 * self.settings.session_ec_ratio)
            static_data_len = (
                1 + 24 + 8 + 16 + 24 + 256 + 16 + 1
            )  # header + nonce + harac-ct + tag + nonce + ass. p. ct  + tag + US_BYTE
            for c in self.window.window_contacts:
                data_len = static_data_len + (len(c.rx_account.encode()) +
                                              len(c.tx_account.encode()))
                enc_data_len = len(rs.encode((os.urandom(data_len))))
                total_data += (no_packets * enc_data_len)

            total_time = 0.0
            if not self.settings.local_testing_mode:
                bauds_in_byte = 10
                total_bauds = total_data * bauds_in_byte
                total_time += total_bauds / self.settings.session_if_speed

            total_time += no_packets * self.gateway.delay

            if self.settings.long_packet_rand_d:
                total_time += no_packets * (self.settings.max_val_for_rand_d /
                                            2)

        delta_seconds = datetime.timedelta(seconds=int(total_time))
        delivery_time = datetime.datetime(1, 1, 1) + delta_seconds

        # Format delivery time string
        if delivery_time.second == 0:
            self.time_s = '00s'
            self.time_l = b'00d 00h 00m 00s'
            return None

        time_l_str = ''
        self.time_s = ''

        for i in [(delivery_time.day - 1, 'd'), (delivery_time.hour, 'h'),
                  (delivery_time.minute, 'm'), (delivery_time.second, 's')]:
            if i[0] > 0:
                self.time_s += str(i[0]).zfill(2) + f'{i[1]} '
            time_l_str += str(i[0]).zfill(2) + f'{i[1]} '

        self.time_s = self.time_s.strip(' ')
        time_l_str.strip()
        self.time_l = time_l_str.encode()
Exemplo n.º 24
0
Arquivo: tcb.py Projeto: AJMartel/tfc
def txm_incoming(queues: Dict[bytes, 'Queue'],
                 settings: 'Settings',
                 unittest: bool = False) -> None:
    """Loop that places messages received from TxM to appropriate queues."""
    rs = RSCodec(2 * settings.session_serial_error_correction)

    q_to_tip = queues[TXM_INCOMING_QUEUE]
    m_to_rxm = queues[RXM_OUTGOING_QUEUE]
    c_to_rxm = queues[TXM_TO_RXM_QUEUE]
    q_to_im = queues[TXM_TO_IM_QUEUE]
    q_to_nh = queues[TXM_TO_NH_QUEUE]

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

            packet = q_to_tip.get()

            try:
                packet = bytes(rs.decode(packet))
            except ReedSolomonError:
                box_print(
                    "Warning! Failed to correct errors in received packet.",
                    head=1,
                    tail=1)
                continue

            ts = datetime.now().strftime("%m-%d / %H:%M:%S")
            header = packet[:1]

            if header == UNENCRYPTED_PACKET_HEADER:
                q_to_nh.put(packet[1:])

            elif header in [LOCAL_KEY_PACKET_HEADER, COMMAND_PACKET_HEADER]:
                p_type = 'local key' if header == LOCAL_KEY_PACKET_HEADER else 'command'
                print("{} - {} TxM > RxM".format(ts, p_type))
                c_to_rxm.put(packet)

            elif header in [MESSAGE_PACKET_HEADER, PUBLIC_KEY_PACKET_HEADER]:
                payload_len, p_type = {
                    PUBLIC_KEY_PACKET_HEADER: (KEY_LENGTH, 'pub key'),
                    MESSAGE_PACKET_HEADER: (MESSAGE_LENGTH, 'message')
                }[header]
                payload = packet[1:1 + payload_len]
                trailer = packet[1 + payload_len:]
                user, contact = trailer.split(US_BYTE)

                print("{} - {} TxM > {} > {}".format(ts, p_type, user.decode(),
                                                     contact.decode()))
                q_to_im.put((header, payload, user, contact))
                m_to_rxm.put(header + payload + ORIGIN_USER_HEADER + contact)

            elif header == EXPORTED_FILE_HEADER:
                payload = packet[1:]

                file_name = os.urandom(8).hex()
                while os.path.isfile(file_name):
                    file_name = os.urandom(8).hex()

                with open(file_name, 'wb+') as f:
                    f.write(payload)
                print("{} - Exported file from TxM as {}".format(
                    ts, file_name))

            if unittest:
                break
Exemplo n.º 25
0
 def __init__(self, **kwargs: Any) -> None:
     self.packets = []
     self.settings = GatewaySettings(**kwargs)
     self.rs = RSCodec(2 * self.settings.serial_error_correction)