]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
trust anchor bootstrapping: parse multiple records
authorVladimír Čunát <vladimir.cunat@nic.cz>
Fri, 3 Feb 2017 16:17:26 +0000 (17:17 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Thu, 9 Feb 2017 16:42:26 +0000 (17:42 +0100)
daemon/engine.c
daemon/lua/trust_anchors.lua

index 21cf159040ea8221db9fca3d570412da704795d2..23d03986381b060015e8a49f6a3371dd1aa65e8a 100644 (file)
@@ -232,6 +232,15 @@ static int l_option(lua_State *L)
        return 1;
 }
 
+/** @internal for l_trustanchor: */
+static void ta_add(zs_scanner_t *zs)
+{
+       map_t *ta = zs->process.data;
+       if (!ta)
+               return;
+       if (kr_ta_add(ta, zs->r_owner, zs->r_type, zs->r_ttl, zs->r_data, zs->r_data_length))
+               zs->process.data = NULL; /* error signalling */
+}
 /** Enable/disable trust anchor. */
 static int l_trustanchor(lua_State *L)
 {
@@ -260,13 +269,11 @@ static int l_trustanchor(lua_State *L)
                lua_pushstring(L, "not enough memory");
                lua_error(L);
        }
-       int ok = zs_set_input_string(zs, anchor, strlen(anchor)) == 0 &&
-                zs_parse_all(zs) == 0;
-       /* Add it to TA set and cleanup */
-       if (ok) {
-               ok = kr_ta_add(&engine->resolver.trust_anchors,
-                              zs->r_owner, zs->r_type, zs->r_ttl, zs->r_data, zs->r_data_length) == 0;
-       }
+       zs_set_processing(zs, ta_add, NULL, &engine->resolver.trust_anchors);
+       bool ok = zs_set_input_string(zs, anchor, strlen(anchor)) == 0
+               && zs_parse_all(zs) == 0;
+       ok = ok && zs->process.data; /* reset to NULL on error in ta_add */
+
        zs_deinit(zs);
        free(zs);
        /* Report errors */
index 52eb0d546f2b2b651547fb05ae7e9b48baf4a305..b219e6a007ba68c2c35055adb16d02940e8fc4af 100644 (file)
@@ -17,7 +17,7 @@ local function https_fetch(url, ca)
        return resp[1]
 end
 
--- Fetch root anchors in XML over HTTPS
+-- Fetch root anchors in XML over HTTPS, returning a zone-file-style string.
 local function bootstrap(url, ca)
        -- @todo ICANN certificate is verified against current CA
        --       this is not ideal, as it should rather verify .xml signature which
@@ -28,11 +28,14 @@ local function bootstrap(url, ca)
        if not xml then
                return false, string.format('[ ta ] fetch of "%s" failed: %s', url, err)
        end
-       -- Parse root trust anchor
-       local fields = {}
-       string.gsub(xml, "<([%w]+).->([^<]+)</[%w]+>", function (k, v) fields[k] = v end)
-       local rrdata = string.format('%s %s %s %s', fields.KeyDigest, fields.Algorithm, fields.DigestType, fields.Digest)
-       local rr = string.format('%s 0 IN DS %s', fields.TrustAnchor, rrdata)
+       local rr = ''
+       -- Parse root trust anchor, one digest at a time, converting to a zone-file-style string.
+       string.gsub(xml, "<KeyDigest[^>]*>(.-)</KeyDigest>", function (xml1)
+               local fields = {}
+               string.gsub(xml1, "<([%w]+).->([^<]+)</[%w]+>", function (k, v) fields[k] = v end)
+               rr = rr .. '\n' .. string.format('. 0 IN DS %s %s %s %s',
+                       fields.KeyTag, fields.Algorithm, fields.DigestType, fields.Digest)
+       end)
        -- Add to key set, create an empty keyset file to be filled
        print('[ ta ] warning: root anchor bootstrapped, you SHOULD check the key manually, see: '..
              'https://data.iana.org/root-anchors/draft-icann-dnssec-trust-anchor.html#sigs')