]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Parse and process snapshot, remember RRDP URIs (session ID and serial).
authorpcarana <pc.moreno2099@gmail.com>
Wed, 27 Nov 2019 21:49:39 +0000 (15:49 -0600)
committerpcarana <pc.moreno2099@gmail.com>
Wed, 27 Nov 2019 21:49:39 +0000 (15:49 -0600)
+Create struct and method to store RRDP URIs data.
+Create handler so that multiple threads can access RRDP URIs data.
+Rename 'gdata' property to 'global_data' at update_notification struct.
+Use prefered access method according to the order specified at the CAs.
+Implement RRDP URIs comparison, considers: URI, session ID and serial so that the caller can determine what to do (process snapshot, deltas, etc.)
+Document rrdp_objects.h structs.
+Add content length to 'publish' structure.
+Add functions to parse 'publish' elements.
+Validate that a new RRDP object parsed matches session ID and serial of the parent.
+Whenever a snapshot file is parsed (and validated), all of its 'publish' elements are parsed as well and created at the local repository.
+Use 'fnstack' to log whenever an RRDP file is being processed.
+Update 'uri.h' to explicitly create either rsync or https URIs.
+Use rrdp_handler at the validation state of each thread (or each TAL, it's the same thing).
+Fix wrong return value on error at __do_file_validation, it should return a 'no memory' error instead of 'invalid value'.
+Fix macro ARRAYLIST_FOREACH, one argument wasn't being utilized.
+Update unit tests, add reference to new header 'db_rrdp.h'.

23 files changed:
src/Makefile.am
src/data_structure/array_list.h
src/object/certificate.c
src/object/tal.c
src/rrdp/db_rrdp.c [new file with mode: 0644]
src/rrdp/db_rrdp.h [new file with mode: 0644]
src/rrdp/rrdp_handler.c [new file with mode: 0644]
src/rrdp/rrdp_handler.h [new file with mode: 0644]
src/rrdp/rrdp_objects.c
src/rrdp/rrdp_objects.h
src/rrdp/rrdp_parser.c
src/rrdp/rrdp_parser.h
src/rsync/rsync.c
src/rtr/db/vrps.c
src/rtr/db/vrps.h
src/state.c
src/state.h
src/uri.c
src/uri.h
test/rsync_test.c
test/rtr/db/vrps_test.c
test/rtr/pdu_handler_test.c
test/tal_test.c

index 9bf88d947a3594c586d6a90e21c30dc035562b17..bca8af9f69d60527ebba779d572319739250a836 100644 (file)
@@ -79,6 +79,8 @@ fort_SOURCES += resource/ip4.h resource/ip4.c
 fort_SOURCES += resource/ip6.h resource/ip6.c
 fort_SOURCES += resource/asn.h resource/asn.c
 
+fort_SOURCES += rrdp/db_rrdp.h rrdp/db_rrdp.c
+fort_SOURCES += rrdp/rrdp_handler.h rrdp/rrdp_handler.c
 fort_SOURCES += rrdp/rrdp_objects.h rrdp/rrdp_objects.c
 fort_SOURCES += rrdp/rrdp_parser.h rrdp/rrdp_parser.c
 
index 7ca927ccfe96703ebfdeefb4328a31484e3e12ed..b20cb9d885e676586e0dcbd5ff13917ec27a73ba 100644 (file)
@@ -74,9 +74,9 @@
        DEFINE_ARRAY_LIST_FUNCTIONS(name, elem_type, )
 
 #define ARRAYLIST_FOREACH(list, node, index) for (                     \
-       (i) = 0, (node) = (list)->array;                                \
-       (i) < (list)->len;                                              \
-       (i)++, (node)++                                                 \
+       (index) = 0, (node) = (list)->array;                            \
+       (index) < (list)->len;                                          \
+       (index)++, (node)++                                             \
 )
 
 #endif /* SRC_DATA_STRUCTURE_ARRAY_LIST_H_ */
index 45707133b5c73bf166458c56b5abb2a86a9df8ae..ca5d98dcf05a631a45df2e327c15ff74107c531b 100644 (file)
@@ -19,6 +19,7 @@
 #include "object/name.h"
 #include "object/manifest.h"
 #include "object/signed_object.h"
+#include "rrdp/rrdp_objects.h"
 #include "rrdp/rrdp_parser.h"
 #include "rsync/rsync.h"
 
@@ -53,6 +54,9 @@ struct bgpsec_ski {
        unsigned char **ski_data;
 };
 
+/* Callback method to fetch repository objects */
+typedef int (access_method_exec)(struct sia_ca_uris *);
+
 static void
 sia_ca_uris_init(struct sia_ca_uris *sia_uris)
 {
@@ -237,7 +241,7 @@ check_dup_public_key(bool *duplicated, char const *file, void *arg)
        rcvd_cert = NULL;
        tmp_size = 0;
 
-       error = uri_create_str(&uri, file, strlen(file));
+       error = uri_create_rsync_str(&uri, file, strlen(file));
        if (error)
                return error;
 
@@ -1873,6 +1877,110 @@ certificate_validate_aia(struct rpki_uri *caIssuers, X509 *cert)
        return force_aia_validation(caIssuers, cert);
 }
 
