X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/21c9ab1efb7ec86accab9f6da703fcbe4d2f7785..2b60a54adb3b0bf5a9b927708085492b816a6015:/sbr/netsec.c diff --git a/sbr/netsec.c b/sbr/netsec.c index 8a03cada..58cab1bb 100644 --- a/sbr/netsec.c +++ b/sbr/netsec.c @@ -54,6 +54,7 @@ static SSL_CTX *sslctx = NULL; /* SSL Context */ 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 */ @@ -140,6 +141,7 @@ netsec_init(void) 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; @@ -180,11 +182,10 @@ netsec_init(void) /* * 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); @@ -218,7 +219,7 @@ netsec_shutdown(netsec_context *nsc, int closeflag) 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) @@ -391,7 +392,7 @@ netsec_read(netsec_context *nsc, void *buffer, size_t size, char **errstr) * 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); @@ -1216,7 +1217,7 @@ netsec_negotiate_sasl(netsec_context *nsc, const char *mechlist, char **errstr) * messages. */ - memset(&secprops, 0, sizeof(secprops)); + ZERO(&secprops); secprops.maxbufsize = SASL_MAXRECVBUF; /* @@ -1507,7 +1508,7 @@ netsec_set_tls(netsec_context *nsc, int tls, int noverify, char **errstr) * 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", @@ -1516,7 +1517,7 @@ netsec_set_tls(netsec_context *nsc, int tls, int noverify, char **errstr) 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", @@ -1577,6 +1578,13 @@ netsec_set_tls(netsec_context *nsc, int tls, int noverify, char **errstr) 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); @@ -1623,7 +1631,7 @@ netsec_negotiate_tls(netsec_context *nsc, char **errstr) 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( @@ -1631,7 +1639,7 @@ netsec_negotiate_tls(netsec_context *nsc, char **errstr) } } else { netsec_err(errstr, "TLS negotiation failed: %s", - ERR_error_string(ERR_get_error(), NULL)); + ERR_error_string(errcode, NULL)); } /*