mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 13:45:10 +00:00
[MOD] One-way Matrix->XMPP comms.
This is not sanitised. I need to make an XML writer.
This commit is contained in:
parent
868f0e4d9c
commit
bdb4fd2f68
17 changed files with 421 additions and 61 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -4,3 +4,5 @@ parsee*
|
|||
parsee
|
||||
*.swp
|
||||
.*
|
||||
data
|
||||
data/*
|
||||
|
|
|
|||
29
src/AS.c
29
src/AS.c
|
|
@ -74,18 +74,23 @@ ASRegisterUser(ParseeConfig *conf, char *user)
|
|||
json = HashMapCreate();
|
||||
|
||||
HashMapSet(json,"type",JsonValueString("m.login.application_service"));
|
||||
|
||||
user = ParseeGetLocal(user);
|
||||
HashMapSet(json,"username",JsonValueString(user));
|
||||
|
||||
ASAuthenticateRequest(conf, ctx);
|
||||
status = ParseeSetRequestJSON(ctx, json);
|
||||
|
||||
HttpClientContextFree(ctx);
|
||||
JsonFree(json);
|
||||
|
||||
Free(user);
|
||||
|
||||
return status == HTTP_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ASPing(ParseeConfig *conf)
|
||||
ASPing(const ParseeConfig *conf)
|
||||
{
|
||||
HttpClientContext *ctx = NULL;
|
||||
HashMap *json = NULL;
|
||||
|
|
@ -116,26 +121,20 @@ void
|
|||
ASJoin(ParseeConfig *conf, char *id, char *masquerade)
|
||||
{
|
||||
HttpClientContext *ctx = NULL;
|
||||
HashMap *json = NULL, *params_obj;
|
||||
char *path, *params;
|
||||
if (!conf || !id)
|
||||
HashMap *json = NULL;
|
||||
char *path;
|
||||
if (!conf || !id || !masquerade)
|
||||
{
|
||||
Log(LOG_ERR, "Bad values %p %p", conf, id);
|
||||
return;
|
||||
}
|
||||
|
||||
params_obj = HashMapCreate();
|
||||
if (masquerade)
|
||||
{
|
||||
HashMapSet(params_obj, "user_id", masquerade);
|
||||
}
|
||||
params = HttpParamEncode(params_obj);
|
||||
HashMapFree(params_obj);
|
||||
path = StrConcat(4,
|
||||
path = StrConcat(5,
|
||||
"/_matrix/client/v3/rooms/", id, "/join?",
|
||||
params
|
||||
"user_id=", masquerade
|
||||
);
|
||||
Free(params);
|
||||
|
||||
Log(LOG_INFO, "%s", path);
|
||||
ctx = ParseeCreateRequest(
|
||||
conf,
|
||||
HTTP_POST, path
|
||||
|
|
@ -144,6 +143,7 @@ ASJoin(ParseeConfig *conf, char *id, char *masquerade)
|
|||
json = HashMapCreate();
|
||||
ASAuthenticateRequest(conf, ctx);
|
||||
ParseeSetRequestJSON(ctx, json);
|
||||
|
||||
HttpClientContextFree(ctx);
|
||||
JsonFree(json);
|
||||
}
|
||||
|
|
@ -152,6 +152,7 @@ ASSend(ParseeConfig *conf, char *id, char *user, char *type, HashMap *c)
|
|||
{
|
||||
HttpClientContext *ctx = NULL;
|
||||
HashMap *json = NULL, *params_obj;
|
||||
Stream *s;
|
||||
char *path, *params;
|
||||
char *txn;
|
||||
if (!conf || !id || !type || !c)
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ ParseeRequest(HttpServerContext *ctx, void *argp)
|
|||
|
||||
HttpSendHeaders(ctx);
|
||||
JsonEncode(response, stream, JSON_DEFAULT);
|
||||
JsonFree(response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
73
src/Main.c
73
src/Main.c
|
|
@ -2,33 +2,43 @@
|
|||
#include <Cytoplasm/Log.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <Parsee.h>
|
||||
#include <XMPP.h>
|
||||
#include <XML.h>
|
||||
#include <AS.h>
|
||||
|
||||
static HttpServer *server = NULL;
|
||||
static void
|
||||
SignalHandler(int signal)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
switch (signal)
|
||||
{
|
||||
case SIGPIPE:
|
||||
return;
|
||||
case SIGTERM:
|
||||
case SIGINT:
|
||||
if (!server)
|
||||
{
|
||||
return;
|
||||
}
|
||||
HttpServerStop(server);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
Main(void)
|
||||
{
|
||||
HttpServer *server = NULL;
|
||||
HttpServerConfig conf;
|
||||
ParseeData *data;
|
||||
const ParseeConfig *parsee_conf;
|
||||
Stream *yaml;
|
||||
{
|
||||
char *as = "TODO";
|
||||
char *shared = "TODO";
|
||||
Stream *jabber = XMPPInitialiseCompStream(as, 0);
|
||||
XMPPAuthenticateCompStream(jabber, as, shared);
|
||||
while (!StreamEof(jabber))
|
||||
{
|
||||
StreamPutc(StreamStderr(), StreamGetc(jabber));
|
||||
StreamFlush(StreamStderr());
|
||||
}
|
||||
XMPPEndCompStream(jabber);
|
||||
return 0;
|
||||
}
|
||||
XMPPComponent *jabber;
|
||||
struct sigaction sigAction;
|
||||
|
||||
Log(LOG_INFO, "%s - v%s", NAME, VERSION);
|
||||
ParseeConfigLoad("parsee.json");
|
||||
|
|
@ -39,18 +49,48 @@ Main(void)
|
|||
StreamClose(yaml);
|
||||
|
||||
parsee_conf = ParseeConfigGet();
|
||||
{
|
||||
jabber = XMPPInitialiseCompStream(
|
||||
parsee_conf->component_host,
|
||||
parsee_conf->component_port
|
||||
);
|
||||
XMPPAuthenticateCompStream(
|
||||
jabber,
|
||||
parsee_conf->shared_comp_secret
|
||||
);
|
||||
}
|
||||
Log(LOG_INFO, "HS token: %s", parsee_conf->hs_token);
|
||||
|
||||
ASRegisterUser(parsee_conf, parsee_conf->sender_localpart);
|
||||
|
||||
|
||||
memset(&conf, 0, sizeof(conf));
|
||||
conf.port = parsee_conf->port;
|
||||
conf.threads = 4;
|
||||
conf.maxConnections = 32;
|
||||
conf.handlerArgs = ParseeInitData();
|
||||
conf.handlerArgs = ParseeInitData(jabber);
|
||||
conf.handler = ParseeRequest;
|
||||
|
||||
sigAction.sa_handler = SignalHandler;
|
||||
sigfillset(&sigAction.sa_mask);
|
||||
sigAction.sa_flags = SA_RESTART;
|
||||
|
||||
#define SIGACTION(sig, act, oact) \
|
||||
if (sigaction(sig, act, oact) < 0) \
|
||||
{ \
|
||||
Log(LOG_ERR, "Unable to install signal handler: %s", #sig); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
Log(LOG_DEBUG, "Installed signal handler: %s", #sig); \
|
||||
}
|
||||
|
||||
SIGACTION(SIGINT, &sigAction, NULL);
|
||||
SIGACTION(SIGTERM, &sigAction, NULL);
|
||||
SIGACTION(SIGPIPE, &sigAction, NULL);
|
||||
SIGACTION(SIGUSR1, &sigAction, NULL);
|
||||
|
||||
#undef SIGACTION
|
||||
|
||||
/* TODO: The rest of Parsee. */
|
||||
server = HttpServerCreate(&conf);
|
||||
HttpServerStart(server);
|
||||
|
|
@ -60,5 +100,6 @@ Main(void)
|
|||
|
||||
HttpServerFree(server);
|
||||
ParseeConfigFree();
|
||||
ParseeFreeData(conf.handlerArgs);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include <Parsee.h>
|
||||
|
||||
#include <Cytoplasm/Memory.h>
|
||||
#include <Cytoplasm/Json.h>
|
||||
#include <Cytoplasm/Str.h>
|
||||
#include <Cytoplasm/Log.h>
|
||||
|
|
@ -9,42 +10,77 @@
|
|||
|
||||
#define GrabString(obj, ...) JsonValueAsString(JsonGet(obj, __VA_ARGS__))
|
||||
static void
|
||||
ParseeMemberHandler(const ParseeConfig *conf, HashMap *event)
|
||||
ParseeMemberHandler(ParseeData *data, HashMap *event)
|
||||
{
|
||||
char *state_key = GrabString(event, 1, "state_key");
|
||||
char *membership = GrabString(event, 2, "content", "membership");
|
||||
char *room_id = GrabString(event, 1, "room_id");
|
||||
const ParseeConfig *conf = data->config;
|
||||
Log(LOG_INFO, "Membership '%s'->'%s'", state_key, membership);
|
||||
|
||||
if (StrEquals(membership, "invite") && ParseeIsPuppet(conf, state_key))
|
||||
{
|
||||
DbRef *ref;
|
||||
HashMap *json;
|
||||
char *jid;
|
||||
Log(LOG_INFO, "Looks like %s was invited to %s",
|
||||
state_key,
|
||||
GrabString(event, 1, "room_id")
|
||||
room_id
|
||||
);
|
||||
ASJoin(conf, room_id, state_key);
|
||||
ref = DbCreate(data->db, 3, "rooms", room_id, "data");
|
||||
json = DbJson(ref);
|
||||
|
||||
Log(LOG_INFO, "Grabbing JID");
|
||||
jid = ParseeDecodeLocalJID(conf, state_key);
|
||||
|
||||
Log(LOG_INFO, "JID: %s", jid);
|
||||
|
||||
HashMapSet(json, "is_direct", JsonValueBoolean(true));
|
||||
HashMapSet(json, "xmpp_user", JsonValueString(jid));
|
||||
|
||||
/* Pretend everything is a dm, ignoring is_direct */
|
||||
if (jid)
|
||||
{
|
||||
Free(jid);
|
||||
}
|
||||
DbUnlock(data->db, ref);
|
||||
}
|
||||
}
|
||||
static void
|
||||
ParseeMessageHandler(const ParseeConfig *conf, HashMap *event)
|
||||
ParseeMessageHandler(ParseeData *data, HashMap *event)
|
||||
{
|
||||
XMPPComponent *jabber = data->jabber;
|
||||
DbRef *ref;
|
||||
HashMap *json;
|
||||
|
||||
char *msgtype = GrabString(event, 2, "content", "msgtype");
|
||||
char *body = GrabString(event, 2, "content", "body");
|
||||
char *id = GrabString(event, 1, "room_id");
|
||||
if (StrEquals(body, "!help"))
|
||||
char *sender = GrabString(event, 1, "sender");
|
||||
|
||||
ref = DbLock(data->db, 3, "rooms", id, "data");
|
||||
json = DbJson(ref);
|
||||
|
||||
if (JsonValueAsBoolean(HashMapGet(json, "is_direct")))
|
||||
{
|
||||
Log(LOG_ERR, "Not implemented!");
|
||||
ASSend(conf, id, NULL, "m.room.message",
|
||||
MatrixCreateNotice("No help, pal.")
|
||||
);
|
||||
char *user = GrabString(json, 1, "xmpp_user");
|
||||
char *local = ParseeEncodeMXID(sender);
|
||||
|
||||
Log(LOG_INFO, "Sending to %s on XMPP", user);
|
||||
XMPPSendPlain(jabber, local, user, body, NULL);
|
||||
|
||||
Free(local);
|
||||
}
|
||||
|
||||
DbUnlock(data->db, ref);
|
||||
}
|
||||
|
||||
void
|
||||
ParseeEventHandler(const ParseeConfig *conf, HashMap *event)
|
||||
ParseeEventHandler(ParseeData *data, HashMap *event)
|
||||
{
|
||||
char *event_type;
|
||||
if (!conf || !event)
|
||||
if (!data || !event)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -57,12 +93,12 @@ ParseeEventHandler(const ParseeConfig *conf, HashMap *event)
|
|||
event_type = GrabString(event, 1, "type");
|
||||
if (StrEquals(event_type, "m.room.member"))
|
||||
{
|
||||
ParseeMemberHandler(conf, event);
|
||||
ParseeMemberHandler(data, event);
|
||||
return;
|
||||
}
|
||||
if (StrEquals(event_type, "m.room.message"))
|
||||
{
|
||||
ParseeMessageHandler(conf, event);
|
||||
ParseeMessageHandler(data, event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,10 @@ ParseeConfigInit(void)
|
|||
config->listen_as = StrDuplicate("localhost");
|
||||
config->port = 7642; /* proposed by Saint */
|
||||
|
||||
config->component_port = 0;
|
||||
config->component_host = NULL;
|
||||
config->shared_comp_secret = NULL;
|
||||
|
||||
stream = StreamOpen("parsee.json", "w");
|
||||
json = HashMapCreate();
|
||||
HashMapSet(json, "as_token", JsonValueString(config->as_token));
|
||||
|
|
@ -67,6 +71,12 @@ ParseeConfigLoad(char *conf)
|
|||
CopyToStr(homeserver_host, "hs_host");
|
||||
CopyToInt(homeserver_port, "hs_port");
|
||||
|
||||
CopyToInt(component_port, "component_port");
|
||||
CopyToStr(component_host, "component_host");
|
||||
CopyToStr(shared_comp_secret, "shared_secret");
|
||||
|
||||
CopyToStr(db_path, "db");
|
||||
|
||||
JsonFree(json);
|
||||
StreamClose(stream);
|
||||
}
|
||||
|
|
@ -92,10 +102,10 @@ ParseeExportConfigYAML(Stream *stream)
|
|||
StreamPrintf(stream, "namespaces: \n");
|
||||
StreamPrintf(stream, " users:\n");
|
||||
StreamPrintf(stream, " - exclusive: true\n");
|
||||
StreamPrintf(stream, " regex: \"@%s_.*\n", config->namespace_base);
|
||||
StreamPrintf(stream, " regex: \"@%s_.*\"\n", config->namespace_base);
|
||||
StreamPrintf(stream, " aliases:\n");
|
||||
StreamPrintf(stream, " - exclusive: true\n");
|
||||
StreamPrintf(stream, " regex: \"#%s_.*\n", config->namespace_base);
|
||||
StreamPrintf(stream, " regex: \"#%s_.*\"\n", config->namespace_base);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -105,6 +115,11 @@ ParseeConfigFree(void)
|
|||
{
|
||||
return;
|
||||
}
|
||||
Free(config->component_host);
|
||||
Free(config->shared_comp_secret);
|
||||
Free(config->db_path);
|
||||
Free(config->homeserver_host);
|
||||
|
||||
Free(config->as_token);
|
||||
Free(config->hs_token);
|
||||
Free(config->sender_localpart);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#include <Routes.h>
|
||||
|
||||
ParseeData *
|
||||
ParseeInitData(void)
|
||||
ParseeInitData(XMPPComponent *comp)
|
||||
{
|
||||
ParseeData *data;
|
||||
if (!ParseeConfigGet())
|
||||
|
|
@ -17,6 +17,8 @@ ParseeInitData(void)
|
|||
data = Malloc(sizeof(*data));
|
||||
data->config = ParseeConfigGet();
|
||||
data->router = HttpRouterCreate();
|
||||
data->jabber = comp;
|
||||
data->db = DbOpen(data->config->db_path, 0);
|
||||
|
||||
#define X_ROUTE(path, func) do {\
|
||||
if (!HttpRouterAdd(data->router, path, func))\
|
||||
|
|
@ -37,6 +39,8 @@ ParseeFreeData(ParseeData *data)
|
|||
return;
|
||||
}
|
||||
|
||||
XMPPEndCompStream(data->jabber);
|
||||
DbClose(data->db);
|
||||
HttpRouterFree(data->router);
|
||||
Free(data);
|
||||
}
|
||||
|
|
|
|||
125
src/ParseeUser.c
125
src/ParseeUser.c
|
|
@ -1,5 +1,8 @@
|
|||
#include <Parsee.h>
|
||||
|
||||
#include <Cytoplasm/Memory.h>
|
||||
#include <Cytoplasm/Str.h>
|
||||
#include <Cytoplasm/Log.h>
|
||||
#include <string.h>
|
||||
|
||||
bool
|
||||
|
|
@ -30,3 +33,125 @@ ParseeIsPuppet(const ParseeConfig *conf, char *user)
|
|||
* room. */
|
||||
return flag;
|
||||
}
|
||||
|
||||
static char *
|
||||
DecodeJID(char *str, char term)
|
||||
{
|
||||
char *out = NULL;
|
||||
#define Okay(c) ((c) && ((c) != term))
|
||||
while (Okay(*str))
|
||||
{
|
||||
char c = *str;
|
||||
char buf[3] = { 0 };
|
||||
char *tmp;
|
||||
if (c == '=' && Okay(*(str + 1)) && Okay(*(str + 2)))
|
||||
{
|
||||
str++;
|
||||
|
||||
memcpy(buf, str, 2);
|
||||
buf[0] = strtol(buf, NULL, 16);
|
||||
buf[1] = '\0';
|
||||
|
||||
tmp = StrConcat(2, out, buf);
|
||||
Free(out);
|
||||
out = tmp;
|
||||
|
||||
str += 2;
|
||||
continue;
|
||||
}
|
||||
memcpy(buf, str, 1);
|
||||
tmp = StrConcat(2, out, buf);
|
||||
Free(out);
|
||||
out = tmp;
|
||||
|
||||
str++;
|
||||
}
|
||||
#undef Okay
|
||||
return out;
|
||||
}
|
||||
char *
|
||||
ParseeDecodeLocalJID(const ParseeConfig *c, char *mxid)
|
||||
{
|
||||
char *localpart, *jid_flags, *data_start;
|
||||
bool plain_jid = false;
|
||||
if (!ParseeIsPuppet(c, mxid))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
localpart = mxid + 1;
|
||||
jid_flags = localpart + strlen(c->namespace_base) + 1;
|
||||
data_start = jid_flags;
|
||||
while (*data_start && *data_start != '_')
|
||||
{
|
||||
/* TODO: Make this a macro */
|
||||
if (*data_start == 'l')
|
||||
{
|
||||
plain_jid = true;
|
||||
}
|
||||
data_start++;
|
||||
}
|
||||
if (!*data_start || !plain_jid)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
data_start++;
|
||||
/* Until the ':', data_start now is an encoded JID */
|
||||
return DecodeJID(data_start, ':');
|
||||
}
|
||||
char *
|
||||
ParseeGetLocal(char *mxid)
|
||||
{
|
||||
char *cpy;
|
||||
size_t i;
|
||||
if (!mxid)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (*mxid != '@')
|
||||
{
|
||||
return StrDuplicate(mxid);
|
||||
}
|
||||
|
||||
mxid++;
|
||||
cpy = Malloc(strlen(mxid) + 1);
|
||||
memset(cpy, '\0', strlen(mxid) + 1);
|
||||
memcpy(cpy, mxid, strlen(mxid));
|
||||
|
||||
for (i = 0; i < strlen(mxid); i++)
|
||||
{
|
||||
if (cpy[i] == ':')
|
||||
{
|
||||
cpy[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return cpy;
|
||||
}
|
||||
char *
|
||||
ParseeEncodeMXID(char *mxid)
|
||||
{
|
||||
char *ret;
|
||||
size_t i;
|
||||
if (!mxid)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
ret = Malloc(strlen(mxid) + 1);
|
||||
for (i = 0; i < strlen(mxid) + 1; i++)
|
||||
{
|
||||
char src = mxid[i];
|
||||
if (src == '@')
|
||||
{
|
||||
src = '%';
|
||||
}
|
||||
else if (src == ':')
|
||||
{
|
||||
src = '=';
|
||||
}
|
||||
ret[i] = src;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ RouteHead(RouteRoot, arr, argp)
|
|||
{
|
||||
ParseeHttpArg *args = argp;
|
||||
|
||||
ASPing(args->data->config);
|
||||
|
||||
HttpResponseHeader(args->ctx, "Content-Type", "text/html");
|
||||
HttpSendHeaders(args->ctx);
|
||||
StreamPrintf(args->stream, "<html lang=\"en\">");
|
||||
|
|
@ -30,5 +28,6 @@ RouteHead(RouteRoot, arr, argp)
|
|||
StreamPrintf(args->stream, " </p>");
|
||||
StreamPrintf(args->stream, " </body>");
|
||||
StreamPrintf(args->stream, "</html>");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ RouteHead(RouteTxns, arr, argp)
|
|||
for (i = 0; i < ArraySize(events); i++)
|
||||
{
|
||||
HashMap *event = JsonValueAsObject(ArrayGet(events, i));
|
||||
ParseeEventHandler(args->data->config, event);
|
||||
ParseeEventHandler(args->data, event);
|
||||
}
|
||||
|
||||
/* TODO: Store TXN ID somewhere so that we can commit
|
||||
|
|
|
|||
41
src/Routes/UserAck.c
Normal file
41
src/Routes/UserAck.c
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#include <Routes.h>
|
||||
|
||||
#include <Cytoplasm/Log.h>
|
||||
|
||||
#include <Matrix.h>
|
||||
#include <AS.h>
|
||||
|
||||
RouteHead(RouteUserAck, arr, argp)
|
||||
{
|
||||
ParseeHttpArg *args = argp;
|
||||
HashMap *request = NULL;
|
||||
HashMap *response = NULL;
|
||||
Array *events;
|
||||
size_t i;
|
||||
|
||||
char *user = ArrayGet(arr, 0);
|
||||
|
||||
Log(LOG_INFO, "Alles Politischemacht");
|
||||
response = ASVerifyRequest(args);
|
||||
if (response)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
if (HttpRequestMethodGet(args->ctx) != HTTP_GET)
|
||||
{
|
||||
HttpResponseStatus(args->ctx, HTTP_METHOD_NOT_ALLOWED);
|
||||
response = MatrixCreateError(
|
||||
"M_UNRECOGNIZED",
|
||||
"Path /users only accepts GET as a valid method."
|
||||
);
|
||||
goto end;
|
||||
}
|
||||
|
||||
Log(LOG_INFO, "user=%s", user);
|
||||
ASRegisterUser(args->data->config, user);
|
||||
/* TODO: Verify the user, and create an XMPP mapping. */
|
||||
response = HashMapCreate();
|
||||
end:
|
||||
JsonFree(request);
|
||||
return response;
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
/* The default component port Prosody uses. */
|
||||
#define DEFAULT_PROSODY_PORT 5347
|
||||
|
||||
Stream *
|
||||
XMPPComponent *
|
||||
XMPPInitialiseCompStream(char *host, int port)
|
||||
{
|
||||
/* TODO */
|
||||
|
|
@ -31,6 +31,7 @@ XMPPInitialiseCompStream(char *host, int port)
|
|||
int error;
|
||||
char serv[8];
|
||||
Stream *stream;
|
||||
XMPPComponent *comp;
|
||||
|
||||
snprintf(serv, sizeof(serv), "%hu", port ? port : DEFAULT_PROSODY_PORT);
|
||||
|
||||
|
|
@ -74,7 +75,11 @@ XMPPInitialiseCompStream(char *host, int port)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return stream;
|
||||
comp = Malloc(sizeof(*comp));
|
||||
comp->host = StrDuplicate(host);
|
||||
comp->stream = stream;
|
||||
|
||||
return comp;
|
||||
}
|
||||
|
||||
#include <Cytoplasm/Sha.h>
|
||||
|
|
@ -95,17 +100,22 @@ ComputeHandshake(char *shared, char *stream)
|
|||
return sha;
|
||||
}
|
||||
bool
|
||||
XMPPAuthenticateCompStream(Stream *stream, char *as, char *shared)
|
||||
XMPPAuthenticateCompStream(XMPPComponent *comp, char *shared)
|
||||
{
|
||||
/* TODO */
|
||||
XMLexer *sax;
|
||||
XMLEvent *ev;
|
||||
char *stream_id, *handshake;
|
||||
bool ret = false;
|
||||
if (!stream || !as || !shared)
|
||||
Stream *stream;
|
||||
char *as;
|
||||
if (!comp || !shared)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
stream = comp->stream;
|
||||
as = comp->host;
|
||||
StreamPrintf(stream,
|
||||
"<stream:stream "
|
||||
"xmlns='jabber:component:accept' "
|
||||
|
|
@ -171,7 +181,13 @@ end:
|
|||
}
|
||||
|
||||
void
|
||||
XMPPEndCompStream(Stream *stream)
|
||||
XMPPEndCompStream(XMPPComponent *comp)
|
||||
{
|
||||
StreamClose(stream);
|
||||
if (!comp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
StreamClose(comp->stream);
|
||||
Free(comp->host);
|
||||
Free(comp);
|
||||
}
|
||||
|
|
|
|||
43
src/XMPP/Stanza.c
Normal file
43
src/XMPP/Stanza.c
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#include <XMPP.h>
|
||||
|
||||
void
|
||||
XMPPSendPlain(XMPPComponent *comp, char *fr, char *to, char *msg, char *type)
|
||||
{
|
||||
if (!comp || !fr || !to || !msg)
|
||||
{
|
||||
return;
|
||||
}
|
||||
StreamPrintf(
|
||||
comp->stream, "<message from='%s@%s' to='%s'",
|
||||
fr, comp->host, to
|
||||
);
|
||||
if (type)
|
||||
{
|
||||
StreamPrintf(comp->stream, " type='%s'", type);
|
||||
}
|
||||
StreamPrintf(comp->stream, ">");
|
||||
StreamPrintf(comp->stream,
|
||||
"<body>"
|
||||
"%s"
|
||||
"</body>"
|
||||
"</message>",
|
||||
msg
|
||||
);
|
||||
StreamFlush(comp->stream);
|
||||
}
|
||||
void
|
||||
XMPPSendPresence(XMPPComponent *comp, char *fr, char *to)
|
||||
{
|
||||
if (!comp || !fr || !to)
|
||||
{
|
||||
return;
|
||||
}
|
||||
StreamPrintf(comp->stream,
|
||||
"<presence from='%s@%s' to='%s'>"
|
||||
"<x xmlns='http://jabber.org/protocol/muc'/>"
|
||||
"</presence>",
|
||||
fr, comp->host,
|
||||
to
|
||||
);
|
||||
StreamFlush(comp->stream);
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ extern void ASAuthenticateRequest(ParseeConfig *, HttpClientContext *);
|
|||
extern bool ASRegisterUser(ParseeConfig *, char *);
|
||||
|
||||
/* Pings the homeserver to get attention. */
|
||||
extern void ASPing(ParseeConfig *);
|
||||
extern void ASPing(const ParseeConfig *);
|
||||
|
||||
/* Joins a room from an ID and a given user we want to masquerade
|
||||
* as. */
|
||||
|
|
|
|||
|
|
@ -5,8 +5,12 @@
|
|||
#include <Cytoplasm/HttpRouter.h>
|
||||
#include <Cytoplasm/HttpClient.h>
|
||||
#include <Cytoplasm/Stream.h>
|
||||
#include <Cytoplasm/Db.h>
|
||||
|
||||
#include <XMPP.h>
|
||||
|
||||
typedef struct ParseeConfig {
|
||||
/* -------- MATRIX -------- */
|
||||
char *as_token, *hs_token;
|
||||
/* id here is "Parsee XMPP". */
|
||||
char *sender_localpart;
|
||||
|
|
@ -18,11 +22,24 @@ typedef struct ParseeConfig {
|
|||
/* Homeserver port info */
|
||||
char *homeserver_host;
|
||||
int homeserver_port;
|
||||
|
||||
|
||||
/* ------- JABBER -------- */
|
||||
char *component_host;
|
||||
char *shared_comp_secret;
|
||||
int component_port;
|
||||
|
||||
/* ------- DB -------- */
|
||||
char *db_path;
|
||||
} ParseeConfig;
|
||||
|
||||
typedef struct ParseeData {
|
||||
const ParseeConfig *config;
|
||||
HttpRouter *router;
|
||||
|
||||
XMPPComponent *jabber;
|
||||
|
||||
Db *db;
|
||||
} ParseeData;
|
||||
|
||||
/* Initialises a Parsee config from scratch, and writes to it
|
||||
|
|
@ -42,7 +59,7 @@ extern void ParseeExportConfigYAML(Stream *);
|
|||
extern void ParseeConfigFree(void);
|
||||
|
||||
/* Creates and destroys a data structure, stored on the heap. */
|
||||
extern ParseeData * ParseeInitData(void);
|
||||
extern ParseeData * ParseeInitData(XMPPComponent *);
|
||||
extern void ParseeFreeData(ParseeData *);
|
||||
|
||||
/* HTTP server handler for Parsee, takes in a config. */
|
||||
|
|
@ -54,8 +71,17 @@ extern HttpClientContext * ParseeCreateRequest(ParseeConfig *, HttpRequestMethod
|
|||
extern HttpStatus ParseeSetRequestJSON(HttpClientContext *, HashMap *);
|
||||
|
||||
/* This function is called on every event received, and routes/manages it. */
|
||||
extern void ParseeEventHandler(const ParseeConfig *, HashMap *);
|
||||
extern void ParseeEventHandler(ParseeData *, HashMap *);
|
||||
|
||||
/* Verifies if a user is a Parsee puppet user. */
|
||||
extern bool ParseeIsPuppet(const ParseeConfig *, char *);
|
||||
|
||||
/* Decodes a local JID for a user into a string. */
|
||||
extern char * ParseeDecodeLocalJID(const ParseeConfig *, char *);
|
||||
|
||||
/* Gets the localpart of a MXID */
|
||||
extern char * ParseeGetLocal(char *);
|
||||
|
||||
/* Encodes an MXID to a valid Jabber ID head */
|
||||
extern char * ParseeEncodeMXID(char *);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ typedef struct ParseeHttpArg {
|
|||
/* A list of all routes. */
|
||||
#define ROUTES X_ROUTE("/", RouteRoot) \
|
||||
X_ROUTE("/_matrix/app/v1/transactions/(.*)", RouteTxns) \
|
||||
X_ROUTE("/_matrix/app/v1/ping", RoutePing)
|
||||
X_ROUTE("/_matrix/app/v1/ping", RoutePing) \
|
||||
X_ROUTE("/_matrix/app/v1/users/(.*)", RouteUserAck)
|
||||
|
||||
#define X_ROUTE(path, name) extern void * name(Array *, void *);
|
||||
ROUTES
|
||||
|
|
|
|||
|
|
@ -3,17 +3,26 @@
|
|||
|
||||
#include <Cytoplasm/Stream.h>
|
||||
|
||||
typedef struct XMPPComponent {
|
||||
char *host;
|
||||
Stream *stream;
|
||||
} XMPPComponent;
|
||||
|
||||
/* Initialises a raw component stream to host, with an optional port.
|
||||
* If said port is 0, then it is set to the default Prosody port */
|
||||
extern Stream * XMPPInitialiseCompStream(char *host, int port);
|
||||
extern XMPPComponent * XMPPInitialiseCompStream(char *host, int port);
|
||||
|
||||
/* Authenticates a component stream with a given shared secret,
|
||||
* with a stream ID from the server. This should be called right
|
||||
* after XMPPInitialiseCompStream. */
|
||||
extern bool XMPPAuthenticateCompStream(Stream *stream, char *as, char *shared);
|
||||
extern bool XMPPAuthenticateCompStream(XMPPComponent *comp, char *shared);
|
||||
|
||||
/* Sends a presence to a user */
|
||||
extern void XMPPSendPresence(XMPPComponent *comp, char *fr, char *to);
|
||||
|
||||
/* TODO: XMPP stuff, I don't fucking know, I'm not a Jabbernerd. */
|
||||
extern void XMPPSendPlain(XMPPComponent *c, char *f, char *t, char *m, char *type);
|
||||
|
||||
/* Closes a raw component stream. */
|
||||
extern void XMPPEndCompStream(Stream *stream);
|
||||
extern void XMPPEndCompStream(XMPPComponent *stream);
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue