示例#1
0
文件: packet.py 项目: gtog/tfc
def queue_file(window: 'TxWindow', settings: 'Settings',
               queues: 'QueueDict') -> None:
    """Ask file path and load file data.

    In TFC there are two ways to send a file.

    For traffic masking, the file is loaded and sent inside normal
    messages using assembly packet headers dedicated for file
    transmission. This transmission is much slower, so the File object
    will determine metadata about the transmission's estimated transfer
    time, number of packets and the name and size of file. This
    information is inserted to the first assembly packet so that the
    recipient can observe the transmission progress from file transfer
    window.

    When traffic masking is disabled, file transmission is much faster
    as the file is only encrypted and transferred over serial once
    before the Relay Program multi-casts the ciphertext to each
    specified recipient. See the send_file docstring (below) for more
    details.
    """
    path = ask_path_gui("Select file to send...", settings, get_file=True)

    if path.endswith(
        ('tx_contacts', 'tx_groups', 'tx_keys', 'tx_login_data', 'tx_settings',
         'rx_contacts', 'rx_groups', 'rx_keys', 'rx_login_data', 'rx_settings',
         'tx_serial_settings.json', 'nc_serial_settings.json',
         'rx_serial_settings.json', 'tx_onion_db')):
        raise FunctionReturn("Error: Can't send TFC database.",
                             head_clear=True)

    if not settings.traffic_masking:
        send_file(path, settings, queues, window)
        return

    file = File(path, window, settings)
    assembly_packets = split_to_assembly_packets(file.plaintext, FILE)

    if settings.confirm_sent_files:
        try:
            if not yes(
                    f"Send {file.name.decode()} ({file.size_hr}) to {window.type_print} {window.name} "
                    f"({len(assembly_packets)} packets, time: {file.time_hr})?"
            ):
                raise FunctionReturn("File selection aborted.",
                                     head_clear=True)
        except (EOFError, KeyboardInterrupt):
            raise FunctionReturn("File selection aborted.", head_clear=True)

    queue_assembly_packets(assembly_packets,
                           FILE,
                           settings,
                           queues,
                           window,
                           log_as_ph=True)
示例#2
0
    def test_small_file(self) -> None:
        # Setup
        input_data = os.urandom(5)
        with open('testfile.txt', 'wb+') as f:
            f.write(input_data)

        self.settings.traffic_masking           = True
        self.settings.multi_packet_random_delay = True

        # Test
        file = File('./testfile.txt', *self.args)

        self.assertEqual(file.name, b'testfile.txt')
        self.assertEqual(file.size_hr, '5.0B')
        self.assertEqual(len(file.plaintext), 114)
        self.assertIsInstance(file.plaintext, bytes)
示例#3
0
    def test_large_file_and_local_testing(self) -> None:
        # Setup
        input_data = os.urandom(2000)
        with open('testfile.txt', 'wb+') as f:
            f.write(input_data)

        self.settings.multi_packet_random_delay = True
        self.settings.local_testing_mode        = True
        self.window.window_contacts             = [create_contact(c) for c in ['Alice', 'Bob']]

        # Test
        file = File('./testfile.txt', *self.args)

        self.assertEqual(file.name, b'testfile.txt')
        self.assertEqual(len(file.plaintext), 2112)
        self.assertEqual(file.size_hr, '2.0KB')
        self.assertIsInstance(file.plaintext, bytes)
        self.assertEqual(file.time_hr, '0:01:48')