]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Thursday
authorAlberto Leiva Popper <ydahhrk@gmail.com>
Fri, 2 Aug 2024 00:05:44 +0000 (18:05 -0600)
committerAlberto Leiva Popper <ydahhrk@gmail.com>
Fri, 2 Aug 2024 00:05:44 +0000 (18:05 -0600)
42 files changed:
src/cache.c
src/cache.h
src/cachent.c
src/cachent.h
src/cert_stack.c
src/cert_stack.h
src/certificate_refs.c
src/certificate_refs.h
src/common.c
src/common.h
src/object/certificate.c
src/object/ghostbusters.c
src/object/manifest.c
src/object/manifest.h
src/object/roa.c
src/object/roa.h
src/object/signed_object.c
src/object/signed_object.h
src/object/tal.c
src/rpp.c
src/rpp.h
src/rrdp.c
src/rtr/db/vrps.c
src/slurm/db_slurm.c
src/thread_var.h
src/types/map.c
src/types/map.h
src/types/str.h
src/types/url.c
test/Makefile.am
test/base64_test.c
test/cache_test.c
test/cache_util.c
test/cache_util.h
test/cachent_test.c
test/mock.c
test/object/manifest_test.c [new file with mode: 0644]
test/rrdp_test.c
test/rrdp_update_test.c
test/tal_test.c
test/types/map_test.c [deleted file]
test/types/url_test.c

index d955b53c007bb9d679549c9b8b2963d7359d5747..6713860fd1356939af5d30bfb7ace5acb384a87f 100644 (file)
@@ -10,6 +10,7 @@
 #include <time.h>
 
 #include "alloc.h"
+#include "cachent.h"
 #include "cachetmp.h"
 #include "common.h"
 #include "config.h"
@@ -513,7 +514,7 @@ dl_rsync(struct cache_node *rpp)
        }
 
        module->flags |= CNF_RSYNC | CNF_CACHED | CNF_FRESH;
