]> diplodocus.org Git - nmh/commitdiff
Normalize connection shutdown handling.
authorKen Hornstein <kenh@pobox.com>
Wed, 31 May 2017 18:39:48 +0000 (14:39 -0400)
committerKen Hornstein <kenh@pobox.com>
Wed, 31 May 2017 18:39:48 +0000 (14:39 -0400)
I originally tried to make things work so that the netsec client code gave
the client the option of closing the file descriptors if it wanted to, but
I was running into a problem where if TLS negotiation failed part of the
negotiation would be interpreted as connection data.  The code has been
changed to have the sockets close when the SSL BIO is released and to
have netsec_shutdown unconditionally close the file descriptors.

h/netsec.h
mts/smtp/smtp.c
sbr/netsec.c
uip/popsbr.c

index 6d3e1767c63d3932b5e600de942900c76a7ed672..e381af86142728d0ef9918768d7daf2981303151 100644 (file)
@@ -15,15 +15,15 @@ netsec_context *netsec_init(void);
 
 /*
  * Shuts down the security context for a connection and frees all
- * associated resources.
+ * associated resources.  Will unconditionally close the network socket
+ * as well.
  *
  * Arguments:
  *
  * ns_context  - Network security context
- * closeflag   - If set to 1, close the socket descriptor as well.
  */
 
-void netsec_shutdown(netsec_context *ns_context, int closeflag);
+void netsec_shutdown(netsec_context *ns_context);
 
 /*
  * Sets the file descriptor for this connection.  This will be used by
index b09fde33cc9ff98ce4632a78149a28fc98999e6b..69477b6c57920f04bc3b04d758a5ce1213a1a096 100644 (file)
@@ -649,7 +649,7 @@ sm_end (int type)
     }
 
     if (nsc != NULL) {
-       netsec_shutdown(nsc, 1);
+       netsec_shutdown(nsc);
        nsc = NULL;
     }
 
index 358b97dfcc403a5f4872c2f7cb20a27b2fc7bad6..dd75bfd56aaa64e8ca88719e36340d1b465e4c93 100644 (file)
@@ -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)
@@ -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);
index 14bc9fc1fe5c73c5afdce3b54e6bdda9f30fd8c4..8d54e021980432569cac3495c9da9a9d90aa214c 100644 (file)
@@ -277,7 +277,7 @@ pop_init (char *host, char *port, char *user, char *proxy, int snoop,
        case DONE: 
            if (poprint)            
                fprintf (stderr, "%s\n", response);
-           netsec_shutdown(nsc, 1);
+           netsec_shutdown(nsc);
            nsc = NULL;
            return NOTOK;
     }
@@ -546,7 +546,7 @@ int
 pop_done (void)
 {
     if (nsc)
-       netsec_shutdown(nsc, 1);
+       netsec_shutdown(nsc);
 
     return OK;
 }