mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 18:35:11 +00:00
[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:
parent
f7eace20c7
commit
868f0e4d9c
7 changed files with 207 additions and 11 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -2,3 +2,5 @@ build/*
|
||||||
build
|
build
|
||||||
parsee*
|
parsee*
|
||||||
parsee
|
parsee
|
||||||
|
*.swp
|
||||||
|
.*
|
||||||
|
|
|
||||||
14
src/Main.c
14
src/Main.c
|
|
@ -4,6 +4,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <Parsee.h>
|
#include <Parsee.h>
|
||||||
|
#include <XMPP.h>
|
||||||
#include <XML.h>
|
#include <XML.h>
|
||||||
#include <AS.h>
|
#include <AS.h>
|
||||||
|
|
||||||
|
|
@ -15,6 +16,19 @@ Main(void)
|
||||||
ParseeData *data;
|
ParseeData *data;
|
||||||
const ParseeConfig *parsee_conf;
|
const ParseeConfig *parsee_conf;
|
||||||
Stream *yaml;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
Log(LOG_INFO, "%s - v%s", NAME, VERSION);
|
Log(LOG_INFO, "%s - v%s", NAME, VERSION);
|
||||||
ParseeConfigLoad("parsee.json");
|
ParseeConfigLoad("parsee.json");
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,82 @@
|
||||||
#include <XML.h>
|
#include <XML.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/Log.h>
|
||||||
|
|
||||||
/* TODO: The rest of all that. */
|
/* TODO: The rest of all that. */
|
||||||
|
|
||||||
XMLElement *
|
XMLElement *
|
||||||
XMLDecode(Stream *stream, bool autofree)
|
XMLDecode(Stream *stream, bool autofree)
|
||||||
{
|
{
|
||||||
/* TODO: Use the existing SAX parser to decode everything */
|
/* TODO: Use the existing SAX parser to decode everything */
|
||||||
|
#define push(x) ArrayAdd(stack, x)
|
||||||
|
#define pop(x) ArrayDelete(stack, ArraySize(stack) - 1)
|
||||||
|
#define peek(x) ArrayGet(stack, ArraySize(stack) - 1)
|
||||||
|
XMLexer *lexer;
|
||||||
|
XMLEvent *event;
|
||||||
|
XMLElement *ret = NULL;
|
||||||
|
XMLElement *top;
|
||||||
|
char *key, *val;
|
||||||
|
|
||||||
|
Array *stack;
|
||||||
|
|
||||||
|
if (!stream)
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
lexer = XMLCreateLexer(stream, autofree);
|
||||||
|
stack = ArrayCreate();
|
||||||
|
while ((event = XMLCrank(lexer)) && (!ret || ArraySize(stack)))
|
||||||
|
{
|
||||||
|
switch (event->type)
|
||||||
|
{
|
||||||
|
case XML_LEXER_STARTELEM:
|
||||||
|
/* Create a new element that will populated. */
|
||||||
|
top = XMLCreateTag(event->element);
|
||||||
|
Log(LOG_INFO, "<%s>", top->name);
|
||||||
|
XMLAddChild(peek(), top);
|
||||||
|
while (HashMapIterate(event->attrs, &key, (void **) &val))
|
||||||
|
{
|
||||||
|
XMLAddAttr(top, key, val);
|
||||||
|
}
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
/* If we didn't have any element before, this one is
|
||||||
|
* going to be our top of the stack */
|
||||||
|
ret = top;
|
||||||
|
}
|
||||||
|
push(top);
|
||||||
|
break;
|
||||||
|
case XML_LEXER_ELEM:
|
||||||
|
/* Create a new element that will populated. */
|
||||||
|
top = XMLCreateTag(event->element);
|
||||||
|
XMLAddChild(peek(), top);
|
||||||
|
Log(LOG_INFO, "<%s />", top->name);
|
||||||
|
while (HashMapIterate(event->attrs, &key, (void **) &val))
|
||||||
|
{
|
||||||
|
XMLAddAttr(top, key, val);
|
||||||
|
}
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
/* If we didn't have any element before, this one is
|
||||||
|
* going to be our top of the stack */
|
||||||
|
ret = top;
|
||||||
|
}
|
||||||
|
push(top);
|
||||||
|
/* Fallthrough */
|
||||||
|
case XML_LEXER_ENDELEM:
|
||||||
|
/* Pop out an element out of the DOM. */
|
||||||
|
Log(LOG_INFO, "</>");
|
||||||
|
pop();
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
XMLFreeEvent(event);
|
||||||
|
event = NULL;
|
||||||
|
}
|
||||||
|
XMLFreeEvent(event);
|
||||||
|
ArrayFree(stack);
|
||||||
|
XMLFreeLexer(lexer);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
#include <Cytoplasm/Memory.h>
|
#include <Cytoplasm/Memory.h>
|
||||||
#include <Cytoplasm/Array.h>
|
#include <Cytoplasm/Array.h>
|
||||||
#include <Cytoplasm/Str.h>
|
#include <Cytoplasm/Str.h>
|
||||||
#include <Cytoplasm/Log.h>
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
@ -24,7 +23,8 @@ struct XMLexer {
|
||||||
|
|
||||||
XML_STATE_ATTR,
|
XML_STATE_ATTR,
|
||||||
XML_STATE_ATTRHEAD_PROP,
|
XML_STATE_ATTRHEAD_PROP,
|
||||||
XML_STATE_ATTRTAIL
|
XML_STATE_ATTRTAIL,
|
||||||
|
XML_STATE_PI
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
@ -161,6 +161,17 @@ XMLCrank(XMLexer *lexer)
|
||||||
lexer->state = XML_STATE_ATTRTAIL;
|
lexer->state = XML_STATE_ATTRTAIL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if (XMLookahead(lexer, "<?", true))
|
||||||
|
{
|
||||||
|
if (lexer->data.str)
|
||||||
|
{
|
||||||
|
XMLFreeEvent(event);
|
||||||
|
event = XMLCreateData(lexer);
|
||||||
|
}
|
||||||
|
|
||||||
|
lexer->state = XML_STATE_PI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
else if (XMLookahead(lexer, "<", true))
|
else if (XMLookahead(lexer, "<", true))
|
||||||
{
|
{
|
||||||
if (lexer->data.str)
|
if (lexer->data.str)
|
||||||
|
|
@ -189,6 +200,14 @@ XMLCrank(XMLexer *lexer)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case XML_STATE_PI:
|
||||||
|
if (XMLookahead(lexer, "?>", true))
|
||||||
|
{
|
||||||
|
lexer->state = XML_STATE_NONE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
XMLGetc(lexer);
|
||||||
|
break;
|
||||||
case XML_STATE_ATTR:
|
case XML_STATE_ATTR:
|
||||||
attrname = XMLParseName(lexer);
|
attrname = XMLParseName(lexer);
|
||||||
if (!attrname)
|
if (!attrname)
|
||||||
|
|
@ -250,7 +269,6 @@ XMLFreeEvent(XMLEvent *event)
|
||||||
void *val;
|
void *val;
|
||||||
while (HashMapIterate(event->attrs, &key, &val))
|
while (HashMapIterate(event->attrs, &key, &val))
|
||||||
{
|
{
|
||||||
Log(LOG_INFO, "Trying to free %s", val);
|
|
||||||
Free(val);
|
Free(val);
|
||||||
}
|
}
|
||||||
HashMapFree(event->attrs);
|
HashMapFree(event->attrs);
|
||||||
|
|
@ -640,6 +658,8 @@ XMLParseAttQuote(XMLexer *lexer)
|
||||||
|
|
||||||
point = XMLInitialiseBuffer(lexer);
|
point = XMLInitialiseBuffer(lexer);
|
||||||
|
|
||||||
|
/* TODO: My Prosody is actually trolling me.
|
||||||
|
* GIVE ME A FUCKING STREAM ID YOU RETARD. */
|
||||||
while ((c = XMLGetc(lexer)))
|
while ((c = XMLGetc(lexer)))
|
||||||
{
|
{
|
||||||
if (!IsNormalQ(c))
|
if (!IsNormalQ(c))
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
#include <XMPP.h>
|
#include <XMPP.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/Memory.h>
|
||||||
|
#include <Cytoplasm/Str.h>
|
||||||
|
#include <Cytoplasm/Log.h>
|
||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -28,7 +32,7 @@ XMPPInitialiseCompStream(char *host, int port)
|
||||||
char serv[8];
|
char serv[8];
|
||||||
Stream *stream;
|
Stream *stream;
|
||||||
|
|
||||||
snprintf(serv, sizeof(serv), "%hu", port);
|
snprintf(serv, sizeof(serv), "%hu", port ? port : DEFAULT_PROSODY_PORT);
|
||||||
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = AF_UNSPEC;
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
|
@ -51,6 +55,7 @@ XMPPInitialiseCompStream(char *host, int port)
|
||||||
sd = -1;
|
sd = -1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
Log(LOG_INFO, "Connected to port %s", serv);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -62,6 +67,7 @@ XMPPInitialiseCompStream(char *host, int port)
|
||||||
freeaddrinfo(res0);
|
freeaddrinfo(res0);
|
||||||
|
|
||||||
stream = StreamFd(sd);
|
stream = StreamFd(sd);
|
||||||
|
Log(LOG_INFO, "Got %d via %p", sd, stream);
|
||||||
if (!stream)
|
if (!stream)
|
||||||
{
|
{
|
||||||
close(sd);
|
close(sd);
|
||||||
|
|
@ -71,13 +77,97 @@ XMPPInitialiseCompStream(char *host, int port)
|
||||||
return stream;
|
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
|
bool
|
||||||
XMPPAuthenticateCompStream(Stream *stream, char *shared)
|
XMPPAuthenticateCompStream(Stream *stream, char *as, char *shared)
|
||||||
{
|
{
|
||||||
/* TODO */
|
/* TODO */
|
||||||
(void) stream;
|
XMLexer *sax;
|
||||||
(void) shared;
|
XMLEvent *ev;
|
||||||
|
char *stream_id, *handshake;
|
||||||
|
bool ret = false;
|
||||||
|
if (!stream || !as || !shared)
|
||||||
|
{
|
||||||
return false;
|
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
|
void
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ typedef struct XMLEvent {
|
||||||
enum {
|
enum {
|
||||||
XML_LEXER_UNKNOWN = 0,
|
XML_LEXER_UNKNOWN = 0,
|
||||||
XML_LEXER_STARTELEM,
|
XML_LEXER_STARTELEM,
|
||||||
XML_LEXER_ELEM, /* Empty attr */
|
|
||||||
XML_LEXER_DATA,
|
XML_LEXER_DATA,
|
||||||
|
XML_LEXER_ELEM, /* Empty attr */
|
||||||
XML_LEXER_ENDELEM,
|
XML_LEXER_ENDELEM,
|
||||||
|
|
||||||
XML_RELAX
|
XML_RELAX
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ extern Stream * XMPPInitialiseCompStream(char *host, int port);
|
||||||
/* Authenticates a component stream with a given shared secret,
|
/* Authenticates a component stream with a given shared secret,
|
||||||
* with a stream ID from the server. This should be called right
|
* with a stream ID from the server. This should be called right
|
||||||
* after XMPPInitialiseCompStream. */
|
* after XMPPInitialiseCompStream. */
|
||||||
extern bool XMPPAuthenticateCompStream(Stream *stream, char *shared);
|
extern bool XMPPAuthenticateCompStream(Stream *stream, char *as, char *shared);
|
||||||
|
|
||||||
/* 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