From: Petr Špaček Date: Thu, 18 Apr 2019 09:00:46 +0000 (+0200) Subject: http: fix http.tls config tests and validate certs during config() X-Git-Tag: v4.0.0~4^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c6e403d1a930f1d6889730c5c9cf08a22b7103a5;p=thirdparty%2Fknot-resolver.git http: fix http.tls config tests and validate certs during config() --- diff --git a/modules/http/http.lua.in b/modules/http/http.lua.in index f76b00673..cdd57f374 100644 --- a/modules/http/http.lua.in +++ b/modules/http/http.lua.in @@ -331,6 +331,29 @@ function mergeconf(...) return merged end +function load_cert(certname, keyname) + local f, err = io.open(certname, 'r') + if not f then + panic('[http] unable to read TLS certificate file %s: %s', certname, err) + end + crt = x509.new(f:read('*all')) + f:close() + if not crt then + panic('[http] unable to parse TLS certificate file %s', certname) + end + + f, err = io.open(keyname, 'r') + if not f then + panic('[http] unable to open TLS key file %s: %s', keyname, err) + end + key = pkey.new(f:read('*all')) + f:close() + if not key then + panic('[http] unable to parse TLS key file %s', keyname) + end + return crt, key +end + -- @function Listen on given socket -- using configuration for specific "kind" of HTTP server function add_socket(fd, kind) @@ -341,22 +364,10 @@ function add_socket(fd, kind) if conf.tls ~= false then -- Check if a cert file was specified -- Read or create self-signed x509 certificate - local f = io.open(conf.cert, 'r') - if f then - crt = assert(x509.new(f:read('*all'))) - f:close() - -- Continue reading key file - if crt then - f = io.open(conf.key, 'r') - if not f then - panic('enable to open HTTP key file %s', - conf.key) - end - key = assert(pkey.new(f:read('*all'))) - f:close() - end - elseif conf.ephemeral then + if conf.ephemeral then crt, key = updatecert(conf.cert, conf.key) + else + crt, key = load_cert(conf.cert, conf.key) end -- Check loaded certificate if not crt or not key then @@ -467,8 +478,10 @@ function M.config(conf, kind) if conf.cert then conf.ephemeral = false if not conf.key then - error('certificate provided, but missing key') + panic('[http] certificate provided, but missing key') end + -- test if it can be loaded or not + load_cert(conf.cert, conf.key) end if conf.geoip then if has_mmdb then diff --git a/modules/http/test_tls/tls.test.lua b/modules/http/test_tls/tls.test.lua index 5bc3bc671..0a9696453 100644 --- a/modules/http/test_tls/tls.test.lua +++ b/modules/http/test_tls/tls.test.lua @@ -14,10 +14,21 @@ else modules.load('http') same(http.config(config), nil, desc .. ' can be configured') - local server = http.servers[1] - ok(server ~= nil, desc .. ' creates server instance') - local _, host, port = server:localname() - ok(host and port, desc .. ' binds to an interface') + local bound + for i = 1,1000 do + bound = net.listen('127.0.0.1', math.random(1025,65535), { kind = 'webmgmt'} ) + if bound then + break + end + end + assert(bound, 'unable to bind a port for HTTP module (1000 attempts)') + + local server_fd = next(http.servers) + assert(server_fd) + local server = http.servers[server_fd].server + ok(server ~= nil, 'creates server instance') + _, host, port = server:localname() + ok(host and port, 'binds to an interface') return host, port end @@ -46,7 +57,7 @@ else end local function test_defaults() - local host, port = setup_module('HTTP module default config', {}) + local host, port = setup_module('HTTP module default config', nil) local uri = string.format('http://%s:%d', host, port) check_protocol(uri, 'HTTP is enabled by default', true) @@ -65,7 +76,6 @@ else local desc = 'HTTP-only config' local host, port = setup_module(desc, { - port = 0, -- Select random port tls = false, }) @@ -79,7 +89,6 @@ else local desc = 'HTTPS-only config' local host, port = setup_module(desc, { - port = 0, -- Select random port tls = true, }) @@ -92,8 +101,6 @@ else local function test_custom_cert() desc = 'config with custom certificate' local host, port = setup_module(desc, {{ - host = host, - port = port, cert = 'test.crt', key = 'test.key' }}) @@ -105,7 +112,6 @@ else local function test_nonexistent_cert() desc = 'config with non-existing certificate file' boom(http.config, {{ - port = 0, cert = '/tmp/surely_nonexistent_cert_1532432095', key = 'test.key' }}, desc) @@ -114,7 +120,6 @@ else local function test_nonexistent_key() desc = 'config with non-existing key file' boom(http.config, {{ - port = 0, cert = 'test.crt', key = '/tmp/surely_nonexistent_cert_1532432095' }}, desc) @@ -123,7 +128,6 @@ else local function test_missing_key_param() desc = 'config with missing key= param' boom(http.config, {{ - port = 0, cert = 'test.crt' }}, desc) end @@ -131,7 +135,6 @@ else local function test_broken_cert() desc = 'config with broken file in cert= param' boom(http.config, {{ - port = 0, cert = 'broken.crt', key = 'test.key' }}, desc) @@ -140,7 +143,6 @@ else local function test_broken_key() desc = 'config with broken file in key= param' boom(http.config, {{ - port = 0, cert = 'test.crt', key = 'broken.key' }}, desc)