From 835b372b75a3c69d08070134f2dbf28cf8cce986 Mon Sep 17 00:00:00 2001 From: Marcel Poul Date: Mon, 28 Nov 2011 20:03:09 +0000 Subject: [PATCH] canl_io_accept with ssl support, sample server modified accordingly --- emi.canl.canl-c/src/canl.c | 12 +++-- emi.canl.canl-c/src/canl_locl.h | 2 + emi.canl.canl-c/src/canl_sample_server.c | 27 ++++++++-- emi.canl.canl-c/src/canl_ssl.c | 89 +++++++++++++++++++++++++++++++- 4 files changed, 120 insertions(+), 10 deletions(-) diff --git a/emi.canl.canl-c/src/canl.c b/emi.canl.canl-c/src/canl.c index deb9c99..5ad9ee2 100644 --- a/emi.canl.canl-c/src/canl.c +++ b/emi.canl.canl-c/src/canl.c @@ -289,15 +289,13 @@ int canl_io_accept(canl_ctx cc, canl_io_handler io, int port, if ((err = bind(sockfd, p->ai_addr, p->ai_addrlen))) { close(sockfd); err = errno; - // set err - perror("server: bind"); continue; } break; } if (p == NULL) { - // set err - fprintf(stderr, "server: failed to bind\n"); - update_error(glb_cc, err, "failed to bind"); //TODO is it there????? + update_error(glb_cc, err, "failed to bind (canl_io_accept)"); //TODO is it there????? freeaddrinfo(servinfo); // all done with this structure goto end; } @@ -317,10 +315,16 @@ int canl_io_accept(canl_ctx cc, canl_io_handler io, int port, err = errno; goto end; } + else + (*io_new_cc)->sock = new_fd; /* TODO everything fine - set new_io_cc according to their_addr*/ - /*call openssl to make a secured connection, optional?*/ + /*call openssl */ + err = ssl_init(glb_cc, *io_new_cc); + if (err) + goto end; + err = ssl_accept(glb_cc, io_cc, (*io_new_cc), timeout); /*write succes or failure to cc, io*/ //if (err) diff --git a/emi.canl.canl-c/src/canl_locl.h b/emi.canl.canl-c/src/canl_locl.h index e0a6572..ca5b821 100644 --- a/emi.canl.canl-c/src/canl_locl.h +++ b/emi.canl.canl-c/src/canl_locl.h @@ -48,6 +48,8 @@ int asyn_getservbyname(int a_family, asyn_result *ares_result,char const *name, struct timeval *timeout); int ssl_init(glb_ctx *cc, io_handler *io); int ssl_connect(glb_ctx *cc, io_handler *io, struct timeval *timeout); +int ssl_accept(glb_ctx *cc, io_handler *io, io_handler *new_io, + struct timeval *timeout); int ssl_read(glb_ctx *cc, io_handler *io, void *buffer, size_t size, struct timeval *tout); int ssl_write(glb_ctx *cc, io_handler *io, void *buffer, size_t size, diff --git a/emi.canl.canl-c/src/canl_sample_server.c b/emi.canl.canl-c/src/canl_sample_server.c index 315cba6..777d80c 100644 --- a/emi.canl.canl-c/src/canl_sample_server.c +++ b/emi.canl.canl-c/src/canl_sample_server.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "canl.h" #define BUF_LEN 1000 @@ -14,6 +15,8 @@ int main(int argc, char *argv[]) char *err_msg = NULL; int opt, port = 4321; char buf[BUF_LEN]; + int buf_len = 0; + struct timeval timeout; while ((opt = getopt(argc, argv, "hp:")) != -1) { switch (opt) { @@ -47,16 +50,32 @@ int main(int argc, char *argv[]) goto end; } + timeout.tv_sec = 15; + timeout.tv_usec = 0; + /* canl_create_io_handler has to be called for my_new_io_h and my_io_h*/ - err = canl_io_accept(my_ctx, my_io_h, port, 0, NULL, NULL, &my_new_io_h); + /* TODO timeout in this function?*/ + err = canl_io_accept(my_ctx, my_io_h, port, 0, NULL, &timeout, &my_new_io_h); if (err) { - //set_error("cannot make a connection"); + printf("connection cannot be established\n"); goto end; } + else { + printf("connection established\n"); + } + + strcpy(buf, "This is the testing message to send"); + buf_len = strlen(buf) + 1; - err = canl_io_write (my_ctx, my_new_io_h, NULL, 0, NULL); + printf("Trying to send sth to the client\n"); + err = canl_io_write (my_ctx, my_new_io_h, buf, buf_len, &timeout); if (err) { - //set_error ("cannot write"); + printf("cannot send message to the client\n"); + goto end; + } + else { + buf[err] = '\0'; + printf("message \"%s\" sent successfully\n", buf); } err = canl_io_read (my_ctx, my_io_h, buf, sizeof(buf)-1, NULL); diff --git a/emi.canl.canl-c/src/canl_ssl.c b/emi.canl.canl-c/src/canl_ssl.c index 9cb8f4c..eb316d2 100644 --- a/emi.canl.canl-c/src/canl_ssl.c +++ b/emi.canl.canl-c/src/canl_ssl.c @@ -1,6 +1,7 @@ #include "canl_locl.h" static int do_ssl_connect( glb_ctx *cc, io_handler *io, struct timeval *timeout); +static int do_ssl_accept( glb_ctx *cc, io_handler *io, struct timeval *timeout); int ssl_init(glb_ctx *cc, io_handler *io) { @@ -17,7 +18,7 @@ int ssl_init(glb_ctx *cc, io_handler *io) SSL_load_error_strings(); SSL_library_init(); - io->s_ctx->ssl_meth = SSLv23_method(); + io->s_ctx->ssl_meth = SSLv23_method(); //TODO dynamically io->s_ctx->ssl_ctx = SSL_CTX_new(io->s_ctx->ssl_meth); if (!io->s_ctx->ssl_ctx){ err = 1; //TODO set appropriate @@ -54,7 +55,7 @@ int ssl_connect(glb_ctx *cc, io_handler *io, struct timeval *timeout) //setup_SSL_proxy_handler(io->s_ctx->ssl_ctx, cacertdir); SSL_set_bio(io->s_ctx->ssl_io, io->s_ctx->bio_conn, io->s_ctx->bio_conn); - io->s_ctx->bio_conn = NULL; //TODO ???? + io->s_ctx->bio_conn = NULL; //TODO WHAT THE HELL IS THIS???? if ((err = do_ssl_connect(cc, io, timeout))) { goto end; @@ -74,6 +75,48 @@ end: return err; } +int ssl_accept(glb_ctx *cc, io_handler *io, io_handler *new_io, + struct timeval *timeout) +{ + int err = 0, flags; + + if (!cc) { + return EINVAL; + } + if (!io) { + err = EINVAL; + goto end; + } + + flags = fcntl(new_io->sock, F_GETFL, 0); + (void)fcntl(new_io->sock, F_SETFL, flags | O_NONBLOCK); + + new_io->s_ctx->bio_conn = BIO_new_socket(new_io->sock, BIO_NOCLOSE); + (void)BIO_set_nbio(new_io->s_ctx->bio_conn,1); + + new_io->s_ctx->ssl_io = SSL_new(new_io->s_ctx->ssl_ctx); + //setup_SSL_proxy_handler(io->s_ctx->ssl_ctx, cacertdir); + SSL_set_bio(new_io->s_ctx->ssl_io, new_io->s_ctx->bio_conn, + new_io->s_ctx->bio_conn); + + if ((err = do_ssl_accept(cc, new_io, timeout))) { + goto end; + } + + /* + if (post_connection_check(io->s_ctx->ssl_io)) { + opened = 1; + (void)Send("0"); + return 1; + } + */ + +end: + if (err) + update_error(cc, err, "(ssl_accept)"); //TODO update error + return err; +} + /* * Encapsulates select behaviour * @@ -176,6 +219,48 @@ static int do_ssl_connect( glb_ctx *cc, io_handler *io, struct timeval *timeout) return 0; } +static int do_ssl_accept( glb_ctx *cc, io_handler *io, struct timeval *timeout) +{ + time_t starttime, curtime; + int ret = -1, ret2 = -1, err = 0; + long errorcode = 0; + int expected = 0; + int locl_timeout = -1; + + /* do not take tv_usec into account in this function*/ + if (timeout) + locl_timeout = timeout->tv_sec; + else + locl_timeout = -1; + curtime = starttime = time(NULL); + + do { + ret = do_select(io->sock, starttime, locl_timeout, expected); + if (ret > 0) { + ret2 = SSL_accept(io->s_ctx->ssl_io); + expected = errorcode = SSL_get_error(io->s_ctx->ssl_io, ret2); + } + curtime = time(NULL); + } while (TEST_SELECT(ret, ret2, locl_timeout, curtime, starttime, errorcode)); + + //TODO split ret2 and ret into 2 ifs to set approp. error message + if (ret2 <= 0 || ret <= 0) { + if (timeout && (curtime - starttime >= locl_timeout)){ + timeout->tv_sec=0; + timeout->tv_usec=0; + err = ETIMEDOUT; + update_error (cc, err, "Connection stuck during handshake: timeout reached (do_ssl_accept)"); + } + else{ + err = -1; //TODO set approp. error message + update_error (cc, err, "Error during SSL handshake (do_ssl_accept)"); + } + return err; + } + + return 0; +} + /* this function has to return # bytes written or ret < 0 when sth went wrong*/ int ssl_write(glb_ctx *cc, io_handler *io, void *buffer, size_t size, struct timeval *timeout) { -- 1.8.2.3