On Fri, Oct 31, 2014 at 09:18:26PM -0700, Doug Hogan wrote:
> On Sat, Nov 01, 2014 at 03:07:24AM +0100, Jan Klemkow wrote:
> > Index: tls_client.c
> > ===================================================================
> > RCS file: /cvs/src/lib/libtls/tls_client.c,v
> > retrieving revision 1.1
> > diff -u -p -r1.1 tls_client.c
> > --- tls_client.c    31 Oct 2014 13:46:17 -0000      1.1
> > +++ tls_client.c    1 Nov 2014 01:50:56 -0000
> > @@ -123,6 +123,13 @@ err:
> >  int
> >  tls_connect_socket(struct tls *ctx, int socket, const char *hostname)
> >  {
> > +   return tls_connect_fds(ctx, socket, socket, hostname);
> > +}
> 
> This changes the behavior of tls_connect_socket() and tls_connect().
> Joel's diff set ctx->socket = socket before calling tls_connect_fds() so
> it would behave the same.  When you call tls_close(ctx), it will close
> ctx->socket in the existing code and Joel's diff.
> 
> I don't think you want to change the semantics like this.  I think
> either tls_connect_fds() is the special case where you need to manually
> close the sockets or tls_close() should close everything.  With the
> above change, even people calling tls_connect() will need to save one of
> the fd_(read|write) before calling tls_close() and then close the fd
> afterward.

Oh, sorry.  This is my fault.  I experimented a little bit and forgot
this part.  I corrected it in the diff below.  Additionally I add some
extra information about the closing behavior inside of the manpage.

Thanks,
Jan

Index: tls.c
===================================================================
RCS file: /cvs/src/lib/libtls/tls.c,v
retrieving revision 1.1
diff -u -p -r1.1 tls.c
--- tls.c       31 Oct 2014 13:46:17 -0000      1.1
+++ tls.c       1 Nov 2014 11:59:36 -0000
@@ -217,6 +217,8 @@ tls_reset(struct tls *ctx)
        ctx->ssl_conn = NULL;
        ctx->ssl_ctx = NULL;
 
+       ctx->fd_read = -1;
+       ctx->fd_write = -1;
        ctx->socket = -1;
 
        ctx->err = 0;
@@ -290,6 +292,8 @@ tls_close(struct tls *ctx)
                        tls_set_error(ctx, "close");
                        goto err;
                }
+               ctx->fd_read = -1;
+               ctx->fd_write = -1;
                ctx->socket = -1;
        }
 
Index: tls.h
===================================================================
RCS file: /cvs/src/lib/libtls/tls.h,v
retrieving revision 1.1
diff -u -p -r1.1 tls.h
--- tls.h       31 Oct 2014 13:46:17 -0000      1.1
+++ tls.h       1 Nov 2014 11:59:36 -0000
@@ -66,6 +66,8 @@ void tls_free(struct tls *ctx);
 
 int tls_accept_socket(struct tls *ctx, struct tls **cctx, int socket);
 int tls_connect(struct tls *ctx, const char *host, const char *port);
+int tls_connect_fds(struct tls *ctx, int fd_read, int fd_write,
+    const char *hostname);
 int tls_connect_socket(struct tls *ctx, int s, const char *hostname);
 int tls_read(struct tls *ctx, void *buf, size_t buflen, size_t *outlen);
 int tls_write(struct tls *ctx, const void *buf, size_t buflen, size_t *outlen);
