]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Separate recursive from non-recursive RSYNCs
authorAlberto Leiva Popper <ydahhrk@gmail.com>
Fri, 22 Mar 2019 17:50:36 +0000 (11:50 -0600)
committerAlberto Leiva Popper <ydahhrk@gmail.com>
Fri, 22 Mar 2019 17:50:36 +0000 (11:50 -0600)
Wraps up #4 properly.

src/config.c
src/config.h
src/config/string_array.c
src/config/string_array.h
src/rsync/rsync.c

index 73b1fc273b7c6f5e91fb40f561571a6ff4a00ad3..cc62fa8df115642b312bb40e011716126cbde9ca 100644 (file)
@@ -54,7 +54,10 @@ struct rpki_config {
 
        struct {
                char *program;
-               struct string_array args;
+               struct {
+                       struct string_array flat;
+                       struct string_array recursive;
+               } args;
        } rsync;
 
        struct {
@@ -179,10 +182,17 @@ static const struct option_field rsync_fields[] = {
                .availability = AVAILABILITY_TOML,
        }, {
                .id = 3001,
-               .name = "arguments",
+               .name = "arguments-recursive",
                .type = &gt_string_array,
-               .offset = offsetof(struct rpki_config, rsync.args),
-               .doc = "Arguments to send to the RSYNC program call",
+               .offset = offsetof(struct rpki_config, rsync.args.recursive),
+               .doc = "RSYNC program arguments that will trigger a recursive RSYNC",
+               .availability = AVAILABILITY_TOML,
+       }, {
+               .id = 3002,
+               .name = "arguments-flat",
+               .type = &gt_string_array,
+               .offset = offsetof(struct rpki_config, rsync.args.flat),
+               .doc = "RSYNC program arguments that will trigger a non-recursive RSYNC",
                .availability = AVAILABILITY_TOML,
        },
        { 0 },
@@ -368,7 +378,7 @@ set_default_values(void)
                "$LOCAL",
        };
 
-       size_t i;
+       int error;
 
        /*
         * Values that might need to be freed WILL be freed, so use heap
@@ -386,20 +396,20 @@ set_default_values(void)
        rpki_config.maximum_certificate_depth = 32;
 
        rpki_config.rsync.program = strdup("rsync");
-       if (rpki_config.rsync.program == NULL)
+       if (rpki_config.rsync.program == NULL) {
+               error = pr_enomem();
                goto revert_repository;
+       }
 
-       rpki_config.rsync.args.length = ARRAY_LEN(default_rsync_args);
-       rpki_config.rsync.args.array = calloc(rpki_config.rsync.args.length,
-           sizeof(char *));
-       if (rpki_config.rsync.args.array == NULL)
+       error = string_array_init(&rpki_config.rsync.args.recursive,
+           default_rsync_args, ARRAY_LEN(default_rsync_args));
+       if (error)
                goto revert_rsync_program;
-
-       for (i = 0; i < ARRAY_LEN(default_rsync_args); i++) {
-               rpki_config.rsync.args.array[i] = strdup(default_rsync_args[i]);
-               if (rpki_config.rsync.args.array[i] == NULL)
-                       goto revert_rsync_args;
-       }
+       /* Simply remove --recursive and --delete. */
+       error = string_array_init(&rpki_config.rsync.args.flat,
+           default_rsync_args + 2, ARRAY_LEN(default_rsync_args) - 2);
+       if (error)
+               goto revert_recursive_array;
 
        rpki_config.output.color = false;
        rpki_config.output.filename_format = FNF_GLOBAL;
@@ -408,15 +418,13 @@ set_default_values(void)
 
        return 0;
 
-revert_rsync_args:
-       for (i = 0; i < ARRAY_LEN(default_rsync_args); i++)
-               free(rpki_config.rsync.args.array[i]);
-       free(rpki_config.rsync.args.array);
+revert_recursive_array:
+       string_array_cleanup(&rpki_config.rsync.args.recursive);
 revert_rsync_program:
        free(rpki_config.rsync.program);
 revert_repository:
        free(rpki_config.local_repository);
-       return pr_enomem();
+       return error;
 }
 
 static int
