]> diplodocus.org Git - nmh/commitdiff
Add support for a base64-decoding snoop callback.
authorKen Hornstein <kenh@pobox.com>
Wed, 21 Sep 2016 04:06:52 +0000 (00:06 -0400)
committerKen Hornstein <kenh@pobox.com>
Wed, 21 Sep 2016 04:06:52 +0000 (00:06 -0400)
h/netsec.h
sbr/netsec.c
uip/popsbr.c

index 27d29382422abc9593225a9703885d88c54b5fbd..e652a6f41ee175a59001479f57f6c4ffc94784cc 100644 (file)
@@ -83,10 +83,34 @@ void netsec_set_snoop(netsec_context *ns_context, int snoop);
  * ns_context  - Network security context
  * string      - String to output
  * len         - Length of string
+ * context     - "Extra" context information to be used by callback.
  */
 
-typedef void (*netsec_snoop_callback)(netsec_context *ns_context,
-                                    const char *string, size_t len);
+typedef void (netsec_snoop_callback)(netsec_context *ns_context,
+                                    const char *string, size_t len,
+                                    void *context);
+
+/*
+ * Set the snoop callback function; will be used to handle protocol-specific
+ * messages.  Set to NULL to disable.
+ *
+ * Arguments:
+ *
+ * ns_context  - Network security context
+ * callback    - Snoop callback
+ * context     - Extra context information to be passed to callback.
+ */
+
+void netsec_set_snoop_callback(netsec_context *ns_context,
+                              netsec_snoop_callback *callback, void *context);
+
+/*
+ * A sample callback protocols can utilize; decode base64 tokens in the
+ * output.  The context is a pointer to an int which contains an offset
+ * into the data to start decoding.
+ */
+
+extern netsec_snoop_callback netsec_b64_snoop_decoder;
 
 /*
  * Set the read timeout for this connection.
index 3fd31854f568c56655493f6fbf499a978931cd41..4d0d672f6edfc413b37c5f8117ec7ad352aed13c 100644 (file)
@@ -57,7 +57,8 @@ struct _netsec_context {
     int ns_fd;                 /* Descriptor for network connection */
     int ns_snoop;              /* If true, display network data */
     int ns_snoop_noend;                /* If true, didn't get a CR/LF on last line */
-    netsec_snoop_callback ns_snoop_cb; /* Snoop output callback */
+    netsec_snoop_callback *ns_snoop_cb; /* Snoop output callback */
+    void *ns_snoop_context;    /* Context data for snoop function */
     int ns_timeout;            /* Network read timeout, in seconds */
     char *ns_userid;           /* Userid for authentication */
     unsigned char *ns_inbuffer;        /* Our read input buffer */
@@ -126,6 +127,7 @@ netsec_init(void)
     nsc->ns_snoop = 0;
     nsc->ns_snoop_noend = 0;
     nsc->ns_snoop_cb = NULL;
+    nsc->ns_snoop_context = NULL;
     nsc->ns_userid = NULL;
     nsc->ns_timeout = 60;      /* Our default */
     nsc->ns_inbufsize = NETSEC_BUFSIZE;
@@ -258,6 +260,50 @@ netsec_set_snoop(netsec_context *nsc, int snoop)
     nsc->ns_snoop = snoop;
 }
 
+/*
+ * Set the snoop callback for this connection.
+ */
+
+void netsec_set_snoop_callback(netsec_context *nsc,
+                              netsec_snoop_callback callback, void *context)
+{
+    nsc->ns_snoop_cb = callback;
+    nsc->ns_snoop_context = context;
+}
+
+/*
+ * A base64-decoding snoop callback
+ */
+
+void
+netsec_b64_snoop_decoder(netsec_context *nsc, const char *string, size_t len,
+                        void *context)
+{
+    const char *decoded;
+    size_t decodedlen;
+
+    int offset = context ? *((int *) context) : 0;
+
+    if (offset > 0) {
+       /*
+        * Output non-base64 data first.
+        */
+       fprintf(stderr, "%.*s", offset, string);
+       string += offset;
+       len -= offset;
+    }
+
+    if (decodeBase64(string, &decoded, &decodedlen, 1, NULL) == OK) {
+       char *hexified;
+       hexify((const unsigned char *) decoded, decodedlen, &hexified);
+       fprintf(stderr, "b64<%s>\n", hexified);
+       free(hexified);
+       free((char *) decoded);
+    } else {
+       fprintf(stderr, "%.*s\n", (int) len, string);
+    }
+}
+
 /*
  * Set the read timeout for this connection
  */
