def decrypt_and_store_file( ts: 'datetime', # Timestamp of received packet file_ct: bytes, # File ciphertext file_key: bytes, # File decryption key file_name: str, # Name of the file onion_pub_key: bytes, # Onion Service pubkey of sender nick: str, # Nickname of sender window_list: 'WindowList', # WindowList object settings: 'Settings' # Settings object ) -> None: """Decrypt and store file.""" try: file_pt = auth_and_decrypt(file_ct, file_key) except nacl.exceptions.CryptoError: raise SoftError("Error: Decryption of file data failed.") try: file_dc = decompress(file_pt, settings.max_decompress_size) except zlib.error: raise SoftError("Error: Decompression of file data failed.") file_dir = f'{DIR_RECV_FILES}{nick}/' final_name = store_unique(file_dc, file_dir, file_name) message = f"Stored file from {nick} as '{final_name}'." if settings.traffic_masking and window_list.active_win is not None: window = window_list.active_win else: window = window_list.get_window(onion_pub_key) window.add_new(ts, message, onion_pub_key, output=True, event_msg=True)
def process_file( ts: 'datetime', # Timestamp of received_packet onion_pub_key: bytes, # Onion Service pubkey of sender file_ct: bytes, # File ciphertext file_key: bytes, # File decryption key contact_list: 'ContactList', # ContactList object window_list: 'WindowList', # WindowList object settings: 'Settings' # Settings object ) -> None: """Store file received from a contact.""" nick = contact_list.get_nick_by_pub_key(onion_pub_key) phase("Processing received file", head=1) try: file_pt = auth_and_decrypt(file_ct, file_key) except nacl.exceptions.CryptoError: raise SoftError( f"Error: Decryption key for file from {nick} was invalid.") try: file_dc = decompress(file_pt, settings.max_decompress_size) except zlib.error: raise SoftError(f"Error: Failed to decompress file from {nick}.") phase(DONE) print_on_previous_line(reps=2) try: file_name = bytes_to_str(file_dc[:PADDED_UTF32_STR_LENGTH]) except UnicodeError: raise SoftError( f"Error: Name of file from {nick} had an invalid encoding.") if not file_name.isprintable() or not file_name or '/' in file_name: raise SoftError(f"Error: Name of file from {nick} was invalid.") file_data = file_dc[PADDED_UTF32_STR_LENGTH:] file_dir = f'{DIR_RECV_FILES}{nick}/' final_name = store_unique(file_data, file_dir, file_name) message = f"Stored file from {nick} as '{final_name}'." if settings.traffic_masking and window_list.active_win is not None: window = window_list.active_win else: window = window_list.get_window(onion_pub_key) window.add_new(ts, message, onion_pub_key, output=True, event_msg=True)
def test_each_file_is_store_with_unique_name(self) -> None: self.assertEqual(store_unique(self.file_data, self.file_dir, self.file_name), 'test_file') self.assertEqual(store_unique(self.file_data, self.file_dir, self.file_name), 'test_file.1') self.assertEqual(store_unique(self.file_data, self.file_dir, self.file_name), 'test_file.2')