+static int
+exec_rrdp_method(struct sia_ca_uris *sia_uris)
+{
+       struct update_notification *upd_notification;
+       struct snapshot *snapshot;
+       enum rrdp_uri_cmp_result res;
+       int error;
+
+       error = rrdp_parse_notification(sia_uris->rpkiNotify.uri,
+           &upd_notification);
+       if (error)
+               return error;
+
+       res = rhandler_uri_cmp(uri_get_global(sia_uris->rpkiNotify.uri),
+           upd_notification->global_data.session_id,
+           upd_notification->global_data.serial);
+       switch(res) {
+       case RRDP_URI_EQUAL:
+               update_notification_destroy(upd_notification);
+               fnstack_pop();
+               return 0;
+       case RRDP_URI_DIFF_SERIAL:
+               /* FIXME (now) Fetch and process the deltas */
+               /* Store the new value */
+               error = rhandler_uri_update(
+                   uri_get_global(sia_uris->rpkiNotify.uri),
+                   upd_notification->global_data.session_id,
+                   upd_notification->global_data.serial);
+               break;
+       case RRDP_URI_DIFF_SESSION:
+               /* FIXME (now) delete the old session files */
+       case RRDP_URI_NOTFOUND:
+               /* Process the snapshot */
+               error = rrdp_parse_snapshot(upd_notification, &snapshot);
+               if (error) {
+                       break;
+               }
+               snapshot_destroy(snapshot);
+               fnstack_pop(); /* FIXME (now) Snapshot pop, shouldn't be here */
+               /* Store the new value */
+               error = rhandler_uri_update(
+                   uri_get_global(sia_uris->rpkiNotify.uri),
+                   upd_notification->global_data.session_id,
+                   upd_notification->global_data.serial);
+
+               break;
+       default:
+               pr_crit("Unknown RRDP URI comparison result");
+       }
+
+       /*
+        * FIXME (now) Now do the validation, start by the root manifest
+        */
+       update_notification_destroy(upd_notification);
+       fnstack_pop();
+       if (error) {
+               return error;
+       }
+       return 0;
+}
+
+static int
+exec_rsync_method(struct sia_ca_uris *sia_uris)
+{
+       return download_files(sia_uris->caRepository.uri, false, false);
+}
+
+/*
+ * Currently only two access methods are supported, just consider those two:
+ * rsync and RRDP. If a new access method is supported, this function must
+ * change (and probably the sia_ca_uris struct as well).
+ */
+static int
+use_access_method(struct sia_ca_uris *sia_uris,
+    access_method_exec rsync_cb, access_method_exec rrdp_cb)
+{
+       access_method_exec *cb_primary;
+       access_method_exec *cb_secondary;
+       int error;
+
+       /*
+        * RSYNC will always be present (at least for now, see
+        * rfc6487#section-4.8.8.1)
+        */
+       if (sia_uris->rpkiNotify.uri == NULL)
+               return rsync_cb(sia_uris);
+
+       /* Get the preferred */
+       if (sia_uris->caRepository.position > sia_uris->rpkiNotify.position) {
+               cb_primary = rrdp_cb;
+               cb_secondary = rsync_cb;
+       } else {
+               cb_primary = rsync_cb;
+               cb_secondary = rrdp_cb;
+       }
+
+       /* Try with the preferred; in case of error, try with the next one */
+       error = cb_primary(sia_uris);
+       if (!error)
+               return 0;
+
+       return cb_secondary(sia_uris);
+}
+
 /** Boilerplate code for CA certificate validation and recursive traversal. */
 int
 certificate_traverse(struct rpp *rpp_parent, struct rpki_uri *cert_uri)
@@ -1983,18 +2091,31 @@ certificate_traverse(struct rpp *rpp_parent, struct rpki_uri *cert_uri)
                goto revert_refs;
        }
 
-       /* Currently there's support for 2 access methods */
-       /* FIXME (now) Download files according to the preferred method */
-       if (sia_uris.rpkiNotify.uri != NULL &&
-           sia_uris.caRepository.position > sia_uris.rpkiNotify.position) {
-               pr_info("Preferred Access Method: RRDP, but doing rsync anyways");
-               rrdp_parse_notification(sia_uris.rpkiNotify.uri);
-       } else
-               pr_info("Preferred Access Method: RSYNC [found RRDP? %s]",
-                   (sia_uris.rpkiNotify.uri == NULL ? "NO" : "YES"));
-
-       /* Currently downloading RSYNC (will always be present) */
-       error = download_files(sia_uris.caRepository.uri, false, false);
+       /*
+        * FIXME (now) Beware: what if RRDP is already being utilized?
+        *
+        * There isn't any restriction about the preferred access method of
+        * children CAs being the same as the parent CA.
+        *
+        * Two possible scenarios arise:
+        * 1) CA Parent didn't utilized (or didn't had) and RRDP update
+        *    notification URI.
+        * 2) CA Parent successfully utilized an RRDP update notification URI.
+        *
+        * Step (1) is simple, do the check of the preferred access method.
+        * Step (2) must do something different.
+        * - The manifest should exist at the snapshot file (aka, directory
+        *   structure), so it should be processed from there on.
+        * - Verify that the manifest file exists locally (must be the same
+        *   session_id and serial, load those at start, the serial can
+        *   be written to a local file, the session_id can be loaded from the
+        *   directory structure <local-repository>/rrdp/<session_id>).:
+        *   + Exists: Read and process normally (no need to do rsync)
+        *   + Doesn't exists: check for preferred access method, keep the flow
+        *     from there on.
+        */
+       error = use_access_method(&sia_uris, exec_rsync_method,
+           exec_rrdp_method);
        if (error)
                return error;
 
index 69eec5bec880a8c76c70148e3d707175f4acc747..3512a4114091a850d754c96b99cf1a2fadb72adc 100644 (file)
@@ -469,6 +469,7 @@ handle_tal_uri(struct tal *tal, struct rpki_uri *uri, void *arg)
         */
 
        struct validation_handler validation_handler;
+       struct rrdp_handler rrdp_handler;
        struct validation *state;
        struct cert_stack *certstack;
        struct deferred_cert deferred;
@@ -479,7 +480,11 @@ handle_tal_uri(struct tal *tal, struct rpki_uri *uri, void *arg)
        validation_handler.handle_router_key = handle_router_key;
        validation_handler.arg = arg;
 
-       error = validation_prepare(&state, tal, &validation_handler);
+       rrdp_handler.uri_cmp = rrdp_uri_cmp;
+       rrdp_handler.uri_update = rrdp_uri_update;
+
+       error = validation_prepare(&state, tal, &validation_handler,
+           &rrdp_handler);
        if (error)
                return ENSURE_NEGATIVE(error);
 
@@ -519,6 +524,8 @@ handle_tal_uri(struct tal *tal, struct rpki_uri *uri, void *arg)
                    validation_pubkey_state(state));
        }
 
