diff --git a/etc/man/man7/.parsee-bridge-guidebook.7.swp b/etc/man/man7/.parsee-bridge-guidebook.7.swp new file mode 100644 index 0000000..50976ea Binary files /dev/null and b/etc/man/man7/.parsee-bridge-guidebook.7.swp differ diff --git a/etc/man/man7/.parsee-cmd-syntax.7.swp b/etc/man/man7/.parsee-cmd-syntax.7.swp new file mode 100644 index 0000000..64990b7 Binary files /dev/null and b/etc/man/man7/.parsee-cmd-syntax.7.swp differ diff --git a/etc/man/man7/parsee-bridge-guidebook.7 b/etc/man/man7/parsee-bridge-guidebook.7 new file mode 100644 index 0000000..b5932f2 --- /dev/null +++ b/etc/man/man7/parsee-bridge-guidebook.7 @@ -0,0 +1,70 @@ +." The last field is the codename, by the way. +." ALL MANPAGES FOR PARSEE ARE UNDER PUBLIC DOMAIN +.TH parsee-bridge-guidebook 7 "Parsee Utility" "star-of-hope" + +.SH NAME +parsee-bridge-guidebook - A short guidebook on running a Parsee bridge + +.SH INTRODUCTION +.P +This manpage is intended to be a guidebook for Parsee administrators. It +is meant to show how to create an instance with an XMPP-Matrix server +(though it cannot be specific, due to their ecosystem diversity), how to +plumb rooms, and moderate them through. +.P +It also assumes Parsee is properly built and installed, in which case you +are seeing this from +.I man +itself. + +.SH CONVENTIONS +This page shall assume a few things that +.B must +be changed to fit your configuration. Please read those carefully, or it +will come and bite at you! + +.P +First off, it assumes that you have a domain at +.I blow.hole +and that any other domains related to Parsee are it's subdomains, as +you'll see. + +.P +We also assume you're planning on making the XMPP component available at +.I j.blow.hole , +and that Parsee can reach it by using +.I localhost:1234 . +It is highly recommended that Parsee can reach the component locally, as +the stream cannot be encrypted! + +.P +The Parsee HTTP server (which is used for media and the appservice) shall +be reached through +.I https://p.blow.hole/ +via a reverse proxy. This manual shall only show you what port to make +available, as there are many reverse proxy options available. + +.P +Finally, the Matrix server will be publicly known as +.I m.blow.hole +. + +That is, if +.B bob +is in it, then they shall be known as +.I @bob:m.blow.hole . + +.SH SETTING UP +Setting up Parsee mainly involves creating a valid configuration file +and the database. Most of this however is dealt with by +.I parsee-config(1) +TODO + +.P + +.SH LICENSE +This document is under public domain, or CC0 if not allowed by local law. + +.SH SEE ALSO +.B parsee(1), parsee-cmd-syntax(7) + diff --git a/src/MatrixEventHandler.c b/src/MatrixEventHandler.c index 89e342d..60a41c7 100644 --- a/src/MatrixEventHandler.c +++ b/src/MatrixEventHandler.c @@ -30,13 +30,16 @@ JoinMUC(ParseeData *data, HashMap *event, char *jid, char *muc, char *name, char UnistrFree(uninick); UnistrFree(filtered); + UnistrFree(filterASCII); - /* TODO: vCards! */ + /* TODO: Make sure that we fall back to plain ASCII if it fails too many + * times. */ while (!XMPPJoinMUC(data->jabber, jid, rev, hash, -1, true) && nonce < 32) { char *nonce_str = StrInt(nonce); char *input = StrConcat(3, sender, name, nonce_str); char *hex = ParseeHMACS(data->id, input); + Unistr *filterASCII = UnistrFilter(uninick, UnistrIsASCII); if (strlen(hex) >= 8) { @@ -45,6 +48,7 @@ JoinMUC(ParseeData *data, HashMap *event, char *jid, char *muc, char *name, char Free(nick); Free(rev); + Free(revscii); nick = StrConcat(4, name, "[", hex, "]"); rev = StrConcat(3, muc, "/", nick); @@ -364,13 +368,13 @@ ParseeMessageHandler(ParseeData *data, HashMap *event) StanzaBuilder *builder = NULL; DbRef *ref = NULL; HashMap *json = NULL; - - char *unedited_id = MatrixGetEdit(event); + + char *m_sender = GrabString(event, 1, "sender"); + char *unedited_id = NULL; char *body = GrabString(event, 2, "content", "body"); char *id = GrabString(event, 1, "room_id"); char *ev_id = GrabString(event, 1, "event_id"); - char *m_sender = GrabString(event, 1, "sender"); - char *chat_id, *muc_id; + char *chat_id = NULL, *muc_id = NULL; char *reply_id = MatrixGetReply(event); char *xepd = ParseeXMPPify(event); char *type, *user, *xmppified_user = NULL, *to = NULL; @@ -381,6 +385,7 @@ ParseeMessageHandler(ParseeData *data, HashMap *event) char *encoded_from = NULL; bool direct = false; + unedited_id = MatrixGetEdit(event); if (unedited_id) { @@ -455,6 +460,7 @@ ParseeMessageHandler(ParseeData *data, HashMap *event) Free(name); Free(avatar); } + if (reply_id) { /* TODO: Monocles chat DM users HATE this trick! @@ -511,8 +517,8 @@ end: Free(stanza); Free(sender); Free(unauth); - Free(unedited_id); Free(encoded_from); + Free(unedited_id); DbUnlock(data->db, ref); ref = NULL; diff --git a/src/Parsee/Utils/Formatting.c b/src/Parsee/Utils/Formatting.c index 2abf3b5..8f41a56 100644 --- a/src/Parsee/Utils/Formatting.c +++ b/src/Parsee/Utils/Formatting.c @@ -210,9 +210,11 @@ XMPPifyElement(HashMap *event, XMLElement *elem, XMPPFlags flags) static char * GetRawBody(HashMap *event) { - if (MatrixGetEdit(event)) + void *id; + if ((id = MatrixGetEdit(event))) { char *new = GrabString(event, 3, "content", "m.new_content", "body"); + Free(id); if (new) { return new; diff --git a/src/Unistr.c b/src/Unistr.c index 5eaae43..a1eb1e4 100644 --- a/src/Unistr.c +++ b/src/Unistr.c @@ -192,6 +192,16 @@ UnistrGetch(Unistr *unistr, size_t i) return i < unistr->length ? unistr->codepoints[i] : 0; } bool +UnistrIsASCII(uint32_t u) +{ + if (u == 0) + { + return NULL; + } + + return u < 0x7F; +} +bool UnistrIsBMP(uint32_t u) { if (u == 0) diff --git a/src/XMPPThread/Stanzas/IQ.c b/src/XMPPThread/Stanzas/IQ.c index 17092b0..af71cca 100644 --- a/src/XMPPThread/Stanzas/IQ.c +++ b/src/XMPPThread/Stanzas/IQ.c @@ -572,7 +572,7 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr) else if (XMLookForTKV(stanza, "query", "xmlns", "jabber:iq:version")) { XMLElement *iq_reply, *query; - XMLElement *name, *version; + XMLElement *name, *version, *os; iq_reply = XMLCreateTag("iq"); XMLAddAttr(iq_reply, "to", from); @@ -585,12 +585,15 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr) { name = XMLCreateTag("name"); version = XMLCreateTag("version"); + os = XMLCreateTag("os"); XMLAddChild(name, XMLCreateText(NAME)); XMLAddChild(version, XMLCreateText(VERSION "[" CODE "]")); + XMLAddChild(os, XMLCreateText(VERSION "POSIX-like")); } XMLAddChild(query, name); XMLAddChild(query, version); + XMLAddChild(query, os); XMLAddChild(iq_reply, query); XMPPSendStanza(jabber, iq_reply, args->config->max_stanza_size); diff --git a/src/XMPPThread/Stanzas/Presence.c b/src/XMPPThread/Stanzas/Presence.c index 65c2082..947fc4b 100644 --- a/src/XMPPThread/Stanzas/Presence.c +++ b/src/XMPPThread/Stanzas/Presence.c @@ -298,7 +298,7 @@ end_item: Free(room); FreeStatuses(statuses); } - if (status) + if (status && !StrEquals(type, "unavailable")) { XMLElement *status_data = ArrayGet(status->children, 0); char *decode_from = ParseeLookupJID(oid); @@ -309,6 +309,8 @@ end_item: status_str = status_data->data; } + + /* TODO: "The server will automatically set a user's presence to * unavailable if their last active time was over a threshold value * (e.g. 5 minutes)." diff --git a/src/include/Unistring.h b/src/include/Unistring.h index 6fbc296..d90d61c 100644 --- a/src/include/Unistring.h +++ b/src/include/Unistring.h @@ -64,6 +64,12 @@ extern void UnistrFree(Unistr *unistr); * Returns: whenever the character is within the BMP */ extern bool UnistrIsBMP(uint32_t u); +/** Returns true IFF the character is within the 7-bit ASCII range + * not 0x0000 + * ------------------------------------------------------------ + * Returns: whenever the character is within ASCII */ +extern bool UnistrIsASCII(uint32_t u); + typedef bool (*UnistrFilterFunc)(uint32_t u); /** "Filters" characters in a Unistring by codepoint, removing * those with callbacks which return false into a new unistring.