about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/omemo/omemo.c32
-rw-r--r--src/omemo/omemo.h4
-rw-r--r--src/xmpp/message.c35
-rw-r--r--src/xmpp/omemo.c66
-rw-r--r--src/xmpp/omemo.h4
-rw-r--r--src/xmpp/session.c2
-rw-r--r--src/xmpp/stanza.c4
-rw-r--r--src/xmpp/stanza.h2
-rw-r--r--src/xmpp/xmpp.h1
9 files changed, 106 insertions, 44 deletions
diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c
index 080baf1b..9300c6b8 100644
--- a/src/omemo/omemo.c
+++ b/src/omemo/omemo.c
@@ -11,6 +11,8 @@
 #include "omemo/crypto.h"
 #include "omemo/omemo.h"
 #include "ui/ui.h"
+#include "xmpp/xmpp.h"
+#include "xmpp/connection.h"
 #include "xmpp/omemo.h"
 
 static gboolean loaded;
@@ -23,7 +25,7 @@ struct omemo_context_t {
     pthread_mutex_t lock;
     signal_context *signal;
     uint32_t device_id;
-    GList *device_list;
+    GHashTable *device_list;
     ratchet_identity_key_pair *identity_key_pair;
     uint32_t registration_id;
     signal_protocol_key_helper_pre_key_list_node *pre_keys_head;
@@ -72,14 +74,23 @@ omemo_init(void)
     signal_context_set_locking_functions(omemo_ctx.signal, lock, unlock);
 
     loaded = FALSE;
-    omemo_ctx.device_list = NULL;
+    omemo_ctx.device_list = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)g_list_free);
 }
 
 void
 omemo_generate_crypto_materials(ProfAccount *account)
 {
+    xmpp_ctx_t * const ctx = connection_get_ctx();
+    char *barejid = xmpp_jid_bare(ctx, session_get_account_name());
+
+    GList *device_list = g_hash_table_lookup(omemo_ctx.device_list, barejid);
+    g_hash_table_steal(omemo_ctx.device_list, barejid);
+
     omemo_ctx.device_id = randombytes_uniform(0x80000000);
-    omemo_ctx.device_list = g_list_append(omemo_ctx.device_list, GINT_TO_POINTER(omemo_ctx.device_id));
+
+    device_list = g_list_append(device_list, GINT_TO_POINTER(omemo_ctx.device_id));
+    g_hash_table_insert(omemo_ctx.device_list, strdup(barejid), device_list);
+
     signal_protocol_key_helper_generate_identity_key_pair(&omemo_ctx.identity_key_pair, omemo_ctx.signal);
     signal_protocol_key_helper_generate_registration_id(&omemo_ctx.registration_id, 0, omemo_ctx.signal);
     signal_protocol_key_helper_generate_pre_keys(&omemo_ctx.pre_keys_head, randombytes_random(), 100, omemo_ctx.signal);
@@ -91,7 +102,7 @@ omemo_generate_crypto_materials(ProfAccount *account)
 
     loaded = TRUE;
 
-    omemo_devicelist_publish();
+    omemo_devicelist_publish(device_list);
     omemo_bundle_publish();
 }
 
@@ -107,12 +118,6 @@ omemo_loaded(void)
     return loaded;
 }
 
-GList * const
-omemo_device_list(void)
-{
-    return omemo_ctx.device_list;
-}
-
 uint32_t
 omemo_device_id(void)
 {
@@ -167,6 +172,13 @@ omemo_prekeys(GList ** const prekeys, GList ** const ids, GList ** const lengths
     }
 }
 