+       /* FIXME (now) Consider RRDP found scenario */
+
        /*
         * From now on, the tree should be considered valid, even if subsequent
         * certificates fail.
@@ -621,7 +628,7 @@ __do_file_validation(char const *tal_file, void *arg)
        thread = malloc(sizeof(struct thread));
        if (thread == NULL) {
                close_thread(pid, tal_file);
-               error = -EINVAL;
+               error = pr_enomem();
                goto free_param;
        }
 
diff --git a/src/rrdp/db_rrdp.c b/src/rrdp/db_rrdp.c
new file mode 100644 (file)
index 0000000..862d106
--- /dev/null
@@ -0,0 +1,151 @@
+#include "db_rrdp.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include "data_structure/uthash_nonfatal.h"
+#include "rrdp/rrdp_objects.h"
+#include "log.h"
+
+struct db_rrdp_uri {
+       /* Key */
+       char *uri;
+       struct global_data data;
+       UT_hash_handle hh;
+};
+
+struct db_rrdp {
+       struct db_rrdp_uri *uris;
+};
+
+static int
+db_rrdp_uri_create(char const *uri, char const *session_id,
+    unsigned long serial, struct db_rrdp_uri **result)
+{
+       struct db_rrdp_uri *tmp;
+       int error;
+
+       tmp = malloc(sizeof(struct db_rrdp_uri));
+       if (tmp == NULL)
+               return pr_enomem();
+       /* Needed by uthash */
+       memset(tmp, 0, sizeof(struct db_rrdp_uri));
+
+       tmp->uri = strdup(uri);
+       if (tmp->uri == NULL) {
+               error = pr_enomem();
+               goto release_tmp;
+       }
+
+       tmp->data.session_id = strdup(session_id);
+       if (tmp->data.session_id == NULL) {
+               error = pr_enomem();
+               goto release_uri;
+       }
+
+       tmp->data.serial = serial;
+
+       *result = tmp;
+       return 0;
+release_uri:
+       free(tmp->uri);
+release_tmp:
+       free(tmp);
+       return error;
+}
+
+static void
+db_rrdp_uri_destroy(struct db_rrdp_uri *uri)
+{
+       free(uri->data.session_id);
+       free(uri->uri);
+       free(uri);
+}
+
+static int
+add_rrdp_uri(struct db_rrdp *db, struct db_rrdp_uri *new_uri)
+{
+       struct db_rrdp_uri *old_uri;
+
+       errno = 0;
+       HASH_FIND_STR(db->uris, new_uri->uri, old_uri);
+       if (errno)
+               return pr_errno(errno,
+                   "RRDP URI couldn't be added to hash table");
+
+       if (old_uri != NULL) {
+               HASH_DELETE(hh, db->uris, old_uri);
+               db_rrdp_uri_destroy(old_uri);
+       }
+       HASH_ADD_KEYPTR(hh, db->uris, new_uri->uri, strlen(new_uri->uri),
+           new_uri);
+
+       return 0;
+}
+
+enum rrdp_uri_cmp_result
+db_rrdp_cmp_uri(struct db_rrdp *db, char const *uri, char const *session_id,
+    unsigned long serial)
+{
+       struct db_rrdp_uri *found;
+
+       HASH_FIND_STR(db->uris, uri, found);
+       if (found == NULL)
+               return RRDP_URI_NOTFOUND;
+
+       if (strcmp(session_id, found->data.session_id) != 0)
+               return RRDP_URI_DIFF_SESSION;
+
+       if (serial != found->data.serial)
+               return RRDP_URI_DIFF_SERIAL;
+
+       return RRDP_URI_EQUAL;
+}
+
+int
+db_rrdp_add_uri(struct db_rrdp *db, char const *uri, char const *session_id,
+    unsigned long serial)
+{
+       struct db_rrdp_uri *db_uri;
+       int error;
+
+       db_uri = NULL;
+       error = db_rrdp_uri_create(uri, session_id, serial, &db_uri);
+       if (error)
+               return error;
+
+       error = add_rrdp_uri(db, db_uri);
+       if (error) {
+               db_rrdp_uri_destroy(db_uri);
+               return error;
+       }
+
+       return 0;
+}
+
+int
+db_rrdp_create(struct db_rrdp **result)
+{
+       struct db_rrdp *tmp;
+
+       tmp = malloc(sizeof(struct db_rrdp));
+       if (tmp == NULL)
+               return pr_enomem();
+
+       tmp->uris = NULL;
+
+       *result = tmp;
+       return 0;
+}
+
+void
+db_rddp_destroy(struct db_rrdp *db)
+{
+       struct db_rrdp_uri *uri_node, *uri_tmp;
+
+       HASH_ITER(hh, db->uris, uri_node, uri_tmp) {
+               HASH_DEL(db->uris, uri_node);
+               db_rrdp_uri_destroy(uri_node);
+       }
+
+       free(db);
+}
diff --git a/src/rrdp/db_rrdp.h b/src/rrdp/db_rrdp.h
new file mode 100644 (file)
index 0000000..48ca94d
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef SRC_RRDP_DB_RRDP_H_
+#define SRC_RRDP_DB_RRDP_H_
+
+#include "rrdp/rrdp_objects.h"
+
+/*
+ * Struct and methods to persist RRDP information, such as URIs, session ID per
+ * URI and current serial number.
+ */
+struct db_rrdp;
+
+int db_rrdp_create(struct db_rrdp **);
+void db_rddp_destroy(struct db_rrdp *);
+
+enum rrdp_uri_cmp_result db_rrdp_cmp_uri(struct db_rrdp *, char const *,
+    char const *, unsigned long);
+int db_rrdp_add_uri(struct db_rrdp *, char const *, char const *,
+    unsigned long);
+
+#endif /* SRC_RRDP_DB_RRDP_H_ */
diff --git a/src/rrdp/rrdp_handler.c b/src/rrdp/rrdp_handler.c
new file mode 100644 (file)
index 0000000..a09765b
--- /dev/null
@@ -0,0 +1,52 @@
+#include "rrdp_handler.h"
+
+#include "thread_var.h"
+
+static int
+get_current_threads_handler(struct rrdp_handler const **result)
+{
+       struct validation *state;
+       struct rrdp_handler const *handler;
+
+       state = state_retrieve();
+       if (state == NULL)
+               return -EINVAL;
+
+       handler = validation_get_rrdp_handler(state);
+       if (handler == NULL)
+               pr_crit("This thread lacks an RRDP handler.");
+
+       *result = handler;
+       return 0;
+}
+
+enum rrdp_uri_cmp_result
+rhandler_uri_cmp(char const *uri, char const *session_id, unsigned long serial)
+{
+       struct rrdp_handler const *handler;
+       int error;
+
+       error = get_current_threads_handler(&handler);
+       if (error)
+               return error;
+
+       return (handler->uri_cmp != NULL)
+           ? handler->uri_cmp(uri, session_id, serial)
+           : RRDP_URI_NOTFOUND;
+}
+
+int
+rhandler_uri_update(char const *uri, char const *session_id,
+    unsigned long serial)
+{
+       struct rrdp_handler const *handler;
+       int error;
+
+       error = get_current_threads_handler(&handler);
+       if (error)
+               return error;
+
+       return (handler->uri_update != NULL)
+           ? handler->uri_update(uri, session_id, serial)
+           : 0;
+}
diff --git a/src/rrdp/rrdp_handler.h b/src/rrdp/rrdp_handler.h
new file mode 100644 (file)
index 0000000..bcf5da7
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef SRC_RRDP_RRDP_HANDLER_H_
+#define SRC_RRDP_RRDP_HANDLER_H_
+
+#include "rrdp/rrdp_objects.h"
+
+/*
+ * Almost the same idea as 'validation_handler.h', only that the main focus is
+ * a multithreaded environment.
+ *
+ * The RRDP URIs are expected to live at the main thread, the other threads can
+ * access such URIs. The handler must assure that the data is safe
+ * (handle r/w locks), that's the reason why there isn't any reference to a
+ * 'db_rrdp' struct.
+ */
+
+struct rrdp_handler {
+       /*
+        * Search the RRDP URI, returns the corresponding enum to indicate
+        * the comparison result.
+        */
+       enum rrdp_uri_cmp_result (*uri_cmp)(char const *, char const *,
+           unsigned long);
+       /* Add or update an RRDP URI */
+       int (*uri_update)(char const *, char const *, unsigned long);
+};
+
+enum rrdp_uri_cmp_result rhandler_uri_cmp(char const *, char const *, unsigned long);
+int rhandler_uri_update(char const *, char const *, unsigned long);
+
+#endif /* SRC_RRDP_RRDP_HANDLER_H_ */
index 05ae9805763ed109e2035356c6755bae8f805892..e5146dc50de102b1c8ed7792ea411a4ee60af992 100644 (file)
@@ -23,6 +23,7 @@ int
 doc_data_init(struct doc_data *data)
 {
        data->hash = NULL;
+       data->hash_len = 0;
        data->uri = NULL;
        return 0;
 }
