[MOD/WIP] Continue XEP-0421

This commit is contained in:
LDA 2024-07-19 17:07:13 +02:00
commit c9f8d69802
8 changed files with 120 additions and 66 deletions

View file

@ -3,6 +3,7 @@
#include <Cytoplasm/Memory.h>
#include <Cytoplasm/Str.h>
#include <Cytoplasm/Log.h>
#include <Cytoplasm/Sha.h>
#include <string.h>
@ -116,6 +117,7 @@ ParseeVerifyAllStanza(ParseeData *args, XMLElement *stanza)
return ret;
}
/* TODO: Cache this information. */
bool
ServerHasXEP421(ParseeData *data, char *from)
{
@ -153,32 +155,84 @@ ServerHasXEP421(ParseeData *data, char *from)
Free(server);
return ret;
}
/* Scrambles an Occupant ID so that Matrix can use it for MXIDs.
* Occupant IDs are to be treated as opaque, therefore, we hash them
* into a SHA-256 value
* > "The recipient MUST consider the occupant identifier to be an opaque
* > string.". */
static char *
ScrambleOID(ParseeData *data, char *opaque_oid)
{
unsigned char *raw;
char *sha, *mxid;
const ParseeConfig *c = data->config;
if (!opaque_oid)
{
return NULL;
}
/* Turns this into a 128-byte long, Matrix-safe value. */
raw = Sha256(opaque_oid);
sha = ShaToHex(raw);
Free(raw);
/* TODO: Either mark this specially, or drop Parsee JID flags
* altogether before any 1.0.0 */
mxid = StrConcat(
6,
"@", c->namespace_base, "_l_", sha, ":",
c->homeserver_host
);
Free(sha);
return mxid;
}
/* TODO: Shove that function everywhere one can see fit. */
char *
ParseeGetBridgedUser(ParseeData *data, XMLElement *stanza)
ParseeGetBridgedUserI(ParseeData *data, XMLElement *stanza, char *force)
{
char *user, *xmpp_from, *type;
char *decode_from;
char *decode_from, *occ_id = NULL;
bool is_chat, has_anon = false, is_anon = false;
if (!data || !stanza)
{
return NULL;
}
xmpp_from = HashMapGet(stanza->attrs, "from");
xmpp_from = force ? force : HashMapGet(stanza->attrs, "from");
type = HashMapGet(stanza->attrs, "type");
decode_from = ParseeLookupJID(xmpp_from);
/* TODO: On semi-anonymous MUCs, it might be preferable to use a
* form of the occupant ID as the base, as it is more unique, and
* less prone to trigger the character limit on Matrix.
* I'll need to detect these first....
*
* See: https://xmpp.org/extensions/xep-0421.html */
user = ParseeEncodeJID(
data->config,
decode_from,
StrEquals(type, "chat")
);
is_chat = StrEquals(type, "chat");
if (!is_chat)
{
has_anon = ServerHasXEP421(data, xmpp_from);
is_anon = has_anon && StrEquals(xmpp_from, decode_from);
}
if (is_anon)
{
XMLElement *occupant;
occupant = XMLookForTKV(
stanza, "occupant-id",
"xmlns", "urn:xmpp:occupant-id:0"
);
occ_id = occupant ? HashMapGet(occupant->attrs, "id") : NULL;
}
if (!occ_id)
{
user = ParseeEncodeJID(
data->config,
decode_from,
type ? is_chat : false
);
Free(decode_from);
return user;
}
Free(decode_from);
return user;
return ScrambleOID(data, occ_id);
}