@@ -597,9 +605,11 @@ config_get_rsync_program(void)
 }
 
 struct string_array const *
-config_get_rsync_args(void)
+config_get_rsync_args(bool is_ta)
 {
-       return &rpki_config.rsync.args;
+       return is_ta
+           ? &rpki_config.rsync.args.flat
+           : &rpki_config.rsync.args.recursive;
 }
 
 void
index c2d755d1fe7564e92092b0d2a8aba8495c2db371..341968c889e4472d33a78290f72e274070475564 100644 (file)
@@ -22,7 +22,7 @@ bool config_get_color_output(void);
 enum filename_format config_get_filename_format(void);
 FILE *config_get_roa_output(void);
 char *config_get_rsync_program(void);
-struct string_array const *config_get_rsync_args(void);
+struct string_array const *config_get_rsync_args(bool);
 
 /* Needed public by the TOML module */
 void *get_rpki_config_field(struct option_field const *);
index 0ee8dd329506b44d24ce63f6eaf2fdbe5c76c877..91a327cc4fc0a35d75569202303347ee0874aea6 100644 (file)
@@ -1,11 +1,45 @@
 #include "config/string_array.h"
 
+#include <errno.h>
 #include <getopt.h>
 #include <stdlib.h>
+#include <string.h>
 #include "log.h"
 
+int
+string_array_init(struct string_array *array, char const *const *values,
+    size_t len)
+{
+       size_t i;
+
+       array->length = len;
+
+       array->array = calloc(len, sizeof(char *));
+       if (array->array == NULL)
+               return -ENOMEM;
+
+       for (i = 0; i < len; i++) {
+               array->array[i] = strdup(values[i]);
+               if (array->array[i] == NULL) {
+                       string_array_cleanup(array);
+                       return -ENOMEM;
+               }
+       }
+
+       return 0;
+}
+
+void
+string_array_cleanup(struct string_array *array)
+{
+       size_t i;
+       for (i = 0; i < array->length; i++)
+               free(array->array[i]);
+       free(array->array);
+}
+
 static void
