diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index bf960f9e..392e6bb3 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -381,15 +381,17 @@ static const struct cmd_t command_defs[] = { CMD_DESC( "Manage blocked users (XEP-0191), calling with no arguments shows the current list of blocked users. " "To blog a certain user in a MUC use the following as jid: room@conference.example.org/spammy-user" - "It is also possible to block and report (XEP-0377) a user with the report-abuse and report-spam commands.") + "It is also possible to block and report (XEP-0377) a user with the report-abuse and report-spam commands. " + "For spam reporting, please include the content of the spam message as evidence for the service operator.") CMD_ARGS( { "add []", "Block the specified Jabber ID. If in a chat window and no jid is specified, the current recipient will be blocked." }, { "remove ", "Remove the specified Jabber ID from the blocked list." }, - { "report-abuse []", "Report the jid as abuse with an optional message to the service operator." }, - { "report-spam []", "Report the jid as spam with an optional message to the service operator." }) + { "report-abuse []", "Report a user for abuse with an optional description of the behavior." }, + { "report-spam []", "Report a user for spam, including the actual spam message as evidence." }) CMD_EXAMPLES( "/blocked add hel@helheim.edda", - "/blocked report-spam hel@helheim.edda Very annoying guy", + "/blocked report-abuse hel@helheim.edda Harassing me in MUC", + "/blocked report-spam spambot@example.com \"You won a free prize!\"", "/blocked add profanity@rooms.dismail.de/spammy-user") }, diff --git a/src/xmpp/blocking.c b/src/xmpp/blocking.c index 53575e8b..bcb98d9c 100644 --- a/src/xmpp/blocking.c +++ b/src/xmpp/blocking.c @@ -116,9 +116,26 @@ blocked_add(char* jid, blocked_report reportkind, const char* const message) xmpp_stanza_set_attribute(report, STANZA_ATTR_REASON, STANZA_REPORTING_SPAM); } + xmpp_stanza_t* origin = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(origin, STANZA_NAME_REPORT_ORIGIN); + xmpp_stanza_set_attribute(origin, STANZA_ATTR_JID, connection_get_fulljid()); + xmpp_stanza_add_child(report, origin); + xmpp_stanza_release(origin); + + xmpp_stanza_t* third_party = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(third_party, STANZA_NAME_THIRD_PARTY); + xmpp_stanza_set_attribute(third_party, STANZA_ATTR_JID, jid); + xmpp_stanza_add_child(report, third_party); + xmpp_stanza_release(third_party); + if (message) { xmpp_stanza_t* text = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(text, STANZA_NAME_TEXT); + if (reportkind == BLOCKED_REPORT_SPAM) { + xmpp_stanza_set_name(text, STANZA_NAME_BODY); + xmpp_stanza_set_ns(text, "jabber:client"); + } else { + xmpp_stanza_set_name(text, STANZA_NAME_TEXT); + } xmpp_stanza_t* txt = xmpp_stanza_new(ctx); xmpp_stanza_set_text(txt, message); @@ -314,3 +331,83 @@ _blocklist_result_handler(xmpp_stanza_t* const stanza, void* const userdata) return 0; } + +int +reporting_set_handler(xmpp_stanza_t* stanza) +{ + const char* from = xmpp_stanza_get_from(stanza); + xmpp_stanza_t* report = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_REPORTING); + if (!report) { + return 1; + } + + const char* reason = xmpp_stanza_get_attribute(report, STANZA_ATTR_REASON); + const char* display_reason = "unknown"; + if (g_strcmp0(reason, STANZA_REPORTING_SPAM) == 0) { + display_reason = "spam"; + } else if (g_strcmp0(reason, STANZA_REPORTING_ABUSE) == 0) { + display_reason = "abuse"; + } + + char* message = NULL; + xmpp_stanza_t* body = xmpp_stanza_get_child_by_name(report, STANZA_NAME_BODY); + if (body) { + message = xmpp_stanza_get_text(body); + } else { + xmpp_stanza_t* text = xmpp_stanza_get_child_by_name(report, STANZA_NAME_TEXT); + if (text) { + message = xmpp_stanza_get_text(text); + } + } + + // Attempt to find the reported JID if it's wrapped in an item (sync push style) + const char* reported_jid = NULL; + xmpp_stanza_t* block = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_BLOCKING); + if (block) { + xmpp_stanza_t* item = xmpp_stanza_get_child_by_name(block, STANZA_NAME_ITEM); + if (item) { + reported_jid = xmpp_stanza_get_attribute(item, STANZA_ATTR_JID); + } + } + + xmpp_stanza_t* third_party = xmpp_stanza_get_child_by_name(report, STANZA_NAME_THIRD_PARTY); + if (third_party) { + reported_jid = xmpp_stanza_get_attribute(third_party, STANZA_ATTR_JID); + } + + const char* reported_by = NULL; + xmpp_stanza_t* origin = xmpp_stanza_get_child_by_name(report, STANZA_NAME_REPORT_ORIGIN); + if (origin) { + reported_by = xmpp_stanza_get_attribute(origin, STANZA_ATTR_JID); + } + + auto_gchar gchar* report_origin_str = NULL; + if (reported_by) { + report_origin_str = g_strdup_printf(" (origin: %s)", reported_by); + } else { + report_origin_str = g_strdup(""); + } + + if (reported_jid) { + if (message) { + cons_show("Incoming %s report%s from %s: User %s reported for %s. Content: \"%s\"", + display_reason, report_origin_str, from, reported_jid, display_reason, message); + } else { + cons_show("Incoming %s report%s from %s: User %s reported for %s.", + display_reason, report_origin_str, from, reported_jid, display_reason); + } + } else { + if (message) { + cons_show("Incoming %s report%s from %s. Content: \"%s\"", + display_reason, report_origin_str, from, message); + } else { + cons_show("Incoming %s report%s from %s.", display_reason, report_origin_str, from); + } + } + + if (message) { + xmpp_free(xmpp_stanza_get_context(stanza), message); + } + + return 1; +} diff --git a/src/xmpp/blocking.h b/src/xmpp/blocking.h index b45dc9f3..7f0df5b4 100644 --- a/src/xmpp/blocking.h +++ b/src/xmpp/blocking.h @@ -12,5 +12,6 @@ void blocking_request(void); int blocked_set_handler(xmpp_stanza_t* stanza); +int reporting_set_handler(xmpp_stanza_t* stanza); #endif diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 1bb2bb64..bbc5b5d4 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -208,6 +208,11 @@ _iq_handler(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* const us blocked_set_handler(stanza); } + xmpp_stanza_t* reporting = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_REPORTING); + if (reporting && (g_strcmp0(type, STANZA_TYPE_SET) == 0)) { + reporting_set_handler(stanza); + } + const char* id = xmpp_stanza_get_id(stanza); if (id) { ProfIqHandler* handler = g_hash_table_lookup(id_handlers, id); diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index 06b65210..e50b5c78 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -96,6 +96,8 @@ #define STANZA_NAME_USERNAME "username" #define STANZA_NAME_PROPOSE "propose" #define STANZA_NAME_REPORT "report" +#define STANZA_NAME_REPORT_ORIGIN "report-origin" +#define STANZA_NAME_THIRD_PARTY "third-party" #define STANZA_NAME_EVENT "event" #define STANZA_NAME_MOOD "mood" #define STANZA_NAME_RECEIVED "received"