Пример #1
0
class TestSettings(TFCTestCase):
    def setUp(self):
        self.o_input = builtins.input
        builtins.input = lambda _: 'yes'
        self.masterkey = MasterKey()
        self.settings = Settings(self.masterkey,
                                 operation='ut',
                                 local_test=False,
                                 dd_sockets=False)
        self.contact_list = ContactList(
            nicks=['contact_{}'.format(n) for n in range(18)])
        self.group_list = GroupList(
            groups=['group_{}'.format(n) for n in range(18)])
        self.group_list.groups[0] = create_group(
            'group_0', ['contact_{}'.format(n) for n in range(18)])

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

    def test_invalid_type_raises_critical_error_on_store(self):
        self.settings.serial_error_correction = b'bytestring'
        with self.assertRaises(SystemExit):
            self.settings.store_settings()

    def test_invalid_type_raises_critical_error_on_load(self):
        with self.assertRaises(SystemExit):
            self.settings.nh_bypass_messages = b'bytestring'
            self.settings.load_settings()

    def test_store_and_load_settings(self):
        # Test store
        self.assertFalse(self.settings.disable_gui_dialog)
        self.settings.disable_gui_dialog = True
        self.settings.store_settings()
        self.assertEqual(os.path.getsize(f"{DIR_USER_DATA}ut_settings"),
                         SETTING_LENGTH)

        # Test load
        settings2 = Settings(self.masterkey, 'ut', False, False)
        self.assertTrue(settings2.disable_gui_dialog)

    def test_invalid_type_raises_critical_error_when_changing_settings(self):
        self.settings.traffic_masking = b'bytestring'
        with self.assertRaises(SystemExit):
            self.assertIsNone(
                self.settings.change_setting('traffic_masking', 'True',
                                             self.contact_list,
                                             self.group_list))

    def test_change_settings(self):
        self.assertFR("Error: Invalid value 'Falsee'",
                      self.settings.change_setting, 'disable_gui_dialog',
                      'Falsee', self.contact_list, self.group_list)
        self.assertFR("Error: Invalid value '1.1'",
                      self.settings.change_setting,
                      'max_number_of_group_members', '1.1', self.contact_list,
                      self.group_list)
        self.assertFR("Error: Invalid value '-1.1'",
                      self.settings.change_setting,
                      'max_duration_of_random_delay', '-1.1',
                      self.contact_list, self.group_list)
        self.assertFR("Error: Invalid value '18446744073709551616'",
                      self.settings.change_setting, 'serial_error_correction',
                      str(2**64), self.contact_list, self.group_list)
        self.assertFR("Error: Invalid value 'True'",
                      self.settings.change_setting,
                      'traffic_masking_static_delay', 'True',
                      self.contact_list, self.group_list)

        self.assertIsNone(
            self.settings.change_setting('serial_error_correction', '10',
                                         self.contact_list, self.group_list))
        self.assertIsNone(
            self.settings.change_setting('rxm_usb_serial_adapter', 'True',
                                         self.contact_list, self.group_list))
        self.assertIsNone(
            self.settings.change_setting('traffic_masking', 'True',
                                         self.contact_list, self.group_list))

    def test_validate_key_value_pair(self):
        self.assertFR(
            "Error: Database padding settings must be divisible by 10.",
            self.settings.validate_key_value_pair,
            'max_number_of_group_members', 0, self.contact_list,
            self.group_list)
        self.assertFR(
            "Error: Database padding settings must be divisible by 10.",
            self.settings.validate_key_value_pair,
            'max_number_of_group_members', 18, self.contact_list,
            self.group_list)
        self.assertFR(
            "Error: Database padding settings must be divisible by 10.",
            self.settings.validate_key_value_pair, 'max_number_of_groups', 18,
            self.contact_list, self.group_list)
        self.assertFR(
            "Error: Database padding settings must be divisible by 10.",
            self.settings.validate_key_value_pair, 'max_number_of_contacts',
            18, self.contact_list, self.group_list)
        self.assertFR("Error: Can't set max number of members lower than 20.",
                      self.settings.validate_key_value_pair,
                      'max_number_of_group_members', 10, self.contact_list,
                      self.group_list)
        self.assertFR("Error: Can't set max number of groups lower than 20.",
                      self.settings.validate_key_value_pair,
                      'max_number_of_groups', 10, self.contact_list,
                      self.group_list)
        self.assertFR("Error: Can't set max number of contacts lower than 20.",
                      self.settings.validate_key_value_pair,
                      'max_number_of_contacts', 10, self.contact_list,
                      self.group_list)
        self.assertFR("Error: Specified baud rate is not supported.",
                      self.settings.validate_key_value_pair, 'serial_baudrate',
                      10, self.contact_list, self.group_list)
        self.assertFR("Error: Invalid value for error correction ratio.",
                      self.settings.validate_key_value_pair,
                      'serial_error_correction', 0, self.contact_list,
                      self.group_list)
        self.assertFR("Error: Invalid value for error correction ratio.",
                      self.settings.validate_key_value_pair,
                      'serial_error_correction', -1, self.contact_list,
                      self.group_list)
        self.assertFR("Error: Too small value for message notify duration.",
                      self.settings.validate_key_value_pair,
                      'new_message_notify_duration', 0.04, self.contact_list,
                      self.group_list)

        self.assertIsNone(
            self.settings.validate_key_value_pair("serial_baudrate", 9600,
                                                  self.contact_list,
                                                  self.group_list))

    def test_too_narrow_terminal_raises_fr_when_printing_settings(self):
        # Setup
        o_get_terminal_size = shutil.get_terminal_size
        shutil.get_terminal_size = lambda: [64, 64]

        # Test
        self.assertFR("Error: Screen width is too small.",
                      self.settings.print_settings)

        # Teardown
        shutil.get_terminal_size = o_get_terminal_size

    def test_setup(self):
        # Setup
        builtins.input = lambda _: 'No'

        # Test
        self.settings.software_operation = TX
        self.settings.setup()
        self.assertFalse(self.settings.txm_usb_serial_adapter)

        self.settings.software_operation = RX
        self.settings.setup()
        self.assertFalse(self.settings.rxm_usb_serial_adapter)

    def test_print_settings(self):
        self.settings.max_number_of_group_members = 30
        self.settings.log_messages_by_default = True
        self.settings.traffic_masking_static_delay = 10.2
        self.assertPrints(
            CLEAR_ENTIRE_SCREEN + CURSOR_LEFT_UP_CORNER + """\

Setting name                    Current value   Default value   Description
────────────────────────────────────────────────────────────────────────────────
disable_gui_dialog              False           False           True replaces
                                                                Tkinter dialogs
                                                                with CLI prompts

max_number_of_group_members     30              20              Max members in
                                                                group (TxM/RxM
                                                                must have the
                                                                same value)

max_number_of_groups            20              20              Max number of
                                                                groups (TxM/RxM
                                                                must have the
                                                                same value)

max_number_of_contacts          20              20              Max number of
                                                                contacts
                                                                (TxM/RxM must
                                                                have the same
                                                                value)

serial_baudrate                 19200           19200           The speed of
                                                                serial interface
                                                                in bauds per
                                                                second

serial_error_correction         5               5               Number of byte
                                                                errors serial
                                                                datagrams can
                                                                recover from

log_messages_by_default         True            False           Default logging
                                                                setting for new
                                                                contacts/groups

accept_files_by_default         False           False           Default file
                                                                reception
                                                                setting for new
                                                                contacts

show_notifications_by_default   True            True            Default message
                                                                notification
                                                                setting for new
                                                                contacts/groups

logfile_masking                 False           False           True hides real
                                                                size of logfile
                                                                during traffic
                                                                masking

txm_usb_serial_adapter          True            True            False uses
                                                                system's
                                                                integrated
                                                                serial interface

nh_bypass_messages              True            True            False removes NH
                                                                bypass interrupt
                                                                messages

confirm_sent_files              True            True            False sends
                                                                files without
                                                                asking for
                                                                confirmation

double_space_exits              False           False           True exits,
                                                                False clears
                                                                screen with
                                                                double space
                                                                command

traffic_masking                 False           False           True enables
                                                                traffic masking
                                                                to hide metadata

traffic_masking_static_delay    10.2            2.0             Static delay
                                                                between traffic
                                                                masking packets

traffic_masking_random_delay    2.0             2.0             Max random delay
                                                                for traffic
                                                                masking timing
                                                                obfuscation

multi_packet_random_delay       False           False           True adds IM
                                                                server spam
                                                                guard evading
                                                                delay

max_duration_of_random_delay    10.0            10.0            Maximum time for
                                                                random spam
                                                                guard evasion
                                                                delay

rxm_usb_serial_adapter          True            True            False uses
                                                                system's
                                                                integrated
                                                                serial interface

new_message_notify_preview      False           False           When True, shows
                                                                preview of
                                                                received message

new_message_notify_duration     1.0             1.0             Number of
                                                                seconds new
                                                                message
                                                                notification
                                                                appears


""", self.settings.print_settings)
Пример #2
0
class TestSettings(TFCTestCase):

    def setUp(self) -> None:
        """Pre-test actions."""
        self.unit_test_dir        = cd_unit_test()
        self.file_name            = f"{DIR_USER_DATA}{TX}_settings"
        self.master_key           = MasterKey()
        self.settings             = Settings(self.master_key, operation=TX, local_test=False)
        self.contact_list         = ContactList(nicks=[f'contact_{n}' for n in range(18)])
        self.group_list           = GroupList(groups=[f'group_{n}' for n in range(18)])
        self.group_list.groups[0] = create_group('group_0', [f'contact_{n}' for n in range(18)])
        self.args                 = self.contact_list, self.group_list

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

    def test_invalid_type_raises_critical_error_on_store(self) -> None:
        self.settings.tm_random_delay = b'bytestring'
        with self.assertRaises(SystemExit):
            self.settings.store_settings()

    def test_invalid_type_raises_critical_error_on_load(self) -> None:
        with self.assertRaises(SystemExit):
            self.settings.nc_bypass_messages = b'bytestring'
            self.settings.load_settings()

    def test_store_and_load_tx_settings(self) -> None:
        # Test store
        self.assertFalse(self.settings.disable_gui_dialog)
        self.settings.disable_gui_dialog = True
        self.settings.store_settings()
        self.assertEqual(os.path.getsize(self.file_name), SETTING_LENGTH)

        # Test load
        settings2 = Settings(self.master_key, TX, False)
        self.assertTrue(settings2.disable_gui_dialog)

    def test_store_and_load_rx_settings(self) -> None:
        # Setup
        self.settings = Settings(self.master_key, operation=RX, local_test=False)

        # Test store
        self.assertFalse(self.settings.disable_gui_dialog)
        self.settings.disable_gui_dialog = True
        self.settings.store_settings()
        self.assertEqual(os.path.getsize(self.file_name), SETTING_LENGTH)

        # Test load
        settings2 = Settings(self.master_key, RX, False)
        self.assertTrue(settings2.disable_gui_dialog)

    def test_load_of_modified_database_raises_critical_error(self) -> None:
        # Store settings to database
        self.settings.store_settings()

        # Test reading from database works normally
        self.assertIsInstance(Settings(self.master_key, operation=TX, local_test=False), Settings)

        # Test loading of the tampered database raises CriticalError
        tamper_file(self.file_name, tamper_size=1)
        with self.assertRaises(SystemExit):
            Settings(self.master_key, operation=TX, local_test=False)

    def test_invalid_type_raises_critical_error_when_changing_settings(self) -> None:
        self.settings.traffic_masking = b'bytestring'
        with self.assertRaises(SystemExit):
            self.assertIsNone(self.settings.change_setting('traffic_masking', 'True', *self.args))

    def test_change_settings(self) -> None:
        self.assert_se("Error: Invalid setting value 'Falsee'.",
                       self.settings.change_setting, 'disable_gui_dialog', 'Falsee', *self.args)
        self.assert_se("Error: Invalid setting value '1.1'.",
                       self.settings.change_setting, 'max_number_of_group_members',     '1.1', *self.args)
        self.assert_se("Error: Invalid setting value '18446744073709551616'.",
                       self.settings.change_setting, 'max_number_of_contacts', str(2 ** 64), *self.args)
        self.assert_se("Error: Invalid setting value '-1.1'.",
                       self.settings.change_setting, 'tm_static_delay',                '-1.1', *self.args)
        self.assert_se("Error: Invalid setting value 'True'.",
                       self.settings.change_setting, 'tm_static_delay',                'True', *self.args)

        self.assertIsNone(self.settings.change_setting('traffic_masking',              'True', *self.args))
        self.assertIsNone(self.settings.change_setting('max_number_of_group_members',  '100',  *self.args))

    @mock.patch('builtins.input', side_effect=['No', 'Yes'])
    def test_validate_key_value_pair(self, _: Any) -> None:
        self.assert_se("Error: Database padding settings must be divisible by 10.",
                       self.settings.validate_key_value_pair, 'max_number_of_group_members', 0, *self.args)
        self.assert_se("Error: Database padding settings must be divisible by 10.",
                       self.settings.validate_key_value_pair, 'max_number_of_group_members', 18, *self.args)
        self.assert_se("Error: Database padding settings must be divisible by 10.",
                       self.settings.validate_key_value_pair, 'max_number_of_groups', 18, *self.args)
        self.assert_se("Error: Database padding settings must be divisible by 10.",
                       self.settings.validate_key_value_pair, 'max_number_of_contacts', 18, *self.args)
        self.assert_se("Error: Can't set the max number of members lower than 20.",
                       self.settings.validate_key_value_pair, 'max_number_of_group_members', 10, *self.args)
        self.assert_se("Error: Can't set the max number of groups lower than 20.",
                       self.settings.validate_key_value_pair, 'max_number_of_groups', 10, *self.args)
        self.assert_se("Error: Can't set the max number of contacts lower than 20.",
                       self.settings.validate_key_value_pair, 'max_number_of_contacts', 10, *self.args)
        self.assert_se("Error: Too small value for message notify duration.",
                       self.settings.validate_key_value_pair, 'new_message_notify_duration', 0.04, *self.args)
        self.assert_se("Error: Can't set static delay lower than 0.1.",
                       self.settings.validate_key_value_pair, 'tm_static_delay', 0.01, *self.args)
        self.assert_se("Error: Can't set random delay lower than 0.1.",
                       self.settings.validate_key_value_pair, 'tm_random_delay', 0.01, *self.args)
        self.assert_se("Aborted traffic masking setting change.",
                       self.settings.validate_key_value_pair, 'tm_random_delay', 0.1, *self.args)

        self.assertIsNone(self.settings.validate_key_value_pair("serial_baudrate",  9600, *self.args))
        self.assertIsNone(self.settings.validate_key_value_pair("tm_static_delay",     1, *self.args))

    @mock.patch('shutil.get_terminal_size', return_value=(64, 64))
    def test_too_narrow_terminal_raises_fr_when_printing_settings(self, _: Any) -> None:
        # Test
        self.assert_se("Error: Screen width is too small.", self.settings.print_settings)

    def test_print_settings(self) -> None:
        self.settings.max_number_of_group_members = 30
        self.settings.log_messages_by_default     = True
        self.settings.tm_static_delay             = 10.2
        self.assert_prints(CLEAR_ENTIRE_SCREEN + CURSOR_LEFT_UP_CORNER + """\

Setting name                    Current value   Default value   Description
────────────────────────────────────────────────────────────────────────────────
disable_gui_dialog              False           False           True replaces
                                                                GUI dialogs with
                                                                CLI prompts

max_number_of_group_members     30              50              Maximum number
                                                                of members in a
                                                                group

max_number_of_groups            50              50              Maximum number
                                                                of groups

max_number_of_contacts          50              50              Maximum number
                                                                of contacts

log_messages_by_default         True            False           Default logging
                                                                setting for new
                                                                contacts/groups

accept_files_by_default         False           False           Default file
                                                                reception
                                                                setting for new
                                                                contacts

show_notifications_by_default   True            True            Default message
                                                                notification
                                                                setting for new
                                                                contacts/groups

log_file_masking                False           False           True hides real
                                                                size of log file
                                                                during traffic
                                                                masking

ask_password_for_log_access     True            True            False disables
                                                                password prompt
                                                                when viewing/exp
                                                                orting logs

nc_bypass_messages              False           False           False removes
                                                                Networked
                                                                Computer bypass
                                                                interrupt
                                                                messages

confirm_sent_files              True            True            False sends
                                                                files without
                                                                asking for
                                                                confirmation

double_space_exits              False           False           True exits,
                                                                False clears
                                                                screen with
                                                                double space
                                                                command

traffic_masking                 False           False           True enables
                                                                traffic masking
                                                                to hide metadata

tm_static_delay                 10.2            2.0             The static delay
                                                                between traffic
                                                                masking packets

tm_random_delay                 2.0             2.0             Max random delay
                                                                for traffic
                                                                masking timing
                                                                obfuscation

allow_contact_requests          True            True            When False, does
                                                                not show TFC
                                                                contact requests

new_message_notify_preview      False           False           When True, shows
                                                                a preview of the
                                                                received message

new_message_notify_duration     1.0             1.0             Number of
                                                                seconds new
                                                                message
                                                                notification
                                                                appears

max_decompress_size             100000000       100000000       Max size
                                                                Receiver accepts
                                                                when
                                                                decompressing
                                                                file

""", self.settings.print_settings)