about summary refs log tree commit diff stats
path: root/src/xmpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/xmpp')
-rw-r--r--src/xmpp/connection.c1
-rw-r--r--src/xmpp/omemo.c51
-rw-r--r--src/xmpp/stanza.c49
-rw-r--r--src/xmpp/stanza.h4
4 files changed, 79 insertions, 26 deletions
diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c
index 0bcab020..d34f9a4f 100644
--- a/src/xmpp/connection.c
+++ b/src/xmpp/connection.c
@@ -454,6 +454,7 @@ connection_get_barejid(void)
 void
 connection_features_received(const char* const jid)
 {
+    log_info("[CONNECTION] connection_features_received %s", jid);
     if (g_hash_table_remove(conn.requested_features, jid) && g_hash_table_size(conn.requested_features) == 0) {
         sv_ev_connection_features_received();
     }
diff --git a/src/xmpp/omemo.c b/src/xmpp/omemo.c
index e527d4c7..917e6f19 100644
--- a/src/xmpp/omemo.c
+++ b/src/xmpp/omemo.c
@@ -63,6 +63,8 @@ omemo_devicelist_publish(GList* device_list)
     xmpp_ctx_t* const ctx = connection_get_ctx();
     xmpp_stanza_t* iq = stanza_create_omemo_devicelist_publish(ctx, device_list);
 
+    log_info("[OMEMO] publish device list");
+
     if (connection_supports(XMPP_FEATURE_PUBSUB_PUBLISH_OPTIONS)) {
         stanza_attach_publish_options(ctx, iq, "pubsub#access_model", "open");
     }
@@ -77,6 +79,8 @@ omemo_devicelist_request(const char* const jid)
     xmpp_ctx_t* const ctx = connection_get_ctx();
     char* id = connection_create_stanza_id();
 
+    log_info("[OMEMO] request device list for jid: %s", jid);
+
     xmpp_stanza_t* iq = stanza_create_omemo_devicelist_request(ctx, id, jid);
     iq_id_handler_add(id, _omemo_receive_devicelist, NULL, NULL);
 
@@ -89,6 +93,7 @@ omemo_devicelist_request(const char* const jid)
 void
 omemo_bundle_publish(gboolean first)
 {
+    log_info("[OMEMO] publish own OMEMO bundle");
     xmpp_ctx_t* const ctx = connection_get_ctx();
     unsigned char* identity_key = NULL;
     size_t identity_key_length;
@@ -114,7 +119,10 @@ omemo_bundle_publish(gboolean first)
     g_list_free(ids);
 
     if (connection_supports(XMPP_FEATURE_PUBSUB_PUBLISH_OPTIONS)) {
-        stanza_attach_publish_options(ctx, iq, "pubsub#access_model", "open");
+        stanza_attach_publish_options_va(ctx, iq,
+                4, // 2 * number of key-value pairs
+                "pubsub#persist_items", "true",
+                "pubsub#access_model", "open");
     }
 
     iq_id_handler_add(id, _omemo_bundle_publish_result, NULL, GINT_TO_POINTER(first));
@@ -134,6 +142,8 @@ omemo_bundle_request(const char* const jid, uint32_t device_id, ProfIqCallback f
     xmpp_ctx_t* const ctx = connection_get_ctx();
     char* id = connection_create_stanza_id();
 
+    log_info("[OMEMO] request omemo bundle (jid: %s, deivce: %d)", jid, device_id);
+
     xmpp_stanza_t* iq = stanza_create_omemo_bundle_request(ctx, id, jid, device_id);
     iq_id_handler_add(id, func, free_func, userdata);
 
@@ -459,7 +469,7 @@ _omemo_receive_devicelist(xmpp_stanza_t* const stanza, void* const userdata)
     if (current) {
         item = current;
     } else if (first) {
-        log_warning("OMEMO: User %s has a non 'current' device item list: %s.", from, xmpp_stanza_get_id(first));
+        log_warning("[OMEMO] User %s has a non 'current' device item list: %s.", from, xmpp_stanza_get_id(first));
         item = first;
     } else {
         return 1;
@@ -480,7 +490,7 @@ _omemo_receive_devicelist(xmpp_stanza_t* const stanza, void* const userdata)
         if (id != NULL) {
             device_list = g_list_append(device_list, GINT_TO_POINTER(strtoul(id, NULL, 10)));
         } else {
-            log_error("OMEMO: received device without ID");
+            log_error("[OMEMO] received device without ID");
         }
     }
 
@@ -489,25 +499,31 @@ _omemo_receive_devicelist(xmpp_stanza_t* const stanza, void* const userdata)
     return 1;
 }
 
+
 static int
 _omemo_bundle_publish_result(xmpp_stanza_t* const stanza, void* const userdata)
 {
+    log_debug("[OMEMO] _omemo_bundle_publish_result()");
+
     const char* type = xmpp_stanza_get_type(stanza);
 
-    if (g_strcmp0(type, STANZA_TYPE_ERROR) != 0) {
+    if (g_strcmp0(type, STANZA_TYPE_RESULT) == 0) {
+        log_info("[OMEMO] bundle published successfully");
         return 0;
     }
 
     if (!GPOINTER_TO_INT(userdata)) {
-        log_error("OMEMO: definitely cannot publish bundle with an open access model");
+        log_error("[OMEMO] definitely cannot publish bundle with an open access model");
         return 0;
     }
 
-    log_info("OMEMO: cannot publish bundle with open access model, trying to configure node");
+    log_info("[OMEMO] cannot publish bundle with open access model, trying to configure node");
     xmpp_ctx_t* const ctx = connection_get_ctx();
     Jid* jid = jid_create(connection_get_fulljid());
     char* id = connection_create_stanza_id();
     char* node = g_strdup_printf("%s:%d", STANZA_NS_OMEMO_BUNDLES, omemo_device_id());
+    log_info("[OMEMO] node: %s", node);
+
     xmpp_stanza_t* iq = stanza_create_pubsub_configure_request(ctx, id, jid->barejid, node);
     g_free(node);
 
@@ -524,18 +540,30 @@ _omemo_bundle_publish_result(xmpp_stanza_t* const stanza, void* const userdata)
 static int
 _omemo_bundle_publish_configure(xmpp_stanza_t* const stanza, void* const userdata)
 {
-    /* TODO handle error */
+    log_debug("[OMEMO] _omemo_bundle_publish_configure()");
+
     xmpp_stanza_t* pubsub = xmpp_stanza_get_child_by_name(stanza, "pubsub");
+    if (!pubsub) {
+        log_error("[OMEMO] The stanza doesn't contain a 'pubsub' child");
+        return 0;
+    }
     xmpp_stanza_t* configure = xmpp_stanza_get_child_by_name(pubsub, STANZA_NAME_CONFIGURE);
+    if (!configure) {
+        log_error("[OMEMO] The stanza doesn't contain a 'configure' child");
+        return 0;
+    }
     xmpp_stanza_t* x = xmpp_stanza_get_child_by_name(configure, "x");
+    if (!x) {
+        log_error("[OMEMO] The stanza doesn't contain an 'x' child");
+        return 0;
+    }
 
     DataForm* form = form_create(x);
     char* tag = g_hash_table_lookup(form->var_to_tag, "pubsub#access_model");
     if (!tag) {
-        log_info("OMEMO: cannot configure bundle to an open access model");
+        log_error("[OMEMO] cannot configure bundle to an open access model");
         return 0;
     }
-    form_set_value(form, tag, "open");
 
     xmpp_ctx_t* const ctx = connection_get_ctx();
     Jid* jid = jid_create(connection_get_fulljid());
@@ -560,10 +588,13 @@ _omemo_bundle_publish_configure_result(xmpp_stanza_t* const stanza, void* const
     const char* type = xmpp_stanza_get_type(stanza);
 
     if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
-        log_error("OMEMO: cannot configure bundle to an open access model");
+        log_error("[OMEMO] cannot configure bundle to an open access model: Result error");
         return 0;
     }
 
+    log_info("[OMEMO] node configured");
+
+    // Try to publish again
     omemo_bundle_publish(TRUE);
 
     return 0;
diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c
index 06615aa9..2b39a023 100644
--- a/src/xmpp/stanza.c
+++ b/src/xmpp/stanza.c
@@ -1940,8 +1940,9 @@ stanza_get_error_message(xmpp_stanza_t* stanza)
     return strdup("unknown");
 }
 
+// Note that the `count' must be 2 * number of key/value pairs
 void
-stanza_attach_publish_options(xmpp_ctx_t* const ctx, xmpp_stanza_t* const iq, const char* const option, const char* const value)
+stanza_attach_publish_options_va(xmpp_ctx_t* const ctx, xmpp_stanza_t* const iq, int count, ...)
 {
     xmpp_stanza_t* publish_options = xmpp_stanza_new(ctx);
     xmpp_stanza_set_name(publish_options, STANZA_NAME_PUBLISH_OPTIONS);
@@ -1964,23 +1965,34 @@ stanza_attach_publish_options(xmpp_ctx_t* const ctx, xmpp_stanza_t* const iq, co
     xmpp_stanza_add_child(form_type, form_type_value);
     xmpp_stanza_add_child(x, form_type);
 
-    xmpp_stanza_t* access_model = xmpp_stanza_new(ctx);
-    xmpp_stanza_set_name(access_model, STANZA_NAME_FIELD);
-    xmpp_stanza_set_attribute(access_model, STANZA_ATTR_VAR, option);
-    xmpp_stanza_t* access_model_value = xmpp_stanza_new(ctx);
-    xmpp_stanza_set_name(access_model_value, STANZA_NAME_VALUE);
-    xmpp_stanza_t* access_model_value_text = xmpp_stanza_new(ctx);
-    xmpp_stanza_set_text(access_model_value_text, value);
-    xmpp_stanza_add_child(access_model_value, access_model_value_text);
-    xmpp_stanza_add_child(access_model, access_model_value);
-    xmpp_stanza_add_child(x, access_model);
-
     xmpp_stanza_t* pubsub = xmpp_stanza_get_child_by_ns(iq, STANZA_NS_PUBSUB);
     xmpp_stanza_add_child(pubsub, publish_options);
 
-    xmpp_stanza_release(access_model_value_text);
-    xmpp_stanza_release(access_model_value);
-    xmpp_stanza_release(access_model);
+    va_list ap;
+    va_start(ap, count);
+    int j;
+    for (j = 0; j < count; j += 2) {
+        const char* const option = va_arg(ap, char* const);
+        const char* const value  = va_arg(ap, char* const);
+
+        xmpp_stanza_t* field = xmpp_stanza_new(ctx);
+        xmpp_stanza_set_name(field, STANZA_NAME_FIELD);
+        xmpp_stanza_set_attribute(field, STANZA_ATTR_VAR, option);
+        xmpp_stanza_t* field_value = xmpp_stanza_new(ctx);
+        xmpp_stanza_set_name(field_value, STANZA_NAME_VALUE);
+        xmpp_stanza_t* field_value_text = xmpp_stanza_new(ctx);
+        xmpp_stanza_set_text(field_value_text, value);
+        xmpp_stanza_add_child(field_value, field_value_text);
+        xmpp_stanza_add_child(field, field_value);
+        xmpp_stanza_add_child(x, field);
+
+        xmpp_stanza_release(field_value_text);
+        xmpp_stanza_release(field_value);
+        xmpp_stanza_release(field);
+    }
+    va_end(ap);
+
+
     xmpp_stanza_release(form_type_value_text);
     xmpp_stanza_release(form_type_value);
     xmpp_stanza_release(form_type);
@@ -1989,6 +2001,13 @@ stanza_attach_publish_options(xmpp_ctx_t* const ctx, xmpp_stanza_t* const iq, co
 }
 
 void
+stanza_attach_publish_options(xmpp_ctx_t* const ctx, xmpp_stanza_t* const iq, const char* const option, const char* const value)
+{
+    stanza_attach_publish_options_va(ctx, iq, 2, option, value);
+}
+
+
+void
 stanza_attach_priority(xmpp_ctx_t* const ctx, xmpp_stanza_t* const presence, const int pri)
 {
     if (pri == 0) {
diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h
index e35b4bcc..a4ac6b33 100644
--- a/src/xmpp/stanza.h
+++ b/src/xmpp/stanza.h
@@ -326,7 +326,9 @@ xmpp_stanza_t* stanza_create_room_kick_iq(xmpp_ctx_t* const ctx, const char* con
 xmpp_stanza_t* stanza_create_command_exec_iq(xmpp_ctx_t* ctx, const char* const target, const char* const node);
 xmpp_stanza_t* stanza_create_command_config_submit_iq(xmpp_ctx_t* ctx, const char* const room, const char* const node, const char* const sessionid, DataForm* form);
 
-void stanza_attach_publish_options(xmpp_ctx_t* const ctx, xmpp_stanza_t* const publish, const char* const option, const char* const value);
+void stanza_attach_publish_options_va(xmpp_ctx_t* const ctx, xmpp_stanza_t* const iq, int count, ...);
+void stanza_attach_publish_options(xmpp_ctx_t* const ctx, xmpp_stanza_t* const iq, const char* const option, const char* const value);
+
 
 xmpp_stanza_t* stanza_create_omemo_devicelist_request(xmpp_ctx_t* ctx, const char* const id, const char* const jid);
 xmpp_stanza_t* stanza_create_omemo_devicelist_subscribe(xmpp_ctx_t* ctx, const char* const jid);