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 + * Copyright (C) 2018 - 2019 Michael Vetter * * 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 + * Copyright (C) 2018 - 2019 Michael Vetter * * This file is part of Profanity. * @@ -38,6 +39,9 @@ #include #include +#include +#include + #ifdef HAVE_LIBMESODE #include #endif @@ -46,7 +50,9 @@ #include #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); - connection_free_uuid(uuid); + gchar *hmac = g_compute_hmac_for_string(G_CHECKSUM_SHA256, + (guchar*)prof_identifier, strlen(prof_identifier), + msgid, strlen(msgid)); - result = result_str->str; - g_string_free(result_str, FALSE); + GString *signature = g_string_new(""); + g_string_printf(signature, "%s%s", msgid, hmac); - return result; + free(msgid); + g_free(hmac); + + 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 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 #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) {}