Hello,

This diff enables libressl to use two file descriptors for read and
write.  This is feature is necessary for communication over two pipes
like in the UCSPI protocol [1].  resslc[3] is a general ssl-client.

+-----------+     +--------+     +--------+
| tcpserver | --> | resslc | --> | client |
|           | <-- |        | <-- |        |
+-----------+     +--------+     +--------+

This diff adds a new function ressl_set_fds() to set a separate file
descriptors for read and write inside of the ressl context structure.
The function ressl_connect_socket() sets the read and write file
descriptors if their were set before.  I also adapt the related manpage.

This approach may not the best to get this feature.  I am open to every
idea that solves this problem in a better way.  I am not sure whether it
is nessacery to touch shlib_version.  So, I leave it untouched.

I tried to test this diff with regress/lib/libressl, but it seems to be brocken.

Thanks,
Jan

Background:

To port one of the sslserver versions to ressl is not possible in my
situation, because this is not flexible enough.  I often have to use the
port net/ucspi-tcp together with socks[2].  This fits perfectly into the
UCSPI protocol.  It is my plan to port socks and resslc like
net/ucspi-tcp later, too.

+-----------+     +-------+     +--------+     +--------+
| tcpserver | --> | socks | --> | resslc | --> | client |
|           | <-- |       | <-- |        | <-- |        |
+-----------+     +-------+     +--------+     +--------+

 [1]: http://cr.yp.to/proto/ucspi.txt
 [2]: https://github.com/younix/ucspi/blob/master/socks.c
 [3]: https://github.com/younix/ucspi/blob/master/resslc.c

Index: Makefile
===================================================================
RCS file: /cvs/src/lib/libressl/Makefile,v
retrieving revision 1.5
diff -u -p -r1.5 Makefile
--- Makefile    8 Oct 2014 19:01:40 -0000       1.5
+++ Makefile    30 Oct 2014 00:24:04 -0000
@@ -27,6 +27,7 @@ MLINKS+=ressl_init.3 ressl_set_cert_file
 MLINKS+=ressl_init.3 ressl_set_cert_mem.3
 MLINKS+=ressl_init.3 ressl_set_ciphers.3
 MLINKS+=ressl_init.3 ressl_set_ecdhcurve.3
+MLINKS+=ressl_init.3 ressl_set_fds.3
 MLINKS+=ressl_init.3 ressl_set_key_file.3
 MLINKS+=ressl_init.3 ressl_set_key_mem.3
 MLINKS+=ressl_init.3 ressl_set_protocols.3
Index: ressl.c
===================================================================
RCS file: /cvs/src/lib/libressl/ressl.c,v
retrieving revision 1.18
diff -u -p -r1.18 ressl.c
--- ressl.c     15 Oct 2014 21:02:39 -0000      1.18
+++ ressl.c     30 Oct 2014 00:24:04 -0000
@@ -73,6 +73,20 @@ ressl_set_error(struct ressl *ctx, char 
        return (rv);
 }
 