-       module->mtim = time(NULL); // XXX catch -1
+       module->mtim = time_nonfatal();
        module->tmppath = tmppath;
 
        for (node = rpp; node != module; node = node->parent) {
@@ -541,7 +542,7 @@ dl_http(struct cache_node *node)
        if (error)
                return error;
 
-       mtim = time(NULL); // XXX
+       mtim = time_nonfatal();
 
        error = http_download(node->url, tmppath, node->mtim, &changed);
        if (error) {
@@ -559,9 +560,10 @@ dl_http(struct cache_node *node)
 /* @uri is either a caRepository or a rpkiNotify */
 static int
 try_uri(char const *uri, struct cache_node *root,
-    dl_cb download, maps_dl_cb validate, void *arg)
+    dl_cb download, validate_cb validate, void *arg)
 {
        struct cache_node *rpp;
+       struct cache_mapping map;
        int error;
 
        if (!uri)
@@ -585,19 +587,23 @@ try_uri(char const *uri, struct cache_node *root,
                }
        }
 
-       error = validate(rpp, arg);
+       map.url = rpp->url;
+       map.path = rpp->path;
+       map.tmppath = rpp->tmppath;
+       error = validate(&map, arg);
        if (error) {
                pr_val_debug("RPP validation failed.");
                return error;
        }
 
        pr_val_debug("RPP validated successfully.");
+       rpp->flags |= CNF_VALID;
        return 0;
 }
 
 static int
 try_uris(struct strlist *uris, struct cache_node *root,
-    char const *prefix, dl_cb dl, maps_dl_cb cb, void *arg)
+    char const *prefix, dl_cb dl, validate_cb cb, void *arg)
 {
        char **str;
        int error;
@@ -613,7 +619,7 @@ try_uris(struct strlist *uris, struct cache_node *root,
 }
 
 int
-cache_download_uri(struct strlist *uris, maps_dl_cb cb, void *arg)
+cache_download_uri(struct strlist *uris, validate_cb cb, void *arg)
 {
        int error;
 
@@ -649,7 +655,7 @@ cache_download_uri(struct strlist *uris, maps_dl_cb cb, void *arg)
  * that's already cached, and callbacks it.
  */
 int
-cache_download_alt(struct sia_uris *sias, maps_dl_cb cb, void *arg)
+cache_download_alt(struct sia_uris *sias, validate_cb cb, void *arg)
 {
        int error;
 
@@ -695,10 +701,6 @@ prune_rsync(void)
                        }
 }
 
-/*
- * XXX this needs to be hit only by files now
- * XXX result is redundant
- */
 static bool
 commit_rpp_delta(struct cache_node *node)
 {
@@ -748,38 +750,6 @@ branch:    node->flags = 0;
        return true;
 }
 
-//static bool
-//is_node_fresh(struct cache_node *node, time_t epoch)
-//{
-//     /* TODO This is a startup; probably complicate this. */
-//     return difftime(epoch, node->attempt.ts) < 0;
-//}
-//
-//static void
-//delete_node(struct rpki_cache *cache, struct cache_node *node)
-//{
-//     HASH_DEL(cache->ht, node);
-//     map_refput(node->map);
-//     rrdp_notif_free(node->notif);
-//     free(node);
-//}
-//
-//static void
-//delete_node_and_cage(struct rpki_cache *cache, struct cache_node *node)
-//{
-//     struct cache_mapping *cage;
-//
-//     if (map_get_type(node->map) == MAP_NOTIF) {
-//             if (map_create_cage(&cage, node->map) == 0) {
-//                     pr_op_debug("Deleting cage %s.", map_get_path(cage));
-//                     file_rm_rf(map_get_path(cage));
-//                     map_refput(cage);
-//             }
-//     }
-//
-//     delete_node(cache, node);
-//}
-
 static int
 rmf(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
 {
index 213fa8bbebafd9eb363490e3f42364f0ef4f5b4f..8fcf64dce9bca1ff69afabb7178abb1a0b7320a6 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef SRC_CACHE_LOCAL_CACHE_H_
 #define SRC_CACHE_LOCAL_CACHE_H_
 
-#include "cachent.h"
+#include "types/map.h"
 #include "types/str.h"
 
 void cache_setup(void);                /* Init this module */
@@ -26,12 +26,10 @@ void sias_cleanup(struct sia_uris *);
  * - 0 on success ("Mapping handled successfully")
  * - > 0 on soft errors ("Try another mapping")
  * - < 0 on hard errors ("Abandon foreach")
- *
- * XXX rename
  */
-typedef int (*maps_dl_cb)(struct cache_node *rpp, void *arg);
-int cache_download_uri(struct strlist *, maps_dl_cb, void *);
-int cache_download_alt(struct sia_uris *, maps_dl_cb, void *);
+typedef int (*validate_cb)(struct cache_mapping *, void *);
+int cache_download_uri(struct strlist *, validate_cb, void *);
+int cache_download_alt(struct sia_uris *, validate_cb, void *);
 
 void cache_print(void); /* Dump cache in stdout. Recursive; tests only */
 
index 44b252e40e2ee5c28d51085d761c675c9631cc36..af68790b169f6da2bedeca121f2b05e1130d6c93 100644 (file)
@@ -34,24 +34,23 @@ cachent_root_https(void)
 }
 
 /* Preorder. @cb returns whether the children should be traversed. */
-int
+void
 cachent_traverse(struct cache_node *root, bool (*cb)(struct cache_node *))
 {
        struct cache_node *iter_start;
        struct cache_node *parent, *child;
        struct cache_node *tmp;
-       int error;
 
        if (!root)
-               return 0;
+               return;
 
        if (!cb(root))
-               return error;
+               return;
 
        parent = root;
        iter_start = parent->children;
        if (iter_start == NULL)
-               return error;
+               return;
 
 reloop:        /* iter_start must not be NULL */
        HASH_ITER(hh, iter_start, child, tmp) {
@@ -65,7 +64,7 @@ reloop:       /* iter_start must not be NULL */
        parent = iter_start->parent;
        do {
                if (parent == NULL)
-                       return error;
+                       return;
                iter_start = parent->hh.next;
                parent = parent->parent;
        } while (iter_start == NULL);
@@ -167,7 +166,8 @@ provide(struct cache_node *parent, char const *url,
  * anything that is not @ancestor or one of its descendants. (ie. dot-dotting is
  * allowed, but the end result must not land outside of @ancestor.)
  *
- * XXX review callers; can now return NULL.
+ * XXX In the end, it seems this is only being used by root ancestors.
+ * Should probably separate the caging to a simple get.
  */
 struct cache_node *
 cachent_provide(struct cache_node *ancestor, char const *url)
index 97143c9deac66ffcd0768954629146c029b9776b..397fd97f2c3ab078984492fe4e15658cf14752bb 100644 (file)
@@ -77,7 +77,7 @@ struct cache_node {
 struct cache_node *cachent_root_rsync(void);
 struct cache_node *cachent_root_https(void);
 
-int cachent_traverse(struct cache_node *, bool (*cb)(struct cache_node *));
+void cachent_traverse(struct cache_node *, bool (*cb)(struct cache_node *));
 
 struct cache_node *cachent_find(struct cache_node *, char const *,
     struct cache_node **);
index 2eb9e46712c40a07be6ef79a3de1be50054c635b..a9186b481ab2787202bb3d794d0a4dfe845db1fc 100644 (file)
@@ -42,7 +42,7 @@ STATIC_ARRAY_LIST(serial_numbers, struct serial_number)
  * Cached certificate data.
  */
 struct metadata_node {
-       struct cache_mapping *map;
+       struct cache_mapping map;
        struct resources *resources;
        /*
         * Serial numbers of the children.
@@ -121,7 +121,6 @@ defer_destroy(struct defer_node *defer)
        case DNT_SEPARATOR:
                break;
        case DNT_CERT:
-               map_refput(defer->deferred.map);
                rpp_refput(defer->deferred.pp);
                break;
        }
@@ -139,7 +138,6 @@ serial_cleanup(struct serial_number *serial)
 static void
 meta_destroy(struct metadata_node *meta)
 {
-       map_refput(meta->map);
        resources_destroy(meta->resources);
        serial_numbers_cleanup(&meta->serials, serial_cleanup);
        free(meta);
@@ -185,7 +183,6 @@ deferstack_push(struct cert_stack *stack, struct deferred_cert *deferred)
 
        node->type = DNT_CERT;
        node->deferred = *deferred;
-       map_refget(deferred->map);
        rpp_refget(deferred->pp);
        SLIST_INSERT_HEAD(&stack->defers, node, next);
 }
@@ -229,7 +226,6 @@ again:      node = SLIST_FIRST(&stack->defers);
        }
 
        *result = node->deferred;
-       map_refget(node->deferred.map);
        rpp_refget(node->deferred.pp);
 
        SLIST_REMOVE_HEAD(&stack->defers, next);
@@ -299,7 +295,7 @@ x509stack_push(struct cert_stack *stack, struct cache_mapping *map, X509 *x509,
 
        meta = pmalloc(sizeof(struct metadata_node));
 
-       meta->map = map_refget(map);
+       meta->map = *map;
        serial_numbers_init(&meta->serials);
 
        error = init_resources(x509, policy, type, &meta->resources);
@@ -325,7 +321,6 @@ destroy_separator:
        resources_destroy(meta->resources);
 cleanup_serial:
        serial_numbers_cleanup(&meta->serials, serial_cleanup);
-       map_refput(meta->map);
        free(meta);
        return error;
 }
@@ -362,7 +357,7 @@ struct cache_mapping *
 x509stack_peek_map(struct cert_stack *stack)
 {
        struct metadata_node *meta = SLIST_FIRST(&stack->metas);
-       return (meta != NULL) ? meta->map : NULL;
+       return (meta != NULL) ? &meta->map : NULL;
 }
 
 struct resources *
index b9c9e248e7e43b87ba9731fcdd39ea4c29ad2a59..3d938148f18760d709019675da37a7be7753ff32 100644 (file)
@@ -31,7 +31,7 @@
 struct cert_stack;
 
 struct deferred_cert {
-       struct cache_mapping *map;
+       struct cache_mapping map;
        struct rpp *pp;
 };
 
index c63cf8e51e8bb0d7a0ea566b54d2a7f9860e94f5..b94f6d31cdddcc19b7b55644992d95b4cbbb0dc4 100644 (file)
@@ -22,34 +22,33 @@ refs_cleanup(struct certificate_refs *refs)
 static int
 validate_cdp(struct certificate_refs *refs, struct rpp const *pp)
 {
-       struct cache_mapping *pp_crl;
+       char const *crl_url;
 
        if (refs->crldp == NULL)
                pr_crit("Certificate's CRL Distribution Point was not recorded.");
 
-       pp_crl = rpp_get_crl(pp);
-       if (pp_crl == NULL)
+       crl_url = rpp_get_crl(pp);
+       if (crl_url == NULL)
                pr_crit("Manifest's CRL was not recorded.");
 
-       if (strcmp(refs->crldp, map_get_url(pp_crl)) != 0) {
+       if (strcmp(refs->crldp, crl_url) != 0) {
                return pr_val_err("Certificate's CRL Distribution Point ('%s') does not match manifest's CRL ('%s').",
-                   refs->crldp, map_get_url(pp_crl));
+                   refs->crldp, crl_url);
        }
 
        return 0;
 }
 
 static int
-validate_signedObject(struct certificate_refs *refs,
-    struct cache_mapping *signedObject_map)
+validate_signedObject(struct certificate_refs *refs, char const *url)
 {
        if (refs->signedObject == NULL)
                pr_crit("Certificate's signedObject was not recorded.");
 
        /* XXX the left one is no longer normalized */
-       if (strcmp(refs->signedObject, map_get_url(signedObject_map)) != 0) {
+       if (strcmp(refs->signedObject, url) != 0) {
                return pr_val_err("Certificate's signedObject ('%s') does not match the URI of its own signed object (%s).",
-                   refs->signedObject, map_get_url(signedObject_map));
+                   refs->signedObject, url);
        }
 
        return 0;
@@ -84,11 +83,11 @@ refs_validate_ca(struct certificate_refs *refs, struct rpp const *pp)
  *
  * @refs: References you want validated.
  * @pp: Repository Publication Point, as described by the Manifest.
- * @map: Mapping of the signed object that contains the EE certificate.
+ * @url: URL of the signed object that contains the EE certificate.
  */
 int
 refs_validate_ee(struct certificate_refs *refs, struct rpp const *pp,
-    struct cache_mapping *map)
+    char const *url)
 {
        int error;
 
@@ -96,5 +95,5 @@ refs_validate_ee(struct certificate_refs *refs, struct rpp const *pp,
        if (error)
                return error;
 
-       return validate_signedObject(refs, map);
+       return validate_signedObject(refs, url);
 }
index 009f4f918b17b9d7c44ad0a59aa8c219c4192245..841ba94b2e2c96065bd35a0564647a0a70ab9e88 100644 (file)
@@ -40,6 +40,6 @@ void refs_init(struct certificate_refs *);
 void refs_cleanup(struct certificate_refs *);
 int refs_validate_ca(struct certificate_refs *, struct rpp const *);
 int refs_validate_ee(struct certificate_refs *, struct rpp const *,
-    struct cache_mapping *);
+    char const *);
 
 #endif /* SRC_CERTIFICATE_REFS_H_ */
index 6aee1b822b377ccc8ae269eab629a0ab97363d64..ace62b54d725d0190f6d1549a1d27a7d64301347 100644 (file)
@@ -383,20 +383,28 @@ release_str:
        return error;
 }
 
-int
-get_current_time(time_t *result)
+time_t
+time_nonfatal(void)
 {
-       time_t now;
-       int error;
+       time_t result;
 
-       now = time(NULL);
-       if (now == ((time_t) -1)) {
-               error = errno;
-               pr_val_err("Error getting the current time: %s",
-                   strerror(errno));
-               return error;
+       result = time(NULL);
+       if (result == ((time_t)-1)) {
+               pr_val_warn("time(NULL) returned -1: %s", strerror(errno));
+               result = 0;
        }
 
-       *result = now;
-       return 0;
+       return result;
+}
+
+time_t
+time_fatal(void)
+{
+       time_t result;
+
+       result = time(NULL);
+       if (result == ((time_t)-1))
+               pr_crit("time(NULL) returned -1: %s", strerror(errno));
+
+       return result;
 }
index 190b04c7b25af9f2a1f670d0751b8627f2c86f62..eff5ee242bb4beaa4cb2b06ae80169060b9ebc96 100644 (file)
 #define ENOTSUPPORTED 3172
 /* "I haven't implemented this yet." */
 #define ENOTIMPLEMENTED 3173
-/* "URI was not RSYNC." */
-#define ENOTRSYNC 3174
-/* "URI was not HTTPS." */
-#define ENOTHTTPS 3175
 
 /*
  * If you're wondering why I'm not using -abs(error), it's because abs(INT_MIN)
@@ -52,6 +48,7 @@ bool valid_file_or_dir(char const *, bool);
 int mkdir_p(char const *, bool, mode_t);
 int delete_dir_recursive_bottom_up(char const *);
 
-int get_current_time(time_t *);
+time_t time_nonfatal(void);
+time_t time_fatal(void);
 
 #endif /* SRC_RTR_COMMON_H_ */
index 06a21cbc8e1eb88a95d9ee2bfd54e5b99aeb0eb9..072032ede68dbb1d043c22f8a5b9fe9af0798b12 100644 (file)
@@ -793,7 +793,7 @@ certificate_load(struct cache_mapping *map, X509 **result)
        bio = BIO_new(BIO_s_file());
        if (bio == NULL)
                return val_crypto_err("BIO_new(BIO_s_file()) returned NULL");
-       if (BIO_read_filename(bio, map_get_path(map)) <= 0) {
+       if (BIO_read_filename(bio, map->path) <= 0) {
                error = val_crypto_err("Error reading certificate");
                goto end;
        }
@@ -821,12 +821,6 @@ update_crl_time(STACK_OF(X509_CRL) *crls, X509_CRL *original_crl)
 {
        ASN1_TIME *tm;
        X509_CRL *clone;
-       time_t t;
-       int error;
-
-       error = get_current_time(&t);
-       if (error)
-               return error;
 
        /*
         * Yes, this is an awful hack. The other options were:
@@ -837,7 +831,7 @@ update_crl_time(STACK_OF(X509_CRL) *crls, X509_CRL *original_crl)
         *   only the nextUpdate field wrong (maybe there are other invalid
         *   things).
         */
-       tm = ASN1_TIME_adj(NULL, t, 0, 60);
+       tm = ASN1_TIME_adj(NULL, time_fatal(), 0, 60);
        if (tm == NULL)
                return val_crypto_err("ASN1_TIME_adj() returned NULL.");
 
@@ -850,8 +844,7 @@ update_crl_time(STACK_OF(X509_CRL) *crls, X509_CRL *original_crl)
        X509_CRL_set1_nextUpdate(clone, tm);
        ASN1_STRING_free(tm);
 
-       error = sk_X509_CRL_push(crls, clone);
-       if (error <= 0) {
+       if (sk_X509_CRL_push(crls, clone) <= 0) {
                X509_CRL_free(clone);
                return val_crypto_err("Error calling sk_X509_CRL_push()");
        }
@@ -1813,7 +1806,7 @@ certificate_traverse(struct rpp *rpp_parent, struct cache_mapping *cert_map)
        struct validation *state;
        int total_parents;
        STACK_OF(X509_CRL) *rpp_parent_crl;
-       X509 *cert;
+       X509 *x509;
        struct sia_uris sia_uris;
        enum rpki_policy policy;
        enum cert_type certype;
@@ -1833,7 +1826,6 @@ certificate_traverse(struct rpp *rpp_parent, struct cache_mapping *cert_map)
        else
                pr_val_debug("Certificate '%s' {",
                    map_val_get_printable(cert_map));
-
        fnstack_push_map(cert_map);
 
        error = rpp_crl(rpp_parent, &rpp_parent_crl);
@@ -1841,14 +1833,14 @@ certificate_traverse(struct rpp *rpp_parent, struct cache_mapping *cert_map)
                goto revert_fnstack_and_debug;
 
        /* -- Validate the certificate (@cert) -- */
-       error = certificate_load(cert_map, &cert);
+       error = certificate_load(cert_map, &x509);
        if (error)
                goto revert_fnstack_and_debug;
-       error = certificate_validate_chain(cert, rpp_parent_crl);
+       error = certificate_validate_chain(x509, rpp_parent_crl);
        if (error)
                goto revert_cert;
 
-       error = get_certificate_type(cert, rpp_parent == NULL, &certype);
+       error = get_certificate_type(x509, rpp_parent == NULL, &certype);
        if (error)
                goto revert_cert;
 
@@ -1869,14 +1861,14 @@ certificate_traverse(struct rpp *rpp_parent, struct cache_mapping *cert_map)
                goto revert_cert;
        }
 
-       error = certificate_validate_rfc6487(cert, certype);
+       error = certificate_validate_rfc6487(x509, certype);
        if (error)
                goto revert_cert;
 
        sias_init(&sia_uris);
        error = (certype == CERTYPE_TA)
-           ? certificate_validate_extensions_ta(cert, &sia_uris, &policy)
-           : certificate_validate_extensions_ca(cert, &sia_uris, &policy,
+           ? certificate_validate_extensions_ta(x509, &sia_uris, &policy)
+           : certificate_validate_extensions_ca(x509, &sia_uris, &policy,
                                                 rpp_parent);
        if (error)
                goto revert_uris;
@@ -1885,11 +1877,11 @@ certificate_traverse(struct rpp *rpp_parent, struct cache_mapping *cert_map)
        if (error)
                goto revert_uris;
 
-       error = x509stack_push(validation_certstack(state), cert_map, cert,
+       error = x509stack_push(validation_certstack(state), cert_map, x509,
            policy, certype);
        if (error)
                goto revert_uris;
-       cert = NULL; /* Ownership stolen */
+       x509 = NULL; /* Ownership stolen */
 
        error = handle_manifest(sia_uris.rpkiManifest, &pp);
        if (error) {
@@ -1904,8 +1896,8 @@ certificate_traverse(struct rpp *rpp_parent, struct cache_mapping *cert_map)
 revert_uris:
        sias_cleanup(&sia_uris);
 revert_cert:
-       if (cert != NULL)
-               X509_free(cert);
+       if (x509 != NULL)
+               X509_free(x509);
 revert_fnstack_and_debug:
        fnstack_pop();
        pr_val_debug("}");
index ec8ec64c9a96578391fc226301b10ad36525e236..bb47c8e847ac7dc566d36429dfd364a92a41887f 100644 (file)
@@ -29,7 +29,7 @@ ghostbusters_traverse(struct cache_mapping *map, struct rpp *pp)
        fnstack_push_map(map);
 
        /* Decode */
-       error = signed_object_decode(&sobj, map);
+       error = signed_object_decode(&sobj, map->path);
        if (error)
                goto revert_log;
 
@@ -46,7 +46,7 @@ ghostbusters_traverse(struct cache_mapping *map, struct rpp *pp)
        error = handle_vcard(&sobj);
        if (error)
                goto revert_args;
-       error = refs_validate_ee(&ee.refs, pp, map);
+       error = refs_validate_ee(&ee.refs, pp, map->url);
 
 revert_args:
        eecert_cleanup(&ee);
index a47afe5f8b8595b8a52b63caed1510153bc48e6f..0afaf6182c110fdb96b1ced7595f7586539102ce 100644 (file)
@@ -78,10 +78,7 @@ validate_dates(GeneralizedTime_t *this, GeneralizedTime_t *next)
                    TM_ARGS(nextUpdate));
        }
 
-       now_tt = 0;
-       error = get_current_time(&now_tt);
-       if (error)
-               return error;
+       now_tt = time_fatal();
        if (gmtime_r(&now_tt, &now) == NULL) {
                error = errno;
                return pr_val_err("gmtime_r(now) error %d: %s", error,
@@ -211,74 +208,74 @@ validate_mft_file(IA5String_t *ia5)
        return 0;
 }
 
-/**
- * Computes the hash of the file @map, and compares it to @expected (The
- * "expected" hash).
- *
- * Returns:
- *   0 if no errors happened and the hashes match, or the hash doesn't match
- *     but there's an incidence to ignore such error.
- * < 0 if there was an error that can't be ignored.
- * > 0 if there was an error but it can be ignored (file not found and there's
- *     an incidence to ignore this).
- */
-static int
-hash_validate_mft_file(struct cache_mapping *map, BIT_STRING_t const *expected)
-{
-       struct hash_algorithm const *algorithm;
-       size_t hash_size;
-       unsigned char actual[EVP_MAX_MD_SIZE];
-       int error;
-
-       algorithm = hash_get_sha256();
-       hash_size = hash_get_size(algorithm);
-
-       if (expected->size != hash_size)
-               return pr_val_err("%s string has bogus size: %zu",
-                   hash_get_name(algorithm), expected->size);
-       if (expected->bits_unused != 0)
-               return pr_val_err("Hash string has unused bits.");
-
-       /*
-        * TODO (#82) This is atrocious. Implement RFC 9286, and probably reuse
-        * hash_validate_file().
-        */
-
-       error = hash_file(algorithm, map_get_path(map), actual, NULL);
-       if (error) {
-               if (error == EACCES || error == ENOENT) {
-                       /* FIXME .................. */
-                       if (incidence(INID_MFT_FILE_NOT_FOUND,
-                           "File '%s' listed at manifest doesn't exist.",
-                           map_val_get_printable(map)))
-                               return -EINVAL;
-
-                       return error;
-               }
-               /* Any other error (crypto, file read) */
-               return ENSURE_NEGATIVE(error);
-       }
-
-       if (memcmp(expected->buf, actual, hash_size) != 0) {
-               return incidence(INID_MFT_FILE_HASH_NOT_MATCH,
-                   "File '%s' does not match its manifest hash.",
-                   map_val_get_printable(map));
-       }
-
-       return 0;
-}
+///**
+// * Computes the hash of the file @map, and compares it to @expected (The
+// * "expected" hash).
+// *
+// * Returns:
+// *   0 if no errors happened and the hashes match, or the hash doesn't match
+// *     but there's an incidence to ignore such error.
+// * < 0 if there was an error that can't be ignored.
+// * > 0 if there was an error but it can be ignored (file not found and there's
+// *     an incidence to ignore this).
+// */
+//static int
+//hash_validate_mft_file(struct cache_mapping *map, BIT_STRING_t const *expected)
+//{
+//     struct hash_algorithm const *algorithm;
+//     size_t hash_size;
+//     unsigned char actual[EVP_MAX_MD_SIZE];
+//     int error;
+//
+//     algorithm = hash_get_sha256();
+//     hash_size = hash_get_size(algorithm);
+//
+//     if (expected->size != hash_size)
+//             return pr_val_err("%s string has bogus size: %zu",
+//                 hash_get_name(algorithm), expected->size);
+//     if (expected->bits_unused != 0)
+//             return pr_val_err("Hash string has unused bits.");
+//
+//     /*
+//      * TODO (#82) This is atrocious. Implement RFC 9286, and probably reuse
+//      * hash_validate_file().
+//      */
+//
+//     error = hash_file(algorithm, map_get_path(map), actual, NULL);
+//     if (error) {
+//             if (error == EACCES || error == ENOENT) {
+//                     /* FIXME .................. */
+//                     if (incidence(INID_MFT_FILE_NOT_FOUND,
+//                         "File '%s' listed at manifest doesn't exist.",
+//                         map_val_get_printable(map)))
+//                             return -EINVAL;
+//
+//                     return error;
+//             }
+//             /* Any other error (crypto, file read) */
+//             return ENSURE_NEGATIVE(error);
+//     }
+//
+//     if (memcmp(expected->buf, actual, hash_size) != 0) {
+//             return incidence(INID_MFT_FILE_HASH_NOT_MATCH,
+//                 "File '%s' does not match its manifest hash.",
+//                 map_val_get_printable(map));
+//     }
+//
+//     return 0;
+//}
 
 static int
 build_rpp(struct Manifest *mft, char const *mft_url, struct rpp **pp)
 {
-       char *path, *slash;
-       size_t path_len;
+       char *rpp_url, *slash;
+       size_t rpp_url_len;
        int i;
        struct FileAndHash *fah;
-       char *file;
-       size_t file_len;
+       char *file_url;
+       size_t file_url_len;
        int written;
-       struct cache_mapping *map;
+       char const *extension;
        int error;
 
        *pp = rpp_create();
@@ -286,8 +283,8 @@ build_rpp(struct Manifest *mft, char const *mft_url, struct rpp **pp)
        slash = strrchr(mft_url, '/');
        if (!slash)
                ; // XXX
-       path_len = slash - mft_url;
-       path = pstrndup(mft_url, path_len);
+       rpp_url_len = slash - mft_url;
+       rpp_url = pstrndup(mft_url, rpp_url_len);
 
        for (i = 0; i < mft->fileList.list.count; i++) {
                fah = mft->fileList.list.array[i];
@@ -302,54 +299,50 @@ build_rpp(struct Manifest *mft, char const *mft_url, struct rpp **pp)
                if (error)
                        ; // XXX
 
-               file_len = path_len + fah->file.size + 2;
-               file = pmalloc(file_len);
-               written = snprintf(file, file_len, "%s/%.*s", path,
+               file_url_len = rpp_url_len + fah->file.size + 2;
+               file_url = pmalloc(file_url_len);
+               written = snprintf(file_url, file_url_len, "%s/%.*s", rpp_url,
                    (int)fah->file.size, fah->file.buf);
-               if (written >= file_len)
-                       ; // XXX
-
-               map = create_map(file); /* Needs to swallow @file. */
-               if (!map)
+               if (written >= file_url_len)
                        ; // XXX
 
-               /*
-                * XXX I think this should be moved somewhere else.
-                *
-                * Expect:
-                * - Negative value: an error not to be ignored, the whole
-                *   manifest will be discarded.
-                * - Zero value: hash at manifest matches file's hash, or it
-                *   doesn't match its hash but there's an incidence to ignore
-                *   such error.
-                * - Positive value: file doesn't exist and keep validating
-                *   manifest.
-                */
-               error = hash_validate_mft_file(map, &fah->hash);
-               if (error < 0) {
-                       map_refput(map);
-                       goto fail;
-               }
-               if (error > 0) {
-                       map_refput(map);
-                       continue;
-               }
-
-               if (map_has_extension(map, ".cer"))
-                       rpp_add_cert(*pp, map);
-               else if (map_has_extension(map, ".roa"))
-                       rpp_add_roa(*pp, map);
-               else if (map_has_extension(map, ".crl"))
-                       error = rpp_add_crl(*pp, map);
-               else if (map_has_extension(map, ".gbr"))
-                       rpp_add_ghostbusters(*pp, map);
+//             /*
+//              * XXX I think this should be moved somewhere else.
+//              *
+//              * Expect:
+//              * - Negative value: an error not to be ignored, the whole
+//              *   manifest will be discarded.
+//              * - Zero value: hash at manifest matches file's hash, or it
+//              *   doesn't match its hash but there's an incidence to ignore
+//              *   such error.
+//              * - Positive value: file doesn't exist and keep validating
+//              *   manifest.
+//              */
+//             error = hash_validate_mft_file(map, &fah->hash);
+//             if (error < 0) {
+//                     free(file_url);
+//                     goto fail;
+//             }
+//             if (error > 0) {
+//                     free(file_url);
+//                     continue;
+//             }
+
+               extension = ((char const *)fah->file.buf) + fah->file.size - 4;
+               if (strcmp(extension, ".cer") == 0)
+                       rpp_add_cert(*pp, file_url);
+               else if (strcmp(extension, ".roa") == 0)
+                       rpp_add_roa(*pp, file_url);
+               else if (strcmp(extension, ".crl") == 0) {
+                       error = rpp_add_crl(*pp, file_url);
+                       if (error) {
+                               free(file_url);
+                               goto fail;
+                       }
+               } else if (strcmp(extension, ".gbr") == 0)
+                       rpp_add_ghostbusters(*pp, file_url);
                else
-                       map_refput(map); /* ignore it. */
-
-               if (error) {
-                       map_refput(map);
-                       goto fail;
-               } /* Otherwise ownership was transferred to @pp. */
+                       free(file_url); /* ignore it. */
        }
 
        /* rfc6486#section-7 */
@@ -370,9 +363,8 @@ fail:
  * @pp.
  */
 int
-handle_manifest(char const *uri, struct rpp **pp)
+handle_manifest(struct cache_mapping *map, struct rpp **pp)
 {
-       struct cache_mapping *map;
        static OID oid = OID_MANIFEST;
        struct oid_arcs arcs = OID2ARCS("manifest", oid);
        struct signed_object sobj;
@@ -381,16 +373,12 @@ handle_manifest(char const *uri, struct rpp **pp)
        STACK_OF(X509_CRL) *crl;
        int error;
 
-       map = create_map(uri);
-       if (!map)
-               return -EINVAL; /* XXX msg */
-
        /* Prepare */
        pr_val_debug("Manifest '%s' {", map_val_get_printable(map));
        fnstack_push_map(map);
 
        /* Decode */
-       error = signed_object_decode(&sobj, map);
+       error = signed_object_decode(&sobj, map->path);
        if (error)
                goto revert_log;
        error = decode_manifest(&sobj, &mft);
@@ -398,7 +386,7 @@ handle_manifest(char const *uri, struct rpp **pp)
                goto revert_sobj;
 
        /* Initialize out parameter (@pp) */
-       error = build_rpp(mft, uri, pp);
+       error = build_rpp(mft, map->url, pp);
        if (error)
                goto revert_manifest;
 
@@ -415,7 +403,7 @@ handle_manifest(char const *uri, struct rpp **pp)
        error = validate_manifest(mft);
        if (error)
                goto revert_args;
-       error = refs_validate_ee(&ee.refs, *pp, map);
+       error = refs_validate_ee(&ee.refs, *pp, map->url);
        if (error)
                goto revert_args;
 
@@ -434,6 +422,5 @@ revert_sobj:
 revert_log:
        pr_val_debug("}");
        fnstack_pop();
-       map_refput(map);
        return error;
 }
index 24d7c17d4a47392e814f66867315d11544750ae8..402813ad5c930c5565705b53a58711099a2214e7 100644 (file)
@@ -2,7 +2,8 @@
 #define SRC_OBJECT_MANIFEST_H_
 
 #include "rpp.h"
+#include "types/map.h"
 
-int handle_manifest(char const *, struct rpp **);
+int handle_manifest(struct cache_mapping *map, struct rpp **);
 
 #endif /* SRC_OBJECT_MANIFEST_H_ */
index 63b810d2300d785c6db6a1230be0e7820b816a26..7d495a50c8e35234fc83b45e8b0aaf971aa0321e 100644 (file)
@@ -262,7 +262,7 @@ roa_traverse(struct cache_mapping *map, struct rpp *pp)
        fnstack_push_map(map);
 
        /* Decode */
-       error = signed_object_decode(&sobj, map);
+       error = signed_object_decode(&sobj, map->path);
        if (error)
                goto revert_log;
        error = decode_roa(&sobj, &roa);
@@ -282,7 +282,7 @@ roa_traverse(struct cache_mapping *map, struct rpp *pp)
        error = __handle_roa(roa, ee.res);
        if (error)
                goto revert_args;
-       error = refs_validate_ee(&ee.refs, pp, map);
+       error = refs_validate_ee(&ee.refs, pp, map->url);
 
 revert_args:
        eecert_cleanup(&ee);
index 310930053612e1807d4046d518f4dae26d5e669b..497f9c478b9c5851c677ca1fb441e3af3b22f34b 100644 (file)
@@ -2,7 +2,6 @@
 #define SRC_OBJECT_ROA_H_
 
 #include "rpp.h"
-#include "types/address.h"
 #include "types/map.h"
 
 int roa_traverse(struct cache_mapping *, struct rpp *);
index cb80aa81755605d224b6c2ecd4b9ee405c745872..f6c11fef51ca6392dc8c3f72762feef70a436cd8 100644 (file)
@@ -4,11 +4,11 @@
 #include "log.h"
 
 int
-signed_object_decode(struct signed_object *sobj, struct cache_mapping *map)
+signed_object_decode(struct signed_object *sobj, char const *path)
 {
        int error;
 
-       error = content_info_load(map_get_path(map), &sobj->cinfo);
+       error = content_info_load(path, &sobj->cinfo);
        if (error)
                return error;
 
index e6c2aba9063bfd0e6f19739516222563843ca468..d148e06356316f186ba6e5d0fc2f223699a493de 100644 (file)
@@ -9,7 +9,7 @@ struct signed_object {
        struct SignedData *sdata;
 };
 
-int signed_object_decode(struct signed_object *, struct cache_mapping *);
+int signed_object_decode(struct signed_object *, char const *);
 int signed_object_validate(struct signed_object *, struct oid_arcs const *,
     struct ee_cert *);
 void signed_object_cleanup(struct signed_object *);
index 81e827c8ebcfa5f6b4c55b290b0a9d622f8dfd35..d5f3ee6a7d9f1bcbb02bb87581b11dd7c11d3751 100644 (file)
@@ -21,8 +21,6 @@
 #include "types/str.h"
 #include "validation_handler.h"
 
-typedef int (*foreach_map_cb)(struct tal *, struct cache_mapping *, void *);
-
 struct tal {
        char const *file_name;
        struct strlist urls;
@@ -164,38 +162,39 @@ tal_get_spki(struct tal *tal, unsigned char const **buffer, size_t *len)
 }
 
 /**
- * Performs the whole validation walkthrough on the @map mapping, which is
- * assumed to have been extracted from TAL @tal.
+ * Performs the whole validation walkthrough that starts with Trust Anchor @ta,
+ * which is assumed to have been extracted from TAL @arg->tal.
  */
 static int
-handle_tal_map(struct tal *tal, struct cache_mapping *map, struct db_table *db)
+handle_ta(struct cache_mapping *ta, void *arg)
 {
+       struct handle_tal_args *args = arg;
        struct validation_handler validation_handler;
        struct validation *state;
        struct cert_stack *certstack;
        struct deferred_cert deferred;
        int error;
 
-       pr_val_debug("TAL URI '%s' {", map_val_get_printable(map));
+       pr_val_debug("TAL URI '%s' {", map_val_get_printable(ta));
 
        validation_handler.handle_roa_v4 = handle_roa_v4;
        validation_handler.handle_roa_v6 = handle_roa_v6;
        validation_handler.handle_router_key = handle_router_key;
-       validation_handler.arg = db;
+       validation_handler.arg = args->db;
 
-       error = validation_prepare(&state, tal, &validation_handler);
+       error = validation_prepare(&state, &args->tal, &validation_handler);
        if (error)
                return ENSURE_NEGATIVE(error);
 
-       if (!map_has_extension(map, ".cer")) {
+       if (!str_ends_with(ta->url, ".cer")) {
                pr_op_err("TAL URI does not point to a certificate. (Expected .cer, got '%s')",
-                   map_op_get_printable(map));
+                   ta->url);
                error = EINVAL;
                goto end;
        }
 
        /* Handle root certificate. */
-       error = certificate_traverse(NULL, map);
+       error = certificate_traverse(NULL, ta);
        if (error) {
                switch (validation_pubkey_state(state)) {
                case PKS_INVALID:
@@ -233,9 +232,8 @@ handle_tal_map(struct tal *tal, struct cache_mapping *map, struct db_table *db)
                 * Ignore result code; remaining certificates are unrelated,
                 * so they should not be affected.
                 */
-               certificate_traverse(deferred.pp, deferred.map);
+               certificate_traverse(deferred.pp, &deferred.map);
 
-               map_refput(deferred.map);
                rpp_refput(deferred.pp);
        } while (true);
 
@@ -244,13 +242,6 @@ end:       validation_destroy(state);
        return error;
 }
 
-static int
-__handle_tal_map(struct cache_mapping *map, void *arg)
-{
-       struct handle_tal_args *args = arg;
-       return handle_tal_map(&args->tal, map, args->db);
-}
-
 static void *
 do_file_validation(void *arg)
 {
@@ -268,8 +259,7 @@ do_file_validation(void *arg)
                goto end;
 
        args.db = db_table_create();
-       thread->error = cache_download_uri(&args.tal.urls,
-           __handle_tal_map, &args);
+       thread->error = cache_download_uri(&args.tal.urls, handle_ta, &args);
        if (thread->error) {
                pr_op_err("None of the URIs of the TAL '%s' yielded a successful traversal.",
                    thread->tal_file);
index e165bb0dfcaa769f3cc47293830f1569c5fb23b1..59a12287a11c97fd11166bd273f2418974d9f064 100644 (file)
--- a/src/rpp.c
+++ b/src/rpp.c
@@ -8,20 +8,19 @@
 #include "object/ghostbusters.h"
 #include "object/roa.h"
 #include "thread_var.h"
-#include "types/arraylist.h"
-#include "types/map.h"
+#include "types/str.h"
 
-/** A Repository Publication Point (RFC 6481), as described by some manifest. */
+/* A Repository Publication Point (RFC 6481), as described by some manifest. */
 struct rpp {
-       struct map_list certs; /* Certificates */
+       struct strlist certs;
 
        /*
         * map NULL implies stack NULL and error 0.
         * If map is set, stack might or might not be set.
         * error is only relevant when map is set and stack is unset.
         */
-       struct { /* Certificate Revocation List */
-               struct cache_mapping *map;
+       struct {
+               char *url;
                /*
                 * CRL in libcrypto-friendly form.
                 * Initialized lazily; access via rpp_crl().
@@ -36,10 +35,8 @@ struct rpp {
        } crl;
 
        /* The Manifest is not needed for now. */
-
-       struct map_list roas; /* Route Origin Attestations */
-
-       struct map_list ghostbusters;
+       struct strlist roas;
+       struct strlist ghostbusters;
 
        /*
         * Note that the reference counting functions are not prepared for
@@ -55,12 +52,12 @@ rpp_create(void)
 
        result = pmalloc(sizeof(struct rpp));
 
-       maps_init(&result->certs);
-       result->crl.map = NULL;
+       strlist_init(&result->certs);
+       result->crl.url = NULL;
        result->crl.stack = NULL;
        result->crl.error = 0;
-       maps_init(&result->roas);
-       maps_init(&result->ghostbusters);
+       strlist_init(&result->roas);
+       strlist_init(&result->ghostbusters);
        result->references = 1;
 
        return result;
@@ -77,54 +74,52 @@ rpp_refput(struct rpp *pp)
 {
        pp->references--;
        if (pp->references == 0) {
-               maps_cleanup(&pp->certs);
-               if (pp->crl.map != NULL)
-                       map_refput(pp->crl.map);
-               if (pp->crl.stack != NULL)
-                       sk_X509_CRL_pop_free(pp->crl.stack, X509_CRL_free);
-               maps_cleanup(&pp->roas);
-               maps_cleanup(&pp->ghostbusters);
+               strlist_cleanup(&pp->certs);
+               free(pp->crl.url);
+               sk_X509_CRL_pop_free(pp->crl.stack, X509_CRL_free);
+               strlist_cleanup(&pp->roas);
+               strlist_cleanup(&pp->ghostbusters);
                free(pp);
        }
 }
 
-/** Steals ownership of @map. */
+/* Steals ownership of @url */
 void
-rpp_add_cert(struct rpp *pp, struct cache_mapping *map)
+rpp_add_cert(struct rpp *pp, char *url)
 {
-       maps_add(&pp->certs, map);
+       strlist_add(&pp->certs, url);
 }
 
-/** Steals ownership of @map. */
+/* Steals ownership of @url */
 void
-rpp_add_roa(struct rpp *pp, struct cache_mapping *map)
+rpp_add_roa(struct rpp *pp, char *url)
 {
-       maps_add(&pp->roas, map);
+       strlist_add(&pp->roas, url);
 }
 
-/** Steals ownership of @map. */
+/* Steals ownership of @url */
 void
-rpp_add_ghostbusters(struct rpp *pp, struct cache_mapping *map)
+rpp_add_ghostbusters(struct rpp *pp, char *url)
 {
-       maps_add(&pp->ghostbusters, map);
+       strlist_add(&pp->ghostbusters, url);
 }
 
-/** Steals ownership of @map. */
+/* Steals ownership of @url */
 int
-rpp_add_crl(struct rpp *pp, struct cache_mapping *map)
+rpp_add_crl(struct rpp *pp, char *url)
 {
        /* rfc6481#section-2.2 */
-       if (pp->crl.map)
+       if (pp->crl.url)
                return pr_val_err("Repository Publication Point has more than one CRL.");
 
-       pp->crl.map = map;
+       pp->crl.url = url;
        return 0;
 }
 
-struct cache_mapping *
+char const *
 rpp_get_crl(struct rpp const *pp)
 {
-       return pp->crl.map;
+       return pp->crl.url;
 }
 
 static int
@@ -134,9 +129,9 @@ add_crl_to_stack(struct rpp *pp, STACK_OF(X509_CRL) *crls)
        int error;
        int idx;
 
-       fnstack_push_map(pp->crl.map);
+       fnstack_push(pp->crl.url);
 
-       error = crl_load(pp->crl.map, &crl);
+       error = crl_load(pp->crl.url, &crl);
        if (error)
                goto end;
 
@@ -152,7 +147,7 @@ end:
        return error;
 }
 
-/**
+/*
  * Returns the pp's CRL in stack form (which is how libcrypto functions want
  * it).
  * The stack belongs to @pp and should not be released. Can be NULL, in which
@@ -169,7 +164,7 @@ rpp_crl(struct rpp *pp, STACK_OF(X509_CRL) **result)
                *result = NULL;
                return 0;
        }
-       if (pp->crl.map == NULL) {
+       if (pp->crl.url == NULL) {
                /* rpp_crl() assumes the rpp has been populated already. */
                pr_crit("RPP lacks a CRL.");
        }
@@ -226,13 +221,11 @@ __cert_traverse(struct rpp *pp)
        return 0;
 }
 
-/**
- * Traverses through all of @pp's known files, validating them.
- */
+/* Traverses through all of @pp's known files, validating them. */
 void
 rpp_traverse(struct rpp *pp)
 {
-       struct cache_mapping **map;
+       char **url;
 
        /*
         * A subtree should not invalidate the rest of the tree, so error codes
@@ -249,13 +242,13 @@ rpp_traverse(struct rpp *pp)
        __cert_traverse(pp);
 
        /* Validate ROAs, apply validation_handler on them. */
-       ARRAYLIST_FOREACH(&pp->roas, map)
-               roa_traverse(*map, pp);
+       ARRAYLIST_FOREACH(&pp->roas, url)
+               roa_traverse(*url, pp);
 
        /*
         * We don't do much with the ghostbusters right now.
         * Just validate them.
         */
-       ARRAYLIST_FOREACH(&pp->ghostbusters, map)
-               ghostbusters_traverse(*map, pp);
+       ARRAYLIST_FOREACH(&pp->ghostbusters, url)
+               ghostbusters_traverse(*url, pp);
 }
index 5f78a2b5397cc2ce72f5a9b851a8f968e4d5979d..8999b4dc03bbd0a3c4b85deb29fc1fd8d34fef4f 100644 (file)
--- a/src/rpp.h
+++ b/src/rpp.h
@@ -4,20 +4,18 @@
 #include <openssl/safestack.h>
 #include <openssl/x509.h>
 
-#include "types/map.h"
-
 struct rpp;
 
 struct rpp *rpp_create(void);
 void rpp_refget(struct rpp *pp);
 void rpp_refput(struct rpp *pp);
 
-void rpp_add_cert(struct rpp *, struct cache_mapping *);
-int rpp_add_crl(struct rpp *, struct cache_mapping *);
-void rpp_add_roa(struct rpp *, struct cache_mapping *);
-void rpp_add_ghostbusters(struct rpp *, struct cache_mapping *);
+void rpp_add_cert(struct rpp *, char *);
+int rpp_add_crl(struct rpp *, char *);
+void rpp_add_roa(struct rpp *, char *);
+void rpp_add_ghostbusters(struct rpp *, char *);
 
-struct cache_mapping *rpp_get_crl(struct rpp const *);
+char const *rpp_get_crl(struct rpp const *);
 int rpp_crl(struct rpp *, STACK_OF(X509_CRL) **);
 
 void rpp_traverse(struct rpp *);
index 94f239d3298753a30a0f89e84625a604a392bd72..6107df514fbfe239ef8dd63a3a5125502ffc5ef0 100644 (file)
@@ -1097,7 +1097,7 @@ dl_notif(struct cache_node *notif, struct update_notification *new)
        if (notif->dlerr)
                return false;
 
-       mtim = time(NULL); // XXX
+       mtim = time_nonfatal();
        changed = false;
        notif->dlerr = http_download(notif->url, tmppath, notif->mtim, &changed);
        notif->flags |= CNF_FRESH;
index 3ba4a73d085455c843f98f300a049c94e03db2ff..1b2618179856ac89fb27713d3505e707b85c90ce 100644 (file)
@@ -82,7 +82,6 @@ static pthread_rwlock_t state_lock;
 int
 vrps_init(void)
 {
-       time_t now;
        int error;
 
        state.base = NULL;
@@ -96,11 +95,7 @@ vrps_init(void)
        state.serial = 0;
 
        /* Get the bits that'll fit in session_id */
-       now = 0;
-       error = get_current_time(&now);
-       if (error)
-               goto revert_deltas;
-       state.v0_session_id = now & 0xFFFF;
+       state.v0_session_id = time_fatal() & 0xFFFF;
 
        /* Minus 1 to prevent same ID */
        state.v1_session_id = (state.v0_session_id != 0)
@@ -113,14 +108,11 @@ vrps_init(void)
        if (error) {
                pr_op_err("state pthread_rwlock_init() errored: %s",
                    strerror(error));
-               goto revert_deltas;
+               darray_destroy(state.deltas);
+               return error;
        }
 
        return 0;
-
-revert_deltas:
-       darray_destroy(state.deltas);
-       return error;
 }
 
 void
index faf7b2b82c2f516458a8922e745bbd6ef3355a82..5a34cfcc3fd75a0b1b79d52cf350a1cc65442718 100644 (file)
@@ -101,11 +101,7 @@ db_slurm_create(struct slurm_csum_list *csums, struct db_slurm **result)
 
        db = pmalloc(sizeof(struct db_slurm));
 
-       error = get_current_time(&db->loaded_date);
-       if (error) {
-               free(db);
-               return error;
-       }
+       db->loaded_date = time_nonfatal();
 
        /* Not ready yet (nor required yet) for multithreading */
        al_filter_prefix_init(&db->lists.filter_pfx_al);
index 0d5d389c2767c790155a8db2bdbd66c45e062328..8b91768fd58c2911373c76489905dccfcdfc758e 100644 (file)
@@ -2,6 +2,7 @@
 #define SRC_THREAD_VAR_H_
 
 #include "state.h"
+#include "types/map.h"
 
 int thvar_init(void); /* This function does not need cleanup. */
 
index 87ab958cc64c8a2fde42635cbc7fa0ccf5dec2da..f2e620f178e95982da9489366c017d5e1f5623d3 100644 (file)
@@ -1,354 +1,8 @@
 #include "types/map.h"
 
-#include <errno.h>
-
-#include "alloc.h"
-#include "cachetmp.h"
-#include "common.h"
+#include <string.h>
 #include "config.h"
-#include "config/filename_format.h"
 #include "log.h"
-#include "rrdp.h"
-#include "state.h"
-#include "thread_var.h"
-#include "types/path.h"
-#include "types/str.h"
-#include "types/url.h"
-
-/**
- * Aside from the reference counter, instances are meant to be immutable.
- *
- * TODO (fine) This structure is so intertwined with the cache module,
- * nowadays it feels like it should be moved there.
- */
-struct cache_mapping {
-       /**
-        * The one that always starts with "rsync://" or "https://".
-        * Normalized, ASCII-only, NULL-terminated.
-        */
-       char *url;
-
-       /**
-        * Cache location where we downloaded the file.
-        * Normalized, ASCII-only, NULL-terminated.
-        * Sometimes NULL, depending on @type.
-        */
-       char *path;
-
-       enum map_type type;
-
-       unsigned int references; /* Reference counter */
-};
-
-/*
- * @character is an integer because we sometimes receive signed chars, and other
- * times we get unsigned chars.
- * Casting a negative char into a unsigned char is undefined behavior.
- */
-static int
-validate_url_character(int character)
-{
-       /*
-        * RFCs 1738 and 3986 define a very specific range of allowed
-        * characters, but I don't think we're that concerned about URL
-        * correctness. Validating the URL properly is more involved than simply
-        * checking legal characters, anyway.
-        *
-        * What I really need this validation for is ensure that we won't get
-        * any trouble later, when we attempt to map the URL to a path.
-        *
-        * Sample trouble: Getting UTF-8 characters. Why are they trouble?
-        * Because we don't have any guarantees that the system's file name
-        * encoding is UTF-8. URIs are not supposed to contain UTF-8 in the
-        * first place, so we have no reason to deal with encoding conversion.
-        *
-        * To be perfectly fair, we have no guarantees that the system's file
-        * name encoding is ASCII-compatible either, but I need to hang onto
-        * SOMETHING.
-        *
-        * (Asking users to use UTF-8 is fine, but asking users to use something
-        * ASCII-compatible is a little better.)
-        *
-        * So just make sure that the character is printable ASCII.
-        *
-        * TODO (next iteration) Consider exhaustive URL validation.
-        */
-       return (0x20 <= character && character <= 0x7E)
-           ? 0
-           : pr_val_err("URL has non-printable character code '%d'.", character);
-}
-
-static int normalize_url(struct path_builder *, char const *, char const *, int);
-
-/**
- * Initializes @map->url by building a normalized version of @str.
- */
-static int
-init_url(struct cache_mapping *map, char const *str)
-{
-       char const *s;
-       char const *pfx;
-       int error;
-       struct path_builder pb;
-
-       if (str == NULL){
-               map->url = NULL;
-               return 0;
-       }
-
-       for (s = str; s[0] != '\0'; s++) {
-               error = validate_url_character(s[0]);
-               if (error)
-                       return error;
-       }
-
-       pfx = NULL;
-       error = 0;
-
-       switch (map->type) {
-       case MAP_RSYNC:
-               pfx = "rsync://";
-               error = ENOTRSYNC;
-               break;
-       case MAP_HTTP:
-       case MAP_NOTIF:
-               pfx = "https://";
-               error = ENOTHTTPS;
-               break;
-       }
-
-       if (pfx == NULL)
-               pr_crit("Unknown mapping type: %u", map->type);
-
-       __pb_init(&pb, RPKI_SCHEMA_LEN - 1);
-       error = normalize_url(&pb, str, pfx, error);
-       if (error) {
-               pb_cleanup(&pb);
-               return error;
-       }
-
-       map->url = strncpy(pb.string, str, RPKI_SCHEMA_LEN);
-       return 0;
-}
-
-struct path_parser {
-       char const *token;
-       char const *slash;
-       size_t len;
-};
-
-/* Return true if there's a new token, false if we're done. */
-static bool
-path_next(struct path_parser *parser)
-{
-       if (parser->slash == NULL)
-               return false;
-
-       parser->token = parser->slash + 1;
-       parser->slash = strchr(parser->token, '/');
-       parser->len = (parser->slash != NULL)
-           ? (parser->slash - parser->token)
-           : strlen(parser->token);
-
-       return parser->token[0] != 0;
-}
-
-static bool
-path_is_dot(struct path_parser *parser)
-{
-       return parser->len == 1 && parser->token[0] == '.';
-}
-
-static bool
-path_is_dotdots(struct path_parser *parser)
-{
-       return parser->len == 2
-           && parser->token[0] == '.'
-           && parser->token[1] == '.';
-}
-
-static int
-normalize_url(struct path_builder *pb, char const *url, char const *pfx,
-    int errnot)
-{
-       struct path_parser parser;
-       size_t dot_dot_limit;
-       int error;
-
-       /* Schema */
-       if (!str_starts_with(url, pfx)) {
-               pr_val_err("URL '%s' does not begin with '%s'.", url, pfx);
-               return errnot;
-       }
-
-       /* Domain */
-       parser.slash = url + 7;
-       if (!path_next(&parser))
-               return pr_val_err("URL '%s' seems to lack a domain.", url);
-       if (path_is_dot(&parser)) {
-               /* Dumping files to the cache root is unsafe. */
-               return pr_val_err("URL '%s' employs the root domain. This is not really cacheable, so I'm going to distrust it.",
-                   url);
-       }
-       if (path_is_dotdots(&parser)) {
-               return pr_val_err("URL '%s' seems to be dot-dotting past its own schema.",
-                   url);
-       }
-       error = pb_appendn(pb, parser.token, parser.len);
-       if (error)
-               return error;
-
-       /* Other components */
-       dot_dot_limit = pb->len;
-       while (path_next(&parser)) {
-               if (path_is_dotdots(&parser)) {
-                       error = pb_pop(pb, false);
-                       if (error)
-                               return error;
-                       if (pb->len < dot_dot_limit) {
-                               return pr_val_err("URL '%s' seems to be dot-dotting past its own domain.",
-                                   url);
-                       }
-               } else if (!path_is_dot(&parser)) {
-                       error = pb_appendn(pb, parser.token, parser.len);
-                       if (error)
-                               return error;
-               }
-       }
-
-       return 0;
-}
-
-/*
- * Maps "rsync://a.b.c/d/e.cer" into "<local-repository>/rsync/a.b.c/d/e.cer".
- */
-static int
-map_simple(struct cache_mapping *map, char const *subdir)
-{
-       struct path_builder pb;
-       int error;
-
-       error = pb_init_cache(&pb, subdir);
-       if (error)
-               return error;
-
-       error = pb_append(&pb, &map->url[RPKI_SCHEMA_LEN]);
-       if (error) {
-               pb_cleanup(&pb);
-               return error;
-       }
-
-       map->path = pb.string;
-       return 0;
-}
-
-static int
-init_path(struct cache_mapping *map)
-{
-       switch (map->type) {
-       case MAP_RSYNC:
-               return map_simple(map, "rsync");
-       case MAP_HTTP:
-               return map_simple(map, "https");
-       case MAP_NOTIF:
-               return cache_tmpfile(&map->path);
-       }
-
-       pr_crit("Unknown URL type: %u", map->type);
-       return -EINVAL; /* Unreachable */
-}
-
-int
-map_create(struct cache_mapping **result, enum map_type type, char const *url)
-{
-       struct cache_mapping *map;
-       int error;
-
-       map = pmalloc(sizeof(struct cache_mapping));
-       map->type = type;
-       map->references = 1;
-
-       error = init_url(map, url);
-       if (error) {
-               free(map);
-               return error;
-       }
-
-       error = init_path(map);
-       if (error) {
-               free(map->url);
-               free(map);
-               return error;
-       }
-
-       *result = map;
-       return 0;
-}
-
-/* Cache-only; url and type are meaningless. */
-struct cache_mapping *
-map_create_cache(char const *path)
-{
-       struct cache_mapping *map;
-
-       map = pzalloc(sizeof(struct cache_mapping));
-       map->path = pstrdup(path);
-       map->references = 1;
-
-       return map;
-}
-
-struct cache_mapping *
-map_refget(struct cache_mapping *map)
-{
-       map->references++;
-       return map;
-}
-
-void
-map_refput(struct cache_mapping *map)
-{
-       if (map == NULL)
-               return;
-
-       map->references--;
-       if (map->references == 0) {
-               free(map->url);
-               free(map->path);
-               free(map);
-       }
-}
-
-char const *
-map_get_url(struct cache_mapping *map)
-{
-       return map->url;
-}
-
-char const *
-map_get_path(struct cache_mapping *map)
-{
-       return map->path;
-}
-
-bool
-map_equals(struct cache_mapping *m1, struct cache_mapping *m2)
-{
-       return strcmp(m1->url, m2->url) == 0;
-}
-
-/* @ext must include the period. */
-bool
-map_has_extension(struct cache_mapping *map, char const *ext)
-{
-       return str_ends_with(map->url, ext);
-}
-
-enum map_type
-map_get_type(struct cache_mapping *map)
-{
-       return map->type;
-}
 
 static char const *
 get_filename(char const *file_path)
@@ -376,44 +30,11 @@ map_get_printable(struct cache_mapping *map, enum filename_format format)
 char const *
 map_val_get_printable(struct cache_mapping *map)
 {
-       enum filename_format format;
-
-       format = config_get_val_log_filename_format();
-       return map_get_printable(map, format);
+       return map_get_printable(map, config_get_val_log_filename_format());
 }
 
 char const *
 map_op_get_printable(struct cache_mapping *map)
 {
-       enum filename_format format;
-
-       format = config_get_op_log_filename_format();
-       return map_get_printable(map, format);
-}
-
-DEFINE_ARRAY_LIST_FUNCTIONS(map_list, struct cache_mapping *, static)
-
-void
-maps_init(struct map_list *maps)
-{
-       map_list_init(maps);
-}
-
-static void
-__map_refput(struct cache_mapping **map)
-{
-       map_refput(*map);
-}
-
-void
-maps_cleanup(struct map_list *maps)
-{
-       map_list_cleanup(maps, __map_refput);
-}
-
-/* Swallows @map. */
-void
-maps_add(struct map_list *maps, struct cache_mapping *map)
-{
-       map_list_add(maps, &map);
+       return map_get_printable(map, config_get_op_log_filename_format());
 }
index 4edb1bc261927f7e258e2c9ed8a1b2215ede0dc0..2eb8568da8f33717371b5e05e14f95714be5f7e1 100644 (file)
@@ -1,61 +1,28 @@
 #ifndef SRC_TYPES_MAP_H_
 #define SRC_TYPES_MAP_H_
 
-#include <stdbool.h>
-#include "asn1/asn1c/IA5String.h"
-#include "types/arraylist.h"
-
-/*
- * "Long" time = seven days.
- * Currently hardcoded, but queued for tweakability.
- */
-enum map_type {
+// XXX document this better
+struct cache_mapping {
        /*
-        * (rsync) Repository Publication Point. RFC 6481.
-        * The directory is cached until it's untraversed for a "long" time.
+        * The one that always starts with "rsync://" or "https://".
+        * Normalized, ASCII-only, NULL-terminated.
         */
-       MAP_RSYNC = (1 << 0),
+       char const *url;
 
-       MAP_HTTP = (1 << 1),
+       /*
+        * Official cache location of the file.
+        * Normalized, ASCII-only, NULL-terminated.
+        */
+       char const *path;
 
        /*
-        * An RRDP notification file; downloaded via HTTP.
-        * The file itself is not cached, but we preserve a handful of metadata
-        * that is needed in subsequent iterations.
-        * The metadata is cached until it's untraversed for a "long" time.
+        * Temporary cache location of the file.
+        * It'll stay here until committed.
         */
-       MAP_NOTIF = (MAP_HTTP | (1 << 2)),
+       char const *tmppath;
 };
 
-struct cache_mapping;
-
-struct cache_mapping *create_map(char const *);
-
-struct cache_mapping *map_refget(struct cache_mapping *);
-void map_refput(struct cache_mapping *);
-
-/*
- * Note that, if you intend to print some mapping, you're likely supposed to use
- * map_*_get_printable() instead.
- */
-char const *map_get_url(struct cache_mapping *);
-char const *map_get_path(struct cache_mapping *);
-
-bool map_has_extension(struct cache_mapping *, char const *);
-
-enum map_type map_get_type(struct cache_mapping *);
-
 char const *map_val_get_printable(struct cache_mapping *);
 char const *map_op_get_printable(struct cache_mapping *);
 
-/* Plural */
-
-/* XXX still used? */
-DEFINE_ARRAY_LIST_STRUCT(map_list, struct cache_mapping *);
-
-void maps_init(struct map_list *);
-void maps_cleanup(struct map_list *);
-
-void maps_add(struct map_list *, struct cache_mapping *);
-
 #endif /* SRC_TYPES_MAP_H_ */
index 9798e7847287166a0b8981b7e597cff23c99bb1c..333596d5748a0393e33a6cca6fb3fbd9070a7229 100644 (file)
@@ -42,7 +42,8 @@ bool token_equals(struct string_tokenizer *, struct string_tokenizer *);
 char *token_read(struct string_tokenizer *);
 size_t token_count(struct string_tokenizer *);
 
-/* XXX delete? */
+/* Plural */
+
 DEFINE_ARRAY_LIST_STRUCT(strlist, char *);
 
 void strlist_init(struct strlist *);
index 5227b33590a7254db1b3f06ca838ef95762913e4..11d321fe128e06003fe3ff104bfeca7034082bb0 100644 (file)
@@ -3,6 +3,52 @@
 #include "alloc.h"
 #include "types/path.h"
 
+/*
+ * XXX use this:
+ *
+ *     for (s = str; s[0] != '\0'; s++) {
+               error = validate_url_character(s[0]);
+               if (error)
+                       return error;
+       }
+ *
+ * @character is an integer because we sometimes receive signed chars, and other
+ * times we get unsigned chars.
+ * Casting a negative char into a unsigned char is undefined behavior.
+ */
+static int
+validate_url_character(int character)
+{
+       /*
+        * RFCs 1738 and 3986 define a very specific range of allowed
+        * characters, but I don't think we're that concerned about URL
+        * correctness. Validating the URL properly is more involved than simply
+        * checking legal characters, anyway.
+        *
+        * What I really need this validation for is ensure that we won't get
+        * any trouble later, when we attempt to map the URL to a path.
+        *
+        * Sample trouble: Getting UTF-8 characters. Why are they trouble?
+        * Because we don't have any guarantees that the system's file name
+        * encoding is UTF-8. URIs are not supposed to contain UTF-8 in the
+        * first place, so we have no reason to deal with encoding conversion.
+        *
+        * To be perfectly fair, we have no guarantees that the system's file
+        * name encoding is ASCII-compatible either, but I need to hang onto
+        * SOMETHING.
+        *
+        * (Asking users to use UTF-8 is fine, but asking users to use something
+        * ASCII-compatible is a little better.)
+        *
+        * So just make sure that the character is printable ASCII.
+        *
+        * TODO (next iteration) Consider exhaustive URL validation.
+        */
+       return (0x20 <= character && character <= 0x7E)
+           ? 0
+           : pr_val_err("URL has non-printable character code '%d'.", character);
+}
+
 static char *
 path_rewind(char const *root, char *cursor)
 {
@@ -12,6 +58,25 @@ path_rewind(char const *root, char *cursor)
        return NULL;
 }
 
+static bool
+has_bad_prefix(char const *url)
+{
+       // XXX what happens if code expects one but url is the other
+       if (strncmp(url, "rsync://", RPKI_SCHEMA_LEN) &&
+           strncmp(url, "https://", RPKI_SCHEMA_LEN))
+               return true;
+
+       /* Disallow the root domain */
+       url += RPKI_SCHEMA_LEN;
+       if (url[0] == '/')
+               return true;
+       if (url[0] == '.' && url[1] == '/')
+               return true;
+
+       // XXX read the standard and reject more bad URLs
+       return false;
+}
+
 /*
  * Collapses '//' (except from the schema), '.' and '..'.
  *
@@ -23,8 +88,7 @@ url_normalize(char const *url)
        char *normal, *dst;
        struct tokenizer tkn;
 
-       if (strncmp(url, "rsync://", RPKI_SCHEMA_LEN) &&
-           strncmp(url, "https://", RPKI_SCHEMA_LEN))
+       if (has_bad_prefix(url))
                return NULL;
 
        normal = pstrdup(url);
index f6a03bf7564ba576223dfd7d3c3de96648d74d74..4adfa9e74cf6fc156e7dad72cf3135adb06e4ae5 100644 (file)
@@ -29,7 +29,7 @@ check_PROGRAMS += db_table.test
 check_PROGRAMS += deltas_array.test
 check_PROGRAMS += hash.test
 check_PROGRAMS += json_util.test
-check_PROGRAMS += map.test
+check_PROGRAMS += mft.test
 check_PROGRAMS += path.test
 check_PROGRAMS += pdu_handler.test
 check_PROGRAMS += pdu_stream.test
@@ -71,8 +71,8 @@ hash_test_LDADD = ${MY_LDADD}
 json_util_test_SOURCES = json_util_test.c
 json_util_test_LDADD = ${MY_LDADD}
 
-map_test_SOURCES = types/map_test.c
-map_test_LDADD = ${MY_LDADD}
+mft_test_SOURCES = object/manifest_test.c
+mft_test_LDADD = ${MY_LDADD}
 
 path_test_SOURCES = types/path_test.c
 path_test_LDADD = ${MY_LDADD}
index b64616462a81be26e12f305791228b4579b520dc..5055046b75f0a92744efb2da94a3ebfbc7622d80 100644 (file)
@@ -4,6 +4,7 @@
 #include "base64.c"
 #include "common.h"
 #include "mock.c"
+#include "types/array.h"
 
 static void
 ck_uchar_array(unsigned char *expected, size_t expected_len,
index dcedef532ebfe9bc34f83b632cd5c56569b05d51..21fdfda96797aba2cc32b7e2d1dc9f9dfa3fa90c 100644 (file)
@@ -56,10 +56,8 @@ setup_test(void)
 }
 
 static int
-okay(struct cache_node *node, void *arg)
+okay(struct cache_mapping *map, void *arg)
 {
-       // XXX ensure the rsync and RRDP codes do this
-       node->flags |= CNF_VALID;
        return 0;
 }
 
@@ -181,13 +179,13 @@ ck_cache(struct cache_node *rsync, struct cache_node *https)
 static void
 ck_cache_rsync(struct cache_node *rsync)
 {
-       ck_cache(rsync, hunode(HE2UP, NULL));
+       ck_cache(rsync, hnode(HE2UP, NULL));
 }
 
 static void
 ck_cache_https(struct cache_node *https)
 {
-       ck_cache(runode(RE2UP, NULL), https);
+       ck_cache(rnode(RE2UP, NULL), https);
 }
 
 static time_t
@@ -197,9 +195,7 @@ get_days_ago(int days)
        struct tm tm;
        int error;
 
-       tt_now = time(NULL);
-       if (tt_now == (time_t) -1)
-               pr_crit("time(NULL) returned (time_t) -1.");
+       tt_now = time_fatal();
        if (localtime_r(&tt_now, &tm) == NULL) {
                error = errno;
                pr_crit("localtime_r(tt, &tm) returned error: %s",
@@ -280,16 +276,16 @@ START_TEST(test_cache_download_rsync)
        printf("==== Startup ====\n");
        run_dl_rsync("rsync://a.b.c/d", 0, 1);
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               ruftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0", NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0", NULL), NULL), NULL));
 
        printf("==== Redownload same file, nothing should happen ====\n");
        run_dl_rsync("rsync://a.b.c/d", 0, 0);
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               ruftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0", NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0", NULL), NULL), NULL));
 
        /*
         * rsyncs are recursive, which means if we've been recently asked to
@@ -298,10 +294,10 @@ START_TEST(test_cache_download_rsync)
        printf("==== Don't redownload child ====\n");
        run_dl_rsync("rsync://a.b.c/d/e", 0, 0);
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               ruftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0",
-                                       rufnode(RO2UP("a.b.c/d/e"), VALIDATED, NULL), NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0",
+                                       rfnode(RO2UP("a.b.c/d/e"), VALIDATED, NULL), NULL), NULL), NULL));
 
        /*
         * rsyncs get truncated, because it results in much faster
@@ -312,28 +308,28 @@ START_TEST(test_cache_download_rsync)
        printf("==== rsync truncated ====\n");
        run_dl_rsync("rsync://x.y.z/m/n/o", 0, 1);
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               ruftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0",
-                                       rufnode(RO2UP("a.b.c/d/e"), VALIDATED, NULL), NULL), NULL),
-                       runode(RO2UP("x.y.z"),
-                               ruftnode(RO2UP("x.y.z/m"), DOWNLOADED, "tmp/tmp/1",
-                                       rufnode(RO2UP("x.y.z/m/n"), BRANCH,
-                                               rufnode(RO2UP("x.y.z/m/n/o"), VALIDATED, NULL), NULL), NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0",
+                                       rfnode(RO2UP("a.b.c/d/e"), VALIDATED, NULL), NULL), NULL),
+                       rnode(RO2UP("x.y.z"),
+                               rftnode(RO2UP("x.y.z/m"), DOWNLOADED, "tmp/tmp/1",
+                                       rfnode(RO2UP("x.y.z/m/n"), BRANCH,
+                                               rfnode(RO2UP("x.y.z/m/n/o"), VALIDATED, NULL), NULL), NULL), NULL), NULL));
 
        printf("==== Sibling ====\n");
        run_dl_rsync("rsync://a.b.c/e/f", 0, 1);
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               ruftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0",
-                                       rufnode(RO2UP("a.b.c/d/e"), VALIDATED, NULL), NULL),
-                               ruftnode(RO2UP("a.b.c/e"), DOWNLOADED, "tmp/tmp/2",
-                                       rufnode(RO2UP("a.b.c/e/f"), VALIDATED, NULL), NULL), NULL),
-                       runode(RO2UP("x.y.z"),
-                               ruftnode(RO2UP("x.y.z/m"), DOWNLOADED, "tmp/tmp/1",
-                                       rufnode(RO2UP("x.y.z/m/n"), BRANCH,
-                                               rufnode(RO2UP("x.y.z/m/n/o"), VALIDATED, NULL), NULL), NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0",
+                                       rfnode(RO2UP("a.b.c/d/e"), VALIDATED, NULL), NULL),
+                               rftnode(RO2UP("a.b.c/e"), DOWNLOADED, "tmp/tmp/2",
+                                       rfnode(RO2UP("a.b.c/e/f"), VALIDATED, NULL), NULL), NULL),
+                       rnode(RO2UP("x.y.z"),
+                               rftnode(RO2UP("x.y.z/m"), DOWNLOADED, "tmp/tmp/1",
+                                       rfnode(RO2UP("x.y.z/m/n"), BRANCH,
+                                               rfnode(RO2UP("x.y.z/m/n/o"), VALIDATED, NULL), NULL), NULL), NULL), NULL));
 
        cleanup_test();
 }
@@ -349,27 +345,27 @@ START_TEST(test_cache_download_rsync_error)
        dl_error = -EINVAL;
        run_dl_rsync("rsync://a.b.c/e", -EINVAL, 1);
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               ruftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0", NULL),
-                               rufnode(RO2UP("a.b.c/e"), FAILED, NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0", NULL),
+                               rfnode(RO2UP("a.b.c/e"), FAILED, NULL), NULL), NULL));
 
        printf("==== Regardless of error, not reattempted because same iteration ====\n");
        dl_error = EINVAL;
        run_dl_rsync("rsync://a.b.c/e", -EINVAL, 0);
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               ruftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0", NULL),
-                               rufnode(RO2UP("a.b.c/e"), FAILED, NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0", NULL),
+                               rfnode(RO2UP("a.b.c/e"), FAILED, NULL), NULL), NULL));
 
        dl_error = 0;
        run_dl_rsync("rsync://a.b.c/e", -EINVAL, 0);
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               ruftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0", NULL),
-                               rufnode(RO2UP("a.b.c/e"), FAILED, NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0", NULL),
+                               rfnode(RO2UP("a.b.c/e"), FAILED, NULL), NULL), NULL));
 
        cleanup_test();
 }
@@ -385,10 +381,10 @@ START_TEST(test_cache_cleanup_rsync)
        run_dl_rsync("rsync://a.b.c/e", 0, 1);
        run_cleanup();
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               rufnode(RO2UP("a.b.c/d"), FULL, NULL),
-                               rufnode(RO2UP("a.b.c/e"), FULL, NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rfnode(RO2UP("a.b.c/d"), FULL, NULL),
+                               rfnode(RO2UP("a.b.c/e"), FULL, NULL), NULL), NULL));
 
        printf("==== One iteration with no changes, for paranoia ====\n");
        new_iteration(true);
@@ -396,10 +392,10 @@ START_TEST(test_cache_cleanup_rsync)
        run_dl_rsync("rsync://a.b.c/e", 0, 1);
        run_cleanup();
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               rufnode(RO2UP("a.b.c/d"), FULL, NULL),
-                               rufnode(RO2UP("a.b.c/e"), FULL, NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rfnode(RO2UP("a.b.c/d"), FULL, NULL),
+                               rfnode(RO2UP("a.b.c/e"), FULL, NULL), NULL), NULL));
 
        printf("==== Add one sibling ====\n");
        new_iteration(true);
@@ -408,62 +404,62 @@ START_TEST(test_cache_cleanup_rsync)
        run_dl_rsync("rsync://a.b.c/f", 0, 1);
        run_cleanup();
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               rufnode(RO2UP("a.b.c/d"), FULL, NULL),
-                               rufnode(RO2UP("a.b.c/e"), FULL, NULL),
-                               rufnode(RO2UP("a.b.c/f"), FULL, NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rfnode(RO2UP("a.b.c/d"), FULL, NULL),
+                               rfnode(RO2UP("a.b.c/e"), FULL, NULL),
+                               rfnode(RO2UP("a.b.c/f"), FULL, NULL), NULL), NULL));
 
        printf("==== Nodes don't get updated, but they're still too young ====\n");
        new_iteration(false);
        run_cleanup();
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               rufnode(RO2UP("a.b.c/d"), STALE, NULL),
-                               rufnode(RO2UP("a.b.c/e"), STALE, NULL),
-                               rufnode(RO2UP("a.b.c/f"), STALE, NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rfnode(RO2UP("a.b.c/d"), STALE, NULL),
+                               rfnode(RO2UP("a.b.c/e"), STALE, NULL),
+                               rfnode(RO2UP("a.b.c/f"), STALE, NULL), NULL), NULL));
 
        printf("==== Remove some branches ====\n");
        new_iteration(true);
        run_dl_rsync("rsync://a.b.c/d", 0, 1);
        run_cleanup();
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               rufnode(RO2UP("a.b.c/d"), FULL, NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rfnode(RO2UP("a.b.c/d"), FULL, NULL), NULL), NULL));
 
        printf("==== Remove old branch and add sibling at the same time ====\n");
        new_iteration(true);
        run_dl_rsync("rsync://a.b.c/e", 0, 1);
        run_cleanup();
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               rufnode(RO2UP("a.b.c/e"), FULL, NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rfnode(RO2UP("a.b.c/e"), FULL, NULL), NULL), NULL));
 
        printf("==== Try child ====\n");
        new_iteration(true);
        run_dl_rsync("rsync://a.b.c/e/f/g", 0, 1);
        run_cleanup();
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               rufnode(RO2UP("a.b.c/e"), FULL, NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rfnode(RO2UP("a.b.c/e"), FULL, NULL), NULL), NULL));
 
        printf("==== Parent again ====\n");
        new_iteration(true);
        run_dl_rsync("rsync://a.b.c/e", 0, 1);
        run_cleanup();
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               rufnode(RO2UP("a.b.c/e"), FULL, NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rfnode(RO2UP("a.b.c/e"), FULL, NULL), NULL), NULL));
 
        printf("==== Empty the tree ====\n");
        new_iteration(true);
        run_cleanup();
-       ck_cache_rsync(runode(RE2UP, NULL));
+       ck_cache_rsync(rnode(RE2UP, NULL));
 
 
        printf("==== Node exists, but file doesn't ====\n");
@@ -471,22 +467,22 @@ START_TEST(test_cache_cleanup_rsync)
        run_dl_rsync("rsync://a.b.c/e", 0, 1);
        run_dl_rsync("rsync://a.b.c/f", 0, 1);
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               ruftnode(RO2UP("a.b.c/e"), FULL, "tmp/tmp/B", NULL),
-                               ruftnode(RO2UP("a.b.c/f"), FULL, "tmp/tmp/C", NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rftnode(RO2UP("a.b.c/e"), FULL, "tmp/tmp/B", NULL),
+                               rftnode(RO2UP("a.b.c/f"), FULL, "tmp/tmp/C", NULL), NULL), NULL));
        run_cleanup();
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               rufnode(RO2UP("a.b.c/e"), FULL, NULL),
-                               rufnode(RO2UP("a.b.c/f"), FULL, NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rfnode(RO2UP("a.b.c/e"), FULL, NULL),
+                               rfnode(RO2UP("a.b.c/f"), FULL, NULL), NULL), NULL));
        ck_assert_int_eq(0, file_rm_rf("tmp/rsync/a.b.c/f"));
        run_cleanup();
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               rufnode(RO2UP("a.b.c/e"), FULL, NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rfnode(RO2UP("a.b.c/e"), FULL, NULL), NULL), NULL));
 
        cleanup_test();
 }
@@ -502,17 +498,17 @@ START_TEST(test_cache_cleanup_rsync_error)
        dl_error = -EINVAL;
        run_dl_rsync("rsync://a.b.c/e", -EINVAL, 1);
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               ruftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0", NULL),
-                               rufnode(RO2UP("a.b.c/e"), FAILED, NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rftnode(RO2UP("a.b.c/d"), FULL, "tmp/tmp/0", NULL),
+                               rfnode(RO2UP("a.b.c/e"), FAILED, NULL), NULL), NULL));
 
        printf("==== Node deleted because file doesn't exist ====\n");
        run_cleanup();
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               rufnode(RO2UP("a.b.c/d"), FULL, NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rfnode(RO2UP("a.b.c/d"), FULL, NULL), NULL), NULL));
 
        printf("==== Node and file preserved because young ====\n");
        /* (Deletion does not depend on success or failure.) */
@@ -520,14 +516,14 @@ START_TEST(test_cache_cleanup_rsync_error)
        dl_error = -EINVAL;
        run_dl_rsync("rsync://a.b.c/d", -EINVAL, 1);
        ck_cache_rsync(
-               runode(RE2UP,
-                       runode(RO2UP("a.b.c"),
-                               rufnode(RO2UP("a.b.c/d"), DOWNLOADED, NULL), NULL), NULL));
+               rnode(RE2UP,
+                       rnode(RO2UP("a.b.c"),
+                               rfnode(RO2UP("a.b.c/d"), DOWNLOADED, NULL), NULL), NULL));
 
        printf("==== Error node deleted because old ====\n");
        new_iteration(true);
        run_cleanup();
-       ck_cache_rsync(runode(RE2UP, NULL));
+       ck_cache_rsync(rnode(RE2UP, NULL));
 
        cleanup_test();
 }
@@ -547,30 +543,30 @@ START_TEST(test_cache_download_https)
        printf("==== Download *file* e ====\n");
        run_dl_https("https://a.b.c/d/e", 0, 1);
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               hunode(HO2UP("a.b.c/d"),
-                                       huftnode(HO2UP("a.b.c/d/e"), HFULL, "tmp/tmp/0", NULL), NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hnode(HO2UP("a.b.c/d"),
+                                       hftnode(HO2UP("a.b.c/d/e"), HFULL, "tmp/tmp/0", NULL), NULL), NULL), NULL));
 
        printf("==== Download something else 1 ====\n");
        run_dl_https("https://a.b.c/e", 0, 1);
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               hunode(HO2UP("a.b.c/d"),
-                                       huftnode(HO2UP("a.b.c/d/e"), HFULL, "tmp/tmp/0", NULL), NULL),
-                               huftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/1", NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hnode(HO2UP("a.b.c/d"),
+                                       hftnode(HO2UP("a.b.c/d/e"), HFULL, "tmp/tmp/0", NULL), NULL),
+                               hftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/1", NULL), NULL), NULL));
 
        printf("==== Download something else 2 ====\n");
        run_dl_https("https://x.y.z/e", 0, 1);
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               hunode(HO2UP("a.b.c/d"),
-                                       huftnode(HO2UP("a.b.c/d/e"), HFULL, "tmp/tmp/0", NULL), NULL),
-                               huftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/1", NULL), NULL),
-                       hunode(HO2UP("x.y.z"),
-                               huftnode(HO2UP("x.y.z/e"), HFULL, "tmp/tmp/2", NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hnode(HO2UP("a.b.c/d"),
+                                       hftnode(HO2UP("a.b.c/d/e"), HFULL, "tmp/tmp/0", NULL), NULL),
+                               hftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/1", NULL), NULL),
+                       hnode(HO2UP("x.y.z"),
+                               hftnode(HO2UP("x.y.z/e"), HFULL, "tmp/tmp/2", NULL), NULL), NULL));
 
        cleanup_test();
 }
@@ -586,10 +582,10 @@ START_TEST(test_cache_download_https_error)
        dl_error = -EINVAL;
        run_dl_https("https://a.b.c/e", -EINVAL, 1);
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               huftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL),
-                               huftnode(HO2UP("a.b.c/e"), HFAILED, NULL, NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL),
+                               hftnode(HO2UP("a.b.c/e"), HFAILED, NULL, NULL), NULL), NULL));
 
        printf("==== Regardless of error, not reattempted because same iteration ====\n");
        dl_error = -EINVAL;
@@ -597,10 +593,10 @@ START_TEST(test_cache_download_https_error)
        dl_error = 0;
        run_dl_https("https://a.b.c/e", -EINVAL, 0);
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               huftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL),
-                               huftnode(HO2UP("a.b.c/e"), HFAILED, NULL, NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL),
+                               hftnode(HO2UP("a.b.c/e"), HFAILED, NULL, NULL), NULL), NULL));
 
        cleanup_test();
 }
@@ -618,39 +614,39 @@ START_TEST(test_cache_cleanup_https)
        run_dl_https("https://a.b.c/e", 0, 1);
        run_cleanup();
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               hufnode(HO2UP("a.b.c/d"), HFULL, NULL),
-                               hufnode(HO2UP("a.b.c/e"), HFULL, NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hfnode(HO2UP("a.b.c/d"), HFULL, NULL),
+                               hfnode(HO2UP("a.b.c/e"), HFULL, NULL), NULL), NULL));
 
        printf("==== Remove one branch ====\n");
        new_iteration(true);
        run_dl_https("https://a.b.c/d", 0, 1);
        run_cleanup();
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               hufnode(HO2UP("a.b.c/d"), HFULL, NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hfnode(HO2UP("a.b.c/d"), HFULL, NULL), NULL), NULL));
 
        printf("==== Change the one branch ====\n");
        new_iteration(true);
        run_dl_https("https://a.b.c/e", 0, 1);
        run_cleanup();
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               hufnode(HO2UP("a.b.c/e"), HFULL, NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hfnode(HO2UP("a.b.c/e"), HFULL, NULL), NULL), NULL));
 
        printf("==== Add a child to the same branch, do not update the old one ====\n");
        new_iteration(true);
        run_dl_https("https://a.b.c/e/f/g", 0, 1);
        run_cleanup();
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               hunode(HO2UP("a.b.c/e"),
-                                       hunode(HO2UP("a.b.c/e/f"),
-                                               hufnode(HO2UP("a.b.c/e/f/g"), HFULL, NULL), NULL), NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hnode(HO2UP("a.b.c/e"),
+                                       hnode(HO2UP("a.b.c/e/f"),
+                                               hfnode(HO2UP("a.b.c/e/f/g"), HFULL, NULL), NULL), NULL), NULL), NULL));
 
        printf("====  Download parent, do not update child ====\n");
        /* (Children need to die, because parent is now a file) */
