diff --git a/src/event/server_events.c b/src/event/server_events.c index 33559230..f8f73d36 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -306,7 +306,7 @@ sv_ev_room_message(ProfMessage *message) // 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))) { + if (!(g_strcmp0(mynick, message->jid->resourcepart) == 0 && message_is_sent_by_us(message, TRUE))) { _log_muc(message); } diff --git a/src/ui/mucwin.c b/src/ui/mucwin.c index 4ffc1759..c08618ad 100644 --- a/src/ui/mucwin.c +++ b/src/ui/mucwin.c @@ -527,7 +527,7 @@ mucwin_incoming_msg(ProfMucWin *mucwin, ProfMessage *message, GSList *mentions, assert(mucwin != NULL); int flags = 0; - if (message_is_sent_by_us(message)) { + if (message_is_sent_by_us(message, TRUE)) { /* Ignore reflection messages */ return; } diff --git a/src/xmpp/message.c b/src/xmpp/message.c index b8a6d3a8..76124ee7 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -186,6 +186,7 @@ message_init(void) message->jid = NULL; message->id = NULL; + message->originid = NULL; message->body = NULL; message->encrypted = NULL; message->plain = NULL; @@ -209,6 +210,10 @@ message_free(ProfMessage *message) xmpp_free(ctx, message->id); } + if (message->originid) { + xmpp_free(ctx, message->originid); + } + if (message->body) { xmpp_free(ctx, message->body); } @@ -748,10 +753,11 @@ _handle_groupchat(xmpp_stanza_t *const stanza) xmpp_ctx_t *ctx = connection_get_ctx(); const char *id = xmpp_stanza_get_id(stanza); + char *originid = NULL; xmpp_stanza_t *origin = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_STABLE_ID); if (origin && g_strcmp0(xmpp_stanza_get_name(origin), STANZA_NAME_ORIGIN_ID) == 0) { - id = xmpp_stanza_get_attribute(origin, STANZA_ATTR_ID); + originid = (char*)xmpp_stanza_get_attribute(origin, STANZA_ATTR_ID); } const char *room_jid = xmpp_stanza_get_from(stanza); @@ -803,6 +809,9 @@ _handle_groupchat(xmpp_stanza_t *const stanza) if (id) { message->id = strdup(id); } + if (originid) { + message->originid = strdup(originid); + } message->body = xmpp_message_get_body(stanza); @@ -1167,33 +1176,46 @@ _send_message_stanza(xmpp_stanza_t *const stanza) xmpp_free(connection_get_ctx(), text); } +/* ckeckOID = true: check origin-id + * checkOID = false: check regular id + */ bool -message_is_sent_by_us(ProfMessage *message) { +message_is_sent_by_us(ProfMessage *message, bool checkOID) { 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); + if (message) { + char *tmp_id = NULL; - // our client sents at least 36 (uuid) + identifier - if (tmp_len > 36) { - char *uuid = g_strndup(tmp, 36); - const char *prof_identifier = connection_get_profanity_identifier(); - - gchar *hmac = g_compute_hmac_for_string(G_CHECKSUM_SHA256, - (guchar*)prof_identifier, strlen(prof_identifier), - uuid, strlen(uuid)); - - if (g_strcmp0(&tmp[36], hmac) == 0) { - ret = TRUE; - } - - g_free(uuid); - g_free(hmac); + if (checkOID && message->originid != NULL) { + tmp_id = message->originid; + } else if (!checkOID && message->id != NULL) { + tmp_id = message->id; + } + + if (tmp_id != NULL) { + gsize tmp_len; + char *tmp = (char*)g_base64_decode(tmp_id, &tmp_len); + + // our client sents at least 36 (uuid) + identifier + if (tmp_len > 36) { + char *uuid = g_strndup(tmp, 36); + const char *prof_identifier = connection_get_profanity_identifier(); + + gchar *hmac = g_compute_hmac_for_string(G_CHECKSUM_SHA256, + (guchar*)prof_identifier, strlen(prof_identifier), + uuid, strlen(uuid)); + + if (g_strcmp0(&tmp[36], hmac) == 0) { + ret = TRUE; + } + + g_free(uuid); + g_free(hmac); + } + free(tmp); } - free(tmp); } return ret; diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 33864d2f..cb5ae9d6 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -126,6 +126,8 @@ typedef enum { typedef struct prof_message_t { Jid *jid; char *id; + /* XEP-0359 */ + char *originid; /* The raw body from xmpp message, either plaintext or OTR encrypted text */ char *body; /* The encrypted message as for PGP */ @@ -178,7 +180,7 @@ 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); +bool message_is_sent_by_us(ProfMessage *message, bool checkOID); void presence_subscription(const char *const jid, const jabber_subscr_t action); GList* presence_get_subscription_requests(void); diff --git a/tests/unittests/xmpp/stub_xmpp.c b/tests/unittests/xmpp/stub_xmpp.c index 85c12667..a9b45321 100644 --- a/tests/unittests/xmpp/stub_xmpp.c +++ b/tests/unittests/xmpp/stub_xmpp.c @@ -132,7 +132,7 @@ 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) { +bool message_is_sent_by_us(ProfMessage *message, bool checkOID) { return TRUE; }