@@ -357,7 +403,8 @@ retry:
 #endif /* TLS_SUPPORT */
                fprintf(stderr, "<= ");
                if (nsc->ns_snoop_cb)
-                   nsc->ns_snoop_cb(nsc, sptr, strlen(sptr));
+                   nsc->ns_snoop_cb(nsc, sptr, strlen(sptr),
+                                    nsc->ns_snoop_context);
                else
                    fprintf(stderr, "%s\n", sptr);
            }
@@ -750,7 +797,8 @@ retry:
 #endif /* TLS_SUPPORT */
            fprintf(stderr, "=> ");
            if (nsc->ns_snoop_cb)
-               nsc->ns_snoop_cb(nsc, nsc->ns_outptr, outlen);
+               nsc->ns_snoop_cb(nsc, nsc->ns_outptr, outlen,
+                                nsc->ns_snoop_context);
            else
                 fprintf(stderr, "%.*s\n", outlen, nsc->ns_outptr); 
        } else {
index 710116679dc30c0618338307370a8a65716508f2..26f4fa0cef8b64f911f44a89af88011356b49241 100644 (file)
@@ -289,7 +289,7 @@ pop_sasl_callback(enum sasl_message_type mtype, unsigned const char *indata,
                  unsigned int indatalen, unsigned char **outdata,
                  unsigned int *outdatalen, char **errstr)
 {
-    int rc;
+    int rc, snoopoffset;
     char *mech, *line;
     size_t len, b64len;
 
@@ -333,13 +333,18 @@ pop_sasl_callback(enum sasl_message_type mtype, unsigned const char *indata,
                               "for initial challenge response");
                    return NOTOK;
                }
+               netsec_set_snoop_callback(nsc, netsec_b64_snoop_decoder, NULL);
                rc = netsec_printf(nsc, errstr, "%s\r\n", b64data);
+               netsec_set_snoop_callback(nsc, NULL, NULL);
                free(b64data);
                if (rc != OK)
                    return NOTOK;
                if (netsec_flush(nsc, errstr) != OK)
                    return NOTOK;
            } else {
+               netsec_set_snoop_callback(nsc, netsec_b64_snoop_decoder,
+                                         &snoopoffset);
+               snoopoffset = 6 + strlen(mech);
                rc = netsec_printf(nsc, errstr, "AUTH %s %s\r\n", mech,
                                   b64data);
                free(b64data);
@@ -362,7 +367,10 @@ pop_sasl_callback(enum sasl_message_type mtype, unsigned const char *indata,
         * and feed it back into the SASL library.
         */
     case NETSEC_SASL_READ:
+       netsec_set_snoop_callback(nsc, netsec_b64_snoop_decoder, &snoopoffset);
+       snoopoffset = 2;
        line = netsec_readline(nsc, &len, errstr);
+       netsec_set_snoop_callback(nsc, NULL, NULL);
 
        if (line == NULL)
            return NOTOK;
@@ -393,7 +401,9 @@ pop_sasl_callback(enum sasl_message_type mtype, unsigned const char *indata,
            unsigned char *b64data;
            b64data = mh_xmalloc(BASE64SIZE(indatalen));
            writeBase64raw(indata, indatalen, b64data);
+           netsec_set_snoop_callback(nsc, netsec_b64_snoop_decoder, NULL);
            rc = netsec_printf(nsc, errstr, "%s\r\n", b64data);
+           netsec_set_snoop_callback(nsc, NULL, NULL);
            free(b64data);
        }
 
@@ -438,8 +448,7 @@ pop_sasl_callback(enum sasl_message_type mtype, unsigned const char *indata,
            return NOTOK;
        break;
     }
-
-    return OK;
+return OK;
 }
 
 /*