diff options
Diffstat (limited to 'src/xmpp')
-rw-r--r-- | src/xmpp/blocking.c | 27 | ||||
-rw-r--r-- | src/xmpp/iq.c | 17 | ||||
-rw-r--r-- | src/xmpp/message.c | 22 | ||||
-rw-r--r-- | src/xmpp/roster_list.c | 24 | ||||
-rw-r--r-- | src/xmpp/roster_list.h | 1 | ||||
-rw-r--r-- | src/xmpp/stanza.c | 51 | ||||
-rw-r--r-- | src/xmpp/stanza.h | 7 | ||||
-rw-r--r-- | src/xmpp/xmpp.h | 9 |
8 files changed, 150 insertions, 8 deletions
diff --git a/src/xmpp/blocking.c b/src/xmpp/blocking.c index 34614679..b16f95cb 100644 --- a/src/xmpp/blocking.c +++ b/src/xmpp/blocking.c @@ -109,7 +109,7 @@ blocked_ac_reset(void) } gboolean -blocked_add(char* jid) +blocked_add(char* jid, blocked_report reportkind, const char* const message) { GList* found = g_list_find_custom(blocked, jid, (GCompareFunc)g_strcmp0); if (found) { @@ -129,6 +129,31 @@ blocked_add(char* jid) xmpp_stanza_set_name(item, STANZA_NAME_ITEM); xmpp_stanza_set_attribute(item, STANZA_ATTR_JID, jid); + if (reportkind != BLOCKED_NO_REPORT) { + xmpp_stanza_t* report = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(report, STANZA_NAME_REPORT); + if (reportkind == BLOCKED_REPORT_ABUSE) { + xmpp_stanza_set_attribute(report, STANZA_ATTR_REASON, STANZA_REPORTING_ABUSE); + } else { + xmpp_stanza_set_attribute(report, STANZA_ATTR_REASON, STANZA_REPORTING_SPAM); + } + + if (message) { + xmpp_stanza_t* text = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(text, STANZA_NAME_TEXT); + + xmpp_stanza_t* txt = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(txt, message); + + xmpp_stanza_add_child(text, txt); + xmpp_stanza_add_child(report, text); + xmpp_stanza_release(txt); + } + + xmpp_stanza_add_child(item, report); + xmpp_stanza_release(report); + } + xmpp_stanza_add_child(block, item); xmpp_stanza_release(item); diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index beecb97e..42571b9c 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -1385,7 +1385,7 @@ _autoping_timed_send(xmpp_conn_t* const conn, void* const userdata) if (connection_supports(XMPP_FEATURE_PING) == FALSE) { log_warning("Server doesn't advertise %s feature, disabling autoping.", XMPP_FEATURE_PING); prefs_set_autoping(0); - cons_show_error("Server ping not supported, autoping disabled."); + cons_show_error("Server ping not supported (%s), autoping disabled.", XMPP_FEATURE_PING); xmpp_conn_t* conn = connection_get_conn(); xmpp_timed_handler_delete(conn, _autoping_timed_send); return 1; @@ -2308,6 +2308,8 @@ _disco_info_response_id_handler(xmpp_stanza_t* const stanza, void* const userdat GSList* features = NULL; while (child) { const char* stanza_name = xmpp_stanza_get_name(child); + const char* child_type = xmpp_stanza_get_type(child); + if (g_strcmp0(stanza_name, STANZA_NAME_FEATURE) == 0) { const char* var = xmpp_stanza_get_attribute(child, STANZA_ATTR_VAR); if (var) { @@ -2315,10 +2317,9 @@ _disco_info_response_id_handler(xmpp_stanza_t* const stanza, void* const userdat } } else if (g_strcmp0(stanza_name, STANZA_NAME_IDENTITY) == 0) { const char* name = xmpp_stanza_get_attribute(child, STANZA_ATTR_NAME); - const char* type = xmpp_stanza_get_type(child); const char* category = xmpp_stanza_get_attribute(child, STANZA_ATTR_CATEGORY); - if (name || category || type) { + if (name || category || child_type) { DiscoIdentity* identity = malloc(sizeof(struct disco_identity_t)); if (identity) { @@ -2332,8 +2333,8 @@ _disco_info_response_id_handler(xmpp_stanza_t* const stanza, void* const userdat } else { identity->category = NULL; } - if (type) { - identity->type = strdup(type); + if (child_type) { + identity->type = strdup(child_type); } else { identity->type = NULL; } @@ -2341,6 +2342,10 @@ _disco_info_response_id_handler(xmpp_stanza_t* const stanza, void* const userdat identities = g_slist_append(identities, identity); } } + } else if (g_strcmp0(child_type, STANZA_TYPE_RESULT) == 0) { + GHashTable *adr = stanza_get_service_contact_addresses(connection_get_ctx(), child); + cons_show_disco_contact_information(adr); + g_hash_table_destroy(adr); } child = xmpp_stanza_get_next(child); @@ -2581,7 +2586,7 @@ iq_mam_request(ProfChatWin* win) { if (connection_supports(XMPP_FEATURE_MAM2) == FALSE) { log_warning("Server doesn't advertise %s feature.", XMPP_FEATURE_MAM2); - cons_show_error("Server doesn't support MAM."); + cons_show_error("Server doesn't support MAM (%s).", XMPP_FEATURE_MAM2); return; } diff --git a/src/xmpp/message.c b/src/xmpp/message.c index 38d3ad49..051d1ece 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -94,6 +94,7 @@ static gboolean _handle_mam(xmpp_stanza_t* const stanza); static void _handle_pubsub(xmpp_stanza_t* const stanza, xmpp_stanza_t* const event); static gboolean _handle_form(xmpp_stanza_t* const stanza); static gboolean _handle_jingle_message(xmpp_stanza_t* const stanza); +static gboolean _should_ignore_based_on_silence(xmpp_stanza_t* const stanza); #ifdef HAVE_LIBGPGME static xmpp_stanza_t* _openpgp_signcrypt(xmpp_ctx_t* ctx, const char* const to, const char* const text); @@ -171,6 +172,11 @@ _message_handler(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* con } else if (type == NULL || g_strcmp0(type, STANZA_TYPE_CHAT) == 0 || g_strcmp0(type, STANZA_TYPE_NORMAL) == 0) { // type: chat, normal (==NULL) + // ignore all messages from JIDs that are not in roster, if 'silence' is set + if (_should_ignore_based_on_silence(stanza)) { + return 1; + } + // XEP-0353: Jingle Message Initiation if (_handle_jingle_message(stanza)) { return 1; @@ -1689,3 +1695,19 @@ _handle_jingle_message(xmpp_stanza_t* const stanza) } return FALSE; } + +static gboolean +_should_ignore_based_on_silence(xmpp_stanza_t* const stanza) +{ + if (prefs_get_boolean(PREF_SILENCE_NON_ROSTER)) { + const char* const from = xmpp_stanza_get_from(stanza); + Jid* from_jid = jid_create(from); + PContact contact = roster_get_contact(from_jid->barejid); + jid_destroy(from_jid); + if (!contact) { + log_debug("[Silence] Ignoring message from: %s", from); + return TRUE; + } + } + return FALSE; +} diff --git a/src/xmpp/roster_list.c b/src/xmpp/roster_list.c index 04d16a17..9d7ac427 100644 --- a/src/xmpp/roster_list.c +++ b/src/xmpp/roster_list.c @@ -171,6 +171,30 @@ roster_get_contact(const char* const barejid) } char* +roster_get_display_name(const char* const barejid) +{ + assert(roster != NULL); + + GString* result = g_string_new(""); + + PContact contact = roster_get_contact(barejid); + if (contact) { + if (p_contact_name(contact)) { + g_string_append(result, p_contact_name(contact)); + } else { + g_string_append(result, barejid); + } + } else { + g_string_append(result, barejid); + } + + char* result_str = result->str; + g_string_free(result, FALSE); + + return result_str; +} + +char* roster_get_msg_display_name(const char* const barejid, const char* const resource) { assert(roster != NULL); diff --git a/src/xmpp/roster_list.h b/src/xmpp/roster_list.h index e47a29cb..f9548d97 100644 --- a/src/xmpp/roster_list.h +++ b/src/xmpp/roster_list.h @@ -70,6 +70,7 @@ GList* roster_get_groups(void); char* roster_group_autocomplete(const char* const search_str, gboolean previous, void* context); char* roster_barejid_autocomplete(const char* const search_str, gboolean previous, void* context); GSList* roster_get_contacts_by_presence(const char* const presence); +char* roster_get_display_name(const char* const barejid); char* roster_get_msg_display_name(const char* const barejid, const char* const resource); gint roster_compare_name(PContact a, PContact b); gint roster_compare_presence(PContact a, PContact b); diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index 235a7dee..604d4003 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -2838,3 +2838,54 @@ stanza_create_muc_register_nick(xmpp_ctx_t* ctx, const char* const id, const cha return iq; } + +static void +_contact_addresses_list_free(GSList* list) +{ + if (list) { + g_slist_free_full(list, g_free); + } +} + +GHashTable* +stanza_get_service_contact_addresses(xmpp_ctx_t* ctx, xmpp_stanza_t* stanza) +{ + GHashTable* addresses = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)_contact_addresses_list_free); + + xmpp_stanza_t* fields = xmpp_stanza_get_children(stanza); + while (fields) { + const char* child_name = xmpp_stanza_get_name(fields); + const char* child_type = xmpp_stanza_get_type(fields); + + if (g_strcmp0(child_name, STANZA_NAME_FIELD) == 0 && g_strcmp0(child_type, STANZA_TYPE_LIST_MULTI) == 0) { + // extract key (eg 'admin-addresses') + const char* var = xmpp_stanza_get_attribute(fields, STANZA_ATTR_VAR ); + + // extract values (a list of contact addresses eg mailto:xmpp@shakespeare.lit, xmpp:admins@shakespeare.lit) + xmpp_stanza_t* values = xmpp_stanza_get_children(fields); + GSList* val_list = NULL; + while (values) { + const char* value_name = xmpp_stanza_get_name(values); + if (value_name && (g_strcmp0(value_name, STANZA_NAME_VALUE) == 0)) { + char* value_text = xmpp_stanza_get_text(values); + if (value_text) { + val_list = g_slist_append(val_list, g_strdup(value_text)); + + xmpp_free(ctx, value_text); + } + } + + values = xmpp_stanza_get_next(values); + } + + // add to list + if (g_slist_length(val_list) > 0) { + g_hash_table_insert(addresses, g_strdup(var), val_list); + } + } + + fields = xmpp_stanza_get_next(fields); + } + + return addresses; +} diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index 5effaf3e..47560ce0 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -122,6 +122,7 @@ #define STANZA_NAME_AFTER "after" #define STANZA_NAME_USERNAME "username" #define STANZA_NAME_PROPOSE "propose" +#define STANZA_NAME_REPORT "report" // error conditions #define STANZA_NAME_BAD_REQUEST "bad-request" @@ -162,6 +163,7 @@ #define STANZA_TYPE_SUBMIT "submit" #define STANZA_TYPE_CANCEL "cancel" #define STANZA_TYPE_MODIFY "modify" +#define STANZA_TYPE_LIST_MULTI "list-multi" #define STANZA_ATTR_TO "to" #define STANZA_ATTR_FROM "from" @@ -244,6 +246,9 @@ #define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo" +#define STANZA_REPORTING_ABUSE "urn:xmpp:reporting:abuse" +#define STANZA_REPORTING_SPAM "urn:xmpp:reporting:spam" + typedef struct caps_stanza_t { char* hash; @@ -388,6 +393,8 @@ char* stanza_get_muc_destroy_reason(xmpp_stanza_t* stanza); const char* stanza_get_actor(xmpp_stanza_t* stanza); char* stanza_get_reason(xmpp_stanza_t* stanza); +GHashTable* stanza_get_service_contact_addresses(xmpp_ctx_t* ctx, xmpp_stanza_t* stanza); + Resource* stanza_resource_from_presence(XMPPPresence* presence); XMPPPresence* stanza_parse_presence(xmpp_stanza_t* stanza, int* err); void stanza_free_presence(XMPPPresence* presence); diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 003c3e07..61c7a642 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -70,6 +70,7 @@ #define XMPP_FEATURE_USER_AVATAR_METADATA_NOTIFY "urn:xmpp:avatar:metadata+notify" #define XMPP_FEATURE_LAST_MESSAGE_CORRECTION "urn:xmpp:message-correct:0" #define XMPP_FEATURE_MAM2 "urn:xmpp:mam:2" +#define XMPP_FEATURE_SPAM_REPORTING "urn:xmpp:reporting:1" typedef enum { JABBER_CONNECTING, @@ -89,6 +90,12 @@ typedef enum { INVITE_MEDIATED } jabber_invite_t; +typedef enum { + BLOCKED_NO_REPORT, + BLOCKED_REPORT_ABUSE, + BLOCKED_REPORT_SPAM +} blocked_report; + typedef struct bookmark_t { char* barejid; @@ -286,7 +293,7 @@ void roster_send_add_new(const char* const barejid, const char* const name); void roster_send_remove(const char* const barejid); GList* blocked_list(void); -gboolean blocked_add(char* jid); +gboolean blocked_add(char* jid, blocked_report reportkind, const char* const message); gboolean blocked_remove(char* jid); char* blocked_ac_find(const char* const search_str, gboolean previous, void* context); void blocked_ac_reset(void); |