about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorMichael Vetter <jubalh@iodoru.org>2019-10-21 09:56:15 +0200
committerGitHub <noreply@github.com>2019-10-21 09:56:15 +0200
commitc4a52b13e856ecf6bade35d01aa6a75f4de3e3fc (patch)
tree2eefe61ded353c476a4d3a961929c777c1e68dbf
parent452a9f645e0f6232a03758942e85dcf0109a1ab9 (diff)
parent963ab841b42fdb1d80594b609a589a25b4034aa7 (diff)
downloadprofani-tty-c4a52b13e856ecf6bade35d01aa6a75f4de3e3fc.tar.gz
Merge pull request #1209 from jubalh/feature/xep-0359
XEP-0359
-rw-r--r--src/common.c20
-rw-r--r--src/common.h2
-rw-r--r--src/config/files.h2
-rw-r--r--src/event/server_events.c21
-rw-r--r--src/xmpp/blocking.c6
-rw-r--r--src/xmpp/bookmark.c2
-rw-r--r--src/xmpp/capabilities.c1
-rw-r--r--src/xmpp/connection.c112
-rw-r--r--src/xmpp/connection.h2
-rw-r--r--src/xmpp/iq.c14
-rw-r--r--src/xmpp/jid.c16
-rw-r--r--src/xmpp/message.c48
-rw-r--r--src/xmpp/message.h22
-rw-r--r--src/xmpp/omemo.c10
-rw-r--r--src/xmpp/presence.c10
-rw-r--r--src/xmpp/roster.c8
-rw-r--r--src/xmpp/stanza.c58
-rw-r--r--src/xmpp/xmpp.h26
-rw-r--r--tests/unittests/test_server_events.c1
-rw-r--r--tests/unittests/xmpp/stub_xmpp.c8
20 files changed, 272 insertions, 117 deletions
diff --git a/src/common.c b/src/common.c
index d8ee9915..b4dfa9d4 100644
--- a/src/common.c
+++ b/src/common.c
@@ -489,3 +489,23 @@ get_file_paths_recursive(const char *path, GSList **contents)
         entry = g_dir_read_name(directory);
     }
 }
+
+char*
+get_random_string(int length)
+{
+    GRand *prng;
+    char *rand;
+    char alphabet[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+    rand = calloc(length+1, sizeof(char));
+
+    prng = g_rand_new();
+
+    int i;
+    for (i = 0; i < length; i++) {
+        rand[i] = alphabet[g_rand_int_range(prng, 0, sizeof(alphabet))];
+    }
+    g_rand_free(prng);
+
+    return rand;
+}
diff --git a/src/common.h b/src/common.h
index 6d4ca39c..38ac909b 100644
--- a/src/common.h
+++ b/src/common.h
@@ -103,4 +103,6 @@ int is_regular_file(const char *path);
 int is_dir(const char *path);
 void get_file_paths_recursive(const char *directory, GSList **contents);
 
+char* get_random_string(int length);
+
 #endif
diff --git a/src/config/files.h b/src/config/files.h
index f7dfa29a..16292dc4 100644
--- a/src/config/files.h
+++ b/src/config/files.h
@@ -2,6 +2,7 @@
  * files.h
  *
  * Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
+ * Copyright (C) 2018 - 2019 Michael Vetter <jubalh@idoru.org>
  *
  * This file is part of Profanity.
  *
@@ -43,6 +44,7 @@
 #define FILE_PLUGIN_SETTINGS "plugin_settings"
 #define FILE_PLUGIN_THEMES "plugin_themes"
 #define FILE_CAPSCACHE "capscache"
+#define FILE_PROFANITY_IDENTIFIER "profident"
 
 #define DIR_THEMES "themes"
 #define DIR_ICONS "icons"
diff --git a/src/event/server_events.c b/src/event/server_events.c
index 0417f35d..cdbd5ad5 100644
--- a/src/event/server_events.c
+++ b/src/event/server_events.c
@@ -49,6 +49,7 @@
 #include "event/common.h"
 #include "plugins/plugins.h"
 #include "ui/window_list.h"
+#include "xmpp/xmpp.h"
 #include "xmpp/muc.h"
 #include "xmpp/chat_session.h"
 #include "xmpp/roster_list.h"
@@ -284,6 +285,15 @@ sv_ev_room_history(ProfMessage *message)
     }
 }
 
+static void _log_muc(ProfMessage *message)
+{
+    if (message->enc == PROF_MSG_ENC_OMEMO) {
+        groupchat_log_omemo_msg_in(message->jid->barejid, message->jid->resourcepart, message->plain);
+    } else {
+        groupchat_log_msg_in(message->jid->barejid, message->jid->resourcepart, message->plain);
+    }
+}
+
 void
 sv_ev_room_message(ProfMessage *message)
 {
@@ -294,13 +304,10 @@ sv_ev_room_message(ProfMessage *message)
 
     char *mynick = muc_nick(mucwin->roomjid);
 
-    // only log messages from others. we log our own via mucwin_outgoing_msg()
-    if (g_strcmp0(mynick, message->jid->resourcepart) != 0) {
-        if (message->enc == PROF_MSG_ENC_OMEMO) {
-            groupchat_log_omemo_msg_in(message->jid->barejid, message->jid->resourcepart, message->plain);
-        } else {
-            groupchat_log_msg_in(message->jid->barejid, message->jid->resourcepart, message->plain);
-        }
+    // only log message not coming from this client (but maybe same account, different client)
+    // our messages are logged when outgoing
+    if (!(g_strcmp0(mynick, message->jid->resourcepart) == 0 && message_is_sent_by_us(message))) {
+        _log_muc(message);
     }
 
     char *old_plain = message->plain;
diff --git a/src/xmpp/blocking.c b/src/xmpp/blocking.c
index 5784122e..5690839a 100644
--- a/src/xmpp/blocking.c
+++ b/src/xmpp/blocking.c
@@ -73,7 +73,7 @@ blocking_request(void)
     }
     blocked_ac = autocomplete_new();
 
-    char *id = connection_create_stanza_id("blocked_list_request");
+    char *id = connection_create_stanza_id();
     iq_id_handler_add(id, _blocklist_result_handler, NULL, NULL);
 
     xmpp_ctx_t *ctx = connection_get_ctx();
@@ -115,7 +115,7 @@ blocked_add(char *jid)
 
     xmpp_ctx_t *ctx = connection_get_ctx();
 
-    char *id = connection_create_stanza_id("block");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
 
     xmpp_stanza_t *block = xmpp_stanza_new(ctx);
@@ -151,7 +151,7 @@ blocked_remove(char *jid)
 
     xmpp_ctx_t *ctx = connection_get_ctx();
 
-    char *id = connection_create_stanza_id("unblock");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
 
     xmpp_stanza_t *block = xmpp_stanza_new(ctx);
diff --git a/src/xmpp/bookmark.c b/src/xmpp/bookmark.c
index 89f1db78..a1c945ec 100644
--- a/src/xmpp/bookmark.c
+++ b/src/xmpp/bookmark.c
@@ -331,7 +331,7 @@ _send_bookmarks(void)
 {
     xmpp_ctx_t *ctx = connection_get_ctx();
 
-    char *id = connection_create_stanza_id("bookmarks_update");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
     free(id);
 
diff --git a/src/xmpp/capabilities.c b/src/xmpp/capabilities.c
index 8d66b25a..5216119e 100644
--- a/src/xmpp/capabilities.c
+++ b/src/xmpp/capabilities.c
@@ -102,6 +102,7 @@ caps_init(void)
     g_hash_table_add(prof_features, strdup(STANZA_NS_VERSION));
     g_hash_table_add(prof_features, strdup(STANZA_NS_CHATSTATES));
     g_hash_table_add(prof_features, strdup(STANZA_NS_PING));
+    g_hash_table_add(prof_features, strdup(STANZA_NS_STABLE_ID));
     if (prefs_get_boolean(PREF_RECEIPTS_SEND)) {
         g_hash_table_add(prof_features, strdup(STANZA_NS_RECEIPTS));
     }
diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c
index 46ae1ed8..e121d9a6 100644
--- a/src/xmpp/connection.c
+++ b/src/xmpp/connection.c
@@ -2,6 +2,7 @@
  * connection.c
  *
  * Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
+ * Copyright (C) 2018 - 2019 Michael Vetter <jubalh@idoru.org>
  *
  * This file is part of Profanity.
  *
@@ -38,6 +39,9 @@
 #include <string.h>
 #include <assert.h>
 
+#include <glib.h>
+#include <glib/gstdio.h>
+
 #ifdef HAVE_LIBMESODE
 #include <mesode.h>
 #endif
@@ -46,7 +50,9 @@
 #include <strophe.h>
 #endif
 
+#include "common.h"
 #include "log.h"
+#include "config/files.h"
 #include "config/preferences.h"
 #include "event/server_events.h"
 #include "xmpp/connection.h"
@@ -69,6 +75,8 @@ typedef struct prof_conn_t {
 } ProfConnection;
 
 static ProfConnection conn;
+static gchar *profanity_instance_id = NULL;
+static gchar *prof_identifier = NULL;
 
 static xmpp_log_t* _xmpp_get_file_logger(void);
 static void _xmpp_file_logger(void *const userdata, const xmpp_log_level_t level, const char *const area, const char *const msg);
@@ -81,6 +89,10 @@ TLSCertificate* _xmppcert_to_profcert(xmpp_tlscert_t *xmpptlscert);
 static int _connection_certfail_cb(xmpp_tlscert_t *xmpptlscert, const char *const errormsg);
 #endif
 
+static void _random_bytes_init(void);
+static void _random_bytes_close(void);
+static void _compute_identifier(const char *barejid);
+
 void
 connection_init(void)
 {
@@ -95,6 +107,8 @@ connection_init(void)
     conn.features_by_jid = NULL;
     conn.available_resources = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)resource_destroy);
     conn.requested_features = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
+
+	_random_bytes_init();
 }
 
 void
@@ -113,6 +127,8 @@ connection_shutdown(void)
 
     free(conn.xmpp_log);
     conn.xmpp_log = NULL;
+
+	_random_bytes_close();
 }
 
 jabber_conn_status_t
@@ -128,6 +144,8 @@ connection_connect(const char *const jid, const char *const passwd, const char *
         conn.conn_status = JABBER_DISCONNECTED;
         return conn.conn_status;
     }
+
+    _compute_identifier(jidp->barejid);
     jid_destroy(jidp);
 
     log_info("Connecting as %s", jid);
@@ -227,6 +245,9 @@ connection_disconnect(void)
             conn.xmpp_ctx = NULL;
         }
     }
+
+    free(prof_identifier);
+    prof_identifier = NULL;
 }
 
 void
@@ -436,24 +457,28 @@ connection_free_uuid(char *uuid)
 }
 
 char*
-connection_create_stanza_id(char *prefix)
+connection_create_stanza_id(void)
 {
-    char *result = NULL;
-    GString *result_str = g_string_new("");
-    char *uuid = connection_create_uuid();
+    char *msgid = get_random_string(10);
 
-    if (prefix) {
-        g_string_printf(result_str, "prof_%s_%s", prefix, uuid);
-    } else {
-        g_string_printf(result_str, "prof_%s", uuid);
-    }
+    assert(msgid != NULL);
+
+    gchar *hmac = g_compute_hmac_for_string(G_CHECKSUM_SHA256,
+            (guchar*)prof_identifier, strlen(prof_identifier),
+            msgid, strlen(msgid));
 
-    connection_free_uuid(uuid);
+    GString *signature = g_string_new("");
+    g_string_printf(signature, "%s%s", msgid, hmac);
 
-    result = result_str->str;
-    g_string_free(result_str, FALSE);
+    free(msgid);
+    g_free(hmac);
 
-    return result;
+    char *b64 = g_base64_encode((unsigned char*)signature->str, signature->len);
+    g_string_free(signature, TRUE);
+
+    assert(b64 != NULL);
+
+    return b64;
 }
 
 char*
