Exemplo n.º 1
0
def change_master_key(ts: 'datetime', window_list: 'WindowList',
                      contact_list: 'ContactList', group_list: 'GroupList',
                      key_list: 'KeyList', settings: 'Settings',
                      master_key: 'MasterKey') -> None:
    """Derive new master key based on master password delivered by TxM."""
    old_master_key = master_key.master_key[:]
    master_key.new_master_key()
    new_master_key = master_key.master_key

    ensure_dir(f'{DIR_USER_DATA}/')
    file_name = f'{DIR_USER_DATA}/{settings.software_operation}_logs'
    if os.path.isfile(file_name):
        phase("Re-encrypting log-file")
        re_encrypt(old_master_key, new_master_key, settings)
        phase('Done')

    key_list.store_keys()
    settings.store_settings()
    contact_list.store_contacts()
    group_list.store_groups()

    box_print("Master key successfully changed.", head=1)
    clear_screen(delay=1.5)

    local_win = window_list.get_window('local')
    local_win.print_new(ts, "Changed RxM master key.", print_=False)
Exemplo n.º 2
0
def change_master_key(ts: 'datetime', window_list: 'WindowList',
                      contact_list: 'ContactList', group_list: 'GroupList',
                      key_list: 'KeyList', settings: 'Settings',
                      master_key: 'MasterKey') -> None:
    """Prompt user for new master password and derive new master key from that."""
    try:
        old_master_key = master_key.master_key[:]
        master_key.new_master_key()

        phase("Re-encrypting databases")

        ensure_dir(DIR_USER_DATA)
        file_name = f'{DIR_USER_DATA}{settings.software_operation}_logs'
        if os.path.isfile(file_name):
            re_encrypt(old_master_key, master_key.master_key, settings)

        key_list.store_keys()
        settings.store_settings()
        contact_list.store_contacts()
        group_list.store_groups()

        phase(DONE)
        box_print("Master key successfully changed.", head=1)
        clear_screen(delay=1.5)

        local_win = window_list.get_window(LOCAL_ID)
        local_win.add_new(ts, "Changed RxM master key.")

    except KeyboardInterrupt:
        raise FunctionReturn("Password change aborted.",
                             delay=1,
                             head=3,
                             tail_clear=True)
Exemplo n.º 3
0
def change_master_key(user_input: 'UserInput', contact_list: 'ContactList',
                      group_list: 'GroupList', settings: 'Settings',
                      queues: Dict[bytes,
                                   'Queue'], master_key: 'MasterKey') -> None:
    """Change master key on TxM/RxM."""
    try:
        if settings.session_traffic_masking:
            raise FunctionReturn(
                "Error: Command is disabled during traffic masking.")

        try:
            device = user_input.plaintext.split()[1].lower()
        except IndexError:
            raise FunctionReturn("Error: No target system specified.")

        if device not in [TX, RX]:
            raise FunctionReturn("Error: Invalid target system.")

        if device == RX:
            queue_command(CHANGE_MASTER_K_HEADER, settings,
                          queues[COMMAND_PACKET_QUEUE])
            return None

        old_master_key = master_key.master_key[:]
        master_key.new_master_key()
        new_master_key = master_key.master_key

        phase("Re-encrypting databases")

        queues[KEY_MANAGEMENT_QUEUE].put(
            (KDB_CHANGE_MASTER_KEY_HEADER, master_key))

        ensure_dir(DIR_USER_DATA)
        file_name = f'{DIR_USER_DATA}{settings.software_operation}_logs'
        if os.path.isfile(file_name):
            re_encrypt(old_master_key, new_master_key, settings)

        settings.store_settings()
        contact_list.store_contacts()
        group_list.store_groups()

        phase(DONE)
        box_print("Master key successfully changed.", head=1)
        clear_screen(delay=1.5)

    except KeyboardInterrupt:
        raise FunctionReturn("Password change aborted.",
                             delay=1,
                             head=3,
                             tail_clear=True)
Exemplo n.º 4
0
def change_master_key(user_input:   'UserInput',
                      contact_list: 'ContactList',
                      group_list:   'GroupList',
                      settings:     'Settings',
                      queues:       Dict[bytes, 'Queue'],
                      master_key:   'MasterKey') -> None:
    """Change master key on TxM/RxM."""
    try:
        if settings.session_trickle:
            raise FunctionReturn("Command disabled during trickle connection.")

        try:
            device = user_input.plaintext.split()[1]
        except IndexError:
            raise FunctionReturn("No target system specified.")

        if device.lower() not in ['tx', 'txm', 'rx', 'rxm']:
            raise FunctionReturn("Invalid target system.")

        if device.lower() in ['rx', 'rxm']:
            queue_command(CHANGE_MASTER_K_HEADER, settings, queues[COMMAND_PACKET_QUEUE])
            print('')
            return None

        old_master_key = master_key.master_key[:]
        master_key.new_master_key()
        new_master_key = master_key.master_key

        ensure_dir(f'{DIR_USER_DATA}/')
        file_name = f'{DIR_USER_DATA}/{settings.software_operation}_logs'
        if os.path.isfile(file_name):
            phase("Re-encrypting log-file")
            re_encrypt(old_master_key, new_master_key, settings)
            phase("Done")

        queues[KEY_MANAGEMENT_QUEUE].put(('KEY', master_key))

        settings.store_settings()
        contact_list.store_contacts()
        group_list.store_groups()

        box_print("Master key successfully changed.", head=1)
        clear_screen(delay=1.5)
    except KeyboardInterrupt:
        raise FunctionReturn("Password change aborted.")
