]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Starting the home stretch, apparently
authorAlberto Leiva Popper <ydahhrk@gmail.com>
Fri, 13 Sep 2024 23:59:18 +0000 (17:59 -0600)
committerAlberto Leiva Popper <ydahhrk@gmail.com>
Fri, 13 Sep 2024 23:59:18 +0000 (17:59 -0600)
Testing. Fixes bugs and TODOs.

31 files changed:
src/asn1/signed_data.c
src/base64.c
src/cache.c
src/cache.h
src/cachent.c
src/cachent.h
src/cert_stack.c
src/cert_stack.h
src/common.c
src/file.c
src/main.c
src/object/certificate.c
src/object/crl.c
src/object/crl.h
src/object/ghostbusters.c
src/object/manifest.c
src/object/roa.c
src/object/tal.c
src/rpp.c
src/rrdp.c
src/rrdp.h
src/thread_var.c
src/types/map.c
src/types/map.h
test/Makefile.am
test/cache_test.c
test/cachent_test.c
test/mock.c
test/object/manifest_test.c
test/object/tal_test.c [moved from test/tal_test.c with 93% similarity]
test/resources/tal/4urls-ignored-protos.tal [new file with mode: 0644]

index 7eb8f7d135a311a96dd2c20d0207f7682bfed60a..05f120b15951b895c2cdbb557d15b3d22de04f4f 100644 (file)
@@ -61,8 +61,6 @@ handle_sdata_certificate(ANY_t *cert_encoded, struct ee_cert *ee,
         * to a tree leaf. Loops aren't possible.
         */
 
-       pr_val_debug("EE Certificate (embedded) {");
-
        /*
         * "If the call is successful *in is incremented to the byte following
         * the parsed data."
@@ -103,14 +101,9 @@ handle_sdata_certificate(ANY_t *cert_encoded, struct ee_cert *ee,
 
        resources_set_policy(ee->res, policy);
        error = certificate_get_resources(cert, ee->res, CERTYPE_EE);
-       if (error)
-               goto end2;
 
-end2:
-       X509_free(cert);
-end1:
-       pr_val_debug("}");
-       return error;
+end2:  X509_free(cert);
+end1:  return error;
 }
 
 /* rfc6488#section-2.1.6.4.1 */
index 25865bffa6280c7b1677fd839139cf5fe4e6e1b5..560a1a5097c1e2f35c54ba8cd7f541abf4600081 100644 (file)
@@ -34,17 +34,21 @@ base64_decode(char *in, size_t in_len, unsigned char **out, size_t *out_len)
 
        status = EVP_DecodeUpdate(ctx, result, &outl, (unsigned char *)in, in_len);
        if (status == -1)
-               return false;
+               goto cancel;
 
        *out_len = outl;
 
        status = EVP_DecodeFinal(ctx, result + outl, &outl);
        if (status != 1)
-               return false;
+               goto cancel;
 
+       EVP_ENCODE_CTX_free(ctx);
        *out = result;
        *out_len += outl;
        return true;
+
+cancel:        EVP_ENCODE_CTX_free(ctx);
+       return false;
 }
 
 /*
index a8bbb2af664b690f9afb2df3404e673cc90867b7..ef15fceb9a305cec78e6a1e00355a1a1b8d3495c 100644 (file)
@@ -165,7 +165,7 @@ init_cachedir_tag(void)
        free(filename);
 }
 
-static void
+static int
 init_tmp_dir(void)
 {
        char *dirname;
@@ -173,19 +173,24 @@ init_tmp_dir(void)
 
        dirname = get_cache_filename(CACHE_TMPDIR, true);
 
-       error = mkdir(dirname, true);
-       if (error != EEXIST)
-               pr_crit("Cannot create %s: %s", dirname, strerror(error));
+       if (mkdir(dirname, 0777) < 0) {
+               error = errno;
+               if (error != EEXIST)
+                       return pr_op_err("Cannot create '%s': %s",
+                           dirname, strerror(error));
+       }
 
        free(dirname);
+       return 0;
 }
 
-void
+int
 cache_setup(void)
 {
        init_cache_metafile();
        init_tmp_dir();
        init_cachedir_tag();
+       return 0;
 }
 
 void
@@ -506,7 +511,7 @@ dl_rsync(struct cache_node *rpp)
                return error;
        }
 
-       module->flags |= CNF_RSYNC | CNF_CACHED | CNF_FRESH;
+       module->flags |= CNF_RSYNC | CNF_CACHED | CNF_FRESH | CNF_FREE_TMPPATH;
        module->mtim = time_nonfatal();
        module->tmppath = tmppath;
 
@@ -543,13 +548,48 @@ dl_http(struct cache_node *node)
                return error;
        }
 
-       node->flags |= CNF_CACHED | CNF_FRESH;
+       node->flags |= CNF_CACHED | CNF_FRESH | CNF_FREE_TMPPATH;
        if (changed)
                node->mtim = mtim;
        node->tmppath = tmppath;
        return 0;
 }
 
+static char *
+get_tmppath(struct cache_node *node)
+{
+       struct cache_node *ancestor;
+       struct path_builder pb;
+       size_t skiplen;
+
+       if (node->tmppath != NULL)
+               return node->tmppath;
+
+       ancestor = node;
+       do {
+               ancestor = ancestor->parent;
+               if (ancestor == NULL)
+                       pr_crit("aaaaa"); // XXX This should never happen, but maybe don't crash anyway
+       } while (ancestor->tmppath == NULL);
+
+       skiplen = strlen(ancestor->path);
+       if (strncmp(ancestor->path, node->path, skiplen) != 0)
+               return NULL; // XXX
+
+       pb_init(&pb);
+       if (pb_append(&pb, ancestor->tmppath) != 0)
+               goto cancel;
+       if (pb_append(&pb, node->path + skiplen) != 0)
+               goto cancel;
+
+       node->flags |= CNF_FREE_TMPPATH;
+       node->tmppath = pb.string;
+       return pb.string;
+
+cancel:        pb_cleanup(&pb);
+       return NULL;
+}
+
 /* @uri is either a caRepository or a rpkiNotify */
 static int
 try_uri(char const *uri, struct cache_node *root,
@@ -581,7 +621,7 @@ try_uri(char const *uri, struct cache_node *root,
        }
 
        map.url = rpp->url;
-       map.path = (download != NULL) ? rpp->tmppath : rpp->path;
+       map.path = (download != NULL) ? get_tmppath(rpp) : rpp->path;
        error = validate(&map, arg);
        if (error) {
                pr_val_debug("RPP validation failed.");
@@ -633,7 +673,7 @@ cache_download_uri(struct strlist *uris, validate_cb cb, void *arg)
        return try_uris(uris, cache.rsync, "rsync://", NULL, cb, arg);
 }
 
-/**
+/*
  * XXX outdated comment
  *
  * Assumes the URIs represent different ways to access the same content.
@@ -734,7 +774,8 @@ commit_rpp_delta(struct cache_node *node)
        node->tmppath = NULL;
        return true;
 
-branch:        node->flags = 0;
+branch:        /* Clean up state flags */
+       node->flags &= ~(CNF_CACHED | CNF_FRESH | CNF_TOUCHED | CNF_VALID);
        if (node->tmppath) {
                free(node->tmppath);
                node->tmppath = NULL;
@@ -745,7 +786,7 @@ branch:     node->flags = 0;
 static int
 rmf(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
 {
-       if (remove(fpath))
+       if (remove(fpath) < 0)
                pr_op_warn("Can't remove %s: %s", fpath, strerror(errno));
        else
                pr_op_debug("Removed %s.", fpath);
@@ -898,7 +939,7 @@ abandoned:
        if (pm)
                cachent_delete(pm);
 unknown:
-       if (remove(path))
+       if (remove(path) < 0)
                PR_DEBUG_MSG("remove(): %s", strerror(errno)); // XXX
        return 0;
 }
@@ -932,6 +973,12 @@ remove_orphaned(struct cache_node *node)
        if (file_exists(node->path) == ENOENT) {
                pr_op_debug("Missing file; deleting node: %s", node->path);
                cachent_delete(node);
+
+               if (node == cache.https)
+                       cache.https = NULL;
+               else if (node == cache.rsync)
+                       cache.rsync = NULL;
+
                return false;
        }
 
index 8fcf64dce9bca1ff69afabb7178abb1a0b7320a6..fdf46a025d7a0074679dcd6b532562903faa4d9d 100644 (file)
@@ -4,12 +4,11 @@
 #include "types/map.h"
 #include "types/str.h"
 
-void cache_setup(void);                /* Init this module */
+int cache_setup(void);         /* Init this module */
 void cache_teardown(void);     /* Destroy this module */
 
 void cache_prepare(void);      /* Prepare cache for new validation cycle */
-void cache_commit(void);       /* Finish successful validation cycle */
-/* XXX Huh. Looks like this could use a cache_rollback() */
+void cache_commit(void);       /* Finish validation cycle */
 
 struct sia_uris {
        char *caRepository;     /* RPP cage */
index af68790b169f6da2bedeca121f2b05e1130d6c93..3f51f822b6f6773e4139f97c6b844ebb9fe445af 100644 (file)
@@ -111,6 +111,7 @@ cachent_find(struct cache_node *root, char const *path, struct cache_node **msm)
        return child;
 }
 
+// XXX path_childn() dup
 static char *
 inherit_path(char const *parent, char const *name, size_t nlen)
 {
@@ -217,6 +218,8 @@ __delete_node(struct cache_node *node)
                free(node->path);
        if (node->flags & CNF_FREE_TMPPATH)
                free(node->tmppath);
+       if (node->flags & CNF_NOTIFICATION)
+               rrdp_notif_cleanup(&node->rrdp);
        free(node);
 
        return valid;
index c67362db937e62c3e2fb26724798fe9a46b21316..63a1c1a98cd25f2e748e0896b63bbf6013b05d3b 100644 (file)
@@ -49,7 +49,6 @@
  */
 #define RSYNC_INHERIT          (CNF_RSYNC | CNF_FRESH)
 
-// XXX rename to cache_entity or cachent
 struct cache_node {
        char *url;              /* rsync://a.b.c/d/e (normalized) */
        char *path;             /* path/to/cache/rsync/a.b.c/d/e */
index 06e5697db877cbd952ad1e6e745006b76227904d..f863ec09c72b7dd457c30c256411f232946cddff 100644 (file)
@@ -15,13 +15,13 @@ enum defer_node_type {
 struct defer_node {
        enum defer_node_type type;
 
-       /**
-        * This field is only relevant if @type == PCT_CERT.
+       /*
+        * This field is only relevant if @type == DNT_CERT.
         * Do not dereference members otherwise.
         */
        struct deferred_cert deferred;
 
-       /** Used by certstack. Points to the next stacked certificate. */
+       /* Used by certstack. Points to the next stacked certificate. */
        SLIST_ENTRY(defer_node) next;
 };
 
@@ -34,9 +34,7 @@ struct serial_number {
 
 STATIC_ARRAY_LIST(serial_numbers, struct serial_number)
 
-/**
- * Cached certificate data.
- */
+/* Cached certificate data */
 struct metadata_node {
        struct cache_mapping map;
        struct resources *resources;
@@ -47,47 +45,31 @@ struct metadata_node {
         */
        struct serial_numbers serials;
 
-       /** Used by certstack. Points to the next stacked certificate. */
+       /* Used by certstack. Points to the next stacked certificate. */
        SLIST_ENTRY(metadata_node) next;
 };
 
-SLIST_HEAD(metadata_stack, metadata_node);
-
-/**
- * This is the foundation through which we pull off our iterative traversal,
- * as opposed to a stack-threatening recursive one.
- *
- * It is a bunch of data that replaces the one that would normally be allocated
- * in the function stack.
- */
+/* Certificates that need to be remembered during a validation cycle. */
 struct cert_stack {
-       /**
-        * Defer stack. Certificates we haven't iterated through yet.
-        *
-        * Every time a certificate validates successfully, its children are
-        * stored here so they can be traversed later.
+       /*
+        * Defer stack; certificates whose validation has been postponed.
+        * (Postponing certificates avoids us recursion and stack overflow.)
         */
        struct defer_stack defers;
 
-       /**
-        * x509 stack. Parents of the certificate we're currently iterating
-        * through.
+       /*
+        * X509 stack. Ancestor certificates of the current certificate.
         * Formatted for immediate libcrypto consumption.
         */
        STACK_OF(X509) *x509s;
 
-       /**
-        * Stacked additional data to each @x509 certificate.
-        *
-        * (These two stacks should always have the same size. The reason why I
-        * don't combine them is because libcrypto's validation function needs
-        * the X509 stack, and I'm not creating it over and over again.)
+       /*
+        * Metadata for each X509. Stuff that doesn't fit in libcrypto's struct.
         *
-        * (This is a SLIST and not a STACK_OF because the OpenSSL stack
-        * implementation is different than the LibreSSL one, and the latter is
-        * seemingly not intended to be used outside of its library.)
+        * (This is a SLIST and not a STACK_OF because the LibreSSL STACK_OF
+        * is seemingly private.)
         */
-       struct metadata_stack metas;
+       SLIST_HEAD(, metadata_node) metas;
 };
 
 int
@@ -111,18 +93,19 @@ certstack_create(struct cert_stack **result)
 }
 
 static void
-defer_destroy(struct defer_node *defer)
+defer_pop(struct cert_stack *stack)
 {
-       switch (defer->type) {
-       case DNT_SEPARATOR:
-               break;
-       case DNT_CERT:
-               free(defer->deferred.map.url);
-               free(defer->deferred.map.path);
+       struct defer_node *defer;
+
+       defer = SLIST_FIRST(&stack->defers);
+       if (defer == NULL)
+               pr_crit("Attempted to pop empty defer stack");
+
+       SLIST_REMOVE_HEAD(&stack->defers, next);
+       if (defer->type == DNT_CERT) {
+               map_cleanup(&defer->deferred.map);
                rpp_refput(defer->deferred.pp);
-               break;
        }
-
        free(defer);
 }
 
@@ -134,10 +117,16 @@ serial_cleanup(struct serial_number *serial)
 }
 
 static void
-meta_destroy(struct metadata_node *meta)
+meta_pop(struct cert_stack *stack)
 {
-       free(meta->map.url);
-       free(meta->map.path);
+       struct metadata_node *meta;
+
+       meta = SLIST_FIRST(&stack->metas);
+       if (meta == NULL)
+               pr_crit("Attempted to pop empty metadata stack");
+
+       SLIST_REMOVE_HEAD(&stack->metas, next);
+       map_cleanup(&meta->map);
        resources_destroy(meta->resources);
        serial_numbers_cleanup(&meta->serials, serial_cleanup);
        free(meta);
@@ -146,30 +135,19 @@ meta_destroy(struct metadata_node *meta)
 void
 certstack_destroy(struct cert_stack *stack)
 {
-       unsigned int stack_size;
-       struct metadata_node *meta;
-       struct defer_node *post;
-
-       stack_size = 0;
-       while (!SLIST_EMPTY(&stack->defers)) {
-               post = SLIST_FIRST(&stack->defers);
-               SLIST_REMOVE_HEAD(&stack->defers, next);
-               defer_destroy(post);
-               stack_size++;
-       }
-       pr_val_debug("Deleted %u deferred certificates.", stack_size);
+       int n;
+
+       for (n = 0; !SLIST_EMPTY(&stack->defers); n++)
+               defer_pop(stack);
+       pr_val_debug("Deleted %d deferred certificates.", n);
 
-       pr_val_debug("Deleting %d stacked x509s.", sk_X509_num(stack->x509s));
+       n = sk_X509_num(stack->x509s);
        sk_X509_pop_free(stack->x509s, X509_free);
+       pr_val_debug("Deleted %d stacked x509s.", n);
 
-       stack_size = 0;
-       while (!SLIST_EMPTY(&stack->metas)) {
-               meta = SLIST_FIRST(&stack->metas);
-               SLIST_REMOVE_HEAD(&stack->metas, next);
-               meta_destroy(meta);
-               stack_size++;
-       }
-       pr_val_debug("Deleted %u metadatas.", stack_size);
+       for (n = 0; !SLIST_EMPTY(&stack->metas); n++)
+               meta_pop(stack);
+       pr_val_debug("Deleted %u metadatas.", n);
 
        free(stack);
 }
@@ -183,7 +161,7 @@ deferstack_push(struct cert_stack *stack, struct cache_mapping *map,
        node = pmalloc(sizeof(struct defer_node));
 
        node->type = DNT_CERT;
-       node->deferred.map = *map; // XXX
+       map_copy(&node->deferred.map, map);
        node->deferred.pp = pp;
        rpp_refget(pp);
        SLIST_INSERT_HEAD(&stack->defers, node, next);
@@ -193,23 +171,16 @@ static void
 x509stack_pop(struct cert_stack *stack)
 {
        X509 *cert;
-       struct metadata_node *meta;
 
        cert = sk_X509_pop(stack->x509s);
        if (cert == NULL)
                pr_crit("Attempted to pop empty X509 stack");
        X509_free(cert);
 
-       meta = SLIST_FIRST(&stack->metas);
-       if (meta == NULL)
-               pr_crit("Attempted to pop empty metadata stack");
-       SLIST_REMOVE_HEAD(&stack->metas, next);
-       meta_destroy(meta);
+       meta_pop(stack);
 }
 
-/**
- * Contract: Returns either 0 or -ENOENT. No other outcomes.
- */
+/* Contract: Returns either 0 or -ENOENT. No other outcomes. */
 int
 deferstack_pop(struct cert_stack *stack, struct deferred_cert *result)
 {
@@ -221,27 +192,17 @@ again:    node = SLIST_FIRST(&stack->defers);
 
        if (node->type == DNT_SEPARATOR) {
                x509stack_pop(stack);
-
-               SLIST_REMOVE_HEAD(&stack->defers, next);
-               defer_destroy(node);
+               defer_pop(stack);
                goto again;
        }
 
        *result = node->deferred;
-//     uri_refget(node->deferred.uri); // XXX
-       rpp_refget(node->deferred.pp);
 
        SLIST_REMOVE_HEAD(&stack->defers, next);
-       defer_destroy(node);
+       free(node);
        return 0;
 }
 
-bool
-deferstack_is_empty(struct cert_stack *stack)
-{
-       return SLIST_EMPTY(&stack->defers);
-}
-
 static int
 init_resources(X509 *x509, enum rpki_policy policy, enum cert_type type,
     struct resources **_result)
@@ -286,7 +247,7 @@ create_separator(void)
        return result;
 }
 
-/** Steals ownership of @x509 on success. */
+/* Steals ownership of @x509 on success. */
 int
 x509stack_push(struct cert_stack *stack, struct cache_mapping *map, X509 *x509,
     enum rpki_policy policy, enum cert_type type)
@@ -298,7 +259,7 @@ x509stack_push(struct cert_stack *stack, struct cache_mapping *map, X509 *x509,
 
        meta = pmalloc(sizeof(struct metadata_node));
 
-       meta->map = *map; // XXX
+       map_copy(&meta->map, map);
        serial_numbers_init(&meta->serials);
 
        error = init_resources(x509, policy, type, &meta->resources);
@@ -330,7 +291,7 @@ cleanup_serial:
        return error;
 }
 
-/**
+/*
  * This one is intended to revert a recent x509 push.
  * Reverts that particular push.
  *
@@ -340,15 +301,8 @@ cleanup_serial:
 void
 x509stack_cancel(struct cert_stack *stack)
 {
-       struct defer_node *defer_separator;
-
        x509stack_pop(stack);
-
-       defer_separator = SLIST_FIRST(&stack->defers);
-       if (defer_separator == NULL)
-               pr_crit("Attempted to pop empty defer stack");
-       SLIST_REMOVE_HEAD(&stack->defers, next);
-       defer_destroy(defer_separator);
+       defer_pop(stack);
 }
 
 X509 *
@@ -357,14 +311,6 @@ x509stack_peek(struct cert_stack *stack)
        return sk_X509_value(stack->x509s, sk_X509_num(stack->x509s) - 1);
 }
 
-/** Does not grab reference. */
-struct cache_mapping *
-x509stack_peek_map(struct cert_stack *stack)
-{
-       struct metadata_node *meta = SLIST_FIRST(&stack->metas);
-       return (meta != NULL) ? &meta->map : NULL;
-}
-
 struct resources *
 x509stack_peek_resources(struct cert_stack *stack)
 {
@@ -384,7 +330,7 @@ get_current_file_name(void)
        return pstrdup(file_name);
 }
 
-/**
+/*
  * Intended to validate serial number uniqueness.
  * "Stores" the serial number in the current relevant certificate metadata,
  * and complains if there's a collision. That's all.
index 7368419ba04db87230ee247af80a09ecc52d6011..5c818aef413cd3d1b35be6ab904ba78fcdf0d71f 100644 (file)
@@ -6,26 +6,6 @@
 #include "object/certificate.h"
 #include "types/name.h"
 
-/*
- * One certificate stack is allocated per validation cycle, and it is used
- * through its entirety to hold the certificates relevant to the ongoing
- * validation.
- *
- * Keep in mind: This module deals with two different (but correlated) stack
- * data structures, and they both store "certificates" (albeit in different
- * representations):
- *
- * - Defer stack: This one stores certificates whose validation has been
- *   postponed during the validation cycle. (They were found in some manifest
- *   list, and haven't been opened yet.)
- *   It prevents us from having to validate the RPKI tree in a recursive manner,
- *   which would be prone to stack overflow.
- * - x509 stack: It is a chain of certificates, ready to be validated by
- *   libcrypto.
- *   For any given certificate being validated, this stack stores all of its
- *   parents.
- */
-
 struct cert_stack;
 
 struct deferred_cert {
@@ -38,18 +18,13 @@ void certstack_destroy(struct cert_stack *);
 
 void deferstack_push(struct cert_stack *, struct cache_mapping *, struct rpp *);
 int deferstack_pop(struct cert_stack *, struct deferred_cert *cert);
-bool deferstack_is_empty(struct cert_stack *);
 
 int x509stack_push(struct cert_stack *, struct cache_mapping *, X509 *,
     enum rpki_policy, enum cert_type);
 void x509stack_cancel(struct cert_stack *);
 X509 *x509stack_peek(struct cert_stack *);
-struct cache_mapping *x509stack_peek_map(struct cert_stack *);
 struct resources *x509stack_peek_resources(struct cert_stack *);
 void x509stack_store_serial(struct cert_stack *, BIGNUM *);
-typedef int (*subject_pk_check_cb)(bool *, char const *, void *);
-int x509stack_store_subject(struct cert_stack *, struct rfc5280_name *,
-    subject_pk_check_cb, void *);
 
 STACK_OF(X509) *certstack_get_x509s(struct cert_stack *);
 int certstack_get_x509_num(struct cert_stack *);
index ace62b54d725d0190f6d1549a1d27a7d64301347..c3c2db7db76417d5f3d84909a1d99971783556ad 100644 (file)
@@ -260,10 +260,10 @@ ensure_dir(char const *path, mode_t mode)
         * path actually refers to a file.
         * So it looks like this stat() is unavoidable.
         */
-       if (stat_dir(path) == ENOTDIR && remove(path))
+       if (stat_dir(path) == ENOTDIR && remove(path) < 0)
                return errno;
 
-       if (mkdir(path, mode)) {
+       if (mkdir(path, mode) < 0) {
                error = errno;
                return (error == EEXIST) ? 0 : error;
        }
@@ -298,7 +298,7 @@ mkdir_p(char const *_path, bool include_basename, mode_t mode)
        }
 
        if (result == ENOTDIR)
-               pr_op_err_st("stack tracing...");
+               pr_op_err_st("stack tracing for '%s'...", path);
 
        for (i = 1; path[i] != '\0'; i++) {
                if (path[i] == '/') {
@@ -334,8 +334,7 @@ delete_dir_recursive_bottom_up(char const *path)
        size_t config_len;
        int error;
 
-       errno = 0;
-       if (remove(path) != 0) {
+       if (remove(path) < 0) {
                error = errno;
                pr_val_err("Couldn't delete '%s': %s", path, strerror(error));
                return error;
index 174a751b1e732b4b4b80f85fbcc0a2a68bda4b72..27e16d12b4de8be436df52078aaf6950e0882e51 100644 (file)
@@ -239,8 +239,7 @@ file_rm_f(char const *path)
 {
        int error;
 
-       errno = 0;
-       if (remove(path) != 0) {
+       if (remove(path) < 0) {
                error = errno;
                if (error != ENOENT)
                        return error;
@@ -253,8 +252,7 @@ static int
 rm(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
 {
        pr_op_debug("Deleting %s.", fpath);
-       errno = 0;
-       return (remove(fpath) != 0) ? errno : 0;
+       return (remove(fpath) < 0) ? errno : 0;
 }
 
 /* Same as `system("rm -rf <path>")`, but more portable and maaaaybe faster. */
index d5ab1b77b85eebced37ea174ff1cbb739b7e2a62..4d63ee81d5ba3bddb4ebacd5e01cf9095b622cc1 100644 (file)
@@ -1,5 +1,6 @@
 #include <errno.h>
 
+#include "cache.h"
 #include "config.h"
 #include "extension.h"
 #include "hash.h"
@@ -75,7 +76,7 @@ fort_server(void)
        return error;
 }
 
-/**
+/*
  * Shells don't like it when we return values other than 0-255.
  * In fact, bash also has its own meanings for 126-255.
  * (See man 1 bash > EXIT STATUS)
@@ -147,6 +148,9 @@ main(int argc, char **argv)
        error = vrps_init();
        if (error)
                goto revert_relax_ng;
+       error = cache_setup();
+       if (error)
+               goto revert_vrps;
 
        /* Meat */
 
@@ -164,6 +168,8 @@ main(int argc, char **argv)
 
        /* End */
 
+       cache_teardown();
+revert_vrps:
        vrps_destroy();
 revert_relax_ng:
        relax_ng_cleanup();
index caeb7337ba06489de0bacab59d7f8e9ec1ac25f0..9a09a8ef8beeb6058c74f27630dcdb6b7782e196 100644 (file)
@@ -211,7 +211,7 @@ validate_subject(X509 *cert)
 static X509_PUBKEY *
 decode_spki(struct tal *tal)
 {
-       X509_PUBKEY *spki = NULL;
+       X509_PUBKEY *spki;
        unsigned char const *origin, *cursor;
        size_t len;
 
@@ -548,9 +548,7 @@ struct progress {
        size_t remaining;
 };
 
-/**
- * Skip the "T" part of a TLV.
- */
+/* Skip the "T" part of a TLV. */
 static int
 skip_t(ANY_t *content, struct progress *p, unsigned int tag)
 {
@@ -567,9 +565,7 @@ skip_t(ANY_t *content, struct progress *p, unsigned int tag)
        return 0;
 }
 
-/**
- * Skip the "TL" part of a TLV.
- */
+/* Skip the "TL" part of a TLV. */
 static int
 skip_tl(ANY_t *content, struct progress *p, unsigned int tag)
 {
@@ -614,9 +610,7 @@ skip_tlv(ANY_t *content, struct progress *p, unsigned int tag)
        return 0;
 }
 
-/**
- * A structure that points to the LV part of a signedAttrs TLV.
- */
+/* A structure that points to the LV part of a signedAttrs TLV. */
 struct encoded_signedAttrs {
        const uint8_t *buffer;
        ber_tlv_len_t size;
@@ -1150,11 +1144,9 @@ __certificate_get_resources(X509 *cert, struct resources *resources,
                        if (!X509_EXTENSION_get_critical(ext))
                                return pr_val_err("The IP extension is not marked as critical.");
 
-                       pr_val_debug("IP {");
-                       error = handle_ip_extension(ext, resources);
-                       pr_val_debug("}");
                        ip_ext_found = true;
 
+                       error = handle_ip_extension(ext, resources);
                        if (error)
                                return error;
 
@@ -1164,12 +1156,10 @@ __certificate_get_resources(X509 *cert, struct resources *resources,
                        if (!X509_EXTENSION_get_critical(ext))
                                return pr_val_err("The AS extension is not marked as critical.");
 
-                       pr_val_debug("ASN {");
-                       error = handle_asn_extension(ext, resources,
-                           allow_asn_inherit);
-                       pr_val_debug("}");
                        asn_ext_found = true;
 
+                       error = handle_asn_extension(ext, resources,
+                           allow_asn_inherit);
                        if (error)
                                return error;
 
@@ -1188,9 +1178,7 @@ __certificate_get_resources(X509 *cert, struct resources *resources,
        return 0;
 }
 
-/**
- * Copies the resources from @cert to @resources.
- */
+/* Copies the resources from @cert to @resources. */
 int
 certificate_get_resources(X509 *cert, struct resources *resources,
     enum cert_type type)
@@ -1528,7 +1516,7 @@ ad2uri(char **uri, ACCESS_DESCRIPTION *ad)
        return 0;
 }
 
-/**
+/*
  * The RFC does not explain AD validation very well. This is personal
  * interpretation, influenced by Tim Bruijnzeels's response
  * (https://mailarchive.ietf.org/arch/msg/sidr/4ycmff9jEU4VU9gGK5RyhZ7JYsQ)
@@ -1691,9 +1679,7 @@ handle_cp(void *ext, void *arg)
        return 0;
 }
 
-/**
- * Validates the certificate extensions, Trust Anchor style.
- */
+/* Validates the certificate extensions, Trust Anchor style. */
 static int
 certificate_validate_extensions_ta(X509 *cert, struct sia_uris *sia_uris,
     enum rpki_policy *policy)
@@ -1717,7 +1703,7 @@ certificate_validate_extensions_ta(X509 *cert, struct sia_uris *sia_uris,
        return handle_extensions(handlers, X509_get0_extensions(cert));
 }
 
-/**
+/*
  * Validates the certificate extensions, (intermediate) Certificate Authority
  * style.
  *
@@ -1880,13 +1866,12 @@ end:    free(mft.path);
        return error;
 }
 
-/** Boilerplate code for CA certificate validation and recursive traversal. */
+/* Boilerplate code for CA certificate validation and recursive traversal. */
 int
 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 *x509;
        struct sia_uris sia_uris;
        enum rpki_policy policy;
@@ -1899,26 +1884,13 @@ certificate_traverse(struct rpp *rpp_parent, struct cache_mapping *cert_map)
        if (total_parents >= config_get_max_cert_depth())
                return pr_val_err("Certificate chain maximum depth exceeded.");
 
-       /* Debug cert type */
-       if (rpp_parent == NULL)
-               pr_val_debug("TA Certificate '%s' {",
-                   map_val_get_printable(cert_map));
-       else
-               pr_val_debug("Certificate '%s' {",
-                   map_val_get_printable(cert_map));
        fnstack_push_map(cert_map);
 
-       rpp_parent_crl = rpp_crl(rpp_parent);
-       if (rpp_parent_crl == NULL) {
-               error = -EINVAL;
-               goto revert_fnstack_and_debug;
-       }
-
        /* -- Validate the certificate (@cert) -- */
        error = certificate_load(cert_map, &x509);
        if (error)
                goto revert_fnstack_and_debug;
-       error = certificate_validate_chain(x509, rpp_parent_crl);
+       error = certificate_validate_chain(x509, rpp_crl(rpp_parent));
        if (error)
                goto revert_cert;
 
@@ -1972,6 +1944,5 @@ revert_cert:
                X509_free(x509);
 revert_fnstack_and_debug:
        fnstack_pop();
-       pr_val_debug("}");
        return error;
 }
index 39a0e717781ace973d5a894ce0800f0bc2fad409..3339aecfd1bac40941b8a099f81821e94d84370e 100644 (file)
@@ -7,6 +7,7 @@
 #include "algorithm.h"
 #include "extension.h"
 #include "log.h"
+#include "thread_var.h"
 #include "types/name.h"
 
 static int
@@ -20,13 +21,13 @@ __crl_load(char const *path, X509_CRL **result)
        if (bio == NULL)
                return val_crypto_err("BIO_new(BIO_s_file()) returned NULL");
        if (BIO_read_filename(bio, path) <= 0) {
-               error = val_crypto_err("Error reading CRL '%s'", path);
+               error = val_crypto_err("Error reading CRL");
                goto end;
        }
 
        crl = d2i_X509_CRL_bio(bio, NULL);
        if (crl == NULL) {
-               error = val_crypto_err("Error parsing CRL '%s'", path);
+               error = val_crypto_err("Error parsing CRL");
                goto end;
        }
 
@@ -163,15 +164,14 @@ crl_validate(X509_CRL *crl)
        return validate_extensions(crl);
 }
 
-/* XXX I suspect this should receive the map */
 int
-crl_load(char const *path, X509_CRL **result)
+crl_load(struct cache_mapping *map, X509_CRL **result)
 {
        int error;
 
-       pr_val_debug("CRL '%s' {", path);
+       fnstack_push_map(map);
 
-       error = __crl_load(path, result);
+       error = __crl_load(map->path, result);
        if (error)
                goto end;
 
@@ -179,7 +179,6 @@ crl_load(char const *path, X509_CRL **result)
        if (error)
                X509_CRL_free(*result);
 
-end:
-       pr_val_debug("}");
+end:   fnstack_pop();
        return error;
 }
index aecffed4ea2caff16e7632289ea0e67a776b0fe5..59006ba04a525fb48f7c3b22b89b2cd195824ac5 100644 (file)
@@ -2,7 +2,8 @@
 #define SRC_OBJECT_CRL_H_
 
 #include <openssl/x509.h>
+#include "types/map.h"
 
-int crl_load(char const *, X509_CRL **);
+int crl_load(struct cache_mapping *, X509_CRL **);
 
 #endif /* SRC_OBJECT_CRL_H_ */
index 833438d412ca7d4082d6e1975718452d38f21255..7f5bf217ca02fe3e453498489d54cbb727efd3e8 100644 (file)
@@ -26,7 +26,6 @@ ghostbusters_traverse(struct cache_mapping *map, struct rpp *pp)
        int error;
 
        /* Prepare */
-       pr_val_debug("Ghostbusters '%s' {", map_val_get_printable(map));
        fnstack_push_map(map);
 
        /* Decode */
@@ -56,7 +55,6 @@ revert_args:
 revert_sobj:
        signed_object_cleanup(&sobj);
 revert_log:
-       pr_val_debug("}");
        fnstack_pop();
        return error;
 }
index 44abf09e81abd1f66ae5a008e96c1f61c797636e..644ec256bf2b8a7a84a12c7ff52c34460ea10793 100644 (file)
@@ -276,11 +276,11 @@ build_rpp(struct cache_mapping *mft_map, struct Manifest *mft,
 
                error = check_file_and_hash(fah, map.path);
                if (error)
-                       goto fail;
+                       goto fail2;
 
                error = rpp_add_file(pp, &map);
                if (error)
-                       goto fail;
+                       goto fail2;
        }
 
        /* rfc6486#section-7 */
@@ -293,6 +293,7 @@ build_rpp(struct cache_mapping *mft_map, struct Manifest *mft,
        *result = pp;
        return 0;
 
+fail2: map_cleanup(&map);
 fail:  map_cleanup(&pp_map);
        rpp_refput(pp);
        return error;
@@ -311,7 +312,6 @@ handle_manifest(struct cache_mapping *map, struct rpp **pp)
        int error;
 
        /* Prepare */
-       pr_val_debug("Manifest '%s' {", map_val_get_printable(map));
        fnstack_push_map(map);
 
        /* Decode */
@@ -359,7 +359,6 @@ revert_manifest:
 revert_sobj:
        signed_object_cleanup(&sobj);
 revert_log:
-       pr_val_debug("}");
        fnstack_pop();
        return error;
 }
index 5074467d8671d7c5821ea92816e02be1464e3a48..c45f614e9926a89281d81623c89741478154edaf 100644 (file)
@@ -29,7 +29,6 @@ ____handle_roa_v4(struct resources *parent, unsigned long asn,
        if (error)
                return error;
 
-       pr_val_debug("ROAIPAddress {");
        pr_val_debug("address: %s/%u", v4addr2str(&prefix.addr), prefix.len);
 
        if (roa_addr->maxLength != NULL) {
@@ -39,21 +38,18 @@ ____handle_roa_v4(struct resources *parent, unsigned long asn,
                                pr_val_err("Error casting ROA's IPv4 maxLength: %s",
                                    strerror(errno));
                        }
-                       error = pr_val_err("The ROA's IPv4 maxLength isn't a valid unsigned long");
-                       goto end_error;
+                       return pr_val_err("The ROA's IPv4 maxLength isn't a valid unsigned long");
                }
                pr_val_debug("maxLength: %lu", max_length);
 
                if (max_length > 32) {
-                       error = pr_val_err("maxLength (%lu) is out of bounds (0-32).",
+                       return pr_val_err("maxLength (%lu) is out of bounds (0-32).",
                            max_length);
-                       goto end_error;
                }
 
                if (prefix.len > max_length) {
-                       error = pr_val_err("Prefix length (%u) > maxLength (%lu)",
+                       return pr_val_err("Prefix length (%u) > maxLength (%lu)",
                            prefix.len, max_length);
-                       goto end_error;
                }
 
        } else {
@@ -61,16 +57,11 @@ ____handle_roa_v4(struct resources *parent, unsigned long asn,
        }
 
        if (!resources_contains_ipv4(parent, &prefix)) {
-               error = pr_val_err("ROA is not allowed to advertise %s/%u.",
+               return pr_val_err("ROA is not allowed to advertise %s/%u.",
                    v4addr2str(&prefix.addr), prefix.len);
-               goto end_error;
        }
 
-       pr_val_debug("}");
        return vhandler_handle_roa_v4(asn, &prefix, max_length);
-end_error:
-       pr_val_debug("}");
-       return error;
 }
 
 static int
@@ -85,7 +76,6 @@ ____handle_roa_v6(struct resources *parent, unsigned long asn,
        if (error)
                return error;
 
-       pr_val_debug("ROAIPAddress {");
        pr_val_debug("address: %s/%u", v6addr2str(&prefix.addr), prefix.len);
 
        if (roa_addr->maxLength != NULL) {
@@ -95,21 +85,18 @@ ____handle_roa_v6(struct resources *parent, unsigned long asn,
                                pr_val_err("Error casting ROA's IPv6 maxLength: %s",
                                    strerror(errno));
                        }
-                       error = pr_val_err("The ROA's IPv6 maxLength isn't a valid unsigned long");
-                       goto end_error;
+                       return pr_val_err("The ROA's IPv6 maxLength isn't a valid unsigned long");
                }
                pr_val_debug("maxLength: %lu", max_length);
 
                if (max_length > 128) {
-                       error = pr_val_err("maxLength (%lu) is out of bounds (0-128).",
+                       return pr_val_err("maxLength (%lu) is out of bounds (0-128).",
                            max_length);
-                       goto end_error;
                }
 
                if (prefix.len > max_length) {
-                       error = pr_val_err("Prefix length (%u) > maxLength (%lu)",
+                       return pr_val_err("Prefix length (%u) > maxLength (%lu)",
                            prefix.len, max_length);
-                       goto end_error;
                }
 
        } else {
@@ -117,16 +104,11 @@ ____handle_roa_v6(struct resources *parent, unsigned long asn,
        }
 
        if (!resources_contains_ipv6(parent, &prefix)) {
-               error = pr_val_err("ROA is not allowed to advertise %s/%u.",
+               return pr_val_err("ROA is not allowed to advertise %s/%u.",
                    v6addr2str(&prefix.addr), prefix.len);
-               goto end_error;
        }
 
-       pr_val_debug("}");
        return vhandler_handle_roa_v6(asn, &prefix, max_length);
-end_error:
-       pr_val_debug("}");
-       return error;
 }
 
 static int
@@ -153,7 +135,6 @@ __handle_roa(struct RouteOriginAttestation *roa, struct resources *parent)
        int a;
        int error;
 
-       pr_val_debug("eContent {");
        if (roa->version != NULL) {
                error = asn_INTEGER2ulong(roa->version, &version);
                if (error) {
@@ -161,14 +142,12 @@ __handle_roa(struct RouteOriginAttestation *roa, struct resources *parent)
                                pr_val_err("Error casting ROA's version: %s",
                                    strerror(errno));
                        }
-                       error = pr_val_err("The ROA's version isn't a valid long");
-                       goto end_error;
+                       return pr_val_err("The ROA's version isn't a valid long");
                }
                /* rfc6482#section-3.1 */
                if (version != 0) {
-                       error = pr_val_err("ROA's version (%lu) is nonzero.",
+                       return pr_val_err("ROA's version (%lu) is nonzero.",
                            version);
-                       goto end_error;
                }
        }
 
@@ -178,70 +157,46 @@ __handle_roa(struct RouteOriginAttestation *roa, struct resources *parent)
                        pr_val_err("Error casting ROA's AS ID value: %s",
                            strerror(errno));
                }
-               error = pr_val_err("ROA's AS ID couldn't be parsed as unsigned long");
-               goto end_error;
+               return pr_val_err("ROA's AS ID couldn't be parsed as unsigned long");
        }
 
-       if (asn > UINT32_MAX) {
-               error = pr_val_err("AS value (%lu) is out of range.", asn);
-               goto end_error;
-       }
-       pr_val_debug("asId: %lu", asn);
+       if (asn > UINT32_MAX)
+               return pr_val_err("AS value (%lu) is out of range.", asn);
 
        /* rfc6482#section-3.3 */
 
-       if (roa->ipAddrBlocks.list.array == NULL) {
-               error = pr_val_err("ipAddrBlocks array is NULL.");
-               goto end_error;
-       }
+       if (roa->ipAddrBlocks.list.array == NULL)
+               return pr_val_err("ipAddrBlocks array is NULL.");
 
-       pr_val_debug("ipAddrBlocks {");
        for (b = 0; b < roa->ipAddrBlocks.list.count; b++) {
                block = roa->ipAddrBlocks.list.array[b];
-               if (block == NULL) {
-                       error = pr_val_err("Address block array element is NULL.");
-                       goto ip_error;
-               }
+               if (block == NULL)
+                       return pr_val_err("Address block array element is NULL.");
 
                if (block->addressFamily.size != 2)
                        goto family_error;
                if (block->addressFamily.buf[0] != 0)
                        goto family_error;
-               if (block->addressFamily.buf[1] != 1
-                   && block->addressFamily.buf[1] != 2)
+               if (block->addressFamily.buf[1] != 1 &&
+                   block->addressFamily.buf[1] != 2)
                        goto family_error;
-               pr_val_debug("%s {",
-                   block->addressFamily.buf[1] == 1 ? "v4" : "v6");
 
-               if (block->addresses.list.array == NULL) {
-                       error = pr_val_err("ROA's address list array is NULL.");
-                       pr_val_debug("}");
-                       goto ip_error;
-               }
+               if (block->addresses.list.array == NULL)
+                       return pr_val_err("ROA's address list array is NULL.");
 
                for (a = 0; a < block->addresses.list.count; a++) {
                        error = ____handle_roa(parent, asn,
                            block->addressFamily.buf[1],
                            block->addresses.list.array[a]);
-                       if (error) {
-                               pr_val_debug("}");
-                               goto ip_error;
-                       }
+                       if (error)
+                               return error;
                }
-               pr_val_debug("}");
        }
 
-       /* Error 0 it's ok */
-       error = 0;
-       goto ip_error;
+       return 0;
 
 family_error:
-       error = pr_val_err("ROA's IP family is not v4 or v6.");
-ip_error:
-       pr_val_debug("}");
-end_error:
-       pr_val_debug("}");
-       return error;
+       return pr_val_err("ROA's IP family is not v4 or v6.");
 }
 
 int
@@ -256,7 +211,6 @@ roa_traverse(struct cache_mapping *map, struct rpp *pp)
        int error;
 
        /* Prepare */
-       pr_val_debug("ROA '%s' {", map_val_get_printable(map));
        fnstack_push_map(map);
 
        /* Decode */
@@ -292,6 +246,5 @@ revert_sobj:
        signed_object_cleanup(&sobj);
 revert_log:
        fnstack_pop();
-       pr_val_debug("}");
        return error;
 }
index 4a4e07f05447b3150729beccdbe2edb03a9a5285..02af11a0f279c0c5d499c48435207bea5a8ae2ef 100644 (file)
@@ -83,8 +83,9 @@ read_content(char *fc /* File Content */, struct tal *tal)
                if (is_blank(fc))
                        break;
 
-               // XXX no longer validating schema
-               strlist_add(&tal->urls, pstrdup(fc));
+               if (str_starts_with(fc, "https://") ||
+                   str_starts_with(fc, "rsync://"))
+                       strlist_add(&tal->urls, pstrdup(fc));
 
                fc = nl + cr + 1;
                if (*fc == '\0')
@@ -105,9 +106,7 @@ premature:
        return pr_op_err("The TAL seems to end prematurely at line '%s'.", fc);
 }
 
-/**
- * @file_name is expected to outlive the result.
- */
+/* @file_path is expected to outlive @tal. */
 static int
 tal_init(struct tal *tal, char const *file_path)
 {
@@ -152,7 +151,7 @@ tal_get_spki(struct tal *tal, unsigned char const **buffer, size_t *len)
        *len = tal->spki_len;
 }
 
-/**
+/*
  * Performs the whole validation walkthrough that starts with Trust Anchor @ta,
  * which is assumed to have been extracted from TAL @arg->tal.
  */
@@ -166,8 +165,6 @@ handle_ta(struct cache_mapping *ta, void *arg)
        struct deferred_cert deferred;
        int error;
 
-       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;
@@ -178,8 +175,7 @@ handle_ta(struct cache_mapping *ta, void *arg)
                return ENSURE_NEGATIVE(error);
 
        if (!str_ends_with(ta->url, ".cer")) {
-               pr_op_err("TAL URI does not point to a certificate. (Expected .cer, got '%s')",
-                   ta->url);
+               pr_op_err("TAL URI lacks '.cer' extension: %s", ta->url);
                error = EINVAL;
                goto end;
        }
@@ -208,8 +204,6 @@ handle_ta(struct cache_mapping *ta, void *arg)
 
        /* Handle every other certificate. */
        certstack = validation_certstack(state);
-       if (certstack == NULL)
-               pr_crit("Validation state has no certificate stack");
 
        do {
                error = deferstack_pop(certstack, &deferred);
@@ -229,7 +223,6 @@ handle_ta(struct cache_mapping *ta, void *arg)
        } while (true);
 
 end:   validation_destroy(state);
-       pr_val_debug("}");
        return error;
 }
 
@@ -252,8 +245,7 @@ do_file_validation(void *arg)
        args.db = db_table_create();
        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);
+               pr_op_err("None of the TAL URIs yielded a successful traversal.");
                db_table_destroy(args.db);
        } else {
                thread->db = args.db;
@@ -312,7 +304,7 @@ perform_standalone_validation(void)
        int error = 0;
        int tmperr;
 
-       cache_setup();
+       cache_prepare();
 
        /* TODO (fine) Maybe don't spawn threads if there's only one TAL */
        if (foreach_file(config_get_tal(), ".tal", true, spawn_tal_thread,
@@ -322,7 +314,12 @@ perform_standalone_validation(void)
                        SLIST_REMOVE_HEAD(&threads, next);
                        thread_destroy(thread);
                }
-               return NULL;
+
+               /*
+                * Commit even on failure, as there's no reason to throw away
+                * something we recently downloaded if it's marked as valid.
+                */
+               goto end;
        }
 
        /* Wait for all */
@@ -330,13 +327,14 @@ perform_standalone_validation(void)
                thread = SLIST_FIRST(&threads);
                tmperr = pthread_join(thread->pid, NULL);
                if (tmperr)
-                       pr_crit("pthread_join() threw %d (%s) on the '%s' thread.",
-                           tmperr, strerror(tmperr), thread->tal_file);
+                       pr_crit("pthread_join() threw '%s' on the '%s' thread.",
+                           strerror(tmperr), thread->tal_file);
                SLIST_REMOVE_HEAD(&threads, next);
                if (thread->error) {
                        error = thread->error;
-                       pr_op_warn("Validation from TAL '%s' yielded error %d (%s); discarding all validation results.",
-                           thread->tal_file, error, strerror(abs(error)));
+                       pr_op_warn("Validation from TAL '%s' yielded '%s'; "
+                           "discarding all validation results.",
+                           thread->tal_file, strerror(abs(error)));
                }
 
                if (!error) {
@@ -351,13 +349,12 @@ perform_standalone_validation(void)
                thread_destroy(thread);
        }
 
-       cache_teardown();
-
-       /* If one thread has errors, we can't keep the resulting table. */
+       /* If at least one thread had a fatal error, the table is unusable. */
        if (error) {
                db_table_destroy(db);
                db = NULL;
        }
 
+end:   cache_commit();
        return db;
 }
index 72ab988c0b7caa7a435715ec1160b8c4b812db70..c3e75f945ad2476998357c785718b0b6d44233a3 100644 (file)
--- a/src/rpp.c
+++ b/src/rpp.c
@@ -65,7 +65,7 @@ set_crl(struct rpp *pp, struct cache_mapping *map)
        if (pp->crl.stack != NULL)
                return pr_val_err("Repository Publication Point has more than one CRL.");
 
-       error = crl_load(map->path, &crl);
+       error = crl_load(map, &crl);
        if (error)
                return error;
 
@@ -87,7 +87,7 @@ set_crl(struct rpp *pp, struct cache_mapping *map)
 int
 rpp_add_file(struct rpp *pp, struct cache_mapping *map)
 {
-       if (str_ends_with(map->url, ".crl") == 0)
+       if (str_ends_with(map->url, ".crl"))
                return set_crl(pp, map);
 
        filelist_add(&pp->files, map);
@@ -107,7 +107,7 @@ rpp_get_crl_url(struct rpp const *pp)
 STACK_OF(X509_CRL) *
 rpp_crl(struct rpp *pp)
 {
-       return pp->crl.stack;
+       return (pp != NULL) ? pp->crl.stack : NULL;
 }
 
 /* Traverses through all of @pp's known files, validating them. */
index 2f172971b29d0ed9a17285d7867bcf2633bab638..5723a1519c5b4d2c8c9bf7fcb923cb2d812079e5 100644 (file)
@@ -101,8 +101,8 @@ session_cleanup(struct rrdp_session *meta)
 static void
 metadata_cleanup(struct file_metadata *meta)
 {
-       free(meta->hash);
        free(meta->uri);
+       free(meta->hash);
 }
 
 static void
@@ -867,7 +867,7 @@ handle_snapshot(struct update_notification *new, struct cache_node *notif)
        if (error)
                goto end2;
        error = parse_snapshot(&new->session, tmppath, notif);
-       delete_file(tmppath);
+//     delete_file(tmppath); XXX
 
 end2:  free(tmppath);
 end1:  fnstack_pop();
@@ -938,7 +938,7 @@ handle_delta(struct update_notification *notif,
        if (error)
                goto end;
        error = parse_delta(notif, delta, tmppath, notif_node);
-       delete_file(tmppath);
+//     delete_file(tmppath); XXX
 
        free(tmppath);
 end:   fnstack_pop();
@@ -1112,19 +1112,22 @@ dl_notif(struct cache_node *notif, struct update_notification *new)
        if (notif->dlerr)
                goto end;
 
-       if (remove(tmppath) == -1) {
-               notif->dlerr = errno;
-               pr_val_err("Can't remove notification's temporal file: %s",
-                  strerror(notif->dlerr));
-               goto end;
-       }
-       if (mkdir(tmppath, 0777) == -1) {
-               notif->dlerr = errno;
-               pr_val_err("Can't create notification's temporal directory: %s",
-                   strerror(notif->dlerr));
-               goto end;
-       }
-
+//     if (remove(tmppath) < 0) {
+//             notif->dlerr = errno;
+//             pr_val_err("Can't remove notification's temporal file: %s",
+//                strerror(notif->dlerr));
+//             update_notification_cleanup(new);
+//             goto end;
+//     }
+//     if (mkdir(tmppath, 0777) < 0) {
+//             notif->dlerr = errno;
+//             pr_val_err("Can't create notification's temporal directory: %s",
+//                 strerror(notif->dlerr));
+//             update_notification_cleanup(new);
+//             goto end;
+//     }
+
+       notif->flags |= CNF_FREE_TMPPATH;
        notif->tmppath = tmppath;
        return true;
 
@@ -1407,12 +1410,18 @@ revert_notif:
 }
 
 void
-rrdp_notif_free(struct cachefile_notification *notif)
+rrdp_notif_cleanup(struct cachefile_notification *notif)
 {
-       if (notif == NULL)
-               return;
-
        session_cleanup(&notif->session);
+       cachent_delete(notif->subtree);
        clear_delta_hashes(notif);
-       free(notif);
+}
+
+void
+rrdp_notif_free(struct cachefile_notification *notif)
+{
+       if (notif != NULL) {
+               rrdp_notif_cleanup(notif);
+               free(notif);
+       }
 }
index d88a5b0aea7677a754f3f8689966b0301c4cdd98..984811a2118e4f7e25f7b5c82d623f737b80b754 100644 (file)
@@ -46,6 +46,7 @@ int rrdp_update(struct cache_node *);
 json_t *rrdp_notif2json(struct cachefile_notification *);
 int rrdp_json2notif(json_t *, struct cachefile_notification **);
 
+void rrdp_notif_cleanup(struct cachefile_notification *);
 void rrdp_notif_free(struct cachefile_notification *);
 
 #endif /* SRC_RRDP_H_ */
index b9a1b681954ed8fb3e2add14979e9034677fc34a..13d5ec5fcc97856d8fa40b1765a84d6334fbe533 100644 (file)
@@ -112,7 +112,7 @@ fnstack_cleanup(void)
                pr_op_err("pthread_setspecific() returned %d.", error);
 }
 
-/**
+/*
  * Call this function every time you're about to start processing a new file.
  * Any pr_op_err()s and friends will now include the new file name.
  * Use fnstack_pop() to revert back to the previously stacked file name.
@@ -156,12 +156,7 @@ fnstack_push(char const *file)
        files->filenames[files->len++] = file;
 }
 
-/**
- * See fnstack_push().
- *
- * This function cannot claim a reference for @map, so @map will have to outlive
- * the push/pop.
- */
+/* See fnstack_push(). @map needs to outlive the push/pop. */
 void
 fnstack_push_map(struct cache_mapping *map)
 {
@@ -201,7 +196,7 @@ addr2str(int af, void const *addr, char *(*buffer_cb)(struct validation *))
        return inet_ntop(af, addr, buffer_cb(state), INET6_ADDRSTRLEN);
 }
 
-/**
+/*
  * Returns @addr, converted to a printable string. Intended for minimal clutter
  * address printing.
  *
@@ -217,27 +212,21 @@ v4addr2str(struct in_addr const *addr)
        return addr2str(AF_INET, addr, validation_get_ip_buffer1);
 }
 
-/**
- * Same as v4addr2str(), except a different buffer is used.
- */
+/* Same as v4addr2str(), except a different buffer is used. */
 char const *
 v4addr2str2(struct in_addr const *addr)
 {
        return addr2str(AF_INET, addr, validation_get_ip_buffer2);
 }
 
-/**
- * See v4addr2str().
- */
+/* See v4addr2str(). */
 char const *
 v6addr2str(struct in6_addr const *addr)
 {
        return addr2str(AF_INET6, addr, validation_get_ip_buffer1);
 }
 
-/**
- * See v4addr2str2().
- */
+/* See v4addr2str2(). */
 char const *
 v6addr2str2(struct in6_addr const *addr)
 {
index d23484e667b269332c2eeacda01f0f71c2e786cf..3f0ea814aaf973ea44a797b8e8625464230c995c 100644 (file)
@@ -59,6 +59,13 @@ map_child(struct cache_mapping *parent, char const *name)
        return child;
 }
 
+void
+map_copy(struct cache_mapping *dst, struct cache_mapping *src)
+{
+       dst->url = pstrdup(src->url);
+       dst->path = pstrdup(src->path);
+}
+
 void
 map_cleanup(struct cache_mapping *map)
 {
index e678fa5b91cd1b9754414c6049747b011139a5a9..c35b27ff2adadff015f375a258600c97b375c3eb 100644 (file)
@@ -15,6 +15,7 @@ char const *map_op_get_printable(struct cache_mapping *);
 void map_parent(struct cache_mapping *, struct cache_mapping *);
 struct cache_mapping *map_child(struct cache_mapping *, char const *);
 
+void map_copy(struct cache_mapping *, struct cache_mapping *);
 void map_cleanup(struct cache_mapping *);
 
 #endif /* SRC_TYPES_MAP_H_ */
index cf83642095454ab2c17db805214f0502026cec97..54a04640f33750eb7491d09decce907e19e49315 100644 (file)
@@ -96,7 +96,7 @@ rsync_test_LDADD = ${MY_LDADD}
 serial_test_SOURCES = types/serial_test.c
 serial_test_LDADD = ${MY_LDADD}
 
-tal_test_SOURCES = tal_test.c
+tal_test_SOURCES = object/tal_test.c
 tal_test_LDADD = ${MY_LDADD}
 
 thread_pool_test_SOURCES = thread_pool_test.c
index 21fdfda96797aba2cc32b7e2d1dc9f9dfa3fa90c..232f1375f87d18782845e1e6acf4818c6fb011ed 100644 (file)
@@ -40,6 +40,7 @@ rsync_download(char const *src, char const *dst, char const *cmpdir)
 
 MOCK_ABORT_INT(rrdp_update, struct cache_node *notif)
 __MOCK_ABORT(rrdp_notif2json, json_t *, NULL, struct cachefile_notification *notif)
+MOCK_ABORT_VOID(rrdp_notif_cleanup, struct cachefile_notification *notif)
 MOCK_VOID(rrdp_notif_free, struct cachefile_notification *notif)
 MOCK_ABORT_INT(rrdp_json2notif, json_t *json, struct cachefile_notification **result)
 MOCK_VOID(__delete_node_cb, struct cache_node const *node)
index 1f821d3375177d920d5d39f6d458cfa5dc91d421..3d37166037df2c3d8ab90bdbe4185829d07521b3 100644 (file)
@@ -10,6 +10,8 @@
 static char deleted[16][6];
 static unsigned int dn;
 
+MOCK_ABORT_VOID(rrdp_notif_cleanup, struct cachefile_notification *notif)
+
 static void
 __delete_node_cb(struct cache_node const *node)
 {
index e3e871742792a05dfc922f08f5f1a0d401936132..44c707367150761b54c4c595c69e42deca8428b1 100644 (file)
@@ -7,9 +7,7 @@
 #include "state.h"
 #include "thread_var.h"
 
-/**
- * Some core functions, as linked from unit tests.
- */
+/* Some core functions, as linked from unit tests. */
 
 MOCK_TRUE(log_val_enabled, unsigned int l)
 MOCK_TRUE(log_op_enabled, unsigned int l)
@@ -123,6 +121,8 @@ 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_init, void)
 MOCK_VOID(fnstack_push, char const *file)
 MOCK_VOID(fnstack_push_map, struct cache_mapping *map)
 MOCK_VOID(fnstack_pop, void)
+MOCK_VOID(fnstack_cleanup, void)
index 823efdcdf3e365efd135fc637be5d943448060c1..a73b86f8b6aecc450c855a0f55eddd1f1e0e510b 100644 (file)
@@ -10,6 +10,7 @@
 #include "types/path.c"
 #include "types/url.c"
 
+MOCK_ABORT_VOID(rrdp_notif_cleanup, struct cachefile_notification *notif)
 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)
similarity index 93%
rename from test/tal_test.c
rename to test/object/tal_test.c
index a64ac582eb42bd76473fa13fbd35454657c71589..bf11db66f3f0d92f2b5aaabd72f940d5d488f899 100644 (file)
 
 /* Mocks */
 
-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_alt, struct sia_uris *sias,
-    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,
-    struct cache_mapping *cert_map)
+MOCK_ABORT_VOID(cache_prepare, void)
+MOCK_ABORT_VOID(cache_commit, void)
 MOCK_ABORT_PTR(db_table_create, db_table, void)
 MOCK_VOID(db_table_destroy, struct db_table *table)
 MOCK_ABORT_INT(db_table_join, struct db_table *dst, struct db_table *src)
@@ -129,6 +122,7 @@ START_TEST(test_tal_load_4urls)
        test_4urls("resources/tal/4urls-crlf.tal");
        test_4urls("resources/tal/4urls-lf-comment.tal");
        test_4urls("resources/tal/4urls-lf-comment-utf8.tal");
+       test_4urls("resources/tal/4urls-ignored-protos.tal");
 }
 END_TEST
 
diff --git a/test/resources/tal/4urls-ignored-protos.tal b/test/resources/tal/4urls-ignored-protos.tal
new file mode 100644 (file)
index 0000000..eb7122b
--- /dev/null
@@ -0,0 +1,14 @@
+rsync://example.com/rpki/ta.cer
+https://example.com/rpki/ta.cer
+ftp://example.com/rpki/ta.cer
+rsync://www.example.com/potato/ta.cer
+http://example.com/rpki/ta.cer
+https://wx3.example.com/tomato/ta.cer
+
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqZEzhYK0+PtDOPfub/KR
+c3MeWx3neXx4/wbnJWGbNAtbYqXg3uU5J4HFzPgk/VIppgSKAhlO0H60DRP48by9
+gr5/yDHu2KXhOmnMg46sYsUIpfgtBS9+VtrqWziJfb+pkGtuOWeTnj6zBmBNZKK+
+5AlMCW1WPhrylIcB+XSZx8tk9GS/3SMQ+YfMVwwAyYjsex14Uzto4GjONALE5oh1
+M3+glRQduD6vzSwOD+WahMbc9vCOTED+2McLHRKgNaQf0YJ9a1jG9oJIvDkKXEqd
+fqDRktwyoD74cV57bW3tBAexB7GglITbInyQAsmdngtfg2LUMrcROHHP86QPZINj
+DQIDAQAB