Merge branch 'master' of ssh://git.citadel.org/appl/gitroot/citadel
authorArt Cancro <ajc@uncensored.citadel.org>
Wed, 31 Dec 2014 15:26:45 +0000 (10:26 -0500)
committerArt Cancro <ajc@uncensored.citadel.org>
Wed, 31 Dec 2014 15:26:45 +0000 (10:26 -0500)
Conflicts:
citadel/modules/xmpp/serv_xmpp.c
citadel/modules/xmpp/xmpp_presence.c
citadel/modules/xmpp/xmpp_query_namespace.c

citadel/modules/xmpp/serv_xmpp.c
citadel/modules/xmpp/xmpp_presence.c
citadel/modules/xmpp/xmpp_query_namespace.c
citadel/modules/xmpp/xmpp_queue.c
citadel/modules/xmpp/xmpp_sasl_service.c

index 7986cb573fdb254de00bac8f1684f79cff2896e6..126385129c82bdaa73faf9e20ed693a0d0c59904 100644 (file)
@@ -17,6 +17,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+// uncomment for more verbosity
+#define XMPP_DEBUG 1
+
 #include "sysdep.h"
 #include <stdlib.h>
 #include <unistd.h>
@@ -76,7 +79,11 @@ static void xmpp_entity_declaration(void *userData, const XML_Char *entityName,
                                const XML_Char *systemId, const XML_Char *publicId,
                                const XML_Char *notationName
 ) {
+<<<<<<< HEAD
+       syslog(LOG_WARNING, "Illegal entity declaration encountered; stopping parser.");
+=======
        XMPPM_syslog(LOG_WARNING, "Illegal entity declaration encountered; stopping parser.");
+>>>>>>> 1c0b8162b0a90f2e97028a531005c11b09441498
        XML_StopParser(XMPP->xp, XML_FALSE);
 }
 #endif
@@ -208,13 +215,21 @@ void xmpp_stream_start(void *data, const char *supplied_el, const char **attr)
 
        /*
         * TLS encryption (but only if it isn't already active)
+<<<<<<< HEAD
+        */ 
+=======
         * / 
+>>>>>>> 1c0b8162b0a90f2e97028a531005c11b09441498
 #ifdef HAVE_OPENSSL
        if (!CC->redirect_ssl) {
                cprintf("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'></starttls>");
        }
 #endif
+<<<<<<< HEAD
+
+=======
        */
