#include <time.h>
#include "alloc.h"
+#include "cachent.h"
#include "cachetmp.h"
#include "common.h"
#include "config.h"
}
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) {
if (error)
return error;
- mtim = time(NULL); // XXX
+ mtim = time_nonfatal();
error = http_download(node->url, tmppath, node->mtim, &changed);
if (error) {
/* @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)
}
}
- 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;
}
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;
* 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;
}
}
-/*
- * XXX this needs to be hit only by files now
- * XXX result is redundant
- */
static bool
commit_rpp_delta(struct cache_node *node)
{
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)
{
#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 */
* - 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 */
}
/* 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) {
parent = iter_start->parent;
do {
if (parent == NULL)
- return error;
+ return;
iter_start = parent->hh.next;
parent = parent->parent;
} while (iter_start == NULL);
* 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)
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 **);
* Cached certificate data.
*/
struct metadata_node {
- struct cache_mapping *map;
+ struct cache_mapping map;
struct resources *resources;
/*
* Serial numbers of the children.
case DNT_SEPARATOR:
break;
case DNT_CERT:
- map_refput(defer->deferred.map);
rpp_refput(defer->deferred.pp);
break;
}
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);
node->type = DNT_CERT;
node->deferred = *deferred;
- map_refget(deferred->map);
rpp_refget(deferred->pp);
SLIST_INSERT_HEAD(&stack->defers, node, next);
}
}
*result = node->deferred;
- map_refget(node->deferred.map);
rpp_refget(node->deferred.pp);
SLIST_REMOVE_HEAD(&stack->defers, next);
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);
resources_destroy(meta->resources);
cleanup_serial:
serial_numbers_cleanup(&meta->serials, serial_cleanup);
- map_refput(meta->map);
free(meta);
return error;
}
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 *
struct cert_stack;
struct deferred_cert {
- struct cache_mapping *map;
+ struct cache_mapping map;
struct rpp *pp;
};
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;
*
* @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;
if (error)
return error;
- return validate_signedObject(refs, map);
+ return validate_signedObject(refs, url);
}
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_ */
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;
}
#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)
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_ */
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;
}
{
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:
* 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.");
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()");
}
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;
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);
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;
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;
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) {
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("}");
fnstack_push_map(map);
/* Decode */
- error = signed_object_decode(&sobj, map);
+ error = signed_object_decode(&sobj, map->path);
if (error)
goto revert_log;
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);
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,
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();
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];
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 */
* @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;
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);
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;
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;
revert_log:
pr_val_debug("}");
fnstack_pop();
- map_refput(map);
return error;
}
#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_ */
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);
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);
#define SRC_OBJECT_ROA_H_
#include "rpp.h"
-#include "types/address.h"
#include "types/map.h"
int roa_traverse(struct cache_mapping *, struct rpp *);
#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;
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 *);
#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;
}
/**
- * 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:
* 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);
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)
{
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);
#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().
} 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
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;
{
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
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;
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
*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.");
}
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
__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);
}
#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 *);
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;
int
vrps_init(void)
{
- time_t now;
int error;
state.base = NULL;
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)
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
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);
#define SRC_THREAD_VAR_H_
#include "state.h"
+#include "types/map.h"
int thvar_init(void); /* This function does not need cleanup. */
#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)
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());
}
#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_ */
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 *);
#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)
{
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 '..'.
*
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);
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
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}
#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,
}
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;
}
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
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",
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
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
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();
}
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();
}
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);
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);
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");
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();
}
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.) */
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();
}
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();
}
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;
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();
}
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) */
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();
}
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();
}
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();
}
}
}
-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;
}
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;
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
{
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);
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);
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);
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",
"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",
"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",
"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",
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)
--- /dev/null
+#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;
+}
/* 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)
/* Mocks */
-MOCK_VOID(fnstack_push, char const *file)
-MOCK_VOID(fnstack_pop, void)
MOCK_VOID(__delete_node_cb, struct cache_node const *node)
/* Utils */
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),
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),
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,
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,
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)
+++ /dev/null
-#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(¬if, 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(¬if, 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;
-}
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