]> diplodocus.org Git - nmh/blobdiff - sbr/netsec.c
Don't output snoop information when doing RETR or TOP.
[nmh] / sbr / netsec.c
index 928f80b77dbb46fca201e711d3079fd6b8cdde77..18bb97ac311cb92ab9fe99f7b9ff41e9bb7b3edf 100644 (file)
@@ -99,6 +99,12 @@ struct _netsec_context {
 
 static int netsec_fillread(netsec_context *ns_context, char **errstr);
 
+/*
+ * Code to check the ASCII content of a byte array.
+ */
+
+static int checkascii(const unsigned char *byte, size_t len);
+
 /*
  * How this code works, in general.
  *
@@ -286,11 +292,12 @@ void
 netsec_b64_snoop_decoder(netsec_context *nsc, const char *string, size_t len,
                         void *context)
 {
-    const char *decoded;
+    unsigned char *decoded;
     size_t decodedlen;
+    int offset;
     NMH_UNUSED(nsc);
 
-    int offset = context ? *((int *) context) : 0;
+    offset = context ? *((int *) context) : 0;
 
     if (offset > 0) {
        /*
@@ -302,16 +309,48 @@ netsec_b64_snoop_decoder(netsec_context *nsc, const char *string, size_t len,
     }
 
     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);
+       /*
+        * Some mechanisms preoduce large binary tokens, which aren't really
+        * readable.  So let's do a simple heuristic.  If the token is greater
+        * than 100 characters _and_ the first 100 bytes are more than 50%
+        * non-ASCII, then don't print the decoded buffer, just the
+        * base64 text.
+        */
+       if (decodedlen > 100 && !checkascii(decoded, 100)) {
+           fprintf(stderr, "%.*s\n", (int) len, string);
+       } else {
+           char *hexified;
+           hexify(decoded, decodedlen, &hexified);
+           fprintf(stderr, "b64<%s>\n", hexified);
+           free(hexified);
+       }
+       free(decoded);
     } else {
        fprintf(stderr, "%.*s\n", (int) len, string);
     }
 }
 
+/*
+ * If the ASCII content is > 50%, return 1
+ */
+
+static int
+checkascii(const unsigned char *bytes, size_t len)
+{
+    size_t count = 0, half = len / 2;
+
+    while (len-- > 0) {
+       if (isascii(*bytes) && isprint(*bytes) && ++count > half)
+           return 1;
+       bytes++;
+       /* No chance by this point */
+       if (count + len < half)
+           return 0;
+    }
+
+    return 0;
+}
+
 /*
  * Set the read timeout for this connection
  */
@@ -403,11 +442,11 @@ retry:
            if (nsc->ns_snoop) {
 #ifdef CYRUS_SASL
                if (nsc->sasl_seclayer)
-                   fprintf(stderr, "(sasl-encrypted) ");
+                   fprintf(stderr, "(sasl-decrypted) ");
 #endif /* CYRUS_SASL */
 #ifdef TLS_SUPPORT
                if (nsc->tls_active)
-                   fprintf(stderr, "(tls-encrypted) ");
+                   fprintf(stderr, "(tls-decrypted) ");
 #endif /* TLS_SUPPORT */
                fprintf(stderr, "<= ");
                if (nsc->ns_snoop_cb)
@@ -796,24 +835,6 @@ netsec_flush(netsec_context *nsc, char **errstr)
     unsigned int netoutlen = nsc->ns_outbuflen;
     int rc;
 
-    /*
-     * For TLS connections, just call BIO_flush(); we'll let TLS handle
-     * all of our output buffering.
-     */
-#if 0
-    if (nsc->tls_active) {
-       rc = BIO_flush(nsc->ssl_io);
-
-       if (rc <= 0) {
-           netsec_err(errstr, "Error flushing TLS connection: %s",
-                      ERR_error_string(ERR_get_error(), NULL));
-           return NOTOK;
-       }
-
-       return OK;
-    }
-#endif /* TLS_SUPPORT */
-
     /*
      * Small optimization
      */
@@ -935,8 +956,8 @@ netsec_set_sasl_params(netsec_context *nsc, const char *hostname,
        nsc->sasl_mech = getcpy(mechanism);
 
        for (p = nsc->sasl_mech; *p; p++)
-           if (isascii(*p))    /* Just in case */
-               *p = toupper(*p);
+           if (isascii((unsigned char) *p))    /* Just in case */
+               *p = toupper((unsigned char) *p);
     }
 
     nsc->sasl_proto_cb = callback;
@@ -1471,17 +1492,6 @@ netsec_set_tls(netsec_context *nsc, int tls, char **errstr)
        SSL_set_bio(ssl, rbio, wbio);
        SSL_set_connect_state(ssl);
 
-#if 0
-       nsc->ssl_io = BIO_new(BIO_f_buffer());
-
-       if (! nsc->ssl_io) {
-           netsec_err(errstr, "Unable to create a buffer BIO: %s",
-                      ERR_error_string(ERR_get_error(), NULL));
-           SSL_free(ssl);
-           return NOTOK;
-       }
-#endif
-
        ssl_bio = BIO_new(BIO_f_ssl());
 
        if (! ssl_bio) {
@@ -1492,9 +1502,6 @@ netsec_set_tls(netsec_context *nsc, int tls, char **errstr)
        }
 
        BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE);
-#if 0
-       BIO_push(nsc->ssl_io, ssl_bio);
-#endif
        nsc->ssl_io = ssl_bio;
 
        return OK;
@@ -1538,7 +1545,7 @@ netsec_negotiate_tls(netsec_context *nsc, char **errstr)
            fprintf(stderr, "WARNING: cannot determine SSL ciphers\n");
        } else {
            const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl);
-           fprintf(stderr, "TLS negotation successful: %s(%d) %s\n",
+           fprintf(stderr, "TLS negotiation successful: %s(%d) %s\n",
                    SSL_CIPHER_get_name(cipher),
                    SSL_CIPHER_get_bits(cipher, NULL),
                    SSL_CIPHER_get_version(cipher));
@@ -1547,18 +1554,6 @@ netsec_negotiate_tls(netsec_context *nsc, char **errstr)
 
     nsc->tls_active = 1;
 
-#if 0
-    /*
-     * At this point, TLS has been activated; we're not going to use
-     * the output buffer, so free it now to save a little bit of memory.
-     */
-
-    if (nsc->ns_outbuffer) {
-       free(nsc->ns_outbuffer);
-       nsc->ns_outbuffer = NULL;
-    }
-#endif
-
     return OK;
 #else /* TLS_SUPPORT */
     netsec_err(errstr, "TLS not supported");