+>>>>>>> 1c0b8162b0a90f2e97028a531005c11b09441498
        if (!CC->logged_in) {
                /* If we're not logged in yet, offer SASL as our feature set */
                xmpp_output_auth_mechs();
@@ -226,13 +241,22 @@ void xmpp_stream_start(void *data, const char *supplied_el, const char **attr)
        /* Offer binding and sessions as part of our feature set */
        cprintf("<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"/>");
        cprintf("<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/>");
+<<<<<<< HEAD
+
+       cprintf("</stream:features>");
+=======
+>>>>>>> 1c0b8162b0a90f2e97028a531005c11b09441498
 
        cprintf("</stream:features>");
 
+<<<<<<< HEAD
+
+=======
        CC->is_async = 1;               /* XMPP sessions are inherently async-capable */
 }
 
 
+>>>>>>> 1c0b8162b0a90f2e97028a531005c11b09441498
 void xmpp_xml_start(void *data, const char *supplied_el, const char **attr) {
        char el[256];
        char *sep = NULL;
@@ -244,12 +268,21 @@ void xmpp_xml_start(void *data, const char *supplied_el, const char **attr) {
                strcpy(el, ++sep);
        }
 
+<<<<<<< HEAD
+#ifdef XMPP_DEBUG
+       syslog(LOG_DEBUG, "XMPP ELEMENT START: <%s>\n", el);
+       for (i=0; attr[i] != NULL; i+=2) {
+               syslog(LOG_DEBUG, "                    Attribute '%s' = '%s'\n", attr[i], attr[i+1]);
+       }
+#endif /* XMPP_DEBUG */
+=======
        /*
        XMPP_syslog(LOG_DEBUG, "XMPP ELEMENT START: <%s>\n", el);
        for (i=0; attr[i] != NULL; i+=2) {
                XMPP_syslog(LOG_DEBUG, "                    Attribute '%s' = '%s'\n", attr[i], attr[i+1]);
        }
        uncomment for more verbosity */
+>>>>>>> 1c0b8162b0a90f2e97028a531005c11b09441498
 
        if (!strcasecmp(el, "stream")) {
                xmpp_stream_start(data, supplied_el, attr);
@@ -258,6 +291,46 @@ void xmpp_xml_start(void *data, const char *supplied_el, const char **attr) {
        else if (!strcasecmp(el, "query")) {
                XMPP->iq_query_xmlns[0] = 0;
                safestrncpy(XMPP->iq_query_xmlns, supplied_el, sizeof XMPP->iq_query_xmlns);
+<<<<<<< HEAD
+       }
+
+       else if (!strcasecmp(el, "bind")) {
+               XMPP->bind_requested = 1;
+       }
+
+       else if (!strcasecmp(el, "iq")) {
+               for (i=0; attr[i] != NULL; i+=2) {
+                       if (!strcasecmp(attr[i], "type")) {
+                               safestrncpy(XMPP->iq_type, attr[i+1], sizeof XMPP->iq_type);
+                       }
+                       else if (!strcasecmp(attr[i], "id")) {
+                               safestrncpy(XMPP->iq_id, attr[i+1], sizeof XMPP->iq_id);
+                       }
+                       else if (!strcasecmp(attr[i], "from")) {
+                               safestrncpy(XMPP->iq_from, attr[i+1], sizeof XMPP->iq_from);
+                       }
+                       else if (!strcasecmp(attr[i], "to")) {
+                               safestrncpy(XMPP->iq_to, attr[i+1], sizeof XMPP->iq_to);
+                       }
+               }
+       }
+
+       else if (!strcasecmp(el, "auth")) {
+               XMPP->sasl_auth_mech[0] = 0;
+               for (i=0; attr[i] != NULL; i+=2) {
+                       if (!strcasecmp(attr[i], "mechanism")) {
+                               safestrncpy(XMPP->sasl_auth_mech, attr[i+1], sizeof XMPP->sasl_auth_mech);
+                       }
+               }
+       }
+
+       else if (!strcasecmp(el, "message")) {
+               for (i=0; attr[i] != NULL; i+=2) {
+                       if (!strcasecmp(attr[i], "to")) {
+                               safestrncpy(XMPP->message_to, attr[i+1], sizeof XMPP->message_to);
+                       }
+               }
+=======
        }
 
        else if (!strcasecmp(el, "bind")) {
@@ -320,9 +393,62 @@ void xmpp_xml_end(void *data, const char *supplied_el) {
        XMPP_syslog(LOG_DEBUG, "XMPP ELEMENT END  : <%s>\n", el);
        if (XMPP->chardata_len > 0) {
                XMPP_syslog(LOG_DEBUG, "          chardata: %s\n", XMPP->chardata);
+>>>>>>> 1c0b8162b0a90f2e97028a531005c11b09441498
        }
-       uncomment for more verbosity */
 
+<<<<<<< HEAD
+       else if (!strcasecmp(el, "html")) {
+               ++XMPP->html_tag_level;
+       }
+}
+
+
+
+void xmpp_xml_end(void *data, const char *supplied_el) {
+       char el[256];
+       char *sep = NULL;
+       char xmlbuf[256];
+
+       /* Axe the namespace, we don't care about it */
+       safestrncpy(el, supplied_el, sizeof el);
+       while (sep = strchr(el, ':'), sep) {
+               strcpy(el, ++sep);
+       }
+
+#ifdef XMPP_DEBUG
+       syslog(LOG_DEBUG, "XMPP ELEMENT END  : <%s>\n", el);
+       if (XMPP->chardata_len > 0) {
+               syslog(LOG_DEBUG, "          chardata: %s\n", XMPP->chardata);
+       }
+#endif /* XMPP_DEBUG */
+
+       if (!strcasecmp(el, "resource")) {
+               if (XMPP->chardata_len > 0) {
+                       safestrncpy(XMPP->iq_client_resource, XMPP->chardata,
+                               sizeof XMPP->iq_client_resource);
+                       striplt(XMPP->iq_client_resource);
+               }
+       }
+
+       else if (!strcasecmp(el, "username")) {         /* NON SASL ONLY */
+               if (XMPP->chardata_len > 0) {
+                       safestrncpy(XMPP->iq_client_username, XMPP->chardata,
+                               sizeof XMPP->iq_client_username);
+                       striplt(XMPP->iq_client_username);
+               }
+       }
+
+       else if (!strcasecmp(el, "password")) {         /* NON SASL ONLY */
+               if (XMPP->chardata_len > 0) {
+                       safestrncpy(XMPP->iq_client_password, XMPP->chardata,
+                               sizeof XMPP->iq_client_password);
+                       striplt(XMPP->iq_client_password);
+               }
+       }
+
+       else if (!strcasecmp(el, "iq")) {
+
+=======
        if (!strcasecmp(el, "resource")) {
                if (XMPP->chardata_len > 0) {
                        safestrncpy(XMPP->iq_client_resource, XMPP->chardata,
@@ -349,6 +475,7 @@ void xmpp_xml_end(void *data, const char *supplied_el) {
 
        else if (!strcasecmp(el, "iq")) {
 
+>>>>>>> 1c0b8162b0a90f2e97028a531005c11b09441498
                /*
                 * iq type="get" (handle queries)
                 */
@@ -380,7 +507,11 @@ void xmpp_xml_end(void *data, const char *supplied_el) {
                         * Unknown query ... return the XML equivalent of a blank stare
                         */
                        else {
+<<<<<<< HEAD
+                               syslog(LOG_DEBUG,
+=======
                                XMPP_syslog(LOG_DEBUG,
+>>>>>>> 1c0b8162b0a90f2e97028a531005c11b09441498
                                            "Unknown query <%s> - returning <service-unavailable/>\n",
                                            el
                                );
@@ -512,6 +643,23 @@ void xmpp_xml_end(void *data, const char *supplied_el) {
 
        else if (!strcasecmp(el, "ping")) {
                XMPP->ping_requested = 1;
+<<<<<<< HEAD
+       }
+
+       else if (!strcasecmp(el, "stream")) {
+               syslog(LOG_DEBUG, "XMPP client shut down their stream\n");
+               xmpp_massacre_roster();
+               cprintf("</stream>\n");
+               CC->kill_me = KILLME_CLIENT_LOGGED_OUT;
+       }
+
+       else if (!strcasecmp(el, "query")) {
+               // no action required here, we picked up the xmlns= parameter during xmpp_xml_start()
+       }
+
+       else {
+               syslog(LOG_DEBUG, "Ignoring unknown tag <%s>\n", el);
+=======
        }
 
        else if (!strcasecmp(el, "stream")) {
@@ -523,6 +671,7 @@ void xmpp_xml_end(void *data, const char *supplied_el) {
 
        else {
                XMPP_syslog(LOG_DEBUG, "Ignoring unknown tag <%s>\n", el);
+>>>>>>> 1c0b8162b0a90f2e97028a531005c11b09441498
        }
 
        XMPP->chardata_len = 0;
@@ -587,7 +736,7 @@ void xmpp_greeting(void) {
 
        XMPP->xp = XML_ParserCreateNS("UTF-8", ':');
        if (XMPP->xp == NULL) {
-               XMPPM_syslog(LOG_ALERT, "Cannot create XML parser!\n");
+               syslog(LOG_ALERT, "Cannot create XML parser!\n");
                CC->kill_me = KILLME_XML_PARSER;
                return;
        }
@@ -621,10 +770,11 @@ void xmpp_command_loop(void) {
        time(&CC->lastcmd);
        rc = client_read_random_blob(stream_input, 30);
        if (rc > 0) {
+               syslog(LOG_DEBUG, "\033[32m%s\033[0m", ChrPtr(stream_input));
                XML_Parse(XMPP->xp, ChrPtr(stream_input), rc, 0);
        }
        else {
-               XMPPM_syslog(LOG_ERR, "client disconnected: ending session.\n");
+               syslog(LOG_ERR, "client disconnected: ending session.\n");
                CC->kill_me = KILLME_CLIENT_DISCONNECTED;
        }
        FreeStrBuf(&stream_input);
index ca8a95949d8d95b10dc7e8d679787ab072a600ac..4c2d50ade321a9cdfe4ede9ef1d9de0bc5b5cb0f 100644 (file)
@@ -67,6 +67,10 @@ void xmpp_indicate_presence(char *presence_jid)
 {
        char xmlbuf[256];
 
+<<<<<<< HEAD
+       syslog(LOG_DEBUG, "XMPP: indicating presence of <%s> to <%s>", presence_jid, XMPP->client_jid);
+=======
+>>>>>>> 1c0b8162b0a90f2e97028a531005c11b09441498
        cprintf("<presence from=\"%s\" ", xmlesc(xmlbuf, presence_jid, sizeof xmlbuf));
        cprintf("to=\"%s\"></presence>", xmlesc(xmlbuf, XMPP->client_jid, sizeof xmlbuf));
 }
@@ -171,7 +175,7 @@ void xmpp_destroy_buddy(char *presence_jid, int aggressively) {
  */
 void xmpp_presence_notify(char *presence_jid, int event_type) {
        struct CitContext *cptr;
-       static int unsolicited_id;
+       static int unsolicited_id = 12345;
        int visible_sessions = 0;
        int nContexts, i;
        int which_cptr_is_relevant = (-1);
@@ -194,13 +198,11 @@ void xmpp_presence_notify(char *presence_jid, int event_type) {
                }
        }
 
-       XMPP_syslog(LOG_DEBUG, "%d sessions for <%s> are now visible to session %d\n",
-                   visible_sessions, presence_jid, CC->cs_pid);
+       syslog(LOG_DEBUG, "%d sessions for <%s> are now visible to session %d\n", visible_sessions, presence_jid, CC->cs_pid);
 
        if ( (event_type == XMPP_EVT_LOGIN) && (visible_sessions == 1) ) {
 
-               XMPP_syslog(LOG_DEBUG, "Telling session %d that <%s> logged in\n",
-                           CC->cs_pid, presence_jid);
+               syslog(LOG_DEBUG, "Telling session %d that <%s> logged in\n", CC->cs_pid, presence_jid);
 
                /* Do an unsolicited roster update that adds a new contact. */
                assert(which_cptr_is_relevant >= 0);
@@ -214,7 +216,7 @@ void xmpp_presence_notify(char *presence_jid, int event_type) {
        }
 
        if (visible_sessions == 0) {
-               XMPP_syslog(LOG_DEBUG, "Telling session %d that <%s> logged out\n",
+               syslog(LOG_DEBUG, "Telling session %d that <%s> logged out\n",
                            CC->cs_pid, presence_jid);
                xmpp_destroy_buddy(presence_jid, 0);    /* non aggressive presence update */
        }
@@ -271,7 +273,7 @@ void xmpp_fetch_mortuary_backend(long msgnum, void *userdata) {
 HashList *xmpp_fetch_mortuary(void) {
        HashList *mortuary = NewHash(1, NULL);
        if (!mortuary) {
-               XMPPM_syslog(LOG_ALERT, "NewHash() failed!\n");
+               syslog(LOG_ALERT, "NewHash() failed!\n");
                return(NULL);
        }
 
index cf6f423a56516cd392ce78ae9c79f93d486ff2f5..fb3374e9e73984a91d1584ab90007171305cd0ad 100644 (file)
@@ -3,19 +3,13 @@
  *
  * Copyright (c) 2007-2009 by Art Cancro
  *
- *  This program is open source software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3.
- *  
- *  
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  
- *  
- *  
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #include "sysdep.h"
@@ -71,6 +65,7 @@ void xmpp_roster_item(struct CitContext *cptr) {
        cprintf("</item>");
 }
 
+
 /* 
  * Return the results for a "jabber:iq:roster:query"
  *
@@ -88,7 +83,7 @@ void xmpp_iq_roster_query(void)
        if (cptr) {
                for (i=0; i<nContexts; i++) {
                        if (xmpp_is_visible(&cptr[i], CC)) {
-                               XMPP_syslog(LOG_DEBUG, "Rosterizing %s\n", cptr[i].user.fullname);
+                               syslog(LOG_DEBUG, "Rosterizing %s\n", cptr[i].user.fullname);
                                xmpp_roster_item(&cptr[i]);
                        }
                }
@@ -98,15 +93,15 @@ void xmpp_iq_roster_query(void)
 }
 
 
+
 /*
- * TODO: handle queries on some or all of these namespaces
- *
-xmpp_query_namespace(purple5b5c1e58, splorph.xand.com, http://jabber.org/protocol/disco#items:query)
-xmpp_query_namespace(purple5b5c1e59, splorph.xand.com, http://jabber.org/protocol/disco#info:query)
-xmpp_query_namespace(purple5b5c1e5a, , vcard-temp:query)
- *
+ * Client is doing a namespace query.  These are all handled differently.
+ * A "rumplestiltskin lookup" is the most efficient way to handle this.  Please do not refactor this code.
  */
+<<<<<<< HEAD
+=======
 
+>>>>>>> 1c0b8162b0a90f2e97028a531005c11b09441498
 void xmpp_query_namespace(char *iq_id, char *iq_from, char *iq_to, char *query_xmlns)
 {
        int supported_namespace = 0;
@@ -120,11 +115,17 @@ void xmpp_query_namespace(char *iq_id, char *iq_from, char *iq_to, char *query_x
        if (
                (!strcasecmp(query_xmlns, "jabber:iq:roster:query"))
                || (!strcasecmp(query_xmlns, "jabber:iq:auth:query"))
+               || (!strcasecmp(query_xmlns, "http://jabber.org/protocol/disco#items:query"))
+               || (!strcasecmp(query_xmlns, "http://jabber.org/protocol/disco#info:query"))
        ) {
                supported_namespace = 1;
        }
 
+<<<<<<< HEAD
+       syslog(LOG_DEBUG, "xmpp_query_namespace(id=%s, from=%s, to=%s, xmlns=%s)\n", iq_id, iq_from, iq_to, query_xmlns);
+=======
        XMPP_syslog(LOG_DEBUG, "xmpp_query_namespace(%s, %s, %s, %s)\n", iq_id, iq_from, iq_to, query_xmlns);
+>>>>>>> 1c0b8162b0a90f2e97028a531005c11b09441498
 
        /*
         * Beginning of query result.
@@ -134,10 +135,17 @@ void xmpp_query_namespace(char *iq_id, char *iq_from, char *iq_to, char *query_x
        }
        else {
                cprintf("<iq type=\"error\" ");
+<<<<<<< HEAD
        }
        if (!IsEmptyStr(iq_from)) {
                cprintf("to=\"%s\" ", xmlesc(xmlbuf, iq_from, sizeof xmlbuf));
        }
+=======
+       }
+       if (!IsEmptyStr(iq_from)) {
+               cprintf("to=\"%s\" ", xmlesc(xmlbuf, iq_from, sizeof xmlbuf));
+       }
+>>>>>>> 1c0b8162b0a90f2e97028a531005c11b09441498
        cprintf("id=\"%s\">", xmlesc(xmlbuf, iq_id, sizeof xmlbuf));
 
        /*
@@ -156,16 +164,30 @@ void xmpp_query_namespace(char *iq_id, char *iq_from, char *iq_to, char *query_x
                );
        }
 
+       // Extension "xep-0030" (http://xmpp.org/extensions/xep-0030.html) (return an empty set of results)
+       else if (!strcasecmp(query_xmlns, "http://jabber.org/protocol/disco#items:query")) {
+               cprintf("<query xmlns=\"%s\"/>", xmlesc(xmlbuf, query_xmlns, sizeof xmlbuf));
+       }
+
+       // Extension "xep-0030" (http://xmpp.org/extensions/xep-0030.html) (return an empty set of results)
+       else if (!strcasecmp(query_xmlns, "http://jabber.org/protocol/disco#info:query")) {
+               cprintf("<query xmlns=\"%s\"/>", xmlesc(xmlbuf, query_xmlns, sizeof xmlbuf));
+       }
+
        /*
         * If we didn't hit any known query namespaces then we should deliver a
         * "service unavailable" error (see RFC3921 section 2.4 and 11.1.5.4)
         */
 
        else {
+<<<<<<< HEAD
+               syslog(LOG_DEBUG, "Unknown query namespace '%s' - returning <service-unavailable/>\n", query_xmlns);
+=======
                XMPP_syslog(LOG_DEBUG,
                            "Unknown query namespace '%s' - returning <service-unavailable/>\n",
                            query_xmlns
                );
+>>>>>>> 1c0b8162b0a90f2e97028a531005c11b09441498
                cprintf("<error code=\"503\" type=\"cancel\">"
                        "<service-unavailable xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/>"
                        "</error>"
index 8cb5662d89f846728c2b53140692325e18553b79..530ea5a76942131f5b69dba7adfa563377380478 100644 (file)
@@ -66,7 +66,7 @@ void xmpp_queue_event(int event_type, char *email_addr) {
        int purged_something = 0;
        struct CitContext *cptr;
 
-       XMPP_syslog(LOG_DEBUG, "xmpp_queue_event(%d, %s)\n", event_type, email_addr);
+       syslog(LOG_DEBUG, "xmpp_queue_event(%d, %s)\n", event_type, email_addr);
 
        /* Purge events more than a minute old */
        begin_critical_section(S_XMPP_QUEUE);
index e7ad1a2b19f40e035750d0d2b750a9abc8957856..393174dce18b2cf78901e61aa1955743d84f08fc 100644 (file)
  */
 int xmpp_auth_plain(char *authstring)
 {
-       StrBuf *AuthBuf;
-       const char *decoded_authstring;
-       char ident[256] = "";
-       char user[256] = "";
-       char pass[256] = "";
+       char decoded_authstring[1024];
+       char ident[256];
+       char user[256];
+       char pass[256];
        int result;
        long len;
 
@@ -77,25 +76,12 @@ int xmpp_auth_plain(char *authstring)
        /* Take apart the authentication string */
        memset(pass, 0, sizeof(pass));
 
-       AuthBuf = NewStrBufPlain(authstring, -1);
-       len = StrBufDecodeBase64(AuthBuf);
-       if (len > 0)
-       {
-               decoded_authstring = ChrPtr(AuthBuf);
-
-               len = safestrncpy(ident, decoded_authstring, sizeof ident);
-
-               decoded_authstring += len + 1;
-
-               len = safestrncpy(user, decoded_authstring, sizeof user);
-
-               decoded_authstring += len + 1;
-
-               len = safestrncpy(pass, decoded_authstring, sizeof pass);
-               if (len < 0)
-                       len = sizeof(pass) - 1;
-       }
-       FreeStrBuf(&AuthBuf);
+       CtdlDecodeBase64(decoded_authstring, authstring, strlen(authstring));
+       safestrncpy(ident, decoded_authstring, sizeof ident);
+       safestrncpy(user, &decoded_authstring[strlen(ident) + 1], sizeof user);
+       len = safestrncpy(pass, &decoded_authstring[strlen(ident) + strlen(user) + 2], sizeof pass);
+       if (len < 0)
+               len = -len;
 
        /* If there are underscores in either string, change them to spaces.  Some clients
         * do not allow spaces so we can tell the user to substitute underscores if their