Exemplo n.º 5
0
    def test_database_encryption_with_another_key(self):
        # Setup
        window                = RxWindow(type=WIN_TYPE_CONTACT, uid='*****@*****.**', name='Alice')
        contact_list          = ContactList(self.old_key, self.settings)
        contact_list.contacts = [create_contact()]
        group_list            = GroupList()

        # Create temp file that must be removed
        with open("user_data/ut_logs_temp", 'wb+') as f:
            f.write(os.urandom(LOG_ENTRY_LENGTH))

        for p in assembly_packet_creator(MESSAGE, b'This is a short message'):
            write_log_entry(p, '*****@*****.**', self.settings, self.old_key, origin=ORIGIN_CONTACT_HEADER)
        for p in assembly_packet_creator(MESSAGE, b'This is a short message'):
            write_log_entry(p, '*****@*****.**', self.settings, self.old_key)

        # Test
        self.assertPrints((CLEAR_ENTIRE_SCREEN + CURSOR_LEFT_UP_CORNER + f"""\
Logfile of messages to/from Alice
════════════════════════════════════════════════════════════════════════════════
{self.time} Alice: This is a short message
{self.time}    Me: This is a short message
<End of logfile>

"""), access_logs, window, contact_list, group_list, self.settings, self.old_key)

        self.assertIsNone(re_encrypt(self.old_key.master_key, self.new_key.master_key, self.settings))

        # Test that decryption works with new key
        self.assertPrints((CLEAR_ENTIRE_SCREEN + CURSOR_LEFT_UP_CORNER + f"""\
Logfile of messages to/from Alice
════════════════════════════════════════════════════════════════════════════════
{self.time} Alice: This is a short message
{self.time}    Me: This is a short message
<End of logfile>

"""), access_logs, window, contact_list, group_list, self.settings, self.new_key)

        # Test that temp file is removed
        self.assertFalse(os.path.isfile("user_data/ut_logs_temp"))
Exemplo n.º 6
0
    def test_read_private_message(self):
        # Setup
        masterkey = MasterKey()
        settings  = Settings()
        window    = Window(type='contact', uid='*****@*****.**', name='Alice')

        contact_list          = ContactList(masterkey, settings)
        contact_list.contacts = [create_contact('Alice')]

        with self.assertRaises(FunctionReturn):
            self.assertIsNone(access_history(window, contact_list, settings, masterkey))

        for p in self.mock_entry_preprocessor('This is a short message'):
            write_log_entry(p, '*****@*****.**', settings, masterkey)

        long_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.")

        for p in self.mock_entry_preprocessor(long_msg):
            write_log_entry(p, '*****@*****.**', settings, masterkey)

        # Add packet cancelled half-way
        packets = self.mock_entry_preprocessor(long_msg)
        packets = packets[2:] + [M_C_HEADER + bytes(255)]
        for p in packets:
            write_log_entry(p, '*****@*****.**', settings, masterkey)

        # Test
        self.assertIsNone(access_history(window, contact_list, settings, masterkey))

        # Test window UID mismatch
        window.uid = '*****@*****.**'
        self.assertIsNone(access_history(window, contact_list, settings, masterkey))

        # Test window type mismatch
        window.uid  = '*****@*****.**'
        window.type = 'group'
        self.assertIsNone(access_history(window, contact_list, settings, masterkey))

        # Group messages

        window = Window(type='group', uid='testgroup', name='testgroup')

        contact_list          = ContactList(masterkey, settings)
        contact_list.contacts = [create_contact(n) for n in ['Alice', 'Charlie']]

        for p in self.mock_entry_preprocessor('This is a short message', group=True):
            write_log_entry(p, '*****@*****.**',   settings, masterkey)
            write_log_entry(p, '*****@*****.**', settings, masterkey)

        long_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.")

        for p in self.mock_entry_preprocessor(long_msg, group=True):
            write_log_entry(p, '*****@*****.**',   settings, masterkey)
            write_log_entry(p, '*****@*****.**', settings, masterkey)

        # Test
        self.assertIsNone(access_history(window, contact_list, settings, masterkey))

        # Test window name mismatch
        window.name = '*****@*****.**'
        self.assertIsNone(access_history(window, contact_list, settings, masterkey))

        # Test window type mismatch
        window.name = 'testgroup'
        window.type = 'contact'
        self.assertIsNone(access_history(window, contact_list, settings, masterkey))

        # Re-encrypt log database

        # Create garbage file to remove
        with open(f'{DIR_USER_DATA}/{settings.software_operation}_logs_temp', 'wb+') as f:
            f.write(b'will screw decryption')

        self.assertIsNone(re_encrypt(masterkey.master_key, 32 * b'\x01', settings))
        masterkey.master_key = 32 * b'\x01'
        self.assertIsNone(access_history(window, contact_list, settings, masterkey))
        self.assertIsNone(access_history(window, contact_list, settings, masterkey, export=True))

        cleanup()
        with self.assertRaises(FunctionReturn):
            re_encrypt(masterkey.master_key, 32 * b'\x01', settings)

        # Teardown
        os.remove("Unittest - Plaintext log (testgroup)")
        cleanup()