* 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.
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 */
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;
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
*/
#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);
}
#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 {
unsigned int indatalen, unsigned char **outdata,
unsigned int *outdatalen, char **errstr)
{
- int rc;
+ int rc, snoopoffset;
char *mech, *line;
size_t len, b64len;
"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);
* 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;
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);
}
return NOTOK;
break;
}
-
- return OK;
+return OK;
}
/*