fix: more issue #112 follow-ups (stanza-id disco gate, account sanitizer)
All checks were successful
CI Code / Check spelling (pull_request) Successful in 19s
CI Code / Check coding style (pull_request) Successful in 32s
CI Code / Linux (debian) (pull_request) Successful in 4m50s
CI Code / Linux (ubuntu) (pull_request) Successful in 5m7s
CI Code / Code Coverage (pull_request) Successful in 7m14s
CI Code / Linux (arch) (pull_request) Successful in 10m31s
All checks were successful
CI Code / Check spelling (pull_request) Successful in 19s
CI Code / Check coding style (pull_request) Successful in 32s
CI Code / Linux (debian) (pull_request) Successful in 4m50s
CI Code / Linux (ubuntu) (pull_request) Successful in 5m7s
CI Code / Code Coverage (pull_request) Successful in 7m14s
CI Code / Linux (arch) (pull_request) Successful in 10m31s
- xmpp: gate XEP-0359 stanza-id dedup on disco urn:xmpp:sid:0. Before honoring <stanza-id by='…'/> for archive_id dedup, check that the entity in `by` (or its domain — that's what profanity disco's on connect) announces the namespace; fall back to no-dedup when caps are unknown, matching the XEP §6 disco-gate (#1). - accounts: narrow group-name sanitizer to only the characters GKeyFile actually forbids in group headers (`[`, `]`, `\n`, `\r`); `=` and `#` are valid inside a header and stay (#2). - functional tests cover both branches of the disco gate — replayed stanza-id is flagged as duplicate when sid:0 is announced, and not flagged when it isn't. Refs #112
This commit is contained in:
@@ -43,8 +43,8 @@ _sanitize_account_name(const char* const name)
|
||||
gchar* sanitized = g_strdup(name);
|
||||
gchar* p = sanitized;
|
||||
while (*p) {
|
||||
// GKeyFile special characters: [ ] = # \n \r
|
||||
if (*p == '[' || *p == ']' || *p == '=' || *p == '#' || *p == '\n' || *p == '\r') {
|
||||
// GKeyFile group header forbids these characters.
|
||||
if (*p == '[' || *p == ']' || *p == '\n' || *p == '\r') {
|
||||
*p = '_';
|
||||
}
|
||||
p++;
|
||||
|
||||
@@ -65,6 +65,7 @@ static void _handle_pubsub(xmpp_stanza_t* const stanza, xmpp_stanza_t* const eve
|
||||
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);
|
||||
static gboolean _stanza_id_by_trusted(const char* by);
|
||||
#ifdef HAVE_OMEMO
|
||||
static void _receive_omemo(xmpp_stanza_t* const stanza, ProfMessage* message);
|
||||
#endif
|
||||
@@ -1088,7 +1089,7 @@ _handle_groupchat(xmpp_stanza_t* const stanza)
|
||||
xmpp_stanza_t* stanzaidst = xmpp_stanza_get_child_by_name_and_ns(stanza, STANZA_NAME_STANZA_ID, STANZA_NS_STABLE_ID);
|
||||
if (stanzaidst) {
|
||||
const char* by = xmpp_stanza_get_attribute(stanzaidst, "by");
|
||||
if (by && (g_strcmp0(by, from_jid->barejid) == 0)) {
|
||||
if (by && g_strcmp0(by, from_jid->barejid) == 0 && _stanza_id_by_trusted(by)) {
|
||||
stanzaid = (char*)xmpp_stanza_get_attribute(stanzaidst, STANZA_ATTR_ID);
|
||||
if (stanzaid) {
|
||||
message->stanzaid = strdup(stanzaid);
|
||||
@@ -1397,7 +1398,7 @@ _handle_chat(xmpp_stanza_t* const stanza, gboolean is_mam, gboolean is_carbon, c
|
||||
xmpp_stanza_t* stanzaidst = xmpp_stanza_get_child_by_name_and_ns(stanza, STANZA_NAME_STANZA_ID, STANZA_NS_STABLE_ID);
|
||||
if (stanzaidst) {
|
||||
const char* by = xmpp_stanza_get_attribute(stanzaidst, "by");
|
||||
if (by && equals_our_barejid(by)) {
|
||||
if (by && equals_our_barejid(by) && _stanza_id_by_trusted(by)) {
|
||||
stanzaid = (char*)xmpp_stanza_get_attribute(stanzaidst, STANZA_ATTR_ID);
|
||||
if (stanzaid) {
|
||||
message->stanzaid = strdup(stanzaid);
|
||||
@@ -1735,3 +1736,22 @@ _should_ignore_based_on_silence(xmpp_stanza_t* const stanza)
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// XEP-0359 §6 disco-gate; falls back to domain since that's what disco is run against.
|
||||
static gboolean
|
||||
_stanza_id_by_trusted(const char* by)
|
||||
{
|
||||
if (!by) {
|
||||
return FALSE;
|
||||
}
|
||||
GHashTable* features = connection_get_features(by);
|
||||
if (features && g_hash_table_contains(features, STANZA_NS_STABLE_ID)) {
|
||||
return TRUE;
|
||||
}
|
||||
const char* at = strchr(by, '@');
|
||||
if (!at) {
|
||||
return FALSE;
|
||||
}
|
||||
features = connection_get_features(at + 1);
|
||||
return features && g_hash_table_contains(features, STANZA_NS_STABLE_ID);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user