@@ -55,7 +56,6 @@ xml_source_destroy(struct xml_source *src){
        }
 }
 
-
 int
 xml_source_set(struct xml_source *src, xmlDoc *orig)
 {
@@ -78,7 +78,7 @@ update_notification_create(struct update_notification **file)
        if (tmp == NULL)
                return pr_enomem();
 
-       global_data_init(&tmp->gdata);
+       global_data_init(&tmp->global_data);
        doc_data_init(&tmp->snapshot);
 
        SLIST_INIT(&tmp->deltas_list);
@@ -101,7 +101,7 @@ update_notification_destroy(struct update_notification *file)
                free(head);
        }
        doc_data_cleanup(&file->snapshot);
-       global_data_cleanup(&file->gdata);
+       global_data_cleanup(&file->global_data);
 
        free(file);
 }
@@ -125,3 +125,72 @@ update_notification_deltas_add(struct deltas_head *deltas, unsigned long serial,
 
        return 0;
 }
+
+int
+snapshot_create(struct snapshot **file)
+{
+       struct snapshot *tmp;
+
+       tmp = malloc(sizeof(struct snapshot));
+       if (tmp == NULL)
+               return pr_enomem();
+
+       global_data_init(&tmp->global_data);
+       SLIST_INIT(&tmp->publish_list);
+       tmp->source = NULL;
+
+       *file = tmp;
+       return 0;
+}
+
+void
+snapshot_destroy(struct snapshot *file)
+{
+       struct publish_list *list;
+       struct publish *head;
+
+       list = &file->publish_list;
+       while (!SLIST_EMPTY(list)) {
+               head = list->slh_first;
+               SLIST_REMOVE_HEAD(list, next);
+               doc_data_cleanup(&head->doc_data);
+               free(head->content);
+               free(head);
+       }
+       global_data_cleanup(&file->global_data);
+       xml_source_destroy(file->source);
+
+       free(file);
+}
+
+int
+publish_create(struct publish **file)
+{
+       struct publish *tmp;
+
+       tmp = malloc(sizeof(struct publish));
+       if (tmp == NULL)
+               return pr_enomem();
+
+       doc_data_init(&tmp->doc_data);
+       tmp->content = NULL;
+       tmp->content_len = 0;
+
+       *file = tmp;
+       return 0;
+}
+
+void
+publish_destroy(struct publish *file)
+{
+       doc_data_cleanup(&file->doc_data);
+       free(file->content);
+       free(file);
+}
+
+int
+publish_list_add(struct publish_list *list, struct publish *elem)
+{
+       SLIST_INSERT_HEAD(list, elem, next);
+       return 0;
+}
index 2090a7acff3b573e2369941fa863c93f2805db91..a9fb90a73da8a9640e2db0aa2e14cc7d03512922 100644 (file)
@@ -5,35 +5,57 @@
 #include <sys/queue.h>
 #include <stddef.h>
 
-/* Common structures */
+/* Possible results for an RRDP URI comparison */
+enum rrdp_uri_cmp_result {
+       /* The URI doesn't exists */
+       RRDP_URI_NOTFOUND,
+
+       /* The URI exists and has the same session ID and serial */
+       RRDP_URI_EQUAL,
+
+       /* The URI exists but has distinct serial */
+       RRDP_URI_DIFF_SERIAL,
+
+       /* The URI exists but has distinct session ID */
+       RRDP_URI_DIFF_SESSION,
+};
+
+/* Structure to remember the XML source file (useful for hash validations) */
 struct xml_source;
 
+/* Global RRDP files data */
 struct global_data {
        char *session_id;
        unsigned long serial;
 };
 
+/* Specific RRDP files data, in some cases the hash can be omitted */
 struct doc_data {
        char *uri;
        unsigned char *hash;
        size_t hash_len;
 };
 
+/* Represents a <publish> element to be utilized inside a list */
 struct publish {
        struct doc_data doc_data;
        unsigned char *content;
+       size_t content_len;
        SLIST_ENTRY(publish) next;
 };
 
+/* Represents a <withdraw> element to be utilized inside a list */
 struct withdraw {
        struct doc_data doc_data;
        SLIST_ENTRY(withdraw) next;
 };
 
-/* Delta file structs */
+/* List of <publish> elements (either in a delta or a snapshot file) */
 SLIST_HEAD(publish_list, publish);
+/* List of <withdraw> elements */
 SLIST_HEAD(withdrawn_list, withdraw);
 
+/* Delta file content */
 struct delta {
        struct global_data global_data;
        struct publish_list publish_list;
@@ -41,24 +63,25 @@ struct delta {
        struct xml_source *source;
 };
 
-/* Snapshot file structs */
+/* Snapshot file content */
 struct snapshot {
        struct global_data global_data;
        struct publish_list publish_list;
        struct xml_source *source;
 };
 
-/* Update notification file structs */
+/* Delta element located at an update notification file */
 struct delta_head {
        unsigned long serial;
        struct doc_data doc_data;
        SLIST_ENTRY(delta_head) next;
 };
 
+/* List of deltas inside an update notification file */
 SLIST_HEAD(deltas_head, delta_head);
 
 struct update_notification {
-       struct global_data gdata;
+       struct global_data global_data;
        struct doc_data snapshot;
        struct deltas_head deltas_list;
 };
@@ -79,4 +102,13 @@ void update_notification_destroy(struct update_notification *);
 int update_notification_deltas_add(struct deltas_head *, unsigned long, char **,
     unsigned char **, size_t);
 
+int snapshot_create(struct snapshot **);
+void snapshot_destroy(struct snapshot *);
+
+int publish_create(struct publish **);
+void publish_destroy(struct publish *);
+
+int publish_list_add(struct publish_list *, struct publish *);
+
+
 #endif /* SRC_RRDP_RRDP_OBJECTS_H_ */
index ec01475c75cb8d3baa3ca10b8b32fc348f1fa56f..9610cdc94b1607eb9cfffac85d4c40922f1f25c6 100644 (file)
@@ -2,17 +2,27 @@
 
 #include <libxml/parser.h>
 #include <libxml/tree.h>
+#include <openssl/evp.h>
+#include <sys/stat.h>
+#include <ctype.h>
 #include <errno.h>
 #include <stdlib.h>
+#include <string.h>
 
+#include "crypto/base64.h"
 #include "http/http.h"
 #include "xml/relax_ng.h"
+#include "common.h"
+#include "file.h"
 #include "log.h"
+#include "thread_var.h"
 
 /* XML Elements */
 #define RRDP_ELEM_NOTIFICATION "notification"
 #define RRDP_ELEM_SNAPSHOT     "snapshot"
 #define RRDP_ELEM_DELTA                "delta"
+#define RRDP_ELEM_PUBLISH      "publish"
+#define RRDP_ELEM_WITHDRAW     "withdraw"
 
 /* XML Attributes */
 #define RRDP_ATTR_VERSION      "version"
@@ -35,16 +45,181 @@ get_root_element(xmlDoc *doc, xmlNode **result)
        return 0;
 }
 
