Ejemplo n.º 1
0
 def setUp(self):
     self.queues = gen_queue_dict()
     self.contact_list = ContactList(nicks=['Alice'])
Ejemplo n.º 2
0
class TestRxWindow(TFCTestCase):
    def setUp(self) -> None:
        """Pre-test actions."""
        self.contact_list = ContactList(
            nicks=['Alice', 'Bob', 'Charlie', LOCAL_ID])
        self.group_list = GroupList(groups=['test_group', 'test_group2'])
        self.settings = Settings()
        self.packet_list = PacketList()
        self.ts = datetime.fromtimestamp(1502750000)
        self.time = self.ts.strftime('%H:%M:%S.%f')[:-4]

        group = self.group_list.get_group('test_group')
        group.members = list(
            map(self.contact_list.get_contact_by_address_or_nick,
                ['Alice', 'Bob', 'Charlie']))

    def create_window(self, uid: bytes):
        """Create new RxWindow object."""
        return RxWindow(uid, self.contact_list, self.group_list, self.settings,
                        self.packet_list)

    def test_command_window_creation(self) -> None:
        window = self.create_window(WIN_UID_COMMAND)
        self.assertEqual(window.type, WIN_TYPE_COMMAND)
        self.assertEqual(window.name, WIN_TYPE_COMMAND)

    def test_file_window_creation(self) -> None:
        window = self.create_window(WIN_UID_FILE)
        self.assertEqual(window.type, WIN_TYPE_FILE)

    def test_contact_window_creation(self) -> None:
        window = self.create_window(nick_to_pub_key("Alice"))
        self.assertEqual(window.type, WIN_TYPE_CONTACT)
        self.assertEqual(window.window_contacts[0].onion_pub_key,
                         nick_to_pub_key("Alice"))
        self.assertEqual(window.name, 'Alice')

    def test_group_window_creation(self) -> None:
        window = self.create_window(group_name_to_group_id('test_group'))
        self.assertEqual(window.type, WIN_TYPE_GROUP)
        self.assertEqual(window.window_contacts[0].onion_pub_key,
                         nick_to_pub_key("Alice"))
        self.assertEqual(window.name, 'test_group')

    def test_invalid_uid_raises_se(self) -> None:
        self.assert_se(
            "Invalid window 'mfqwcylbmfqwcylbmfqwcylbmfqwcylbmfqwcylbmfqwcylbmfqwbfad'.",
            self.create_window, ONION_SERVICE_PUBLIC_KEY_LENGTH * b'a')

        self.assert_se("Invalid window '2dnAMoWNfTXAJ'.", self.create_window,
                       GROUP_ID_LENGTH * b'a')

        self.assert_se("Invalid window '<unable to encode>'.",
                       self.create_window, b'bad_uid')

    def test_window_iterates_over_message_tuples(self) -> None:
        # Setup
        window = self.create_window(nick_to_pub_key("Alice"))
        window.message_log = 5 * [
            (datetime.now(), 'Lorem ipsum', nick_to_pub_key("Alice"),
             ORIGIN_CONTACT_HEADER, False, False)
        ]

        # Test
        for mt in window:
            self.assertEqual(mt[1:], ("Lorem ipsum", nick_to_pub_key("Alice"),
                                      ORIGIN_CONTACT_HEADER, False, False))

    def test_len_returns_number_of_messages_in_window(self) -> None:
        # Setup
        window = self.create_window(nick_to_pub_key("Alice"))
        window.message_log = 5 * [
            (datetime.now(), "Lorem ipsum", nick_to_pub_key("Alice"),
             ORIGIN_CONTACT_HEADER, False, False)
        ]

        # Test
        self.assertEqual(len(window), 5)

    def test_remove_contacts(self) -> None:
        # Setup
        window = self.create_window(group_name_to_group_id('test_group'))

        # Test
        self.assertEqual(len(window.window_contacts), 3)
        self.assertIsNone(
            window.remove_contacts([
                nick_to_pub_key("Alice"),
                nick_to_pub_key("Bob"),
                nick_to_pub_key("DoesNotExist")
            ]))
        self.assertEqual(len(window.window_contacts), 1)

    def test_add_contacts(self) -> None:
        # Setup
        window = self.create_window(group_name_to_group_id('test_group'))
        window.window_contacts = [
            self.contact_list.get_contact_by_address_or_nick('Alice')
        ]

        # Test
        self.assertIsNone(
            window.add_contacts([
                nick_to_pub_key("Alice"),
                nick_to_pub_key("Bob"),
                nick_to_pub_key("DoesNotExist")
            ]))
        self.assertEqual(len(window.window_contacts), 2)

    def test_reset_window(self) -> None:
        # Setup
        window = self.create_window(group_name_to_group_id('test_group'))
        window.message_log = \
            [(datetime.now(), "Hi everybody", nick_to_pub_key("Alice"), ORIGIN_USER_HEADER,    False, False),
             (datetime.now(), "Hi David",     nick_to_pub_key("Alice"), ORIGIN_CONTACT_HEADER, False, False),
             (datetime.now(), "Hi David",     nick_to_pub_key("Bob"),   ORIGIN_CONTACT_HEADER, False, False)]

        # Test
        self.assertIsNone(window.reset_window())
        self.assertEqual(len(window), 0)

    def test_has_contact(self) -> None:
        window = self.create_window(group_name_to_group_id('test_group'))
        self.assertTrue(window.has_contact(nick_to_pub_key("Alice")))
        self.assertFalse(window.has_contact(nick_to_pub_key("DoesNotExist")))

    def test_create_handle_dict(self) -> None:
        # Setup
        window = self.create_window(group_name_to_group_id('test_group'))
        message_log = [
            (datetime.now(), "Lorem ipsum", nick_to_pub_key("Alice"),
             ORIGIN_CONTACT_HEADER, False, False),
            (datetime.now(), "Lorem ipsum", nick_to_pub_key("Bob"),
             ORIGIN_USER_HEADER, False, False),
            (datetime.now(), "Lorem ipsum", nick_to_pub_key("Charlie"),
             ORIGIN_CONTACT_HEADER, False, False),
            (datetime.now(), "Lorem ipsum", nick_to_pub_key("Charlie"),
             ORIGIN_CONTACT_HEADER, True, False),
            (datetime.now(), "Lorem ipsum", nick_to_pub_key("Charlie"),
             ORIGIN_CONTACT_HEADER, False, False),
            (datetime.now(), "Lorem ipsum", nick_to_pub_key("David"),
             ORIGIN_CONTACT_HEADER, False, False),
            (datetime.now(), "Lorem ipsum", nick_to_pub_key("Eric"),
             ORIGIN_CONTACT_HEADER, False, False)
        ]

        # Test
        self.assertIsNone(window.create_handle_dict(message_log))
        self.assertEqual(
            window.handle_dict, {
                nick_to_pub_key("Alice"): 'Alice',
                nick_to_pub_key("Bob"): 'Bob',
                nick_to_pub_key("Charlie"): 'Charlie',
                nick_to_pub_key("David"): nick_to_short_address("David"),
                nick_to_pub_key("Eric"): nick_to_short_address("Eric")
            })

    def test_get_command_handle(self) -> None:
        # Setup
        window = self.create_window(WIN_UID_COMMAND)
        window.is_active = True

        # Test
        self.assertEqual(
            window.get_handle(self.ts, WIN_UID_COMMAND, ORIGIN_USER_HEADER),
            f"{self.time} -!- ")

    def test_get_contact_handle(self) -> None:
        # Setup
        window = self.create_window(nick_to_pub_key("Alice"))
        window.is_active = True
        window.handle_dict = {nick_to_pub_key("Alice"): 'Alice'}

        # Test
        self.assertEqual(
            window.get_handle(self.ts, nick_to_pub_key("Alice"),
                              ORIGIN_USER_HEADER), f"{self.time}    Me: ")
        self.assertEqual(
            window.get_handle(self.ts, nick_to_pub_key("Alice"),
                              ORIGIN_CONTACT_HEADER), f"{self.time} Alice: ")

        window.is_active = False
        self.assertEqual(
            window.get_handle(self.ts, nick_to_pub_key("Alice"),
                              ORIGIN_USER_HEADER),
            f"{self.time} Me (private message): ")
        self.assertEqual(
            window.get_handle(self.ts, nick_to_pub_key("Alice"),
                              ORIGIN_CONTACT_HEADER),
            f"{self.time} Alice (private message): ")

    def test_get_group_contact_handle(self) -> None:
        # Setup
        window = self.create_window(group_name_to_group_id('test_group'))
        window.is_active = True
        window.handle_dict = {
            nick_to_pub_key("Alice"): 'Alice',
            nick_to_pub_key("Charlie"): 'Charlie',
            nick_to_pub_key("David"): nick_to_short_address("David"),
            nick_to_pub_key("Eric"): nick_to_short_address("Eric")
        }

        # Test
        self.assertEqual(
            window.get_handle(self.ts, nick_to_pub_key("Alice"),
                              ORIGIN_USER_HEADER), f"{self.time}      Me: ")
        self.assertEqual(
            window.get_handle(self.ts, nick_to_pub_key("Charlie"),
                              ORIGIN_CONTACT_HEADER), f"{self.time} Charlie: ")

        window.is_active = False
        self.assertEqual(
            window.get_handle(self.ts, nick_to_pub_key("Alice"),
                              ORIGIN_USER_HEADER),
            f"{self.time} Me (group test_group): ")
        self.assertEqual(
            window.get_handle(self.ts, nick_to_pub_key("Charlie"),
                              ORIGIN_CONTACT_HEADER),
            f"{self.time} Charlie (group test_group): ")

    @mock.patch('time.sleep', return_value=None)
    def test_print_to_inactive_window_preview_on_short_message(self,
                                                               _: Any) -> None:
        # Setup
        window = self.create_window(nick_to_pub_key("Alice"))
        window.handle_dict = {nick_to_pub_key("Alice"): 'Alice'}
        window.is_active = False
        window.settings = Settings(new_message_notify_preview=True)
        msg_tuple = (self.ts, "Hi Bob", nick_to_pub_key("Bob"),
                     ORIGIN_USER_HEADER, False, False)

        # Test
        self.assert_prints(
            f"{BOLD_ON}{self.time} Me (private message): {NORMAL_TEXT}"
            f"Hi Bob\n{CURSOR_UP_ONE_LINE}{CLEAR_ENTIRE_LINE}", window.print,
            msg_tuple)

    @mock.patch('time.sleep', return_value=None)
    def test_print_to_inactive_window_preview_on_long_message(self,
                                                              _: Any) -> None:
        # Setup
        window = self.create_window(nick_to_pub_key("Alice"))
        window.is_active = False
        window.handle_dict = {nick_to_pub_key("Alice"): 'Alice'}
        window.settings = Settings(new_message_notify_preview=True)
        long_message = (
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque consequat libero et lao"
            "reet egestas. Aliquam a arcu malesuada, elementum metus eget, elementum mi. Vestibulum i"
            "d arcu sem. Ut sodales odio sed viverra mollis. Praesent gravida ante tellus, pellentesq"
            "ue venenatis massa placerat quis. Nullam in magna porta, hendrerit sem vel, dictum ipsum"
            ". Ut sagittis, ipsum ut bibendum ornare, ex lorem congue metus, vel posuere metus nulla "
            "at augue.")
        msg_tuple = (self.ts, long_message, nick_to_pub_key("Bob"),
                     ORIGIN_USER_HEADER, False, False)

        # Test
        self.assert_prints(
            f"{BOLD_ON}{self.time} Me (private message): {NORMAL_TEXT}Lorem ipsum dolor sit "
            f"amet, consectetu…\n{CURSOR_UP_ONE_LINE}{CLEAR_ENTIRE_LINE}",
            window.print, msg_tuple)

    @mock.patch('time.sleep', return_value=None)
    def test_print_to_inactive_window_preview_off(self, _: Any) -> None:
        # Setup
        window = self.create_window(nick_to_pub_key("Alice"))
        window.is_active = False
        window.handle_dict = {nick_to_pub_key("Alice"): 'Alice'}
        window.settings = Settings(new_message_notify_preview=False)
        msg_tuple = (self.ts, "Hi Bob", nick_to_pub_key("Bob"),
                     ORIGIN_USER_HEADER, False, False)

        # Test
        self.assert_prints(
            f"{BOLD_ON}{self.time} Me (private message): {NORMAL_TEXT}{BOLD_ON}1 unread message{NORMAL_TEXT}\n"
            f"{CURSOR_UP_ONE_LINE}{CLEAR_ENTIRE_LINE}", window.print,
            msg_tuple)

    def test_print_to_active_window_no_date_change(self) -> None:
        # Setup
        window = self.create_window(nick_to_pub_key("Alice"))
        window.previous_msg_ts = datetime.fromtimestamp(1502750000)
        window.is_active = True
        window.handle_dict = {nick_to_pub_key("Bob"): 'Bob'}
        window.settings = Settings(new_message_notify_preview=False)
        msg_tuple = (self.ts, "Hi Alice", nick_to_pub_key("Bob"),
                     ORIGIN_CONTACT_HEADER, False, False)

        # Test
        self.assert_prints(
            f"{BOLD_ON}{self.time} Bob: {NORMAL_TEXT}Hi Alice\n", window.print,
            msg_tuple)

    def test_print_to_active_window_with_date_change_and_whisper(self) -> None:
        # Setup
        window = self.create_window(nick_to_pub_key("Alice"))
        window.previous_msg_ts = datetime.fromtimestamp(1501750000)
        window.is_active = True
        window.handle_dict = {nick_to_pub_key("Bob"): 'Bob'}
        window.settings = Settings(new_message_notify_preview=False)
        msg_tuple = (self.ts, "Hi Alice", nick_to_pub_key("Bob"),
                     ORIGIN_CONTACT_HEADER, True, False)
        self.time = self.ts.strftime('%H:%M:%S.%f')[:-4]

        # Test
        self.assert_prints(
            f"""\
{BOLD_ON}00:00 -!- Day changed to 2017-08-15{NORMAL_TEXT}
{BOLD_ON}{self.time} Bob (whisper): {NORMAL_TEXT}Hi Alice
""", window.print, msg_tuple)

    def test_print_to_active_window_with_date_change_and_whisper_empty_message(
            self) -> None:
        # Setup
        window = self.create_window(nick_to_pub_key("Alice"))
        window.previous_msg_ts = datetime.fromtimestamp(1501750000)
        window.is_active = True
        window.handle_dict = {nick_to_pub_key("Bob"): 'Bob'}
        window.settings = Settings(new_message_notify_preview=False)
        msg_tuple = (self.ts, " ", nick_to_pub_key("Bob"),
                     ORIGIN_CONTACT_HEADER, True, False)

        # Test
        self.assert_prints(
            f"""\
{BOLD_ON}00:00 -!- Day changed to 2017-08-15{NORMAL_TEXT}
{BOLD_ON}{self.time} Bob (whisper): {NORMAL_TEXT}
""", window.print, msg_tuple)

    @mock.patch('time.sleep', return_value=None)
    def test_print_new(self, _: Any) -> None:
        # Setup
        window = self.create_window(nick_to_pub_key("Alice"))

        # Test
        self.assertIsNone(
            window.add_new(self.ts,
                           "Hi Alice",
                           nick_to_pub_key("Bob"),
                           ORIGIN_CONTACT_HEADER,
                           output=True))
        self.assertEqual(len(window.message_log), 1)
        self.assertEqual(window.handle_dict[nick_to_pub_key("Bob")], 'Bob')

    def test_redraw_message_window(self) -> None:
        # Setup
        window = self.create_window(nick_to_pub_key("Alice"))
        window.is_active = True
        window.message_log = [(self.ts, "Hi Alice", nick_to_pub_key("Bob"),
                               ORIGIN_CONTACT_HEADER, False, False)]
        window.unread_messages = 1

        # Test
        self.assert_prints(
            f"""\
{CLEAR_ENTIRE_SCREEN}{CURSOR_LEFT_UP_CORNER}
------------------------------- Unread Messages --------------------------------

{BOLD_ON}{self.time}   Bob: {NORMAL_TEXT}Hi Alice
""", window.redraw)
        self.assertEqual(window.unread_messages, 0)

    def test_redraw_empty_window(self) -> None:
        # Setup
        window = self.create_window(nick_to_pub_key("Alice"))
        window.is_active = True
        window.message_log = []

        # Test
        self.assert_prints(
            f"""\
{CLEAR_ENTIRE_SCREEN}{CURSOR_LEFT_UP_CORNER}
{BOLD_ON}                   This window for Alice is currently empty.                    {NORMAL_TEXT}\n
""", window.redraw)

    @mock.patch('time.sleep', return_value=None)
    def test_redraw_file_win(self, _: Any) -> None:
        # Setup
        self.packet_list.packets = [
            Packet(type=FILE,
                   name='testfile.txt',
                   assembly_pt_list=5 * [b'a'],
                   packets=10,
                   size="100.0KB",
                   contact=create_contact('Bob')),
            Packet(type=FILE,
                   name='testfile2.txt',
                   assembly_pt_list=7 * [b'a'],
                   packets=100,
                   size="15.0KB",
                   contact=create_contact('Charlie'))
        ]

        # Test
        window = self.create_window(WIN_UID_FILE)
        self.assert_prints(
            f"""\

File name        Size       Sender     Complete    
────────────────────────────────────────────────────────────────────────────────
testfile.txt     100.0KB    Bob        50.00%      
testfile2.txt    15.0KB     Charlie    7.00%       

{6*(CURSOR_UP_ONE_LINE+CLEAR_ENTIRE_LINE)}""", window.redraw_file_win)

    @mock.patch('time.sleep', return_value=None)
    def test_redraw_empty_file_win(self, _: Any) -> None:
        # Setup
        self.packet_list.packet_l = []

        # Test
        window = self.create_window(WIN_UID_FILE)
        self.assert_prints(
            f"""\

{BOLD_ON}                  No file transmissions currently in progress.                  {NORMAL_TEXT}

{3*(CURSOR_UP_ONE_LINE+CLEAR_ENTIRE_LINE)}""", window.redraw_file_win)
Ejemplo n.º 3
0
class TestChContactSetting(TFCTestCase):

    def setUp(self) -> None:
        """Pre-test actions."""
        self.ts           = datetime.fromtimestamp(1502750000)
        self.contact_list = ContactList(nicks=['Alice', 'Bob'])
        self.group_list   = GroupList(groups=['test_group', 'test_group2'])
        self.window_list  = WindowList(contact_list=self.contact_list,
                                       group_list=self.group_list)
        self.args         = self.ts, self.window_list, self.contact_list, self.group_list

    def test_invalid_window_raises_se(self) -> None:
        # Setup
        cmd_data          = ENABLE + nick_to_pub_key("Bob")
        header            = CH_LOGGING
        self.contact_list = ContactList(nicks=['Alice'])
        self.window_list  = WindowList(contact_list=self.contact_list,
                                       group_list=self.group_list)
        # Test
        self.assert_se(f"Error: Found no window for '{nick_to_short_address('Bob')}'.",
                       ch_contact_s, cmd_data, *self.args, header)

    def test_setting_change_contact(self) -> None:
        # Setup
        self.window                 = self.window_list.get_window(nick_to_pub_key("Bob"))
        self.window.type            = WIN_TYPE_CONTACT
        self.window.type_print      = 'contact'
        self.window.window_contacts = self.contact_list.contacts
        bob                         = self.contact_list.get_contact_by_address_or_nick("Bob")

        # Test
        for attr, header in [('log_messages',   CH_LOGGING),
                             ('notifications',  CH_NOTIFY),
                             ('file_reception', CH_FILE_RECV)]:
            for s in [ENABLE, ENABLE, DISABLE, DISABLE]:
                cmd_data = s + nick_to_pub_key("Bob")
                self.assertIsNone(ch_contact_s(cmd_data, *self.args, header))
                self.assertEqual(bob.__getattribute__(attr), (s == ENABLE))

    def test_setting_change_group(self) -> None:
        # Setup
        self.window                 = self.window_list.get_window(group_name_to_group_id('test_group'))
        self.window.type            = WIN_TYPE_GROUP
        self.window.type_print      = 'group'
        self.window.window_contacts = self.group_list.get_group('test_group').members

        # Test
        for attr, header in [('log_messages',   CH_LOGGING),
                             ('notifications',  CH_NOTIFY),
                             ('file_reception', CH_FILE_RECV)]:
            for s in [ENABLE, ENABLE, DISABLE, DISABLE]:
                cmd_data = s + group_name_to_group_id('test_group')
                self.assertIsNone(ch_contact_s(cmd_data, *self.args, header))

                if header in [CH_LOGGING, CH_NOTIFY]:
                    self.assertEqual(self.group_list.get_group('test_group').__getattribute__(attr), (s == ENABLE))

                if header == CH_FILE_RECV:
                    for m in self.group_list.get_group('test_group').members:
                        self.assertEqual(m.file_reception, (s == ENABLE))

    def test_setting_change_all(self) -> None:
        # Setup
        self.window                 = self.window_list.get_window(nick_to_pub_key("Bob"))
        self.window.type            = WIN_TYPE_CONTACT
        self.window.type_print      = 'contact'
        self.window.window_contacts = self.contact_list.contacts

        # Test
        for attr, header in [('log_messages',   CH_LOGGING),
                             ('notifications',  CH_NOTIFY),
                             ('file_reception', CH_FILE_RECV)]:
            for s in [ENABLE, ENABLE, DISABLE, DISABLE]:
                cmd_data = s.upper() + US_BYTE
                self.assertIsNone(ch_contact_s(cmd_data, *self.args, header))

                if header in [CH_LOGGING, CH_NOTIFY]:
                    for c in self.contact_list.get_list_of_contacts():
                        self.assertEqual(c.__getattribute__(attr), (s == ENABLE))
                    for g in self.group_list.groups:
                        self.assertEqual(g.__getattribute__(attr), (s == ENABLE))

                if header == CH_FILE_RECV:
                    for c in self.contact_list.get_list_of_contacts():
                        self.assertEqual(c.__getattribute__(attr), (s == ENABLE))
