[IOMultiplexerV2] Fixed listening SSL sockets
authorpk910 <philipp@zoelle1.de>
Sun, 16 Mar 2014 15:56:17 +0000 (16:56 +0100)
committerpk910 <philipp@zoelle1.de>
Sun, 16 Mar 2014 20:35:10 +0000 (21:35 +0100)
src/IOHandler/IOSSLBackend.c
src/IOHandler/IOSockets.c
src/IOHandler_test/server_ssl/iotest.c

index 786c65c8f84dcb5eabf7a0409bbcb60d4acb94af..f45b6d42712c7f2117b10d6bce140ab173fe4628 100644 (file)
 #include <errno.h>
 /* GnuTLS Backend */
 static gnutls_dh_params_t dh_params;
+static unsigned int dh_params_bits;
 
 static int generate_dh_params() {
-       unsigned int bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY);
+       dh_params_bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY);
        gnutls_dh_params_init(&dh_params);
-       gnutls_dh_params_generate2(dh_params, bits);
+       gnutls_dh_params_generate2(dh_params, dh_params_bits);
        return 0;
 }
 
 void iossl_init() {
-    int ret;
+       int ret;
        if((ret = gnutls_global_init()) != GNUTLS_E_SUCCESS) {
                iolog_trigger(IOLOG_ERROR, "SSL: gnutls_global_init(): failed (%d)", ret);
                //TODO: Error handling?
@@ -47,7 +48,7 @@ void iossl_init() {
 
 // Client
 void iossl_connect(struct _IOSocket *iosock) {
-    struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
+       struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
        int err;
        
        err = gnutls_certificate_allocate_credentials(&sslnode->ssl.client.credentials);
@@ -57,25 +58,25 @@ void iossl_connect(struct _IOSocket *iosock) {
        
        gnutls_init(&sslnode->ssl.client.session, GNUTLS_CLIENT);
        
-       gnutls_priority_set_direct(sslnode->ssl.client.session, "NONE:+VERS-TLS1.0:+VERS-SSL3.0:+CIPHER-ALL:+COMP-ALL:+RSA:+DHE-RSA:+DHE-DSS:+MAC-ALL", NULL);
+       gnutls_priority_set_direct(sslnode->ssl.client.session, "SECURE128:+SECURE192:-VERS-TLS-ALL:+VERS-TLS1.2", NULL);
        gnutls_credentials_set(sslnode->ssl.client.session, GNUTLS_CRD_CERTIFICATE, sslnode->ssl.client.credentials);
-    
+       
        gnutls_transport_set_int(sslnode->ssl.client.session, iosock->fd);
        gnutls_handshake_set_timeout(sslnode->ssl.client.session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
        
-    iosock->sslnode = sslnode;
+       iosock->sslnode = sslnode;
        iosock->socket_flags |= IOSOCKETFLAG_SSL_HANDSHAKE;
-    iossl_client_handshake(iosock);
-    return;
+       iossl_client_handshake(iosock);
+       return;
 ssl_connect_err:
-    free(sslnode);
-    iosocket_events_callback(iosock, 0, 0);
+       free(sslnode);
+       iosocket_events_callback(iosock, 0, 0);
 }
 
 void iossl_client_handshake(struct _IOSocket *iosock) {
-    // Perform an SSL handshake.
-    int ret = gnutls_handshake(iosock->sslnode->ssl.client.session);
-    iosock->socket_flags &= ~IOSOCKETFLAG_SSL_WANTWRITE;
+       // Perform an SSL handshake.
+       int ret = gnutls_handshake(iosock->sslnode->ssl.client.session);
+       iosock->socket_flags &= ~IOSOCKETFLAG_SSL_WANTWRITE;
        
        if(ret < 0) {
                if(gnutls_error_is_fatal(ret) == 0) {
@@ -102,34 +103,35 @@ void iossl_client_handshake(struct _IOSocket *iosock) {
 
 // Server
 void iossl_listen(struct _IOSocket *iosock, const char *certfile, const char *keyfile) {
-    struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
+       struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
        
-       gnutls_priority_init(&sslnode->ssl.server.priority, "NONE:+VERS-TLS1.0:+VERS-SSL3.0:+CIPHER-ALL:+COMP-ALL:+RSA:+DHE-RSA:+DHE-DSS:+MAC-ALL", NULL);
+       gnutls_priority_init(&sslnode->ssl.server.priority, "SECURE128:+SECURE192:-VERS-TLS-ALL:+VERS-TLS1.2", NULL);
        
        gnutls_certificate_allocate_credentials(&sslnode->ssl.server.credentials);
        int ret = gnutls_certificate_set_x509_key_file(sslnode->ssl.server.credentials, certfile, keyfile, GNUTLS_X509_FMT_PEM);
-    if (ret < 0) {
+       if (ret < 0) {
                iolog_trigger(IOLOG_ERROR, "SSL: could not load server certificate/key (%s %s): %d - %s", certfile, keyfile, ret, gnutls_strerror(ret));
                goto ssl_listen_err;
        }
        
        gnutls_certificate_set_dh_params(sslnode->ssl.server.credentials, dh_params);
        
-    iosock->sslnode = sslnode;
-    iosock->socket_flags |= IOSOCKETFLAG_SSL_ESTABLISHED;
-    return;
+       iosock->sslnode = sslnode;
+       iosock->socket_flags |= IOSOCKETFLAG_SSL_ESTABLISHED;
+       return;
 ssl_listen_err:
-    free(sslnode);
-    iosock->sslnode = NULL;
-    iosocket_events_callback(iosock, 0, 0);
+       free(sslnode);
+       iosock->sslnode = NULL;
+       iosocket_events_callback(iosock, 0, 0);
 }
 
 void iossl_client_accepted(struct _IOSocket *iosock, struct _IOSocket *new_iosock) {
-    struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
-    
+       struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
+       
        gnutls_init(&sslnode->ssl.client.session, GNUTLS_SERVER);
        gnutls_priority_set(sslnode->ssl.client.session, iosock->sslnode->ssl.server.priority);
        gnutls_credentials_set(sslnode->ssl.client.session, GNUTLS_CRD_CERTIFICATE, iosock->sslnode->ssl.server.credentials);
+       gnutls_dh_set_prime_bits(sslnode->ssl.client.session, dh_params_bits);
        
        /* We don't request any certificate from the client.
         * If we did we would need to verify it.
@@ -138,41 +140,42 @@ void iossl_client_accepted(struct _IOSocket *iosock, struct _IOSocket *new_iosoc
        
        gnutls_transport_set_int(sslnode->ssl.client.session, new_iosock->fd);
        
-    new_iosock->sslnode = sslnode;
-    new_iosock->socket_flags |= IOSOCKETFLAG_SSL_HANDSHAKE;
-    return;
+       new_iosock->sslnode = sslnode;
+       new_iosock->socket_flags |= IOSOCKETFLAG_SSL_HANDSHAKE;
+       return;
        /*
 ssl_accept_err:
-    free(sslnode);
-    iosock->sslnode = NULL;
-    iosocket_events_callback(new_iosock, 0, 0);
+       free(sslnode);
+       iosock->sslnode = NULL;
+       iosocket_events_callback(new_iosock, 0, 0);
        */
 }
 
 void iossl_server_handshake(struct _IOSocket *iosock) {
-    return iossl_client_handshake(iosock);
+       return iossl_client_handshake(iosock);
 }
 
 void iossl_disconnect(struct _IOSocket *iosock) {
-    if(!iosock->sslnode) return;
+       if(!iosock->sslnode) return;
        
        if((iosock->socket_flags & IOSOCKETFLAG_LISTENING)) {
                gnutls_certificate_free_credentials(iosock->sslnode->ssl.server.credentials);
                gnutls_priority_deinit(iosock->sslnode->ssl.server.priority);
        } else {
                gnutls_bye(iosock->sslnode->ssl.client.session, GNUTLS_SHUT_RDWR);
-               gnutls_certificate_free_credentials(iosock->sslnode->ssl.client.credentials);
+               if(!(iosock->socket_flags & IOSOCKETFLAG_INCOMING))
+                       gnutls_certificate_free_credentials(iosock->sslnode->ssl.client.credentials);
                gnutls_deinit(iosock->sslnode->ssl.client.session);
        }
        
-    free(iosock->sslnode);
-    iosock->sslnode = NULL;
-    iosock->socket_flags &= ~IOSOCKETFLAG_SSLSOCKET;
+       free(iosock->sslnode);
+       iosock->sslnode = NULL;
+       iosock->socket_flags &= ~IOSOCKETFLAG_SSLSOCKET;
 }
 
 static void iossl_rehandshake(struct _IOSocket *iosock, int hsflag) {
        int ret = gnutls_handshake(iosock->sslnode->ssl.client.session);
-    iosock->socket_flags &= ~IOSOCKETFLAG_SSL_WANTWRITE;
+       iosock->socket_flags &= ~IOSOCKETFLAG_SSL_WANTWRITE;
        
        if(ret < 0) {
                if(gnutls_error_is_fatal(ret) == 0) {
@@ -197,14 +200,14 @@ static void iossl_rehandshake(struct _IOSocket *iosock, int hsflag) {
 }
 
 int iossl_read(struct _IOSocket *iosock, char *buffer, int len) {
-    if((iosock->socket_flags & (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED)) != (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED))
+       if((iosock->socket_flags & (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED)) != (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED))
                return 0;
        if((iosock->socket_flags & IOSOCKETFLAG_SSL_READHS)) {
                iossl_rehandshake(iosock, IOSOCKETFLAG_SSL_READHS);
                errno = EAGAIN;
                return -1;
        }
-    int ret = gnutls_record_recv(iosock->sslnode->ssl.client.session, buffer, len);
+       int ret = gnutls_record_recv(iosock->sslnode->ssl.client.session, buffer, len);
        if(ret == 0) {
                //TLS session closed
                //TODO: Action?
@@ -220,19 +223,19 @@ int iossl_read(struct _IOSocket *iosock, char *buffer, int len) {
                errno = ret;
                return ret;
        }
-    return ret;
+       return ret;
 }
 
 int iossl_write(struct _IOSocket *iosock, char *buffer, int len) {
-    if((iosock->socket_flags & (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED)) != (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED))
+       if((iosock->socket_flags & (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED)) != (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED))
                return 0;
        if((iosock->socket_flags & IOSOCKETFLAG_SSL_WRITEHS)) {
                iossl_rehandshake(iosock, IOSOCKETFLAG_SSL_WRITEHS);
                errno = EAGAIN;
                return -1;
        }
-    int ret = gnutls_record_send(iosock->sslnode->ssl.client.session, buffer, len);
-    if(ret < 0 && gnutls_error_is_fatal(ret) == 0) {
+       int ret = gnutls_record_send(iosock->sslnode->ssl.client.session, buffer, len);
+       if(ret < 0 && gnutls_error_is_fatal(ret) == 0) {
                iolog_trigger(IOLOG_WARNING, "gnutls_record_send for fd %d returned %s", iosock->fd, gnutls_strerror(ret));
                if(ret == GNUTLS_E_REHANDSHAKE) {
                        iossl_rehandshake(iosock, IOSOCKETFLAG_SSL_WRITEHS);
@@ -244,7 +247,7 @@ int iossl_write(struct _IOSocket *iosock, char *buffer, int len) {
                errno = ret;
                return ret;
        }
-    return ret;
+       return ret;
 }
 
 #elif defined(HAVE_OPENSSL_SSL_H)
@@ -252,221 +255,227 @@ int iossl_write(struct _IOSocket *iosock, char *buffer, int len) {
 
 
 void iossl_init() {
-    SSL_library_init();
-    OpenSSL_add_all_algorithms(); /* load & register all cryptos, etc. */
-    SSL_load_error_strings();
+       SSL_library_init();
+       OpenSSL_add_all_algorithms(); /* load & register all cryptos, etc. */
+       SSL_load_error_strings();
 }
 
 static void iossl_error() {
-    unsigned long e;
-    while((e = ERR_get_error())) {
-        iolog_trigger(IOLOG_ERROR, "SSLv23 ERROR %lu: %s", e, ERR_error_string(e, NULL));
-    }
+       unsigned long e;
+       while((e = ERR_get_error())) {
+               iolog_trigger(IOLOG_ERROR, "SSLv23 ERROR %lu: %s", e, ERR_error_string(e, NULL));
+       }
 }
 
 // Client
 void iossl_connect(struct _IOSocket *iosock) {
-    struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
-    sslnode->sslContext = SSL_CTX_new(SSLv23_client_method());
-    if(!sslnode->sslContext) {
-        iossl_error();
-        iolog_trigger(IOLOG_ERROR, "SSL: could not create client SSL CTX");
-        goto ssl_connect_err;
-    }
-    sslnode->sslHandle = SSL_new(sslnode->sslContext);
-    if(!sslnode->sslHandle) {
-        iossl_error();
-        iolog_trigger(IOLOG_ERROR, "SSL: could not create client SSL Handle");
-        goto ssl_connect_err;
-    }
-    if(!SSL_set_fd(sslnode->sslHandle, iosock->fd)) {
-        iossl_error();
-        iolog_trigger(IOLOG_ERROR, "SSL: could not set client fd in SSL Handle");
-        goto ssl_connect_err;
-    }
-    SSL_set_connect_state(sslnode->sslHandle);
-    iosock->sslnode = sslnode;
+       struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
+       sslnode->sslContext = SSL_CTX_new(SSLv23_client_method());
+       if(!sslnode->sslContext) {
+               iossl_error();
+               iolog_trigger(IOLOG_ERROR, "SSL: could not create client SSL CTX");
+               goto ssl_connect_err;
+       }
+       sslnode->sslHandle = SSL_new(sslnode->sslContext);
+       if(!sslnode->sslHandle) {
+               iossl_error();
+               iolog_trigger(IOLOG_ERROR, "SSL: could not create client SSL Handle");
+               goto ssl_connect_err;
+       }
+       if(!SSL_set_fd(sslnode->sslHandle, iosock->fd)) {
+               iossl_error();
+               iolog_trigger(IOLOG_ERROR, "SSL: could not set client fd in SSL Handle");
+               goto ssl_connect_err;
+       }
+       SSL_set_connect_state(sslnode->sslHandle);
+       iosock->sslnode = sslnode;
        iosock->socket_flags |= IOSOCKETFLAG_SSL_HANDSHAKE;
-    iossl_client_handshake(iosock);
-    return;
+       iossl_client_handshake(iosock);
+       return;
 ssl_connect_err:
-    free(sslnode);
-    iosocket_events_callback(iosock, 0, 0);
+       free(sslnode);
+       iosocket_events_callback(iosock, 0, 0);
 }
 
 void iossl_client_handshake(struct _IOSocket *iosock) {
-    // Perform an SSL handshake.
-    int ret = SSL_do_handshake(iosock->sslnode->sslHandle);
-    iosock->socket_flags &= ~IOSOCKETFLAG_SSL_WANTWRITE;
-    switch(SSL_get_error(iosock->sslnode->sslHandle, ret)) {
-        case SSL_ERROR_NONE:
-            iolog_trigger(IOLOG_DEBUG, "SSL handshake for fd %d successful", iosock->fd);
+       // Perform an SSL handshake.
+       int ret = SSL_do_handshake(iosock->sslnode->sslHandle);
+       iosock->socket_flags &= ~IOSOCKETFLAG_SSL_WANTWRITE;
+       switch(SSL_get_error(iosock->sslnode->sslHandle, ret)) {
+               case SSL_ERROR_NONE:
+                       iolog_trigger(IOLOG_DEBUG, "SSL handshake for fd %d successful", iosock->fd);
                        iosock->socket_flags |= IOSOCKETFLAG_SSL_ESTABLISHED;
-            iosocket_events_callback(iosock, 0, 0); //perform IOEVENT_CONNECTED event
-            break;
-        case SSL_ERROR_WANT_READ:
-            iolog_trigger(IOLOG_DEBUG, "SSL_do_handshake for fd %d returned SSL_ERROR_WANT_READ", iosock->fd);
-            break;
-        case SSL_ERROR_WANT_WRITE:
-            iosock->socket_flags |= IOSOCKETFLAG_SSL_WANTWRITE;
-            iolog_trigger(IOLOG_DEBUG, "SSL_do_handshake for fd %d returned SSL_ERROR_WANT_WRITE", iosock->fd);
-            break;
-        default:
-            iolog_trigger(IOLOG_ERROR, "SSL_do_handshake for fd %d failed with ", iosock->fd);
-            iosocket_events_callback(iosock, 0, 0);
-            break;
-    }
+                       iosocket_events_callback(iosock, 0, 0); //perform IOEVENT_CONNECTED event
+                       break;
+               case SSL_ERROR_WANT_READ:
+                       iolog_trigger(IOLOG_DEBUG, "SSL_do_handshake for fd %d returned SSL_ERROR_WANT_READ", iosock->fd);
+                       break;
+               case SSL_ERROR_WANT_WRITE:
+                       iosock->socket_flags |= IOSOCKETFLAG_SSL_WANTWRITE;
+                       iolog_trigger(IOLOG_DEBUG, "SSL_do_handshake for fd %d returned SSL_ERROR_WANT_WRITE", iosock->fd);
+                       break;
+               default:
+                       iolog_trigger(IOLOG_ERROR, "SSL_do_handshake for fd %d failed with ", iosock->fd);
+                       iosocket_events_callback(iosock, 0, 0);
+                       break;
+       }
 }
 
 
 // Server
 void iossl_listen(struct _IOSocket *iosock, const char *certfile, const char *keyfile) {
-    struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
-    sslnode->sslContext = SSL_CTX_new(SSLv23_server_method());
-    if(!sslnode->sslContext) {
-        iossl_error();
-        iolog_trigger(IOLOG_ERROR, "SSL: could not create server SSL CTX");
-        goto ssl_listen_err;
-    }
-    /* load certificate */
-    if(SSL_CTX_use_certificate_file(sslnode->sslContext, certfile, SSL_FILETYPE_PEM) <= 0) {
-        iossl_error();
-        iolog_trigger(IOLOG_ERROR, "SSL: could not load server certificate (%s)", certfile);
-        goto ssl_listen_err;
-    }
-    /* load keyfile */
-    if(SSL_CTX_use_PrivateKey_file(sslnode->sslContext, keyfile, SSL_FILETYPE_PEM) <= 0) {
-        iossl_error();
-        iolog_trigger(IOLOG_ERROR, "SSL: could not load server keyfile (%s)", keyfile);
-        goto ssl_listen_err;
-    }
-    /* check certificate and keyfile */
-    if(!SSL_CTX_check_private_key(sslnode->sslContext)) {
-        iossl_error();
-        iolog_trigger(IOLOG_ERROR, "SSL: server certificate (%s) and keyfile (%s) doesn't match!", certfile, keyfile);
-        goto ssl_listen_err;
-    }
-    iosock->sslnode = sslnode;\r
-    iosock->socket_flags |= IOSOCKETFLAG_SSL_ESTABLISHED;
-    return;
+       struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
+       sslnode->sslContext = SSL_CTX_new(SSLv23_server_method());
+       if(!sslnode->sslContext) {
+               iossl_error();
+               iolog_trigger(IOLOG_ERROR, "SSL: could not create server SSL CTX");
+               goto ssl_listen_err;
+       }
+       /* load certificate */
+       if(SSL_CTX_use_certificate_file(sslnode->sslContext, certfile, SSL_FILETYPE_PEM) <= 0) {
+               iossl_error();
+               iolog_trigger(IOLOG_ERROR, "SSL: could not load server certificate (%s)", certfile);
+               goto ssl_listen_err;
+       }
+       /* load keyfile */
+       if(SSL_CTX_use_PrivateKey_file(sslnode->sslContext, keyfile, SSL_FILETYPE_PEM) <= 0) {
+               iossl_error();
+               iolog_trigger(IOLOG_ERROR, "SSL: could not load server keyfile (%s)", keyfile);
+               goto ssl_listen_err;
+       }
+       /* check certificate and keyfile */
+       if(!SSL_CTX_check_private_key(sslnode->sslContext)) {
+               iossl_error();
+               iolog_trigger(IOLOG_ERROR, "SSL: server certificate (%s) and keyfile (%s) doesn't match!", certfile, keyfile);
+               goto ssl_listen_err;
+       }
+       iosock->sslnode = sslnode;
+       iosock->socket_flags |= IOSOCKETFLAG_SSL_ESTABLISHED;
+       return;
 ssl_listen_err:
-    free(sslnode);
-    iosock->sslnode = NULL;
-    iosocket_events_callback(iosock, 0, 0);
+       free(sslnode);
+       iosock->sslnode = NULL;
+       iosocket_events_callback(iosock, 0, 0);
 }
 
 void iossl_client_accepted(struct _IOSocket *iosock, struct _IOSocket *new_iosock) {
-    struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
-    sslnode->sslHandle = SSL_new(iosock->sslnode->sslContext);
-    if(!sslnode->sslHandle) {
-        iossl_error();
-        iolog_trigger(IOLOG_ERROR, "SSL: could not create client SSL Handle");
-        goto ssl_accept_err;
-    }
-    if(!SSL_set_fd(sslnode->sslHandle, new_iosock->fd)) {
-        iossl_error();
-        iolog_trigger(IOLOG_ERROR, "SSL: could not set client fd in SSL Handle");
-        goto ssl_accept_err;
-    }
-    new_iosock->sslnode = sslnode;\r
-    new_iosock->socket_flags |= IOSOCKETFLAG_SSL_HANDSHAKE;
-    return;
+       struct IOSSLDescriptor *sslnode = malloc(sizeof(*sslnode));
+       sslnode->sslHandle = SSL_new(iosock->sslnode->sslContext);
+       if(!sslnode->sslHandle) {
+               iossl_error();
+               iolog_trigger(IOLOG_ERROR, "SSL: could not create client SSL Handle");
+               goto ssl_accept_err;
+       }
+       if(!SSL_set_fd(sslnode->sslHandle, new_iosock->fd)) {
+               iossl_error();
+               iolog_trigger(IOLOG_ERROR, "SSL: could not set client fd in SSL Handle");
+               goto ssl_accept_err;
+       }
+       new_iosock->sslnode = sslnode;
+       new_iosock->socket_flags |= IOSOCKETFLAG_SSL_HANDSHAKE;
+       return;
 ssl_accept_err:
-    free(sslnode);\r
-    iosock->sslnode = NULL;\r
-    iosocket_events_callback(new_iosock, 0, 0);
+       free(sslnode);
+       iosock->sslnode = NULL;
+       iosocket_events_callback(new_iosock, 0, 0);
 }
 
 void iossl_server_handshake(struct _IOSocket *iosock) {
-    // Perform an SSL handshake.
-    int ret = SSL_accept(iosock->sslnode->sslHandle);
-    iosock->socket_flags &= ~IOSOCKETFLAG_SSL_WANTWRITE;
-    switch(SSL_get_error(iosock->sslnode->sslHandle, ret)) {
-        case SSL_ERROR_NONE:
-            iolog_trigger(IOLOG_DEBUG, "SSL handshake for fd %d successful", iosock->fd);
+       // Perform an SSL handshake.
+       int ret = SSL_accept(iosock->sslnode->sslHandle);
+       iosock->socket_flags &= ~IOSOCKETFLAG_SSL_WANTWRITE;
+       switch(SSL_get_error(iosock->sslnode->sslHandle, ret)) {
+               case SSL_ERROR_NONE:
+                       iolog_trigger(IOLOG_DEBUG, "SSL handshake for fd %d successful", iosock->fd);
                        iosock->socket_flags |= IOSOCKETFLAG_SSL_ESTABLISHED;
-            iosocket_events_callback(iosock, 0, 0); //perform IOEVENT_CONNECTED event
-            break;
-        case SSL_ERROR_WANT_READ:
-            iolog_trigger(IOLOG_DEBUG, "SSL_do_handshake for fd %d returned SSL_ERROR_WANT_READ", iosock->fd);
-            break;
-        case SSL_ERROR_WANT_WRITE:
-            iosock->socket_flags |= IOSOCKETFLAG_SSL_WANTWRITE;
-            iolog_trigger(IOLOG_DEBUG, "SSL_do_handshake for fd %d returned SSL_ERROR_WANT_WRITE", iosock->fd);
-            break;
-        default:
-            iolog_trigger(IOLOG_ERROR, "SSL_do_handshake for fd %d failed with ", iosock->fd);
-            iosocket_events_callback(iosock, 0, 0);
-            break;
-    }
+                       iosocket_events_callback(iosock, 0, 0); //perform IOEVENT_CONNECTED event
+                       break;
+               case SSL_ERROR_WANT_READ:
+                       iolog_trigger(IOLOG_DEBUG, "SSL_do_handshake for fd %d returned SSL_ERROR_WANT_READ", iosock->fd);
+                       break;
+               case SSL_ERROR_WANT_WRITE:
+                       iosock->socket_flags |= IOSOCKETFLAG_SSL_WANTWRITE;
+                       iolog_trigger(IOLOG_DEBUG, "SSL_do_handshake for fd %d returned SSL_ERROR_WANT_WRITE", iosock->fd);
+                       break;
+               default:
+                       iolog_trigger(IOLOG_ERROR, "SSL_do_handshake for fd %d failed with ", iosock->fd);
+                       iosocket_events_callback(iosock, 0, 0);
+                       break;
+       }
 }
 
 void iossl_disconnect(struct _IOSocket *iosock) {
-    if(!iosock->sslnode) return;
-    SSL_shutdown(iosock->sslnode->sslHandle);
-    SSL_free(iosock->sslnode->sslHandle);
-    SSL_CTX_free(iosock->sslnode->sslContext);
-    free(iosock->sslnode);
-    iosock->sslnode = NULL;
-    iosock->socket_flags &= ~IOSOCKETFLAG_SSLSOCKET;
+       if(!iosock->sslnode) return;
+       SSL_shutdown(iosock->sslnode->sslHandle);
+       SSL_free(iosock->sslnode->sslHandle);
+       if(!(iosock->socket_flags & IOSOCKETFLAG_INCOMING))
+               SSL_CTX_free(iosock->sslnode->sslContext);
+       free(iosock->sslnode);
+       iosock->sslnode = NULL;
+       iosock->socket_flags &= ~IOSOCKETFLAG_SSLSOCKET;
 }
 
 int iossl_read(struct _IOSocket *iosock, char *buffer, int len) {
-    if((iosock->socket_flags & (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED)) != (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED))\r
+       if((iosock->socket_flags & (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED)) != (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED))
                return 0;
-    int ret = SSL_read(iosock->sslnode->sslHandle, buffer, len);
-    iosock->socket_flags &= ~(IOSOCKETFLAG_SSL_WANTWRITE | IOSOCKETFLAG_SSL_READHS);
-    switch(SSL_get_error(iosock->sslnode->sslHandle, ret)) {
-        case SSL_ERROR_NONE:
-        case SSL_ERROR_ZERO_RETURN:
-            break;
-        case SSL_ERROR_WANT_READ:\r
+       int ret = SSL_read(iosock->sslnode->sslHandle, buffer, len);
+       iosock->socket_flags &= ~(IOSOCKETFLAG_SSL_WANTWRITE | IOSOCKETFLAG_SSL_READHS);
+       int err = SSL_get_error(iosock->sslnode->sslHandle, ret);
+       switch(err) {
+               case SSL_ERROR_NONE:
+               case SSL_ERROR_ZERO_RETURN:
+                       break;
+               case SSL_ERROR_WANT_READ:
                        iosock->socket_flags |= IOSOCKETFLAG_SSL_READHS;
-            iolog_trigger(IOLOG_DEBUG, "SSL_read for fd %d returned SSL_ERROR_WANT_READ", iosock->fd);
-            errno = EAGAIN;
-            ret = -1;
-            break;
-        case SSL_ERROR_WANT_WRITE:
-            iosock->socket_flags |= IOSOCKETFLAG_SSL_WANTWRITE | IOSOCKETFLAG_SSL_READHS;
-            iolog_trigger(IOLOG_DEBUG, "SSL_read for fd %d returned SSL_ERROR_WANT_WRITE", iosock->fd);
-            errno = EAGAIN;
-            ret = -1;
-            break;
-        default:
-            iolog_trigger(IOLOG_ERROR, "SSL_read for fd %d failed with ", iosock->fd);
-            ret = -1;
-            break;
-    }\r
-    return ret;
+                       iolog_trigger(IOLOG_DEBUG, "SSL_read for fd %d returned SSL_ERROR_WANT_READ", iosock->fd);
+                       errno = EAGAIN;
+                       ret = -1;
+                       break;
+               case SSL_ERROR_WANT_WRITE:
+                       iosock->socket_flags |= IOSOCKETFLAG_SSL_WANTWRITE | IOSOCKETFLAG_SSL_READHS;
+                       iolog_trigger(IOLOG_DEBUG, "SSL_read for fd %d returned SSL_ERROR_WANT_WRITE", iosock->fd);
+                       errno = EAGAIN;
+                       ret = -1;
+                       break;
+               case SSL_ERROR_SYSCALL:
+                       iolog_trigger(IOLOG_ERROR, "SSL_read for fd %d failed with SSL_ERROR_SYSCALL: %d", iosock->fd, errno);
+                       ret = -1;
+                       break;
+               default:
+                       iolog_trigger(IOLOG_ERROR, "SSL_read for fd %d failed with %d", iosock->fd, err);
+                       ret = -1;
+                       break;
+       }
+       return ret;
 }
 
 int iossl_write(struct _IOSocket *iosock, char *buffer, int len) {
-    if((iosock->socket_flags & (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED)) != (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED))\r
+       if((iosock->socket_flags & (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED)) != (IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_ESTABLISHED))
                return 0;
-    int ret = SSL_write(iosock->sslnode->sslHandle, buffer, len);
-    iosock->socket_flags &= ~(IOSOCKETFLAG_SSL_WANTWRITE | IOSOCKETFLAG_SSL_WRITEHS);
-    switch(SSL_get_error(iosock->sslnode->sslHandle, ret)) {
-        case SSL_ERROR_NONE:
-        case SSL_ERROR_ZERO_RETURN:
-            break;
-        case SSL_ERROR_WANT_READ:
-            iosock->socket_flags |= IOSOCKETFLAG_SSL_WRITEHS;
-            iolog_trigger(IOLOG_DEBUG, "SSL_write for fd %d returned SSL_ERROR_WANT_READ", iosock->fd);
-            errno = EAGAIN;
-            ret = -1;
-            break;
-        case SSL_ERROR_WANT_WRITE:
-            iosock->socket_flags |= IOSOCKETFLAG_SSL_WANTWRITE | IOSOCKETFLAG_SSL_WRITEHS;
-            iolog_trigger(IOLOG_DEBUG, "SSL_write for fd %d returned SSL_ERROR_WANT_WRITE", iosock->fd);
-            errno = EAGAIN;
-            ret = -1;
-            break;
-        default:
-            iolog_trigger(IOLOG_ERROR, "SSL_write for fd %d failed with ", iosock->fd);
-            ret = -1;
-            break;
-    }\r
-    return ret;
+       int ret = SSL_write(iosock->sslnode->sslHandle, buffer, len);
+       iosock->socket_flags &= ~(IOSOCKETFLAG_SSL_WANTWRITE | IOSOCKETFLAG_SSL_WRITEHS);
+       switch(SSL_get_error(iosock->sslnode->sslHandle, ret)) {
+               case SSL_ERROR_NONE:
+               case SSL_ERROR_ZERO_RETURN:
+                       break;
+               case SSL_ERROR_WANT_READ:
+                       iosock->socket_flags |= IOSOCKETFLAG_SSL_WRITEHS;
+                       iolog_trigger(IOLOG_DEBUG, "SSL_write for fd %d returned SSL_ERROR_WANT_READ", iosock->fd);
+                       errno = EAGAIN;
+                       ret = -1;
+                       break;
+               case SSL_ERROR_WANT_WRITE:
+                       iosock->socket_flags |= IOSOCKETFLAG_SSL_WANTWRITE | IOSOCKETFLAG_SSL_WRITEHS;
+                       iolog_trigger(IOLOG_DEBUG, "SSL_write for fd %d returned SSL_ERROR_WANT_WRITE", iosock->fd);
+                       errno = EAGAIN;
+                       ret = -1;
+                       break;
+               default:
+                       iolog_trigger(IOLOG_ERROR, "SSL_write for fd %d failed with ", iosock->fd);
+                       ret = -1;
+                       break;
+       }
+       return ret;
 }
 
 #else
index 91e69261bded749f7c4c8699ae4b279bdd57c673..abae08fdb0c04f57ed2795421589c7c3a9497262 100644 (file)
@@ -551,7 +551,7 @@ static void iosocket_listen_finish(struct _IOSocket *iosock) {
        if((iosock->socket_flags & IOSOCKETFLAG_IPV6SOCKET)) {
                struct sockaddr_in6 *ip6bind = (void*) iosock->bind.addr.address;
                ip6bind->sin6_family = AF_INET6;
-               ip6bind->sin6_port = htons(0);
+               ip6bind->sin6_port = htons(iosock->port);
                
                int opt = 1;
                setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt));
@@ -560,7 +560,7 @@ static void iosocket_listen_finish(struct _IOSocket *iosock) {
        } else {
                struct sockaddr_in *ip4bind = (void*) iosock->bind.addr.address;
                ip4bind->sin_family = AF_INET;
-               ip4bind->sin_port = htons(0);
+               ip4bind->sin_port = htons(iosock->port);
                
                int opt = 1;
                setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt));
@@ -591,6 +591,7 @@ struct _IOSocket *iosocket_accept_client(struct _IOSocket *iosock) {
        }
        new_iosocket->iosocket = new_iosock;
        new_iosocket->status = IOSOCKET_CONNECTED;
+       new_iosocket->data = iosock;
        new_iosock->parent = new_iosocket;
        new_iosock->socket_flags |= IOSOCKETFLAG_PARENT_PUBLIC | IOSOCKETFLAG_INCOMING | (iosock->socket_flags & IOSOCKETFLAG_IPV6SOCKET);
        
@@ -753,7 +754,7 @@ struct IOSocket *iosocket_listen_ssl(const char *hostname, unsigned int port, co
 struct IOSocket *iosocket_listen_ssl_flags(const char *hostname, unsigned int port, const char *certfile, const char *keyfile, iosocket_callback *callback, int flags) {
        struct IOSocket *iosocket = iosocket_listen_flags(hostname, port, callback, flags);\r
        struct _IOSocket *iosock = iosocket->iosocket;\r
-       iosock->socket_flags |= IOSOCKETFLAG_SSLSOCKET | IOSOCKETFLAG_SSL_HANDSHAKE;\r
+       iosock->socket_flags |= IOSOCKETFLAG_SSLSOCKET;\r
        iossl_listen(iosock, certfile, keyfile);
        return iosocket;
 }
@@ -910,7 +911,12 @@ void iosocket_events_callback(struct _IOSocket *iosock, int readable, int writea
                                        //incoming SSL connection accepted\r
                                        iosock->socket_flags &= ~IOSOCKETFLAG_SSL_HANDSHAKE;\r
                                        callback_event.type = IOSOCKETEVENT_ACCEPT;\r
-                                       callback_event.data.accept_socket = iosock->parent;\r
+                                       callback_event.data.accept_socket = iosock->parent;
+                                       struct _IOSocket *parent_socket = iosocket->data;
+                                       callback_event.socket = parent_socket->parent;
+                                       
+                                       //initialize readbuf
+                                       iosocket_increase_buffer(&iosock->readbuf, 1024);\r
                                } else {\r
                                        //incoming SSL connection failed, simply drop\r
                                        iosock->socket_flags |= IOSOCKETFLAG_DEAD;\r
index 37b5dc18357d3e8cdf551729f788b2158f5939fc..6407216d2067feb9a1d7283ec60ab985395d19f9 100644 (file)
@@ -22,7 +22,7 @@
 #include "../../IOHandler/IOLog.h"
 
 #define CERTFILE "cert.pem"
-#define KEYFILE "key.pen"
+#define KEYFILE "key.pem"
 
 static IOSOCKET_CALLBACK(io_callback);
 static IOLOG_CALLBACK(io_log);