+static size_t
+write_local(unsigned char *content, size_t size, size_t nmemb, void *arg)
+{
+       FILE *fd = arg;
+       size_t read = size * nmemb;
+       size_t written;
+
+       written = fwrite(content, size, nmemb, fd);
+       if (written != nmemb)
+               return -EINVAL;
+
+       return read;
+}
+
+/* Trim @from, setting the result at @result pointer */
+static int
+trim(char *from, char **result, size_t *result_size)
+{
+       char *start, *end;
+       size_t tmp_size;
+
+       start = from;
+       tmp_size = strlen(from);
+       while (isspace(*start)) {
+               start++;
+               tmp_size--;
+       }
+       if (*start == '\0')
+               return pr_err("Invalid base64 encoded string (seems to be empty or full of spaces).");
+
+       end = start;
+       while (*end != '\0') {
+               if (!isspace(*end)) {
+                       end++;
+                       continue;
+               }
+               /* No middle spaces, newlines, etc. allowed */
+               *end = '\0';
+               tmp_size = end - start;
+               break;
+       }
+
+       *result = start;
+       *result_size = tmp_size;
+       return 0;
+}
+
+/*
+ * Get the base64 chars from @content and allocate to @out with lines no greater
+ * than 65 chars (including line feed).
+ *
+ * Why? LibreSSL doesn't like lines greater than 80 chars, so use a common
+ * length per line.
+ */
+static int
+base64_sanitize(char *content, char **out)
+{
+#define BUF_SIZE 65
+       char *result;
+       char *tmp;
+       size_t original_size, new_size;
+       size_t offset, buf_len;
+       int error;
+
+       original_size = 0;
+       error = trim(content, &tmp, &original_size);
+       if (error)
+               return error;
+
+       if (original_size <= BUF_SIZE) {
+               result = malloc(original_size + 1);
+               if (result == NULL)
+                       return pr_enomem();
+               result[original_size] = '\0';
+               *out = result;
+               return 0;
+       }
+
+       new_size = original_size + (original_size / BUF_SIZE);
+       result = malloc(new_size + 1);
+       if (result == NULL)
+               return pr_enomem();
+
+       offset = 0;
+       while (original_size > 0){
+               buf_len = original_size > BUF_SIZE ? BUF_SIZE : original_size;
+               memcpy(&result[offset], tmp, buf_len);
+               tmp += buf_len;
+               offset += buf_len;
+               original_size -= buf_len;
+
+               if (original_size <= 0)
+                       break;
+               result[offset] = '\n';
+               offset++;
+       }
+
+       /* Reallocate to exact size and add nul char */
+       if (offset != new_size + 1) {
+               tmp = realloc(result, offset + 1);
+               if (tmp == NULL) {
+                       free(result);
+                       return pr_enomem();
+               }
+               result = tmp;
+       }
+
+       result[offset] = '\0';
+       *out = result;
+       return 0;
+#undef BUF_SIZE
+}
+
+static int
+base64_read(char *content, unsigned char **out, size_t *out_len)
+{
+       BIO *encoded; /* base64 encoded. */
+       unsigned char *result;
+       char *sanitized;
+       size_t alloc_size;
+       size_t result_len;
+       int error;
+
+       sanitized = NULL;
+       error = base64_sanitize(content, &sanitized);
+       if (error)
+               return error;
+
+       encoded = BIO_new_mem_buf(sanitized, -1);
+       if (encoded == NULL) {
+               error = crypto_err("BIO_new_mem_buf() returned NULL");
+               goto release_sanitized;
+       }
+
+       alloc_size = EVP_DECODE_LENGTH(strlen(content));
+       result = malloc(alloc_size);
+       if (result == NULL) {
+               error = pr_enomem();
+               goto release_bio;
+       }
+
+       error = base64_decode(encoded, result, true, alloc_size, &result_len);
+       if (error)
+               goto release_result;
+
+       free(sanitized);
+       BIO_free(encoded);
+
+       *out = result;
+       (*out_len) = result_len;
+       return 0;
+release_result:
+       free(result);
+release_bio:
+       BIO_free(encoded);
+release_sanitized:
+       free(sanitized);
+       return error;
+}
+
 static int
 parse_string(xmlNode *root, char const *attr, char **result)
 {
        xmlChar *xml_value;
        char *tmp;
 
-       xml_value = xmlGetProp(root, BAD_CAST attr);
+       if (attr == NULL)
+               xml_value = xmlNodeGetContent(root);
+       else
+               xml_value = xmlGetProp(root, BAD_CAST attr);
+
        if (xml_value == NULL)
-               return pr_err("RRDP file: Couldn't find xml attribute %s",
-                   attr);
+               return pr_err("RRDP file: Couldn't find %s from '%s'",
+                   (attr == NULL ? "string content" : "xml attribute"),
+                   root->name);
 
        tmp = malloc(xmlStrlen(xml_value) + 1);
        if (tmp == NULL) {
@@ -132,7 +307,8 @@ parse_hex_string(xmlNode *root, char const *attr, unsigned char **result,
 
 /* @gdata elements are allocated */
 static int
-parse_global_data(xmlNode *root, struct global_data *gdata)
+parse_global_data(xmlNode *root, struct global_data *gdata,
+    struct global_data *parent_data)
 {
        int error;
 
@@ -146,6 +322,24 @@ parse_global_data(xmlNode *root, struct global_data *gdata)
                return error;
        }
 
+       if (parent_data == NULL)
+               return 0;
+
+       /*
+        * FIXME (now) Prepare the callers to receive positive error values,
+        * which means the file was successfully parsed but is has a logic error
+        * (in this case, session ID or serial don't match parent's).
+        */
+       if (strcmp(parent_data->session_id, gdata->session_id) != 0) {
+               pr_info("Object session id doesn't match parent's session id");
+               return EINVAL;
+       }
+
+       if (parent_data->serial != gdata->serial) {
+               pr_info("Object serial doesn't match parent's serial");
+               return EINVAL;
+       }
+
        return 0;
 }
 
@@ -218,8 +412,104 @@ parse_notification_data(xmlNode *root, struct update_notification *file)
 }
 
 static int
-parse_notification(const char *path,
-    struct update_notification **file)
+parse_publish(xmlNode *root, bool parse_hash, struct publish **publish)
+{
+       struct publish *tmp;
+       char *base64_str;
+       int error;
+
+       error = publish_create(&tmp);
+       if (error)
+               return error;
+
+       error = parse_doc_data(root, parse_hash, &tmp->doc_data);
+       if (error)
+               goto release_tmp;
+
+       error = parse_string(root, NULL, &base64_str);
+       if (error)
+               goto release_tmp;
+
+       error = base64_read(base64_str, &tmp->content, &tmp->content_len);
+       if (error)
+               goto release_base64;
+
+       free(base64_str);
+       *publish = tmp;
+       return 0;
+release_base64:
+       free(base64_str);
+release_tmp:
+       publish_destroy(tmp);
+       return error;
+}
+
+static int
+write_from_uri(char const *location, unsigned char *content, size_t content_len)
+{
+       struct rpki_uri *uri;
+       struct stat stat;
+       FILE *out;
+       size_t written;
+       int error;
+
+       error = uri_create_mixed_str(&uri, location, strlen(location));
+       if (error)
+               return error;
+
+       error = create_dir_recursive(uri_get_local(uri));
+       if (error) {
+               uri_refput(uri);
+               return error;
+       }
+
+       error = file_write(uri_get_local(uri), &out, &stat);
+       if (error) {
+               uri_refput(uri);
+               return error;
+       }
+
+       written = fwrite(content, sizeof(unsigned char), content_len, out);
+       if (written != content_len) {
+               uri_refput(uri);
+               file_close(out);
+               return pr_err("Coudln't write bytes to file %s",
+                   uri_get_local(uri));
+       }
+
+       uri_refput(uri);
+       file_close(out);
+       return 0;
+}
+
+static int
+parse_snapshot_publish_list(xmlNode *root, struct snapshot *file)
+{
+       struct publish *tmp;
+       xmlNode *cur_node;
+       int error;
+
+       /* Only publish elements are expected, already validated by syntax */
+       for (cur_node = root->children; cur_node; cur_node = cur_node->next) {
+               if (xmlStrEqual(cur_node->name, BAD_CAST RRDP_ELEM_PUBLISH)) {
+                       tmp = NULL;
+                       error = parse_publish(cur_node, false, &tmp);
+                       if (error)
+                               return error;
+
+                       error = write_from_uri(tmp->doc_data.uri, tmp->content,
+                           tmp->content_len);
+                       publish_destroy(tmp);
+                       if (error)
+                               return error;
+               }
+       }
+
+       return 0;
+}
+
+static int
+parse_notification(const char *path, struct update_notification **file)
 {
        xmlDoc *doc;
        xmlNode *root;
@@ -238,10 +528,10 @@ parse_notification(const char *path,
 
        error = get_root_element(doc, &root);
        if (error)
-               return error;
+               goto release_update;
 
        /* FIXME (now) validate version, namespace, etc. */
-       error = parse_global_data(root, &tmp->gdata);
+       error = parse_global_data(root, &tmp->global_data, NULL);
        if (error)
                goto release_update;
 
@@ -260,41 +550,113 @@ release_doc:
        return error;
 }
 
-static size_t
-write_local(unsigned char *content, size_t size, size_t nmemb, void *arg)
+static int
+parse_snapshot(const char *path, struct update_notification *parent,
+    struct snapshot **file)
 {
-       FILE *fd = arg;
-       size_t read = size * nmemb;
-       size_t written;
+       xmlDoc *doc;
+       xmlNode *root;
+       struct snapshot *tmp;
+       struct xml_source *source;
+       int error;
 
-       written = fwrite(content, size, nmemb, fd);
-       if (written != nmemb)
-               return -EINVAL;
+       root = NULL;
 
-       return read;
+       error = relax_ng_validate(path, &doc);
+       if (error)
+               return error;
+
+       error = snapshot_create(&tmp);
+       if (error)
+               goto release_doc;
+
+       error = get_root_element(doc, &root);
+       if (error)
+               goto release_snapshot;
+
+       /* FIXME (now) validate hash, version, namespace, etc. */
+       error = xml_source_create(&source);
+       if (error)
+               goto release_snapshot;
+
+       tmp->source = source;
+       error = xml_source_set(source, doc);
+       if (error)
+               goto release_snapshot;
+
+       error = parse_global_data(root, &tmp->global_data,
+           &parent->global_data);
+       if (error)
+               goto release_snapshot;
+
+       error = parse_snapshot_publish_list(root, tmp);
+       if (error)
+               goto release_snapshot;
+
+       *file = tmp;
+       /* Error 0 is ok */
+       goto release_doc;
+release_snapshot:
+       snapshot_destroy(tmp);
+release_doc:
+       xmlFreeDoc(doc);
+       return error;
 }
 
-/* FIXME (now) Receive an **update_notification? */
 int
-rrdp_parse_notification(struct rpki_uri *uri)
+rrdp_parse_notification(struct rpki_uri *uri,
+    struct update_notification **result)
 {
-       struct update_notification *tmp;
        int error;
 
        if (uri == NULL || uri_is_rsync(uri))
                pr_crit("Wrong call, trying to parse a non HTTPS URI");
 
+       /*
+        * FIXME (now) Add "If-Modified-Since" header (see rfc8182#section-4.2)
+        */
        error = http_download_file(uri, write_local);
        if (error)
                return error;
 
-       error = parse_notification(uri_get_local(uri), &tmp);
+       fnstack_push_uri(uri);
+       error = parse_notification(uri_get_local(uri), result);
+       if (error) {
+               fnstack_pop();
+               return error;
+       }
+
+       return 0;
+}
+
+int
+rrdp_parse_snapshot(struct update_notification *parent,
+    struct snapshot **result)
+{
+       struct rpki_uri *uri;
+       struct snapshot *tmp;
+       int error;
+
+       error = uri_create_https_str(&uri, parent->snapshot.uri,
+           strlen(parent->snapshot.uri));
        if (error)
                return error;
 
-       /* FIXME (now) This is just a test, must be removed */
-       update_notification_destroy(tmp);
+       error = http_download_file(uri, write_local);
+       if (error)
+               goto release_uri;
+
+       fnstack_push_uri(uri);
+       error = parse_snapshot(uri_get_local(uri), parent, &tmp);
+       if (error)
+               goto release_uri;
 
-       /* result = tmp; */
+       uri_refput(uri);
+       *result = tmp;
+       fnstack_pop();
        return 0;
+release_uri:
+       fnstack_pop();
+       uri_refput(uri);
+       return error;
 }
index edfd591b5da0a494fe1e3f1db40802cbd3455d53..3cd2f3a2d38d8a3eaf2dc85b3b5ac978edd0f548 100644 (file)
@@ -4,6 +4,7 @@
 #include "rrdp/rrdp_objects.h"
 #include "uri.h"
 
-int rrdp_parse_notification(struct rpki_uri *);
+int rrdp_parse_notification(struct rpki_uri *, struct update_notification **);
+int rrdp_parse_snapshot(struct update_notification *, struct snapshot **);
 
 #endif /* SRC_RRDP_RRDP_PARSER_H_ */
index 62a3ac169463400111a7b4a325560d71c79238b4..652a77808e4dba71fbfc95fc4fe54f3470b6222b 100644 (file)
@@ -141,7 +141,7 @@ handle_root_strategy(struct rpki_uri *src, struct rpki_uri **dst)
                if (global[i] == '/') {
                        slashes++;
                        if (slashes == 4)
-                               return uri_create_str(dst, global, i);
+                               return uri_create_rsync_str(dst, global, i);
                }
        }
 
index 462337336683ed1e583641dade40831d684b1c04..877cb60dd276427c13f2a09eb8727af37a588f08 100644 (file)
@@ -11,6 +11,7 @@
 #include "data_structure/array_list.h"
 #include "object/router_key.h"
 #include "object/tal.h"
+#include "rrdp/db_rrdp.h"
 #include "rtr/db/db_table.h"
 #include "slurm/slurm_loader.h"
 
@@ -60,6 +61,10 @@ struct state {
        serial_t next_serial;
        uint16_t v0_session_id;
        uint16_t v1_session_id;
+
+       /* RRDP URIs known from certificates */
+       struct db_rrdp *rrdp_uris;
+
 } state;
 
 /** Read/write lock, which protects @state and its inhabitants. */
@@ -98,21 +103,30 @@ vrps_init(void)
            : (0xFFFFu);
 
        state.slurm = NULL;
+       error = db_rrdp_create(&state.rrdp_uris);
+       if (error)
+               goto release_deltas;
 
        error = pthread_rwlock_init(&state_lock, NULL);
        if (error) {
-               deltas_db_cleanup(&state.deltas, deltagroup_cleanup);
-               return pr_errno(error, "state pthread_rwlock_init() errored");
+               error = pr_errno(error, "state pthread_rwlock_init() errored");
+               goto release_db_rrdp;
        }
 
        error = pthread_rwlock_init(&table_lock, NULL);
        if (error) {
-               pthread_rwlock_destroy(&state_lock);
-               deltas_db_cleanup(&state.deltas, deltagroup_cleanup);
-               return pr_errno(error, "table pthread_rwlock_init() errored");
+               error = pr_errno(error, "table pthread_rwlock_init() errored");
+               goto release_state_lock;
        }
 
        return 0;
+release_state_lock:
+       pthread_rwlock_destroy(&state_lock);
+release_db_rrdp:
+       db_rddp_destroy(state.rrdp_uris);
+release_deltas:
+       deltas_db_cleanup(&state.deltas, deltagroup_cleanup);
+       return error;
 }
 
 void
