def _make_command(command, attrs, dataform): command_node = Node('command', attrs=attrs) if dataform is not None: command_node.addChild(node=dataform) iq = Iq('set', to=command.jid) iq.addChild(node=command_node) return iq
def _make_keylist(keylist): item = Node('public-keys-list', {'xmlns': Namespace.OPENPGP}) if keylist is not None: for key in keylist: date = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(key.date)) attrs = {'v4-fingerprint': key.fingerprint, 'date': date} item.addChild('pubkey-metadata', attrs=attrs) return item
def _make_devicelist(devicelist): if devicelist is None: devicelist = [] devicelist_node = Node('list', attrs={'xmlns': Namespace.OMEMO_TEMP}) for device in devicelist: devicelist_node.addChild('device').setAttr('id', device) return devicelist_node
def _make_search_query(jid, dataform, items_per_page=50, after=None): search = Node('search', attrs={'xmlns': Namespace.MUCLUMBUS}) search.addChild(node=dataform) rsm = search.addChild('set', namespace=Namespace.RSM) rsm.addChild('max').setData(items_per_page) if after is not None: rsm.addChild('after').setData(after) query = Iq(to=jid, typ='get') query.addChild(node=search) return query
def _make_publish_options(options): data = Node(Namespace.DATA + ' x', attrs={'type': 'submit'}) field = data.addChild('field', attrs={ 'var': 'FORM_TYPE', 'type': 'hidden' }) field.setTagData('value', Namespace.PUBSUB_PUBLISH_OPTIONS) for var, value in options.items(): field = data.addChild('field', attrs={'var': var}) field.setTagData('value', value) return data
def get_publish_options(config): options = Node(Namespace.DATA + ' x', attrs={'type': 'submit'}) field = options.addChild('field', attrs={ 'var': 'FORM_TYPE', 'type': 'hidden' }) field.setTagData('value', Namespace.PUBSUB_PUBLISH_OPTIONS) for var, value in config.items(): field = options.addChild('field', attrs={'var': var}) field.setTagData('value', value) return options
def set_location(self, data): task = yield item = Node('geoloc', {'xmlns': Namespace.LOCATION}) if data is not None: data = data._asdict() for tag, value in data.items(): if value is not None: item.addChild(tag, payload=value) result = yield self.publish(Namespace.LOCATION, item, id_='current') yield finalize(task, result)
def set_mood(self, data): task = yield item = Node('mood', {'xmlns': Namespace.MOOD}) if data is not None and data.mood: item.addChild(data.mood) if data.text: item.addChild('text', payload=data.text) result = yield self.publish(Namespace.MOOD, item, id_='current') yield finalize(task, result)
def set_activity(self, data): task = yield item = Node('activity', {'xmlns': Namespace.ACTIVITY}) if data is not None and data.activity: activity_node = item.addChild(data.activity) if data.subactivity: activity_node.addChild(data.subactivity) if data.text: item.addChild('text', payload=data.text) result = yield self.publish(Namespace.ACTIVITY, item, id_='current') yield finalize(task, result)
def _make_bundle(bundle): ''' <publish node='eu.siacs.conversations.axolotl.bundles:31415'> <item id='current'> <bundle xmlns='eu.siacs.conversations.axolotl'> <signedPreKeyPublic signedPreKeyId='1'> BASE64ENCODED... </signedPreKeyPublic> <signedPreKeySignature> BASE64ENCODED... </signedPreKeySignature> <identityKey> BASE64ENCODED... </identityKey> <prekeys> <preKeyPublic preKeyId='1'> BASE64ENCODED... </preKeyPublic> <preKeyPublic preKeyId='2'> BASE64ENCODED... </preKeyPublic> <preKeyPublic preKeyId='3'> BASE64ENCODED... </preKeyPublic> <!-- ... --> </prekeys> </bundle> </item> </publish> ''' bundle_node = Node('bundle', attrs={'xmlns': Namespace.OMEMO_TEMP}) prekey_pub_node = bundle_node.addChild( 'signedPreKeyPublic', attrs={'signedPreKeyId': bundle.spk['id']}) prekey_pub_node.addData(b64encode(bundle.spk['key'])) prekey_sig_node = bundle_node.addChild('signedPreKeySignature') prekey_sig_node.addData(b64encode(bundle.spk_signature)) identity_key_node = bundle_node.addChild('identityKey') identity_key_node.addData(b64encode(bundle.ik)) prekeys = bundle_node.addChild('prekeys') for key in bundle.otpks: pre_key_public = prekeys.addChild('preKeyPublic', attrs={'preKeyId': key['id']}) pre_key_public.addData(b64encode(key['key'])) return bundle_node
def get_key_transport_message(typ, jid, omemo_message): message = Message(typ=typ, to=jid) encrypted = Node('encrypted', attrs={'xmlns': Namespace.OMEMO_TEMP}) header = Node('header', attrs={'sid': omemo_message.sid}) for rid, (key, prekey) in omemo_message.keys.items(): attrs = {'rid': rid} if prekey: attrs['prekey'] = 'true' child = header.addChild('key', attrs=attrs) child.addData(b64encode(key)) header.addChild('iv').addData(b64encode(omemo_message.iv)) encrypted.addChild(node=header) message.addChild(node=encrypted) return message
def build_storage_node(bookmarks): storage_node = Node(tag='storage', attrs={'xmlns': Namespace.BOOKMARKS}) for bookmark in bookmarks: conf_node = storage_node.addChild(name="conference") conf_node.setAttr('jid', bookmark.jid) conf_node.setAttr('autojoin', to_xs_boolean(bookmark.autojoin)) if bookmark.name: conf_node.setAttr('name', bookmark.name) if bookmark.nick: conf_node.setTagData('nick', bookmark.nick) if bookmark.password: conf_node.setTagData('password', bookmark.password) return storage_node
def create_omemo_message(stanza, omemo_message, store_hint=True, node_whitelist=None): ''' <message> <encrypted xmlns='eu.siacs.conversations.axolotl'> <header sid='27183'> <key rid='31415'>BASE64ENCODED...</key> <key prekey="true" rid='12321'>BASE64ENCODED...</key> <!-- ... --> <iv>BASE64ENCODED...</iv> </header> <payload>BASE64ENCODED</payload> </encrypted> <store xmlns='urn:xmpp:hints'/> </message> ''' if node_whitelist is not None: cleanup_stanza(stanza, node_whitelist) encrypted = Node('encrypted', attrs={'xmlns': Namespace.OMEMO_TEMP}) header = Node('header', attrs={'sid': omemo_message.sid}) for rid, (key, prekey) in omemo_message.keys.items(): attrs = {'rid': rid} if prekey: attrs['prekey'] = 'true' child = header.addChild('key', attrs=attrs) child.addData(b64encode(key)) header.addChild('iv').addData(b64encode(omemo_message.iv)) encrypted.addChild(node=header) payload = encrypted.addChild('payload') payload.addData(b64encode(omemo_message.payload)) stanza.addChild(node=encrypted) stanza.addChild(node=Node('encryption', attrs={ 'xmlns': Namespace.EME, 'name': 'OMEMO', 'namespace': Namespace.OMEMO_TEMP })) stanza.setBody("You received a message encrypted with " "OMEMO but your client doesn't support OMEMO.") if store_hint: stanza.addChild(node=Node('store', attrs={'xmlns': Namespace.HINTS}))
def create_signcrypt_node(stanza, recipients, not_encrypted_nodes): ''' <signcrypt xmlns='urn:xmpp:openpgp:0'> <to jid='*****@*****.**'/> <time stamp='2014-07-10T17:06:00+02:00'/> <rpad> f0rm1l4n4-mT8y33j!Y%fRSrcd^ZE4Q7VDt1L%WEgR!kv </rpad> <payload> <body xmlns='jabber:client'> This is a secret message. </body> </payload> </signcrypt> ''' encrypted_nodes = [] child_nodes = list(stanza.getChildren()) for node in child_nodes: if (node.getName(), node.getNamespace()) not in not_encrypted_nodes: if not node.getNamespace(): node.setNamespace(Namespace.CLIENT) encrypted_nodes.append(node) stanza.delChild(node) signcrypt = Node('signcrypt', attrs={'xmlns': Namespace.OPENPGP}) for recipient in recipients: signcrypt.addChild('to', attrs={'jid': str(recipient)}) timestamp = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()) signcrypt.addChild('time', attrs={'stamp': timestamp}) signcrypt.addChild('rpad').addData(get_rpad()) payload = signcrypt.addChild('payload') for node in encrypted_nodes: payload.addChild(node=node) return signcrypt
def _make_public_key(key, date): date = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(date)) item = Node('pubkey', attrs={'xmlns': Namespace.OPENPGP, 'date': date}) data = item.addChild('data') data.addData(b64encode(key)) return item
def _make_metadata_node(infos): item = Node('metadata', attrs={'xmlns': Namespace.AVATAR_METADATA}) for info in infos: item.addChild('info', attrs=info.to_dict()) return item