Tue, 27 Dec 2016 11:16:39 +0100
adds ssl protocol configuration
--- 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); }