@@ -658,87 +654,87 @@ START_TEST(test_cache_cleanup_https)
        run_dl_https("https://a.b.c/e/f", 0, 1);
        run_cleanup();
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               hunode(HO2UP("a.b.c/e"),
-                                       hufnode(HO2UP("a.b.c/e/f"), HFULL, NULL), NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hnode(HO2UP("a.b.c/e"),
+                                       hfnode(HO2UP("a.b.c/e/f"), HFULL, NULL), NULL), NULL), NULL));
 
        printf("==== Do it again ====\n");
        new_iteration(true);
        run_dl_https("https://a.b.c/e", 0, 1);
        run_cleanup();
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               hufnode(HO2UP("a.b.c/e"), HFULL, NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hfnode(HO2UP("a.b.c/e"), HFULL, NULL), NULL), NULL));
 
 
        printf("==== Empty the tree ====\n");
        new_iteration(true);
        run_cleanup();
-       ck_cache_https(hunode(HE2UP, NULL));
+       ck_cache_https(hnode(HE2UP, NULL));
 
        printf("==== Node exists, but file doesn't ====\n");
        new_iteration(true);
        run_dl_https("https://a.b.c/e", 0, 1);
        run_dl_https("https://a.b.c/f/g/h", 0, 1);
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               huftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/7", NULL),
-                               hunode(HO2UP("a.b.c/f"),
-                                       hunode(HO2UP("a.b.c/f/g"),
-                                               huftnode(HO2UP("a.b.c/f/g/h"), HFULL, "tmp/tmp/8", NULL), NULL), NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/7", NULL),
+                               hnode(HO2UP("a.b.c/f"),
+                                       hnode(HO2UP("a.b.c/f/g"),
+                                               hftnode(HO2UP("a.b.c/f/g/h"), HFULL, "tmp/tmp/8", NULL), NULL), NULL), NULL), NULL));
        run_cleanup(); /* Move from tmp/tmp to tmp/https */
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               hufnode(HO2UP("a.b.c/e"), HFULL, NULL),
-                               hunode(HO2UP("a.b.c/f"),
-                                       hunode(HO2UP("a.b.c/f/g"),
-                                               hufnode(HO2UP("a.b.c/f/g/h"), HFULL, NULL), NULL), NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hfnode(HO2UP("a.b.c/e"), HFULL, NULL),
+                               hnode(HO2UP("a.b.c/f"),
+                                       hnode(HO2UP("a.b.c/f/g"),
+                                               hfnode(HO2UP("a.b.c/f/g/h"), HFULL, NULL), NULL), NULL), NULL), NULL));
        ck_assert_int_eq(0, file_rm_rf("tmp/https/a.b.c/f/g/h"));
        run_cleanup(); /* Actual test */
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               hufnode(HO2UP("a.b.c/e"), HFULL, NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hfnode(HO2UP("a.b.c/e"), HFULL, NULL), NULL), NULL));
 
        printf("==== Temporal version disappears before we get a commit ====\n");
        new_iteration(true);
        run_dl_https("https://a.b.c/e", 0, 1);
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               huftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/9", NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/9", NULL), NULL), NULL));
        ck_assert_int_eq(0, file_rm_rf("tmp/tmp/9"));
        run_cleanup();
