[MOD] Be stringent about OIDs, use fmemopen

This commit is contained in:
LDA 2024-08-29 15:31:11 +02:00
commit 3366fcb759
8 changed files with 76 additions and 122 deletions

View file

@ -19,6 +19,7 @@ ASUpload(const ParseeConfig *c, Stream *from, unsigned int size, char *mime)
HashMap *reply; HashMap *reply;
if (!c || !from) if (!c || !from)
{ {
Log(LOG_ERR, "No ASUpload input (c=%p from=%p)", c, from);
return NULL; return NULL;
} }

View file

@ -7,125 +7,13 @@
#include <string.h> #include <string.h>
typedef struct ReaderCookie {
size_t length;
size_t offset;
char *buffer;
} ReaderCookie;
#define Remaining() (cook->length - cook->offset)
static ssize_t
ReadStreamReader(void *coop, void *to, size_t n)
{
ReaderCookie *cook = coop;
size_t remaining;
if (!cook)
{
return 0;
}
remaining = Remaining();
if (n > remaining)
{
memcpy(to, cook->buffer + cook->offset, remaining);
cook->offset = cook->length;
return remaining;
}
memcpy(to, cook->buffer + cook->offset, n);
cook->offset += n;
return n;
}
static ssize_t
WriteStreamReader(void *coop, void *from, size_t n)
{
/* Writing to a stream reader is silly. */
return 0;
}
static off_t
SeekStreamReader(void *coop, off_t mag, int sgn)
{
ReaderCookie *cook = coop;
if (!cook)
{
return 0;
}
switch (sgn)
{
case SEEK_SET:
if (mag > cook->length)
{
cook->offset = cook->length;
return 0;
}
else if (mag < 0)
{
cook->offset = 0;
return 0;
}
cook->offset = mag;
return 0;
case SEEK_CUR:
cook->offset += mag;
if (cook->offset > cook->length)
{
cook->offset = cook->length;
}
else if (cook->offset < 0)
{
cook->offset = 0;
}
return 0;
case SEEK_END:
cook->offset += cook->length + mag;
if (cook->offset > cook->length)
{
cook->offset = cook->length;
}
else if (cook->offset < 0)
{
cook->offset = 0;
}
return 0;
}
return 0;
}
static int
CloseStreamReader(void *coop)
{
/* Nothing to free as of now. */
if (coop)
{
Free(coop);
}
return 0;
}
const static IoFunctions Functions = {
.read = ReadStreamReader,
.seek = SeekStreamReader,
.write = WriteStreamReader,
.close = CloseStreamReader,
};
Stream * Stream *
StrStreamReaderN(char *buffer, int n) StrStreamReaderN(char *buffer, int n)
{ {
Io *raw_io;
ReaderCookie *cookie;
if (!buffer) if (!buffer)
{ {
return NULL; return NULL;
} }
cookie = Malloc(sizeof(*cookie)); return StreamFile(fmemopen(buffer, n ? n : strlen(buffer), "rb"));
cookie->buffer = buffer;
cookie->length = n ? n : strlen(buffer);
cookie->offset = 0;
raw_io = IoCreate(cookie, Functions);
return StreamIo(raw_io);
} }

View file

@ -43,7 +43,6 @@ AddAdminCallback(XMPPCommandManager *m, char *from, XMLElement *form, XMLElement
ref = DbLock(data->db, 1, "admins"); ref = DbLock(data->db, 1, "admins");
admins = GrabArray(DbJson(ref), 1, "admins"); admins = GrabArray(DbJson(ref), 1, "admins");
ArrayAdd(admins, JsonValueString(glob)); ArrayAdd(admins, JsonValueString(glob));
DbUnlock(data->db, ref); DbUnlock(data->db, ref);
} }

View file

@ -161,7 +161,7 @@ ServerHasXEP421(ParseeData *data, char *from)
* into a SHA-256 value * into a SHA-256 value
* > "The recipient MUST consider the occupant identifier to be an opaque * > "The recipient MUST consider the occupant identifier to be an opaque
* > string.". */ * > string.". */
static char * char *
ScrambleOID(ParseeData *data, char *opaque_oid) ScrambleOID(ParseeData *data, char *opaque_oid)
{ {
char *sha, *mxid; char *sha, *mxid;
@ -226,6 +226,7 @@ ParseeGetBridgedUserI(ParseeData *data, XMLElement *stanza, char *force)
{ {
ParseePushOIDTable(xmpp_from, occ_id); ParseePushOIDTable(xmpp_from, occ_id);
} }
Log(LOG_DEBUG, "Trying Occ ID for %s{%s}", xmpp_from, occ_id);
} }
if (!occ_id) if (!occ_id)

