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;