@@ -123,6 +137,7 @@ vrps_destroy(void)
        if (state.slurm != NULL)
                db_slurm_destroy(state.slurm);
        deltas_db_cleanup(&state.deltas, deltagroup_cleanup);
+       db_rddp_destroy(state.rrdp_uris);
        /* Nothing to do with error codes from now on */
        pthread_rwlock_destroy(&state_lock);
        pthread_rwlock_destroy(&table_lock);
@@ -135,6 +150,13 @@ vrps_destroy(void)
        rwlock_unlock(lock);                                            \
        return error;
 
+#define RLOCK_HANDLER(lock, cb)                                                \
+       int error;                                                      \
+       rwlock_read_lock(lock);                                         \
+       error = cb;                                                     \
+       rwlock_unlock(lock);                                            \
+       return error;
+
 int
 handle_roa_v4(uint32_t as, struct ipv4_prefix const *prefix,
     uint8_t max_length, void *arg)
@@ -159,6 +181,20 @@ handle_router_key(unsigned char const *ski, uint32_t as,
            rtrhandler_handle_router_key(arg, ski, as, spk))
 }
 
+enum rrdp_uri_cmp_result
+rrdp_uri_cmp(char const *uri, char const *session_id, unsigned long serial)
+{
+       RLOCK_HANDLER(&state_lock,
+           db_rrdp_cmp_uri(state.rrdp_uris, uri, session_id, serial))
+}
+
+int
+rrdp_uri_update(char const *uri, char const *session_id, unsigned long serial)
+{
+       WLOCK_HANDLER(&state_lock,
+           db_rrdp_add_uri(state.rrdp_uris, uri, session_id, serial))
+}
+
 static int
 __perform_standalone_validation(struct db_table **result)
 {
@@ -274,6 +310,7 @@ __vrps_update(bool *changed)
        old_base = NULL;
        new_base = NULL;
 
+       /* FIXME (now) identify if RRDP is being utilized? */
        error = __perform_standalone_validation(&new_base);
        if (error)
                return error;
index 7877084971dd814d6725918c332006a62ef01ab5..0ed662d65c454c8ce724bec0864af887942f2c18 100644 (file)
@@ -41,6 +41,10 @@ int handle_roa_v6(uint32_t, struct ipv6_prefix const *, uint8_t, void *);
 int handle_router_key(unsigned char const *, uint32_t, unsigned char const *,
     void *);
 
+enum rrdp_uri_cmp_result rrdp_uri_cmp(char const *, char const *,
+    unsigned long);
+int rrdp_uri_update(char const *, char const *, unsigned long);
+
 uint16_t get_current_session_id(uint8_t);
 
 #endif /* SRC_VRPS_H_ */
index 343f8a24091c43c95ed3d18b5164e6576eab1d6e..40ee2d621ef67cd285fb5c31e2174467e9739c80 100644 (file)
@@ -38,6 +38,12 @@ struct validation {
        char addr_buffer2[INET6_ADDRSTRLEN];
 
        struct validation_handler validation_handler;
+
+       /*
+        * Handler of RRDP functions, this handler can access data from the
+        * main thread, so that multiple threads can use it.
+        */
+       struct rrdp_handler rrdp_handler;
 };
 
 /*
@@ -81,7 +87,8 @@ cb(int ok, X509_STORE_CTX *ctx)
  */
 int
 validation_prepare(struct validation **out, struct tal *tal,
-    struct validation_handler *validation_handler)
+    struct validation_handler *validation_handler,
+    struct rrdp_handler *rrdp_handler)
 {
        struct validation *result;
        X509_VERIFY_PARAM *params;
@@ -123,6 +130,7 @@ validation_prepare(struct validation **out, struct tal *tal,
 
        result->pubkey_state = PKS_UNTESTED;
        result->validation_handler = *validation_handler;
+       result->rrdp_handler = *rrdp_handler;
        result->x509_data.params = params; /* Ownership transfered */
 
        *out = result;
@@ -207,3 +215,9 @@ validation_get_validation_handler(struct validation *state)
 {
        return &state->validation_handler;
 }
+
+struct rrdp_handler const *
+validation_get_rrdp_handler(struct validation *state)
+{
+       return &state->rrdp_handler;
+}
index 495ae87349c31795c864236abb1b830a15d2e2aa..8c21a0f0b375f2eafcc4ec32d2f8e470f81c2f87 100644 (file)
@@ -5,12 +5,13 @@
 #include "cert_stack.h"
 #include "validation_handler.h"
 #include "object/tal.h"
+#include "rrdp/rrdp_handler.h"
 #include "rsync/rsync.h"
 
 struct validation;
 
 int validation_prepare(struct validation **, struct tal *,
-    struct validation_handler *);
+    struct validation_handler *, struct rrdp_handler *);
 void validation_destroy(struct validation *);
 
 struct tal *validation_tal(struct validation *);
@@ -34,4 +35,7 @@ char *validation_get_ip_buffer2(struct validation *);
 struct validation_handler const *
 validation_get_validation_handler(struct validation *);
 
+struct rrdp_handler const *
+validation_get_rrdp_handler(struct validation *);
+
 #endif /* SRC_STATE_H_ */
index 291fe270be22279a744a0fc4774b57dd75a42add..605da499cb460b243576de9bb45f53e8737223de 100644 (file)
--- a/src/uri.c
+++ b/src/uri.c
@@ -334,11 +334,17 @@ uri_create(struct rpki_uri **result, uint8_t flags, void const *guri,
 }
 
 int
-uri_create_str(struct rpki_uri **uri, char const *guri, size_t guri_len)
+uri_create_rsync_str(struct rpki_uri **uri, char const *guri, size_t guri_len)
 {
        return uri_create(uri, URI_VALID_RSYNC, guri, guri_len);
 }
 
+int
+uri_create_https_str(struct rpki_uri **uri, char const *guri, size_t guri_len)
+{
+       return uri_create(uri, URI_VALID_HTTPS, guri, guri_len);
+}
+
 /* A URI that can be rsync or https */
 int
 uri_create_mixed_str(struct rpki_uri **uri, char const *guri, size_t guri_len)
index c1fce5dcd012c22d32f987ac158258f170aa4c3a..693c8a4fccf90137c60b75147b15d24aa2d0ab0d 100644 (file)
--- a/src/uri.h
+++ b/src/uri.h
@@ -11,7 +11,8 @@
 
 struct rpki_uri;
 
-int uri_create_str(struct rpki_uri **, char const *, size_t);
+int uri_create_rsync_str(struct rpki_uri **, char const *, size_t);
+int uri_create_https_str(struct rpki_uri **, char const *, size_t);
 int uri_create_mixed_str(struct rpki_uri **, char const *, size_t);
 int uri_create_mft(struct rpki_uri **, struct rpki_uri *, IA5String_t *);
 int uri_create_ad(struct rpki_uri **, ACCESS_DESCRIPTION *, int);
index 3fcb1f36639b5d6df8c58573ef6393f954d0ed36..943c9069dd54c4104defa92264f89906e46e6a59 100644 (file)
@@ -27,9 +27,9 @@ assert_descendant(bool expected, char *ancestor, char *descendant)
        struct rpki_uri *ancestor_uri;
        struct rpki_uri *descendant_uri;
 
-       ck_assert_int_eq(0, uri_create_str(&ancestor_uri, ancestor,
+       ck_assert_int_eq(0, uri_create_rsync_str(&ancestor_uri, ancestor,
            strlen(ancestor)));
-       ck_assert_int_eq(0, uri_create_str(&descendant_uri, descendant,
+       ck_assert_int_eq(0, uri_create_rsync_str(&descendant_uri, descendant,
            strlen(descendant)));
 
        ck_assert_int_eq(is_descendant(ancestor_uri, descendant_uri), expected);
@@ -62,7 +62,7 @@ static void
 __mark_as_downloaded(char *uri_str, struct uri_list *visited_uris)
 {
        struct rpki_uri *uri;
-       ck_assert_int_eq(0, uri_create_str(&uri, uri_str, strlen(uri_str)));
+       ck_assert_int_eq(0, uri_create_rsync_str(&uri, uri_str, strlen(uri_str)));
        ck_assert_int_eq(mark_as_downloaded(uri, visited_uris), 0);
        uri_refput(uri);
 }
@@ -71,7 +71,7 @@ static void
 assert_downloaded(char *uri_str, struct uri_list *visited_uris, bool expected)
 {
        struct rpki_uri *uri;
-       ck_assert_int_eq(0, uri_create_str(&uri, uri_str, strlen(uri_str)));
+       ck_assert_int_eq(0, uri_create_rsync_str(&uri, uri_str, strlen(uri_str)));
        ck_assert_int_eq(is_already_downloaded(uri, visited_uris), expected);
        uri_refput(uri);
 }
@@ -112,7 +112,7 @@ test_root_strategy(char *test, char *expected)
        struct rpki_uri *src;
        struct rpki_uri *dst;
 
-       ck_assert_int_eq(0, uri_create_str(&src, test, strlen(test)));
+       ck_assert_int_eq(0, uri_create_rsync_str(&src, test, strlen(test)));
        ck_assert_int_eq(handle_root_strategy(src, &dst), 0);
        ck_assert_str_eq(uri_get_global(dst), expected);
 
index 962cc4477333750350ad12b10dbdba82f5698aeb..0802761be151cd049850970dbda5fa6ae4f3d536 100644 (file)
@@ -11,6 +11,7 @@
 #include "log.c"
 #include "output_printer.c"
 #include "object/router_key.c"
+#include "rrdp/db_rrdp.c"
 #include "rtr/db/delta.c"
 #include "rtr/db/db_table.c"
 #include "rtr/db/rtr_db_impersonator.c"
index efe1e3588f4fac5e589e1fba67d9a26795f5087e..67d28207cdeea395a4c0a66e8c5bdfc7aa3dda3a 100644 (file)
@@ -12,6 +12,7 @@
 #include "output_printer.c"
 #include "crypto/base64.c"
 #include "object/router_key.c"
+#include "rrdp/db_rrdp.c"
 #include "rtr/pdu.c"
 #include "rtr/pdu_handler.c"
 #include "rtr/primitive_reader.c"
index aedfabc646a7221a0f15a719027f67c516fb4e1f..ee762f25d5b2e6907c1bf67255227aea7e04f995 100644 (file)
@@ -20,7 +20,8 @@
 
 int
 validation_prepare(struct validation **out, struct tal *tal,
-    struct validation_handler *validation_handler)
+    struct validation_handler *validation_handler,
+    struct rrdp_handler *rrdp_handler)
 {
        return 0;
 }