From: Ken Hornstein Date: Thu, 22 Sep 2016 03:33:29 +0000 (-0400) Subject: Merge branch 'pop-tls' of git.sv.gnu.org:/srv/git/nmh into pop-tls X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/d98775ebddf66dabdc0e46153f6d4308ff015054?ds=inline;hp=-c Merge branch 'pop-tls' of git.sv.gnu.org:/srv/git/nmh into pop-tls --- d98775ebddf66dabdc0e46153f6d4308ff015054 diff --combined sbr/netsec.c index a5110f0c,0333bf20..9fc6f465 --- a/sbr/netsec.c +++ b/sbr/netsec.c @@@ -54,7 -54,8 +54,8 @@@ static SSL_CTX *sslctx = NULL; /* SSL */ struct _netsec_context { - int ns_fd; /* Descriptor for network connection */ + int ns_readfd; /* Read descriptor for network connection */ + int ns_writefd; /* Write 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 */ @@@ -123,7 -124,8 +124,8 @@@ netsec_init(void { netsec_context *nsc = mh_xmalloc(sizeof(*nsc)); - nsc->ns_fd = -1; + nsc->ns_readfd = -1; + nsc->ns_writefd = -1; nsc->ns_snoop = 0; nsc->ns_snoop_noend = 0; nsc->ns_snoop_cb = NULL; @@@ -214,8 -216,12 +216,12 @@@ netsec_shutdown(netsec_context *nsc, in BIO_free_all(nsc->ssl_io); #endif /* TLS_SUPPORT */ - if (closeflag && nsc->ns_fd != -1) - close(nsc->ns_fd); + if (closeflag) { + if (nsc->ns_readfd != -1) + close(nsc->ns_readfd); + if (nsc->ns_writefd != -1 && nsc->ns_writefd != nsc->ns_readfd) + close(nsc->ns_writefd); + } free(nsc); } @@@ -225,9 -231,10 +231,10 @@@ */ void - netsec_set_fd(netsec_context *nsc, int fd) + netsec_set_fd(netsec_context *nsc, int readfd, writefd) { - nsc->ns_fd = fd; + nsc->ns_readfd = readfd; + nsc->ns_writefd = writefd; } /* @@@ -281,7 -288,6 +288,7 @@@ netsec_b64_snoop_decoder(netsec_contex { const char *decoded; size_t decodedlen; + NMH_UNUSED(nsc); int offset = context ? *((int *) context) : 0; @@@ -475,12 -481,12 +482,12 @@@ retry fd_set rfds; FD_ZERO(&rfds); - FD_SET(nsc->ns_fd, &rfds); + FD_SET(nsc->ns_readfd, &rfds); tv.tv_sec = nsc->ns_timeout; tv.tv_usec = 0; - rc = select(nsc->ns_fd + 1, &rfds, NULL, NULL, &tv); + rc = select(nsc->ns_readfd + 1, &rfds, NULL, NULL, &tv); if (rc == -1) { netsec_err(errstr, "select() while reading failed: %s", @@@ -552,7 -558,7 +559,7 @@@ * select() above) so this read SHOULDN'T block. Hopefully. */ - rc = read(nsc->ns_fd, readbuf, readbufsize); + rc = read(nsc->ns_readfd, readbuf, readbufsize); if (rc == 0) { netsec_err(errstr, "Received EOF on network read"); @@@ -798,7 -804,7 +805,7 @@@ 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, (char *) nsc->ns_outptr, outlen, nsc->ns_snoop_context); else fprintf(stderr, "%.*s\n", outlen, nsc->ns_outptr); @@@ -867,7 -873,7 +874,7 @@@ netsec_flush(netsec_context *nsc, char } #endif /* CYRUS_SASL */ - rc = write(nsc->ns_fd, netoutbuf, netoutlen); + rc = write(nsc->ns_writefd, netoutbuf, netoutlen); if (rc < 0) { netsec_err(errstr, "write() failed: %s", strerror(errno)); @@@ -1094,6 -1100,7 +1101,6 @@@ netsec_negotiate_sasl(netsec_context *n i = (str[i] == NULL); - free(str); free(mlist); if (i) { @@@ -1150,7 -1157,7 +1157,7 @@@ * we ignore it and send a blank message in response. We should * then get either an +OK or -ERR */ - free(errstr); + free(*errstr); nsc->sasl_proto_cb(NETSEC_SASL_WRITE, NULL, 0, NULL, 0, NULL); rc = nsc->sasl_proto_cb(NETSEC_SASL_FINISH, NULL, 0, NULL, 0, errstr); @@@ -1382,7 -1389,7 +1389,7 @@@ netsec_set_tls(netsec_context *nsc, in if (tls) { #ifdef TLS_SUPPORT SSL *ssl; - BIO *sbio, *ssl_bio;; + BIO *rbio, *wbio, *ssl_bio;; if (! tls_initialized) { SSL_library_init(); @@@ -1408,7 -1415,7 +1415,7 @@@ tls_initialized++; } - if (nsc->ns_fd == -1) { + if (nsc->ns_readfd == -1 || nsc->ns_writefd == -1) { netsec_err(errstr, "Invalid file descriptor in netsec context"); return NOTOK; } @@@ -1448,16 -1455,26 +1455,26 @@@ * So writes and reads are buffered (we mostly care about writes). */ - sbio = BIO_new_socket(nsc->ns_fd, BIO_NOCLOSE); + rbio = BIO_new_socket(nsc->ns_readfd, BIO_NOCLOSE); + + if (! rbio) { + netsec_err(errstr, "Unable to create a read socket BIO: %s", + ERR_error_string(ERR_get_error(), NULL)); + SSL_free(ssl); + return NOTOK; + } + + wbio = BIO_new_socket(nsc->ns_writefd, BIO_NOCLOSE); - if (! sbio) { - netsec_err(errstr, "Unable to create a socket BIO: %s", + if (! wbio) { + netsec_err(errstr, "Unable to create a write socket BIO: %s", ERR_error_string(ERR_get_error(), NULL)); SSL_free(ssl); + BIO_free(rbio); return NOTOK; } - SSL_set_bio(ssl, sbio, sbio); + SSL_set_bio(ssl, rbio, wbio); SSL_set_connect_state(ssl); nsc->ssl_io = BIO_new(BIO_f_buffer());