From: Alberto Leiva Popper Date: Wed, 29 Nov 2023 23:13:22 +0000 (-0600) Subject: Allow some nulls in the configuration JSON X-Git-Tag: 1.6.0~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=63e71946db91119417b94bd09ea6829d8f11f84a;p=thirdparty%2FFORT-validator.git Allow some nulls in the configuration JSON 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. --- diff --git a/src/config.c b/src/config.c index 4d851bc0..de54d908 100644 --- a/src/config.c +++ b/src/config.c @@ -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 = "|", + .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 = "", + .json_null_allowed = false, }, { .id = 2001, .name = "shuffle-uris", @@ -292,7 +294,8 @@ static const struct option_field options[] = { .type = >_string, .offset = offsetof(struct rpki_config, slurm), .doc = "Path to the SLURM file or SLURMs directory (files must have the extension .slurm)", - .arg_doc = "|" + .arg_doc = "|", + .json_null_allowed = true, }, { .id = 1004, .name = "mode", @@ -328,6 +331,7 @@ static const struct option_field options[] = { .type = >_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 = >_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 = "", .availability = AVAILABILITY_JSON, + .json_null_allowed = false, }, { .id = 3006, .name = "rsync.arguments-recursive", @@ -517,6 +523,7 @@ static const struct option_field options[] = { .type = >_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 = "", + .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 = "", + .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 = "", + .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 = "", + .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 = "", + .json_null_allowed = true, }, { .id = 6002, .name = "output.format", diff --git a/src/config/str.c b/src/config/str.c index e3b2a9a1..2ac77c2e 100644 --- a/src/config/str.c +++ b/src/config/str.c @@ -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); diff --git a/src/config/types.h b/src/config/types.h index c5c3d19d..f2dc0bc7 100644 --- a/src/config/types.h +++ b/src/config/types.h @@ -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;