@@ -605,3 +630,64 @@ _xmpp_file_logger(void *const userdata, const xmpp_log_level_t xmpp_level, const
         sv_ev_xmpp_stanza(msg);
     }
 }
+
+static void _random_bytes_init(void)
+{
+    char *rndbytes_loc;
+    GKeyFile *rndbytes;
+
+    rndbytes_loc = files_get_data_path(FILE_PROFANITY_IDENTIFIER);
+
+    if (g_file_test(rndbytes_loc, G_FILE_TEST_EXISTS)) {
+        g_chmod(rndbytes_loc, S_IRUSR | S_IWUSR);
+    }
+
+    rndbytes = g_key_file_new();
+    g_key_file_load_from_file(rndbytes, rndbytes_loc, G_KEY_FILE_KEEP_COMMENTS, NULL);
+
+    if (g_key_file_has_group(rndbytes, "identifier")) {
+        profanity_instance_id = g_key_file_get_string(rndbytes, "identifier", "random_bytes", NULL);
+    } else {
+        profanity_instance_id = get_random_string(10);
+        g_key_file_set_string(rndbytes, "identifier", "random_bytes", profanity_instance_id);
+
+        gsize g_data_size;
+        gchar *g_accounts_data = g_key_file_to_data(rndbytes, &g_data_size, NULL);
+
+        gchar *base = g_path_get_basename(rndbytes_loc);
+        gchar *true_loc = get_file_or_linked(rndbytes_loc, base);
+        g_file_set_contents(true_loc, g_accounts_data, g_data_size, NULL);
+
+        g_free(base);
+        free(true_loc);
+        g_free(g_accounts_data);
+    }
+
+    free(rndbytes_loc);
+    g_key_file_free(rndbytes);
+}
+
+static void _random_bytes_close(void)
+{
+    g_free(profanity_instance_id);
+}
+
+static void _compute_identifier(const char *barejid)
+{
+    gchar *hmac = g_compute_hmac_for_string(G_CHECKSUM_SHA256,
+            (guchar*)profanity_instance_id, strlen(profanity_instance_id),
+            barejid, strlen(barejid));
+
+    char *b64 = g_base64_encode((guchar*)hmac, XMPP_SHA1_DIGEST_SIZE);
+    assert(b64 != NULL);
+    g_free(hmac);
+
+    //in case of reconnect (lost connection)
+    free(prof_identifier);
+
+    prof_identifier = b64;
+}
+
+char *connection_get_profanity_identifier(void) {
+    return prof_identifier;
+}
diff --git a/src/xmpp/connection.h b/src/xmpp/connection.h
index 044cf368..3f15df82 100644
--- a/src/xmpp/connection.h
+++ b/src/xmpp/connection.h
@@ -62,6 +62,6 @@ void connection_clear_data(void);
 void connection_add_available_resource(Resource *resource);
 void connection_remove_available_resource(const char *const resource);
 
-char* connection_create_stanza_id(char *prefix);
+char* connection_create_stanza_id(void);
 
 #endif
diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c
index 93ab8553..6138cfc0 100644
--- a/src/xmpp/iq.c
+++ b/src/xmpp/iq.c
@@ -349,7 +349,7 @@ iq_room_list_request(gchar *conferencejid, gchar *filter)
     log_debug("Rooms request not cached for: %s", conferencejid);
 
     xmpp_ctx_t * const ctx = connection_get_ctx();
-    char *id = connection_create_stanza_id("confreq");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = stanza_create_disco_items_iq(ctx, id, conferencejid, NULL);
 
     iq_id_handler_add(id, _room_list_id_handler, NULL, filter);
@@ -394,7 +394,7 @@ iq_http_upload_request(HTTPUpload *upload)
     }
 
     xmpp_ctx_t * const ctx = connection_get_ctx();
-    char *id = connection_create_stanza_id("http_upload_request");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = stanza_create_http_upload_request(ctx, id, jid, upload);
     // TODO add free func
     iq_id_handler_add(id, _http_upload_response_id_handler, NULL, upload);
@@ -410,7 +410,7 @@ void
 iq_disco_info_request(gchar *jid)
 {
     xmpp_ctx_t * const ctx = connection_get_ctx();
-    char *id = connection_create_stanza_id("disco_info");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, jid, NULL);
 
     iq_id_handler_add(id, _disco_info_response_id_handler, NULL, NULL);
@@ -425,7 +425,7 @@ void
 iq_disco_info_request_onconnect(gchar *jid)
 {
     xmpp_ctx_t * const ctx = connection_get_ctx();
-    char *id = connection_create_stanza_id("disco_info_onconnect");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, jid, NULL);
 
     iq_id_handler_add(id, _disco_info_response_id_handler_onconnect, NULL, NULL);
