def test_store_local_settings(self): abc_setting = self.manager.get_setting('abc.de') abc_setting.set_template('xAxonaxxxx') self.manager.set_setting(abc_setting) new_setting = PasswordSetting('hugo.com') new_setting.set_template('xonxAxxaxxxx') self.manager.set_setting(new_setting) kgk_manager = KgkManager() kgk_manager.set_preference_manager(self.preference_manager) kgk_manager.create_new_kgk() salt = os.urandom(32) kgk_manager.create_and_save_new_kgk_block( Crypter(Crypter.createIvKey(b'xyz', salt, iterations=3))) self.manager.store_local_settings(kgk_manager) with open(os.path.expanduser('~/.ctSESAM_test.pws'), 'br') as f: data = f.read() settings_crypter = PasswordSettingsManager.get_settings_crypter( kgk_manager) decrypted_settings = settings_crypter.decrypt(data[144:]) sync_settings_len = struct.unpack('!I', decrypted_settings[:4])[0] data = json.loads( Packer.decompress( decrypted_settings[4 + sync_settings_len:]).decode('utf8')) self.assertEqual('abc.de', data['settings']['abc.de']['domain']) self.assertEqual('xAxonaxxxx', data['settings']['abc.de']['passwordTemplate']) self.assertEqual('hugo.com', data['settings']['hugo.com']['domain']) self.assertEqual('xonxAxxaxxxx', data['settings']['hugo.com']['passwordTemplate'])
def update_from_export_data(self, kgk_manager, blob): """ Call this method to pull settings from the sync server. :param kgk_manager: the kgk manager used for the decryption :type kgk_manager: KgkManager :param blob: the export data :type blob: bytes """ if not blob[0] == 1: print("Version error: Wrong data format. Could not import anything.") return True settings_crypter = self.get_settings_crypter(kgk_manager) decrypted_settings = settings_crypter.decrypt(blob[145:]) if len(decrypted_settings) <= 0: print("Wrong password.") return False self.remote_data = json.loads(str(Packer.decompress(decrypted_settings), encoding='utf-8')) self.update_remote = False for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] found = False i = 0 while i < len(self.settings): setting = self.settings[i] if setting.get_domain() == domain_name: found = True if datetime.strptime(data_set['mDate'], "%Y-%m-%dT%H:%M:%S") > setting.get_m_date(): if 'deleted' in data_set and data_set['deleted']: self.settings.pop(i) else: setting.load_from_dict(data_set) setting.set_synced(True) self.update_remote = True i += 1 else: i += 1 else: i += 1 if not found: new_setting = PasswordSetting(domain_name) new_setting.load_from_dict(data_set) new_setting.set_synced(True) self.settings.append(new_setting) for setting in self.settings: found = False for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] if setting.get_domain() == domain_name: found = True if setting.get_m_date() >= datetime.strptime(data_set['mDate'], "%Y-%m-%dT%H:%M:%S"): self.update_remote = True if not found: self.update_remote = True self.store_local_settings(kgk_manager) return self.update_remote
def test_get_export_data(self): settings = { 'settings': { 'unit.test': { 'domain': 'unit.test', 'extras': '#!"§$%&/()[]{}=-_+*<>;:.', 'passwordTemplate': 'xnxoaAxxxx', 'iterations': 5000, 'notes': 'Nice note!', 'salt': 'cGVwcGVy', 'cDate': '2011-02-12T11:07:31', 'mDate': '2011-02-12T11:07:32' }, 'some.domain': { 'domain': 'some.domain', 'extras': '6478593021', 'passwordTemplate': 'xnxoaA', 'iterations': 4096, 'salt': 'cGVwcGVy', 'cDate': '2013-06-17T04:03:41', 'mDate': '2014-08-02T10:37:12' } }, 'synced': [] } salt = os.urandom(32) kgk_manager = KgkManager() kgk_manager.set_preference_manager(self.preference_manager) kgk_manager.create_new_kgk() kgk_block = kgk_manager.create_and_save_new_kgk_block( Crypter(Crypter.createIvKey(b'xyz', salt, iterations=3))) crypter = PasswordSettingsManager.get_settings_crypter(kgk_manager) f = open(os.path.expanduser('~/.ctSESAM_test.pws'), 'bw') f.write(salt + kgk_block + crypter.encrypt( struct.pack('!I', 0) + Packer.compress(json.dumps(settings).encode('utf-8')))) f.close() self.preference_manager.read_file() self.manager.load_local_settings(kgk_manager) data = b64decode(self.manager.get_export_data(kgk_manager)) self.assertEqual(b'\x01', data[:1]) salt = data[1:33] kgk_crypter = Crypter(Crypter.createIvKey(b'xyz', salt, iterations=3)) kgk_manager2 = KgkManager() kgk_manager2.set_preference_manager(self.preference_manager) kgk_manager2.decrypt_kgk(data[33:145], kgk_crypter) settings_crypter = PasswordSettingsManager.get_settings_crypter( kgk_manager2) self.assertEqual( settings['settings'], json.loads( str(Packer.decompress(settings_crypter.decrypt(data[145:])), encoding='utf-8')))
def load_local_settings(self, kgk_manager): """ This loads the saved settings. It is a good idea to call this method the minute you have a kgk manager. :param kgk_manager: kgk manager :type kgk_manager: KgkManager """ encrypted_settings = self.preference_manager.get_settings_data() if len(encrypted_settings) < 40: return settings_crypter = PasswordSettingsManager.get_settings_crypter( kgk_manager) decrypted_settings = settings_crypter.decrypt(encrypted_settings) sync_settings_len = struct.unpack('!I', decrypted_settings[0:4])[0] if sync_settings_len > 0: self.sync_manager.load_binary_sync_settings( decrypted_settings[4:4 + sync_settings_len]) if len(decrypted_settings) < sync_settings_len + 44: raise ValueError("The decrypted settings are too short.") decompressed_settings = Packer.decompress( decrypted_settings[4 + sync_settings_len:]) if len(decompressed_settings) <= 0: raise PermissionError( "Wrong password: The settings could not decompress.") saved_settings = json.loads( str(decompressed_settings, encoding='utf-8')) for domain_name in saved_settings['settings'].keys(): data_set = saved_settings['settings'][domain_name] found = False i = 0 while i < len(self.settings): setting = self.settings[i] if setting.get_domain() == domain_name: found = True if datetime.strptime( data_set['mDate'], "%Y-%m-%dT%H:%M:%S") > setting.get_m_date(): setting.load_from_dict(data_set) setting.set_synced( setting.get_domain() in saved_settings['synced']) i += 1 if not found: new_setting = PasswordSetting(domain_name) new_setting.load_from_dict(data_set) new_setting.set_synced( new_setting.get_domain() in saved_settings['synced']) self.settings.append(new_setting)
def load_binary_sync_settings(self, data): """ loads sync settings :param bytes data: packed json data of sync settings """ settings_dict = json.loads( str(Packer.decompress(data), encoding='utf-8')) if "server-address" in settings_dict and \ "username" in settings_dict and \ "password" in settings_dict: self.server_address = settings_dict["server-address"] self.username = settings_dict["username"] self.password = settings_dict["password"] self.certificate = None if "certificate" in settings_dict: self.certificate = settings_dict["certificate"] if len( settings_dict["certificate"]) > 0 else None self.create_certificate_file_if_needed() self.create_sync()
def load_binary_sync_settings(self, data): """ loads sync settings :param bytes data: packed json data of sync settings """ settings_dict = json.loads(str(Packer.decompress(data), encoding='utf-8')) if "server-address" in settings_dict and \ "username" in settings_dict and \ "password" in settings_dict and \ "certificate" in settings_dict: self.server_address = settings_dict["server-address"] self.username = settings_dict["username"] self.password = settings_dict["password"] self.certificate = settings_dict["certificate"] if self.certificate_file: self.certificate_file.close() self.certificate_file = NamedTemporaryFile() self.certificate_file.write(self.certificate.encode('utf-8')) self.certificate_file.seek(0) self.create_sync()
def load_local_settings(self, kgk_manager): """ This loads the saved settings. It is a good idea to call this method the minute you have a kgk manager. :param kgk_manager: kgk manager :type kgk_manager: KgkManager """ encrypted_settings = self.preference_manager.get_settings_data() if len(encrypted_settings) < 40: return settings_crypter = PasswordSettingsManager.get_settings_crypter(kgk_manager) decrypted_settings = settings_crypter.decrypt(encrypted_settings) sync_settings_len = struct.unpack('!I', decrypted_settings[0:4])[0] if sync_settings_len > 0: self.sync_manager.load_binary_sync_settings(decrypted_settings[4:4+sync_settings_len]) if len(decrypted_settings) < sync_settings_len+44: raise ValueError("The decrypted settings are too short.") decompressed_settings = Packer.decompress(decrypted_settings[4+sync_settings_len:]) if len(decompressed_settings) <= 0: raise PermissionError("Wrong password: The settings could not decompress.") saved_settings = json.loads(str(decompressed_settings, encoding='utf-8')) for domain_name in saved_settings['settings'].keys(): data_set = saved_settings['settings'][domain_name] found = False i = 0 while i < len(self.settings): setting = self.settings[i] if setting.get_domain() == domain_name: found = True if datetime.strptime(data_set['mDate'], "%Y-%m-%dT%H:%M:%S") > setting.get_m_date(): setting.load_from_dict(data_set) setting.set_synced(setting.get_domain() in saved_settings['synced']) i += 1 if not found: new_setting = PasswordSetting(domain_name) new_setting.load_from_dict(data_set) new_setting.set_synced(new_setting.get_domain() in saved_settings['synced']) self.settings.append(new_setting)
def update_from_export_data(self, kgk_manager, blob): """ Call this method to pull settings from the sync server. :param kgk_manager: the kgk manager used for the decryption :type kgk_manager: KgkManager :param blob: the export data :type blob: bytes """ if not blob[0] == 1: print( "Version error: Wrong data format. Could not import anything.") return True settings_crypter = self.get_settings_crypter(kgk_manager) decrypted_settings = settings_crypter.decrypt(blob[145:]) if len(decrypted_settings) <= 0: print("Wrong password.") return False self.remote_data = json.loads( str(Packer.decompress(decrypted_settings), encoding='utf-8')) self.update_remote = False for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] found = False i = 0 while i < len(self.settings): setting = self.settings[i] if setting.get_domain() == domain_name: found = True if 'mDate' in data_set: last_modification_date = data_set['mDate'] else: last_modification_date = data_set['cDate'] if PasswordSetting.convert_ISO_date( last_modification_date) > setting.get_m_date(): if 'deleted' in data_set and data_set['deleted']: self.settings.pop(i) else: setting.load_from_dict(data_set) setting.set_synced(True) self.update_remote = True i += 1 else: i += 1 else: i += 1 if not found: new_setting = PasswordSetting(domain_name) new_setting.load_from_dict(data_set) new_setting.set_synced(True) self.settings.append(new_setting) for setting in self.settings: found = False for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] if setting.get_domain() == domain_name: found = True if 'mDate' in data_set: last_modification_date = data_set['mDate'] else: last_modification_date = data_set['cDate'] if setting.get_m_date( ) >= PasswordSetting.convert_ISO_date( last_modification_date): self.update_remote = True if not found: self.update_remote = True self.store_local_settings(kgk_manager) return self.update_remote
def test_decompress(self): self.assertEqual( b'Some packable information', Packer.decompress( b64decode( "AAAAGXjaC87PTVUoSEzOTkzKSVXIzEvLL8pNLMnMzwMAedUJrg==")))
def test_decompress(self): self.assertEqual( b'Some packable information', Packer.decompress(b64decode("AAAAGXjaC87PTVUoSEzOTkzKSVXIzEvLL8pNLMnMzwMAedUJrg==")))