-       ck_cache_https(hunode(HE2UP, NULL));
+       ck_cache_https(hnode(HE2UP, NULL));
 
        printf("==== Temporal version disappears after we get a commit ====\n");
        new_iteration(true);
        run_dl_https("https://a.b.c/e", 0, 1);
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               huftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/A", NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/A", NULL), NULL), NULL));
        run_cleanup(); /* Commit */
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               hufnode(HO2UP("a.b.c/e"), HFULL, NULL, NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hfnode(HO2UP("a.b.c/e"), HFULL, NULL, NULL), NULL), NULL));
        new_iteration(false);
        run_dl_https("https://a.b.c/e", 0, 1);
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               huftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/B", NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/B", NULL), NULL), NULL));
        ck_assert_int_eq(0, file_rm_rf("tmp/tmp/B"));
        run_cleanup();
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               hufnode(HO2UP("a.b.c/e"), HFULL, NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hfnode(HO2UP("a.b.c/e"), HFULL, NULL), NULL), NULL));
 
        cleanup_test();
 }
@@ -755,39 +751,39 @@ START_TEST(test_cache_cleanup_https_error)
        run_dl_https("https://a.b.c/e", -EINVAL, 1);
        PR_DEBUG;
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               huftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL),
-                               hufnode(HO2UP("a.b.c/e"), HFAILED, NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL),
+                               hfnode(HO2UP("a.b.c/e"), HFAILED, NULL), NULL), NULL));
 
        printf("==== Deleted because file ENOENT ====\n");
        run_cleanup();
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               hufnode(HO2UP("a.b.c/d"), HFULL, NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hfnode(HO2UP("a.b.c/d"), HFULL, NULL), NULL), NULL));
 
        printf("==== Fail d ====\n");
        new_iteration(false);
        dl_error = -EINVAL;
        run_dl_https("https://a.b.c/d", -EINVAL, 1);
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               hufnode(HO2UP("a.b.c/d"), CNF_CACHED | CNF_FRESH, NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hfnode(HO2UP("a.b.c/d"), CNF_CACHED | CNF_FRESH, NULL), NULL), NULL));
 
        printf("==== Not deleted, because not old ====\n");
        new_iteration(false);
        run_cleanup();
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               hufnode(HO2UP("a.b.c/d"), CNF_CACHED, NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hfnode(HO2UP("a.b.c/d"), CNF_CACHED, NULL), NULL), NULL));
 
        printf("==== Become old ====\n");
        new_iteration(true);
        run_cleanup();
