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.
*
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) {
/*
}
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
*/
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)
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.
- */
-#ifdef TLS_SUPPORT
- 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
*/
return NOTOK;
}
- nsc->sasl_mech = mechanism ? getcpy(mechanism) : NULL;
+ /*
+ * According to the RFC, mechanisms can only be uppercase letter, numbers,
+ * and a hypen or underscore. So make sure we uppercase any letters
+ * in case the user passed in lowercase.
+ */
+
+ if (mechanism) {
+ char *p;
+ nsc->sasl_mech = getcpy(mechanism);
+
+ for (p = nsc->sasl_mech; *p; p++)
+ if (isascii((unsigned char) *p)) /* Just in case */
+ *p = toupper((unsigned char) *p);
+ }
+
nsc->sasl_proto_cb = callback;
nsc->sasl_hostname = getcpy(hostname);
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) {
}
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;
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));
nsc->tls_active = 1;
- /*
- * 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;
- }
-
return OK;
#else /* TLS_SUPPORT */
netsec_err(errstr, "TLS not supported");