about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorPaul Fariello <paul@fariello.eu>2019-03-01 05:10:23 +0220
committerPaul Fariello <paul@fariello.eu>2019-04-10 16:03:50 +0200
commit810ea3222319e349bfc149fd85be470247b66c96 (patch)
treee701635c55f90f7be45758083d06e32df48d27ac /src
parentd871efdcf91cce85e0dcc543d5be51b32871903f (diff)
downloadprofani-tty-810ea3222319e349bfc149fd85be470247b66c96.tar.gz
Follow normal workflow for OMEMO message reception
We try to decrypt all messages, if it's successful we use
sv_ev_incoming_message even for OMEMO messages. We pass an OMEMO
boolean to let UI be aware that message were encrypted.
Diffstat (limited to 'src')
-rw-r--r--src/event/server_events.c2
-rw-r--r--src/event/server_events.h2
-rw-r--r--src/plugins/api.c2
-rw-r--r--src/xmpp/message.c143
-rw-r--r--src/xmpp/omemo.c79
-rw-r--r--src/xmpp/omemo.h1
6 files changed, 110 insertions, 119 deletions
diff --git a/src/event/server_events.c b/src/event/server_events.c
index 69883141..ccb57213 100644
--- a/src/event/server_events.c
+++ b/src/event/server_events.c
@@ -442,7 +442,7 @@ _sv_ev_incoming_plain(ProfChatWin *chatwin, gboolean new_win, char *barejid, cha
 }
 
 void
-sv_ev_incoming_message(char *barejid, char *resource, char *message, char *pgp_message, GDateTime *timestamp)
+sv_ev_incoming_message(char *barejid, char *resource, char *message, char *pgp_message, GDateTime *timestamp, gboolean omemo)
 {
     gboolean new_win = FALSE;
     ProfChatWin *chatwin = wins_get_chat(barejid);
diff --git a/src/event/server_events.h b/src/event/server_events.h
index cc261487..b12ac94c 100644
--- a/src/event/server_events.h
+++ b/src/event/server_events.h
@@ -49,7 +49,7 @@ void sv_ev_room_history(const char *const room_jid, const char *const nick,
     GDateTime *timestamp, const char *const message);
 void sv_ev_room_message(const char *const room_jid, const char *const nick,
     const char *const message);
-void sv_ev_incoming_message(char *barejid, char *resource, char *message, char *pgp_message, GDateTime *timestamp);
+void sv_ev_incoming_message(char *barejid, char *resource, char *message, char *pgp_message, GDateTime *timestamp, gboolean omemo);
 void sv_ev_incoming_private_message(const char *const fulljid, char *message);
 void sv_ev_delayed_private_message(const char *const fulljid, char *message, GDateTime *timestamp);
 void sv_ev_typing(char *barejid, char *resource);
diff --git a/src/plugins/api.c b/src/plugins/api.c
index 4d8434e1..fc47f193 100644
--- a/src/plugins/api.c
+++ b/src/plugins/api.c
@@ -473,7 +473,7 @@ api_settings_int_set(const char *const group, const char *const key, int value)
 void
 api_incoming_message(const char *const barejid, const char *const resource, const char *const message)
 {
-    sv_ev_incoming_message((char*)barejid, (char*)resource, (char*)message, NULL, NULL);
+    sv_ev_incoming_message((char*)barejid, (char*)resource, (char*)message, NULL, NULL, FALSE);
 
     // TODO handle all states
     sv_ev_activity((char*)barejid, (char*)resource, FALSE);
diff --git a/src/xmpp/message.c b/src/xmpp/message.c
index a2911e0d..08ff4530 100644
--- a/src/xmpp/message.c
+++ b/src/xmpp/message.c
@@ -64,6 +64,7 @@
 #include "xmpp/xmpp.h"
 
 #ifdef HAVE_OMEMO
+#include "xmpp/omemo.h"
 #include "omemo/omemo.h"
 #endif
 
@@ -82,7 +83,6 @@ 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_chat(xmpp_stanza_t *const stanza);
-static void _handle_omemo(xmpp_stanza_t *const stanza);
 
 static void _send_message_stanza(xmpp_stanza_t *const stanza);
 
@@ -150,13 +150,6 @@ _message_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *con
         }
     }
 
-#ifdef HAVE_OMEMO
-    xmpp_stanza_t *omemo = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_OMEMO);
-    if (omemo) {
-        _handle_omemo(stanza);
-    }
-#endif
-
     _handle_chat(stanza);
 
     return 1;