Ejemplo n.º 4
0
class TestLocalKey(TFCTestCase):
    def setUp(self) -> None:
        """Pre-test actions."""
        self.contact_list = ContactList()
        self.settings = Settings()
        self.queues = gen_queue_dict()
        self.args = self.contact_list, self.settings, self.queues

    def tearDown(self) -> None:
        """Post-test actions."""
        tear_queues(self.queues)

    def test_new_local_key_when_traffic_masking_is_enabled_raises_soft_error(
            self) -> None:
        self.settings.traffic_masking = True
        self.contact_list.contacts = [create_contact(LOCAL_ID)]
        self.assert_se("Error: Command is disabled during traffic masking.",
                       new_local_key, *self.args)

    @mock.patch('time.sleep', return_value=None)
    @mock.patch('builtins.input', side_effect=['bad', '', '61'])
    @mock.patch('os.getrandom',
                side_effect=[
                    SYMMETRIC_KEY_LENGTH * b'a', SYMMETRIC_KEY_LENGTH * b'a',
                    SYMMETRIC_KEY_LENGTH * b'a', XCHACHA20_NONCE_LENGTH * b'a',
                    SYMMETRIC_KEY_LENGTH * b'a', SYMMETRIC_KEY_LENGTH * b'a'
                ])
    @mock.patch('os.urandom', return_value=CONFIRM_CODE_LENGTH * b'a')
    @mock.patch('os.system', return_value=None)
    def test_new_local_key(self, *_: Any) -> None:
        # Setup
        self.settings.nc_bypass_messages = False
        self.settings.traffic_masking = False

        # Test
        self.assertIsNone(new_local_key(*self.args))
        local_contact = self.contact_list.get_contact_by_pub_key(LOCAL_PUBKEY)

        self.assertEqual(local_contact.onion_pub_key, LOCAL_PUBKEY)
        self.assertEqual(local_contact.nick, LOCAL_NICK)
        self.assertEqual(
            local_contact.tx_fingerprint,
            blake2b(b58encode(blake2b(SYMMETRIC_KEY_LENGTH * b'a')).encode()))
        self.assertEqual(local_contact.rx_fingerprint,
                         bytes(FINGERPRINT_LENGTH))
        self.assertFalse(local_contact.log_messages)
        self.assertFalse(local_contact.file_reception)
        self.assertFalse(local_contact.notifications)

        self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 1)

        cmd, account, tx_key, rx_key, tx_hek, rx_hek = self.queues[
            KEY_MANAGEMENT_QUEUE].get()

        self.assertEqual(cmd, KDB_ADD_ENTRY_HEADER)
        self.assertEqual(account, LOCAL_PUBKEY)
        for key in [tx_key, rx_key, tx_hek, rx_hek]:
            self.assertIsInstance(key, bytes)
            self.assertEqual(len(key), SYMMETRIC_KEY_LENGTH)

    @mock.patch('time.sleep', return_value=None)
    @mock.patch('builtins.input', side_effect=KeyboardInterrupt)
    @mock.patch('os.getrandom', lambda x, flags: x * b'a')
    def test_keyboard_interrupt_raises_soft_error(self, *_: Any) -> None:
        self.assert_se("Local key setup aborted.", new_local_key, *self.args)
Ejemplo n.º 5
0
    def test_loop(self):
        # Setup
        queues                 = gen_queue_dict()
        settings               = Settings(traffic_masking=False)
        gateway                = Gateway()
        key_list               = KeyList()
        window                 = TxWindow(log_messages=True)
        contact_list           = ContactList(nicks=['Alice', LOCAL_ID])
        window.contact_list    = contact_list
        window.window_contacts = [contact_list.get_contact_by_address_or_nick('Alice')]
        user_input             = UserInput(plaintext='test')

        delay = 0.01

        def queue_delayer():
            """Place datagrams into queue after delay."""
            time.sleep(delay)
            queue_command(b'test', settings, queues)

            time.sleep(delay)
            queue_to_nc(PUBLIC_KEY_DATAGRAM_HEADER + TFC_PUBLIC_KEY_LENGTH * b'a' + nick_to_pub_key('Alice'),  # 1
                        queues[RELAY_PACKET_QUEUE])

            time.sleep(delay)
            queue_to_nc(UNENCRYPTED_DATAGRAM_HEADER + UNENCRYPTED_WIPE_COMMAND, queues[RELAY_PACKET_QUEUE])  # 2

            time.sleep(delay)
            queue_to_nc(UNENCRYPTED_DATAGRAM_HEADER + UNENCRYPTED_EXIT_COMMAND, queues[RELAY_PACKET_QUEUE])  # 3

            time.sleep(delay)
            queues[KEY_MANAGEMENT_QUEUE].put((KDB_ADD_ENTRY_HEADER, LOCAL_PUBKEY,  # 4
                                              SYMMETRIC_KEY_LENGTH * b'a', SYMMETRIC_KEY_LENGTH * b'a',
                                              SYMMETRIC_KEY_LENGTH * b'a', SYMMETRIC_KEY_LENGTH * b'a'))

            time.sleep(delay)
            queue_message(user_input, window, settings, queues)  # 5

            time.sleep(delay)
            queue_message(user_input, window, settings, queues)  # 6

            time.sleep(delay)
            queues[KEY_MANAGEMENT_QUEUE].put((KDB_ADD_ENTRY_HEADER, nick_to_pub_key('Alice'),
                                              SYMMETRIC_KEY_LENGTH * b'a', SYMMETRIC_KEY_LENGTH * b'a',
                                              SYMMETRIC_KEY_LENGTH * b'a', SYMMETRIC_KEY_LENGTH * b'a'))

            time.sleep(delay)
            queue_message(user_input, window, settings, queues)  # 7

            time.sleep(delay)
            queue_message(user_input, window, settings, queues)  # 8

            time.sleep(delay)
            queues[SENDER_MODE_QUEUE].put(settings)

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

        # Test
        settings, m_buffer = standard_sender_loop(queues, gateway, key_list)
        self.assertIsInstance(settings, Settings)
        self.assertEqual(m_buffer,                   {nick_to_pub_key('Alice'): []})
        self.assertEqual(len(gateway.packets),       8)
        self.assertEqual(queues[EXIT_QUEUE].qsize(), 2)

        # Teardown
        tear_queues(queues)