+void
+omemo_set_device_list(const char *const jid, GList * const device_list)
+{
+    /* TODO handle self device_list to ensure we still are on the list */
+    g_hash_table_insert(omemo_ctx.device_list, strdup(jid), device_list);
+}
+
 static void
 lock(void *user_data)
 {
diff --git a/src/omemo/omemo.h b/src/omemo/omemo.h
index 20fd5d5d..ca9f7208 100644
--- a/src/omemo/omemo.h
+++ b/src/omemo/omemo.h
@@ -1,3 +1,5 @@
+#include <glib.h>
+
 #include "config/account.h"
 
 typedef struct omemo_context_t omemo_context;
@@ -5,12 +7,12 @@ typedef struct omemo_context_t omemo_context;
 void omemo_init(void);
 void omemo_generate_crypto_materials(ProfAccount *account);
 
-GList * const omemo_device_list(void);
 uint32_t omemo_device_id(void);
 void omemo_identity_key(unsigned char **output, size_t *length);
 void omemo_signed_prekey(unsigned char **output, size_t *length);
 void omemo_signed_prekey_signature(unsigned char **output, size_t *length);
 void omemo_prekeys(GList ** const prekeys, GList ** const ids, GList ** const lengths);
+void omemo_set_device_list(const char *const jid, GList * const device_list);
 
 void omemo_start_session(ProfAccount *account, char *barejid);
 gboolean omemo_loaded(void);
diff --git a/src/xmpp/message.c b/src/xmpp/message.c
index 8240402d..fba62bc8 100644
--- a/src/xmpp/message.c
+++ b/src/xmpp/message.c
@@ -76,7 +76,6 @@ static void _handel_muc_user(xmpp_stanza_t *const stanza);
 static void _handle_conference(xmpp_stanza_t *const stanza);
 static void _handle_captcha(xmpp_stanza_t *const stanza);
 static void _handle_receipt_received(xmpp_stanza_t *const stanza);
-static void _handle_pubsub_event(xmpp_stanza_t *const stanza);
 static void _handle_chat(xmpp_stanza_t *const stanza);
 
 static void _send_message_stanza(xmpp_stanza_t *const stanza);
@@ -129,7 +128,20 @@ _message_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *con
 
     xmpp_stanza_t *event = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_PUBSUB_EVENT);
     if (event) {
-        _handle_pubsub_event(event);
+        xmpp_stanza_t *child = xmpp_stanza_get_children(event);
+        if (child) {
+            const char *node = xmpp_stanza_get_attribute(child, STANZA_ATTR_NODE);
+            if (node) {
+                ProfMessageHandler *handler = g_hash_table_lookup(pubsub_event_handlers, node);
+                if (handler) {
+                    int keep = handler->func(stanza, handler->userdata);
+                    if (!keep) {
+                        free(handler);
+                        g_hash_table_remove(pubsub_event_handlers, node);
+                    }
+                }
+            }
+        }
     }
 
     _handle_chat(stanza);
@@ -665,25 +677,6 @@ _handle_receipt_received(xmpp_stanza_t *const stanza)
     jid_destroy(jidp);
 }
 
-static void
-_handle_pubsub_event(xmpp_stanza_t *const event)
-{
-    xmpp_stanza_t *child = xmpp_stanza_get_children(event);
-    if (child) {
-        const char *node = xmpp_stanza_get_attribute(event, STANZA_ATTR_NODE);
-        if (node) {
-            ProfMessageHandler *handler = g_hash_table_lookup(pubsub_event_handlers, node);
-            if (handler) {
-                int keep = handler->func(event, handler->userdata);
-                if (!keep) {
-                    free(handler);
-                    g_hash_table_remove(pubsub_event_handlers, node);
-                }
-            }
-        }
-    }
-}
-
 void
 _receipt_request_handler(xmpp_stanza_t *const stanza)
 {
diff --git a/src/xmpp/omemo.c b/src/xmpp/omemo.c
index a979ec90..ab10e975 100644
--- a/src/xmpp/omemo.c
+++ b/src/xmpp/omemo.c
@@ -1,31 +1,37 @@
+#include <glib.h>
+
 #include "xmpp/connection.h"
+#include "xmpp/message.h"
 #include "xmpp/iq.h"
 #include "xmpp/stanza.h"
 
 #include "omemo/omemo.h"
 
+static int _omemo_receive_devicelist(xmpp_stanza_t *const stanza, void *const userdata);
+
 void
 omemo_devicelist_subscribe(void)
 {
-    xmpp_ctx_t * const ctx = connection_get_ctx();
-    char *barejid = xmpp_jid_bare(ctx, session_get_account_name());
-    xmpp_stanza_t *iq = stanza_create_omemo_devicelist_subscribe(ctx, barejid);
-    iq_send_stanza(iq);
-    xmpp_stanza_release(iq);
+    message_pubsub_event_handler_add(STANZA_NS_OMEMO_DEVICELIST, _omemo_receive_devicelist, NULL, NULL);
 
-    free(barejid);
+    caps_add_feature(XMPP_FEATURE_OMEMO_DEVICELIST_NOTIFY);
 }
 
 void
-omemo_devicelist_publish(void)
+omemo_devicelist_publish(GList *device_list)
 {
     xmpp_ctx_t * const ctx = connection_get_ctx();
-    xmpp_stanza_t *iq = stanza_create_omemo_devicelist_publish(ctx, omemo_device_list());
+    xmpp_stanza_t *iq = stanza_create_omemo_devicelist_publish(ctx, device_list);
     iq_send_stanza(iq);
     xmpp_stanza_release(iq);
 }
 
 void
+omemo_devicelist_fetch(void)
+{
+}
+
+void
 omemo_bundle_publish(void)
 {
     xmpp_ctx_t * const ctx = connection_get_ctx();
@@ -53,3 +59,47 @@ omemo_bundle_publish(void)
     free(signed_prekey);
     free(signed_prekey_signature);
 }
+
+void
+omemo_bundles_fetch(const char * const jid)
+{
+}
+
+static int
+_omemo_receive_devicelist(xmpp_stanza_t *const stanza, void *const userdata)
+{
+    GList *device_list = NULL;
+    const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
+    if (!from) {
+        return 1;
+    }
+
+    xmpp_stanza_t *event = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_PUBSUB_EVENT);
+    if (!event) {
+        return 1;
+    }
+
+    xmpp_stanza_t *items = xmpp_stanza_get_child_by_name(event, "items");
+    if (!items) {
+        return 1;
+    }
+
+    xmpp_stanza_t *item = xmpp_stanza_get_child_by_name(items, "item");
+    if (!item) {
+        return 1;
+    }
+
+    xmpp_stanza_t *list = xmpp_stanza_get_child_by_ns(item, STANZA_NS_OMEMO);
+    if (!list) {
+        return 1;
+    }
+
+    xmpp_stanza_t *device;
+    for (device = xmpp_stanza_get_children(list); device != NULL; device = xmpp_stanza_get_next(device)) {
+        const char *id = xmpp_stanza_get_id(device);
+        device_list = g_list_append(device_list, GINT_TO_POINTER(strtoul(id, NULL, 10)));
+    }
+    omemo_set_device_list(from, device_list);
+
+    return 1;
+}
diff --git a/src/xmpp/omemo.h b/src/xmpp/omemo.h
index eff3eee3..5409c6fd 100644
--- a/src/xmpp/omemo.h
+++ b/src/xmpp/omemo.h
@@ -1,3 +1,5 @@
+#include <glib.h>
+
 void omemo_devicelist_subscribe(void);