-       ck_cache_https(hunode(HE2UP, NULL));
+       ck_cache_https(hnode(HE2UP, NULL));
 
        cleanup_test();
 }
@@ -799,28 +795,28 @@ START_TEST(test_dots)
 
        run_dl_https("https://a.b.c/d", 0, 1);
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               huftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL), NULL), NULL));
 
        run_dl_https("https://a.b.c/d/.", 0, 0);
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               huftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL), NULL), NULL));
 
        run_dl_https("https://a.b.c/d/e/..", 0, 0);
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               huftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL), NULL), NULL));
 
        run_dl_https("https://a.b.c/./d/../e", 0, 1);
        ck_cache_https(
-               hunode(HE2UP,
-                       hunode(HO2UP("a.b.c"),
-                               huftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL),
-                               huftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/1", NULL), NULL), NULL));
+               hnode(HE2UP,
+                       hnode(HO2UP("a.b.c"),
+                               hftnode(HO2UP("a.b.c/d"), HFULL, "tmp/tmp/0", NULL),
+                               hftnode(HO2UP("a.b.c/e"), HFULL, "tmp/tmp/1", NULL), NULL), NULL));
 
        cleanup_test();
 }
index 74475bf58fb317d4c3be330ce971b0cc4a97e24a..08a588dbca9897d8e87a214c4dd9685a93a993f1 100644 (file)
@@ -42,8 +42,8 @@ ck_assert_cachent_eq(struct cache_node *expected, struct cache_node *actual)
        }
 }
 
