]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Stop trying to cage non-notification URLs during cleanup
authorAlberto Leiva Popper <ydahhrk@gmail.com>
Tue, 5 Dec 2023 13:01:33 +0000 (10:01 -0300)
committerAlberto Leiva Popper <ydahhrk@gmail.com>
Wed, 6 Dec 2023 16:56:37 +0000 (13:56 -0300)
Fixes the new issue reported in #103.

src/abbreviations.txt
src/cache/local_cache.c
src/object/certificate.c
src/object/manifest.c
src/object/tal.c
src/rrdp.c
src/types/uri.c
src/types/uri.h
test/cache/local_cache_test.c
test/rrdp_test.c
test/types/uri_test.c

index bbb5b147e723ba5f323c0137c5af9ec7c21e95c0..5024c4d893426ff005f7e23a39dbfea9d8a5f393 100644 (file)
@@ -21,7 +21,7 @@ len: length
 max: maximum
 min: minimum
 msg: message
-notif: Notification
+notif: (RRDP) Notification
 pdu: Protocol Data Unit (RFC 6810)
 pp: Publication Point
 pr: print
index 436f73c19c454a19876ee49535d916e7447bb864..6cdb6e6bbf21848a7d0a502038969b180913233d 100644 (file)
@@ -44,6 +44,7 @@ struct rpki_cache {
 #define TAGNAME_ATTEMPT_TS "attempt-timestamp"
 #define TAGNAME_ATTEMPT_ERR "attempt-result"
 #define TAGNAME_SUCCESS_TS "success-timestamp"
+#define TAGNAME_IS_NOTIF "is-rrdp-notification"
 
 static char *
 get_json_filename(struct rpki_cache *cache)
@@ -58,6 +59,7 @@ json2node(struct rpki_cache *cache, json_t *json)
 {
        struct cache_node *node;
        char const *url;
+       bool is_notif;
        enum uri_type type;
        int error;
 
@@ -78,7 +80,16 @@ json2node(struct rpki_cache *cache, json_t *json)
                pr_op_err("Unknown protocol: %s", url);
                goto fail;
        }
-       error = uri_create(&node->url, cache->tal, type, NULL, url);
+
+       error = json_get_bool(json, TAGNAME_IS_NOTIF, &is_notif);
+       if (error < 0)
+               goto fail;
+
+       error = uri_create(&node->url, cache->tal, type, is_notif, NULL, url);
+       if (error) {
+               pr_op_err("Cannot parse '%s' into a URI.", url);
+               goto fail;
+       }
 
        error = json_get_ts(json, TAGNAME_ATTEMPT_TS, &node->attempt.ts);
        if (error) {
@@ -191,6 +202,9 @@ node2json(struct cache_node *node)
 
        if (json_add_str(json, TAGNAME_URL, uri_get_global(node->url)))
                goto cancel;
+       if (uri_is_notif(node->url))
+               if (json_add_bool(json, TAGNAME_IS_NOTIF, true))
+                       goto cancel;
        if (json_add_date(json, TAGNAME_ATTEMPT_TS, node->attempt.ts))
                goto cancel;
        if (json_add_int(json, TAGNAME_ATTEMPT_ERR, node->attempt.result))
@@ -315,15 +329,15 @@ get_url(struct rpki_uri *uri, const char *tal, struct rpki_uri **url)
                if (*c == '/') {
                        slashes++;
                        if (slashes == 4)
-                               return __uri_create(url, tal, UT_RSYNC, NULL,
-                                   guri, c - guri + 1);
+                               return __uri_create(url, tal, UT_RSYNC, false,
+                                   NULL, guri, c - guri + 1);
                }
        }
 
        if (slashes == 3 && *(c - 1) != '/') {
                guri2 = pstrdup(guri); /* Remove const */
                guri2[c - guri] = '/';
-               error = __uri_create(url, tal, UT_RSYNC, NULL, guri2,
+               error = __uri_create(url, tal, UT_RSYNC, false, NULL, guri2,
                    c - guri + 1);
                free(guri2);
                return error;
@@ -604,12 +618,9 @@ static void
 delete_node_and_cage(struct rpki_cache *cache, struct cache_node *node)
 {
        struct rpki_uri *cage;
-       int error;
 
-       if (uri_get_type(node->url) == UT_HTTPS) {
-               error = __uri_create(&cage, cache->tal, UT_CAGED, node->url,
-                   "", 0);
-               if (!error) {
+       if (uri_is_notif(node->url)) {
+               if (uri_create_cage(&cage, cache->tal, node->url) == 0) {
                        pr_op_debug("Deleting cage %s.", uri_get_local(cage));
                        file_rm_rf(uri_get_local(cage));
                        uri_refput(cage);
@@ -656,6 +667,7 @@ cleanup_node(struct rpki_cache *cache, struct cache_node *node,
                break;
        case ENOENT:
                /* Node exists but file doesn't: Delete node */
+               pr_op_debug("Node exists but file doesn't: %s", path);
                delete_node_and_cage(cache, node);
                return;
        default:
@@ -739,9 +751,10 @@ delete_unknown_files(struct rpki_cache *cache)
                uri_refget(node->url);
                uris_add(&dnc, node->url);
 
-               error = __uri_create(&cage, cache->tal, UT_CAGED, node->url,
-                   "", 0);
-               if (error) {
+               if (!uri_is_notif(node->url))
+                       continue;
+
+               if (uri_create_cage(&cage, cache->tal, node->url) != 0) {
                        pr_op_err("Cannot generate %s's cage. I'm probably going to end up deleting it from the cache.",
                            uri_op_get_printable(node->url));
                        continue;
@@ -771,10 +784,12 @@ cache_cleanup(struct rpki_cache *cache)
        struct cache_node *node, *tmp;
        time_t last_week;
 
+       pr_op_debug("Cleaning up old abandoned cache files.");
        last_week = get_days_ago(7);
        HASH_ITER(hh, cache->ht, node, tmp)
                cleanup_node(cache, node, last_week);
 
+       pr_op_debug("Cleaning up unknown cache files.");
        delete_unknown_files(cache);
 }
 
index a5cc53b3ab3832410c06f81d32515dae33c2212b..0724cae6ad96a28eae24f8b8b54577e7de06a25a 100644 (file)
@@ -1481,12 +1481,13 @@ end:
  * Create @uri from the @ad
  */
 static int
-uri_create_ad(struct rpki_uri **uri, ACCESS_DESCRIPTION *ad, enum uri_type type)
+uri_create_ad(struct rpki_uri **uri, ACCESS_DESCRIPTION *ad, enum uri_type type,
+    bool is_notif)
 {
-       ASN1_STRING *asn1_string;
+       ASN1_STRING *asn1str;
        int ptype;
 
-       asn1_string = GENERAL_NAME_get0_value(ad->location, &ptype);
+       asn1str = GENERAL_NAME_get0_value(ad->location, &ptype);
 
        /*
         * RFC 6487: "This extension MUST have an instance of an
@@ -1524,9 +1525,9 @@ uri_create_ad(struct rpki_uri **uri, ACCESS_DESCRIPTION *ad, enum uri_type type)
         * But ask the testers to keep an eye on it anyway.
         */
        return __uri_create(uri,
-           tal_get_file_name(validation_tal(state_retrieve())), type, NULL,
-           ASN1_STRING_get0_data(asn1_string),
-           ASN1_STRING_length(asn1_string));
+           tal_get_file_name(validation_tal(state_retrieve())), type,
+           is_notif, NULL,
+           ASN1_STRING_get0_data(asn1str), ASN1_STRING_length(asn1str));
 }
 
 /**
@@ -1560,7 +1561,8 @@ handle_ad(int nid, struct ad_metadata const *meta, SIGNATURE_INFO_ACCESS *ia,
        for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ia); i++) {
                ad = sk_ACCESS_DESCRIPTION_value(ia, i);
                if (OBJ_obj2nid(ad->method) == nid) {
-                       error = uri_create_ad(&uri, ad, meta->type);
+                       error = uri_create_ad(&uri, ad, meta->type,
+                           meta == &RPKI_NOTIFY);
                        switch (error) {
                        case 0:
                                break;
index f1a81ac8cb1333c3c85a62409824540640ef0161..3d1739d89002e518855bd32cb63b0cc7d4aea2c0 100644 (file)
@@ -23,10 +23,9 @@ cage(struct rpki_uri **uri, struct rpki_uri *notif)
                return 0;
        }
 
-       return __uri_create(uri,
-           tal_get_file_name(validation_tal(state_retrieve())),
-           UT_CAGED, notif, uri_get_global(*uri),
-           uri_get_global_len(*uri));
+       return uri_create_caged(uri,
+           tal_get_file_name(validation_tal(state_retrieve())), notif,
+           uri_get_global(*uri), uri_get_global_len(*uri));
 }
 
 static int
index fa8e6341a942f2ac6d5d6a31409ab68d7e933005..2d0fe8d29c41c7fa614063bde4d75d5dc5ceceab 100644 (file)
@@ -55,9 +55,9 @@ add_uri(struct uri_list *uris, char const *tal, char *uri)
        int error;
 
        if (str_starts_with(uri, "rsync://"))
-               error = uri_create(&new, tal, UT_RSYNC, NULL, uri);
+               error = uri_create(&new, tal, UT_RSYNC, false, NULL, uri);
        else if (str_starts_with(uri, "https://"))
-               error = uri_create(&new, tal, UT_HTTPS, NULL, uri);
+               error = uri_create(&new, tal, UT_HTTPS, false, NULL, uri);
        else
                return pr_op_err("TAL has non-RSYNC/HTTPS URI: %s", uri);
        if (error)
index 2c09fef882d96d878818c419e756492a07d239b1..7a522e9bb53bac9c4e9268cf304c1ab0a3e24abc 100644 (file)
@@ -479,7 +479,7 @@ parse_file_metadata(xmlTextReaderPtr reader, struct rpki_uri *notif,
        error = uri_create(&meta->uri,
            tal_get_file_name(validation_tal(state_retrieve())),
            (notif != NULL) ? UT_CAGED : UT_HTTPS,
-           notif, (char const *)uri);
+           false, notif, (char const *)uri);
        xmlFree(uri);
        if (error)
                return error;
index bc691659b0a8d0718ccaf0f91bc308405cea0dee..cc7fb74e8a8121d078ec0572582d150358c78e6f 100644 (file)
@@ -1,6 +1,5 @@
 #include "types/uri.h"
 
-
 #include "alloc.h"
 #include "common.h"
 #include "config.h"
@@ -64,6 +63,7 @@ struct rpki_uri {
        /* "local_len" is never needed right now. */
 
        enum uri_type type;
+       bool is_notif; /* Does it point to an RRDP Notification? */
 
        unsigned int references;
 };
@@ -393,7 +393,7 @@ autocomplete_local(struct rpki_uri *uri, char const *tal,
  */
 int
 __uri_create(struct rpki_uri **result, char const *tal, enum uri_type type,
-    struct rpki_uri *notif, void const *guri, size_t guri_len)
+    bool is_notif, struct rpki_uri *notif, void const *guri, size_t guri_len)
 {
        struct rpki_uri *uri;
        int error;
@@ -407,6 +407,7 @@ __uri_create(struct rpki_uri **result, char const *tal, enum uri_type type,
        }
 
        uri->type = type;
+       uri->is_notif = is_notif;
 
        error = autocomplete_local(uri, tal, notif);
        if (error) {
@@ -421,13 +422,6 @@ __uri_create(struct rpki_uri **result, char const *tal, enum uri_type type,
        return 0;
 }
 
-int
-uri_create(struct rpki_uri **result, char const *tal, enum uri_type type,
-    struct rpki_uri *notif, char const *guri)
-{
-       return __uri_create(result, tal, type, notif, guri, strlen(guri));
-}
-
 /*
  * Manifest fileList entries are a little special in that they're just file
  * names. This function will infer the rest of the URL.
@@ -541,6 +535,12 @@ uri_is_certificate(struct rpki_uri *uri)
        return uri_has_extension(uri, ".cer");
 }
 
+bool
+uri_is_notif(struct rpki_uri *uri)
+{
+       return uri->is_notif;
+}
+
 enum uri_type
 uri_get_type(struct rpki_uri *uri)
 {
index d4d8188cc1ba51d1bcec0b65779f7048c7688959..4730ec4834b7a56088eb6e12f88781d15ac3d26b 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef SRC_TYPES_URI_H_
 #define SRC_TYPES_URI_H_
 
+#include <stdbool.h>
 #include "asn1/asn1c/IA5String.h"
 #include "data_structure/array_list.h"
 
@@ -19,13 +20,18 @@ enum uri_type {
 struct rpki_uri;
 
 int __uri_create(struct rpki_uri **, char const *, enum uri_type,
-    struct rpki_uri *, void const *, size_t);
-int uri_create(struct rpki_uri **, char const *, enum uri_type,
-    struct rpki_uri *, char const *);
+    bool, struct rpki_uri *, void const *, size_t);
 int uri_create_mft(struct rpki_uri **, char const *, struct rpki_uri *,
     struct rpki_uri *, IA5String_t *);
 struct rpki_uri *uri_create_cache(char const *);
 
+#define uri_create(uri, tal, type, is_notif, notif, guri) \
+       __uri_create(uri, tal, type, is_notif, notif, guri, strlen(guri))
+#define uri_create_caged(uri, tal, notif, guri, guri_len) \
+       __uri_create(uri, tal, UT_CAGED, false, notif, guri, guri_len)
+#define uri_create_cage(uri, tal, notif) \
+       uri_create_caged(uri, tal, notif, "", 0)
+
 struct rpki_uri *uri_refget(struct rpki_uri *);
 void uri_refput(struct rpki_uri *);
 
@@ -40,6 +46,7 @@ size_t uri_get_global_len(struct rpki_uri *);
 bool uri_equals(struct rpki_uri *, struct rpki_uri *);
 bool uri_has_extension(struct rpki_uri *, char const *);
 bool uri_is_certificate(struct rpki_uri *);
+bool uri_is_notif(struct rpki_uri *);
 
 enum uri_type uri_get_type(struct rpki_uri *);
 bool uri_is_rsync(struct rpki_uri *);
index 1ac44079eaf65d6296d396c84f66cf1032adb7db..0491c7d472bb3359a16caffabd76d2be48267551 100644 (file)
@@ -124,7 +124,7 @@ run_cache_download(char const *url, int expected_error,
        rsync_counter = 0;
        https_counter = 0;
 
-       ck_assert_int_eq(0, uri_create(&uri, TAL_FILE, type, NULL, url));
+       ck_assert_int_eq(0, uri_create(&uri, TAL_FILE, type, false, NULL, url));
        ck_assert_int_eq(expected_error, cache_download(cache, uri, NULL));
        ck_assert_uint_eq(rsync_calls, rsync_counter);
        ck_assert_uint_eq(https_calls, https_counter);
@@ -133,7 +133,8 @@ run_cache_download(char const *url, int expected_error,
 }
 
 static struct cache_node *
-node(char const *url, time_t attempt, int err, bool succeeded, time_t success)
+node(char const *url, time_t attempt, int err, bool succeeded, time_t success,
+    bool is_notif)
 {
        enum uri_type type;
        struct cache_node *result;
@@ -146,7 +147,8 @@ node(char const *url, time_t attempt, int err, bool succeeded, time_t success)
                ck_abort_msg("Bad protocol: %s", url);
 
        result = pzalloc(sizeof(struct cache_node));
-       ck_assert_int_eq(0, uri_create(&result->url, TAL_FILE, type, NULL, url));
+       ck_assert_int_eq(0, uri_create(&result->url, TAL_FILE, type, is_notif,
+           NULL, url));
        result->attempt.ts = attempt;
        result->attempt.result = err;
        result->success.happened = succeeded;
@@ -156,7 +158,7 @@ node(char const *url, time_t attempt, int err, bool succeeded, time_t success)
 }
 
 #define NODE(url, err, succeeded, has_file) \
-       node(url, has_file, err, succeeded, 0)
+       node(url, has_file, err, succeeded, 0, 0)
 
 static void
 reset_visiteds(void)
@@ -724,13 +726,12 @@ START_TEST(test_metadata_json)
        add_node(cache, NODE("rsync://a.b.c/e", 1, 0, 0));
        add_node(cache, NODE("rsync://x.y.z/e", 0, 1, 0));
        add_node(cache, NODE("https://a/b", 1, 1, 0));
-       add_node(cache, NODE("https://a/c", 0, 1, 0));
+       add_node(cache, node("https://a/c", 0, 0, 1, 0, 1));
 
        json = build_metadata_json(cache);
        ck_assert_int_eq(0, json_dump_file(json, "tmp/" TAL_FILE "/metadata.json", JSON_COMPACT));
 
        str = json_dumps(json, /* JSON_INDENT(4) */ JSON_COMPACT);
-       /* printf("%s\n", str); */
        json_decref(json);
 
        ck_assert_str_eq(
@@ -738,9 +739,8 @@ START_TEST(test_metadata_json)
            "{\"url\":\"rsync://a.b.c/e\",\"attempt-timestamp\":\"1970-01-01T00:00:00Z\",\"attempt-result\":1},"
            "{\"url\":\"rsync://x.y.z/e\",\"attempt-timestamp\":\"1970-01-01T00:00:00Z\",\"attempt-result\":0,\"success-timestamp\":\"1970-01-01T00:00:00Z\"},"
            "{\"url\":\"https://a/b\",\"attempt-timestamp\":\"1970-01-01T00:00:00Z\",\"attempt-result\":1,\"success-timestamp\":\"1970-01-01T00:00:00Z\"},"
-           "{\"url\":\"https://a/c\",\"attempt-timestamp\":\"1970-01-01T00:00:00Z\",\"attempt-result\":0,\"success-timestamp\":\"1970-01-01T00:00:00Z\"}]",
+           "{\"url\":\"https://a/c\",\"is-rrdp-notification\":true,\"attempt-timestamp\":\"1970-01-01T00:00:00Z\",\"attempt-result\":0,\"success-timestamp\":\"1970-01-01T00:00:00Z\"}]",
            str);
-       printf("%s", str);
        free(str);
 
        cache_reset(cache);
@@ -778,7 +778,8 @@ prepare_uri_list(struct uri_list *uris, ...)
                        type = UT_RSYNC;
                else
                        ck_abort_msg("Bad protocol: %s", str);
-               ck_assert_int_eq(0, uri_create(&uri, TAL_FILE, type, NULL, str));
+               ck_assert_int_eq(0, uri_create(&uri, TAL_FILE, type, false,
+                   NULL, str));
                uris_add(uris, uri);
        }
        va_end(args);
@@ -838,18 +839,18 @@ START_TEST(test_recover)
         */
        cache_reset(cache);
 
-       add_node(cache, node("rsync://a/1", 100, 0, 1, 100));
-       add_node(cache, node("rsync://a/2", 100, 1, 1, 100));
-       add_node(cache, node("rsync://a/3", 200, 0, 1, 100));
-       add_node(cache, node("rsync://a/4", 200, 1, 1, 100));
-       add_node(cache, node("rsync://a/5", 100, 0, 1, 200));
-       add_node(cache, node("rsync://a/6", 100, 1, 1, 200));
-       add_node(cache, node("rsync://b/1", 100, 0, 0, 100));
-       add_node(cache, node("rsync://b/2", 100, 1, 0, 100));
-       add_node(cache, node("rsync://b/3", 200, 0, 0, 100));
-       add_node(cache, node("rsync://b/4", 200, 1, 0, 100));
-       add_node(cache, node("rsync://b/5", 100, 0, 0, 200));
-       add_node(cache, node("rsync://b/6", 100, 1, 0, 200));
+       add_node(cache, node("rsync://a/1", 100, 0, 1, 100, 0));
+       add_node(cache, node("rsync://a/2", 100, 1, 1, 100, 0));
+       add_node(cache, node("rsync://a/3", 200, 0, 1, 100, 0));
+       add_node(cache, node("rsync://a/4", 200, 1, 1, 100, 0));
+       add_node(cache, node("rsync://a/5", 100, 0, 1, 200, 0));
+       add_node(cache, node("rsync://a/6", 100, 1, 1, 200, 0));
+       add_node(cache, node("rsync://b/1", 100, 0, 0, 100, 0));
+       add_node(cache, node("rsync://b/2", 100, 1, 0, 100, 0));
+       add_node(cache, node("rsync://b/3", 200, 0, 0, 100, 0));
+       add_node(cache, node("rsync://b/4", 200, 1, 0, 100, 0));
+       add_node(cache, node("rsync://b/5", 100, 0, 0, 200, 0));
+       add_node(cache, node("rsync://b/6", 100, 1, 0, 200, 0));
 
        /* Multiple successful caches: Prioritize the most recent one */
        PREPARE_URI_LIST(&uris, "rsync://a/1", "rsync://a/3", "rsync://a/5");
index 40b7f79a3ed3cc6b84dd73c2b653d8e16a367a5d..cab2b21e0ed2e073125a170d4b2fbeabd1736690 100644 (file)
@@ -24,8 +24,6 @@ MOCK_ABORT_INT(hash_validate_file, struct rpki_uri *uri,
 MOCK_ABORT_INT(relax_ng_parse, const char *path, xml_read_cb cb, void *arg)
 MOCK_ABORT_PTR(state_retrieve, validation, void)
 __MOCK_ABORT(tal_get_file_name, char const *, NULL, struct tal *tal)
-MOCK_ABORT_INT(uri_create, struct rpki_uri **result, char const *tal,
-    enum uri_type type, struct rpki_uri *notif, char const *guri)
 __MOCK_ABORT(uri_get_global, char const *, NULL, struct rpki_uri *uri)
 __MOCK_ABORT(uri_get_local, char const *, NULL, struct rpki_uri *uri)
 __MOCK_ABORT(uri_get_rrdp_workspace, char *, NULL, char const *tal,
index 7385866717f70482b37f78109dbe4adbb68b0098..d81960936f44015f65901b8a16a46a9a5f037f55 100644 (file)
@@ -20,8 +20,8 @@ MOCK_ABORT_INT(rrdp_update, struct rpki_uri *uri)
 
 /* Tests */
 
-#define URI_CREATE_HTTP(uri, str) uri_create(&uri, "test.tal", UT_HTTPS, NULL, str)
-#define URI_CREATE_RSYNC(uri, str) uri_create(&uri, "test.tal", UT_RSYNC, NULL, str)
+#define URI_CREATE_HTTP(uri, str) uri_create(&uri, "test.tal", UT_HTTPS, false, NULL, str)
+#define URI_CREATE_RSYNC(uri, str) uri_create(&uri, "test.tal", UT_RSYNC, false, NULL, str)
 
 START_TEST(test_constructor)
 {
@@ -147,14 +147,14 @@ START_TEST(check_caged)
 {
        struct rpki_uri *uri;
 
-       ck_assert_int_eq(0, uri_create(&notif, "test.tal", UT_HTTPS, NULL, "https://a.b.c/d/e.xml"));
-       ck_assert_int_eq(0, uri_create(&uri, "test.tal", UT_CAGED, notif, "rsync://x.y.z/v/w.cer"));
+       ck_assert_int_eq(0, uri_create(&notif, "test.tal", UT_HTTPS, true, NULL, "https://a.b.c/d/e.xml"));
+       ck_assert_int_eq(0, uri_create(&uri, "test.tal", UT_CAGED, false, notif, "rsync://x.y.z/v/w.cer"));
        ck_assert_str_eq("tmp/test.tal/rrdp/a.b.c/d/e.xml/x.y.z/v/w.cer", uri_get_local(uri));
        uri_refput(uri);
        uri_refput(notif);
 
-       ck_assert_int_eq(0, uri_create(&notif, "test.tal", UT_HTTPS, NULL, "https://a.b.c"));
-       ck_assert_int_eq(0, uri_create(&uri, "test.tal", UT_CAGED, notif, "rsync://w"));
+       ck_assert_int_eq(0, uri_create(&notif, "test.tal", UT_HTTPS, true, NULL, "https://a.b.c"));
+       ck_assert_int_eq(0, uri_create(&uri, "test.tal", UT_CAGED, false, notif, "rsync://w"));
        ck_assert_str_eq("tmp/test.tal/rrdp/a.b.c/w", uri_get_local(uri));
        uri_refput(uri);
        uri_refput(notif);