Hi, this diff adds tls_accept_fds(3) to libtls. It allows to accept server side tls connections based on separate file descriptors for read and write, like tls_connect_fds(3) for client side connections.
I tried to keep this diff similar to tls_connect_fds. If anything is wrong just tell me. I will fix it. bye, Jan Index: Makefile =================================================================== RCS file: /cvs/src/lib/libtls/Makefile,v retrieving revision 1.7 diff -u -p -r1.7 Makefile --- Makefile 22 Feb 2015 15:09:54 -0000 1.7 +++ Makefile 30 Mar 2015 00:03:51 -0000 @@ -50,6 +50,7 @@ MLINKS+=tls_init.3 tls_connect_fds.3 MLINKS+=tls_init.3 tls_connect_servername.3 MLINKS+=tls_init.3 tls_connect_socket.3 MLINKS+=tls_init.3 tls_accept_socket.3 +MLINKS+=tls_init.3 tls_accept_fds.3 MLINKS+=tls_init.3 tls_read.3 MLINKS+=tls_init.3 tls_write.3 Index: tls.h =================================================================== RCS file: /cvs/src/lib/libtls/tls.h,v retrieving revision 1.11 diff -u -p -r1.11 tls.h --- tls.h 26 Feb 2015 10:36:30 -0000 1.11 +++ tls.h 30 Mar 2015 00:03:51 -0000 @@ -72,6 +72,8 @@ int tls_configure(struct tls *_ctx, stru void tls_reset(struct tls *_ctx); void tls_free(struct tls *_ctx); +int tls_accept_fds(struct tls *_ctx, struct tls **_cctx, int _fd_read, + int _fd_write); 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, Index: tls_init.3 =================================================================== RCS file: /cvs/src/lib/libtls/tls_init.3,v retrieving revision 1.18 diff -u -p -r1.18 tls_init.3 --- tls_init.3 22 Feb 2015 15:09:54 -0000 1.18 +++ tls_init.3 30 Mar 2015 00:03:51 -0000 @@ -51,6 +51,7 @@ .Nm tls_connect_servername , .Nm tls_connect_socket , .Nm tls_accept_socket , +.Nm tls_accept_fds , .Nm tls_read , .Nm tls_write .Nd TLS client and server API @@ -122,6 +123,8 @@ .Ft "int" .Fn tls_accept_socket "struct tls *tls" "struct tls **cctx" "int socket" .Ft "int" +.Fn tls_accept_fds "struct tls *tls" "struct tls **cctx" "int fd_read" "int fd_write" +.Ft "int" .Fn tls_read "struct tls *ctx" "void *buf" "size_t buflen" "size_t *outlen" .Ft "int" .Fn tls_write "struct tls *ctx" "const void *buf" "size_t buflen" "size_t *outlen" @@ -180,6 +183,14 @@ file descriptors by calling A server can accept a new client connection by calling .Fn tls_accept_socket on an already established socket connection. +If an established connection is based on two separate file descriptors for read +and write a server can also accept a new client connection by calling +.Fn tls_accept_fds . +When using +.Fn tls_accept_fds +with two different file descriptors, these descriptors will not closed by +.Fn tls_close . +They have to be closed separately. .Pp Two functions are provided for input and output, .Fn tls_read @@ -360,6 +371,16 @@ connects a client context to an already .Fn tls_accept_socket creates a new context suitable for reading and writing on an already established socket connection and returns it in +.Fa *cctx . +A configured server context should be passed in +.Fa ctx +and +.Fa *cctx +should be initialized to NULL. +.It +.Fn tls_accept_fds +creates a new context suitable for reading and writing on an already +established connection of a pair of file descriptors and returns it in .Fa *cctx . A configured server context should be passed in .Fa ctx Index: tls_server.c =================================================================== RCS file: /cvs/src/lib/libtls/tls_server.c,v retrieving revision 1.5 diff -u -p -r1.5 tls_server.c --- tls_server.c 7 Feb 2015 09:50:09 -0000 1.5 +++ tls_server.c 30 Mar 2015 00:03:51 -0000 @@ -99,7 +99,7 @@ err: } int -tls_accept_socket(struct tls *ctx, struct tls **cctx, int socket) +tls_accept_fds(struct tls *ctx, struct tls **cctx, int fd_read, int fd_write) { struct tls *conn_ctx = *cctx; int ret, err; @@ -116,20 +116,23 @@ tls_accept_socket(struct tls *ctx, struc } *cctx = conn_ctx; - conn_ctx->socket = socket; + conn_ctx->socket = fd_read == fd_write ? fd_read : -1; if ((conn_ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) { tls_set_error(ctx, "ssl failure"); goto err; } - if (SSL_set_fd(conn_ctx->ssl_conn, socket) != 1) { + if (SSL_set_rfd(conn_ctx->ssl_conn, fd_read) != 1 || + SSL_set_wfd(conn_ctx->ssl_conn, fd_write) != 1) { tls_set_error(ctx, "ssl set fd failure"); goto err; } SSL_set_app_data(conn_ctx->ssl_conn, conn_ctx); } + fprintf(stderr, "SSL_accept\n"); + if ((ret = SSL_accept(conn_ctx->ssl_conn)) != 1) { err = tls_ssl_error(conn_ctx, ret, "accept"); if (err == TLS_READ_AGAIN || err == TLS_WRITE_AGAIN) { @@ -142,4 +145,10 @@ tls_accept_socket(struct tls *ctx, struc err: return (-1); +} + +int +tls_accept_socket(struct tls *ctx, struct tls **cctx, int socket) +{ + return tls_accept_fds(ctx, cctx, socket, socket); }