Ejemplo n.º 6
0
    def test_loop(self):
        # Setup
        queues = {
            MESSAGE_PACKET_QUEUE: Queue(),
            FILE_PACKET_QUEUE: Queue(),
            COMMAND_PACKET_QUEUE: Queue(),
            NH_PACKET_QUEUE: Queue(),
            LOG_PACKET_QUEUE: Queue(),
            NOISE_PACKET_QUEUE: Queue(),
            NOISE_COMMAND_QUEUE: Queue(),
            KEY_MANAGEMENT_QUEUE: Queue(),
            WINDOW_SELECT_QUEUE: Queue(),
            EXIT_QUEUE: Queue()
        }

        settings = Settings(session_traffic_masking=True)
        gateway = Gateway()
        key_list = KeyList(nicks=['Alice', LOCAL_ID])
        window = TxWindow(log_messages=True)
        contact_list = ContactList(nicks=['Alice', LOCAL_ID])
        window.contact_list = contact_list
        window.window_contacts = [contact_list.get_contact('Alice')]
        user_input = UserInput(plaintext='test')

        queue_message(user_input, window, settings,
                      queues[MESSAGE_PACKET_QUEUE])
        queue_message(user_input, window, settings,
                      queues[MESSAGE_PACKET_QUEUE])
        queue_message(user_input, window, settings,
                      queues[MESSAGE_PACKET_QUEUE])
        queue_command(b'test', settings, queues[COMMAND_PACKET_QUEUE])
        queue_command(b'test', settings, queues[COMMAND_PACKET_QUEUE])
        queue_command(b'test', settings, queues[COMMAND_PACKET_QUEUE], window)
        queue_to_nh(UNENCRYPTED_PACKET_HEADER + UNENCRYPTED_EXIT_COMMAND,
                    settings, queues[NH_PACKET_QUEUE])
        queue_to_nh(UNENCRYPTED_PACKET_HEADER + UNENCRYPTED_WIPE_COMMAND,
                    settings, queues[NH_PACKET_QUEUE])

        def queue_delayer():
            time.sleep(0.1)
            queues[WINDOW_SELECT_QUEUE].put((window, True))

        # Test
        threading.Thread(target=queue_delayer).start()
        self.assertIsNone(
            sender_loop(queues, settings, gateway, key_list, unittest=True))

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

        self.assertIsNone(
            sender_loop(queues, settings, gateway, key_list, unittest=True))

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

        self.assertIsNone(
            sender_loop(queues, settings, gateway, key_list, unittest=True))

        self.assertEqual(len(gateway.packets), 8)
        self.assertEqual(queues[EXIT_QUEUE].qsize(), 2)

        # Teardown
        for key in queues:
            while not queues[key].empty():
                queues[key].get()
            time.sleep(0.1)
            queues[key].close()
Ejemplo n.º 7
0
class TestKeyExchange(TFCTestCase):
    def setUp(self) -> None:
        """Pre-test actions."""
        self.contact_list = ContactList(nicks=[LOCAL_ID])
        self.settings = Settings()
        self.queues = gen_queue_dict()
        self.args = self.contact_list, self.settings, self.queues

    def tearDown(self) -> None:
        """Post-test actions."""
        tear_queues(self.queues)

    @mock.patch('shutil.get_terminal_size', return_value=[200, 200])
    @mock.patch('builtins.input',
                return_value=b58encode(bytes(TFC_PUBLIC_KEY_LENGTH),
                                       public_key=True))
    def test_zero_public_key_raises_soft_error(self, *_: Any) -> None:
        self.assert_se("Error: Zero public key", start_key_exchange,
                       nick_to_pub_key("Alice"), 'Alice', *self.args)

    @mock.patch('shutil.get_terminal_size', return_value=[200, 200])
    @mock.patch('builtins.input',
                return_value=b58encode((TFC_PUBLIC_KEY_LENGTH - 1) * b'a',
                                       public_key=True))
    def test_invalid_public_key_length_raises_soft_error(self,
                                                         *_: Any) -> None:
        self.assert_se("Error: Invalid public key length", start_key_exchange,
                       nick_to_pub_key("Alice"), 'Alice', *self.args)

    @mock.patch(
        'builtins.input',
        side_effect=[
            '',  # Empty message should resend key
            VALID_ECDHE_PUB_KEY[:-1],  # Short key should fail
            VALID_ECDHE_PUB_KEY + 'a',  # Long key should fail
            VALID_ECDHE_PUB_KEY[:-1] + 'a',  # Invalid key should fail
            VALID_ECDHE_PUB_KEY,  # Correct key
            'No'
        ])  # Fingerprint mismatch)
    @mock.patch('time.sleep', return_value=None)
    @mock.patch('shutil.get_terminal_size', return_value=[200, 200])
    def test_fingerprint_mismatch_raises_soft_error(self, *_: Any) -> None:
        self.assert_se("Error: Fingerprint mismatch", start_key_exchange,
                       nick_to_pub_key("Alice"), 'Alice', *self.args)

    @mock.patch(
        'builtins.input',
        side_effect=[
            '',  # Resend public key
            VALID_ECDHE_PUB_KEY,  # Correct key
            'Yes',  # Fingerprint match
            '',  # Resend contact data
            'ff',  # Invalid confirmation code
            blake2b(nick_to_pub_key('Alice'),
                    digest_size=CONFIRM_CODE_LENGTH).hex()
        ])
    @mock.patch('shutil.get_terminal_size', return_value=[200, 200])
    @mock.patch('time.sleep', return_value=None)
    def test_successful_exchange(self, *_: Any) -> None:
        self.assertIsNone(
            start_key_exchange(nick_to_pub_key("Alice"), 'Alice', *self.args))

        contact = self.contact_list.get_contact_by_pub_key(
            nick_to_pub_key("Alice"))
        self.assertEqual(contact.onion_pub_key, nick_to_pub_key("Alice"))
        self.assertEqual(contact.nick, 'Alice')
        self.assertEqual(contact.kex_status, KEX_STATUS_VERIFIED)
        self.assertIsInstance(contact.tx_fingerprint, bytes)
        self.assertIsInstance(contact.rx_fingerprint, bytes)
        self.assertEqual(len(contact.tx_fingerprint), FINGERPRINT_LENGTH)
        self.assertEqual(len(contact.rx_fingerprint), FINGERPRINT_LENGTH)
        self.assertFalse(contact.log_messages)
        self.assertFalse(contact.file_reception)
        self.assertTrue(contact.notifications)

        self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 2)
        self.assertEqual(self.queues[RELAY_PACKET_QUEUE].qsize(), 2)

        cmd, account, tx_key, rx_key, tx_hek, rx_hek = self.queues[
            KEY_MANAGEMENT_QUEUE].get()

        self.assertEqual(cmd, KDB_ADD_ENTRY_HEADER)
        self.assertEqual(account, nick_to_pub_key("Alice"))
        self.assertEqual(len(tx_key), SYMMETRIC_KEY_LENGTH)

        for key in [tx_key, rx_key, tx_hek, rx_hek]:
            self.assertIsInstance(key, bytes)
            self.assertEqual(len(key), SYMMETRIC_KEY_LENGTH)

    @mock.patch(
        'builtins.input',
        side_effect=[
            '',  # Resend public key
            VALID_ECDHE_PUB_KEY,  # Correct key
            KeyboardInterrupt,  # Skip fingerprint verification
            '',  # Manual proceed for warning message
            blake2b(nick_to_pub_key('Alice'),
                    digest_size=CONFIRM_CODE_LENGTH).hex()
        ])
    @mock.patch('time.sleep', return_value=None)
    @mock.patch('shutil.get_terminal_size', return_value=[200, 200])
    def test_successful_exchange_skip_fingerprint_verification(
            self, *_: Any) -> None:
        self.assertIsNone(
            start_key_exchange(nick_to_pub_key("Alice"), 'Alice', *self.args))

        contact = self.contact_list.get_contact_by_pub_key(
            nick_to_pub_key("Alice"))
        self.assertEqual(contact.onion_pub_key, nick_to_pub_key("Alice"))
        self.assertEqual(contact.nick, 'Alice')
        self.assertEqual(contact.kex_status, KEX_STATUS_UNVERIFIED)

    @mock.patch(
        'os.getrandom',
        side_effect=[SYMMETRIC_KEY_LENGTH * b'a', SYMMETRIC_KEY_LENGTH * b'a'])
    @mock.patch('builtins.input',
                side_effect=[
                    KeyboardInterrupt, VALID_ECDHE_PUB_KEY, 'Yes',
                    blake2b(nick_to_pub_key('Alice'),
                            digest_size=CONFIRM_CODE_LENGTH).hex()
                ])
    @mock.patch('time.sleep', return_value=None)
    @mock.patch('shutil.get_terminal_size', return_value=[200, 200])
    def test_successful_exchange_with_previous_key(self, *_: Any) -> None:
        # Test caching of private key
        self.assert_se("Key exchange interrupted.", start_key_exchange,
                       nick_to_pub_key('Alice'), 'Alice', *self.args)

        alice = self.contact_list.get_contact_by_address_or_nick('Alice')
        self.assertEqual(alice.kex_status, KEX_STATUS_PENDING)

        # Test re-using private key
        self.assertIsNone(
            start_key_exchange(nick_to_pub_key('Alice'), 'Alice', *self.args))
        self.assertIsNone(alice.tfc_private_key)
        self.assertEqual(alice.kex_status, KEX_STATUS_VERIFIED)
Ejemplo n.º 8
0
 def setUp(self) -> None:
     """Pre-test actions."""
     self.queues       = gen_queue_dict()
     self.contact_list = ContactList(nicks=['Alice'])
Ejemplo n.º 9
0
class TestKeyExchange(TFCTestCase):
    def setUp(self):
        self.o_input = builtins.input

        self.contact_list = ContactList()
        self.settings = Settings()
        self.queues = {
            COMMAND_PACKET_QUEUE: Queue(),
            NH_PACKET_QUEUE: Queue(),
            KEY_MANAGEMENT_QUEUE: Queue()
        }

    def tearDown(self):
        builtins.input = self.o_input

        for key in self.queues.keys():
            while not self.queues[key].empty():
                self.queues[key].get()
            time.sleep(0.1)
            self.queues[key].close()

    def test_zero_public_key_raises_fr(self):
        # Setup
        builtins.input = lambda _: b58encode(bytes(32))

        # Test
        self.assertFR("Error: Zero public key", start_key_exchange,
                      '*****@*****.**', '*****@*****.**', 'Alice',
                      self.contact_list, self.settings, self.queues)

    def test_raises_fr_during_fingerprint_mismatch(self):
        # Setup
        input_list = [
            'resend',  # Resend should resend key
            '5JCVapni8CR2PEXr5v92cCY2QgSd4cztR2v3L3vK2eair7dGHi',  # Short key should fail
            '5JCVapni8CR2PEXr5v92cCY2QgSd4cztR2v3L3vK2eair7dGHiHa',  # Long key should fail
            '5JCVapni8CR2PEXr5v92cCY2QgSd4cztR2v3L3vK2eair7dGHia',  # Invalid key should fail
            '5JCVapni8CR2PEXr5v92cCY2QgSd4cztR2v3L3vK2eair7dGHiH',  # Correct key
            'No'
        ]  # Fingerprint mismatch

        gen = iter(input_list)
        builtins.input = lambda _: str(next(gen))

        # Test
        self.assertFR("Error: Fingerprint mismatch", start_key_exchange,
                      '*****@*****.**', '*****@*****.**', 'Alice',
                      self.contact_list, self.settings, self.queues)

    def test_successful_exchange(self):
        # Setup
        input_list = [
            '5JCVapni8CR2PEXr5v92cCY2QgSd4cztR2v3L3vK2eair7dGHiH',  # Correct key
            'Yes'
        ]  # Fingerprint match
        gen = iter(input_list)
        builtins.input = lambda _: str(next(gen))

        # Test
        self.assertIsNone(
            start_key_exchange('*****@*****.**', '*****@*****.**', 'Alice',
                               self.contact_list, self.settings, self.queues))
        time.sleep(0.1)

        contact = self.contact_list.get_contact('*****@*****.**')

        self.assertEqual(contact.rx_account, '*****@*****.**')
        self.assertEqual(contact.tx_account, '*****@*****.**')
        self.assertEqual(contact.nick, 'Alice')
        self.assertIsInstance(contact.tx_fingerprint, bytes)
        self.assertIsInstance(contact.rx_fingerprint, bytes)
        self.assertEqual(len(contact.tx_fingerprint), FINGERPRINT_LEN)
        self.assertEqual(len(contact.rx_fingerprint), FINGERPRINT_LEN)
        self.assertFalse(contact.log_messages)
        self.assertFalse(contact.file_reception)
        self.assertTrue(contact.notifications)

        self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 1)

        cmd, account, tx_key, rx_key, tx_hek, rx_hek = self.queues[
            KEY_MANAGEMENT_QUEUE].get()

        self.assertEqual(cmd, KDB_ADD_ENTRY_HEADER)
        self.assertEqual(account, '*****@*****.**')
        self.assertEqual(len(tx_key), KEY_LENGTH)
        for key in [tx_key, rx_key, tx_hek, rx_hek]:
            self.assertIsInstance(key, bytes)
            self.assertEqual(len(key), KEY_LENGTH)
Ejemplo n.º 10
0
 def setUp(self):
     self.contact_list = ContactList(nicks=['Alice', 'Bob'])
     self.group_list = GroupList(groups=['testgroup'])
     self.settings = Settings(key_list=['key1', 'key2'])
Ejemplo n.º 11
0
    def test_loop(self, *_):
        # Setup
        queues = gen_queue_dict()
        kek = SYMMETRIC_KEY_LENGTH * b'a'
        conf_code = bytes(1)
        tx_pub_key = nick_to_pub_key('Bob')
        o_sleep = self.o_sleep
        test_delay = 0.1

        def queue_packet(mk, hk, tx_harac, packet, onion_pub_key=None):
            """Create encrypted datagram."""
            if onion_pub_key is None:
                header = b''
                queue = queues[COMMAND_DATAGRAM_HEADER]
                packet = split_to_assembly_packets(packet, COMMAND)[0]
            else:
                header = onion_pub_key + ORIGIN_CONTACT_HEADER
                queue = queues[MESSAGE_DATAGRAM_HEADER]
                packet = split_to_assembly_packets(packet, MESSAGE)[0]

            encrypted_harac = encrypt_and_sign(int_to_bytes(tx_harac), hk)
            encrypted_message = encrypt_and_sign(packet, mk)
            encrypted_packet = header + encrypted_harac + encrypted_message
            queue.put((datetime.datetime.now(), encrypted_packet))

        def queue_delayer():
            """Place datagrams into queue after delay."""
            o_sleep(test_delay)
            local_harac = INITIAL_HARAC
            tx_harac = INITIAL_HARAC
            local_hek = SYMMETRIC_KEY_LENGTH * b'a'
            file_key = SYMMETRIC_KEY_LENGTH * b'b'
            local_key = SYMMETRIC_KEY_LENGTH * b'a'
            tx_mk = SYMMETRIC_KEY_LENGTH * b'a'
            tx_hk = SYMMETRIC_KEY_LENGTH * b'a'

            # Queue local key packet
            local_key_packet = encrypt_and_sign(local_key + local_hek +
                                                conf_code,
                                                key=kek)
            queues[LOCAL_KEY_DATAGRAM_HEADER].put(
                (datetime.datetime.now(), local_key_packet))
            o_sleep(test_delay)

            # Select file window
            command = WIN_SELECT + WIN_UID_FILE
            queue_packet(local_key, tx_hk, local_harac, command)
            local_key, local_harac = rotate_key(local_key, local_harac)
            o_sleep(test_delay)

            # Select local window
            command = WIN_SELECT + WIN_UID_LOCAL
            queue_packet(local_key, tx_hk, local_harac, command)
            local_key, local_harac = rotate_key(local_key, local_harac)
            o_sleep(test_delay)

            # A message that goes to buffer
            queue_packet(
                tx_mk, tx_hk, tx_harac,
                bool_to_bytes(False) + PRIVATE_MESSAGE_HEADER + b'Hi Bob',
                tx_pub_key)
            tx_mk, tx_harac = rotate_key(tx_mk, tx_harac)

            # ECDHE keyset for Bob
            command = KEY_EX_ECDHE + nick_to_pub_key("Bob") + (
                4 * SYMMETRIC_KEY_LENGTH * b'a') + str_to_bytes('Bob')
            queue_packet(local_key, tx_hk, local_harac, command)
            local_key, local_harac = rotate_key(local_key, local_harac)
            o_sleep(test_delay)

            # Message for Bob
            queue_packet(
                tx_mk, tx_hk, tx_harac,
                bool_to_bytes(False) + PRIVATE_MESSAGE_HEADER + b'Hi Bob',
                tx_pub_key)
            tx_mk, tx_harac = rotate_key(tx_mk, tx_harac)
            o_sleep(test_delay)

            # Enable file reception for Bob
            command = CH_FILE_RECV + ENABLE.upper() + US_BYTE
            queue_packet(local_key, tx_hk, local_harac, command)
            o_sleep(test_delay)

            # File packet from Bob
            ct = encrypt_and_sign(b'test', file_key)
            f_hash = blake2b(ct)
            packet = nick_to_pub_key('Bob') + ORIGIN_CONTACT_HEADER + ct
            queues[FILE_DATAGRAM_HEADER].put((datetime.datetime.now(), packet))
            o_sleep(test_delay)

            # File key packet from Bob
            queue_packet(
                tx_mk, tx_hk, tx_harac,
                bool_to_bytes(False) + FILE_KEY_HEADER +
                base64.b85encode(f_hash + file_key), tx_pub_key)
            o_sleep(test_delay)

            # Queue exit message to break the loop
            o_sleep(0.5)
            queues[UNITTEST_QUEUE].put(EXIT)
            o_sleep(test_delay)

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

        # Test
        self.assertIsNone(
            output_loop(queues,
                        Gateway(),
                        Settings(),
                        ContactList(),
                        KeyList(),
                        GroupList(),
                        MasterKey(),
                        stdin_fd=1,
                        unittest=True))

        # Teardown
        tear_queues(queues)
