]> diplodocus.org Git - nmh/commitdiff
Merge branch 'pop-tls' of git.sv.gnu.org:/srv/git/nmh into pop-tls
authorKen Hornstein <kenh@pobox.com>
Thu, 22 Sep 2016 03:33:29 +0000 (23:33 -0400)
committerKen Hornstein <kenh@pobox.com>
Thu, 22 Sep 2016 03:33:29 +0000 (23:33 -0400)
1  2 
sbr/netsec.c

diff --combined sbr/netsec.c
index a5110f0c643fc53a2f3d78d27e678935003c0b58,0333bf20f0ed317986955af1afd012e9f4bf49be..9fc6f46513b9b48abf22ecdf2f809a48514e42aa
@@@ -54,7 -54,8 +54,8 @@@ static SSL_CTX *sslctx = NULL;                /* SSL 
   */
  
  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 +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 +216,12 @@@ netsec_shutdown(netsec_context *nsc, in
        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);
  }
   */
  
  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;
  }
  
  /*
@@@ -281,7 -288,6 +288,7 @@@ netsec_b64_snoop_decoder(netsec_contex
  {
      const char *decoded;
      size_t decodedlen;
 +    NMH_UNUSED(nsc);
  
      int offset = context ? *((int *) context) : 0;
  
@@@ -475,12 -481,12 +482,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",
       * 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");
@@@ -798,7 -804,7 +805,7 @@@ retry
  #endif /* TLS_SUPPORT */
            fprintf(stderr, "=> ");
            if (nsc->ns_snoop_cb)
 -              nsc->ns_snoop_cb(nsc, nsc->ns_outptr, outlen,
 +              nsc->ns_snoop_cb(nsc, (char *) nsc->ns_outptr, outlen,
                                 nsc->ns_snoop_context);
            else
                 fprintf(stderr, "%.*s\n", outlen, nsc->ns_outptr); 
@@@ -867,7 -873,7 +874,7 @@@ netsec_flush(netsec_context *nsc, char 
  
      }
  #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));
@@@ -1094,6 -1100,7 +1101,6 @@@ netsec_negotiate_sasl(netsec_context *n
  
        i = (str[i] == NULL);
  
 -      free(str);
        free(mlist);
  
        if (i) {
             * we ignore it and send a blank message in response.  We should
             * then get either an +OK or -ERR
             */
 -          free(errstr);
 +          free(*errstr);
            nsc->sasl_proto_cb(NETSEC_SASL_WRITE, NULL, 0, NULL, 0, NULL);
            rc = nsc->sasl_proto_cb(NETSEC_SASL_FINISH, NULL, 0, NULL, 0,
                                    errstr);
@@@ -1382,7 -1389,7 +1389,7 @@@ netsec_set_tls(netsec_context *nsc, in
      if (tls) {
  #ifdef TLS_SUPPORT
        SSL *ssl;
-       BIO *sbio, *ssl_bio;;
+       BIO *rbio, *wbio, *ssl_bio;;
  
        if (! tls_initialized) {
            SSL_library_init();
            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;
        }
         * 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());