mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 15:05:11 +00:00
[MOD] Hash-based name conflict resolution
Still basic, but should prevent basic name issues.
This commit is contained in:
parent
c0c13883d1
commit
59cbd8b22d
11 changed files with 147 additions and 109 deletions
|
|
@ -62,7 +62,7 @@ CommandHead(CmdPlumb, cmd, argp)
|
||||||
if (chat_id)
|
if (chat_id)
|
||||||
{
|
{
|
||||||
char *rev = StrConcat(2, muc, "/parsee");
|
char *rev = StrConcat(2, muc, "/parsee");
|
||||||
XMPPJoinMUC(args->data->jabber, "parsee", rev);
|
XMPPJoinMUC(args->data->jabber, "parsee", rev, false);
|
||||||
|
|
||||||
Free(rev);
|
Free(rev);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
16
src/Main.c
16
src/Main.c
|
|
@ -101,15 +101,25 @@ Main(Array *args, HashMap *env)
|
||||||
ParseeInitialiseOIDTable();
|
ParseeInitialiseOIDTable();
|
||||||
ParseeInitialiseHeadTable();
|
ParseeInitialiseHeadTable();
|
||||||
|
|
||||||
Log(LOG_NOTICE, "Setting up local Matrix user...");
|
|
||||||
ASRegisterUser(parsee_conf, parsee_conf->sender_localpart);
|
|
||||||
|
|
||||||
conf.port = parsee_conf->port;
|
conf.port = parsee_conf->port;
|
||||||
conf.threads = parsee_conf->http_threads;
|
conf.threads = parsee_conf->http_threads;
|
||||||
conf.maxConnections = conf.threads << 2;
|
conf.maxConnections = conf.threads << 2;
|
||||||
conf.handlerArgs = ParseeInitData(jabber);
|
conf.handlerArgs = ParseeInitData(jabber);
|
||||||
conf.handler = ParseeRequest;
|
conf.handler = ParseeRequest;
|
||||||
|
|
||||||
|
Log(LOG_NOTICE, "Setting up local Matrix user...");
|
||||||
|
if (ASRegisterUser(parsee_conf, parsee_conf->sender_localpart))
|
||||||
|
{
|
||||||
|
char *parsee = ParseeMXID(conf.handlerArgs);
|
||||||
|
ASSetAvatar(parsee_conf,
|
||||||
|
parsee,
|
||||||
|
"mxc://tedomum.net/"
|
||||||
|
"7e228734ec8e792960bb5633e43f0cb845f709f61825130490034651136"
|
||||||
|
);
|
||||||
|
ASSetName(parsee_conf, parsee, "Parsee bridge");
|
||||||
|
Free(parsee);
|
||||||
|
}
|
||||||
|
|
||||||
Log(LOG_NOTICE, "Starting up local cronjobs...");
|
Log(LOG_NOTICE, "Starting up local cronjobs...");
|
||||||
cron = CronCreate( 10 SECONDS );
|
cron = CronCreate( 10 SECONDS );
|
||||||
CronEvery(cron, 5 MINUTES, ParseeCleanup, conf.handlerArgs);
|
CronEvery(cron, 5 MINUTES, ParseeCleanup, conf.handlerArgs);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include <Cytoplasm/Json.h>
|
#include <Cytoplasm/Json.h>
|
||||||
#include <Cytoplasm/Str.h>
|
#include <Cytoplasm/Str.h>
|
||||||
#include <Cytoplasm/Log.h>
|
#include <Cytoplasm/Log.h>
|
||||||
|
#include <Cytoplasm/Sha.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
@ -11,6 +12,38 @@
|
||||||
#include <Matrix.h>
|
#include <Matrix.h>
|
||||||
#include <AS.h>
|
#include <AS.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
JoinMUC(ParseeData *data, HashMap *event, char *jid, char *muc, char *name)
|
||||||
|
{
|
||||||
|
char *sender = GrabString(event, 1, "sender");
|
||||||
|
|
||||||
|
char *rev = StrConcat(3, muc, "/", name);
|
||||||
|
int nonce = 0;
|
||||||
|
|
||||||
|
while (!XMPPJoinMUC(data->jabber, jid, rev, true) && nonce < 20)
|
||||||
|
{
|
||||||
|
char *nonce_str = StrInt(nonce);
|
||||||
|
char *input = StrConcat(4, sender, name, data->id, nonce_str);
|
||||||
|
unsigned char *digest = Sha256(input);
|
||||||
|
char *hex = ShaToHex(digest);
|
||||||
|
|
||||||
|
if (strlen(hex) >= 8)
|
||||||
|
{
|
||||||
|
hex[8] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
Free(rev);
|
||||||
|
rev = StrConcat(6, muc, "/", name, "[", hex, "]");
|
||||||
|
nonce++;
|
||||||
|
|
||||||
|
Free(nonce_str);
|
||||||
|
Free(digest);
|
||||||
|
Free(input);
|
||||||
|
Free(hex);
|
||||||
|
}
|
||||||
|
Free(rev);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ParseeMemberHandler(ParseeData *data, HashMap *event)
|
ParseeMemberHandler(ParseeData *data, HashMap *event)
|
||||||
{
|
{
|
||||||
|
|
@ -55,10 +88,10 @@ ParseeMemberHandler(ParseeData *data, HashMap *event)
|
||||||
if (chat_id)
|
if (chat_id)
|
||||||
{
|
{
|
||||||
char *muc = ParseeGetMUCID(data, chat_id);
|
char *muc = ParseeGetMUCID(data, chat_id);
|
||||||
char *rev = StrConcat(2, muc, "/parsee");
|
char *name = ASGetName(data->config, room_id, state_key);
|
||||||
|
|
||||||
XMPPJoinMUC(data->jabber, jid, rev);
|
JoinMUC(data, event, jid, muc, name);
|
||||||
Free(rev);
|
Free(name);
|
||||||
Free(muc);
|
Free(muc);
|
||||||
|
|
||||||
/* TODO: XEP-0084 magic to advertise a new avatar if possible. */
|
/* TODO: XEP-0084 magic to advertise a new avatar if possible. */
|
||||||
|
|
@ -162,8 +195,6 @@ GetXMPPInformation(ParseeData *data, HashMap *event, char **from, char **to)
|
||||||
DbRef *room_data;
|
DbRef *room_data;
|
||||||
HashMap *data_json;
|
HashMap *data_json;
|
||||||
|
|
||||||
XMPPComponent *jabber = data ? data->jabber : NULL;
|
|
||||||
|
|
||||||
bool direct = false;
|
bool direct = false;
|
||||||
if (!data || !event || !from || !to)
|
if (!data || !event || !from || !to)
|
||||||
{
|
{
|
||||||
|
|
@ -194,7 +225,7 @@ GetXMPPInformation(ParseeData *data, HashMap *event, char **from, char **to)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *matrix_name, *muc_join_as;
|
char *matrix_name;
|
||||||
|
|
||||||
muc_id = ParseeGetMUCID(data, chat_id);
|
muc_id = ParseeGetMUCID(data, chat_id);
|
||||||
if (!chat_id)
|
if (!chat_id)
|
||||||
|
|
@ -208,18 +239,16 @@ GetXMPPInformation(ParseeData *data, HashMap *event, char **from, char **to)
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix_name = ASGetName(data->config, room_id, matrix_sender);
|
matrix_name = ASGetName(data->config, room_id, matrix_sender);
|
||||||
muc_join_as = StrConcat(4, muc_id, "/", matrix_name, "[p]");
|
|
||||||
|
|
||||||
/* TODO: Manage name conflicts. That would have been an easy
|
/* TODO: Manage name conflicts. That would have been an easy
|
||||||
* task(try the original one, and use a counter if it fails),
|
* task(try the original one, and use a counter if it fails),
|
||||||
* but that'd involve modifying the rest of the code, which
|
* but that'd involve modifying the rest of the code, which
|
||||||
* I'm not doing at 01:39 ... */
|
* I'm not doing at 01:39 ... */
|
||||||
XMPPJoinMUC(jabber, *from, muc_join_as);
|
JoinMUC(data, event, *from, muc_id, matrix_name);
|
||||||
|
|
||||||
*to = muc_id;
|
*to = muc_id;
|
||||||
|
|
||||||
Free(matrix_name);
|
Free(matrix_name);
|
||||||
Free(muc_join_as);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Free(chat_id);
|
Free(chat_id);
|
||||||
|
|
@ -295,7 +324,7 @@ ParseeMessageHandler(ParseeData *data, HashMap *event)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *name, *rev;
|
char *name;
|
||||||
/* Try to find the chat ID */
|
/* Try to find the chat ID */
|
||||||
muc_id = ParseeGetMUCID(data, chat_id);
|
muc_id = ParseeGetMUCID(data, chat_id);
|
||||||
if (!chat_id)
|
if (!chat_id)
|
||||||
|
|
@ -307,14 +336,12 @@ ParseeMessageHandler(ParseeData *data, HashMap *event)
|
||||||
* Is there a good way to check for that that isn't
|
* Is there a good way to check for that that isn't
|
||||||
* just "await on join and try again?" */
|
* just "await on join and try again?" */
|
||||||
name = ASGetName(data->config, id, m_sender);
|
name = ASGetName(data->config, id, m_sender);
|
||||||
rev = StrConcat(4, muc_id, "/", name, "[p]");
|
|
||||||
|
|
||||||
XMPPJoinMUC(jabber, encoded_from, rev);
|
JoinMUC(data, event, encoded_from, muc_id, name);
|
||||||
|
|
||||||
to = muc_id;
|
to = muc_id;
|
||||||
|
|
||||||
Free(name);
|
Free(name);
|
||||||
Free(rev);
|
|
||||||
}
|
}
|
||||||
if (reply_id)
|
if (reply_id)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -780,7 +780,7 @@ ParseeManageBan(ParseeData *data, char *user, char *room)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ref = DbLock(data->db, 1, "global_bans");
|
ref = DbLockIntent(data->db, DB_HINT_READONLY, 1, "global_bans");
|
||||||
j = DbJson(ref);
|
j = DbJson(ref);
|
||||||
while (HashMapIterate(j, &key, (void **) &val))
|
while (HashMapIterate(j, &key, (void **) &val))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -540,7 +540,7 @@ ParseeSendPresence(ParseeData *data)
|
||||||
char *rev = StrConcat(2, muc, "/parsee");
|
char *rev = StrConcat(2, muc, "/parsee");
|
||||||
/* Make a fake user join the MUC */
|
/* Make a fake user join the MUC */
|
||||||
Log(LOG_NOTICE, "Sending presence to %s", rev);
|
Log(LOG_NOTICE, "Sending presence to %s", rev);
|
||||||
XMPPJoinMUC(data->jabber, "parsee", rev);
|
XMPPJoinMUC(data->jabber, "parsee", rev, false);
|
||||||
|
|
||||||
Free(rev);
|
Free(rev);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ RouteHead(RouteRoomAck, arr, argp)
|
||||||
{
|
{
|
||||||
char *rev = StrConcat(2, muc, "/parsee");
|
char *rev = StrConcat(2, muc, "/parsee");
|
||||||
Log(LOG_NOTICE, "Sending presence to %s", rev);
|
Log(LOG_NOTICE, "Sending presence to %s", rev);
|
||||||
XMPPJoinMUC(args->data->jabber, "parsee", rev);
|
XMPPJoinMUC(args->data->jabber, "parsee", rev, false);
|
||||||
|
|
||||||
Free(rev);
|
Free(rev);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -199,8 +199,11 @@ XMPPEndCompStream(XMPPComponent *comp)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pthread_mutex_destroy(&comp->write_lock);
|
pthread_mutex_lock(&comp->write_lock);
|
||||||
StreamClose(comp->stream);
|
StreamClose(comp->stream);
|
||||||
|
comp->stream = NULL;
|
||||||
|
pthread_mutex_unlock(&comp->write_lock);
|
||||||
|
pthread_mutex_destroy(&comp->write_lock);
|
||||||
Free(comp->host);
|
Free(comp->host);
|
||||||
Free(comp);
|
Free(comp);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -167,3 +167,87 @@ XMPPRequestVoice(XMPPComponent *jabber, char *from, char *muc)
|
||||||
XMLFreeElement(stanza);
|
XMLFreeElement(stanza);
|
||||||
Free(identifier);
|
Free(identifier);
|
||||||
}
|
}
|
||||||
|
bool
|
||||||
|
XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, bool care)
|
||||||
|
{
|
||||||
|
XMLElement *presence, *x, *reply;
|
||||||
|
char *from, *id;
|
||||||
|
if (!comp || !fr || !muc)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&comp->write_lock);
|
||||||
|
|
||||||
|
presence = XMLCreateTag("presence");
|
||||||
|
x = XMLCreateTag("x");
|
||||||
|
XMLAddAttr(presence, "from", (from = StrConcat(3, fr, "@", comp->host)));
|
||||||
|
XMLAddAttr(presence, "to", muc);
|
||||||
|
XMLAddAttr(presence, "id", (id = StrRandom(8)));
|
||||||
|
XMLAddAttr(x, "xmlns", "http://jabber.org/protocol/muc");
|
||||||
|
|
||||||
|
XMLAddChild(presence, x);
|
||||||
|
XMPPAnnotatePresence(presence);
|
||||||
|
|
||||||
|
XMLEncode(comp->stream, presence);
|
||||||
|
StreamFlush(comp->stream);
|
||||||
|
|
||||||
|
XMLFreeElement(presence);
|
||||||
|
Free(from);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&comp->write_lock);
|
||||||
|
|
||||||
|
if (care && (reply = ParseeAwaitStanza(id, 500)))
|
||||||
|
{
|
||||||
|
bool exit_code = true;
|
||||||
|
|
||||||
|
if (XMPPHasError(reply, "conflict"))
|
||||||
|
{
|
||||||
|
exit_code = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
XMLFreeElement(reply);
|
||||||
|
Free(id);
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
|
Free(id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *reason)
|
||||||
|
{
|
||||||
|
XMLElement *presence;
|
||||||
|
char *from, *id;
|
||||||
|
if (!comp || !fr || !muc)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&comp->write_lock);
|
||||||
|
|
||||||
|
presence = XMLCreateTag("presence");
|
||||||
|
XMLAddAttr(presence, "from", (from = StrConcat(3, fr, "@", comp->host)));
|
||||||
|
XMLAddAttr(presence, "to", muc);
|
||||||
|
XMLAddAttr(presence, "id", (id = StrRandom(8)));
|
||||||
|
XMLAddAttr(presence, "type", "unavailable");
|
||||||
|
|
||||||
|
if (reason)
|
||||||
|
{
|
||||||
|
XMLElement *status = XMLCreateTag("status");
|
||||||
|
XMLElement *string = XMLCreateText(reason);
|
||||||
|
|
||||||
|
XMLAddChild(status, string);
|
||||||
|
XMLAddChild(presence, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
XMPPAnnotatePresence(presence);
|
||||||
|
|
||||||
|
XMLEncode(comp->stream, presence);
|
||||||
|
StreamFlush(comp->stream);
|
||||||
|
|
||||||
|
XMLFreeElement(presence);
|
||||||
|
Free(from);
|
||||||
|
Free(id);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&comp->write_lock);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,93 +76,7 @@ XMPPRetract(XMPPComponent *comp, char *fr, char *to, char *type, char *redact)
|
||||||
Free(from);
|
Free(from);
|
||||||
Free(ident);
|
Free(ident);
|
||||||
}
|
}
|
||||||
void
|
|
||||||
XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *reason)
|
|
||||||
{
|
|
||||||
XMLElement *presence;
|
|
||||||
char *from, *id;
|
|
||||||
if (!comp || !fr || !muc)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_lock(&comp->write_lock);
|
|
||||||
|
|
||||||
presence = XMLCreateTag("presence");
|
|
||||||
XMLAddAttr(presence, "from", (from = StrConcat(3, fr, "@", comp->host)));
|
|
||||||
XMLAddAttr(presence, "to", muc);
|
|
||||||
XMLAddAttr(presence, "id", (id = StrRandom(8)));
|
|
||||||
XMLAddAttr(presence, "type", "unavailable");
|
|
||||||
|
|
||||||
if (reason)
|
|
||||||
{
|
|
||||||
XMLElement *status = XMLCreateTag("status");
|
|
||||||
XMLElement *string = XMLCreateText(reason);
|
|
||||||
|
|
||||||
XMLAddChild(status, string);
|
|
||||||
XMLAddChild(presence, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
XMPPAnnotatePresence(presence);
|
|
||||||
|
|
||||||
XMLEncode(comp->stream, presence);
|
|
||||||
StreamFlush(comp->stream);
|
|
||||||
|
|
||||||
XMLFreeElement(presence);
|
|
||||||
Free(from);
|
|
||||||
Free(id);
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&comp->write_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc)
|
|
||||||
{
|
|
||||||
XMLElement *presence, *x, *reply;
|
|
||||||
char *from, *id;
|
|
||||||
if (!comp || !fr || !muc)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_lock(&comp->write_lock);
|
|
||||||
|
|
||||||
presence = XMLCreateTag("presence");
|
|
||||||
x = XMLCreateTag("x");
|
|
||||||
XMLAddAttr(presence, "from", (from = StrConcat(3, fr, "@", comp->host)));
|
|
||||||
XMLAddAttr(presence, "to", muc);
|
|
||||||
XMLAddAttr(presence, "id", (id = StrRandom(8)));
|
|
||||||
XMLAddAttr(x, "xmlns", "http://jabber.org/protocol/muc");
|
|
||||||
|
|
||||||
XMLAddChild(presence, x);
|
|
||||||
XMPPAnnotatePresence(presence);
|
|
||||||
|
|
||||||
XMLEncode(comp->stream, presence);
|
|
||||||
StreamFlush(comp->stream);
|
|
||||||
|
|
||||||
XMLFreeElement(presence);
|
|
||||||
Free(from);
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&comp->write_lock);
|
|
||||||
|
|
||||||
/*if ((reply = ParseeAwaitStanza(id, 500)))
|
|
||||||
{
|
|
||||||
bool exit_code = true;
|
|
||||||
|
|
||||||
if (XMPPHasError(reply, "conflict"))
|
|
||||||
{
|
|
||||||
Log(LOG_WARNING, "UNIMPLEMENTED NAMING CONFLICT.");
|
|
||||||
exit_code = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
XMLFreeElement(reply);
|
|
||||||
Free(id);
|
|
||||||
return exit_code;
|
|
||||||
}*/
|
|
||||||
(void) reply;
|
|
||||||
Free(id);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool
|
bool
|
||||||
XMPPIsParseeStanza(XMLElement *stanza)
|
XMPPIsParseeStanza(XMLElement *stanza)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -393,7 +393,7 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
|
||||||
version = XMLCreateTag("version");
|
version = XMLCreateTag("version");
|
||||||
|
|
||||||
XMLAddChild(name, XMLCreateText(NAME));
|
XMLAddChild(name, XMLCreateText(NAME));
|
||||||
XMLAddChild(version, XMLCreateText(VERSION));
|
XMLAddChild(version, XMLCreateText(VERSION "[" CODE "]"));
|
||||||
}
|
}
|
||||||
XMLAddChild(query, name);
|
XMLAddChild(query, name);
|
||||||
XMLAddChild(query, version);
|
XMLAddChild(query, version);
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ extern XMPPComponent * XMPPInitialiseCompStream(char *host, int port);
|
||||||
extern bool XMPPAuthenticateCompStream(XMPPComponent *comp, char *shared);
|
extern bool XMPPAuthenticateCompStream(XMPPComponent *comp, char *shared);
|
||||||
|
|
||||||
/* Makes a user join/leave a MUC */
|
/* Makes a user join/leave a MUC */
|
||||||
extern bool XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc);
|
extern bool XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, bool care);
|
||||||
extern void XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *r);
|
extern void XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *r);
|
||||||
|
|
||||||
/* TODO: XMPP stuff, I don't fucking know, I'm not a Jabbernerd. */
|
/* TODO: XMPP stuff, I don't fucking know, I'm not a Jabbernerd. */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue