]> diplodocus.org Git - nmh/blobdiff - sbr/netsec.c
Move m_getfld's MS_* mbox-type macros to the only user.
[nmh] / sbr / netsec.c
index e64fde0c2777b86c423327ac1e299908fa597a33..ab05cf8e85e9235c6f874169bc0b488b40a36ec0 100644 (file)
@@ -1,5 +1,4 @@
-/*
- * 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
@@ -55,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 */
@@ -141,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;
@@ -181,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);
@@ -219,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)
@@ -392,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);
 
@@ -1016,7 +1016,7 @@ netsec_set_sasl_params(netsec_context *nsc, const char *service,
 
     /*
      * 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.
      */
 
@@ -1436,7 +1436,7 @@ netsec_set_tls(netsec_context *nsc, int tls, int noverify, char **errstr)
 #ifdef TLS_SUPPORT
     if (tls) {
        SSL *ssl;
-       BIO *rbio, *wbio, *ssl_bio;;
+        BIO *rbio, *wbio, *ssl_bio;
 
        if (! tls_initialized) {
            SSL_library_init();
@@ -1508,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",
@@ -1517,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",
@@ -1578,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);
@@ -1624,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(errcode, NULL));
            } else {
                netsec_err(errstr, "Server certificate verification failed: %s",
                           X509_verify_cert_error_string(
@@ -1632,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));
        }
 
        /*