]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
modules/prefill and TA: Move https_fetch to daemon/lua/kluautil.lua
authorLukáš Ježek <lukas.jezek@nic.cz>
Thu, 19 Dec 2019 10:28:02 +0000 (11:28 +0100)
committerPetr Špaček <petr.spacek@nic.cz>
Fri, 20 Dec 2019 09:23:40 +0000 (10:23 +0100)
daemon/lua/kluautil.lua
daemon/lua/trust_anchors.lua.in
modules/policy/policy.lua
modules/prefill/prefill.lua

index 1ab6d5356979d6751a9ecd72d00a1b268a5b23d2..158927914d96c5f30d5f94642265e88842ed352b 100644 (file)
@@ -8,3 +8,39 @@ function kr_table_len (t)
        return len
 end
 
+-- Fetch over HTTPS
+function kr_https_fetch (url, ca_file, file)
+       local http_ok, http_request = pcall(require, 'http.request')
+       local openssl_ok, openssl_ctx = pcall(require, 'openssl.ssl.context')
+
+       if not http_ok or not openssl_ok then
+               return nil, 'error: lua-http and luaossl libraries are missing (but required)'
+       end
+
+       assert(string.match(url, '^https://'))
+       assert(ca_file)
+
+       local req = http_request.new_from_uri(url)
+       req.ctx = openssl_ctx.new()
+       local store = req.ctx:getStore()
+       store:add(ca_file)
+
+       req.ctx:setVerify(openssl_ctx.VERIFY_PEER)
+       req.tls = true
+
+       local headers, stream = req:go()
+       assert(headers, 'HTTP client library error')
+       if headers:get(':status') ~= "200" then
+               return nil, headers:get(':status')
+       end
+
+       local err, errmsg = stream:save_body_to_file(file)
+       if err == nil then
+               return err, errmsg
+       end
+
+       file:seek ("set", 0)
+
+       return true
+end
+
index 87135c81aa46358a57d015b22949236089aa93a0..2676a6a3398f3d5eb018c48247ecbf9ac2558128 100644 (file)
@@ -22,32 +22,6 @@ local function upgrade_required(msg)
 end
 
 -- TODO: Move bootstrap to a separate module or even its own binary
--- Fetch over HTTPS with peert cert checked
-local function https_fetch(url, ca)
-       local http_ok, http_request = pcall(require, 'http.request')
-       local openssl_ok, openssl_ctx = pcall(require, 'openssl.ssl.context')
-
-       if not http_ok or not openssl_ok then
-               return nil, 'error: lua-http and luaossl libraries are missing (but required) for root TA bootstrap'
-       end
-
-       local request = http_request.new_from_uri(url)
-       request.ctx = openssl_ctx.new('TLSv1_2')
-       local store = request.ctx:getStore()
-       store:add(ca)
-
-       request.ctx:setVerify(openssl_ctx.VERIFY_PEER)
-       request.tls = true
-
-       local headers, stream = request:go()
-       if headers == nil then return nil, 'HTTP client library error' end
-       if headers:get(':status') ~= "200" then return nil, headers:get(':status') end
-
-       local resp, err = stream:get_body_as_string()
-
-       return resp, err or ""
-end
-
 -- remove UTC timezone specification if present or throw error
 local function time2utc(orig_timespec)
        local patterns = {'[+-]00:00$', 'Z$'}
@@ -144,15 +118,21 @@ end
 -- Fetch root anchors in XML over HTTPS, returning a zone-file-style string
 -- or false in case of error, and a message.
 local function bootstrap(url, ca)
+       local kluautil = pcall(require, 'kluautil')
+       local file = io.tmpfile()
        -- RFC 7958, sec. 2, but we don't do precise XML parsing.
        -- @todo ICANN certificate is verified against current CA
        --       this is not ideal, as it should rather verify .xml signature which
        --       is signed by ICANN long-lived cert, but luasec has no PKCS7
-       local xml, err = https_fetch(url, ca)
-       if not xml then
-               return false, string.format('[ ta ] fetch of "%s" failed: %s', url, err)
+       local rcode, errmsg = kluautil.kr_https_fetch(url, ca, file)
+       if rcode == nil then
+               file:close()
+               return false, string.format('[ ta ] fetch of "%s" failed: %s', url, errmsg)
        end
 
+       local xml = file:read("*a")
+       file:close()
+
        -- we support only minimal subset of https://tools.ietf.org/html/rfc7958
        assert_str_match(xml, '<?xml version="1%.0" encoding="UTF%-8"%?>', 1)
        assert_str_match(xml, '<TrustAnchor ', 1)
index c5775aae72635ac64a0698f6f439333a3ce6108a..d9da4d80031d8c7e4ca01003e7cb0ae442ac66d2 100644 (file)
@@ -13,7 +13,7 @@ end
 
 -- Support for client sockets from inside policy actions
 local socket_client = function ()
-       return error("missing lua-cqueues library, can't create socket client") 
+       return error("missing lua-cqueues library, can't create socket client")
 end
 local has_socket, socket = pcall(require, 'cqueues.socket')
 if has_socket then
index 821e8bb8f4149525db75fb51459bb63b7d250cdf..aa2246eea89746e795bf9d3336d0202ee8a84cd5 100644 (file)
@@ -16,50 +16,6 @@ local rz_interval_min = 3600
 local prefill = {
 }
 
-
--- Fetch over HTTPS
-local function https_fetch(url, ca_file, fname)
-       local http_ok, http_request = pcall(require, 'http.request')
-       local openssl_ok, openssl_ctx = pcall(require, 'openssl.ssl.context')
-
-       if not http_ok or not openssl_ok then
-               return nil, 'lua-http and luaossl needed for root TA bootstrap'
-       end
-
-       assert(string.match(url, '^https://'))
-       assert(ca_file)
-
-       local req = http_request.new_from_uri(url)
-       req.ctx = openssl_ctx.new()
-       local store = req.ctx:getStore()
-       store:add(ca_file)
-
-       req.ctx:setVerify(openssl_ctx.VERIFY_PEER)
-       req.tls = true
-
-       local headers, stream = req:go()
-       assert(headers, 'HTTP client library error')
-       if headers:get(':status') ~= "200" then
-               return nil, headers:get(':status')
-       end
-
-       local file, errmsg = io.open(fname, 'w')
-       if not file then
-               error(string.format("[prefill] unable to open file %s (%s)",
-                       fname, errmsg))
-       end
-
-       local err
-       err, errmsg = stream:save_body_to_file(file)
-       if err == nil then
-               return err, errmsg
-       end
-
-       file:close()
-
-       return file
-end
-
 local function display_delay(time)
        local days = math.floor(time / 86400)
        local hours = math.floor((time % 86400) / 3600)
@@ -93,11 +49,21 @@ local function get_file_ttl(fname)
 end
 
 local function download(url, fname)
+       local kluautil = pcall(require, 'kluautil')
+       local file, rcode, errmsg
+       file, errmsg = io.open(fname, 'w')
+       if not file then
+               error(string.format("[prefill] unable to open file %s (%s)",
+                       fname, errmsg))
+       end
+
        log("[prefill] downloading root zone to file %s ...", fname)
-       local rzone, err = https_fetch(url, rz_ca_file, fname)
-       if rzone == nil then
-               error(string.format("[prefill] fetch of `%s` failed: %s", url, err))
+       rcode, errmsg = kluautil.kr_https_fetch(url, rz_ca_file, file)
+       if rcode == nil then
+               error(string.format("[prefill] fetch of `%s` failed: %s", url, errmsg))
        end
+
+       file:close()
 end
 
 local function import(fname)