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

Reply via email to