@@ -327,7 +320,7 @@ message_send_chat_omemo(const char *const jid, uint32_t sid, GList *keys,
     const unsigned char *const ciphertext, size_t ciphertext_len,
     gboolean request_receipt)
 {
-    char *state = chat_session_get_state(barejid);
+    char *state = chat_session_get_state(jid);
     xmpp_ctx_t * const ctx = connection_get_ctx();
     char *id = connection_create_stanza_id("msg");
 
@@ -932,6 +925,7 @@ _handle_carbons(xmpp_stanza_t *const stanza)
 static void
 _handle_chat(xmpp_stanza_t *const stanza)
 {
+    char *message = NULL;
     // ignore if type not chat or absent
     const char *type = xmpp_stanza_get_type(stanza);
     if (!(g_strcmp0(type, "chat") == 0 || type == NULL)) {
@@ -944,11 +938,17 @@ _handle_chat(xmpp_stanza_t *const stanza)
         return;
     }
 
+    // check omemo encryption
+    gboolean omemo = FALSE;
+#ifdef HAVE_OMEMO
+    message = omemo_receive_message(stanza);
+    omemo = message != NULL;
+#endif
+
     // ignore handled namespaces
     xmpp_stanza_t *conf = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CONFERENCE);
     xmpp_stanza_t *captcha = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CAPTCHA);
-    xmpp_stanza_t *omemo = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_OMEMO);
-    if (conf || captcha || omemo) {
+    if (conf || captcha) {
         return;
     }
 
@@ -974,19 +974,24 @@ _handle_chat(xmpp_stanza_t *const stanza)
     // standard chat message, use jid without resource
     xmpp_ctx_t *ctx = connection_get_ctx();
     GDateTime *timestamp = stanza_get_delay(stanza);
-    if (body) {
-        char *message = xmpp_stanza_get_text(body);
-        if (message) {
-            char *enc_message = NULL;
-            xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_ENCRYPTED);
-            if (x) {
-                enc_message = xmpp_stanza_get_text(x);
-            }
-            sv_ev_incoming_message(jid->barejid, jid->resourcepart, message, enc_message, timestamp);
-            xmpp_free(ctx, enc_message);
+    if (!message && body) {
+        message = xmpp_stanza_get_text(body);
+    }
 
-            _receipt_request_handler(stanza);
+    if (message) {
+        char *enc_message = NULL;
+        xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_ENCRYPTED);
+        if (x) {
+            enc_message = xmpp_stanza_get_text(x);
+        }
+        sv_ev_incoming_message(jid->barejid, jid->resourcepart, message, enc_message, timestamp, omemo);
+        xmpp_free(ctx, enc_message);
 
+        _receipt_request_handler(stanza);
+
+        if (omemo) {
+            free(message);
+        } else {
             xmpp_free(ctx, message);
         }
     }
@@ -1017,100 +1022,6 @@ _handle_chat(xmpp_stanza_t *const stanza)
 }
 
 static void