@@ -440,7 +440,7 @@ void
 iq_last_activity_request(gchar *jid)
 {
     xmpp_ctx_t * const ctx = connection_get_ctx();
-    char *id = connection_create_stanza_id("lastactivity");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = stanza_create_last_activity_iq(ctx, id, jid);
 
     iq_id_handler_add(id, _last_activity_response_id_handler, NULL, NULL);
@@ -455,7 +455,7 @@ void
 iq_room_info_request(const char *const room, gboolean display_result)
 {
     xmpp_ctx_t * const ctx = connection_get_ctx();
-    char *id = connection_create_stanza_id("room_disco_info");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = stanza_create_disco_info_iq(ctx, id, room, NULL);
 
     ProfRoomInfoData *cb_data = malloc(sizeof(ProfRoomInfoData));
@@ -731,7 +731,7 @@ void
 iq_command_list(const char *const target)
 {
     xmpp_ctx_t * const ctx = connection_get_ctx();
-    const char *id = connection_create_stanza_id("cmdlist");
+    const char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = stanza_create_disco_items_iq(ctx, id, target, STANZA_NS_COMMAND);
 
     iq_id_handler_add(id, _command_list_result_handler, NULL, NULL);
diff --git a/src/xmpp/jid.c b/src/xmpp/jid.c
index 49bf7b9c..25067050 100644
--- a/src/xmpp/jid.c
+++ b/src/xmpp/jid.c
@@ -198,18 +198,10 @@ jid_fulljid_or_barejid(Jid *jid)
 char*
 jid_random_resource(void)
 {
-    GRand *prng;
-    char rand[5];
-    char alphabet[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+    char *rand = get_random_string(4);
 
-    prng = g_rand_new();
+    gchar *result = g_strdup_printf("profanity.%s", rand);
+    free(rand);
 
-    int i;
-    for (i = 0; i < 4; i++) {
-        rand[i] = alphabet[g_rand_int_range(prng, 0, sizeof(alphabet))];
-    }
-    rand[4] = '\0';
-    g_rand_free(prng);
-
-    return g_strdup_printf("profanity.%s", rand);
+    return result;
 }
diff --git a/src/xmpp/message.c b/src/xmpp/message.c
index 00f5baf3..fb9022dc 100644
--- a/src/xmpp/message.c
+++ b/src/xmpp/message.c
@@ -254,7 +254,7 @@ message_send_chat(const char *const barejid, const char *const msg, const char *
 
     char *state = chat_session_get_state(barejid);
     char *jid = chat_session_get_jid(barejid);
-    char *id = connection_create_stanza_id("msg");
+    char *id = connection_create_stanza_id();
 
     xmpp_stanza_t *message = xmpp_message_new(ctx, STANZA_TYPE_CHAT, jid, id);
     xmpp_message_set_body(message, msg);
@@ -285,7 +285,7 @@ message_send_chat_pgp(const char *const barejid, const char *const msg, gboolean
 
     char *state = chat_session_get_state(barejid);
     char *jid = chat_session_get_jid(barejid);
-    char *id = connection_create_stanza_id("msg");
+    char *id = connection_create_stanza_id();
 
     xmpp_stanza_t *message = NULL;
 #ifdef HAVE_LIBGPGME
@@ -344,7 +344,7 @@ message_send_chat_otr(const char *const barejid, const char *const msg, gboolean
 
     char *state = chat_session_get_state(barejid);
     char *jid = chat_session_get_jid(barejid);
-    char *id = connection_create_stanza_id("msg");
+    char *id = connection_create_stanza_id();
 
     xmpp_stanza_t *message = xmpp_message_new(ctx, STANZA_TYPE_CHAT, barejid, id);
     xmpp_message_set_body(message, msg);
@@ -381,11 +381,11 @@ message_send_chat_omemo(const char *const jid, uint32_t sid, GList *keys,
     char *id;
     xmpp_stanza_t *message;
     if (muc) {
-        id = connection_create_stanza_id("muc");
+        id = connection_create_stanza_id();
         message = xmpp_message_new(ctx, STANZA_TYPE_GROUPCHAT, jid, id);
         stanza_attach_origin_id(ctx, message, id);
     } else {
-        id = connection_create_stanza_id("msg");
+        id = connection_create_stanza_id();
         message = xmpp_message_new(ctx, STANZA_TYPE_CHAT, jid, id);
     }
 
@@ -485,7 +485,7 @@ void
 message_send_private(const char *const fulljid, const char *const msg, const char *const oob_url)
 {
     xmpp_ctx_t * const ctx = connection_get_ctx();
-    char *id = connection_create_stanza_id("prv");
+    char *id = connection_create_stanza_id();
 
     xmpp_stanza_t *message = xmpp_message_new(ctx, STANZA_TYPE_CHAT, fulljid, id);
     xmpp_message_set_body(message, msg);
@@ -504,7 +504,7 @@ char*
 message_send_groupchat(const char *const roomjid, const char *const msg, const char *const oob_url)
 {
     xmpp_ctx_t * const ctx = connection_get_ctx();
-    char *id = connection_create_stanza_id("muc");
+    char *id = connection_create_stanza_id();
 
     xmpp_stanza_t *message = xmpp_message_new(ctx, STANZA_TYPE_GROUPCHAT, roomjid, id);
     stanza_attach_origin_id(ctx, message, id);
@@ -841,7 +841,7 @@ _message_send_receipt(const char *const fulljid, const char *const message_id)
 {
     xmpp_ctx_t * const ctx = connection_get_ctx();
 
-    char *id = connection_create_stanza_id("receipt");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *message = xmpp_message_new(ctx, NULL, fulljid, id);
     free(id);
 
@@ -1158,3 +1158,35 @@ _send_message_stanza(xmpp_stanza_t *const stanza)
     }
     xmpp_free(connection_get_ctx(), text);
 }
+
+bool
+message_is_sent_by_us(ProfMessage *message) {
+    bool ret = FALSE;
+
+    // we check the </origin-id> for this we calculate a hash into it so we can detect
+    // whether this client sent it. See connection_create_stanza_id()
+    if (message && message->id != NULL) {
+        gsize tmp_len;
+        char *tmp = (char*)g_base64_decode(message->id, &tmp_len);
+
+        // our client sents at least 10 for the identifier + random message bytes
+        if (tmp_len > 10) {
+            char *msgid = g_strndup(tmp, 10);
+            char *prof_identifier = connection_get_profanity_identifier();
+
+            gchar *hmac = g_compute_hmac_for_string(G_CHECKSUM_SHA256,
+                    (guchar*)prof_identifier, strlen(prof_identifier),
+                    msgid, strlen(msgid));
+
+            if (g_strcmp0(&tmp[10], hmac) == 0) {
+                ret = TRUE;
+            }
+
+            g_free(msgid);
+            g_free(hmac);
+        }
+        free(tmp);
+    }
+
+    return  ret;
+}
diff --git a/src/xmpp/message.h b/src/xmpp/message.h
index badfba72..7faa45d7 100644
--- a/src/xmpp/message.h
+++ b/src/xmpp/message.h
@@ -37,28 +37,6 @@
 
 #include "xmpp/xmpp.h"
 
-typedef enum {
-    PROF_MSG_ENC_PLAIN,
-    PROF_MSG_ENC_OTR,
-    PROF_MSG_ENC_PGP,
-    PROF_MSG_ENC_OMEMO
-} prof_enc_t;
-
-typedef struct prof_message_t {
-   Jid *jid;
-   char *id;
-   /* The raw body from xmpp message, either plaintext or OTR encrypted text */
-   char *body;
-   /* The encrypted message as for PGP */
-   char *encrypted;
-   /* The message that will be printed on screen and logs */
-   char *plain;
-   GDateTime *timestamp;
-   prof_enc_t enc;
-   gboolean trusted;
-   gboolean mucuser;
-} ProfMessage;
-
 typedef int(*ProfMessageCallback)(xmpp_stanza_t *const stanza, void *const userdata);
 typedef void(*ProfMessageFreeCallback)(void *userdata);
 
diff --git a/src/xmpp/omemo.c b/src/xmpp/omemo.c
index 99f4785d..79d74ffb 100644
--- a/src/xmpp/omemo.c
+++ b/src/xmpp/omemo.c
@@ -40,7 +40,7 @@ void
 omemo_devicelist_request(const char * const jid)
 {
     xmpp_ctx_t * const ctx = connection_get_ctx();
-    char *id = connection_create_stanza_id("devicelist_request");
+    char *id = connection_create_stanza_id();
 
     xmpp_stanza_t *iq = stanza_create_omemo_devicelist_request(ctx, id, jid);
     iq_id_handler_add(id, _omemo_receive_devicelist, NULL, NULL);
@@ -68,7 +68,7 @@ omemo_bundle_publish(gboolean first)
     omemo_signed_prekey_signature(&signed_prekey_signature, &signed_prekey_signature_length);
     omemo_prekeys(&prekeys, &ids, &lengths);
 
-    char *id = connection_create_stanza_id("omemo_bundle_publish");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = stanza_create_omemo_bundle_publish(ctx, id,
         omemo_device_id(), identity_key, identity_key_length, signed_prekey,
         signed_prekey_length, signed_prekey_signature,
@@ -97,7 +97,7 @@ void
 omemo_bundle_request(const char * const jid, uint32_t device_id, ProfIqCallback func, ProfIqFreeCallback free_func, void *userdata)
 {
     xmpp_ctx_t * const ctx = connection_get_ctx();
-    char *id = connection_create_stanza_id("bundle_request");
+    char *id = connection_create_stanza_id();
 
     xmpp_stanza_t *iq = stanza_create_omemo_bundle_request(ctx, id, jid, device_id);
     iq_id_handler_add(id, func, free_func, userdata);
@@ -408,7 +408,7 @@ _omemo_bundle_publish_result(xmpp_stanza_t *const stanza, void *const userdata)
     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("omemo_bundle_node_configure_request");
+    char *id = connection_create_stanza_id();
     char *node = g_strdup_printf("%s:%d", STANZA_NS_OMEMO_BUNDLES, omemo_device_id());
     xmpp_stanza_t *iq = stanza_create_pubsub_configure_request(ctx, id, jid->barejid, node);
     g_free(node);
@@ -441,7 +441,7 @@ _omemo_bundle_publish_configure(xmpp_stanza_t *const stanza, void *const userdat
 
     xmpp_ctx_t * const ctx = connection_get_ctx();
     Jid *jid = jid_create(connection_get_fulljid());
-    char *id = connection_create_stanza_id("omemo_bundle_node_configure_submit");
+    char *id = connection_create_stanza_id();
     char *node = g_strdup_printf("%s:%d", STANZA_NS_OMEMO_BUNDLES, omemo_device_id());
     xmpp_stanza_t *iq = stanza_create_pubsub_configure_submit(ctx, id, jid->barejid, node, form);
     g_free(node);
diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c
index 6d615de4..0468dd3d 100644
--- a/src/xmpp/presence.c
+++ b/src/xmpp/presence.c
@@ -128,7 +128,7 @@ presence_subscription(const char *const jid, const jabber_subscr_t action)
     xmpp_ctx_t * const ctx = connection_get_ctx();
     xmpp_stanza_t *presence = xmpp_presence_new(ctx);
 
-    char *id = connection_create_stanza_id("sub");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_set_id(presence, id);
     free(id);
 
@@ -211,7 +211,7 @@ presence_send(const resource_presence_t presence_type, const int idle, char *sig
     xmpp_ctx_t * const ctx = connection_get_ctx();
     xmpp_stanza_t *presence = xmpp_presence_new(ctx);
 
-    char *id = connection_create_stanza_id("presence");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_set_id(presence, id);
     free(id);
 
@@ -579,7 +579,7 @@ _handle_caps(const char *const jid, XMPPCaps *caps)
                 caps_map_jid_to_ver(jid, caps->ver);
             } else {
                 log_info("Capabilities cache miss: %s, for %s, sending service discovery request", caps->ver, jid);
-                char *id = connection_create_stanza_id("caps");
+                char *id = connection_create_stanza_id();
                 iq_send_caps_request(jid, id, caps->node, caps->ver);
                 free(id);
             }
@@ -588,14 +588,14 @@ _handle_caps(const char *const jid, XMPPCaps *caps)
     // unsupported hash, xep-0115, associate with JID, no cache
     } else if (caps->hash) {
         log_info("Hash %s not supported: %s, sending service discovery request", caps->hash, jid);
-        char *id = connection_create_stanza_id("caps");
+        char *id = connection_create_stanza_id();
         iq_send_caps_request_for_jid(jid, id, caps->node, caps->ver);
         free(id);
 
    // no hash, legacy caps, cache against node#ver
    } else if (caps->node && caps->ver) {
         log_info("No hash specified: %s, legacy request made for %s#%s", jid, caps->node, caps->ver);
-        char *id = connection_create_stanza_id("caps");
+        char *id = connection_create_stanza_id();
         iq_send_caps_request_legacy(jid, id, caps->node, caps->ver);
         free(id);
     } else {
diff --git a/src/xmpp/roster.c b/src/xmpp/roster.c
index adcd447c..e2f4bcca 100644
--- a/src/xmpp/roster.c
+++ b/src/xmpp/roster.c
@@ -88,7 +88,7 @@ void
 roster_send_add_new(const char *const barejid, const char *const name)
 {
     xmpp_ctx_t * const ctx = connection_get_ctx();
-    char *id = connection_create_stanza_id("roster");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = stanza_create_roster_set(ctx, id, barejid, name, NULL);
     free(id);
     iq_send_stanza(iq);
@@ -108,7 +108,7 @@ void
 roster_send_name_change(const char *const barejid, const char *const new_name, GSList *groups)
 {
     xmpp_ctx_t * const ctx = connection_get_ctx();
-    char *id = connection_create_stanza_id("roster");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = stanza_create_roster_set(ctx, id, barejid, new_name, groups);
     free(id);
     iq_send_stanza(iq);
@@ -127,7 +127,7 @@ roster_send_add_to_group(const char *const group, PContact contact)
 
     new_groups = g_slist_append(new_groups, strdup(group));
     // add an id handler to handle the response
-    char *unique_id = connection_create_stanza_id(NULL);
+    char *unique_id = connection_create_stanza_id();
     GroupData *data = malloc(sizeof(GroupData));
     data->group = strdup(group);
     if (p_contact_name(contact)) {
@@ -170,7 +170,7 @@ roster_send_remove_from_group(const char *const group, PContact contact)
     xmpp_ctx_t * const ctx = connection_get_ctx();
 
     // add an id handler to handle the response
-    char *unique_id = connection_create_stanza_id(NULL);
+    char *unique_id = connection_create_stanza_id();
     GroupData *data = malloc(sizeof(GroupData));
     data->group = strdup(group);
     if (p_contact_name(contact)) {
diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c
index a63cfef3..5aa98799 100644
--- a/src/xmpp/stanza.c
+++ b/src/xmpp/stanza.c
@@ -66,7 +66,7 @@
 #include "xmpp/form.h"
 #include "xmpp/muc.h"
 
-static void _stanza_add_unique_id(xmpp_stanza_t *stanza, char *prefix);
+static void _stanza_add_unique_id(xmpp_stanza_t *stanza);
 static char* _stanza_create_sha1_hash(char *str);
 
 #if 0
@@ -134,7 +134,7 @@ xmpp_stanza_t*
 stanza_create_bookmarks_pubsub_add(xmpp_ctx_t *ctx, const char *const jid,
     const gboolean autojoin, const char *const nick)
 {
-    char *id = connection_create_stanza_id("bookmark_add");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *stanza = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
     free(id);
 
@@ -280,7 +280,7 @@ stanza_create_http_upload_request(xmpp_ctx_t *ctx, const char *const id,
 xmpp_stanza_t*
 stanza_enable_carbons(xmpp_ctx_t *ctx)
 {
-    char *id = connection_create_stanza_id("carbons");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
     free(id);
 
@@ -297,7 +297,7 @@ stanza_enable_carbons(xmpp_ctx_t *ctx)
 xmpp_stanza_t*
 stanza_disable_carbons(xmpp_ctx_t *ctx)
 {
-    char *id = connection_create_stanza_id("carbons");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
     free(id);
 
@@ -314,7 +314,7 @@ stanza_disable_carbons(xmpp_ctx_t *ctx)
 xmpp_stanza_t*
 stanza_create_chat_state(xmpp_ctx_t *ctx, const char *const fulljid, const char *const state)
 {
-    char *id = connection_create_stanza_id(NULL);
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *msg = xmpp_message_new(ctx, STANZA_TYPE_CHAT, fulljid, id);
     free(id);
 
@@ -446,7 +446,7 @@ stanza_attach_x_oob_url(xmpp_ctx_t *ctx, xmpp_stanza_t *stanza, const char *cons
 xmpp_stanza_t*
 stanza_create_roster_remove_set(xmpp_ctx_t *ctx, const char *const barejid)
 {
-    char *id = connection_create_stanza_id("roster");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
     free(id);
 
@@ -512,7 +512,7 @@ xmpp_stanza_t*
 stanza_create_invite(xmpp_ctx_t *ctx, const char *const room,
     const char *const contact, const char *const reason, const char *const password)
 {
-    char *id = connection_create_stanza_id(NULL);
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *message = xmpp_message_new(ctx, NULL, contact, id);
     free(id);
 
@@ -538,7 +538,7 @@ xmpp_stanza_t*
 stanza_create_mediated_invite(xmpp_ctx_t *ctx, const char *const room,
     const char *const contact, const char *const reason)
 {
-    char *id = connection_create_stanza_id(NULL);
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *message = xmpp_message_new(ctx, NULL, room, id);
     free(id);
 
@@ -575,7 +575,7 @@ stanza_create_room_join_presence(xmpp_ctx_t *const ctx,
 {
     xmpp_stanza_t *presence = xmpp_presence_new(ctx);
     xmpp_stanza_set_to(presence, full_room_jid);
-    _stanza_add_unique_id(presence, "join");
+    _stanza_add_unique_id(presence);
 
     xmpp_stanza_t *x = xmpp_stanza_new(ctx);
     xmpp_stanza_set_name(x, STANZA_NAME_X);
@@ -603,7 +603,7 @@ stanza_create_room_newnick_presence(xmpp_ctx_t *ctx,
     const char *const full_room_jid)
 {
     xmpp_stanza_t *presence = xmpp_presence_new(ctx);
-    _stanza_add_unique_id(presence, "sub");
+    _stanza_add_unique_id(presence);
     xmpp_stanza_set_to(presence, full_room_jid);
 
     return presence;
@@ -620,7 +620,7 @@ stanza_create_room_leave_presence(xmpp_ctx_t *ctx, const char *const room,
     xmpp_stanza_t *presence = xmpp_presence_new(ctx);
     xmpp_stanza_set_type(presence, STANZA_TYPE_UNAVAILABLE);
     xmpp_stanza_set_to(presence, full_jid->str);
-    _stanza_add_unique_id(presence, "leave");
+    _stanza_add_unique_id(presence);
 
     g_string_free(full_jid, TRUE);
 
@@ -630,7 +630,7 @@ stanza_create_room_leave_presence(xmpp_ctx_t *ctx, const char *const room,
 xmpp_stanza_t*
 stanza_create_instant_room_request_iq(xmpp_ctx_t *ctx, const char *const room_jid)
 {
-    char *id = connection_create_stanza_id("room");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
     free(id);
     xmpp_stanza_set_to(iq, room_jid);
@@ -656,7 +656,7 @@ stanza_create_instant_room_request_iq(xmpp_ctx_t *ctx, const char *const room_ji
 xmpp_stanza_t*
 stanza_create_instant_room_destroy_iq(xmpp_ctx_t *ctx, const char *const room_jid)
 {
-    char *id = connection_create_stanza_id("room");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
     free(id);
     xmpp_stanza_set_to(iq, room_jid);
@@ -680,7 +680,7 @@ stanza_create_instant_room_destroy_iq(xmpp_ctx_t *ctx, const char *const room_ji
 xmpp_stanza_t*
 stanza_create_room_config_request_iq(xmpp_ctx_t *ctx, const char *const room_jid)
 {
-    char *id = connection_create_stanza_id("room");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_GET, id);
     free(id);
     xmpp_stanza_set_to(iq, room_jid);
@@ -698,7 +698,7 @@ stanza_create_room_config_request_iq(xmpp_ctx_t *ctx, const char *const room_jid
 xmpp_stanza_t*
 stanza_create_room_config_cancel_iq(xmpp_ctx_t *ctx, const char *const room_jid)
 {
-    char *id = connection_create_stanza_id("room");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
     free(id);
     xmpp_stanza_set_to(iq, room_jid);
@@ -724,7 +724,7 @@ stanza_create_room_config_cancel_iq(xmpp_ctx_t *ctx, const char *const room_jid)
 xmpp_stanza_t*
 stanza_create_room_affiliation_list_iq(xmpp_ctx_t *ctx, const char *const room, const char *const affiliation)
 {
-    char *id = connection_create_stanza_id("affiliation_get");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_GET, id);
     free(id);
     xmpp_stanza_set_to(iq, room);
@@ -748,7 +748,7 @@ stanza_create_room_affiliation_list_iq(xmpp_ctx_t *ctx, const char *const room,
 xmpp_stanza_t*
 stanza_create_room_role_list_iq(xmpp_ctx_t *ctx, const char *const room, const char *const role)
 {
-    char *id = connection_create_stanza_id("role_get");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_GET, id);
     free(id);
     xmpp_stanza_set_to(iq, room);
@@ -773,7 +773,7 @@ xmpp_stanza_t*
 stanza_create_room_affiliation_set_iq(xmpp_ctx_t *ctx, const char *const room, const char *const jid,
     const char *const affiliation, const char *const reason)
 {
-    char *id = connection_create_stanza_id("affiliation_set");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
     free(id);
     xmpp_stanza_set_to(iq, room);
@@ -811,7 +811,7 @@ xmpp_stanza_t*
 stanza_create_room_role_set_iq(xmpp_ctx_t *const ctx, const char *const room, const char *const nick,
     const char *const role, const char *const reason)
 {
-    char *id = connection_create_stanza_id("role_set");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
     free(id);
     xmpp_stanza_set_to(iq, room);
@@ -849,7 +849,7 @@ xmpp_stanza_t*
 stanza_create_room_kick_iq(xmpp_ctx_t *const ctx, const char *const room, const char *const nick,
     const char *const reason)
 {
-    char *id = connection_create_stanza_id("room_kick");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
     free(id);
     xmpp_stanza_set_to(iq, room);
@@ -886,7 +886,7 @@ stanza_create_room_kick_iq(xmpp_ctx_t *const ctx, const char *const room, const
 xmpp_stanza_t*
 stanza_create_software_version_iq(xmpp_ctx_t *ctx, const char *const fulljid)
 {
-    char *id = connection_create_stanza_id("sv");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_GET, id);
     free(id);
     xmpp_stanza_set_to(iq, fulljid);
@@ -975,7 +975,7 @@ stanza_create_last_activity_iq(xmpp_ctx_t *ctx, const char *const id, const char
 xmpp_stanza_t*
 stanza_create_room_config_submit_iq(xmpp_ctx_t *ctx, const char *const room, DataForm *form)
 {
-    char *id = connection_create_stanza_id("roomconf_submit");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
     free(id);
     xmpp_stanza_set_to(iq, room);
@@ -1052,7 +1052,7 @@ stanza_contains_chat_state(xmpp_stanza_t *stanza)
 xmpp_stanza_t*
 stanza_create_ping_iq(xmpp_ctx_t *ctx, const char *const target)
 {
-    char *id = connection_create_stanza_id("ping");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_GET, id);
     free(id);
     if (target) {
@@ -2122,7 +2122,7 @@ xmpp_stanza_t*
 stanza_create_command_exec_iq(xmpp_ctx_t *ctx, const char *const target,
     const char *const node)
 {
-    char *id = connection_create_stanza_id("cmdexec");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
     free(id);
     xmpp_stanza_set_to(iq, target);
@@ -2144,7 +2144,7 @@ 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)
 {
-    char *id = connection_create_stanza_id("commandconf_submit");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
     free(id);
     xmpp_stanza_set_to(iq, room);
@@ -2194,7 +2194,7 @@ stanza_create_omemo_devicelist_request(xmpp_ctx_t *ctx, const char *const id,
 xmpp_stanza_t*
 stanza_create_omemo_devicelist_subscribe(xmpp_ctx_t *ctx, const char *const jid)
 {
-    char *id = connection_create_stanza_id("omemo_devicelist_subscribe");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
     free(id);
 
@@ -2219,7 +2219,7 @@ stanza_create_omemo_devicelist_subscribe(xmpp_ctx_t *ctx, const char *const jid)
 xmpp_stanza_t*
 stanza_create_omemo_devicelist_publish(xmpp_ctx_t *ctx, GList *const ids)
 {
-    char *id = connection_create_stanza_id("omemo_devicelist_publish");
+    char *id = connection_create_stanza_id();
     xmpp_stanza_t *iq = xmpp_iq_new(ctx, STANZA_TYPE_SET, id);
     free(id);
 
@@ -2457,9 +2457,9 @@ stanza_attach_origin_id(xmpp_ctx_t *ctx, xmpp_stanza_t *stanza, const char *cons
 }
 
 static void
-_stanza_add_unique_id(xmpp_stanza_t *stanza, char *prefix)
+_stanza_add_unique_id(xmpp_stanza_t *stanza)
 {
-    char *id = connection_create_stanza_id(prefix);
+    char *id = connection_create_stanza_id();
     xmpp_stanza_set_id(stanza, id);
     free(id);
 }
diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h
index ae6df097..4a1b9b2a 100644
--- a/src/xmpp/xmpp.h
+++ b/src/xmpp/xmpp.h
@@ -116,6 +116,28 @@ typedef struct disco_item_t {
     char *name;
 } DiscoItem;
 
+typedef enum {
+    PROF_MSG_ENC_PLAIN,
+    PROF_MSG_ENC_OTR,
+    PROF_MSG_ENC_PGP,
+    PROF_MSG_ENC_OMEMO
+} prof_enc_t;
+
+typedef struct prof_message_t {
+   Jid *jid;
+   char *id;
+   /* The raw body from xmpp message, either plaintext or OTR encrypted text */
+   char *body;
+   /* The encrypted message as for PGP */
+   char *encrypted;
+   /* The message that will be printed on screen and logs */
+   char *plain;
+   GDateTime *timestamp;
+   prof_enc_t enc;
+   gboolean trusted;
+   gboolean mucuser;
+} ProfMessage;
+
 void session_init(void);
 jabber_conn_status_t session_connect_with_details(const char *const jid, const char *const passwd,
     const char *const altdomain, const int port, const char *const tls_policy);
@@ -140,6 +162,8 @@ GList* connection_get_available_resources(void);
 gboolean connection_supports(const char *const feature);
 char* connection_jid_for_feature(const char *const feature);
 
+char *connection_get_profanity_identifier(void);
+
 char* message_send_chat(const char *const barejid, const char *const msg, const char *const oob_url,
     gboolean request_receipt);
 char* message_send_chat_otr(const char *const barejid, const char *const msg, gboolean request_receipt);
@@ -154,6 +178,8 @@ void message_send_paused(const char *const jid);
 void message_send_gone(const char *const jid);
 void message_send_invite(const char *const room, const char *const contact, const char *const reason);
 
+bool message_is_sent_by_us(ProfMessage *message);
+
 void presence_subscription(const char *const jid, const jabber_subscr_t action);
 GList* presence_get_subscription_requests(void);
 gint presence_sub_request_count(void);
diff --git a/tests/unittests/test_server_events.c b/tests/unittests/test_server_events.c
index 282c1ffe..54688dec 100644
--- a/tests/unittests/test_server_events.c
+++ b/tests/unittests/test_server_events.c
@@ -7,6 +7,7 @@
 #include <glib.h>
 
 #include "event/server_events.h"
+#include "xmpp/xmpp.h"
 #include "xmpp/roster_list.h"
 #include "xmpp/chat_session.h"
 #include "config/preferences.h"
diff --git a/tests/unittests/xmpp/stub_xmpp.c b/tests/unittests/xmpp/stub_xmpp.c
index 41870d73..9cc60fad 100644
--- a/tests/unittests/xmpp/stub_xmpp.c
+++ b/tests/unittests/xmpp/stub_xmpp.c
@@ -92,6 +92,10 @@ connection_supports(const char *const feature)
     return FALSE;
 }
 
+char *connection_get_profanity_identifier(void) {
+    return "profident";
+}
+
 // message functions
 char* message_send_chat(const char * const barejid, const char * const msg, const char *const oob_url,
     gboolean request_receipt)
@@ -128,6 +132,10 @@ void message_send_gone(const char * const barejid) {}
 void message_send_invite(const char * const room, const char * const contact,
     const char * const reason) {}
 
+bool message_is_sent_by_us(ProfMessage *message) {
+    return TRUE;
+}
+
 // presence functions
 void presence_subscription(const char * const jid, const jabber_subscr_t action) {}