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 get_export_data(self, kgk_manager): """ This gives you a base64 encoded string of encrypted settings data (the blob). :param kgk_manager: kgk manager :type kgk_manager: KgkManager :return: encrypted settings blob :rtype: str """ kgk_block = kgk_manager.get_fresh_encrypted_kgk() settings_list = self.get_settings_as_dict()['settings'] if self.remote_data: for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] if 'deleted' in data_set and data_set['deleted']: for i, setting_dict in enumerate(settings_list): if setting_dict['domain'] == setting_dict['domain'] and \ PasswordSetting.convert_ISO_date(data_set['mDate']) > \ PasswordSetting.convert_ISO_date(setting_dict['mDate']): settings_list[i] = data_set if domain_name not in settings_list.keys(): settings_list[domain_name] = { 'mDate': datetime.now(), 'deleted': True } settings_crypter = self.get_settings_crypter(kgk_manager) return b64encode(b'\x01' + kgk_manager.get_kgk_crypter_salt() + kgk_block + settings_crypter.encrypt( Packer.compress(json.dumps(settings_list))))
def test_custom_character_set(self): setting = PasswordSetting('some.domain') setting.set_salt('pepper'.encode('utf-8')) setting.set_extra_character_set( 'abcdefghijklmnopqrstuvwxyzABCDUFGHJKLMNPQRTEVWXYZ0123456789#!"§$%&/()[]{}=-_+*<>;:.') setting.set_template("oxxxxxxxxx") manager = CtSesam(domain=setting.get_domain(), username=setting.get_username(), kgk='foo'.encode('utf-8')) self.assertEqual("5#%KiEvUU7", manager.generate(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 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_template(self): s = PasswordSetting("unit.test") s.set_template("xxxaxxxxxxx") self.assertEqual("xxxaxxxxxxx", s.get_template()) s.set_template("6;xxxxxxoxxxnAxxxa") self.assertEqual("xxxxxxoxxxnAxxxa", s.get_template()) self.assertEqual(16, len(s.get_template()))
def test_get_character_set(self): s = PasswordSetting("unit.test") self.assertEqual("c", s.get_character_set()[12]) s.set_extra_character_set("axFLp0") s.set_template("xox") self.assertEqual(6, len(s.get_character_set())) self.assertEqual("F", s.get_character_set()[2]) self.assertEqual("0", s.get_character_set()[5])
def test_custom_character_set(self): setting = PasswordSetting("some.domain") setting.set_salt("pepper".encode("utf-8")) setting.set_extra_character_set( 'abcdefghijklmnopqrstuvwxyzABCDUFGHJKLMNPQRTEVWXYZ0123456789#!"§$%&/()[]{}=-_+*<>;:.' ) setting.set_template("oxxxxxxxxx") manager = CtSesam(domain=setting.get_domain(), username=setting.get_username(), kgk="foo".encode("utf-8")) self.assertEqual("5#%KiEvUU7", manager.generate(setting))
def test_change_length(self): s = PasswordSetting("unit.test") s.set_full_template("1;xxxaxxxxxxx") self.assertEqual(11, s.get_length()) s.set_length(16) self.assertEqual(16, s.get_length()) self.assertEqual(16, len(s.get_template()))
def test_default(self): setting = PasswordSetting('some.domain') setting.set_salt('pepper'.encode('utf-8')) setting.set_template("xaxnxxAoxx") manager = CtSesam(domain=setting.get_domain(), username=setting.get_username(), kgk='foo'.encode('utf-8')) self.assertEqual("]ew26XW.X<", manager.generate(setting))
def test_custom_salt(self): setting = PasswordSetting('some.domain') setting.set_salt(b'qanisaoerna56745678eornsiarteonstiaroenstiaeroh') setting.set_template("oxAxxaxxnx") manager = CtSesam(domain=setting.get_domain(), username=setting.get_username(), kgk='foo'.encode('utf-8')) self.assertEqual(")hN8ol<;6<", manager.generate(setting))
def test_long(self): setting = PasswordSetting('some.domain') setting.set_salt('pepper'.encode('utf-8')) setting.set_template("Aanoxxxxxxxxxxxxxxxxxxxxxxxxxxxx") manager = CtSesam(domain=setting.get_domain(), username=setting.get_username(), kgk='foo'.encode('utf-8')) self.assertEqual("Ba0=}#K.X<$/eS0AuGjRm>(\"dnDnvZCx", manager.generate(setting))
def test_custom_character_set(self): setting = PasswordSetting('some.domain') setting.set_salt('pepper'.encode('utf-8')) setting.set_custom_character_set( 'abcdefghijklmnopqrstuvwxyzABCDUFGHJKLMNPQRTEVWXYZ0123456789#!"§$%&/()[]{}=-_+*<>;:.') manager = CtSesam(domain=setting.get_domain(), username=setting.get_username(), kgk='foo'.encode('utf-8')) self.assertEqual("5#%KiEvUU7", manager.generate(setting))
def test_salt(self): s = PasswordSetting("unit.test") self.assertEqual(32, len(s.get_salt())) s.set_salt("somethingelse".encode('utf-8')) expected = "somethingelse".encode('utf-8') self.assertEqual(len(expected), len(s.get_salt())) for i in range(len(expected)): self.assertEqual(expected[i], s.get_salt()[i])
def test_get_character_set(self): s = PasswordSetting("unit.test") self.assertEqual("c", s.get_character_set()[2]) s.set_custom_character_set("axFLp0") self.assertEqual(6, len(s.get_character_set())) self.assertEqual("F", s.get_character_set()[2]) self.assertEqual("0", s.get_character_set()[5])
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 PasswordSetting.create_ISO_date( data_set['mDate']) > 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 get_setting(self, domain): """ This function always returns a setting. If no setting was stored for the given domain a new PasswordSetting object is created. :param domain: The "domain" is the identifier of a settings object. :type domain: str :return: a setting object :rtype: PasswordSetting """ for setting in self.settings: if setting.get_domain() == domain: return setting setting = PasswordSetting(domain) self.settings.append(setting) return setting
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 test_username(self): s = PasswordSetting("unit.test") self.assertEqual("", s.get_username()) s.set_username("Hugo") self.assertEqual("Hugo", s.get_username())
def test_simple_password_3_tpl(self): setting = PasswordSetting('FooBar') setting.set_iterations(8192) setting.set_template("xxAxxx") setting.set_salt('blahfasel'.encode('utf-8')) kgk = 'test'.encode('utf-8') manager = CtSesam(domain=setting.get_domain(), username=setting.get_username(), kgk=kgk, salt=setting.get_salt(), iterations=setting.get_iterations()) self.assertEqual( unhexlify( "309d504d68dc921dcece9d10c14b406673715f15782032d64229b4b42336c8ec860cd9b9451048" + "24ce43720b3a088828843df4029fdb8b2314f8b5129c815949"), manager.hash_value) self.assertEqual("BAELOH", manager.generate(setting))
def test_notes(self): s = PasswordSetting("unit.test") self.assertEqual("", s.get_notes()) s.set_notes("Beware of the password!") self.assertEqual("Beware of the password!", s.get_notes())
def test_simple_password_4_tpl(self): setting = PasswordSetting('FooBar') setting.set_iterations(8192) setting.set_extra_character_set("0123456789abcdef") setting.set_template("xxxxxxxxxxxxxxxxxxxxxxxoxxxx") setting.set_salt('SALT'.encode('utf-8')) kgk = 'MY_T0P_5ecr57_PA55W0RD ;-)'.encode('utf-8') manager = CtSesam(domain=setting.get_domain(), username=setting.get_username(), kgk=kgk, salt=setting.get_salt(), iterations=setting.get_iterations()) self.assertEqual( unhexlify( "4993fd21600977c6f56b833eed223dda9b1bd34294afd1db4925553099cce402abda7000a22d2c" + "fda152afcf8a3a142e55ce57a9597434a39d05ccd93a853626"), manager.hash_value) self.assertEqual("626358a39dcc50d93a4347959a75", manager.generate(setting))
def test_character_set(self): s = PasswordSetting("unit.test") self.assertEqual("0123456789" + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "#!\"§$%&/()[]{}=-_+*<>;:.", s.get_character_set()) s.set_extra_character_set("&=Oo0wWsS$#uUvVzZ") s.set_template("oxxxxxxxxx") self.assertEqual("&=Oo0wWsS$#uUvVzZ", s.get_character_set()) s.set_extra_character_set( "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "#!\"§$%&/()[]{}=-_+*<>;:.") self.assertEqual("abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "#!\"§$%&/()[]{}=-_+*<>;:.", s.get_character_set()) s.set_template("noxxxxxxxx") s.set_extra_character_set("#!\"§$%&/()[]{}=-_+*<>;:.") self.assertEqual("0123456789#!\"§$%&/()[]{}=-_+*<>;:.", s.get_character_set()) s.set_template("xaxxxAxxx") self.assertEqual("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", s.get_character_set())
def test_simple_password_1(self): setting = PasswordSetting('ct.de') setting.set_extra_character_set( "abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRTUVWXYZ0123456789" + "#!\"§$%&/()[]{}=-_+*<>;:.") setting.set_iterations(4096) setting.set_template("oxxxxxxxxx") setting.set_salt('pepper'.encode('utf-8')) kgk = 'test'.encode('utf-8') manager = CtSesam(domain=setting.get_domain(), username=setting.get_username(), kgk=kgk, salt=setting.get_salt(), iterations=setting.get_iterations()) self.assertEqual( unhexlify( "f4d54b303b21ee3d8bff9c1eae6f66d90db58c0a5cc770eee322cc59d4dec65793bf8f5dec" + "717fd1404bbfacf59befa68c4ad9168bfeaa6a9e28b326a76a82bb"), manager.hash_value) self.assertEqual("YBVUH=sN/3", manager.generate(setting))
def test_simple_password_1_tpl(self): setting = PasswordSetting('FooBar') setting.set_extra_character_set("#!\"$%&/()[]{}=-_+*<>;:.") setting.set_iterations(4096) setting.set_template("xxoxAxxxxxxxxxaxx") setting.set_salt('blahfasel'.encode('utf-8')) kgk = 'test'.encode('utf-8') manager = CtSesam(domain=setting.get_domain(), username=setting.get_username(), kgk=kgk, salt=setting.get_salt(), iterations=setting.get_iterations()) self.assertEqual( unhexlify( "4e9e2503556bda7ad06cf45cab4490213becd3473845a868900fb61fa17d1c448496d11987c4" + "446d8007562029cce7f176eda4157604012a44e42add594a524e"), manager.hash_value) self.assertEqual("pU)VUfgJ-Ws*wgzzE", manager.generate(setting))
def test_default(self): setting = PasswordSetting('some.domain') setting.set_salt('pepper'.encode('utf-8')) manager = CtSesam(domain=setting.get_domain(), username=setting.get_username(), kgk='foo'.encode('utf-8')) self.assertEqual("]#]Y6Q-+)T", manager.generate(setting))
def test_custom_salt(self): setting = PasswordSetting('some.domain') setting.set_salt(b'qanisaoerna56745678eornsiarteonstiaroenstiaeroh') manager = CtSesam(domain=setting.get_domain(), username=setting.get_username(), kgk='foo'.encode('utf-8')) self.assertEqual("]#]Y6Q-+)T", manager.generate(setting))
def test_set_use_lower_case(self): s = PasswordSetting("unit.test") s.set_custom_character_set("Eabc2") s.set_use_lower_case(False) self.assertEqual("E2", s.get_character_set()) s.set_custom_character_set("Eabc2") s.set_use_lower_case(True) self.assertEqual("abcdefghijklmnopqrstuvwxyzE2", s.get_character_set())
def test_set_use_digits(self): s = PasswordSetting("unit.test") s.set_custom_character_set("abE;c2") s.set_use_digits(False) self.assertEqual("abcE;", s.get_character_set()) s.set_custom_character_set("aL;^bc2") s.set_use_digits(True) self.assertEqual("abcL0123456789;^", s.get_character_set())
def test_load_from_json(self): json_str = "{\"domain\": \"unit.test\", \"username\": \"testilinius\", " +\ "\"notes\": \"interesting note\", \"legacyPassword\": \"rtSr?bS,mi\", " +\ "\"usedCharacters\": \"AEIOUaeiou\", \"iterations\": 5341, " +\ "\"length\": 16, \"salt\": \"ZmFzY2luYXRpbmc=\", " +\ "\"cDate\": \"2001-01-01T02:14:12\", \"mDate\": \"2005-01-01T01:14:12\"}" s = PasswordSetting(json.loads(json_str)["domain"]) s.load_from_dict(json.loads(json_str)) self.assertEquals("unit.test", s.get_domain()) self.assertEquals("testilinius", s.get_username()) self.assertEquals("interesting note", s.get_notes()) self.assertEquals("rtSr?bS,mi", s.get_legacy_password()) self.assertFalse(s.use_lower_case()) self.assertFalse(s.use_upper_case()) self.assertFalse(s.use_digits()) self.assertFalse(s.use_extra()) self.assertTrue(s.use_custom_character_set()) self.assertEquals("AEIOUaeiou", s.get_character_set()) self.assertEquals(5341, s.get_iterations()) self.assertEquals(16, s.get_length()) expected_salt = "fascinating".encode('utf-8') self.assertEqual(len(expected_salt), len(s.get_salt())) for i in range(len(expected_salt)): self.assertEqual(expected_salt[i], s.get_salt()[i]) self.assertEquals("2001-01-01T02:14:12", s.get_creation_date()) self.assertEquals("2005-01-01T01:14:12", s.get_modification_date())
def test_long(self): setting = PasswordSetting("some.domain") setting.set_salt("pepper".encode("utf-8")) setting.set_template("Aanoxxxxxxxxxxxxxxxxxxxxxxxxxxxx") manager = CtSesam(domain=setting.get_domain(), username=setting.get_username(), kgk="foo".encode("utf-8")) self.assertEqual('Ba0=}#K.X<$/eS0AuGjRm>("dnDnvZCx', manager.generate(setting))
def test_character_set(self): s = PasswordSetting("unit.test") self.assertFalse(s.use_custom_character_set()) self.assertEqual("abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "#!\"§$%&/()[]{}=-_+*<>;:.", s.get_character_set()) s.set_custom_character_set("&=Oo0wWsS$#uUvVzZ") self.assertTrue(s.use_custom_character_set()) self.assertEqual("&=Oo0wWsS$#uUvVzZ", s.get_character_set()) s.set_custom_character_set( "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "#!\"§$%&/()[]{}=-_+*<>;:.") self.assertFalse(s.use_custom_character_set()) self.assertEqual("abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "#!\"§$%&/()[]{}=-_+*<>;:.", s.get_character_set()) s.set_use_letters(False) self.assertEqual("0123456789#!\"§$%&/()[]{}=-_+*<>;:.", s.get_character_set()) s.set_use_letters(True) s.set_use_digits(False) s.set_use_extra(False) self.assertEqual("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", s.get_character_set())
def test_load_from_json(self): json_str = "{\"domain\": \"unit.test\", \"username\": \"testilinius\", " +\ "\"notes\": \"interesting note\", \"legacyPassword\": \"rtSr?bS,mi\", " +\ "\"extras\": \"AEIOUaeiou\", \"iterations\": 5341, " +\ "\"passwordTemplate\": \"7;xxxxoxxxxxxxxxxx\", \"salt\": \"ZmFzY2luYXRpbmc=\", " +\ "\"cDate\": \"2001-01-01T02:14:12.000\", \"mDate\": \"2005-01-01T01:14:12.000\"}" s = PasswordSetting(json.loads(json_str)["domain"]) s.load_from_dict(json.loads(json_str)) self.assertEqual("unit.test", s.get_domain()) self.assertEqual("testilinius", s.get_username()) self.assertEqual("interesting note", s.get_notes()) self.assertEqual("rtSr?bS,mi", s.get_legacy_password()) self.assertEqual("AEIOUaeiou", s.get_character_set()) self.assertEqual(5341, s.get_iterations()) self.assertEqual("xxxxoxxxxxxxxxxx", s.get_template()) expected_salt = "fascinating".encode('utf-8') self.assertEqual(len(expected_salt), len(s.get_salt())) for i in range(len(expected_salt)): self.assertEqual(expected_salt[i], s.get_salt()[i]) self.assertEqual("2001-01-01T02:14:12.000", s.get_creation_date()) self.assertEqual("2005-01-01T01:14:12.000", s.get_modification_date())
def test_custom_salt(self): setting = PasswordSetting("some.domain") setting.set_salt(b"qanisaoerna56745678eornsiarteonstiaroenstiaeroh") setting.set_template("oxAxxaxxnx") manager = CtSesam(domain=setting.get_domain(), username=setting.get_username(), kgk="foo".encode("utf-8")) self.assertEqual(")hN8ol<;6<", manager.generate(setting))
def test_legacy_password(self): s = PasswordSetting("unit.test") self.assertEqual("", s.get_legacy_password()) s.set_legacy_password("K6x/vyG9(p") self.assertEqual("K6x/vyG9(p", s.get_legacy_password())
def test_default(self): setting = PasswordSetting("some.domain") setting.set_salt("pepper".encode("utf-8")) setting.set_template("xaxnxxAoxx") manager = CtSesam(domain=setting.get_domain(), username=setting.get_username(), kgk="foo".encode("utf-8")) self.assertEqual("]ew26XW.X<", manager.generate(setting))
def test_pin(self): setting = PasswordSetting('Bank') setting.set_iterations(1) setting.set_extra_character_set("0123456789") setting.set_template("oxxx") setting.set_salt('pepper'.encode('utf-8')) kgk = 'reallysafe'.encode('utf-8') manager = CtSesam(domain=setting.get_domain(), username=setting.get_username(), kgk=kgk, salt=setting.get_salt(), iterations=setting.get_iterations()) self.assertEqual( unhexlify( "55b5f5cdd9bf2845e339650b4f6e1398cf7fe9ceed087eb5f5bc059882723579fc8ec27443417" + "cf33c9763bafac6277fbe991bf27dd0206e78f7d9dfd574167f"), manager.hash_value) self.assertEqual("7809", manager.generate(setting))
def test_set_modification_date(self): s = PasswordSetting("unit.test") s.set_creation_date("2007-01-01T02:14:12") s.set_modification_date("2005-01-01T01:14:12") self.assertEqual("2005-01-01T01:14:12", s.get_creation_date()) self.assertEqual("2005-01-01T01:14:12", s.get_modification_date())
def test_set_modification_date(self): s = PasswordSetting("unit.test") s.set_creation_date("2007-01-01T02:14:12") s.set_modification_date("2005-01-01T01:14:12") self.assertEqual("2005-01-01T01:14:12.000", s.get_creation_date()) self.assertEqual("2005-01-01T01:14:12.000", s.get_modification_date())
def test_to_json(self): s = PasswordSetting("unit.test") s.set_modification_date("2005-01-01T01:14:12") s.set_creation_date("2001-01-01T02:14:12") s.set_salt("something".encode('utf-8')) s.set_iterations(213) s.set_template("xxxxxxxxxxoxxx") s.set_extra_character_set("XVLCWKHGFQUIAEOSNRTDYÜÖÄPZBMJ") s.set_notes("Some note.") self.assertIn("domain", s.to_dict()) self.assertEqual("unit.test", s.to_dict()["domain"]) self.assertIn("cDate", s.to_dict()) self.assertEqual("2001-01-01T02:14:12.000", s.to_dict()["cDate"]) self.assertIn("mDate", s.to_dict()) self.assertEqual("2005-01-01T01:14:12.000", s.to_dict()["mDate"]) self.assertIn("salt", s.to_dict()) self.assertEqual(str(b64encode("something".encode('utf-8')), encoding='utf-8'), s.to_dict()["salt"]) self.assertIn("iterations", s.to_dict()) self.assertEqual(213, s.to_dict()["iterations"]) self.assertIn("passwordTemplate", s.to_dict()) self.assertEqual("xxxxxxxxxxoxxx", s.to_dict()["passwordTemplate"]) self.assertIn("extras", s.to_dict()) self.assertEqual("XVLCWKHGFQUIAEOSNRTDYÜÖÄPZBMJ", s.to_dict()["extras"]) self.assertIn("notes", s.to_dict()) self.assertEqual("Some note.", s.to_dict()["notes"])
def test_to_json(self): s = PasswordSetting("unit.test") s.set_modification_date("2005-01-01T01:14:12") s.set_creation_date("2001-01-01T02:14:12") s.set_salt("something".encode('utf-8')) s.set_iterations(213) s.set_length(14) s.set_custom_character_set("XVLCWKHGFQUIAEOSNRTDYÜÖÄPZBMJ") s.set_notes("Some note.") self.assertIn("domain", s.to_dict()) self.assertEqual("unit.test", s.to_dict()["domain"]) self.assertIn("cDate", s.to_dict()) self.assertEqual("2001-01-01T02:14:12", s.to_dict()["cDate"]) self.assertIn("mDate", s.to_dict()) self.assertEqual("2005-01-01T01:14:12", s.to_dict()["mDate"]) self.assertIn("salt", s.to_dict()) self.assertEqual(str(b64encode("something".encode('utf-8')), encoding='utf-8'), s.to_dict()["salt"]) self.assertIn("iterations", s.to_dict()) self.assertEqual(213, s.to_dict()["iterations"]) self.assertIn("length", s.to_dict()) self.assertEqual(14, s.to_dict()["length"]) self.assertIn("usedCharacters", s.to_dict()) self.assertEqual("XVLCWKHGFQUIAEOSNRTDYÜÖÄPZBMJ", s.to_dict()["usedCharacters"]) self.assertIn("notes", s.to_dict()) self.assertEqual("Some note.", s.to_dict()["notes"])
def test_set_use_upper_case(self): s = PasswordSetting("unit.test") s.set_custom_character_set("Eab2c3") s.set_use_upper_case(False) self.assertEqual("abc23", s.get_character_set()) s.set_custom_character_set("Eab2c3") s.set_use_upper_case(True) self.assertEqual("abcABCDEFGHIJKLMNOPQRSTUVWXYZ23", s.get_character_set())
def test_long(self): setting = PasswordSetting('some.domain') setting.set_salt('pepper'.encode('utf-8')) setting.set_length(32) manager = CtSesam(domain=setting.get_domain(), username=setting.get_username(), kgk='foo'.encode('utf-8')) self.assertEqual("]#]Y6Q-+)TCus§&8[kEw5O.pJsTjOC#}", manager.generate(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_set_use_extra(self): s = PasswordSetting("unit.test") s.set_custom_character_set("Eab;^2c3") s.set_use_extra(False) self.assertEqual("abcE23", s.get_character_set()) s.set_custom_character_set("Eab;^2c3") s.set_use_extra(True) self.assertEqual("abcE23#!\"§$%&/()[]{}=-_+*<>;:.^", s.get_character_set())
def test_simple_password_2(self): setting = PasswordSetting('MyFavoriteDomain') setting.set_extra_character_set( "abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRTUVWXYZ") setting.set_iterations(8192) setting.set_template("oxxxxxxxxxxxxxxx") setting.set_salt('pepper'.encode('utf-8')) kgk = 'foobar'.encode('utf-8') manager = CtSesam(domain=setting.get_domain(), username=setting.get_username(), kgk=kgk, salt=setting.get_salt(), iterations=setting.get_iterations()) self.assertEqual( unhexlify( "cb0ae7b2b7fc969770a9bfc1eef3a9afd02d2b28d6d8e9cb324f41a31392a0f800ea7e2e43" + "e847537ceb863a16a869d5e4dd6822cf3be0206440eff97dc2001c"), manager.hash_value) self.assertEqual("wLUwoQvKzBaYXbme", manager.generate(setting))