Index: tls_client.c
===================================================================
RCS file: /cvs/src/lib/libtls/tls_client.c,v
retrieving revision 1.1
diff -u -p -r1.1 tls_client.c
--- tls_client.c        31 Oct 2014 13:46:17 -0000      1.1
+++ tls_client.c        1 Nov 2014 11:59:36 -0000
@@ -123,6 +123,15 @@ err:
 int
 tls_connect_socket(struct tls *ctx, int socket, const char *hostname)
 {
+       ctx->socket = socket;
+
+       return tls_connect_fds(ctx, socket, socket, hostname);
+}
+
+int
+tls_connect_fds(struct tls *ctx, int fd_read, int fd_write,
+    const char *hostname)
+{
        union { struct in_addr ip4; struct in6_addr ip6; } addrbuf;
        X509 *cert = NULL;
        int ret;
@@ -132,7 +141,13 @@ tls_connect_socket(struct tls *ctx, int 
                goto err;
        }
 
-       ctx->socket = socket;
+       if (fd_read < 0 || fd_write < 0) {
+               tls_set_error(ctx, "invalid file descriptors");
+               return (-1);
+       }
+
+       ctx->fd_read = fd_read;
+       ctx->fd_write = fd_write;
 
        if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) {
                tls_set_error(ctx, "ssl context failure");
@@ -166,7 +181,8 @@ tls_connect_socket(struct tls *ctx, int 
                tls_set_error(ctx, "ssl connection failure");
                goto err;
        }
-       if (SSL_set_fd(ctx->ssl_conn, ctx->socket) != 1) {
+       if (SSL_set_rfd(ctx->ssl_conn, ctx->fd_read) != 1 ||
+           SSL_set_wfd(ctx->ssl_conn, ctx->fd_write) != 1) {
                tls_set_error(ctx, "ssl file descriptor failure");
                goto err;
        }
Index: tls_init.3
===================================================================
RCS file: /cvs/src/lib/libtls/tls_init.3,v
retrieving revision 1.1
diff -u -p -r1.1 tls_init.3
--- tls_init.3  31 Oct 2014 13:46:17 -0000      1.1
+++ tls_init.3  1 Nov 2014 11:59:36 -0000
@@ -43,6 +43,7 @@
 .Nm tls_close ,
 .Nm tls_free ,
 .Nm tls_connect ,
+.Nm tls_connect_fds ,
 .Nm tls_connect_socket ,
 .Nm tls_read ,
 .Nm tls_write ,
@@ -100,6 +101,8 @@
 .Ft "int"
 .Fn tls_connect "struct tls *ctx" "const char *host" "const char *port"
 .Ft "int"
+.Fn tls_connect_fds "struct tls *ctx" "int fd_read" "int fd_write" "const char 
*hostname"
+.Ft "int"
 .Fn tls_connect_socket "struct tls *ctx" "int s" "const char *hostname"
 .Ft "int"
 .Fn tls_read "struct tls *ctx" "void *buf" "size_t buflen" "size_t *outlen"
@@ -146,6 +149,9 @@ This function will create a new socket, 
 port, and then establish a secure connection.
 An already existing socket can be upgraded to a secure connection by calling
 .Fn tls_connect_socket .
+An already existing connection with two separate file descriptors for read and
+write can be upgraded to a secure connection by calling
+.Fn tls_connect_fds .
 .Pp
 Two functions are provided for input and output,
 .Fn tls_read
@@ -158,6 +164,13 @@ should be closed with
 .Fn tls_close ,
 and then freed by calling
 .Fn tls_free .
+If
+.Fn tls_connect_fds
+was used to connect before, only the TLS layer will be closed by calling
+.Fn tls_close .
+The caller have to close the file descriptors which were used by
+.Fn tls_connect_fds
+by itself.
 When no more contexts are to be created, the
 .Em tls_config
 object should be freed by calling
@@ -279,6 +292,10 @@ The
 .Fa port
 may be numeric or a service name.
 If it is NULL then a host of the format "hostname:port" is permitted.
+.It
+.Fn tls_connect_fds
+connects a client context to an already established connection with two 
separate
+file descriptors for read and write.
 .It
 .Fn tls_connect_socket
 connects a client context to an already established socket connection.
Index: tls_internal.h
===================================================================
RCS file: /cvs/src/lib/libtls/tls_internal.h,v
retrieving revision 1.1
diff -u -p -r1.1 tls_internal.h
--- tls_internal.h      31 Oct 2014 13:46:17 -0000      1.1
+++ tls_internal.h      1 Nov 2014 11:59:36 -0000
@@ -53,6 +53,8 @@ struct tls {
        int err;
        char *errmsg;
 
+       int fd_read;
+       int fd_write;
        int socket;
 
        SSL *ssl_conn;

Reply via email to