[ADD/WIP] Begin XMPPwerk

The fuck is a stanza? Presence? Why did Prosody not tell me I'm an idiot
when I clearly made a MALFORMED XML document? This and much more, in the
next commit!
This commit is contained in:
LDA 2024-06-16 11:08:18 +02:00
commit 868f0e4d9c
7 changed files with 207 additions and 11 deletions

View file

@ -1,5 +1,9 @@
#include <XMPP.h>
#include <Cytoplasm/Memory.h>
#include <Cytoplasm/Str.h>
#include <Cytoplasm/Log.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
@ -28,7 +32,7 @@ XMPPInitialiseCompStream(char *host, int port)
char serv[8];
Stream *stream;
snprintf(serv, sizeof(serv), "%hu", port);
snprintf(serv, sizeof(serv), "%hu", port ? port : DEFAULT_PROSODY_PORT);
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
@ -51,6 +55,7 @@ XMPPInitialiseCompStream(char *host, int port)
sd = -1;
continue;
}
Log(LOG_INFO, "Connected to port %s", serv);
break;
}
@ -62,6 +67,7 @@ XMPPInitialiseCompStream(char *host, int port)
freeaddrinfo(res0);
stream = StreamFd(sd);
Log(LOG_INFO, "Got %d via %p", sd, stream);
if (!stream)
{
close(sd);
@ -71,13 +77,97 @@ XMPPInitialiseCompStream(char *host, int port)
return stream;
}
#include <Cytoplasm/Sha.h>
static char *
ComputeHandshake(char *shared, char *stream)
{
char *source;
unsigned char *raw_sha;
char *sha;
source = StrConcat(2, stream, shared);
raw_sha = Sha1(source);
sha = ShaToHex(raw_sha);
Free(raw_sha);
Free(source);
return sha;
}
bool
XMPPAuthenticateCompStream(Stream *stream, char *shared)
XMPPAuthenticateCompStream(Stream *stream, char *as, char *shared)
{
/* TODO */
(void) stream;
(void) shared;
return false;
XMLexer *sax;
XMLEvent *ev;
char *stream_id, *handshake;
bool ret = false;
if (!stream || !as || !shared)
{
return false;
}
StreamPrintf(stream,
"<stream:stream "
"xmlns='jabber:component:accept' "
"xmlns:stream='http://etherx.jabber.org/streams' "
"to='%s'>", as
);
StreamFlush(stream);
sax = XMLCreateLexer(stream, false);
while ((ev = XMLCrank(sax)))
{
if (ev->type == XML_RELAX)
{
XMLFreeEvent(ev);
continue;
}
break;
}
if (ev->type != XML_LEXER_STARTELEM ||
!StrEquals(ev->element, "stream:stream"))
{
Log(LOG_ERR, "Excepted strea:stream element.");
XMLFreeEvent(ev);
goto end;
}
stream_id = StrDuplicate(HashMapGet(ev->attrs, "id"));
handshake = ComputeHandshake(shared, stream_id);
/* y no stream id */
Log(LOG_NOTICE, "- sID='%s'", stream_id);
StreamPrintf(stream, "<handshake>%s</handshake>", handshake);
StreamFlush(stream);
XMLFreeEvent(ev);
while ((ev = XMLCrank(sax)))
{
if (ev->type == XML_RELAX)
{
XMLFreeEvent(ev);
continue;
}
break;
}
if (ev->type != XML_LEXER_ELEM ||
!StrEquals(ev->element, "handshake"))
{
Log(LOG_ERR, "Excepted empty handshake reply, got nonsense.");
Free(stream_id);
Free(handshake);
XMLFreeEvent(ev);
goto end;
}
ret = true;
/* We can uhh, send stanzas, and receive them! */
Log(LOG_INFO, "Communications to '%s' established.", as);
XMLFreeEvent(ev);
Free(stream_id);
Free(handshake);
end:
XMLFreeLexer(sax);
return ret;
}
void