Ejemplo n.º 12
0
 def setUp(self):
     self.contact_list = ContactList(nicks=['Alice'])
Ejemplo n.º 13
0
class TestNewFile(TFCTestCase):
    def setUp(self):
        self.unittest_dir = cd_unittest()
        self.ts = datetime.now()
        self.packet = b''
        self.file_keys = dict()
        self.file_buf = dict()
        self.contact_list = ContactList(nicks=['Alice'])
        self.window_list = WindowList()
        self.file_key = SYMMETRIC_KEY_LENGTH * b'a'
        self.settings = Settings()
        self.compressed = zlib.compress(str_to_bytes("test_file.txt") +
                                        b'file_data',
                                        level=COMPRESSION_LEVEL)
        self.args = self.file_keys, self.file_buf, self.contact_list, self.window_list, self.settings

    def tearDown(self):
        cleanup(self.unittest_dir)

    def test_unknown_account_raises_fr(self):
        # Setup
        file_ct = encrypt_and_sign(self.compressed, self.file_key)
        packet = nick_to_pub_key('Bob') + ORIGIN_CONTACT_HEADER + file_ct

        # Test
        self.assert_fr("File from an unknown account.", new_file, self.ts,
                       packet, *self.args)

    def test_disabled_file_reception_raises_fr(self):
        # Setup
        file_ct = encrypt_and_sign(self.compressed, self.file_key)
        packet = nick_to_pub_key('Alice') + ORIGIN_CONTACT_HEADER + file_ct
        self.contact_list.get_contact_by_address_or_nick(
            'Alice').file_reception = False

        # Test
        self.assert_fr(
            "Alert! Discarded file from Alice as file reception for them is disabled.",
            new_file, self.ts, packet, *self.args)

    def test_valid_file_without_key_is_cached(self):
        # Setup
        file_ct = encrypt_and_sign(self.compressed, self.file_key)
        file_hash = blake2b(file_ct)
        packet = nick_to_pub_key('Alice') + ORIGIN_CONTACT_HEADER + file_ct

        # Test
        self.assertIsNone(new_file(self.ts, packet, *self.args))
        self.assertEqual(self.file_buf[nick_to_pub_key('Alice') + file_hash],
                         (self.ts, file_ct))

    @mock.patch('time.sleep', return_value=None)
    def test_valid_file_with_key_is_processed(self, _):
        # Setup
        file_ct = encrypt_and_sign(self.compressed, self.file_key)
        file_hash = blake2b(file_ct)
        packet = nick_to_pub_key('Alice') + ORIGIN_CONTACT_HEADER + file_ct
        self.file_keys = {
            (nick_to_pub_key('Alice') + file_hash): self.file_key
        }
        self.args = self.file_keys, self.file_buf, self.contact_list, self.window_list, self.settings

        # Test
        self.assertIsNone(new_file(self.ts, packet, *self.args))
Ejemplo n.º 14
0
 def setUp(self):
     self.contact_list = ContactList()
     self.settings = Settings()
     self.onion_service = OnionService()
     self.gateway = Gateway()
     self.args = self.contact_list, self.settings, self.onion_service, self.gateway
Ejemplo n.º 15
0
 def setUp(self) -> None:
     """Pre-test actions."""
     self.contact_list = ContactList(nicks=['Alice', 'Bob'])
     self.group_list = GroupList(groups=['test_group'])
Ejemplo n.º 16
0
class TestPSK(TFCTestCase):
    def setUp(self):
        if 'TRAVIS' not in os.environ or not os.environ['TRAVIS'] == 'true':
            self.o_getrandom = os.getrandom

        self.o_input = builtins.input
        self.o_getpass = getpass.getpass
        self.contact_list = ContactList()
        self.settings = Settings(disable_gui_dialog=True)
        self.queues = {
            COMMAND_PACKET_QUEUE: Queue(),
            KEY_MANAGEMENT_QUEUE: Queue()
        }

        if 'TRAVIS' not in os.environ or not os.environ['TRAVIS'] == 'true':
            os.getrandom = lambda n, flags: n * b'\x00'

        getpass.getpass = lambda _: 'test_password'
        input_list = [
            '/root/',  # Invalid directory
            '.'
        ]  # Valid directory
        gen = iter(input_list)
        builtins.input = lambda _: str(next(gen))

    def tearDown(self):
        builtins.input = self.o_input
        getpass.getpass = self.o_getpass

        if 'TRAVIS' not in os.environ or not os.environ['TRAVIS'] == 'true':
            os.getrandom = self.o_getrandom

        with ignored(OSError):
            os.remove('[email protected] - Give to [email protected]')

        for key in self.queues.keys():
            while not self.queues[key].empty():
                self.queues[key].get()
            time.sleep(0.1)
            self.queues[key].close()

    def test_psk_creation(self):
        self.assertIsNone(
            create_pre_shared_key('*****@*****.**', '*****@*****.**',
                                  'Alice', self.contact_list, self.settings,
                                  self.queues))

        contact = self.contact_list.get_contact('*****@*****.**')

        self.assertEqual(contact.rx_account, '*****@*****.**')
        self.assertEqual(contact.tx_account, '*****@*****.**')
        self.assertEqual(contact.nick, 'Alice')
        self.assertEqual(contact.tx_fingerprint, bytes(FINGERPRINT_LEN))
        self.assertEqual(contact.rx_fingerprint, bytes(FINGERPRINT_LEN))
        self.assertFalse(contact.log_messages)
        self.assertFalse(contact.file_reception)
        self.assertTrue(contact.notifications)

        cmd, account, tx_key, rx_key, tx_hek, rx_hek = self.queues[
            KEY_MANAGEMENT_QUEUE].get()

        self.assertEqual(cmd, KDB_ADD_ENTRY_HEADER)
        self.assertEqual(account, '*****@*****.**')
        for key in [tx_key, rx_key, tx_hek, rx_hek]:
            self.assertIsInstance(key, bytes)
            self.assertEqual(len(key), KEY_LENGTH)

        self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 1)
        self.assertTrue(
            os.path.isfile('[email protected] - Give to [email protected]'))
Ejemplo n.º 17
0
 def setUp(self) -> None:
     """Pre-test actions."""
     self.contact_list = ContactList(nicks=['Alice', 'Bob'])
     self.group_list = GroupList(groups=['test_group'])
     self.settings = Settings(key_list=['key1', 'key2'])
     self.gateway = Gateway()
Ejemplo n.º 18
0
class TestLocalKey(TFCTestCase):
    def setUp(self):
        self.o_input = builtins.input
        self.o_urandom = os.urandom

        if 'TRAVIS' not in os.environ or not os.environ['TRAVIS'] == 'true':
            self.o_getrandom = os.getrandom

        self.contact_list = ContactList()
        self.settings = Settings()
        self.queues = {
            COMMAND_PACKET_QUEUE: Queue(),
            NH_PACKET_QUEUE: Queue(),
            KEY_MANAGEMENT_QUEUE: Queue()
        }

    def tearDown(self):
        builtins.input = self.o_input
        os.urandom = self.o_urandom

        if 'TRAVIS' not in os.environ or not os.environ['TRAVIS'] == 'true':
            os.getrandom = self.o_getrandom

        for key in self.queues.keys():
            while not self.queues[key].empty():
                self.queues[key].get()
            time.sleep(0.1)
            self.queues[key].close()

    def test_new_local_key_when_traffic_masking_is_enabled_raises_fr(self):
        # Setup
        self.settings.session_traffic_masking = True

        # Test
        self.assertFR("Error: Command is disabled during traffic masking.",
                      new_local_key, self.contact_list, self.settings,
                      self.queues)

    def test_new_local_key(self):
        # Setup
        self.settings.nh_bypass_messages = False
        self.settings.session_traffic_masking = False

        if 'TRAVIS' not in os.environ or not os.environ['TRAVIS'] == 'true':
            os.getrandom = lambda n, flags: n * b'\xff'

        os.urandom = lambda n: n * b'\xff'
        input_list = ['bad', 'resend', 'ff']
        gen = iter(input_list)
        builtins.input = lambda _: str(next(gen))

        # Test
        self.assertIsNone(
            new_local_key(self.contact_list, self.settings, self.queues))
        time.sleep(0.1)

        local_contact = self.contact_list.get_contact(LOCAL_ID)

        self.assertEqual(local_contact.rx_account, LOCAL_ID)
        self.assertEqual(local_contact.tx_account, LOCAL_ID)
        self.assertEqual(local_contact.nick, LOCAL_ID)
        self.assertEqual(local_contact.tx_fingerprint, bytes(FINGERPRINT_LEN))
        self.assertEqual(local_contact.rx_fingerprint, bytes(FINGERPRINT_LEN))
        self.assertFalse(local_contact.log_messages)
        self.assertFalse(local_contact.file_reception)
        self.assertFalse(local_contact.notifications)

        self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 1)

        cmd, account, tx_key, rx_key, tx_hek, rx_hek = self.queues[
            KEY_MANAGEMENT_QUEUE].get()

        self.assertEqual(cmd, KDB_ADD_ENTRY_HEADER)
        self.assertEqual(account, LOCAL_ID)
        for key in [tx_key, rx_key, tx_hek, rx_hek]:
            self.assertIsInstance(key, bytes)
            self.assertEqual(len(key), KEY_LENGTH)
Ejemplo n.º 19
0
class TestSendFile(TFCTestCase):
    def setUp(self) -> None:
        """Pre-test actions."""
        self.unit_test_dir = cd_unit_test()
        self.settings = Settings()
        self.queues = gen_queue_dict()
        self.window = TxWindow()
        self.onion_service = OnionService()
        self.contact_list = ContactList(nicks=['Alice', 'Bob', 'Charlie'])
        self.args = self.settings, self.queues, self.window

    def tearDown(self) -> None:
        """Post-test actions."""
        cleanup(self.unit_test_dir)
        tear_queues(self.queues)

    def test_traffic_masking_raises_soft_error(self) -> None:
        self.settings.traffic_masking = True
        self.assert_se("Error: Command is disabled during traffic masking.",
                       send_file, "testfile.txt", *self.args)

    def test_missing_file_raises_soft_error(self) -> None:
        self.assert_se("Error: File not found.", send_file, "testfile.txt",
                       *self.args)

    def test_empty_file_raises_soft_error(self) -> None:
        # Setup
        open('testfile.txt', 'wb+').close()

        # Test
        self.assert_se("Error: Target file is empty.", send_file,
                       "testfile.txt", *self.args)

    @mock.patch('time.sleep', return_value=None)
    def test_file_transmission_to_contact(self, _: Any) -> None:
        # Setup
        self.window.window_contacts = [
            self.contact_list.get_contact_by_address_or_nick('Alice')
        ]
        self.window.type_print = 'contact'

        input_data = os.urandom(5)
        with open('testfile.txt', 'wb+') as f:
            f.write(input_data)

        # Test
        self.assertIsNone(send_file("testfile.txt", *self.args))
        self.assertEqual(self.queues[MESSAGE_PACKET_QUEUE].qsize(), 1)
        self.assertEqual(self.queues[RELAY_PACKET_QUEUE].qsize(), 1)

    @mock.patch('time.sleep', return_value=None)
    def test_file_transmission_to_group(self, _: Any) -> None:
        # Setup
        self.window.window_contacts = [
            self.contact_list.get_contact_by_address_or_nick('Alice'),
            self.contact_list.get_contact_by_address_or_nick('Bob')
        ]
        self.window.type_print = 'group'

        input_data = os.urandom(5)
        with open('testfile.txt', 'wb+') as f:
            f.write(input_data)

        self.assertIsNone(send_file("testfile.txt", *self.args))
        self.assertEqual(self.queues[MESSAGE_PACKET_QUEUE].qsize(), 2)
        self.assertEqual(self.queues[RELAY_PACKET_QUEUE].qsize(), 1)
