adds ssl protocol configuration

Tue, 27 Dec 2016 11:16:39 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Tue, 27 Dec 2016 11:16:39 +0100
changeset 130
198ad9d8cec1
parent 129
fd324464f56f
child 131
70010b94bda5

adds ssl protocol configuration

src/server/daemon/config.c file | annotate | diff | comparison | revisions
src/server/daemon/httplistener.c file | annotate | diff | comparison | revisions
src/server/daemon/httplistener.h file | annotate | diff | comparison | revisions
src/server/daemon/log.c file | annotate | diff | comparison | revisions
src/server/daemon/main.c file | annotate | diff | comparison | revisions
--- a/src/server/daemon/config.c	Mon Dec 26 16:46:55 2016 +0100
+++ b/src/server/daemon/config.c	Tue Dec 27 11:16:39 2016 +0100
@@ -556,6 +556,7 @@
 
 int cfg_handle_listener(ServerConfiguration *cfg, ServerConfigObject *obj) {
     ListenerConfig lc;
+    ZERO(&lc, sizeof(ListenerConfig));
     lc.cfg = cfg;
     lc.port = 8080;
     lc.nacceptors = 1;
@@ -577,20 +578,34 @@
     sstr_t ssl = cfg_directivelist_get_str(obj->directives, S("SSL"));
     if(util_getboolean_s(ssl, WS_FALSE)) {
         sstr_t cert = cfg_directivelist_get_str(obj->directives, S("Cert"));
-        sstr_t privkey = cfg_directivelist_get_str(obj->directives, S("PrivateKey"));
-        sstr_t chain = cfg_directivelist_get_str(obj->directives, S("Chain"));
+        sstr_t privkey = cfg_directivelist_get_str(obj->directives, S("Key"));
+        sstr_t chain = cfg_directivelist_get_str(obj->directives, S("CertChain"));
+        sstr_t disableprot = cfg_directivelist_get_str(
+                obj->directives,
+                S("SSLDisableProtocol"));
+        
         WSBool config_ok = WS_TRUE;
         // TODO: log error
         if(!cert.ptr && !chain.ptr) {
+            log_ereport(
+                    LOG_MISCONFIG,
+                    "SSL Listener %s: Missing Cert or ChainCert directive",
+                    lc.name.ptr);
             config_ok = WS_FALSE;
         }
         if(!privkey.ptr) {
+            log_ereport(
+                    LOG_MISCONFIG,
+                    "SSL Listener %s: Missing Key directive",
+                    lc.name.ptr);
             config_ok = WS_FALSE;
         }
+        
         if(config_ok) {
             lc.certfile = cert;
             lc.privkeyfile = privkey;
             lc.chainfile = chain;
+            lc.disable_proto = disableprot;
             lc.ssl = WS_TRUE;
         }
     } else {
--- a/src/server/daemon/httplistener.c	Mon Dec 26 16:46:55 2016 +0100
+++ b/src/server/daemon/httplistener.c	Tue Dec 27 11:16:39 2016 +0100
@@ -160,12 +160,77 @@
     listener->ref = 1;
     listener->next = NULL;
     listener->ssl = NULL;
+    
+    int error = 0;
+    
     if(conf->ssl) {
         listener->ssl = malloc(sizeof(HttpSSL));
         
-        SSL_CTX *ctx = SSL_CTX_new( SSLv23_server_method());
-        SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
+        SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method());
+        SSL_CTX_set_options(
+                ctx,
+                SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv3);
+        if(conf->disable_proto.ptr) {
+            ssize_t n = 0;
+            sstr_t *plist = sstrsplit(conf->disable_proto, S(","), &n);
+            if(plist) {
+                for(int i=0;i<n;i++) {
+                    sstr_t proto = plist[i];
+                    log_ereport(
+                            LOG_VERBOSE,
+                            "Listener %s: Disable protocol %s",
+                            listener->name.ptr,
+                            proto.ptr);
+                    if(!sstrcasecmp(sstrtrim(proto), S("SSLv2"))) {
+                        SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
+                    } else if(!sstrcasecmp(sstrtrim(proto), S("SSLv3"))) {
+                        SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
+                    } else if(!sstrcasecmp(sstrtrim(proto), S("TLSv1"))) {
+                        SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1);
+                    } else if(!sstrcasecmp(sstrtrim(proto), S("TLSv1.1"))) {
+#ifdef SSL_OP_NO_TLSv1_1
+                        SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1);
+#else
+                        log_ereport(
+                                LOG_WARN,
+                                "Listener: %s: TLSv1.1 already not supported",
+                                listener->name.ptr);
+#endif
+                    } else if(sstrcasecmp(sstrtrim(proto), S("TLSv1.2"))) {
+#ifdef SSL_OP_NO_TLSv1_2
+                        SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2);
+#else
+                        log_ereport(
+                                LOG_WARN,
+                                "Listener: %s: TLSv1.2 already not supported",
+                                listener->name.ptr);
+#endif
+                    } else if(sstrcasecmp(sstrtrim(proto), S("TLSv1.3"))) {
+#ifdef SSL_OP_NO_TLSv1_3
+                        SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_3);
+#else
+                        log_ereport(
+                                LOG_WARN,
+                                "Listener: %s: TLSv1.3 already not supported",
+                                listener->name.ptr);
+#endif
+                    } else {
+                        error = 1;
+                        log_ereport(
+                                LOG_MISCONFIG,
+                                "Listener: %s: Unknown protocol %s",
+                                listener->name.ptr,
+                                proto.ptr);
+                    }
+                    free(proto.ptr);
+                }
+                free(plist);
+            }
+        }
         
+        if(error) {
+            return NULL;
+        }
         // TODO: cleanup on error
         
         sstr_t file;
--- a/src/server/daemon/httplistener.h	Mon Dec 26 16:46:55 2016 +0100
+++ b/src/server/daemon/httplistener.h	Tue Dec 27 11:16:39 2016 +0100
@@ -66,6 +66,7 @@
     sstr_t               certfile;
     sstr_t               privkeyfile;
     sstr_t               chainfile;
+    sstr_t               disable_proto;
 };
 
 struct _acceptor {
--- a/src/server/daemon/log.c	Mon Dec 26 16:46:55 2016 +0100
+++ b/src/server/daemon/log.c	Tue Dec 27 11:16:39 2016 +0100
@@ -144,6 +144,8 @@
 }
 
 void log_uninitialized_writeln(char *str, size_t len) {
+    printf("%.*s\n", (int)len, str);
+    
     if(ui_buffer == NULL) {
         ui_buffer = sbuf_new(1024);
         if(ui_buffer == NULL) {
@@ -162,6 +164,7 @@
 void log_file_writeln(char *str, size_t len) {
     if(!is_initialized) {
         log_uninitialized_writeln(str, len);
+        return;
     }
     
     struct iovec io[] = {
@@ -169,7 +172,7 @@
         { "\n", 1}
     };
     
-    writev(log_file_fd, io, 2); /* TODO: aio */
+    writev(log_file_fd, io, 2); /* TODO: aio? */
     if(!main_is_daemon()) {
         writev(STDOUT_FILENO, io, 2);
     }
--- a/src/server/daemon/main.c	Mon Dec 26 16:46:55 2016 +0100
+++ b/src/server/daemon/main.c	Tue Dec 27 11:16:39 2016 +0100
@@ -158,6 +158,8 @@
     sigaction(SIGPIPE, &act, NULL);
 
     /* start webserver */
+    log_ereport(LOG_INFORM, "startup");
+    
     int status;
     status = webserver_init();
     if(status != 0) {

mercurial