+int
+ressl_set_fds(struct ressl *ctx, int fd_read, int fd_write)
+{
+       if (fd_read < 0 || fd_write < 0) {
+               ressl_set_error(ctx, "failed to set fds");
+               return (1);
+       }
+
+       ctx->socket_read = fd_read;
+       ctx->socket_write = fd_write;
+
+       return (0);
+}
+
 struct ressl *
 ressl_new(void)
 {
@@ -218,6 +232,8 @@ ressl_reset(struct ressl *ctx)
        ctx->ssl_ctx = NULL;
 
        ctx->socket = -1;
+       ctx->socket_read = -1;
+       ctx->socket_write = -1;
 
        ctx->err = 0;
        free(ctx->errmsg);
Index: ressl.h
===================================================================
RCS file: /cvs/src/lib/libressl/ressl.h,v
retrieving revision 1.21
diff -u -p -r1.21 ressl.h
--- ressl.h     15 Oct 2014 21:02:39 -0000      1.21
+++ ressl.h     30 Oct 2014 00:24:04 -0000
@@ -71,6 +71,7 @@ void ressl_free(struct ressl *ctx);
 int ressl_accept(struct ressl *ctx, struct ressl **cctx);
 int ressl_accept_socket(struct ressl *ctx, struct ressl **cctx, int socket);
 int ressl_connect(struct ressl *ctx, const char *host, const char *port);
+int ressl_set_fds(struct ressl *ctx, int read_fd, int write_fd);
 int ressl_connect_socket(struct ressl *ctx, int s, const char *hostname);
 int ressl_listen(struct ressl *ctx, const char *host, const char *port, int 
af);
 int ressl_read(struct ressl *ctx, void *buf, size_t buflen, size_t *outlen);
Index: ressl_client.c
===================================================================
RCS file: /cvs/src/lib/libressl/ressl_client.c,v
retrieving revision 1.5
diff -u -p -r1.5 ressl_client.c
--- ressl_client.c      3 Oct 2014 14:14:40 -0000       1.5
+++ ressl_client.c      30 Oct 2014 00:24:05 -0000
@@ -166,7 +166,14 @@ ressl_connect_socket(struct ressl *ctx, 
                ressl_set_error(ctx, "ssl connection failure");
                goto err;
        }
-       if (SSL_set_fd(ctx->ssl_conn, ctx->socket) != 1) {
+
+       if (ctx->socket_read != -1 && ctx->socket_write != -1) {
+               if (SSL_set_rfd(ctx->ssl_conn, ctx->socket_read) != 1 ||
+                   SSL_set_wfd(ctx->ssl_conn, ctx->socket_write) != 1) {
+                       ressl_set_error(ctx, "ssl file descriptor failure");
+                       goto err;
+               }
+       } else if (SSL_set_fd(ctx->ssl_conn, ctx->socket) != 1) {
                ressl_set_error(ctx, "ssl file descriptor failure");
                goto err;
        }
Index: ressl_init.3
===================================================================
RCS file: /cvs/src/lib/libressl/ressl_init.3,v
retrieving revision 1.9
diff -u -p -r1.9 ressl_init.3
--- ressl_init.3        16 Oct 2014 12:46:35 -0000      1.9
+++ ressl_init.3        30 Oct 2014 00:24:05 -0000
@@ -43,6 +43,7 @@
 .Nm ressl_close ,
 .Nm ressl_free ,
 .Nm ressl_connect ,
+.Nm ressl_set_fds ,
 .Nm ressl_connect_socket ,
 .Nm ressl_read ,
 .Nm ressl_write ,
@@ -100,6 +101,8 @@
 .Ft "int"
 .Fn ressl_connect "struct ressl *ctx" "const char *host" "const char *port"
 .Ft "int"
+.Fn ressl_set_fds "struct ressl *ctx" "int fd_read" "int fd_write"
+.Ft "int"
 .Fn ressl_connect_socket "struct ressl *ctx" "int s" "const char *hostname"
 .Ft "int"
 .Fn ressl_read "struct ressl *ctx" "void *buf" "size_t buflen" "size_t *outlen"
@@ -146,6 +149,15 @@ 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 ressl_connect_socket .
+The function
+.Fn ressl_set_fds
+have to be called before
+.Fn ressl_connect_socket
+to set file descriptors 
+in cases of different file descriptors for read and write directions.
+This is useful for communications with two
+.Xr pipe 2
+file descriptors.
 .Pp
 Two functions are provided for input and output,
 .Fn ressl_read
@@ -260,6 +272,9 @@ creates a new ressl context for server c
 .Fn ressl_configure
 readies a ressl context for use by applying the configuration
 options.
+.It
+.Fn ressl_set_fds
+sets file descriptors for read and write directions.
 .It
 .Fn ressl_close
 closes a connection after use.
Index: ressl_internal.h
===================================================================
RCS file: /cvs/src/lib/libressl/ressl_internal.h,v
retrieving revision 1.12
diff -u -p -r1.12 ressl_internal.h
--- ressl_internal.h    3 Oct 2014 14:14:40 -0000       1.12
+++ ressl_internal.h    30 Oct 2014 00:24:05 -0000
@@ -54,6 +54,8 @@ struct ressl {
        char *errmsg;
 
        int socket;
+       int socket_read;
+       int socket_write;
 
        SSL *ssl_conn;
        SSL_CTX *ssl_ctx;

Reply via email to