Ejemplo n.º 20
0
class TestTxWindow(TFCTestCase):
    def setUp(self) -> None:
        """Pre-test actions."""
        self.contact_list = ContactList(['Alice', 'Bob', LOCAL_ID])
        self.group_list = GroupList(groups=['test_group', 'test_group_2'])
        self.window = TxWindow(self.contact_list, self.group_list)
        self.window.group = self.group_list.get_group('test_group')
        self.window.type = WIN_TYPE_GROUP
        self.settings = Settings()
        self.queues = gen_queue_dict()
        self.onion_service = OnionService()
        self.gateway = Gateway()
        self.args = self.settings, self.queues, self.onion_service, self.gateway

    def tearDown(self) -> None:
        """Post-test actions."""
        tear_queues(self.queues)

    def test_window_iterates_over_contacts(self) -> None:
        # Setup
        self.window.window_contacts = self.contact_list.contacts

        # Test
        for c in self.window:
            self.assertIsInstance(c, Contact)

    def test_len_returns_number_of_contacts_in_window(self) -> None:
        # Setup
        self.window.window_contacts = [
            self.contact_list.get_contact_by_pub_key(nick_to_pub_key('Alice')),
            self.contact_list.get_contact_by_pub_key(nick_to_pub_key('Bob'))
        ]

        # Test
        self.assertEqual(len(self.window), 2)

    def test_group_window_change_during_traffic_masking_raises_se(
            self) -> None:
        # Setup
        self.settings.traffic_masking = True
        self.window.uid = 'test_group'

        # Test
        self.assert_se("Error: Can't change window during traffic masking.",
                       self.window.select_tx_window,
                       *self.args,
                       selection='test_group_2',
                       cmd=True)

    def test_contact_window_change_during_traffic_masking_raises_se(
            self) -> None:
        # Setup
        self.settings.traffic_masking = True
        self.window.uid = nick_to_pub_key("Alice")

        # Test
        self.assert_se("Error: Can't change window during traffic masking.",
                       self.window.select_tx_window,
                       *self.args,
                       selection=nick_to_onion_address("Bob"),
                       cmd=True)

    def test_contact_window_reload_during_traffic_masking(self) -> None:
        # Setup
        self.settings.traffic_masking = True
        self.window.uid = nick_to_pub_key("Alice")

        # Test
        self.assertIsNone(
            self.window.select_tx_window(
                *self.args, selection=nick_to_onion_address("Alice"),
                cmd=True))
        self.assertEqual(self.window.uid, nick_to_pub_key("Alice"))

    def test_group_window_reload_during_traffic_masking(self) -> None:
        # Setup
        self.settings.traffic_masking = True
        self.window.name = 'test_group'
        self.window.uid = group_name_to_group_id('test_group')

        # Test
        self.assertIsNone(
            self.window.select_tx_window(*self.args,
                                         selection='test_group',
                                         cmd=True))
        self.assertEqual(self.window.uid, group_name_to_group_id('test_group'))

    def test_invalid_selection_raises_se(self) -> None:
        # Setup
        self.window.uid = nick_to_pub_key("Alice")

        # Test
        self.assert_se("Error: No contact/group was found.",
                       self.window.select_tx_window,
                       *self.args,
                       selection=nick_to_onion_address("Charlie"),
                       cmd=True)

    @mock.patch('builtins.input', return_value=nick_to_onion_address("Bob"))
    def test_window_selection_during_traffic_masking(self, *_: Any) -> None:
        # Setup
        self.settings.traffic_masking = True
        self.window.uid = None

        # Test
        self.assertIsNone(self.window.select_tx_window(*self.args))
        self.assertEqual(self.queues[WINDOW_SELECT_QUEUE].qsize(), 1)

    @mock.patch('builtins.input', return_value=nick_to_onion_address("Bob"))
    def test_contact_window_selection_from_input(self, *_: Any) -> None:
        # Setup
        self.window.uid = None

        # Test
        self.assertIsNone(self.window.select_tx_window(*self.args))
        self.assertEqual(self.window.uid, nick_to_pub_key("Bob"))

    def test_group_window_selection_from_command(self) -> None:
        # Setup
        self.window.uid = None

        self.assertIsNone(
            self.window.select_tx_window(*self.args,
                                         selection='test_group',
                                         cmd=True))
        self.assertEqual(self.window.uid, group_name_to_group_id('test_group'))

    def test_deselect_window(self) -> None:
        # Setup
        self.window.window_contacts = self.contact_list.contacts
        self.window.contact = self.contact_list.get_contact_by_address_or_nick(
            "Bob")
        self.window.name = 'Bob'
        self.window.type = WIN_TYPE_CONTACT
        self.window.uid = nick_to_pub_key("Bob")

        # Test
        self.assertIsNone(self.window.deselect())
        self.assertIsNone(self.window.contact)
        self.assertEqual(self.window.name, '')
        self.assertEqual(self.window.type, '')
        self.assertEqual(self.window.uid, b'')

    def test_is_selected(self) -> None:
        self.window.name = ''
        self.assertFalse(self.window.is_selected())

        self.window.name = nick_to_pub_key("Bob")
        self.assertTrue(self.window.is_selected())

    def test_update_log_messages_for_contact(self) -> None:
        # Setup
        self.window.type = WIN_TYPE_CONTACT
        self.window.log_messages = None
        self.window.contact = self.contact_list.get_contact_by_address_or_nick(
            'Alice')
        self.window.contact.log_messages = False

        # Test
        self.assertIsNone(self.window.update_log_messages())
        self.assertFalse(self.window.log_messages)

    def test_update_log_messages_for_group(self) -> None:
        # Setup
        self.window.type = WIN_TYPE_GROUP
        self.window.log_messages = None
        self.window.group = self.group_list.get_group('test_group')
        self.window.group.log_messages = False

        # Test
        self.assertIsNone(self.window.update_log_messages())
        self.assertFalse(self.window.log_messages)

    def test_update_group_win_members_if_group_is_available(self) -> None:
        # Setup
        self.window.window_contacts = []
        self.window.group = None
        self.window.group_id = group_name_to_group_id('test_group')
        self.window.name = 'test_group'
        self.window.type = WIN_TYPE_GROUP

        # Test
        self.assertIsNone(self.window.update_window(self.group_list))
        self.assertEqual(self.window.group,
                         self.group_list.get_group('test_group'))
        self.assertEqual(self.window.window_contacts,
                         self.window.group.members)

    def test_window_contact_is_reloaded_when_contact_is_active(self) -> None:
        # Setup
        self.window.type = WIN_TYPE_CONTACT
        self.window.contact = create_contact('Alice')
        self.window.window_contacts = [self.window.contact]
        self.assertIsNot(
            self.window.contact,
            self.window.contact_list.get_contact_by_pub_key(
                nick_to_pub_key('Alice')))
        self.assertIsNot(
            self.window.window_contacts[0],
            self.window.contact_list.get_contact_by_pub_key(
                nick_to_pub_key('Alice')))

        # Test
        self.assertIsNone(self.window.update_window(self.group_list))
        self.assertIs(
            self.window.contact,
            self.window.contact_list.get_contact_by_pub_key(
                nick_to_pub_key('Alice')))
        self.assertIs(
            self.window.window_contacts[0],
            self.window.contact_list.get_contact_by_pub_key(
                nick_to_pub_key('Alice')))

    def test_deactivate_window_if_group_is_not_available(self) -> None:
        # Setup
        self.window.window_contacts = []
        self.window.group = None
        self.window.name = 'test_group_3'
        self.window.type = WIN_TYPE_GROUP

        # Test
        self.assertIsNone(self.window.update_window(self.group_list))
        self.assertIsNone(self.window.contact)
        self.assertEqual(self.window.name, '')
        self.assertEqual(self.window.type, '')
        self.assertEqual(self.window.uid, b'')

    @mock.patch('time.sleep', return_value=None)
    @mock.patch('builtins.input',
                side_effect=[
                    'Alice', VALID_ECDHE_PUB_KEY, 'yes',
                    blake2b(nick_to_pub_key('Alice'),
                            digest_size=CONFIRM_CODE_LENGTH).hex()
                ])
    @mock.patch('shutil.get_terminal_size', return_value=[200, 200])
    def test_selecting_pending_contact_starts_key_exchange(self,
                                                           *_: Any) -> None:
        # Setup
        alice = self.contact_list.get_contact_by_address_or_nick('Alice')
        bob = self.contact_list.get_contact_by_address_or_nick('Bob')
        alice.kex_status = KEX_STATUS_PENDING
        bob.kex_status = KEX_STATUS_PENDING

        # Test
        self.assertIsNone(self.window.select_tx_window(*self.args))
        self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 2)
        self.assertEqual(self.queues[WINDOW_SELECT_QUEUE].qsize(), 0)
        self.assertEqual(alice.kex_status, KEX_STATUS_VERIFIED)

    @mock.patch('time.sleep', return_value=None)
    @mock.patch('builtins.input',
                side_effect=[
                    '/add',
                    nick_to_onion_address('Alice'), 'Alice', '',
                    VALID_ECDHE_PUB_KEY, 'yes',
                    blake2b(nick_to_pub_key('Alice'),
                            digest_size=CONFIRM_CODE_LENGTH).hex()
                ])
    @mock.patch('shutil.get_terminal_size', return_value=[200, 200])
    def test_adding_new_contact_from_contact_selection(self, *_: Any) -> None:
        # Setup
        alice = self.contact_list.get_contact_by_address_or_nick('Alice')
        alice.kex_status = KEX_STATUS_PENDING

        # Test
        self.assert_se('New contact added.', self.window.select_tx_window,
                       *self.args)
        self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 1)
        self.assertEqual(self.queues[WINDOW_SELECT_QUEUE].qsize(), 0)
        self.assertEqual(alice.kex_status, KEX_STATUS_VERIFIED)

    @mock.patch('time.sleep', return_value=None)
    @mock.patch('builtins.input', side_effect=['/rm '])
    def test_missing_account_when_removing_raises_se(self, *_: Any) -> None:
        self.assert_se("Error: No account specified.",
                       self.window.select_tx_window, *self.args)

    @mock.patch('time.sleep', return_value=None)
    @mock.patch('builtins.input', side_effect=['/rm Charlie', 'yes'])
    def test_unknown_account_when_removing_raises_se(self, *_: Any) -> None:
        self.assert_se("Error: Unknown contact 'Charlie'.",
                       self.window.select_tx_window, *self.args)

    @mock.patch('time.sleep', return_value=None)
    @mock.patch('builtins.input', side_effect=['/rm Alice', 'no'])
    def test_abort_removal_of_contact_form_contact_selection(self,
                                                             *_: Any) -> None:
        self.assert_se("Removal of contact aborted.",
                       self.window.select_tx_window, *self.args)

    @mock.patch('time.sleep', return_value=None)
    @mock.patch('builtins.input', side_effect=['/rm Alice', 'yes'])
    def test_removing_pending_contact_from_contact_selection(self,
                                                             *_: Any) -> None:
        self.assert_se("Removed contact 'Alice'.",
                       self.window.select_tx_window, *self.args)

    @mock.patch('time.sleep', return_value=None)
    @mock.patch('builtins.input', side_effect=['/connect', b'a'.hex()])
    def test_sending_onion_service_data_from_contact_selection(
            self, *_: Any) -> None:
        self.assertIsNone(self.window.select_tx_window(*self.args))
        self.assertEqual(len(self.gateway.packets), 1)

    @mock.patch('time.sleep', return_value=None)
    @mock.patch('builtins.input', side_effect=['/help'])
    def test_invalid_command_raises_se(self, *_: Any) -> None:
        self.assert_se("Error: Invalid command.", self.window.select_tx_window,
                       *self.args)
Ejemplo n.º 21
0
class TestPSK(TFCTestCase):
    def setUp(self) -> None:
        """Pre-test actions."""
        self.unit_test_dir = cd_unit_test()
        self.contact_list = ContactList()
        self.settings = Settings(disable_gui_dialog=True)
        self.queues = gen_queue_dict()
        self.onion_service = OnionService()
        self.args = self.contact_list, self.settings, self.onion_service, self.queues

    def tearDown(self) -> None:
        """Post-test actions."""
        cleanup(self.unit_test_dir)

        with ignored(OSError):
            os.remove(
                f"{self.onion_service.user_short_address}.psk - Give to {nick_to_short_address('Alice')}"
            )

        tear_queues(self.queues)

    @mock.patch('builtins.input', side_effect=['/root/', '.', 'fc'])
    @mock.patch('time.sleep', return_value=None)
    @mock.patch('getpass.getpass', return_value='test_password')
    @mock.patch('src.transmitter.key_exchanges.ARGON2_PSK_MEMORY_COST', 1000)
    @mock.patch('src.transmitter.key_exchanges.ARGON2_PSK_TIME_COST', 1)
    def test_psk_creation(self, *_: Any) -> None:
        self.assertIsNone(
            create_pre_shared_key(nick_to_pub_key("Alice"), 'Alice',
                                  *self.args))

        contact = self.contact_list.get_contact_by_pub_key(
            nick_to_pub_key("Alice"))

        self.assertEqual(contact.onion_pub_key, nick_to_pub_key("Alice"))
        self.assertEqual(contact.nick, 'Alice')
        self.assertEqual(contact.tx_fingerprint, bytes(FINGERPRINT_LENGTH))
        self.assertEqual(contact.rx_fingerprint, bytes(FINGERPRINT_LENGTH))
        self.assertEqual(contact.kex_status, KEX_STATUS_NO_RX_PSK)

        self.assertFalse(contact.log_messages)
        self.assertFalse(contact.file_reception)
        self.assertTrue(contact.notifications)

        cmd, account, tx_key, rx_key, tx_hek, rx_hek = self.queues[
            KEY_MANAGEMENT_QUEUE].get()

        self.assertEqual(cmd, KDB_ADD_ENTRY_HEADER)
        self.assertEqual(account, nick_to_pub_key("Alice"))

        for key in [tx_key, rx_key, tx_hek, rx_hek]:
            self.assertIsInstance(key, bytes)
            self.assertEqual(len(key), SYMMETRIC_KEY_LENGTH)

        self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 1)
        self.assertTrue(
            os.path.isfile(
                f"{self.onion_service.user_short_address}.psk - Give to {nick_to_short_address('Alice')}"
            ))

    @mock.patch('time.sleep', return_value=None)
    @mock.patch('getpass.getpass', side_effect=KeyboardInterrupt)
    def test_keyboard_interrupt_raises_soft_error(self, *_: Any) -> None:
        self.assert_se("PSK generation aborted.", create_pre_shared_key,
                       nick_to_pub_key("Alice"), 'Alice', *self.args)
Ejemplo n.º 22
0
class TestRemoveContact(TFCTestCase):
    def setUp(self):
        self.o_input = builtins.input
        self.settings = Settings()
        self.master_key = MasterKey()
        self.queues = {
            KEY_MANAGEMENT_QUEUE: Queue(),
            COMMAND_PACKET_QUEUE: Queue()
        }
        self.contact_list = ContactList(nicks=['Alice'])
        self.group_list = GroupList(groups=['testgroup'])

    def tearDown(self):
        builtins.input = self.o_input

        for key in self.queues:
            while not self.queues[key].empty():
                self.queues[key].get()
            time.sleep(0.1)
            self.queues[key].close()

    def test_contact_removal_during_traffic_masking_raises_fr(self):
        # Setup
        self.settings.session_traffic_masking = True

        # Test
        self.assertFR("Error: Command is disabled during traffic masking.",
                      remove_contact, None, None, None, None, self.settings,
                      None, self.master_key)

    def test_missing_account_raises_fr(self):
        # Setup
        user_input = UserInput('rm ')

        # Test
        self.assertFR("Error: No account specified.", remove_contact,
                      user_input, None, None, None, self.settings, None,
                      self.master_key)

    def test_user_abort_raises_fr(self):
        # Setup
        builtins.input = lambda _: 'No'
        user_input = UserInput('rm [email protected]')

        # Test
        self.assertFR("Removal of contact aborted.", remove_contact,
                      user_input, None, None, None, self.settings, None,
                      self.master_key)

    def test_successful_removal_of_contact(self):
        # Setup
        builtins.input = lambda _: 'Yes'
        user_input = UserInput('rm Alice')
        window = TxWindow(
            window_contacts=[self.contact_list.get_contact('Alice')],
            type=WIN_TYPE_CONTACT,
            uid='*****@*****.**')

        # Test
        for g in self.group_list:
            self.assertIsInstance(g, Group)
            self.assertTrue(g.has_member('*****@*****.**'))

        self.assertIsNone(
            remove_contact(user_input, window, self.contact_list,
                           self.group_list, self.settings, self.queues,
                           self.master_key))
        time.sleep(0.1)
        self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 2)

        km_data = self.queues[KEY_MANAGEMENT_QUEUE].get()
        self.assertEqual(km_data,
                         (KDB_REMOVE_ENTRY_HEADER, '*****@*****.**'))
        self.assertFalse(self.contact_list.has_contact('*****@*****.**'))

        for g in self.group_list:
            self.assertIsInstance(g, Group)
            self.assertFalse(g.has_member('*****@*****.**'))

    def test_successful_removal_of_last_member_of_active_group(self):
        # Setup
        builtins.input = lambda _: 'Yes'
        user_input = UserInput('rm Alice')
        window = TxWindow(
            window_contacts=[self.contact_list.get_contact('Alice')],
            type=WIN_TYPE_GROUP,
            name='testgroup')
        group = self.group_list.get_group('testgroup')
        group.members = [self.contact_list.get_contact('*****@*****.**')]

        # Test
        for g in self.group_list:
            self.assertIsInstance(g, Group)
            self.assertTrue(g.has_member('*****@*****.**'))
        self.assertEqual(len(group), 1)

        self.assertIsNone(
            remove_contact(user_input, window, self.contact_list,
                           self.group_list, self.settings, self.queues,
                           self.master_key))
        time.sleep(0.1)

        for g in self.group_list:
            self.assertIsInstance(g, Group)
            self.assertFalse(g.has_member('*****@*****.**'))

        self.assertFalse(self.contact_list.has_contact('*****@*****.**'))
        self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 2)

        km_data = self.queues[KEY_MANAGEMENT_QUEUE].get()
        self.assertEqual(km_data,
                         (KDB_REMOVE_ENTRY_HEADER, '*****@*****.**'))

    def test_no_contact_found_on_txm(self):
        # Setup
        builtins.input = lambda _: 'Yes'
        user_input = UserInput('rm [email protected]')
        contact_list = ContactList(nicks=['Bob'])
        window = TxWindow(window_contact=[contact_list.get_contact('Bob')],
                          type=WIN_TYPE_GROUP)

        # Test
        self.assertIsNone(
            remove_contact(user_input, window, self.contact_list,
                           self.group_list, self.settings, self.queues,
                           self.master_key))
        time.sleep(0.1)

        self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 2)
        command_packet, settings_ = self.queues[COMMAND_PACKET_QUEUE].get()
        self.assertIsInstance(command_packet, bytes)
        self.assertIsInstance(settings_, Settings)
Ejemplo n.º 23
0
 def setUp(self) -> None:
     """Pre-test actions."""
     self.contact_list = ContactList()
     self.settings = Settings()
     self.queues = gen_queue_dict()
     self.args = self.contact_list, self.settings, self.queues
Ejemplo n.º 24
0
class TestContactSetting(TFCTestCase):
    def setUp(self):
        self.c_queue = Queue()
        self.contact_list = ContactList(nicks=['Alice', 'Bob'])
        self.settings = Settings()
        self.group_list = GroupList(groups=['testgroup'])

    def tearDown(self):
        while not self.c_queue.empty():
            self.c_queue.get()
        time.sleep(0.1)
        self.c_queue.close()

    def test_invalid_command_raises_fr(self):
        # Setup
        user_input = UserInput('loging on')

        # Test
        self.assertFR("Error: Invalid command.", contact_setting, user_input,
                      None, None, None, None, None)

    def test_missing_parameter_raises_fr(self):
        # Setup
        user_input = UserInput('')

        # Test
        self.assertFR("Error: Invalid command.", contact_setting, user_input,
                      None, None, None, None, None)

    def test_invalid_extra_parameter_raises_fr(self):
        # Setup
        user_input = UserInput('logging on al')

        # Test
        self.assertFR("Error: Invalid command.", contact_setting, user_input,
                      None, None, None, None, None)

    def test_enable_logging_for_user(self):
        # Setup
        user_input = UserInput('logging on')
        contact = self.contact_list.get_contact('Alice')
        contact.log_messages = False
        window = TxWindow(uid='*****@*****.**',
                          type=WIN_TYPE_CONTACT,
                          contact=contact)

        # Test
        self.assertFalse(contact.log_messages)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        self.assertTrue(contact.log_messages)

    def test_enable_logging_for_user_during_traffic_masking(self):
        # Setup
        user_input = UserInput('logging on')
        contact = self.contact_list.get_contact('Alice')
        contact.log_messages = False
        window = TxWindow(uid='*****@*****.**',
                          type=WIN_TYPE_CONTACT,
                          contact=contact,
                          log_messages=False)
        self.settings.session_traffic_masking = True

        # Test
        self.assertFalse(contact.log_messages)
        self.assertFalse(window.log_messages)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        self.assertEqual(self.c_queue.qsize(), 1)
        self.assertTrue(window.log_messages)
        self.assertTrue(contact.log_messages)

    def test_enable_logging_for_group(self):
        # Setup
        user_input = UserInput('logging on')
        group = self.group_list.get_group('testgroup')
        group.log_messages = False
        window = TxWindow(uid='testgroup',
                          type=WIN_TYPE_GROUP,
                          group=group,
                          window_contacts=group.members)

        # Test
        self.assertFalse(group.log_messages)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        self.assertTrue(group.log_messages)

    def test_enable_logging_for_all_users(self):
        # Setup
        user_input = UserInput('logging on all')
        contact = self.contact_list.get_contact('*****@*****.**')
        window = TxWindow(uid='*****@*****.**',
                          type=WIN_TYPE_CONTACT,
                          contact=contact,
                          window_contacts=[contact])

        for c in self.contact_list:
            c.log_messages = False
        for g in self.group_list:
            g.log_messages = False

        # Test
        for c in self.contact_list:
            self.assertFalse(c.log_messages)
        for g in self.group_list:
            self.assertFalse(g.log_messages)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        for c in self.contact_list:
            self.assertTrue(c.log_messages)
        for g in self.group_list:
            self.assertTrue(g.log_messages)

    def test_disable_logging_for_user(self):
        # Setup
        user_input = UserInput('logging off')
        contact = self.contact_list.get_contact('Alice')
        contact.log_messages = True
        window = TxWindow(uid='*****@*****.**',
                          type=WIN_TYPE_CONTACT,
                          contact=contact,
                          window_contacts=[contact])

        # Test
        self.assertTrue(contact.log_messages)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        self.assertFalse(contact.log_messages)

    def test_disable_logging_for_group(self):
        # Setup
        user_input = UserInput('logging off')
        group = self.group_list.get_group('testgroup')
        group.log_messages = True
        window = TxWindow(uid='testgroup',
                          type=WIN_TYPE_GROUP,
                          group=group,
                          window_contacts=group.members)

        # Test
        self.assertTrue(group.log_messages)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        self.assertFalse(group.log_messages)

    def test_disable_logging_for_all_users(self):
        # Setup
        user_input = UserInput('logging off all')
        contact = self.contact_list.get_contact('*****@*****.**')
        window = TxWindow(uid='*****@*****.**',
                          type=WIN_TYPE_CONTACT,
                          contact=contact,
                          window_contacts=[contact])

        for c in self.contact_list:
            c.log_messages = True
        for g in self.group_list:
            g.log_messages = True

        # Test
        for c in self.contact_list:
            self.assertTrue(c.log_messages)
        for g in self.group_list:
            self.assertTrue(g.log_messages)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        for c in self.contact_list:
            self.assertFalse(c.log_messages)
        for g in self.group_list:
            self.assertFalse(g.log_messages)

    def test_enable_file_reception_for_user(self):
        # Setup
        user_input = UserInput('store on')
        contact = self.contact_list.get_contact('Alice')
        contact.file_reception = False
        window = TxWindow(uid='*****@*****.**',
                          type=WIN_TYPE_CONTACT,
                          contact=contact,
                          window_contacts=[contact])

        # Test
        self.assertFalse(contact.file_reception)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        self.assertTrue(contact.file_reception)

    def test_enable_file_reception_for_group(self):
        # Setup
        user_input = UserInput('store on')
        group = self.group_list.get_group('testgroup')
        window = TxWindow(uid='testgroup',
                          type=WIN_TYPE_GROUP,
                          group=group,
                          window_contacts=group.members)

        for m in group:
            m.file_reception = False

        # Test
        for m in group:
            self.assertFalse(m.file_reception)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        for m in group:
            self.assertTrue(m.file_reception)

    def test_enable_file_reception_for_all_users(self):
        # Setup
        user_input = UserInput('store on all')
        contact = self.contact_list.get_contact('*****@*****.**')
        window = TxWindow(uid='*****@*****.**',
                          type=WIN_TYPE_CONTACT,
                          contact=contact,
                          window_contacts=[contact])

        for c in self.contact_list:
            c.file_reception = False

        # Test
        for c in self.contact_list:
            self.assertFalse(c.file_reception)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        for c in self.contact_list:
            self.assertTrue(c.file_reception)

    def test_disable_file_reception_for_user(self):
        # Setup
        user_input = UserInput('store off')
        contact = self.contact_list.get_contact('Alice')
        contact.file_reception = True
        window = TxWindow(uid='*****@*****.**',
                          type=WIN_TYPE_CONTACT,
                          contact=contact,
                          window_contacts=[contact])

        # Test
        self.assertTrue(contact.file_reception)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        self.assertFalse(contact.file_reception)

    def test_disable_file_reception_for_group(self):
        # Setup
        user_input = UserInput('store off')
        group = self.group_list.get_group('testgroup')
        window = TxWindow(uid='testgroup',
                          type=WIN_TYPE_GROUP,
                          group=group,
                          window_contacts=group.members)

        for m in group:
            m.file_reception = True

        # Test
        for m in group:
            self.assertTrue(m.file_reception)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        for m in group:
            self.assertFalse(m.file_reception)

    def test_disable_file_reception_for_all_users(self):
        # Setup
        user_input = UserInput('store off all')
        contact = self.contact_list.get_contact('*****@*****.**')
        window = TxWindow(uid='*****@*****.**',
                          type=WIN_TYPE_CONTACT,
                          contact=contact,
                          window_contacts=[contact])

        for c in self.contact_list:
            c.file_reception = True

        # Test
        for c in self.contact_list:
            self.assertTrue(c.file_reception)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        for c in self.contact_list:
            self.assertFalse(c.file_reception)

    def test_enable_notifications_for_user(self):
        # Setup
        user_input = UserInput('notify on')
        contact = self.contact_list.get_contact('Alice')
        contact.notifications = False
        window = TxWindow(uid='*****@*****.**',
                          type=WIN_TYPE_CONTACT,
                          contact=contact)

        # Test
        self.assertFalse(contact.notifications)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        self.assertTrue(contact.notifications)

    def test_enable_notifications_for_group(self):
        # Setup
        user_input = UserInput('notify on')
        group = self.group_list.get_group('testgroup')
        group.notifications = False
        window = TxWindow(uid='testgroup',
                          type=WIN_TYPE_GROUP,
                          group=group,
                          window_contacts=group.members)

        # Test
        self.assertFalse(group.notifications)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        self.assertTrue(group.notifications)

    def test_enable_notifications_for_all_users(self):
        # Setup
        user_input = UserInput('notify on all')
        contact = self.contact_list.get_contact('*****@*****.**')
        window = TxWindow(uid='*****@*****.**',
                          type=WIN_TYPE_CONTACT,
                          contact=contact,
                          window_contacts=[contact])

        for c in self.contact_list:
            c.notifications = False
        for g in self.group_list:
            g.notifications = False

        # Test
        for c in self.contact_list:
            self.assertFalse(c.notifications)
        for g in self.group_list:
            self.assertFalse(g.notifications)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        for c in self.contact_list:
            self.assertTrue(c.notifications)
        for g in self.group_list:
            self.assertTrue(g.notifications)

    def test_disable_notifications_for_user(self):
        # Setup
        user_input = UserInput('notify off')
        contact = self.contact_list.get_contact('Alice')
        contact.notifications = True
        window = TxWindow(uid='*****@*****.**',
                          type=WIN_TYPE_CONTACT,
                          contact=contact,
                          window_contacts=[contact])

        # Test
        self.assertTrue(contact.notifications)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        self.assertFalse(contact.notifications)

    def test_disable_notifications_for_group(self):
        # Setup
        user_input = UserInput('notify off')
        group = self.group_list.get_group('testgroup')
        group.notifications = True
        window = TxWindow(uid='testgroup',
                          type=WIN_TYPE_GROUP,
                          group=group,
                          window_contacts=group.members)

        # Test
        self.assertTrue(group.notifications)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        self.assertFalse(group.notifications)

    def test_disable_notifications_for_all_users(self):
        # Setup
        user_input = UserInput('notify off all')
        contact = self.contact_list.get_contact('*****@*****.**')
        window = TxWindow(uid='*****@*****.**',
                          type=WIN_TYPE_CONTACT,
                          contact=contact,
                          window_contacts=[contact])

        for c in self.contact_list:
            c.notifications = True
        for g in self.group_list:
            g.notifications = True

        # Test
        for c in self.contact_list:
            self.assertTrue(c.notifications)
        for g in self.group_list:
            self.assertTrue(g.notifications)

        self.assertIsNone(
            contact_setting(user_input, window, self.contact_list,
                            self.group_list, self.settings, self.c_queue))
        time.sleep(0.1)

        for c in self.contact_list:
            self.assertFalse(c.notifications)
        for g in self.group_list:
            self.assertFalse(g.notifications)
Ejemplo n.º 25
0
 def setUp(self) -> None:
     """Pre-test actions."""
     self.contact_list = ContactList(nicks=['Alice'])
     self.lines = [nick_to_pub_key('Alice'), nick_to_pub_key('Bob')]
     self.group_name = 'test_group'
Ejemplo n.º 26
0
 def setUp(self):
     self.c_queue = Queue()
     self.contact_list = ContactList(nicks=['Alice', 'Bob'])
     self.settings = Settings()
     self.group_list = GroupList(groups=['testgroup'])