-_handle_omemo(xmpp_stanza_t *const stanza)
-{
-    xmpp_stanza_t *encrypted = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_OMEMO);
-    if (!encrypted) {
-        return;
-    }
-
-    xmpp_stanza_t *header = xmpp_stanza_get_child_by_name(encrypted, "header");
-    if (!header) {
-        return;
-    }
-
-    const char *sid_text = xmpp_stanza_get_attribute(header, "sid");
-    if (!sid_text) {
-        return;
-    }
-    uint32_t sid = strtoul(sid_text, NULL, 10);
-
-    xmpp_stanza_t *iv = xmpp_stanza_get_child_by_name(header, "iv");
-    if (!iv) {
-        return;
-    }
-    const char *iv_text = xmpp_stanza_get_text(iv);
-    if (!iv_text) {
-        return;
-    }
-    size_t iv_len;
-    const unsigned char *iv_raw = g_base64_decode(iv_text, &iv_len);
-
-    xmpp_stanza_t *payload = xmpp_stanza_get_child_by_name(encrypted, "payload");
-    if (!payload) {
-        return;
-    }
-    const char *payload_text = xmpp_stanza_get_text(payload);
-    if (!payload_text) {
-        return;
-    }
-    size_t payload_len;
-    const unsigned char *payload_raw = g_base64_decode(payload_text, &payload_len);
-
-    GList *keys = NULL;
-    xmpp_stanza_t *key_stanza;
-    for (key_stanza = xmpp_stanza_get_children(header); key_stanza != NULL; key_stanza = xmpp_stanza_get_next(key_stanza)) {
-        if (g_strcmp0(xmpp_stanza_get_name(key_stanza), "key") != 0) {
-            continue;
-        }
-
-        omemo_key_t *key = malloc(sizeof(omemo_key_t));
-        const char *key_text = xmpp_stanza_get_text(key_stanza);
-        if (!key_text) {
-            goto skip;
-        }
-
-
-        const char *rid_text = xmpp_stanza_get_attribute(key_stanza, "rid");
-        key->device_id = strtoul(rid_text, NULL, 10);
-        if (!key->device_id) {
-            goto skip;
-        }
-        key->data = g_base64_decode(key_text, &key->length);
-        key->prekey = g_strcmp0(xmpp_stanza_get_attribute(key_stanza, "prekey"), "true") == 0;
-        keys = g_list_append(keys, key);
-        continue;
-
-skip:
-        free(key);
-    }
-
-    const char *from = xmpp_stanza_get_from(stanza);
-    Jid *jid = jid_create(from);
-    GDateTime *timestamp = stanza_get_delay(stanza);
-
-    char *plaintext = omemo_on_message_recv(jid->barejid, sid, iv_raw, iv_len, keys, payload_raw, payload_len);
-    if (!plaintext) {
-        goto out;
-    }
-
-    gboolean new_win = FALSE;
-    ProfChatWin *chatwin = wins_get_chat(jid->barejid);
-    if (!chatwin) {
-        ProfWin *window = wins_new_chat(jid->barejid);
-        chatwin = (ProfChatWin*)window;
-        new_win = TRUE;
-    }
-
-    chat_log_omemo_msg_in(jid->barejid, plaintext, timestamp);
-    chatwin_incoming_msg(chatwin, jid->resourcepart, plaintext, timestamp, new_win, PROF_MSG_OMEMO);
-
-out:
-    jid_destroy(jid);
-    if (timestamp) g_date_time_unref(timestamp);
-}
-
-static void
 _send_message_stanza(xmpp_stanza_t *const stanza)
 {
     char *text;
diff --git a/src/xmpp/omemo.c b/src/xmpp/omemo.c
index 048126fa..25057d55 100644
--- a/src/xmpp/omemo.c
+++ b/src/xmpp/omemo.c
@@ -191,6 +191,85 @@ omemo_start_device_session_handle_bundle(xmpp_stanza_t *const stanza, void *cons
     return 1;
 }
 
+char *
+omemo_receive_message(xmpp_stanza_t *const stanza)
+{
+    xmpp_stanza_t *encrypted = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_OMEMO);
+    if (!encrypted) {
+        return NULL;
+    }
+
+    xmpp_stanza_t *header = xmpp_stanza_get_child_by_name(encrypted, "header");
+    if (!header) {
+        return NULL;
+    }
+
+    const char *sid_text = xmpp_stanza_get_attribute(header, "sid");
+    if (!sid_text) {
+        return NULL;
+    }
+    uint32_t sid = strtoul(sid_text, NULL, 10);
+
+    xmpp_stanza_t *iv = xmpp_stanza_get_child_by_name(header, "iv");
+    if (!iv) {
+        return NULL;
+    }
+    const char *iv_text = xmpp_stanza_get_text(iv);
+    if (!iv_text) {
+        return NULL;
+    }
+    size_t iv_len;
+    const unsigned char *iv_raw = g_base64_decode(iv_text, &iv_len);
+
+    xmpp_stanza_t *payload = xmpp_stanza_get_child_by_name(encrypted, "payload");
+    if (!payload) {
+        return NULL;
+    }
+    const char *payload_text = xmpp_stanza_get_text(payload);
+    if (!payload_text) {
+        return NULL;
+    }
+    size_t payload_len;
+    const unsigned char *payload_raw = g_base64_decode(payload_text, &payload_len);
+
+    GList *keys = NULL;
+    xmpp_stanza_t *key_stanza;
+    for (key_stanza = xmpp_stanza_get_children(header); key_stanza != NULL; key_stanza = xmpp_stanza_get_next(key_stanza)) {
+        if (g_strcmp0(xmpp_stanza_get_name(key_stanza), "key") != 0) {
+            continue;
+        }
+
+        omemo_key_t *key = malloc(sizeof(omemo_key_t));
+        const char *key_text = xmpp_stanza_get_text(key_stanza);
+        if (!key_text) {
+            goto skip;
+        }
+
+
+        const char *rid_text = xmpp_stanza_get_attribute(key_stanza, "rid");
+        key->device_id = strtoul(rid_text, NULL, 10);
+        if (!key->device_id) {
+            goto skip;
+        }
+        key->data = g_base64_decode(key_text, &key->length);
+        key->prekey = g_strcmp0(xmpp_stanza_get_attribute(key_stanza, "prekey"), "true") == 0;
+        keys = g_list_append(keys, key);
+        continue;
+
+skip:
+        free(key);
+    }
+
+    const char *from = xmpp_stanza_get_from(stanza);
+    Jid *jid = jid_create(from);
+
+    char *plaintext = omemo_on_message_recv(jid->barejid, sid, iv_raw, iv_len, keys, payload_raw, payload_len);
+
+    jid_destroy(jid);
+
+    return plaintext;
+}
+
 static int
 _omemo_receive_devicelist(xmpp_stanza_t *const stanza, void *const userdata)
 {
diff --git a/src/xmpp/omemo.h b/src/xmpp/omemo.h
index c384c4f0..81c3b979 100644
--- a/src/xmpp/omemo.h
+++ b/src/xmpp/omemo.h
@@ -8,3 +8,4 @@ void omemo_devicelist_request(const char * const jid);
 void omemo_bundle_publish(void);
 void omemo_bundle_request(const char * const jid, uint32_t device_id, ProfIqCallback func, ProfIqFreeCallback free_func, void *userdata);
 int omemo_start_device_session_handle_bundle(xmpp_stanza_t *const stanza, void *const userdata);
+char * omemo_receive_message(xmpp_stanza_t *const stanza);