View file

@ -186,6 +186,10 @@ IQResult(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
jid = ParseeLookupJID(from); jid = ParseeLookupJID(from);
from_matrix = ParseeGetBridgedUser(args, stanza); from_matrix = ParseeGetBridgedUser(args, stanza);
Log(LOG_DEBUG,
"Setting the avatar of '%s' to %s",
from_matrix, mxc
);
ASSetAvatar(args->config, from_matrix, mxc); ASSetAvatar(args->config, from_matrix, mxc);
Free(mxc); Free(mxc);
@ -224,12 +228,13 @@ IQResult(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
/* Get the base64, decode it, and shove it in a nicely put /* Get the base64, decode it, and shove it in a nicely put
* MXC address */ * MXC address */
base64 = data->data; base64 = TrimBase64(data->data);
b64len = base64 ? strlen(base64) : 0; b64len = base64 ? strlen(base64) : 0;
length = Base64DecodedSize(base64, b64len); length = Base64DecodedSize(base64, b64len);
bdata = Base64Decode(base64, b64len); bdata = Base64Decode(base64, b64len);
datastream = StrStreamReaderN(bdata, length); datastream = StrStreamReaderN(bdata, length);
Log(LOG_DEBUG, "(%dB @ %p) = %p (%d)", b64len, base64, bdata, length);
mxc = ASUpload( mxc = ASUpload(
args->config, args->config,
datastream, datastream,
@ -237,6 +242,7 @@ IQResult(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
tdata ? tdata->data : NULL tdata ? tdata->data : NULL
); );
Free(bdata); Free(bdata);
Free(base64);
StreamClose(datastream); StreamClose(datastream);
room = ParseeGetBridgedRoom(args, stanza); room = ParseeGetBridgedRoom(args, stanza);
@ -247,8 +253,27 @@ IQResult(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
/* TODO: More reliable system for telling the difference appart */ /* TODO: More reliable system for telling the difference appart */
if (jid && !StrEquals(from, resource)) if (jid && !StrEquals(from, resource))
{ {
from_matrix = ParseeGetBridgedUserI(args, stanza, jid); char *oid = ParseeLookupOID(jid);
char *hsh = ParseeSHA256(oid);
bool scrambled =
oid && StrEquals(jid, HashMapGet(stanza->attrs, "from"));
from_matrix = scrambled
? ScrambleOID(args, oid)
: ParseeGetBridgedUser(args, stanza);
Log(LOG_DEBUG,
"Setting the vCard of '%s'(%s) to %s (%d B)",
from_matrix, jid, mxc,
length
);
Log(LOG_DEBUG,
"OID=%s[%s]",
oid, hsh
);
ASSetAvatar(args->config, from_matrix, mxc); ASSetAvatar(args->config, from_matrix, mxc);
Free(oid);
Free(hsh);
} }
else if (room) else if (room)
{ {

View file

@ -88,14 +88,33 @@ MessageStanza(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
from = NULL; from = NULL;
decode_from = NULL; decode_from = NULL;
from_matrix = NULL; from_matrix = NULL;
Log(LOG_DEBUG, "<message> usage=%d", MemoryAllocated());
from = HashMapGet(stanza->attrs, "from"); from = HashMapGet(stanza->attrs, "from");
if (ParseeManageBan(args, from, NULL)) if (ParseeManageBan(args, from, NULL))
{ {
XMLFreeElement(stanza); XMLFreeElement(stanza);
Log(LOG_DEBUG, "<message/> usage=%d (%s:%d)", MemoryAllocated(), __FILE__, __LINE__);
return false; return false;
} }
if (ServerHasXEP421(args, from))
{
XMLElement *occupant = XMLookForTKV(
stanza, "occupant-id",
"xmlns", "urn:xmpp:occupant-id:0"
);
char *occ_id = occupant ? HashMapGet(occupant->attrs, "id") : NULL;
if (occ_id)
{
Log(LOG_DEBUG,
"'%s' has support for XEP-421, fetching OID=%s",
from, occ_id
);
ParseePushOIDTable(from, occ_id);
}
}
if (StrEquals(type, "error")) if (StrEquals(type, "error"))
{ {
char *type, *text, *user, *parsee; char *type, *text, *user, *parsee;
@ -132,6 +151,7 @@ end_error:
Free(parsee); Free(parsee);
Free(room); Free(room);
Free(user); Free(user);
Log(LOG_DEBUG, "<message/> usage=%d (%s:%d)", MemoryAllocated(), __FILE__, __LINE__);
return false; return false;
} }
@ -402,6 +422,7 @@ end:
Free(decode_from); Free(decode_from);
Free(room); Free(room);
Free(to); Free(to);
Log(LOG_DEBUG, "<message/> usage=%d (%s:%d)", MemoryAllocated(), __FILE__, __LINE__);
return true; return true;
} }

View file

@ -63,8 +63,26 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
XMLElement *user_info; XMLElement *user_info;
XMLElement *vc = XMLookForTKV(stanza, "x", "xmlns", "vcard-temp:x:update"); XMLElement *vc = XMLookForTKV(stanza, "x", "xmlns", "vcard-temp:x:update");
XMLElement *status = XMLookForUnique(stanza, "status"); XMLElement *status = XMLookForUnique(stanza, "status");
char *oid = HashMapGet(stanza->attrs, "from"); char *oid = HashMapGet(stanza->attrs, "from");
if (ServerHasXEP421(args, oid))
{
XMLElement *occupant = XMLookForTKV(
stanza, "occupant-id",
"xmlns", "urn:xmpp:occupant-id:0"
);
char *occ_id = occupant ? HashMapGet(occupant->attrs, "id") : NULL;
if (occ_id)
{
Log(LOG_DEBUG,
"'%s' has support for XEP-421, fetching OID=%s",
oid, occ_id
);
ParseePushOIDTable(oid, occ_id);
}
}
if ((user_info = XMLookForTKV(stanza, "x", "xmlns", MUC_USER_NS))) if ((user_info = XMLookForTKV(stanza, "x", "xmlns", MUC_USER_NS)))
{ {
XMLElement *item = XMLookForUnique(user_info, "item"); XMLElement *item = XMLookForUnique(user_info, "item");
@ -259,7 +277,7 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
{ {
if (args->verbosity >= PARSEE_VERBOSE_COMICAL) if (args->verbosity >= PARSEE_VERBOSE_COMICAL)
{ {
Log(LOG_DEBUG, Log(LOG_WARNING,
"VCard: %s is already cached for %s", avatar_id, oid "VCard: %s is already cached for %s", avatar_id, oid
); );
} }
@ -267,10 +285,6 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
return; return;
} }
if (args->verbosity >= PARSEE_VERBOSE_COMICAL)
{
Log(LOG_DEBUG, "VCard: %s for %s", p_dat->data, oid);
}
JsonValueFree(JsonSet( JsonValueFree(JsonSet(
json, JsonValueString(p_dat->data), json, JsonValueString(p_dat->data),
1, oid) 1, oid)
@ -279,6 +293,9 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
from = ParseeJID(args); from = ParseeJID(args);
Log(LOG_DEBUG,
"Sending a vCard avatar request for %s(=%s)", oid, p_dat->data
);
vcard_request = CreateVCardRequest( vcard_request = CreateVCardRequest(
from, HashMapGet(stanza->attrs, "from") from, HashMapGet(stanza->attrs, "from")
); );

View file

@ -94,3 +94,5 @@ void DestroyPEPManager(PEPManager *manager);
/* PEP callbacks for the handler */ /* PEP callbacks for the handler */
void PEPAvatarEvent(PEPManager *m, XMLElement *stanza, XMLElement *item); void PEPAvatarEvent(PEPManager *m, XMLElement *stanza, XMLElement *item);
void PEPVCardEvent(PEPManager *m, XMLElement *stanza, XMLElement *item); void PEPVCardEvent(PEPManager *m, XMLElement *stanza, XMLElement *item);
char * ScrambleOID(ParseeData *data, char *opaque_oid);