Ejemplo n.º 27
0
class TestProcessMessagePacket(TFCTestCase):
    def setUp(self) -> None:
        """Pre-test actions."""
        self.unit_test_dir = cd_unit_test()

        self.msg = (
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean condimentum consectetur purus quis"
            " dapibus. Fusce venenatis lacus ut rhoncus faucibus. Cras sollicitudin commodo sapien, sed bibendu"
            "m velit maximus in. Aliquam ac metus risus. Sed cursus ornare luctus. Integer aliquet lectus id ma"
            "ssa blandit imperdiet. Ut sed massa eget quam facilisis rutrum. Mauris eget luctus nisl. Sed ut el"
            "it iaculis, faucibus lacus eget, sodales magna. Nunc sed commodo arcu. In hac habitasse platea dic"
            "tumst. Integer luctus aliquam justo, at vestibulum dolor iaculis ac. Etiam laoreet est eget odio r"
            "utrum, vel malesuada lorem rhoncus. Cras finibus in neque eu euismod. Nulla facilisi. Nunc nec ali"
            "quam quam, quis ullamcorper leo. Nunc egestas lectus eget est porttitor, in iaculis felis sceleris"
            "que. In sem elit, fringilla id viverra commodo, sagittis varius purus. Pellentesque rutrum loborti"
            "s neque a facilisis. Mauris id tortor placerat, aliquam dolor ac, venenatis arcu."
        )

        self.ts = datetime.now()
        self.master_key = MasterKey()
        self.settings = Settings(log_file_masking=True)
        self.file_name = f'{DIR_USER_DATA}{self.settings.software_operation}_logs'

        self.contact_list = ContactList(
            nicks=['Alice', 'Bob', 'Charlie', LOCAL_ID])
        self.key_list = KeyList(nicks=['Alice', 'Bob', 'Charlie', LOCAL_ID])
        self.group_list = GroupList(groups=['test_group'])
        self.packet_list = PacketList(contact_list=self.contact_list,
                                      settings=self.settings)
        self.window_list = WindowList(contact_list=self.contact_list,
                                      settings=self.settings,
                                      group_list=self.group_list,
                                      packet_list=self.packet_list)
        self.group_id = group_name_to_group_id('test_group')
        self.file_keys = dict()

        self.log_file = f'{DIR_USER_DATA}{self.settings.software_operation}_logs'
        self.tfc_log_database = MessageLog(self.log_file,
                                           self.master_key.master_key)

        self.group_list.get_group('test_group').log_messages = True
        self.args = (self.window_list, self.packet_list, self.contact_list,
                     self.key_list, self.group_list, self.settings,
                     self.file_keys, self.tfc_log_database)

        ensure_dir(DIR_USER_DATA)

    def tearDown(self) -> None:
        """Post-test actions."""
        cleanup(self.unit_test_dir)

    # Invalid packets
    @mock.patch('time.sleep', return_value=None)
    def test_invalid_origin_header_raises_se(self, _: Any) -> None:
        # Setup
        invalid_origin_header = b'e'
        packet = nick_to_pub_key(
            'Alice') + invalid_origin_header + MESSAGE_LENGTH * b'm'

        # Test
        self.assert_se("Error: Received packet had an invalid origin-header.",
                       process_message_packet, self.ts, packet, *self.args)

    @mock.patch('time.sleep', return_value=None)
    def test_masqueraded_command_raises_se(self, _: Any) -> None:
        for origin_header in [ORIGIN_USER_HEADER, ORIGIN_CONTACT_HEADER]:
            # Setup
            packet = LOCAL_PUBKEY + origin_header + MESSAGE_LENGTH * b'm'

            # Test
            self.assert_se(
                "Warning! Received packet masqueraded as a command.",
                process_message_packet, self.ts, packet, *self.args)

    # Private messages
    @mock.patch('time.sleep', return_value=None)
    def test_private_msg_from_contact(self, _: Any) -> None:
        # Setup
        assembly_ct_list = assembly_packet_creator(
            MESSAGE,
            self.msg,
            origin_header=ORIGIN_CONTACT_HEADER,
            encrypt_packet=True,
            onion_pub_key=nick_to_pub_key('Alice'))

        # Test
        for p in assembly_ct_list:
            self.assertIsNone(process_message_packet(self.ts, p, *self.args))

    @mock.patch('time.sleep', return_value=None)
    def test_private_msg_from_user(self, _: Any) -> None:
        # Setup
        assembly_ct_list = assembly_packet_creator(
            MESSAGE,
            self.msg,
            origin_header=ORIGIN_USER_HEADER,
            encrypt_packet=True,
            onion_pub_key=nick_to_pub_key('Alice'))

        # Test
        for p in assembly_ct_list:
            self.assertIsNone(process_message_packet(self.ts, p, *self.args))

    # Whispered messages
    @mock.patch('time.sleep', return_value=None)
    def test_whisper_msg_from_contact(self, _: Any) -> None:
        # Setup
        assembly_ct_list = assembly_packet_creator(
            MESSAGE,
            self.msg,
            origin_header=ORIGIN_CONTACT_HEADER,
            encrypt_packet=True,
            onion_pub_key=nick_to_pub_key('Alice'),
            whisper_header=bool_to_bytes(True))

        # Test
        for p in assembly_ct_list[:-1]:
            self.assertIsNone(process_message_packet(self.ts, p, *self.args))

        for p in assembly_ct_list[-1:]:
            self.assert_se("Whisper message complete.", process_message_packet,
                           self.ts, p, *self.args)

    @mock.patch('time.sleep', return_value=None)
    def test_whisper_msg_from_user(self, _: Any) -> None:
        # Setup
        assembly_ct_list = assembly_packet_creator(
            MESSAGE,
            self.msg,
            origin_header=ORIGIN_USER_HEADER,
            encrypt_packet=True,
            onion_pub_key=nick_to_pub_key('Alice'),
            whisper_header=bool_to_bytes(True))
        # Test
        for p in assembly_ct_list[:-1]:
            self.assertIsNone(process_message_packet(self.ts, p, *self.args))

        for p in assembly_ct_list[-1:]:
            self.assert_se("Whisper message complete.", process_message_packet,
                           self.ts, p, *self.args)

    @mock.patch('time.sleep', return_value=None)
    def test_empty_whisper_msg_from_user(self, _: Any) -> None:
        # Setup
        assembly_ct_list = assembly_packet_creator(
            MESSAGE,
            '',
            origin_header=ORIGIN_USER_HEADER,
            encrypt_packet=True,
            onion_pub_key=nick_to_pub_key('Alice'),
            whisper_header=bool_to_bytes(True))
        # Test
        for p in assembly_ct_list[:-1]:
            self.assertIsNone(process_message_packet(self.ts, p, *self.args))

        for p in assembly_ct_list[-1:]:
            self.assert_se("Whisper message complete.", process_message_packet,
                           self.ts, p, *self.args)

    # File key messages
    @mock.patch('time.sleep', return_value=None)
    def test_user_origin_raises_se(self, _: Any) -> None:
        assembly_ct_list = assembly_packet_creator(
            MESSAGE,
            ' ',
            origin_header=ORIGIN_USER_HEADER,
            encrypt_packet=True,
            onion_pub_key=nick_to_pub_key('Alice'),
            message_header=FILE_KEY_HEADER)

        for p in assembly_ct_list[-1:]:
            self.assert_se("File key message from the user.",
                           process_message_packet, self.ts, p, *self.args)

    @mock.patch('time.sleep', return_value=None)
    def test_invalid_file_key_data_raises_se(self, _: Any) -> None:
        assembly_ct_list = assembly_packet_creator(
            MESSAGE,
            ' ',
            origin_header=ORIGIN_CONTACT_HEADER,
            encrypt_packet=True,
            onion_pub_key=nick_to_pub_key('Alice'),
            message_header=FILE_KEY_HEADER)

        for p in assembly_ct_list[-1:]:
            self.assert_se("Error: Received an invalid file key message.",
                           process_message_packet, self.ts, p, *self.args)

    @mock.patch('time.sleep', return_value=None)
    def test_too_large_file_key_data_raises_se(self, _: Any) -> None:
        assembly_ct_list = assembly_packet_creator(
            MESSAGE,
            base64.b85encode(BLAKE2_DIGEST_LENGTH * b'a' +
                             SYMMETRIC_KEY_LENGTH * b'b' + b'a').decode(),
            origin_header=ORIGIN_CONTACT_HEADER,
            encrypt_packet=True,
            onion_pub_key=nick_to_pub_key('Alice'),
            message_header=FILE_KEY_HEADER)

        for p in assembly_ct_list[-1:]:
            self.assert_se("Error: Received an invalid file key message.",
                           process_message_packet, self.ts, p, *self.args)

    @mock.patch('time.sleep', return_value=None)
    def test_valid_file_key_message(self, _: Any) -> None:
        assembly_ct_list = assembly_packet_creator(
            MESSAGE,
            base64.b85encode(BLAKE2_DIGEST_LENGTH * b'a' +
                             SYMMETRIC_KEY_LENGTH * b'b').decode(),
            origin_header=ORIGIN_CONTACT_HEADER,
            encrypt_packet=True,
            onion_pub_key=nick_to_pub_key('Alice'),
            message_header=FILE_KEY_HEADER)
        for p in assembly_ct_list[-1:]:
            self.assert_se("Received file decryption key from Alice",
                           process_message_packet, self.ts, p, *self.args)

    # Group messages
    @mock.patch('time.sleep', return_value=None)
    def test_invalid_message_header_raises_se(self, _: Any) -> None:
        # Setup
        assembly_ct_list = assembly_packet_creator(
            MESSAGE,
            'test_message',
            origin_header=ORIGIN_CONTACT_HEADER,
            encrypt_packet=True,
            onion_pub_key=nick_to_pub_key('Alice'),
            message_header=b'Z')

        # Test
        self.assert_se("Error: Message from contact had an invalid header.",
                       process_message_packet, self.ts, assembly_ct_list[0],
                       *self.args)

    @mock.patch('time.sleep', return_value=None)
    def test_invalid_window_raises_se(self, _: Any) -> None:
        # Setup
        assembly_ct_list = assembly_packet_creator(
            MESSAGE,
            'test_message',
            origin_header=ORIGIN_CONTACT_HEADER,
            encrypt_packet=True,
            onion_pub_key=nick_to_pub_key('Alice'),
            group_id=self.group_id)

        self.group_list.get_group(
            'test_group').group_id = GROUP_ID_LENGTH * b'a'

        # Test
        self.assert_se("Error: Received message to an unknown group.",
                       process_message_packet, self.ts, assembly_ct_list[0],
                       *self.args)

    @mock.patch('time.sleep', return_value=None)
    def test_invalid_message_raises_se(self, _: Any) -> None:
        # Setup
        assembly_ct_list = assembly_packet_creator(
            MESSAGE,
            ' ',
            origin_header=ORIGIN_CONTACT_HEADER,
            encrypt_packet=True,
            onion_pub_key=nick_to_pub_key('Alice'),
            group_id=self.group_id,
            tamper_plaintext=True)

        # Test
        self.assert_se("Error: Received an invalid group message.",
                       process_message_packet, self.ts, assembly_ct_list[0],
                       *self.args)

    @mock.patch('time.sleep', return_value=None)
    def test_invalid_whisper_header_raises_se(self, _: Any) -> None:
        # Setup
        assembly_ct_list = assembly_packet_creator(
            MESSAGE,
            '',
            origin_header=ORIGIN_CONTACT_HEADER,
            encrypt_packet=True,
            onion_pub_key=nick_to_pub_key('Alice'),
            whisper_header=b'',
            message_header=b'')

        # Test
        self.assert_se(
            "Error: Message from contact had an invalid whisper header.",
            process_message_packet, self.ts, assembly_ct_list[0], *self.args)

    @mock.patch('time.sleep', return_value=None)
    def test_contact_not_in_group_raises_se(self, _: Any) -> None:
        # Setup

        assembly_ct_list = assembly_packet_creator(
            MESSAGE,
            'test_message',
            origin_header=ORIGIN_CONTACT_HEADER,
            encrypt_packet=True,
            group_id=self.group_id,
            onion_pub_key=nick_to_pub_key('Charlie'))

        # Test
        self.assert_se("Error: Account is not a member of the group.",
                       process_message_packet, self.ts, assembly_ct_list[0],
                       *self.args)

    @mock.patch('time.sleep', return_value=None)
    def test_normal_group_msg_from_contact(self, _: Any) -> None:
        # Setup
        assembly_ct_list = assembly_packet_creator(
            MESSAGE,
            self.msg,
            origin_header=ORIGIN_CONTACT_HEADER,
            group_id=self.group_id,
            encrypt_packet=True,
            onion_pub_key=nick_to_pub_key('Alice'))

        for p in assembly_ct_list:
            self.assertIsNone(process_message_packet(self.ts, p, *self.args))

    @mock.patch('time.sleep', return_value=None)
    def test_normal_group_msg_from_user(self, _: Any) -> None:
        # Setup
        assembly_ct_list = assembly_packet_creator(
            MESSAGE,
            self.msg,
            origin_header=ORIGIN_USER_HEADER,
            group_id=self.group_id,
            encrypt_packet=True,
            onion_pub_key=nick_to_pub_key('Alice'))

        for p in assembly_ct_list:
            self.assertIsNone(process_message_packet(self.ts, p, *self.args))

    # Files
    @mock.patch('time.sleep', return_value=None)
    def test_file(self, _: Any) -> None:
        # Setup
        assembly_ct_list = assembly_packet_creator(
            FILE,
            origin_header=ORIGIN_CONTACT_HEADER,
            encrypt_packet=True,
            onion_pub_key=nick_to_pub_key('Alice'))

        # Test
        for p in assembly_ct_list[:-1]:
            self.assertIsNone(process_message_packet(self.ts, p, *self.args))

        for p in assembly_ct_list[-1:]:
            self.assert_se("File storage complete.", process_message_packet,
                           self.ts, p, *self.args)

    @mock.patch('time.sleep', return_value=None)
    def test_file_when_reception_is_disabled(self, _: Any) -> None:
        # Setup
        assembly_ct_list = assembly_packet_creator(
            FILE,
            origin_header=ORIGIN_CONTACT_HEADER,
            encrypt_packet=True,
            onion_pub_key=nick_to_pub_key('Alice'))

        self.contact_list.get_contact_by_pub_key(
            nick_to_pub_key('Alice')).file_reception = False

        # Test
        self.assert_se(
            "Alert! File transmission from Alice but reception is disabled.",
            process_message_packet, self.ts, assembly_ct_list[0], *self.args)
Ejemplo n.º 28
0
class TestAddNewContact(TFCTestCase):
    def setUp(self):
        self.o_getpass = getpass.getpass
        self.contact_list = ContactList()
        self.group_list = GroupList()
        self.settings = Settings(disable_gui_dialog=True)
        self.queues = {
            COMMAND_PACKET_QUEUE: Queue(),
            NH_PACKET_QUEUE: Queue(),
            KEY_MANAGEMENT_QUEUE: Queue()
        }

    def tearDown(self):
        getpass.getpass = self.o_getpass

        with ignored(OSError):
            os.remove('[email protected] - Give to [email protected]')

        for key in self.queues:
            while not self.queues[key].empty():
                self.queues[key].get()
            time.sleep(0.1)
            self.queues[key].close()

    def test_adding_new_contact_during_traffic_masking_raises_fr(self):
        # Setup
        self.settings.session_traffic_masking = True

        # Test
        self.assertFR("Error: Command is disabled during traffic masking.",
                      add_new_contact, self.contact_list, self.group_list,
                      self.settings, self.queues)

    def test_contact_list_full_raises_fr(self):
        # Setup
        self.contact_list = ContactList(
            nicks=['contact_{}'.format(n) for n in range(20)])

        # Test
        self.assertFR("Error: TFC settings only allow 20 accounts.",
                      add_new_contact, self.contact_list, self.group_list,
                      self.settings, self.queues)

    def test_default_nick_x25519_kex(self):
        # Setup
        input_list = [
            '*****@*****.**', '*****@*****.**', '', '',
            '5JJwZE46Eic9B8sKJ8Qocyxa8ytUJSfcqRo7Hr5ES7YgFGeJjCJ', 'Yes'
        ]
        gen = iter(input_list)
        builtins.input = lambda _: str(next(gen))

        # Test
        self.assertIsNone(
            add_new_contact(self.contact_list, self.group_list, self.settings,
                            self.queues))

        contact = self.contact_list.get_contact('*****@*****.**')
        self.assertEqual(contact.nick, 'Alice')
        self.assertNotEqual(contact.tx_fingerprint, bytes(
            FINGERPRINT_LEN))  # Indicates that PSK function was not called

    def test_standard_nick_psk_kex(self):
        # Setup
        getpass.getpass = lambda _: 'test_password'
        input_list = [
            '*****@*****.**', '*****@*****.**', 'Alice_', 'psk', '.'
        ]
        gen = iter(input_list)
        builtins.input = lambda _: str(next(gen))

        # Test
        self.assertIsNone(
            add_new_contact(self.contact_list, self.group_list, self.settings,
                            self.queues))
        contact = self.contact_list.get_contact('*****@*****.**')
        self.assertEqual(contact.nick, 'Alice_')
        self.assertEqual(
            contact.tx_fingerprint,
            bytes(FINGERPRINT_LEN))  # Indicates that PSK function was called
Ejemplo n.º 29
0
 def setUp(self):
     self.contact_list = ContactList(nicks=['Alice', 'Bob'])
     self.group_list = GroupList(groups=['test_group'])
Ejemplo n.º 30
0
class TestContactSetting(TFCTestCase):

    def setUp(self):
        """Pre-test actions."""
        self.contact_list = ContactList(nicks=['Alice', 'Bob'])
        self.group_list   = GroupList(groups=['test_group'])
        self.settings     = Settings()
        self.queues       = gen_queue_dict()
        self.pub_key      = nick_to_pub_key("Alice")
        self.args         = self.contact_list, self.group_list, self.settings, self.queues

    def tearDown(self):
        """Post-test actions."""
        tear_queues(self.queues)

    def test_invalid_command_raises_fr(self):
        self.assert_fr("Error: Invalid command.", contact_setting, UserInput('loging on'), None, *self.args)

    def test_missing_parameter_raises_fr(self):
        self.assert_fr("Error: Invalid command.", contact_setting, UserInput(''), None, *self.args)

    def test_invalid_extra_parameter_raises_fr(self):
        self.assert_fr("Error: Invalid command.", contact_setting, UserInput('logging on al'), None, *self.args)

    def test_enable_logging_for_user(self):
        # Setup
        contact              = self.contact_list.get_contact_by_address_or_nick('Alice')
        contact.log_messages = False
        window               = TxWindow(uid=self.pub_key,
                                        type=WIN_TYPE_CONTACT,
                                        contact=contact)

        # Test
        self.assertFalse(contact.log_messages)
        self.assertIsNone(contact_setting(UserInput('logging on'), window, *self.args))
        self.assertEqual(self.queues[COMMAND_PACKET_QUEUE].qsize(), 1)
        self.assertEqual(self.queues[LOG_SETTING_QUEUE].qsize(),    0)
        self.assertTrue(contact.log_messages)

    def test_enable_logging_for_user_during_traffic_masking(self):
        # Setup
        contact              = self.contact_list.get_contact_by_address_or_nick('Alice')
        contact.log_messages = False
        window               = TxWindow(uid=self.pub_key,
                                        type=WIN_TYPE_CONTACT,
                                        contact=contact,
                                        log_messages=False)
        self.settings.traffic_masking = True

        # Test
        self.assertFalse(contact.log_messages)
        self.assertFalse(window.log_messages)

        self.assertIsNone(contact_setting(UserInput('logging on'), window, *self.args))

        self.assertEqual(self.queues[TM_COMMAND_PACKET_QUEUE].qsize(), 1)
        self.assertTrue(self.queues[LOG_SETTING_QUEUE].get())
        self.assertTrue(window.log_messages)
        self.assertTrue(contact.log_messages)

    def test_enable_logging_for_group(self):
        # Setup
        group              = self.group_list.get_group('test_group')
        group.log_messages = False
        window             = TxWindow(uid=group_name_to_group_id('test_group'),
                                      type=WIN_TYPE_GROUP,
                                      group=group,
                                      window_contacts=group.members)

        # Test
        self.assertFalse(group.log_messages)
        self.assertIsNone(contact_setting(UserInput('logging on'), window, *self.args))
        self.assertTrue(group.log_messages)

    def test_enable_logging_for_all_users(self):
        # Setup
        contact = self.contact_list.get_contact_by_address_or_nick("Alice")
        window  = TxWindow(uid=self.pub_key,
                           type=WIN_TYPE_CONTACT,
                           contact=contact,
                           window_contacts=[contact])

        for c in self.contact_list:
            c.log_messages = False
        for g in self.group_list:
            g.log_messages = False

        # Test
        for c in self.contact_list:
            self.assertFalse(c.log_messages)
        for g in self.group_list:
            self.assertFalse(g.log_messages)

        self.assertIsNone(contact_setting(UserInput('logging on all'), window, *self.args))

        for c in self.contact_list:
            self.assertTrue(c.log_messages)
        for g in self.group_list:
            self.assertTrue(g.log_messages)

    def test_disable_logging_for_user(self):
        # Setup
        contact              = self.contact_list.get_contact_by_address_or_nick('Alice')
        contact.log_messages = True
        window               = TxWindow(uid=self.pub_key,
                                        type=WIN_TYPE_CONTACT,
                                        contact=contact,
                                        window_contacts=[contact])

        # Test
        self.assertTrue(contact.log_messages)
        self.assertIsNone(contact_setting(UserInput('logging off'), window, *self.args))
        self.assertFalse(contact.log_messages)

    def test_disable_logging_for_group(self):
        # Setup
        group              = self.group_list.get_group('test_group')
        group.log_messages = True
        window             = TxWindow(uid=group_name_to_group_id('test_group'),
                                      type=WIN_TYPE_GROUP,
                                      group=group,
                                      window_contacts=group.members)

        # Test
        self.assertTrue(group.log_messages)
        self.assertIsNone(contact_setting(UserInput('logging off'), window, *self.args))
        self.assertFalse(group.log_messages)

    def test_disable_logging_for_all_users(self):
        # Setup
        contact = self.contact_list.get_contact_by_address_or_nick("Alice")
        window  = TxWindow(uid=self.pub_key,
                           type=WIN_TYPE_CONTACT,
                           contact=contact,
                           window_contacts=[contact])

        for c in self.contact_list:
            c.log_messages = True
        for g in self.group_list:
            g.log_messages = True

        # Test
        for c in self.contact_list:
            self.assertTrue(c.log_messages)
        for g in self.group_list:
            self.assertTrue(g.log_messages)

        self.assertIsNone(contact_setting(UserInput('logging off all'), window, *self.args))

        for c in self.contact_list:
            self.assertFalse(c.log_messages)
        for g in self.group_list:
            self.assertFalse(g.log_messages)

    def test_enable_file_reception_for_user(self):
        # Setup
        contact                = self.contact_list.get_contact_by_address_or_nick('Alice')
        contact.file_reception = False
        window                 = TxWindow(uid=self.pub_key,
                                          type=WIN_TYPE_CONTACT,
                                          contact=contact,
                                          window_contacts=[contact])

        # Test
        self.assertFalse(contact.file_reception)
        self.assertIsNone(contact_setting(UserInput('store on'), window, *self.args))
        self.assertTrue(contact.file_reception)

    def test_enable_file_reception_for_group(self):
        # Setup
        group  = self.group_list.get_group('test_group')
        window = TxWindow(uid=group_name_to_group_id('test_group'),
                          type=WIN_TYPE_GROUP,
                          group=group,
                          window_contacts=group.members)

        for m in group:
            m.file_reception = False

        # Test
        for m in group:
            self.assertFalse(m.file_reception)
        self.assertIsNone(contact_setting(UserInput('store on'), window, *self.args))
        for m in group:
            self.assertTrue(m.file_reception)

    def test_enable_file_reception_for_all_users(self):
        # Setup
        contact = self.contact_list.get_contact_by_address_or_nick("Alice")
        window  = TxWindow(uid=self.pub_key,
                           type=WIN_TYPE_CONTACT,
                           contact=contact,
                           window_contacts=[contact])

        for c in self.contact_list:
            c.file_reception = False

        # Test
        for c in self.contact_list:
            self.assertFalse(c.file_reception)

        self.assertIsNone(contact_setting(UserInput('store on all'), window, *self.args))
        for c in self.contact_list:
            self.assertTrue(c.file_reception)

    def test_disable_file_reception_for_user(self):
        # Setup
        contact                = self.contact_list.get_contact_by_address_or_nick('Alice')
        contact.file_reception = True
        window                 = TxWindow(uid=self.pub_key,
                                          type=WIN_TYPE_CONTACT,
                                          contact=contact,
                                          window_contacts=[contact])

        # Test
        self.assertTrue(contact.file_reception)
        self.assertIsNone(contact_setting(UserInput('store off'), window, *self.args))
        self.assertFalse(contact.file_reception)

    def test_disable_file_reception_for_group(self):
        # Setup
        group  = self.group_list.get_group('test_group')
        window = TxWindow(uid=group_name_to_group_id('test_group'),
                          type=WIN_TYPE_GROUP,
                          group=group,
                          window_contacts=group.members)

        for m in group:
            m.file_reception = True

        # Test
        for m in group:
            self.assertTrue(m.file_reception)

        self.assertIsNone(contact_setting(UserInput('store off'), window, *self.args))
        for m in group:
            self.assertFalse(m.file_reception)

    def test_disable_file_reception_for_all_users(self):
        # Setup
        contact = self.contact_list.get_contact_by_address_or_nick("Alice")
        window  = TxWindow(uid=self.pub_key,
                           type=WIN_TYPE_CONTACT,
                           contact=contact,
                           window_contacts=[contact])

        for c in self.contact_list:
            c.file_reception = True

        # Test
        for c in self.contact_list:
            self.assertTrue(c.file_reception)
        self.assertIsNone(contact_setting(UserInput('store off all'), window, *self.args))
        for c in self.contact_list:
            self.assertFalse(c.file_reception)

    def test_enable_notifications_for_user(self):
        # Setup
        contact               = self.contact_list.get_contact_by_address_or_nick('Alice')
        contact.notifications = False
        window                = TxWindow(uid=self.pub_key,
                                         type=WIN_TYPE_CONTACT,
                                         contact=contact)

        # Test
        self.assertFalse(contact.notifications)
        self.assertIsNone(contact_setting(UserInput('notify on'), window, *self.args))
        self.assertTrue(contact.notifications)

    def test_enable_notifications_for_group(self):
        # Setup
        user_input          = UserInput('notify on')
        group               = self.group_list.get_group('test_group')
        group.notifications = False
        window              = TxWindow(uid=group_name_to_group_id('test_group'),
                                       type=WIN_TYPE_GROUP,
                                       group=group,
                                       window_contacts=group.members)

        # Test
        self.assertFalse(group.notifications)
        self.assertIsNone(contact_setting(user_input, window, *self.args))
        self.assertTrue(group.notifications)

    def test_enable_notifications_for_all_users(self):
        # Setup
        contact = self.contact_list.get_contact_by_address_or_nick("Alice")
        window  = TxWindow(uid=self.pub_key,
                           type=WIN_TYPE_CONTACT,
                           contact=contact,
                           window_contacts=[contact])

        for c in self.contact_list:
            c.notifications = False
        for g in self.group_list:
            g.notifications = False

        # Test
        for c in self.contact_list:
            self.assertFalse(c.notifications)
        for g in self.group_list:
            self.assertFalse(g.notifications)

        self.assertIsNone(contact_setting(UserInput('notify on all'), window, *self.args))

        for c in self.contact_list:
            self.assertTrue(c.notifications)
        for g in self.group_list:
            self.assertTrue(g.notifications)

    def test_disable_notifications_for_user(self):
        # Setup
        contact               = self.contact_list.get_contact_by_address_or_nick('Alice')
        contact.notifications = True
        window                = TxWindow(uid=self.pub_key,
                                         type=WIN_TYPE_CONTACT,
                                         contact=contact,
                                         window_contacts=[contact])

        # Test
        self.assertTrue(contact.notifications)
        self.assertIsNone(contact_setting(UserInput('notify off'), window, *self.args))
        self.assertFalse(contact.notifications)

    def test_disable_notifications_for_group(self):
        # Setup
        group               = self.group_list.get_group('test_group')
        group.notifications = True
        window              = TxWindow(uid=group_name_to_group_id('test_group'),
                                       type=WIN_TYPE_GROUP,
                                       group=group,
                                       window_contacts=group.members)

        # Test
        self.assertTrue(group.notifications)
        self.assertIsNone(contact_setting(UserInput('notify off'), window, *self.args))
        self.assertFalse(group.notifications)

    def test_disable_notifications_for_all_users(self):
        # Setup
        contact = self.contact_list.get_contact_by_address_or_nick("Alice")
        window  = TxWindow(uid=self.pub_key,
                           type=WIN_TYPE_CONTACT,
                           contact=contact,
                           window_contacts=[contact])

        for c in self.contact_list:
            c.notifications = True
        for g in self.group_list:
            g.notifications = True

        # Test
        for c in self.contact_list:
            self.assertTrue(c.notifications)
        for g in self.group_list:
            self.assertTrue(g.notifications)

        self.assertIsNone(contact_setting(UserInput('notify off all'), window, *self.args))

        for c in self.contact_list:
            self.assertFalse(c.notifications)
        for g in self.group_list:
            self.assertFalse(g.notifications)