def test_create_identity_id_list(self): """Test identity ID list request creation""" id1 = dandelion.identity.generate() id2 = dandelion.identity.generate() id3 = dandelion.identity.generate() tc = b'\x01\x03\x03\x07' tc_str_ok = encode_b64_bytes(tc).decode() str_ = dandelion.protocol.create_identity_id_list(tc, [id1, id2, id3])[:-1] tc_str, id1_str, id2_str, id3_str = str_.split(';') self.assertEqual(tc_str, tc_str_ok) self.assertEqual(id1.fingerprint, decode_b64_bytes(id1_str.encode())) self.assertEqual(id2.fingerprint, decode_b64_bytes(id2_str.encode())) self.assertEqual(id3.fingerprint, decode_b64_bytes(id3_str.encode())) str_ = dandelion.protocol.create_identity_id_list(tc, None)[:-1] self.assertEqual(str_, tc_str) str_ = dandelion.protocol.create_identity_id_list(tc, [])[:-1] self.assertEqual(str_, tc_str) """Testing bad input""" self.assertRaises(TypeError, dandelion.protocol.create_identity_id_list, 1337, None) self.assertRaises(TypeError, dandelion.protocol.create_identity_id_list, tc, id1) self.assertRaises(TypeError, dandelion.protocol.create_identity_id_list, [id1], tc) self.assertRaises(AttributeError, dandelion.protocol.create_identity_id_list, tc, tc) self.assertRaises(ValueError, dandelion.protocol.create_identity_id_list, None, []) self.assertRaises(TypeError, dandelion.protocol.create_identity_id_list, 0, None) self.assertRaises(AttributeError, dandelion.protocol.create_identity_id_list, tc, ['fo'])
def parse_identity_id_list(identitystr): """Parse the identity ID response string from the server. Returns a (tc, [identityid]) tuple. Raises a ProtocolParseError if the string can't be parsed. """ _assert_type(identitystr, str) match = re.search(''.join([r'^', r'([a-zA-Z0-9+/=]+)', r'(;[a-zA-Z0-9+/=]+)*', TERMINATOR, r'$']), identitystr) if not match: raise ProtocolParseError tc = match.groups()[0] if tc is None: raise ProtocolParseError return (decode_b64_bytes(tc.encode()), [decode_b64_bytes(identityid.encode()) for identityid in identitystr[:-len(TERMINATOR)].split(_FIELD_SEPARATOR)[1:]])
def test_create_message_id_list(self): """Test message ID list request creation""" id1 = dandelion.identity.generate() id2 = dandelion.identity.generate() ts = 1337 msg1 = dandelion.message.create('M1', ts, id1, id2) msg2 = Message('M2') msg3 = Message('M3') tc = b'\x01\x03\x03\x07' tc_str_ok = encode_b64_bytes(tc).decode() str_ = dandelion.protocol.create_message_id_list(tc, [msg1, msg2, msg3])[:-1] tc_str, m1_str, m2_str, m3_str = str_.split(';') self.assertEqual(tc_str, tc_str_ok) self.assertEqual(msg1.id, decode_b64_bytes(m1_str.encode())) self.assertEqual(msg2.id, decode_b64_bytes(m2_str.encode())) self.assertEqual(msg3.id, decode_b64_bytes(m3_str.encode())) str_ = dandelion.protocol.create_message_id_list(tc, None)[:-1] self.assertEqual(str_, tc_str) str_ = dandelion.protocol.create_message_id_list(tc, [])[:-1] self.assertEqual(str_, tc_str) """Testing bad input""" self.assertRaises(TypeError, dandelion.protocol.create_message_id_list, 1337, None) self.assertRaises(TypeError, dandelion.protocol.create_message_id_list, tc, msg1) self.assertRaises(TypeError, dandelion.protocol.create_message_id_list, [msg1], tc) self.assertRaises(AttributeError, dandelion.protocol.create_message_id_list, tc, tc) self.assertRaises(ValueError, dandelion.protocol.create_message_id_list, None, []) self.assertRaises(TypeError, dandelion.protocol.create_message_id_list, 0, None) self.assertRaises(AttributeError, dandelion.protocol.create_message_id_list, tc, ['fo'])
def __init__(self, config_file='dandelion.conf'): self._cfg_file_name = config_file self._server_config = ServerConfig() self._synchronizer_config = SynchronizerConfig() self._discoverer_config = DiscovererConfig() self._id_manager_config = IdentityConfig() self._ui_config = UiConfig() self.read_file() self._content_db = ContentDB(self._server_config.db_file) if self._id_manager_config.my_id is not None and not self._content_db.contains_identity(decode_b64_bytes(self._id_manager_config.my_id.encode())) : print("WARNING! Bad or non existing ID requested in config. Requested:", self._id_manager_config.my_id) self._id_manager_config.my_id = None if self._id_manager_config.my_id is not None: fp = decode_b64_bytes(self._id_manager_config.my_id.encode()) try: self._identity = self._content_db.get_private_identity(fp) print("My claimed ID:", self._id_manager_config.my_id) return except ValueError: pass self._identity = dandelion.identity.generate() self._content_db.add_private_identity(self._identity) id_str = encode_b64_bytes(self._identity.fingerprint).decode() self._id_manager_config.my_id = id_str
def parse_identity_id_list_request(identitystr): """Parse the identity id request string. If a time cookie is present in the string it will be returned as a bytes type. If not, None will be returned. Raises a ProtocolParseError if the string can't be parsed. """ _assert_type(identitystr, str) if not is_identity_id_list_request(identitystr): raise ProtocolParseError match = re.search(''.join([r'^', _GETIDENTITYLIST, r'( ([a-zA-Z0-9+/=]+))?', TERMINATOR, r'$']), identitystr) if not match: raise ProtocolParseError if match.groups()[0] is None: return None return decode_b64_bytes(match.groups()[1].encode())
def _string2message(mstr): """Parse the string and create a message""" TEXT_INDEX, TIMESTAMP_INDEX, RECEIVER_INDEX, SENDER_INDEX, SIGNATURE_INDEX = (0, 1, 2, 3, 4) mparts = mstr.split(_SUB_FIELD_SEPARATOR) if len(mparts) != 5: raise ProtocolParseError if (mparts[SENDER_INDEX] != '' and mparts[SIGNATURE_INDEX] == '') or (mparts[SENDER_INDEX] == '' and mparts[SIGNATURE_INDEX] != ''): raise ProtocolParseError receiver = None if mparts[RECEIVER_INDEX] == '' else decode_b64_bytes(mparts[RECEIVER_INDEX].encode()) text = decode_b64_bytes(mparts[TEXT_INDEX].encode()) timestamp = None if mparts[TIMESTAMP_INDEX] == '' else decode_b64_int(mparts[TIMESTAMP_INDEX].encode()) textstr = text.decode() if receiver is None else text # Decode unless encrypted sender = None if mparts[SENDER_INDEX] == '' else decode_b64_bytes(mparts[SENDER_INDEX].encode()) signature = None if mparts[SIGNATURE_INDEX] == '' else decode_b64_bytes(mparts[SIGNATURE_INDEX].encode()) return Message(textstr, timestamp, receiver, sender, signature)
def test_decode_bytes(self): self.assertEqual(decode_b64_bytes(b''), b'') self.assertEqual(decode_b64_bytes(b'AAAA'), b'\x00\x00\x00') self.assertEqual(decode_b64_bytes(b'////'), b'\xFF\xFF\xFF') self.assertEqual(decode_b64_bytes(b'MTIz'), b'123') self.assertEqual(decode_b64_bytes(bytearray(b'MTIz')), b'123') self.assertEqual(decode_b64_bytes(b'MTMzNw=='), b'1337') self.assertRaises(TypeError, decode_b64_bytes, None) self.assertRaises(TypeError, decode_b64_bytes, '1337') self.assertRaises(TypeError, decode_b64_bytes, 1337)
def parse_identity_list_request(identitystr): """Parse the identity request string from the client Raises a ProtocolParseError if the string can't be parsed. """ if not is_identity_list_request(identitystr): raise ProtocolParseError match = re.search(r''.join([r'^', _GETIDENTITIES, r'( [a-zA-Z0-9+/=]+)?', r'(;[a-zA-Z0-9+/=]+)*', TERMINATOR, r'$']), identitystr) if not match: raise ProtocolParseError if not match.groups()[0]: return None id_strings = identitystr[len(_GETIDENTITIES) + 1:-len(TERMINATOR)].split(_FIELD_SEPARATOR) return [decode_b64_bytes(id.encode()) for id in id_strings]
def parse_greeting_message(msgstr): """Parse the greeting message string. Returns the data base id (bytes) or raises a ProtocolParseError if the string can't be parsed. If the message is a valid greeting but announces a version that is incompatible with the current protocol version, a ProtocolVersionError is raised. """ _assert_type(msgstr, str) match = re.search( ''.join([r'^', _PROTOCOL_COOKIE, _FIELD_SEPARATOR, r'([0-9]+\.[0-9]+)', _FIELD_SEPARATOR, r'([a-zA-Z0-9+/=]+)', TERMINATOR, r'$']), msgstr) if not match: raise ProtocolParseError ver, dbid_str = match.groups() """Only exact match for now (should preferably support older versions)""" if PROTOCOL_VERSION != ver: raise ProtocolVersionError('Incompatible Protocol versions') try: dbid = decode_b64_bytes(dbid_str.encode()) except ValueError: raise ProtocolParseError return dbid
def _decode_id(self, id): """Text to binary decoding of id's""" return decode_b64_bytes(id.encode())