-void omemo_devicelist_publish(void);
+void omemo_devicelist_publish(GList *device_list);
 void omemo_bundle_publish(void);
diff --git a/src/xmpp/session.c b/src/xmpp/session.c
index ef53ad6f..b05c5f7b 100644
--- a/src/xmpp/session.c
+++ b/src/xmpp/session.c
@@ -321,7 +321,7 @@ session_login_success(gboolean secured)
 #ifdef HAVE_OMEMO
     omemo_devicelist_subscribe();
     if (omemo_loaded()) {
-        omemo_devicelist_publish();
+        /* TODO: update devicelist */
     }
 #endif
 
diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c
index e6400b0b..e2ced2ac 100644
--- a/src/xmpp/stanza.c
+++ b/src/xmpp/stanza.c
@@ -2105,7 +2105,7 @@ stanza_create_omemo_devicelist_subscribe(xmpp_ctx_t *ctx, const char *const jid)
 
     xmpp_stanza_t *subscribe = xmpp_stanza_new(ctx);
     xmpp_stanza_set_name(subscribe, STANZA_NAME_SUBSCRIBE);
-    xmpp_stanza_set_attribute(subscribe, "node", "eu.siacs.conversations.axolotl.devicelist");
+    xmpp_stanza_set_attribute(subscribe, "node", STANZA_NS_OMEMO_DEVICELIST);
     xmpp_stanza_set_attribute(subscribe, "jid", jid);
 
     xmpp_stanza_add_child(pubsub, subscribe);
@@ -2130,7 +2130,7 @@ stanza_create_omemo_devicelist_publish(xmpp_ctx_t *ctx, GList *const ids)
 
     xmpp_stanza_t *publish = xmpp_stanza_new(ctx);
     xmpp_stanza_set_name(publish, STANZA_NAME_PUBLISH);
-    xmpp_stanza_set_attribute(publish, "node", "eu.siacs.conversations.axolotl.devicelist");
+    xmpp_stanza_set_attribute(publish, "node", STANZA_NS_OMEMO_DEVICELIST);
 
     xmpp_stanza_t *item = xmpp_stanza_new(ctx);
     xmpp_stanza_set_name(item, STANZA_NAME_ITEM);
diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h
index df9c27ff..23b47de1 100644
--- a/src/xmpp/stanza.h
+++ b/src/xmpp/stanza.h
@@ -191,6 +191,8 @@
 #define STANZA_NS_X_OOB "jabber:x:oob"
 #define STANZA_NS_BLOCKING "urn:xmpp:blocking"
 #define STANZA_NS_COMMAND "http://jabber.org/protocol/commands"
+#define STANZA_NS_OMEMO "eu.siacs.conversations.axolotl"
+#define STANZA_NS_OMEMO_DEVICELIST "eu.siacs.conversations.axolotl.devicelist"
 
 #define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo"
 
diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h
index c9403090..5c0dae76 100644
--- a/src/xmpp/xmpp.h
+++ b/src/xmpp/xmpp.h
@@ -61,6 +61,7 @@
 #define XMPP_FEATURE_LASTACTIVITY "jabber:iq:last"
 #define XMPP_FEATURE_MUC "http://jabber.org/protocol/muc"
 #define XMPP_FEATURE_COMMANDS "http://jabber.org/protocol/commands"
+#define XMPP_FEATURE_OMEMO_DEVICELIST_NOTIFY "eu.siacs.conversations.axolotl.devicelist+notify"
 
 typedef enum {
     JABBER_CONNECTING,