Author: ArcRiley Date: 2009-01-08 01:11:56 -0500 (Thu, 08 Jan 2009) New Revision: 1441
Modified: trunk/concordance/src/Core.c trunk/concordance/src/Core.h Log: * start of element parsing framework * session can now be closed from within XML handlers * depth=1 case now tests per namespace Modified: trunk/concordance/src/Core.c =================================================================== --- trunk/concordance/src/Core.c 2009-01-08 06:09:29 UTC (rev 1440) +++ trunk/concordance/src/Core.c 2009-01-08 06:11:56 UTC (rev 1441) @@ -471,7 +471,7 @@ /* initialize session state */ - newSession->state = CON_E_NONE; + newSession->state = CON_E_OPEN; newSession->depth = 0; @@ -544,7 +544,14 @@ */ status = g_io_channel_read_chars(channel, buff, 4096, &buff_len, NULL); if (status == G_IO_STATUS_NORMAL && buff_len > 0) { - if (XML_Parse(session->pars, buff, buff_len, FALSE)) + /* parse XML data + + XML_Parse will execute the appropriate callback(s) found in the + "XML Handlers" section below. If the stream has been closed + the session->state will be reset to CON_E_CLOSE (== FALSE) + to indicate that the session needs to get wrapped up. + */ + if (XML_Parse(session->pars, buff, buff_len, FALSE) && session->state) /* return true so GMainLoop will continue watching this channel */ return TRUE; } @@ -610,11 +617,110 @@ return (session->wbuff->len != 0); } + /* + # + ########################################################################### + # + # Element responses + # */ + static void + conCore_saslFailure(conSession* session, gchar* failure) { /*\ + cdef : \*/ + GString* buff; + /* printf failure to a GString, then send it + GString* g_string_new (const gchar *init); + void g_string_printf (GString *string, + const gchar *format, + ...); + gchar* g_string_free (GString *string, + gboolean free_segment); + */ + buff = g_string_new(""); + g_string_printf(buff, "<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" + "%s</failure>", failure); + conCore_sessionSend(session, buff->str, buff->len); + g_string_free(buff, TRUE); + } + /* # ########################################################################### # + # Element handlers + # */ + static void + conCore_stream(conSession* session) { /*\ + cdef : \*/ + conCoreObject* self = session->core; + GString* buff; + + /* initialize response buffer + + GString* g_string_new (const gchar *init); + */ + buff = g_string_new(""); + + /* init <stream:stream>, <stream:features>, and <mechanisms> + + void g_string_printf (GString *string, + const gchar *format, + ...); + */ + g_string_printf(buff, "<?xml version='1.0' encoding='UTF-8'?>" + "<stream:stream xmlns='jabber:client'" + " xmlns:stream='http://etherx.jabber.org/streams'" + " from='%s' id='%s'>" + "<stream:features><mechanisms" + " xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>", + "selket.apogean.org", "concordance-1"); + + /* add a <mechanism> element for each supported SASL mechanism + + int gsasl_server_support_p (Gsasl* ctx, + const char* name); + GString* g_string_append (GString *string, + const gchar *val); + */ + if (gsasl_server_support_p(self->saslCntx, "DIGEST-MD5")) + buff = g_string_append(buff, "<mechanism>DIGEST-MD5</mechanism>"); + if (gsasl_server_support_p(self->saslCntx, "PLAIN")) + buff = g_string_append(buff, "<mechanism>PLAIN</mechanism>"); + + /* close <mechanisms> and <stream:features>, then send buffer */ + buff = g_string_append(buff, "</mechanisms></stream:features>"); + conCore_sessionSend(session, buff->str, buff->len); + + /* free response buffer before returning + + gchar* g_string_free (GString *string, + gboolean free_segment); + */ + g_string_free(buff, TRUE); + } + + + static void + conCore_saslAuth(conSession* session) { /*\ + cdef : \*/ + conCoreObject* self = session->core; + + return; /* unfinished */ + /* gchar* g_base64_encode (const guchar *data, + gsize len); + */ + + + /*g_string_printf(buff, + "<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" + "%s</challenge>", ""); */ + } + + + /* + # + ########################################################################### + # # XML Callbacks # */ static void @@ -624,7 +730,6 @@ conSession* session = (conSession*) s; conCoreObject* self = session->core; gchar** element; - GString* buff; gint i; /* split name by namespace and element @@ -635,9 +740,6 @@ */ element = g_strsplit(name, " ", 2); - /* initialize response buffer */ - buff = g_string_new(""); - /* this from http://www.xml.com/pub/a/1999/09/expat/index.html?page=2 */ for (i = 0; i < session->depth; i++) printf(" "); @@ -648,93 +750,53 @@ printf(">\n"); switch (session->depth) { - case 0 : { - /* only stream element is valid at depth == 0 */ - if (strcmp(name, "http://etherx.jabber.org/streams stream") == 0) { - /* init <stream:stream>, <stream:features>, and <mechanisms> + case 0 : + /* only stream:stream element is valid at depth == 0 - void g_string_printf (GString *string, - const gchar *format, - ...); - */ - g_string_printf(buff, - "<?xml version='1.0' encoding='UTF-8'?>" - "<stream:stream xmlns='jabber:client'" - " xmlns:stream='http://etherx.jabber.org/streams'" - " from='%s' id='%s'>" - "<stream:features><mechanisms" - " xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>", - "selket.apogean.org", "concordance-1"); + if anything else is sent, session->state will be changed from + CON_E_OPEN to CON_E_CLOSE and the session will be cleanly closed + in the conCore_sessionRead just after the XMLParse call (above). + */ + if (strcmp(name, "http://etherx.jabber.org/streams stream") == 0) + conCore_stream(session); + else + session->state = CON_E_CLOSE; - /* add a <mechanism> element for each supported SASL mechanism - - int gsasl_server_support_p (Gsasl* ctx, - const char* name); - GString* g_string_append (GString *string, - const gchar *val); - */ - if (gsasl_server_support_p(self->saslCntx, "DIGEST-MD5")) - buff = g_string_append(buff, "<mechanism>DIGEST-MD5</mechanism>"); - if (gsasl_server_support_p(self->saslCntx, "PLAIN")) - buff = g_string_append(buff, "<mechanism>PLAIN</mechanism>"); - - /* close <mechanisms> and <stream:features>, then send buffer */ - buff = g_string_append(buff, "</mechanisms></stream:features>"); - conCore_sessionSend(session, buff->str, buff->len); - } - /* should disconnect here, something other than session was sent */ - } case 1 : { - if (strcmp(name, "urn:ietf:params:xml:ns:xmpp-sasl auth") == 0) { - gint mech = 0; - for (i = 0; atts[i]; i += 2) - if (strcmp(atts[i], "mechanism") == 0 && - gsasl_server_support_p(self->saslCntx, atts[i+1])) - mech = i+1; + if (strcmp(element[0], "urn:ietf:params:xml:ns:xmpp-sasl") == 0) { + if (strcmp(element[1], "auth") == 0) { + const gchar* mech = conSearchAttributes(atts, "mechanism"); + if (gsasl_server_support_p(self->saslCntx, mech)) { + /* initiate server session - if (mech) { - /* initiate server session - - int gsasl_server_start (Gsasl* ctx, + int gsasl_server_start (Gsasl* ctx, const char* mech, Gsasl_session** sctx); - */ - printf("------ init %s mechanism\n", atts[mech]); - gsasl_server_start(self->saslCntx, atts[mech], &session->sctx); - /* int gsasl_nonce (char* data, - size_t datalen) - /* gchar* g_base64_encode (const guchar *data, - gsize len); - */ + */ + printf("------ init %s mechanism\n", mech); + gsasl_server_start(self->saslCntx, mech, &session->sctx); + session->state = CON_E_SASL_AUTH; + } + else { + conCore_saslFailure(session, "<invalid-mechanism/>"); + session->state = CON_E_CLOSE; + } + } - - g_string_printf(buff, - "<challenge" - " xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" - "%s</challenge>", ""); - } - else { - g_string_append(buff, - "<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" - "<incorrect-encoding/></failure></stream:stream>"); - /* need to close the connection now */ - } - conCore_sessionSend(session, buff->str, buff->len); + /* remaining: response, abort */ } + /* other depth=1 namespaces */ } + + default : { + /* process inner tags depending on state */ + } } /* increase XML depth regardless of element */ session->depth++; - /* free response buffer before returning - - gchar* g_string_free (GString *string, - gboolean free_segment); - */ - g_string_free(buff, TRUE); - /* free the element string array void g_strfreev (gchar **str_array); Modified: trunk/concordance/src/Core.h =================================================================== --- trunk/concordance/src/Core.h 2009-01-08 06:09:29 UTC (rev 1440) +++ trunk/concordance/src/Core.h 2009-01-08 06:11:56 UTC (rev 1441) @@ -59,11 +59,13 @@ enum conSessionState { - CON_E_NONE, /* new session */ - CON_E_STREAM, /* <stream:stream> */ - CON_E_STREAM_PRESENCE, /* <presence> */ - CON_E_STREAM_MESSAGE, /* <message> */ - CON_E_STREAM_IQ, /* <iq> */ + CON_E_CLOSE = 0, /* close </stream> */ + CON_E_OPEN, /* inside <stream> */ + CON_E_PRESENCE, /* <presence> */ + CON_E_MESSAGE, /* <message> */ + CON_E_IQ, /* <iq> */ + CON_E_SASL_AUTH, /* <auth> */ + CON_E_SASL_RESPONSE, /* <response> */ }; _______________________________________________ PySoy-SVN mailing list PySoy-SVN@pysoy.org http://www.pysoy.org/mailman/listinfo/pysoy-svn