]> diplodocus.org Git - nmh/blobdiff - sbr/netsec.c
new.c: Order two return statements to match comment.
[nmh] / sbr / netsec.c
index a64743aa5decd853c57a6c8ceb848c22aa7548f8..25b1f888fbcf2a146ff670fad0bf48802d088a6c 100644 (file)
@@ -12,6 +12,7 @@
 #include <h/oauth.h>
 #include <stdarg.h>
 #include <sys/select.h>
+#include "base64.h"
 
 #ifdef CYRUS_SASL
 #include <sasl/sasl.h>
@@ -54,6 +55,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 +142,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,25 +183,24 @@ 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);
-    mh_xfree(nsc->ns_inbuffer);
-    mh_xfree(nsc->ns_outbuffer);
-    mh_xfree(nsc->sasl_mech);
-    mh_xfree(nsc->sasl_chosen_mech);
+    free(nsc->ns_userid);
+    free(nsc->ns_hostname);
+    free(nsc->ns_inbuffer);
+    free(nsc->ns_outbuffer);
+    free(nsc->sasl_mech);
+    free(nsc->sasl_chosen_mech);
 #ifdef OAUTH_SERVICE
-    mh_xfree(nsc->oauth_service);
+    free(nsc->oauth_service);
 #endif /* OAUTH_SERVICE */
 #ifdef CYRUS_SASL
     if (nsc->sasl_conn)
        sasl_dispose(&nsc->sasl_conn);
-    mh_xfree(nsc->sasl_cbs);
+    free(nsc->sasl_cbs);
     if (nsc->sasl_creds)
        nmh_credentials_free(nsc->sasl_creds);
     if (nsc->sasl_secret) {
@@ -207,7 +209,7 @@ netsec_shutdown(netsec_context *nsc, int closeflag)
        }
        free(nsc->sasl_secret);
     }
-    mh_xfree(nsc->sasl_tmpbuf);
+    free(nsc->sasl_tmpbuf);
 #endif /* CYRUS_SASL */
 #ifdef TLS_SUPPORT
     if (nsc->ssl_io)
@@ -218,7 +220,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)
@@ -459,8 +461,10 @@ retry:
                if (nsc->ns_snoop_cb)
                    nsc->ns_snoop_cb(nsc, sptr, strlen(sptr),
                                     nsc->ns_snoop_context);
-               else
-                   fprintf(stderr, "%s\n", sptr);
+               else {
+                    fputs(sptr, stderr);
+                    putc('\n', stderr);
+                }
            }
            return sptr;
        }
@@ -472,7 +476,7 @@ retry:
      */
 
     if (count >= nsc->ns_inbufsize / 2) {
-       netsec_err(errstr, "Unable to find a line terminator after %d bytes",
+       netsec_err(errstr, "Unable to find a line terminator after %zu bytes",
                   count);
        return NULL;
     }
@@ -1216,7 +1220,7 @@ netsec_negotiate_sasl(netsec_context *nsc, const char *mechlist, char **errstr)
      * messages.
      */
 
-    memset(&secprops, 0, sizeof(secprops));
+    ZERO(&secprops);
     secprops.maxbufsize = SASL_MAXRECVBUF;
 
     /*
@@ -1278,7 +1282,7 @@ netsec_negotiate_sasl(netsec_context *nsc, const char *mechlist, char **errstr)
        rc = sasl_client_step(nsc->sasl_conn, (char *) outbuf, outbuflen, NULL,
                              (const char **) &saslbuf, &saslbuflen);
 
-        mh_xfree(outbuf);
+        free(outbuf);
 
        if (rc != SASL_OK && rc != SASL_CONTINUE) {
            netsec_err(errstr, "SASL client negotiation failed: %s",
@@ -1507,7 +1511,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 +1520,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 +1581,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 +1634,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 +1642,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));
        }
 
        /*