-print_string_array(struct group_fields const *group,
+string_array_print(struct group_fields const *group,
     struct option_field const *field, void *_value)
 {
        struct string_array *value = _value;
@@ -23,7 +57,7 @@ print_string_array(struct group_fields const *group,
 }
 
 static int
-parse_toml_string_array(struct option_field const *opt,
+string_array_parse_toml(struct option_field const *opt,
     struct toml_table_t *toml, void *_result)
 {
        toml_array_t *array;
@@ -67,14 +101,11 @@ fail:
 }
 
 static void
-free_string_array(void *_array)
+string_array_free(void *_array)
 {
        struct string_array *array = _array;
-       size_t i;
 
-       for (i = 0; i < array->length; i++)
-               free(array->array[i]);
-       free(array->array);
+       string_array_cleanup(array);
 
        array->array = NULL;
        array->length = 0;
@@ -83,8 +114,8 @@ free_string_array(void *_array)
 const struct global_type gt_string_array = {
        .has_arg = required_argument,
        .size = sizeof(char *const *),
-       .print = print_string_array,
-       .parse.toml = parse_toml_string_array,
-       .free = free_string_array,
+       .print = string_array_print,
+       .parse.toml = string_array_parse_toml,
+       .free = string_array_free,
        .arg_doc = "<sequence of strings>",
 };
index 02c73e29e3624e41fcdd777bab158feb9c2c5a0a..74989eaa9553314b36183a87862ecd1f8f7ea8a5 100644 (file)
@@ -11,4 +11,7 @@ struct string_array {
 
 extern const struct global_type gt_string_array;
 
+int string_array_init(struct string_array *, char const *const *, size_t);
+void string_array_cleanup(struct string_array *);
+
 #endif /* SRC_CONFIG_STRING_ARRAY_H_ */
index 47e6206ff555ca7cfa528bdaf3c245cd64979974..e8b93e96ce742a3ea257d442f5ce3ab1991ba706 100644 (file)
@@ -130,10 +130,10 @@ handle_root_strategy(struct rpki_uri const *src, struct rpki_uri *dst)
 }
 
 static int
-get_rsync_uri(struct rpki_uri const *requested_uri, bool force_strict,
+get_rsync_uri(struct rpki_uri const *requested_uri, bool is_ta,
     struct rpki_uri *rsync_uri)
 {
-       if (force_strict)
+       if (is_ta)
                return handle_strict_strategy(requested_uri, rsync_uri);
 
        switch (config_get_sync_strategy()) {
@@ -231,7 +231,7 @@ create_dir_recursive(char *localuri)
 }
 
 static void
-handle_child_thread(struct rpki_uri *uri)
+handle_child_thread(struct rpki_uri *uri, bool is_ta)
 {
        /* THIS FUNCTION MUST NEVER RETURN!!! */
 
@@ -240,7 +240,7 @@ handle_child_thread(struct rpki_uri *uri)
        unsigned int i;
        int error;
 
-       config_args = config_get_rsync_args();
+       config_args = config_get_rsync_args(is_ta);
        /*
         * We need to work on a copy, because the config args are immutable,
         * and we need to add the program name (for some reason) and NULL
@@ -285,7 +285,7 @@ handle_child_thread(struct rpki_uri *uri)
  * Downloads the @uri->global file into the @uri->local path.
  */
 static int
-do_rsync(struct rpki_uri *uri)
+do_rsync(struct rpki_uri *uri, bool is_ta)
 {
        pid_t child_pid;
        int child_status;
@@ -297,8 +297,10 @@ do_rsync(struct rpki_uri *uri)
 
        /* We need to fork because execvp() magics the thread away. */
        child_pid = fork();
-       if (child_pid == 0)
-               handle_child_thread(uri); /* This code is run by the child. */
+       if (child_pid == 0) {
+               /* This code is run by the child. */
+               handle_child_thread(uri, is_ta);
+       }
 
        /* This code is run by us. */
 
@@ -340,18 +342,14 @@ do_rsync(struct rpki_uri *uri)
 }
 
 /**
- * @force_srict:
- *     true:
- *         SYNC_OFF    -> SYNC_OFF
- *         SYNC_STRICT -> SYNC_STRICT
- *         SYNC_ROOT   -> SYNC_STRICT
- *     false:
- *         SYNC_OFF    -> SYNC_OFF
- *         SYNC_STRICT -> SYNC_STRICT
- *         SYNC_ROOT   -> SYNC_ROOT
+ * @is_ta: Are we rsync'ing the TA?
+ * The TA rsync will not be recursive, and will force SYNC_STRICT
+ * (unless the strategy has been set to SYNC_OFF.)
+ * Why? Because we should probably not trust the repository until we've
+ * validated the TA's public key.
  */
 int
-download_files(struct rpki_uri const *requested_uri, bool force_strict)
+download_files(struct rpki_uri const *requested_uri, bool is_ta)
 {
        /**
         * Note:
@@ -370,14 +368,14 @@ download_files(struct rpki_uri const *requested_uri, bool force_strict)
                return 0;
        }
 
-       error = get_rsync_uri(requested_uri, force_strict, &rsync_uri);
+       error = get_rsync_uri(requested_uri, is_ta, &rsync_uri);
        if (error)
                return error;
 
        pr_debug("Going to RSYNC '%s' ('%s').", rsync_uri.global,
            rsync_uri.local);
 
-       error = do_rsync(&rsync_uri);
+       error = do_rsync(&rsync_uri, is_ta);
        if (!error)
                error = mark_as_downloaded(&rsync_uri);