]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Allow some nulls in the configuration JSON
authorAlberto Leiva Popper <ydahhrk@gmail.com>
Wed, 29 Nov 2023 23:13:22 +0000 (17:13 -0600)
committerAlberto Leiva Popper <ydahhrk@gmail.com>
Wed, 29 Nov 2023 23:13:22 +0000 (17:13 -0600)
While playing with the configuration sample, I found out that setting
a `null` slurm property in the JSON was rejected, even though the SLURM
file itself is not mandatory.

So rethink this, and for a few other fields as well.

src/config.c
src/config/str.c
src/config/types.h

index 4d851bc0a5c554777f4e70bfcf17acc8779c352e..de54d9086e000f9a36f2f8f612d95baa35227659 100644 (file)
@@ -259,6 +259,7 @@ static const struct option_field options[] = {
                .offset = offsetof(struct rpki_config, tal),
                .doc = "Path to the TAL file or TALs directory",
                .arg_doc = "<file>|<directory>",
+               .json_null_allowed = false,
        }, {
                .id = 'r',
                .name = "local-repository",
@@ -266,6 +267,7 @@ static const struct option_field options[] = {
                .offset = offsetof(struct rpki_config, local_repository),
                .doc = "Directory where the repository local cache will be stored/read",
                .arg_doc = "<directory>",
+               .json_null_allowed = false,
        }, {
                .id = 2001,
                .name = "shuffle-uris",
@@ -292,7 +294,8 @@ static const struct option_field options[] = {
                .type = &gt_string,
                .offset = offsetof(struct rpki_config, slurm),
                .doc = "Path to the SLURM file or SLURMs directory (files must have the extension .slurm)",
-               .arg_doc = "<file>|<directory>"
+               .arg_doc = "<file>|<directory>",
+               .json_null_allowed = true,
        }, {
                .id = 1004,
                .name = "mode",
@@ -328,6 +331,7 @@ static const struct option_field options[] = {
                .type = &gt_string,
                .offset = offsetof(struct rpki_config, server.port),
                .doc = "Default port to which RTR server addresses will bind itself to. Can be a string, in which case a number will be resolved. If all of the addresses have a port, this value isn't utilized.",
+               .json_null_allowed = false,
        }, {
                .id = 5002,
                .name = "server.backlog",
@@ -434,6 +438,7 @@ static const struct option_field options[] = {
                .type = &gt_string,
                .offset = offsetof(struct rpki_config, rsync.strategy),
                .doc = "Deprecated; does nothing.",
+               .json_null_allowed = true,
                .deprecated = true,
        }, {
                .id = 3003,
@@ -459,6 +464,7 @@ static const struct option_field options[] = {
                .doc = "Name of the program needed to execute an RSYNC",
                .arg_doc = "<path to program>",
                .availability = AVAILABILITY_JSON,
+               .json_null_allowed = false,
        }, {
                .id = 3006,
                .name = "rsync.arguments-recursive",
@@ -517,6 +523,7 @@ static const struct option_field options[] = {
                .type = &gt_string,
                .offset = offsetof(struct rpki_config, http.user_agent),
                .doc = "User-Agent to use at HTTP requests, eg. Fort Validator Local/1.0",
+               .json_null_allowed = false,
        }, {
                .id = 9012,
                .name = "http.max-redirs",
@@ -572,6 +579,7 @@ static const struct option_field options[] = {
                .offset = offsetof(struct rpki_config, http.ca_path),
                .doc = "Directory where CA certificates are found, used to verify the peer",
                .arg_doc = "<directory>",
+               .json_null_allowed = false,
        },
 
        /* Logging fields */
@@ -600,6 +608,7 @@ static const struct option_field options[] = {
                .offset = offsetof(struct rpki_config, log.tag),
                .doc = "Text tag to identify operation logs",
                .arg_doc = "<string>",
+               .json_null_allowed = true,
        }, {
                .id = 4004,
                .name = "log.facility",
@@ -645,6 +654,7 @@ static const struct option_field options[] = {
                .offset = offsetof(struct rpki_config, validation_log.tag),
                .doc = "Text tag to identify validation logs",
                .arg_doc = "<string>",
+               .json_null_allowed = true,
        }, {
                .id = 4014,
                .name = "validation-log.facility",
@@ -683,6 +693,7 @@ static const struct option_field options[] = {
                .offset = offsetof(struct rpki_config, output.roa),
                .doc = "File where ROAs will be stored, use '-' to print at console",
                .arg_doc = "<file>",
+               .json_null_allowed = true,
        }, {
                .id = 6001,
                .name = "output.bgpsec",
@@ -690,6 +701,7 @@ static const struct option_field options[] = {
                .offset = offsetof(struct rpki_config, output.bgpsec),
                .doc = "File where BGPsec Router Keys will be stored, use '-' to print at console",
                .arg_doc = "<file>",
+               .json_null_allowed = true,
        }, {
                .id = 6002,
                .name = "output.format",
index e3b2a9a11926870453f22ddcf8f97364638c47e1..2ac77c2e6a2a6db45d05f8ea9336d03392a51981 100644 (file)
@@ -45,7 +45,23 @@ string_parse_json(struct option_field const *opt, json_t *json, void *result)
 
        string = NULL;
        error = parse_json_string(json, opt->name, &string);
-       return error ? error : string_parse_argv(opt, string, result);
+       if (error)
+               return error;
+
+       if (string == NULL) {
+               if (opt->json_null_allowed) {
+                       DEREFERENCE(result) = NULL;
+                       return 0;
+               } else {
+                       if (string == NULL) {
+                               return pr_op_err(
+                                   "The '%s' field is not allowed to be null.",
+                                   opt->name);
+                       }
+               }
+       }
+
+       return string_parse_argv(opt, string, result);
 }
 
 static void
@@ -70,6 +86,11 @@ const struct global_type gt_string = {
 int
 parse_json_string(json_t *json, char const *name, char const **result)
 {
+       if (json_is_null(json)) {
+               *result = NULL;
+               return 0;
+       }
+
        if (!json_is_string(json))
                return pr_op_err("The '%s' element is not a JSON string.", name);
 
index c5c3d19d942285aaedb4eb899b450e0c31ce0029..f2dc0bc76ed20220e3c4ecb2f64f0231e8989aa0 100644 (file)
@@ -81,6 +81,8 @@ struct option_field {
         * Optional.
         */
        int availability;
+       /* Explicit null only; absence of field implies default value. */
+       bool json_null_allowed;
        bool deprecated;
        unsigned int min;
        unsigned int max;