]> diplodocus.org Git - nmh/commitdiff
Change things so we can take two file descriptors, one for input
authorKen Hornstein <kenh@pobox.com>
Thu, 22 Sep 2016 03:32:11 +0000 (23:32 -0400)
committerKen Hornstein <kenh@pobox.com>
Thu, 22 Sep 2016 03:32:11 +0000 (23:32 -0400)
and one for output.

h/netsec.h
sbr/netsec.c

index e652a6f41ee175a59001479f57f6c4ffc94784cc..45d6c9d3f1a44097bb31881df2b6c9c66ada374a 100644 (file)
@@ -34,10 +34,11 @@ void netsec_shutdown(netsec_context *ns_context, int closeflag);
  * Arguments:
  *
  * ns_context  - Network security context
- * fd          - File descriptor of network connection.
+ * readfd      - Read file descriptor of remote connection.
+ * writefd     - Write file descriptor of remote connection
  */
 
-void netsec_set_fd(netsec_context *ns_context, int fd);
+void netsec_set_fd(netsec_context *ns_context, int readfd, writefd);
 
 /*
  * Set the userid used to authenticate to this connection.
@@ -138,7 +139,7 @@ void netsec_set_timeout(netsec_context *ns_context, int timeout);
  * Returns pointer to string, or NULL on error.
  */
 
-char *netsec_readline(netsec_context *ns_context, size_t *lenght,
+char *netsec_readline(netsec_context *ns_context, size_t *length,
                      char **errstr);
 
 /*
index 4d0d672f6edfc413b37c5f8117ec7ad352aed13c..0333bf20f0ed317986955af1afd012e9f4bf49be 100644 (file)
@@ -54,7 +54,8 @@ static SSL_CTX *sslctx = NULL;                /* SSL Context */
  */
 
 struct _netsec_context {
-    int ns_fd;                 /* Descriptor for network connection */
+    int ns_readfd;             /* Read descriptor for network connection */
+    int ns_writefd;            /* Write descriptor for network connection */
     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 */
@@ -123,7 +124,8 @@ netsec_init(void)
 {
     netsec_context *nsc = mh_xmalloc(sizeof(*nsc));
 
-    nsc->ns_fd = -1;
+    nsc->ns_readfd = -1;
+    nsc->ns_writefd = -1;
     nsc->ns_snoop = 0;
     nsc->ns_snoop_noend = 0;
     nsc->ns_snoop_cb = NULL;
@@ -214,8 +216,12 @@ netsec_shutdown(netsec_context *nsc, int closeflag)
        BIO_free_all(nsc->ssl_io);
 #endif /* TLS_SUPPORT */
 
-    if (closeflag && nsc->ns_fd != -1)
-       close(nsc->ns_fd);
+    if (closeflag) {
+       if (nsc->ns_readfd != -1)
+           close(nsc->ns_readfd);
+       if (nsc->ns_writefd != -1 && nsc->ns_writefd != nsc->ns_readfd)
+           close(nsc->ns_writefd);
+    }
 
     free(nsc);
 }
@@ -225,9 +231,10 @@ netsec_shutdown(netsec_context *nsc, int closeflag)
  */
 
 void
-netsec_set_fd(netsec_context *nsc, int fd)
+netsec_set_fd(netsec_context *nsc, int readfd, writefd)
 {
-    nsc->ns_fd = fd;
+    nsc->ns_readfd = readfd;
+    nsc->ns_writefd = writefd;
 }
 
 /*
@@ -474,12 +481,12 @@ retry:
        fd_set rfds;
 
        FD_ZERO(&rfds);
-       FD_SET(nsc->ns_fd, &rfds);
+       FD_SET(nsc->ns_readfd, &rfds);
 
        tv.tv_sec = nsc->ns_timeout;
        tv.tv_usec = 0;
 
-       rc = select(nsc->ns_fd + 1, &rfds, NULL, NULL, &tv);
+       rc = select(nsc->ns_readfd + 1, &rfds, NULL, NULL, &tv);
 
        if (rc == -1) {
            netsec_err(errstr, "select() while reading failed: %s",
@@ -551,7 +558,7 @@ retry:
      * select() above) so this read SHOULDN'T block.  Hopefully.
      */
 
-    rc = read(nsc->ns_fd, readbuf, readbufsize);
+    rc = read(nsc->ns_readfd, readbuf, readbufsize);
 
     if (rc == 0) {
        netsec_err(errstr, "Received EOF on network read");
@@ -866,7 +873,7 @@ netsec_flush(netsec_context *nsc, char **errstr)
 
     }
 #endif /* CYRUS_SASL */
-    rc = write(nsc->ns_fd, netoutbuf, netoutlen);
+    rc = write(nsc->ns_writefd, netoutbuf, netoutlen);
 
     if (rc < 0) {
        netsec_err(errstr, "write() failed: %s", strerror(errno));
@@ -1382,7 +1389,7 @@ netsec_set_tls(netsec_context *nsc, int tls, char **errstr)
     if (tls) {
 #ifdef TLS_SUPPORT
        SSL *ssl;
-       BIO *sbio, *ssl_bio;;
+       BIO *rbio, *wbio, *ssl_bio;;
 
        if (! tls_initialized) {
            SSL_library_init();
@@ -1408,7 +1415,7 @@ netsec_set_tls(netsec_context *nsc, int tls, char **errstr)
            tls_initialized++;
        }
 
-       if (nsc->ns_fd == -1) {
+       if (nsc->ns_readfd == -1 || nsc->ns_writefd == -1) {
            netsec_err(errstr, "Invalid file descriptor in netsec context");
            return NOTOK;
        }
@@ -1448,16 +1455,26 @@ netsec_set_tls(netsec_context *nsc, int tls, char **errstr)
         * So writes and reads are buffered (we mostly care about writes).
         */
 
-       sbio = BIO_new_socket(nsc->ns_fd, BIO_NOCLOSE);
+       rbio = BIO_new_socket(nsc->ns_readfd, BIO_NOCLOSE);
+
+       if (! rbio) {
+           netsec_err(errstr, "Unable to create a read socket BIO: %s",
+                      ERR_error_string(ERR_get_error(), NULL));
+           SSL_free(ssl);
+           return NOTOK;
+       }
+
+       wbio = BIO_new_socket(nsc->ns_writefd, BIO_NOCLOSE);
 
-       if (! sbio) {
-           netsec_err(errstr, "Unable to create a socket BIO: %s",
+       if (! wbio) {
+           netsec_err(errstr, "Unable to create a write socket BIO: %s",
                       ERR_error_string(ERR_get_error(), NULL));
            SSL_free(ssl);
+           BIO_free(rbio);
            return NOTOK;
        }
 
-       SSL_set_bio(ssl, sbio, sbio);
+       SSL_set_bio(ssl, rbio, wbio);
        SSL_set_connect_state(ssl);
 
        nsc->ssl_io = BIO_new(BIO_f_buffer());