mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 16:55:10 +00:00
[MOD/WIP] Continue XEP-0421
This commit is contained in:
parent
63c1bc819e
commit
c9f8d69802
8 changed files with 120 additions and 66 deletions
|
|
@ -515,7 +515,7 @@ XMPPSendDisco(XMPPComponent *jabber, char *from, char *to)
|
|||
pthread_mutex_unlock(&jabber->write_lock);
|
||||
XMLFreeElement(iq);
|
||||
|
||||
ret = ParseeAwaitStanza(identifier, 250);
|
||||
ret = ParseeAwaitStanza(identifier, 5000);
|
||||
Free(identifier);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,12 +43,19 @@ NoflyCallback(XMPPCommandManager *m, char *from, XMLElement *form, XMLElement *o
|
|||
XMLAddAttr(x, "type", "result");
|
||||
{
|
||||
DbRef *ref = DbLock(data->db, 1, "global_bans");
|
||||
HashMap *bans = DbJson(ref);
|
||||
HashMap *bans;
|
||||
char *banned, *reason;
|
||||
JsonValue *ban_val;
|
||||
reported = XMLCreateTag("reported");
|
||||
XMLAddChild(x, reported);
|
||||
|
||||
if (!ref)
|
||||
{
|
||||
ref = DbCreate(data->db, 1, "global_bans");
|
||||
}
|
||||
|
||||
bans = DbJson(ref);
|
||||
|
||||
/* Report */
|
||||
Report("ban", "Banned glob");
|
||||
Report("reason", "Reason for the nofly");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -229,15 +229,6 @@ ParseeXMPPThread(void *argp)
|
|||
XMLElement *
|
||||
ParseeAwaitStanza(char *identifier, int64_t timeout)
|
||||
{
|
||||
XMPPAwait *awa;
|
||||
XMLElement *stanza;
|
||||
struct timespec ts;
|
||||
|
||||
if (!identifier)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* XXX: You may be wondering _why_ I am using stdlib's malloc, instead of
|
||||
* Cytoplasm's Malloc wrapper(which are essentially the same thing, plus
|
||||
* some memchecking as of now), or the stack, as done previously.
|
||||
|
|
@ -246,15 +237,26 @@ ParseeAwaitStanza(char *identifier, int64_t timeout)
|
|||
* since, as I said, it is as of now just malloc with extra metadata prepended
|
||||
* to it. A _guess_ may be that the metadata makes everything unaligned, which,
|
||||
* just sounds silly. pthreads should be able to cope fine with that, I think.
|
||||
* - The stack seems to be a prime candidate to cause a stack corruption, which
|
||||
* puzzled me for a comically long while("why is the value being swapped for
|
||||
* the key?" "why does duplicating twice cause the former problem to disappear,
|
||||
* but still obviously creating another one?", ...).
|
||||
*
|
||||
* I am open to issues talking about such fun behaviour and ideas to fix this.
|
||||
* This is a bodge, and potentially a problem, or vulnerability with Cytoplasm/
|
||||
* Parsee. As long as it isn't "use Rust". Please don't say that. */
|
||||
awa = malloc(sizeof(XMPPAwait));
|
||||
XMPPAwait awa = { 0 };
|
||||
XMLElement *stanza;
|
||||
struct timespec ts;
|
||||
|
||||
if (!identifier)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&await_lock);
|
||||
if (HashMapGet(await_table, identifier))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
pthread_mutex_unlock(&await_lock);
|
||||
|
||||
|
||||
/* Convert into an absolute timeout.
|
||||
* =================================
|
||||
|
|
@ -282,29 +284,24 @@ ParseeAwaitStanza(char *identifier, int64_t timeout)
|
|||
|
||||
pthread_mutex_lock(&await_lock);
|
||||
|
||||
pthread_cond_init(&awa->condition, NULL);
|
||||
pthread_mutex_init(&awa->cond_lock, NULL);
|
||||
awa->stanza = NULL;
|
||||
|
||||
if (HashMapGet(await_table, identifier))
|
||||
{
|
||||
HashMapDelete(await_table, identifier);
|
||||
}
|
||||
pthread_cond_init(&awa.condition, NULL);
|
||||
pthread_mutex_init(&awa.cond_lock, NULL);
|
||||
awa.stanza = NULL;
|
||||
|
||||
HashMapSet(await_table, identifier, awa);
|
||||
HashMapSet(await_table, identifier, &awa);
|
||||
pthread_mutex_unlock(&await_lock);
|
||||
|
||||
pthread_mutex_lock(&awa->cond_lock);
|
||||
while (!awa->stanza)
|
||||
pthread_mutex_lock(&awa.cond_lock);
|
||||
while (!awa.stanza)
|
||||
{
|
||||
int code;
|
||||
|
||||
if (timeout <= 0)
|
||||
{
|
||||
pthread_cond_wait(&awa->condition, &awa->cond_lock);
|
||||
pthread_cond_wait(&awa.condition, &awa.cond_lock);
|
||||
continue;
|
||||
}
|
||||
code = pthread_cond_timedwait(&awa->condition, &awa->cond_lock, &ts);
|
||||
code = pthread_cond_timedwait(&awa.condition, &awa.cond_lock, &ts);
|
||||
if (code == ETIMEDOUT)
|
||||
{
|
||||
/* Timeout detected, give up regardless of the status of our
|
||||
|
|
@ -319,11 +316,10 @@ ParseeAwaitStanza(char *identifier, int64_t timeout)
|
|||
}
|
||||
}
|
||||
|
||||
stanza = awa->stanza;
|
||||
pthread_mutex_unlock(&awa->cond_lock);
|
||||
stanza = awa.stanza;
|
||||
pthread_mutex_unlock(&awa.cond_lock);
|
||||
|
||||
pthread_cond_destroy(&awa->condition);
|
||||
pthread_mutex_destroy(&awa->cond_lock);
|
||||
free(awa);
|
||||
pthread_cond_destroy(&awa.condition);
|
||||
pthread_mutex_destroy(&awa.cond_lock);
|
||||
return stanza;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ IQResult(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
|
|||
mxc = ASUpload(args->config, datastream, length, "image/png");
|
||||
|
||||
jid = ParseeLookupJID(from);
|
||||
from_matrix = ParseeEncodeJID(args->config, jid, false);
|
||||
from_matrix = ParseeGetBridgedUser(args, stanza);
|
||||
ASSetAvatar(args->config, from_matrix, mxc);
|
||||
|
||||
JsonValueFree(JsonSet(
|
||||
|
|
|
|||
|
|
@ -148,11 +148,6 @@ MessageStanza(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (ServerHasXEP421(args, HashMapGet(stanza->attrs, "from")))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
to = ParseeDecodeMXID(HashMapGet(stanza->attrs, "to"));
|
||||
decode_from = ParseeLookupJID(from);
|
||||
from_matrix = ParseeEncodeJID(args->config, decode_from, true);
|
||||
|
|
|
|||
|
|
@ -76,8 +76,7 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
|
|||
char *from = NULL;
|
||||
char *type = HashMapGet(stanza->attrs, "type");
|
||||
char *room = ParseeGetBridgedRoom(args, stanza);
|
||||
char *decode_from = ParseeLookupJID(oid);
|
||||
char *real_matrix = ParseeDecodeMXID(decode_from);
|
||||
char *decode_from, *real_matrix;
|
||||
char *matrix_user_pl = ParseeEncodeJID(args->config, trim, false);
|
||||
char *affiliation = HashMapGet(item->attrs, "affiliation");
|
||||
int power_level = 0;
|
||||
|
|
@ -85,10 +84,18 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
|
|||
|
||||
Free(trim);
|
||||
|
||||
if (jid)
|
||||
{
|
||||
ParseePushJIDTable(oid, jid);
|
||||
}
|
||||
decode_from = ParseeLookupJID(oid);
|
||||
real_matrix = ParseeDecodeMXID(decode_from);
|
||||
|
||||
if (!real_matrix || *real_matrix != '@')
|
||||
{
|
||||
Free(real_matrix);
|
||||
real_matrix = ParseeEncodeJID(args->config, decode_from, false);
|
||||
/*real_matrix = ParseeEncodeJID(args->config, decode_from, false);*/
|
||||
real_matrix = ParseeGetBridgedUserI(args, stanza, oid);
|
||||
}
|
||||
|
||||
if (StrEquals(affiliation, "owner"))
|
||||
|
|
@ -163,10 +170,6 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
|
|||
}
|
||||
}
|
||||
|
||||
if (jid)
|
||||
{
|
||||
ParseePushJIDTable(oid, jid);
|
||||
}
|
||||
|
||||
Free(from);
|
||||
Free(decode_from);
|
||||
|
|
@ -179,8 +182,7 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
|
|||
{
|
||||
XMLElement *status_data = ArrayGet(status->children, 0);
|
||||
char *decode_from = ParseeLookupJID(oid);
|
||||
char *trimmed = ParseeTrimJID(decode_from);
|
||||
char *from_matrix = ParseeEncodeJID(args->config, trimmed, false);
|
||||
char *from_matrix = ParseeGetBridgedUser(args, stanza);
|
||||
char *status_str = NULL;
|
||||
if (status_data)
|
||||
{
|
||||
|
|
@ -199,7 +201,6 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
|
|||
|
||||
Free(decode_from);
|
||||
Free(from_matrix);
|
||||
Free(trimmed);
|
||||
}
|
||||
if (vc)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -78,4 +78,5 @@ void PresenceStanza(ParseeData *args, XMLElement *stanza);
|
|||
|
||||
bool ServerHasXEP421(ParseeData *data, char *from);
|
||||
|
||||
char * ParseeGetBridgedUser(ParseeData *data, XMLElement *stanza);
|
||||
char * ParseeGetBridgedUserI(ParseeData *data, XMLElement *stanza, char *force);
|
||||
#define ParseeGetBridgedUser(data, stanza) ParseeGetBridgedUserI(data, stanza, NULL)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue