]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
http: fix http.tls config tests and validate certs during config()
authorPetr Špaček <petr.spacek@nic.cz>
Thu, 18 Apr 2019 09:00:46 +0000 (11:00 +0200)
committerPetr Špaček <petr.spacek@nic.cz>
Thu, 18 Apr 2019 09:00:46 +0000 (11:00 +0200)
modules/http/http.lua.in
modules/http/test_tls/tls.test.lua

index f76b00673cefe1bc2c288b03fc5e9e9b8b4bac02..cdd57f37444a274aa4814eaa512f730836f69a44 100644 (file)
@@ -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
index 5bc3bc671d9ce25bc7c30af3e9a1b5d1afce0df7..0a96964531cfd4e7ba7288ed034b6de856877eca 100644 (file)
@@ -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)