Skip to content

Instantly share code, notes, and snippets.

Self hosting UnifiedPush w/ Conversations as Distributor

You might have heard that XMPP in general, and Conversations in particular, make a great UnifiedPush Distributor. That is correct! However, you might find yourself in a dilemma: you already have an XMPP account with a trusted provider that you want to keep using, and you don’t want to host and maintain your own XMPP server. Furthermore, you may not feel comfortable using the publicly accessible Rewrite Proxy up.conversations.im. Luckily, you can easily self-host just the Rewrite Proxy component (the part that would otherwise default to up.conversations.im in Conversations).

⚠️ If you are already self hosting an XMPP server stop reading and just configure the respective modules for Prosody and ejabberd.

Requirements

This tutorial assumes you have a domain (any su

<iq type="set" id="7RXOvvazuTAi" from="a/Conversations.34B6" to="b/Conversations.eVjR">
<jingle sid="Nu0lPv07EN8O5Wn7jVRszA" action="session-initiate" xmlns="urn:xmpp:jingle:1">
<content name="0" creator="initiator" senders="initiator" xmlns="urn:xmpp:jingle:1">
<description xmlns="urn:xmpp:jingle:apps:file-transfer:5">
<file xmlns="urn:xmpp:jingle:apps:file-transfer:5">
<name>af9742ee-85d2-46b6-ba48-e72ffbbbd221.jpg</name>
<size>65751</size>
<mediaType>image/jpeg</mediaType>
</file>
</description>
@iNPUTmice
iNPUTmice / send_image.py
Last active June 30, 2021 19:44
Send an image in a chat message with SleekXMPP
import logging
import threading
import sleekxmpp
logging.basicConfig(level=logging.DEBUG)
class Bot(sleekxmpp.ClientXMPP):
def __init__(self, jid, password):

Verify encrypted A/V calls with OMEMO

Audio and Video calls in XMPP are encrypted end-to-end with DTLS-SRTP as per XEP-0320: Use of DTLS-SRTP in Jingle Sessions.

This protocol replaces XEP-0320 with something that is encrypted with and verified by OMEMO.

Disclaimer: The proper solution is to use OMEMO version 0.5+ and Stanza Content Encryption and encrypt the entire Jingle handshake. However we are still a long road away from having OMEMO 0.5+ in general and any implementational experience with SCE for IQ based protocols in particular. The protocol proposed here is a hack that is hopefully not too dirty.

Extension of XEP-0353: Jingle Message Initiation

#!/bin/sh
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk/
export ANDROID_HOME=/opt/android-sdk
BUILD_DIRECTORY="lttrs-android-build"
git clone https://github.com/iNPUTmice/lttrs-android.git
mkdir $BUILD_DIRECTORY
disorderfs --sort-dirents=yes --reverse-dirents=no lttrs-android $BUILD_DIRECTORY
cd $BUILD_DIRECTORY
./gradlew assembleRelease
sha256sum app/build/outputs/apk/release/Ltt.rs-0.1.0-release-unsigned.apk
Section "InputClass"
Identifier "system-keyboard"
MatchIsKeyboard "on"
Option "XkbModel" "pc105"
Option "XkbLayout" "de"
Option "XkbVariant" "neo"
EndSection

OMEMO encryption in group chats works basically like it works in 1:1 chats as well. Instead of encrypting using all of your contacts‘ sessions and all of your other devices’ sessions you encrypt using all of the the participants’ devices sesions (plus all of your other devices).

General

It is recommended to use the very same sessions you’d be using for 1:1 chats as well. So messages going to someone directly are encrypted using the same session as messages going to a group chat with that someone in it.

For this to work we need to be able to discover the real XMPP address of all participants. Therefor it is a fundamental requirement for all OMEMO enabled group chats to be non-anonymous. On top of that Conversations (and probably other clients) limit OMEMO to members-only groups. Encrypting messages in a chat where everyone can join and potentially has the expection to be able to read the backlog does not make much sense. However this is an artificial limitation and not a technical requirement.

Sidenote:

Using PEP with a different access model

PubSub—and by inheritence PEP—supports five access models for a node. This document describes an algorithm for setting the access model of a PEP node savely and securely with minimal round trip times. Especially in a scenario where a node is supposed to be private, a publish first and configure access model later approach must be avoided as this could leak information in between those requests.

Publish with publish-options

Assuming we want to publish <content xmlns="com.example.dummy"/> to a node called com.example.dummy that should be available to everyone and not just our contacts.

Warning: We must ensure that the server annouces the namespace http://jabber.org/protocol/pubsub#publish-options on the account jid. Otherwise we risk the server just ignoring the publish-options in the following request which would be especially dang

<iq to="you@conversations.im" id="blockspam01" type="set">
<block xmlns='urn:xmpp:blocking'>
<item jid="kdetalk.net"/>
<item jid="swissjabber.li"/>
<item jid="swissjabber.eu"/>
<item jid="swissjabber.ch"/>
<item jid="swissjabber.org"/>
<item jid="swissjabber.de"/>
</block >
</iq>