-
-/*
- * netsec.c -- Network security routines for handling protocols that
+/* netsec.c -- Network security routines for handling protocols that
* require SASL and/or TLS.
*
* This code is Copyright (c) 2016, by the authors of nmh. See the
struct _netsec_context {
int ns_readfd; /* Read descriptor for network connection */
int ns_writefd; /* Write descriptor for network connection */
+ int ns_noclose; /* Do not close file descriptors if set */
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 */
NEW(nsc);
nsc->ns_readfd = -1;
nsc->ns_writefd = -1;
+ nsc->ns_noclose = 0;
nsc->ns_snoop = 0;
nsc->ns_snoop_noend = 0;
nsc->ns_snoop_cb = NULL;
/*
* Shutdown the connection completely and free all resources.
- * The connection is only closed if the flag is given.
*/
void
-netsec_shutdown(netsec_context *nsc, int closeflag)
+netsec_shutdown(netsec_context *nsc)
{
mh_xfree(nsc->ns_userid);
mh_xfree(nsc->ns_hostname);
BIO_free_all(nsc->ssl_io);
#endif /* TLS_SUPPORT */
- if (closeflag) {
+ if (! nsc->ns_noclose) {
if (nsc->ns_readfd != -1)
close(nsc->ns_readfd);
if (nsc->ns_writefd != -1 && nsc->ns_writefd != nsc->ns_readfd)
* assume here that this has something in it.
*/
- retlen = size > nsc->ns_inbuflen ? nsc->ns_inbuflen : size;
+ retlen = min(size, nsc->ns_inbuflen);
memcpy(buffer, nsc->ns_inptr, retlen);
nsc->sasl_creds = nmh_get_credentials(nsc->ns_hostname, nsc->ns_userid);
#else /* CYRUS_SASL */
- NMH_UNUSED(hostname);
NMH_UNUSED(service);
NMH_UNUSED(errstr);
#endif /* CYRUS_SASL */
/*
* According to the RFC, mechanisms can only be uppercase letter, numbers,
- * and a hypen or underscore. So make sure we uppercase any letters
+ * and a hyphen or underscore. So make sure we uppercase any letters
* in case the user passed in lowercase.
*/
* messages.
*/
- memset(&secprops, 0, sizeof(secprops));
+ ZERO(&secprops);
secprops.maxbufsize = SASL_MAXRECVBUF;
/*
#ifdef TLS_SUPPORT
if (tls) {
SSL *ssl;
- BIO *rbio, *wbio, *ssl_bio;;
+ BIO *rbio, *wbio, *ssl_bio;
if (! tls_initialized) {
SSL_library_init();
* SSL BIO -> socket BIO.
*/
- rbio = BIO_new_socket(nsc->ns_readfd, BIO_NOCLOSE);
+ rbio = BIO_new_socket(nsc->ns_readfd, BIO_CLOSE);
if (! rbio) {
netsec_err(errstr, "Unable to create a read socket BIO: %s",
return NOTOK;
}
- wbio = BIO_new_socket(nsc->ns_writefd, BIO_NOCLOSE);
+ wbio = BIO_new_socket(nsc->ns_writefd, BIO_CLOSE);
if (! wbio) {
netsec_err(errstr, "Unable to create a write socket BIO: %s",
BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE);
nsc->ssl_io = ssl_bio;
+ /*
+ * Since SSL now owns these file descriptors, have it handle the
+ * closing of them instead of netsec_shutdown().
+ */
+
+ nsc->ns_noclose = 1;
+
return OK;
}
BIO_free_all(nsc->ssl_io);
if (BIO_get_ssl(nsc->ssl_io, &ssl) < 1) {
netsec_err(errstr, "Certificate verification failed, but "
"cannot retrieve SSL handle: %s",
- ERR_error_string(ERR_get_error(), NULL));
+ ERR_error_string(ERR_get_error(), NULL));
} else {
netsec_err(errstr, "Server certificate verification failed: %s",
X509_verify_cert_error_string(
}
} else {
netsec_err(errstr, "TLS negotiation failed: %s",
- ERR_error_string(ERR_get_error(), NULL));
+ ERR_error_string(errcode, NULL));
}
/*