-struct cache_node *
-vcreate_node(char const *url, char const *path, int flags, char const *tmppath,
+static struct cache_node *
+vnode(char const *url, char const *path, int flags, char const *tmppath,
     va_list children)
 {
        struct cache_node *result;
@@ -69,76 +69,78 @@ vcreate_node(char const *url, char const *path, int flags, char const *tmppath,
 }
 
 struct cache_node *
-ruftnode(char const *url, char const *path, int flags, char const *tmppath, ...)
+rftnode(char const *url, char const *path, int flags, char const *tmppath, ...)
 {
        struct cache_node *result;
        va_list children;
 
        va_start(children, tmppath);
-       result = vcreate_node(url, path, flags, tmppath, children);
+       result = vnode(url, path, flags, tmppath, children);
        va_end(children);
 
        return result;
 }
 
 struct cache_node *
-rufnode(char const *url, char const *path, int flags, ...)
+rfnode(char const *url, char const *path, int flags, ...)
 {
        struct cache_node *result;
        va_list children;
 
        va_start(children, flags);
-       result = vcreate_node(url, path, flags, NULL, children);
+       result = vnode(url, path, flags, NULL, children);
        va_end(children);
 
        return result;
 }
 
 struct cache_node *
-runode(char const *url, char const *path, ...)
+rnode(char const *url, char const *path, ...)
 {
        struct cache_node *result;
        va_list children;
 
        va_start(children, path);
-       result = vcreate_node(url, path, 0, NULL, children);
+       result = vnode(url, path, 0, NULL, children);
        va_end(children);
 
        return result;
 }
 
 struct cache_node *
-huftnode(char const *url, char const *path, int flags, char const *tmppath, ...)
+hftnode(char const *url, char const *path, int flags, char const *tmppath, ...)
 {
        struct cache_node *result;
        va_list children;
 
        va_start(children, tmppath);
-       result = vcreate_node(url, path, flags, tmppath, children);
+       result = vnode(url, path, flags, tmppath, children);
        va_end(children);
 
        return result;
 }
 
-struct cache_node *hufnode(char const *url, char const *path, int flags, ...)
+struct cache_node *
+hfnode(char const *url, char const *path, int flags, ...)
 {
        struct cache_node *result;
        va_list children;
 
        va_start(children, flags);
-       result = vcreate_node(url, path, flags, NULL, children);
+       result = vnode(url, path, flags, NULL, children);
        va_end(children);
 
        return result;
 }
 
-struct cache_node *hunode(char const *url, char const *path, ...)
+struct cache_node *
+hnode(char const *url, char const *path, ...)
 {
        struct cache_node *result;
        va_list children;
 
        va_start(children, path);
-       result = vcreate_node(url, path, 0, NULL, children);
+       result = vnode(url, path, 0, NULL, children);
        va_end(children);
 
        return result;
index 185895adbf62defe9e7ad74e80d47a557bacb251..f2461023bab1d4abb1a0455d48dde46feaafeeae 100644 (file)
@@ -6,16 +6,13 @@
 
 void ck_assert_cachent_eq(struct cache_node *, struct cache_node *);
 
-struct cache_node *vcreate_node(char const *, char const *, int, char const *, va_list);
+struct cache_node *rftnode(char const *, char const *, int, char const *, ...);
+struct cache_node *rfnode(char const *, char const *, int, ...);
+struct cache_node *rnode(char const *, char const *, ...);
 
-// XXX Rename ?
-struct cache_node *ruftnode(char const *, char const *, int, char const *, ...);
-struct cache_node *rufnode(char const *, char const *, int, ...);
-struct cache_node *runode(char const *, char const *, ...);
-
-struct cache_node *huftnode(char const *, char const *, int, char const *, ...);
-struct cache_node *hufnode(char const *, char const *, int, ...);
-struct cache_node *hunode(char const *, char const *, ...);
+struct cache_node *hftnode(char const *, char const *, int, char const *, ...);
+struct cache_node *hfnode(char const *, char const *, int, ...);
+struct cache_node *hnode(char const *, char const *, ...);
 
 /* rsync offset to url + path */
 #define RO2UP(offset) "rsync://" offset, "tmp/rsync/" offset
index 8ffe46ad4aea8179dee8d87d108cbc215df1cd90..1f821d3375177d920d5d39f6d458cfa5dc91d421 100644 (file)
@@ -20,14 +20,14 @@ START_TEST(test_delete)
 {
        struct cache_node *root, *a, *b;
 
-       a = runode(RO2UP("a"), NULL);
+       a = rnode(RO2UP("a"), NULL);
        dn = 0;
        cachent_delete(a);
        ck_assert_uint_eq(1, dn);
        ck_assert_str_eq("a", deleted[0]);
 
-       a = runode(RO2UP("a"), NULL);
-       root = runode(RE2UP, a, NULL);
+       a = rnode(RO2UP("a"), NULL);
+       root = rnode(RE2UP, a, NULL);
        dn = 0;
        cachent_delete(a);
        ck_assert_ptr_eq(NULL, root->children);
@@ -39,23 +39,23 @@ START_TEST(test_delete)
        ck_assert_uint_eq(1, dn);
        ck_assert_str_eq("rsync", deleted[0]);
 
-       b = runode(RO2UP("a/b"),
-               runode(RO2UP("a/b/c"), NULL),
-               runode(RO2UP("a/b/d"), NULL),
-               runode(RO2UP("a/b/e"), NULL),
-               runode(RO2UP("a/b/f"), NULL), NULL);
-       a = runode(RO2UP("a"),
+       b = rnode(RO2UP("a/b"),
+               rnode(RO2UP("a/b/c"), NULL),
+               rnode(RO2UP("a/b/d"), NULL),
+               rnode(RO2UP("a/b/e"), NULL),
+               rnode(RO2UP("a/b/f"), NULL), NULL);
+       a = rnode(RO2UP("a"),
                b,
-               runode(RO2UP("a/g"),
-                       runode(RO2UP("a/g/h"),
-                               runode(RO2UP("a/g/h/i"), NULL), NULL),
-                       runode(RO2UP("a/g/j"),
-                               runode(RO2UP("a/g/j/k"), NULL), NULL),
-                       runode(RO2UP("a/g/l"),
-                               runode(RO2UP("a/g/l/m"), NULL), NULL),
-                       runode(RO2UP("a/g/n"),
-                               runode(RO2UP("a/g/n/o"), NULL), NULL), NULL), NULL);
-       root = runode(RE2UP, a, NULL);
+               rnode(RO2UP("a/g"),
+                       rnode(RO2UP("a/g/h"),
+                               rnode(RO2UP("a/g/h/i"), NULL), NULL),
+                       rnode(RO2UP("a/g/j"),
+                               rnode(RO2UP("a/g/j/k"), NULL), NULL),
+                       rnode(RO2UP("a/g/l"),
+                               rnode(RO2UP("a/g/l/m"), NULL), NULL),
+                       rnode(RO2UP("a/g/n"),
+                               rnode(RO2UP("a/g/n/o"), NULL), NULL), NULL), NULL);
+       root = rnode(RE2UP, a, NULL);
 
        dn = 0;
        cachent_delete(b);
@@ -111,7 +111,7 @@ ck_traverse(struct cache_node *root, ...)
        expected[p] = NULL;
 
        e = 0;
-       ck_assert_int_eq(0, cachent_traverse(root, ck_traverse_cb));
+       cachent_traverse(root, ck_traverse_cb);
        ck_assert_uint_eq(p, e);
 
        cachent_delete(root);
@@ -124,36 +124,36 @@ START_TEST(test_traverse)
        root = NULL;
        ck_traverse(root, NULL);
 
-       root =  runode(RO2UP("a"), NULL);
+       root =  rnode(RO2UP("a"), NULL);
        ck_traverse(root, "tmp/rsync/a", NULL);
 
-       root =  runode(RO2UP("a"),
-                       runode(RO2UP("a/b"), NULL), NULL);
+       root =  rnode(RO2UP("a"),
+                       rnode(RO2UP("a/b"), NULL), NULL);
        ck_traverse(root, "tmp/rsync/a", "tmp/rsync/a/b", NULL);
 
-       root =  runode(RO2UP("a"),
-                       runode(RO2UP("a/b"),
-                               runode(RO2UP("a/b/c"), NULL), NULL), NULL);
+       root =  rnode(RO2UP("a"),
+                       rnode(RO2UP("a/b"),
+                               rnode(RO2UP("a/b/c"), NULL), NULL), NULL);
        ck_traverse(root,
                "tmp/rsync/a",
                "tmp/rsync/a/b",
                "tmp/rsync/a/b/c", NULL);
 
-       root =  runode(RO2UP("a"),
-                       runode(RO2UP("a/b"),
-                               runode(RO2UP("a/b/c"), NULL),
-                               runode(RO2UP("a/b/d"), NULL), NULL), NULL);
+       root =  rnode(RO2UP("a"),
+                       rnode(RO2UP("a/b"),
+                               rnode(RO2UP("a/b/c"), NULL),
+                               rnode(RO2UP("a/b/d"), NULL), NULL), NULL);
        ck_traverse(root,
                "tmp/rsync/a",
                "tmp/rsync/a/b",
                "tmp/rsync/a/b/c",
                "tmp/rsync/a/b/d", NULL);
 
-       root =  runode(RO2UP("a"),
-                       runode(RO2UP("a/b"),
-                               runode(RO2UP("a/b/c"), NULL),
-                               runode(RO2UP("a/b/d"), NULL), NULL),
-                       runode(RO2UP("a/e"), NULL), NULL);
+       root =  rnode(RO2UP("a"),
+                       rnode(RO2UP("a/b"),
+                               rnode(RO2UP("a/b/c"), NULL),
+                               rnode(RO2UP("a/b/d"), NULL), NULL),
+                       rnode(RO2UP("a/e"), NULL), NULL);
        ck_traverse(root,
                "tmp/rsync/a",
                "tmp/rsync/a/b",
@@ -161,11 +161,11 @@ START_TEST(test_traverse)
                "tmp/rsync/a/b/d",
                "tmp/rsync/a/e", NULL);
 
-       root =  runode(RO2UP("a"),
-                       runode(RO2UP("a/b"), NULL),
-                       runode(RO2UP("a/c"),
-                               runode(RO2UP("a/c/d"), NULL),
-                               runode(RO2UP("a/c/e"), NULL), NULL), NULL);
+       root =  rnode(RO2UP("a"),
+                       rnode(RO2UP("a/b"), NULL),
+                       rnode(RO2UP("a/c"),
+                               rnode(RO2UP("a/c/d"), NULL),
+                               rnode(RO2UP("a/c/e"), NULL), NULL), NULL);
        ck_traverse(root,
                "tmp/rsync/a",
                "tmp/rsync/a/b",
@@ -173,13 +173,13 @@ START_TEST(test_traverse)
                "tmp/rsync/a/c/d",
                "tmp/rsync/a/c/e", NULL);
 
-       root =  runode(RO2UP("a"),
-                       runode(RO2UP("a/b"),
-                               runode(RO2UP("a/b/c"), NULL),
-                               runode(RO2UP("a/b/d"), NULL), NULL),
-                       runode(RO2UP("a/e"),
-                               runode(RO2UP("a/e/f"), NULL),
-                               runode(RO2UP("a/e/g"), NULL), NULL), NULL);
+       root =  rnode(RO2UP("a"),
+                       rnode(RO2UP("a/b"),
+                               rnode(RO2UP("a/b/c"), NULL),
+                               rnode(RO2UP("a/b/d"), NULL), NULL),
+                       rnode(RO2UP("a/e"),
+                               rnode(RO2UP("a/e/f"), NULL),
+                               rnode(RO2UP("a/e/g"), NULL), NULL), NULL);
        ck_traverse(root,
                "tmp/rsync/a",
                "tmp/rsync/a/b",
@@ -189,21 +189,21 @@ START_TEST(test_traverse)
                "tmp/rsync/a/e/f",
                "tmp/rsync/a/e/g", NULL);
 
-       root =  runode(RO2UP("a"),
-                       runode(RO2UP("a/b"),
-                               runode(RO2UP("a/b/c"), NULL),
-                               runode(RO2UP("a/b/d"), NULL),
-                               runode(RO2UP("a/b/e"), NULL),
-                               runode(RO2UP("a/b/f"), NULL), NULL),
-                       runode(RO2UP("a/g"),
-                               runode(RO2UP("a/g/h"),
-                                       runode(RO2UP("a/g/h/i"), NULL), NULL),
-                               runode(RO2UP("a/g/j"),
-                                       runode(RO2UP("a/g/j/k"), NULL), NULL),
-                               runode(RO2UP("a/g/l"),
-                                       runode(RO2UP("a/g/l/m"), NULL), NULL),
-                               runode(RO2UP("a/g/n"),
-                                       runode(RO2UP("a/g/n/o"), NULL), NULL), NULL), NULL);
+       root =  rnode(RO2UP("a"),
+                       rnode(RO2UP("a/b"),
+                               rnode(RO2UP("a/b/c"), NULL),
+                               rnode(RO2UP("a/b/d"), NULL),
+                               rnode(RO2UP("a/b/e"), NULL),
+                               rnode(RO2UP("a/b/f"), NULL), NULL),
+                       rnode(RO2UP("a/g"),
+                               rnode(RO2UP("a/g/h"),
+                                       rnode(RO2UP("a/g/h/i"), NULL), NULL),
+                               rnode(RO2UP("a/g/j"),
+                                       rnode(RO2UP("a/g/j/k"), NULL), NULL),
+                               rnode(RO2UP("a/g/l"),
+                                       rnode(RO2UP("a/g/l/m"), NULL), NULL),
+                               rnode(RO2UP("a/g/n"),
+                                       rnode(RO2UP("a/g/n/o"), NULL), NULL), NULL), NULL);
        ck_traverse(root,
                "tmp/rsync/a",
                "tmp/rsync/a/b",
index 7df1a8e4cb1e79b5889943e40a635b75fa0cc735..b420710cda8dfc164e92b7fcd655c07cf36470b5 100644 (file)
@@ -124,3 +124,7 @@ MOCK_NULL(config_get_output_roa, char const *, void)
 MOCK_NULL(config_get_output_bgpsec, char const *, void)
 MOCK(config_get_op_log_filename_format, enum filename_format, FNF_NAME, void)
 MOCK(config_get_val_log_filename_format, enum filename_format, FNF_NAME, void)
+
+MOCK_VOID(fnstack_push, char const *file)
+MOCK_VOID(fnstack_push_map, struct cache_mapping *map)
+MOCK_VOID(fnstack_pop, void)
diff --git a/test/object/manifest_test.c b/test/object/manifest_test.c
new file mode 100644 (file)
index 0000000..823efdc
--- /dev/null
@@ -0,0 +1,98 @@
+#include <errno.h>
+#include <check.h>
+
+#include "alloc.c"
+#include "cachent.c"
+#include "common.c"
+#include "mock.c"
+#include "object/manifest.c"
+#include "types/map.c"
+#include "types/path.c"
+#include "types/url.c"
+
+MOCK_ABORT_INT(signed_object_decode, struct signed_object *sobj, char const *path)
+MOCK_ABORT_VOID(signed_object_cleanup, struct signed_object *sobj)
+MOCK_VOID(__delete_node_cb, struct cache_node const *node)
+
+#define BUFFER_LEN 128
+static uint8_t buffer[BUFFER_LEN];
+
+static int
+__test_validate(char const *src, size_t len)
+{
+       IA5String_t dst;
+       unsigned int i;
+
+       memcpy(buffer, src, len);
+       for (i = len; i < BUFFER_LEN - 1; i++)
+               buffer[i] = '_';
+       buffer[BUFFER_LEN - 1] = 0;
+
+       dst.buf = buffer;
+       dst.size = len;
+
+       return validate_mft_file(&dst);
+}
+
+#define test_validate(str) __test_validate(str, sizeof(str) - 1)
+
+START_TEST(check_validate_current_directory)
+{
+       ck_assert_int_eq(-EINVAL, test_validate(""));
+       ck_assert_int_eq(-EINVAL, test_validate("."));
+       ck_assert_int_eq(-EINVAL, test_validate(".."));
+
+       ck_assert_int_eq(-EINVAL, test_validate("filename"));
+       ck_assert_int_eq(-EINVAL, test_validate("filename."));
+       ck_assert_int_eq(-EINVAL, test_validate("filename.a"));
+       ck_assert_int_eq(-EINVAL, test_validate("filename.ab"));
+       ck_assert_int_eq(0, test_validate("filename.abc"));
+       ck_assert_int_eq(-EINVAL, test_validate("file.abcd"));
+
+       ck_assert_int_eq(0, test_validate("file-name.ABC"));
+       ck_assert_int_eq(0, test_validate("file_name.123"));
+       ck_assert_int_eq(0, test_validate("file0name.aB2"));
+       ck_assert_int_eq(0, test_validate("file9name.---"));
+       ck_assert_int_eq(0, test_validate("FileName.A3_"));
+       ck_assert_int_eq(-EINVAL, test_validate("file.name.abc"));
+       ck_assert_int_eq(-EINVAL, test_validate("file/name.abc"));
+       ck_assert_int_eq(-EINVAL, test_validate("file\0name.abc"));
+       ck_assert_int_eq(-EINVAL, test_validate("filename.abc\0filename.abc"));
+       ck_assert_int_eq(-EINVAL, test_validate("filenameabc\0filename.abc"));
+       ck_assert_int_eq(0, test_validate("-.---"));
+
+       ck_assert_int_eq(0, test_validate("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890-_.-_-"));
+       ck_assert_int_eq(0, test_validate("vixxBTS_TVXQ-2pmGOT7.cer"));
+}
+END_TEST
+
+static Suite *
+mft_suite(void)
+{
+       Suite *suite;
+       TCase *core;
+
+       core = tcase_create("core");
+       tcase_add_test(core, check_validate_current_directory);
+
+       suite = suite_create("mft");
+       suite_add_tcase(suite, core);
+       return suite;
+}
+
+int
+main(int argc, char **argv)
+{
+       Suite *suite;
+       SRunner *runner;
+       int tests_failed;
+
+       suite = mft_suite();
+
+       runner = srunner_create(suite);
+       srunner_run_all(runner, CK_NORMAL);
+       tests_failed = srunner_ntests_failed(runner);
+       srunner_free(runner);
+
+       return (tests_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
index 20c379effb3f66b6a2a2cdeeedadf202542498d3..4041892ca1160354fd9d6c9dc0e2e185276e8600 100644 (file)
@@ -18,8 +18,6 @@
 
 /* Mocks */
 
-MOCK_VOID(fnstack_push, char const *file)
-MOCK_VOID(fnstack_pop, void)
 MOCK_VOID(__delete_node_cb, struct cache_node const *node)
 MOCK_ABORT_INT(http_download, char const *url, char const *path, curl_off_t ims,
     bool *changed)
index 303fc904d0cdc1416909c3c744dac756e5ed5efe..17cb823911f3a14164fb3acead060bc981d027bf 100644 (file)
@@ -18,8 +18,6 @@
 
 /* Mocks */
 
-MOCK_VOID(fnstack_push, char const *file)
-MOCK_VOID(fnstack_pop, void)
 MOCK_VOID(__delete_node_cb, struct cache_node const *node)
 
 /* Utils */
@@ -97,10 +95,10 @@ START_TEST(startup)
        ck_assert_uint_eq(2, https_counter);
        ck_file("tmp/tmp/0/a/b/c.cer");
        ck_assert_cachent_eq(
-               ruftnode("rsync://", NOTIF_PATH, 0, "tmp/tmp/0",
-                       ruftnode("rsync://a", NOTIF_PATH "/a", 0, "tmp/tmp/0/a",
-                               ruftnode("rsync://a/b", NOTIF_PATH "/a/b", 0, "tmp/tmp/0/a/b",
-                                       ruftnode("rsync://a/b/c.cer", NOTIF_PATH "/a/b/c.cer", 0, "tmp/tmp/0/a/b/c.cer", NULL),
+               rftnode("rsync://", NOTIF_PATH, 0, "tmp/tmp/0",
+                       rftnode("rsync://a", NOTIF_PATH "/a", 0, "tmp/tmp/0/a",
+                               rftnode("rsync://a/b", NOTIF_PATH "/a/b", 0, "tmp/tmp/0/a/b",
+                                       rftnode("rsync://a/b/c.cer", NOTIF_PATH "/a/b/c.cer", 0, "tmp/tmp/0/a/b/c.cer", NULL),
                                        NULL),
                                NULL),
                        NULL),
@@ -113,10 +111,10 @@ START_TEST(startup)
        ck_assert_uint_eq(1, https_counter);
        ck_file("tmp/tmp/0/a/b/c.cer");
        ck_assert_cachent_eq(
-               ruftnode("rsync://", NOTIF_PATH, 0, "tmp/tmp/0",
-                       ruftnode("rsync://a", NOTIF_PATH "/a", 0, "tmp/tmp/0/a",
-                               ruftnode("rsync://a/b", NOTIF_PATH "/a/b", 0, "tmp/tmp/0/a/b",
-                                       ruftnode("rsync://a/b/c.cer", NOTIF_PATH "/a/b/c.cer", 0, "tmp/tmp/0/a/b/c.cer", NULL),
+               rftnode("rsync://", NOTIF_PATH, 0, "tmp/tmp/0",
+                       rftnode("rsync://a", NOTIF_PATH "/a", 0, "tmp/tmp/0/a",
+                               rftnode("rsync://a/b", NOTIF_PATH "/a/b", 0, "tmp/tmp/0/a/b",
+                                       rftnode("rsync://a/b/c.cer", NOTIF_PATH "/a/b/c.cer", 0, "tmp/tmp/0/a/b/c.cer", NULL),
                                        NULL),
                                NULL),
                        NULL),
index aacfe6d748aa6a29969c5abc4d8f8168524c8f34..a64ac582eb42bd76473fa13fbd35454657c71589 100644 (file)
 MOCK_ABORT_VOID(cache_setup, void)
 MOCK(cache_create, struct rpki_cache *, NULL, void)
 MOCK_VOID(cache_destroy, struct rpki_cache *cache)
-MOCK_ABORT_INT(cache_download, struct rpki_cache *cache,
-    struct cache_mapping *map, bool *changed,
-    struct cachefile_notification ***notif)
 MOCK_ABORT_INT(cache_download_alt, struct sia_uris *sias,
-    maps_dl_cb cb, void *arg)
-MOCK_ABORT_PTR(cache_recover, cache_mapping, struct rpki_cache *cache,
-    struct map_list *maps)
+    validate_cb cb, void *arg)
 MOCK_ABORT_INT(cache_tmpfile, char **filename)
 MOCK_ABORT_VOID(cache_teardown, void)
 MOCK_ABORT_INT(certificate_traverse, struct rpp *rpp_parent,
@@ -32,9 +27,6 @@ MOCK_VOID(db_table_destroy, struct db_table *table)
 MOCK_ABORT_INT(db_table_join, struct db_table *dst, struct db_table *src)
 MOCK_ABORT_INT(deferstack_pop, struct cert_stack *stack,
     struct deferred_cert *result)
-MOCK_ABORT_VOID(fnstack_cleanup, void)
-MOCK_ABORT_VOID(fnstack_init, void)
-MOCK_ABORT_VOID(fnstack_push, char const *f)
 MOCK_ABORT_INT(handle_roa_v4, uint32_t as, struct ipv4_prefix const *prefix,
     uint8_t max_length, void *arg)
 MOCK_ABORT_INT(handle_roa_v6, uint32_t as, struct ipv6_prefix const *prefix,
@@ -42,7 +34,6 @@ MOCK_ABORT_INT(handle_roa_v6, uint32_t as, struct ipv6_prefix const *prefix,
 MOCK_ABORT_INT(handle_router_key, unsigned char const *ski,
     struct asn_range const *asns, unsigned char const *spk, void *arg)
 MOCK_ABORT_VOID(rpp_refput, struct rpp *pp)
-MOCK_ABORT_INT(rrdp_update, struct cache_node *notif)
 MOCK(state_retrieve, struct validation *, NULL, void)
 MOCK_ABORT_PTR(validation_certstack, cert_stack, struct validation *state)
 MOCK_ABORT_VOID(validation_destroy, struct validation *state)
diff --git a/test/types/map_test.c b/test/types/map_test.c
deleted file mode 100644 (file)
index cd901ce..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-#include <check.h>
-#include <errno.h>
-#include <stdint.h>
-
-#include "alloc.c"
-#include "common.c"
-#include "mock.c"
-#include "types/map.c"
-#include "types/path.c"
-
-/* Mocks */
-
-static struct cache_mapping *notif;
-
-MOCK(state_retrieve, struct validation *, NULL, void)
-MOCK(validation_tal, struct tal *, NULL, struct validation *state)
-MOCK(tal_get_file_name, char const *, NULL, struct tal *tal)
-
-int
-cache_tmpfile(char **filename)
-{
-       static unsigned int used = 1;
-
-       if (used > 2) {
-               ck_abort_msg("cache_tmpfile() called a third time!");
-               return -EINVAL;
-       }
-
-       *filename = pstrdup("tmp/tmp/0");
-       used = true;
-       return 0;
-}
-
-/* Tests */
-
-#define MAP_CREATE_HTTP(map, str) map_create(&map, MAP_HTTP, str)
-#define MAP_CREATE(map, type, str) map_create(&map, type, str)
-
-START_TEST(test_constructor)
-{
-       struct cache_mapping *map;
-
-       ck_assert_int_eq(ENOTHTTPS, MAP_CREATE_HTTP(map, ""));
-       ck_assert_int_eq(ENOTHTTPS, MAP_CREATE_HTTP(map, "h"));
-       ck_assert_int_eq(ENOTHTTPS, MAP_CREATE_HTTP(map, "http"));
-       ck_assert_int_eq(ENOTHTTPS, MAP_CREATE_HTTP(map, "https"));
-       ck_assert_int_eq(ENOTHTTPS, MAP_CREATE_HTTP(map, "https:"));
-       ck_assert_int_eq(ENOTHTTPS, MAP_CREATE_HTTP(map, "https:/"));
-       ck_assert_int_eq(-EINVAL, MAP_CREATE_HTTP(map, "https://"));
-
-       ck_assert_int_eq(0, MAP_CREATE_HTTP(map, "https://a.b.c"));
-       ck_assert_str_eq("https://a.b.c", map_get_url(map));
-       ck_assert_str_eq("tmp/https/a.b.c", map_get_path(map));
-       map_refput(map);
-
-       ck_assert_int_eq(0, MAP_CREATE_HTTP(map, "https://a.b.c/"));
-       ck_assert_str_eq("https://a.b.c", map_get_url(map));
-       ck_assert_str_eq("tmp/https/a.b.c", map_get_path(map));
-       map_refput(map);
-
-       ck_assert_int_eq(0, MAP_CREATE_HTTP(map, "https://a.b.c/d"));
-       ck_assert_str_eq("https://a.b.c/d", map_get_url(map));
-       ck_assert_str_eq("tmp/https/a.b.c/d", map_get_path(map));
-       map_refput(map);
-
-       ck_assert_int_eq(0, MAP_CREATE_HTTP(map, "https://a.b.c/d/e"));
-       ck_assert_str_eq("https://a.b.c/d/e", map_get_url(map));
-       ck_assert_str_eq("tmp/https/a.b.c/d/e", map_get_path(map));
-       map_refput(map);
-
-       ck_assert_int_eq(0, MAP_CREATE_HTTP(map, "https://a.b.c/d/.."));
-       ck_assert_str_eq("https://a.b.c", map_get_url(map));
-       ck_assert_str_eq("tmp/https/a.b.c", map_get_path(map));
-       map_refput(map);
-
-       ck_assert_int_eq(0, MAP_CREATE_HTTP(map, "https://a.b.c/."));
-       ck_assert_str_eq("https://a.b.c", map_get_url(map));
-       ck_assert_str_eq("tmp/https/a.b.c", map_get_path(map));
-       map_refput(map);
-
-       ck_assert_int_eq(0, MAP_CREATE_HTTP(map, "https://a.b.c/././d/././e/./."));
-       ck_assert_str_eq("https://a.b.c/d/e", map_get_url(map));
-       ck_assert_str_eq("tmp/https/a.b.c/d/e", map_get_path(map));
-       map_refput(map);
-
-       ck_assert_int_eq(0, MAP_CREATE_HTTP(map, "https://a.b.c/a/b/.././.."));
-       ck_assert_str_eq("https://a.b.c", map_get_url(map));
-       ck_assert_str_eq("tmp/https/a.b.c", map_get_path(map));
-       map_refput(map);
-
-       ck_assert_int_eq(-EINVAL, MAP_CREATE_HTTP(map, "https://a.b.c/.."));
-       ck_assert_int_eq(-EINVAL, MAP_CREATE_HTTP(map, "https://a.b.c/../.."));
-       ck_assert_int_eq(-EINVAL, MAP_CREATE_HTTP(map, "https://a.b.c/d/../.."));
-       ck_assert_int_eq(-EINVAL, MAP_CREATE_HTTP(map, "https://a.b.c/d/../../.."));
-       ck_assert_int_eq(-EINVAL, MAP_CREATE_HTTP(map, "https://."));
-       ck_assert_int_eq(-EINVAL, MAP_CREATE_HTTP(map, "https://./."));
-       ck_assert_int_eq(-EINVAL, MAP_CREATE_HTTP(map, "https://.."));
-       ck_assert_int_eq(-EINVAL, MAP_CREATE_HTTP(map, "https://../.."));
-       ck_assert_int_eq(-EINVAL, MAP_CREATE_HTTP(map, "https://../../.."));
-
-       ck_assert_int_eq(ENOTHTTPS, MAP_CREATE_HTTP(map, "rsync://a.b.c/d"));
-       ck_assert_int_eq(ENOTHTTPS, MAP_CREATE_HTTP(map, "http://a.b.c/d"));
-       ck_assert_int_eq(ENOTRSYNC, MAP_CREATE(map, MAP_RSYNC, "https://a.b.c/d"));
-
-       ck_assert_int_eq(0, MAP_CREATE(map, MAP_RSYNC, "rsync://a.b.c/d"));
-       ck_assert_str_eq("rsync://a.b.c/d", map_get_url(map));
-       ck_assert_str_eq("tmp/rsync/a.b.c/d", map_get_path(map));
-       map_refput(map);
-
-       ck_assert_int_eq(0, MAP_CREATE(map, MAP_RSYNC, "rsync://a.b.c/d.cer"));
-       ck_assert_str_eq("rsync://a.b.c/d.cer", map_get_url(map));
-       ck_assert_str_eq("tmp/rsync/a.b.c/d.cer", map_get_path(map));
-       map_refput(map);
-
-       ck_assert_int_eq(0, MAP_CREATE(map, MAP_NOTIF, "https://a.b.c/notification.xml"));
-       ck_assert_str_eq("https://a.b.c/notification.xml", map_get_url(map));
-       ck_assert_str_eq("tmp/tmp/0", map_get_path(map));
-       map_refput(map);
-
-       /* XXX
-       ck_assert_int_eq(0, MAP_CREATE(map, MAP_TMP, "https://a.b.c/snapshot.xml"));
-       ck_assert_str_eq("https://a.b.c/snapshot.xml", map_get_url(map));
-       ck_assert_str_eq("tmp/tmp/0", map_get_path(map));
-       map_refput(map);
-       */
-}
-END_TEST
-
-/*
-#define BUFFER_LEN 128
-static uint8_t buffer[BUFFER_LEN];
-
-static int
-__test_validate(char const *src, size_t len)
-{
-       IA5String_t dst;
-       unsigned int i;
-
-       memcpy(buffer, src, len);
-       for (i = len; i < BUFFER_LEN - 1; i++)
-               buffer[i] = '_';
-       buffer[BUFFER_LEN - 1] = 0;
-
-       dst.buf = buffer;
-       dst.size = len;
-
-       return validate_mft_file(&dst);
-}
-
-#define test_validate(str) __test_validate(str, sizeof(str) - 1)
-*/
-
-START_TEST(check_validate_current_directory)
-{
-       /* XXX wtf is this doing in the map test?
-       ck_assert_int_eq(-EINVAL, test_validate(""));
-       ck_assert_int_eq(-EINVAL, test_validate("."));
-       ck_assert_int_eq(-EINVAL, test_validate(".."));
-
-       ck_assert_int_eq(-EINVAL, test_validate("filename"));
-       ck_assert_int_eq(-EINVAL, test_validate("filename."));
-       ck_assert_int_eq(-EINVAL, test_validate("filename.a"));
-       ck_assert_int_eq(-EINVAL, test_validate("filename.ab"));
-       ck_assert_int_eq(0, test_validate("filename.abc"));
-       ck_assert_int_eq(-EINVAL, test_validate("file.abcd"));
-
-       ck_assert_int_eq(0, test_validate("file-name.ABC"));
-       ck_assert_int_eq(0, test_validate("file_name.123"));
-       ck_assert_int_eq(0, test_validate("file0name.aB2"));
-       ck_assert_int_eq(0, test_validate("file9name.---"));
-       ck_assert_int_eq(0, test_validate("FileName.A3_"));
-       ck_assert_int_eq(-EINVAL, test_validate("file.name.abc"));
-       ck_assert_int_eq(-EINVAL, test_validate("file/name.abc"));
-       ck_assert_int_eq(-EINVAL, test_validate("file\0name.abc"));
-       ck_assert_int_eq(-EINVAL, test_validate("filename.abc\0filename.abc"));
-       ck_assert_int_eq(-EINVAL, test_validate("filenameabc\0filename.abc"));
-       ck_assert_int_eq(0, test_validate("-.---"));
-
-       ck_assert_int_eq(0, test_validate("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890-_.-_-"));
-       ck_assert_int_eq(0, test_validate("vixxBTS_TVXQ-2pmGOT7.cer"));
-       */
-}
-END_TEST
-
-START_TEST(check_caged)
-{
-       /* XXX
-       struct cache_mapping *map;
-
-       ck_assert_int_eq(0, map_create(&notif, MAP_NOTIF, "https://a.b.c/d/e.xml"));
-       ck_assert_int_eq(0, map_create(&map, MAP_CAGED, notif, "rsync://x.y.z/v/w.cer"));
-       ck_assert_str_eq("tmp/rrdp/a.b.c/d/e.xml/x.y.z/v/w.cer", map_get_path(map));
-       map_refput(map);
-       map_refput(notif);
-
-       ck_assert_int_eq(0, map_create(&notif, MAP_NOTIF, "https://a.b.c"));
-       ck_assert_int_eq(0, map_create(&map, MAP_CAGED, notif, "rsync://w"));
-       ck_assert_str_eq("tmp/rrdp/a.b.c/w", map_get_path(map));
-       map_refput(map);
-       map_refput(notif);
-       */
-}
-END_TEST
-
-static Suite *address_load_suite(void)
-{
-       Suite *suite;
-       TCase *core;
-
-       core = tcase_create("Core");
-       tcase_add_test(core, test_constructor);
-       tcase_add_test(core, check_validate_current_directory);
-       tcase_add_test(core, check_caged);
-
-       suite = suite_create("Encoding checking");
-       suite_add_tcase(suite, core);
-       return suite;
-}
-
-int main(void)
-{
-       Suite *suite;
-       SRunner *runner;
-       int tests_failed;
-
-       suite = address_load_suite();
-
-       runner = srunner_create(suite);
-       srunner_run_all(runner, CK_NORMAL);
-       tests_failed = srunner_ntests_failed(runner);
-       srunner_free(runner);
-
-       return (tests_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
-}
index 8d20ab30ec63bedb810eaf7055dbbce851294107..7decf0001fff388644c2da129f040310faf32c9a 100644 (file)
@@ -17,21 +17,36 @@ START_TEST(test_normalize)
 
        TEST_NORMALIZE("rsync://a.b.c", "rsync://a.b.c");
        TEST_NORMALIZE("rsync://a.b.c/", "rsync://a.b.c");
+       TEST_NORMALIZE("rsync://a.b.c/d", "rsync://a.b.c/d");
        TEST_NORMALIZE("rsync://a.b.c//////", "rsync://a.b.c");
        TEST_NORMALIZE("rsync://a.b.c/d/e", "rsync://a.b.c/d/e");
        TEST_NORMALIZE("rsync://a.b.c/d/e/.", "rsync://a.b.c/d/e");
        TEST_NORMALIZE("rsync://a.b.c/d/e/.", "rsync://a.b.c/d/e");
-       TEST_NORMALIZE("rsync://a.b.c/d/./e/.", "rsync://a.b.c/d/e");
+       TEST_NORMALIZE("rsync://a.b.c/././d/././e/./.", "rsync://a.b.c/d/e");
+       TEST_NORMALIZE("rsync://a.b.c/d/..", "rsync://a.b.c");
        TEST_NORMALIZE("rsync://a.b.c/x/../x/y/z", "rsync://a.b.c/x/y/z");
        TEST_NORMALIZE("rsync://a.b.c/d/../d/../d/e/", "rsync://a.b.c/d/e");
        TEST_NORMALIZE("rsync://x//y/z/../../m/./n/o", "rsync://x/m/n/o");
+
+       ck_assert_ptr_eq(NULL, url_normalize(""));
+       ck_assert_ptr_eq(NULL, url_normalize("h"));
+       ck_assert_ptr_eq(NULL, url_normalize("http"));
+       ck_assert_ptr_eq(NULL, url_normalize("https"));
+       ck_assert_ptr_eq(NULL, url_normalize("https:"));
+       ck_assert_ptr_eq(NULL, url_normalize("https:/"));
        ck_assert_ptr_eq(NULL, url_normalize("rsync://"));
        ck_assert_ptr_eq(NULL, url_normalize("rsync://."));
+       ck_assert_ptr_eq(NULL, url_normalize("https://./."));
+       ck_assert_ptr_eq(NULL, url_normalize("https://./d"));
        ck_assert_ptr_eq(NULL, url_normalize("rsync://.."));
+       ck_assert_ptr_eq(NULL, url_normalize("rsync://../.."));
+       ck_assert_ptr_eq(NULL, url_normalize("rsync://../d"));
        ck_assert_ptr_eq(NULL, url_normalize("rsync://a.b.c/.."));
+       ck_assert_ptr_eq(NULL, url_normalize("rsync://a.b.c/../.."));
        ck_assert_ptr_eq(NULL, url_normalize("rsync://a.b.c/../x"));
        ck_assert_ptr_eq(NULL, url_normalize("rsync://a.b.c/../x/y/z"));
        ck_assert_ptr_eq(NULL, url_normalize("rsync://a.b.c/d/e/../../.."));
+       ck_assert_ptr_eq(NULL, url_normalize("http://a.b.c/d"));
        ck_assert_ptr_eq(NULL, url_normalize("abcde://a.b.c/d"));
 }
 END_TEST