]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Add argument to set the desired output format
authorpcarana <pc.moreno2099@gmail.com>
Thu, 18 Feb 2021 02:08:30 +0000 (20:08 -0600)
committerpcarana <pc.moreno2099@gmail.com>
Thu, 18 Feb 2021 02:08:30 +0000 (20:08 -0600)
src/Makefile.am
src/config.c
src/config.h
src/config/output_format.c [new file with mode: 0644]
src/config/output_format.h [new file with mode: 0644]
src/output_printer.c

index ccf10fc8cd31415b06ac5dd4b3c289c34baddc11..86a8a15a4783f1ac07a8e71cdbacf16b9f0daaa3 100644 (file)
@@ -47,6 +47,7 @@ fort_SOURCES += config/filename_format.h config/filename_format.c
 fort_SOURCES += config/log_conf.h config/log_conf.c
 fort_SOURCES += config/mode.c config/mode.h
 fort_SOURCES += config/incidences.h config/incidences.c
+fort_SOURCES += config/output_format.h config/output_format.c
 fort_SOURCES += config/rrdp_conf.h config/rrdp_conf.c
 fort_SOURCES += config/rsync_strategy.h config/rsync_strategy.c
 fort_SOURCES += config/str.c config/str.h
index 43cc8ca35d5c8d71deddd22c780a61f6239744ba..de6ca67a50206b5f9a01dbdfdb2a6360b46de1c2 100644 (file)
@@ -186,8 +186,8 @@ struct rpki_config {
                char *roa;
                /** File where the validated BGPsec certs will be stored */
                char *bgpsec;
-                /** File where the validated ROAs will be stored in JSON format */
-               char *roa_json;
+               /** Format for the output */
+               enum output_format format;
        } output;
 
        /* ASN1 decoder max stack size allowed */
@@ -690,22 +690,21 @@ static const struct option_field options[] = {
                .name = "output.roa",
                .type = &gt_string,
                .offset = offsetof(struct rpki_config, output.roa),
-               .doc = "File where ROAs will be stored in CSV format, use '-' to print at console",
+               .doc = "File where ROAs will be stored, use '-' to print at console",
                .arg_doc = "<file>",
        }, {
                .id = 6001,
                .name = "output.bgpsec",
                .type = &gt_string,
                .offset = offsetof(struct rpki_config, output.bgpsec),
-               .doc = "File where BGPsec Router Keys will be stored in CSV format, use '-' to print at console",
+               .doc = "File where BGPsec Router Keys will be stored, use '-' to print at console",
                .arg_doc = "<file>",
        }, {
-               .id = 6002,
-               .name = "output.roa.json",
-               .type = &gt_string,
-                .offset = offsetof(struct rpki_config, output.roa_json),
-               .doc = "File where ROAs will be stored in JSON format, use '-' to print at console",
-               .arg_doc = "<file>",
+               .id = 6002,
+               .name = "output.format",
+               .type = &gt_output_format,
+               .offset = offsetof(struct rpki_config, output.format),
+               .doc = "Format to print ROAs and BGPsec Router Keys",
        },
 
        {
@@ -985,8 +984,8 @@ set_default_values(void)
        }
 
        rpki_config.output.roa = NULL;
-       rpki_config.output.roa_json = NULL;
        rpki_config.output.bgpsec = NULL;
+       rpki_config.output.format = OFM_CSV;
 
        rpki_config.asn1_decode_max_stack = 4096; /* 4kB */
        rpki_config.stale_repository_period = 43200; /* 12 hours */
@@ -1448,15 +1447,15 @@ config_get_output_roa(void)
 }
 
 char const *
-config_get_output_roa_json(void)
+config_get_output_bgpsec(void)
 {
-       return rpki_config.output.roa_json;
+       return rpki_config.output.bgpsec;
 }
 
-char const *
-config_get_output_bgpsec(void)
+enum output_format
+config_get_output_format(void)
 {
-       return rpki_config.output.bgpsec;
+       return rpki_config.output.format;
 }
 
 unsigned int
index e77721679ba8d764dc63f84d6ed1afa7476a2bb6..680109c98e68d6fa0e77ebc455dd94b6c0c34a3b 100644 (file)
@@ -7,6 +7,7 @@
 #include "config/filename_format.h"
 #include "config/log_conf.h"
 #include "config/mode.h"
+#include "config/output_format.h"
 #include "config/rsync_strategy.h"
 #include "config/string_array.h"
 #include "config/types.h"
@@ -48,8 +49,8 @@ unsigned int config_get_http_priority(void);
 unsigned int config_get_http_retry_count(void);
 unsigned int config_get_http_retry_interval(void);
 char const *config_get_output_roa(void);
-char const *config_get_output_roa_json(void);
 char const *config_get_output_bgpsec(void);
+enum output_format config_get_output_format(void);
 unsigned int config_get_asn1_decode_max_stack(void);
 unsigned int config_get_stale_repository_period(void);
 
diff --git a/src/config/output_format.c b/src/config/output_format.c
new file mode 100644 (file)
index 0000000..525d4b0
--- /dev/null
@@ -0,0 +1,65 @@
+#include "config/output_format.h"
+
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "log.h"
+#include "config/str.h"
+
+#define OFM_VALUE_CSV  "csv"
+#define OFM_VALUE_JSON "json"
+
+#define DEREFERENCE(void_value) (*((enum output_format *) void_value))
+
+static void
+print_output_format(struct option_field const *field, void *value)
+{
+       char const *str = "<unknown>";
+
+       switch (DEREFERENCE(value)) {
+       case OFM_CSV:
+               str = OFM_VALUE_CSV;
+               break;
+       case OFM_JSON:
+               str = OFM_VALUE_JSON;
+               break;
+       }
+
+       pr_op_info("%s: %s", field->name, str);
+}
+
+static int
+parse_argv_output_format(struct option_field const *field, char const *str,
+    void *result)
+{
+       if (strcmp(str, OFM_VALUE_CSV) == 0)
+               DEREFERENCE(result) = OFM_CSV;
+       else if (strcmp(str, OFM_VALUE_JSON) == 0)
+               DEREFERENCE(result) = OFM_JSON;
+       else
+               return pr_op_err("Unknown output format %s: '%s'",
+                   field->name, str);
+
+       return 0;
+}
+
+static int
+parse_json_output_format(struct option_field const *opt, json_t *json,
+    void *result)
+{
+       char const *string;
+       int error;
+
+       error = parse_json_string(json, opt->name, &string);
+       return error ? error : parse_argv_output_format(opt, string, result);
+}
+
+const struct global_type gt_output_format = {
+       .has_arg = required_argument,
+       .size = sizeof(enum output_format),
+       .print = print_output_format,
+       .parse.argv = parse_argv_output_format,
+       .parse.json = parse_json_output_format,
+       .arg_doc = OFM_VALUE_CSV "|" OFM_VALUE_JSON,
+};
diff --git a/src/config/output_format.h b/src/config/output_format.h
new file mode 100644 (file)
index 0000000..537e94c
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef SRC_CONFIG_OUTPUT_FORMAT_H_
+#define SRC_CONFIG_OUTPUT_FORMAT_H_
+
+#include "config/types.h"
+
+enum output_format {
+       /* CSV format */
+       OFM_CSV,
+       /* JSON format */
+       OFM_JSON,
+};
+
+extern const struct global_type gt_output_format;
+
+#endif /* SRC_CONFIG_OUTPUT_FORMAT_H_ */
index 18c98b41d59d7579ba20f2efef7842c6a953e7db..7c35de55d5183e41ae3b0666cc83b70248487c12 100644 (file)
 
 static char addr_buf[INET6_ADDRSTRLEN];
 
+typedef struct json_out {
+       FILE *file;
+       bool first;
+} JSON_OUT;
+
 static int
 load_output_file(char const *output, FILE **result, bool *fopen)
 {
@@ -40,7 +45,7 @@ load_output_file(char const *output, FILE **result, bool *fopen)
 }
 
 static int
-print_roa(struct vrp const *vrp, void *arg)
+print_roa_csv(struct vrp const *vrp, void *arg)
 {
        FILE *out = arg;
 
@@ -62,40 +67,44 @@ print_roa(struct vrp const *vrp, void *arg)
        return 0;
 }
 
-typedef struct json_out { FILE *file; int first; } JSON_OUT;
-
 static int
 print_roa_json(struct vrp const *vrp, void *arg)
 {
        JSON_OUT *json_out = arg;
-       FILE *out = json_out->file;
+       FILE *out;
 
+       out = json_out->file;
        if (!json_out->first)
                fprintf(out, ",");
 
-
        switch (vrp->addr_fam) {
        case AF_INET:
-               fprintf(out, "\n  { \"asn\" : \"AS%u\", \"prefix\" : \"%s/%u\", \"maxLength\" : %u }", vrp->asn,
-                       addr2str4(&vrp->prefix.v4, addr_buf), vrp->prefix_length,
-                       vrp->max_prefix_length);
+               fprintf(out,
+                   "\n  { \"asn\" : \"AS%u\", \"prefix\" : \"%s/%u\", \"maxLength\" : %u }",
+                   vrp->asn,
+                   addr2str4(&vrp->prefix.v4, addr_buf),
+                   vrp->prefix_length,
+                   vrp->max_prefix_length);
                break;
        case AF_INET6:
-                fprintf(out, "\n  { \"asn\" : \"AS%u\", \"prefix\" : \"%s/%u\", \"maxLength\" : %u }", vrp->asn,
-                       addr2str6(&vrp->prefix.v6, addr_buf), vrp->prefix_length,
-                       vrp->max_prefix_length);
+               fprintf(out,
+                   "\n  { \"asn\" : \"AS%u\", \"prefix\" : \"%s/%u\", \"maxLength\" : %u }",
+                   vrp->asn,
+                   addr2str6(&vrp->prefix.v6, addr_buf),
+                   vrp->prefix_length,
+                   vrp->max_prefix_length);
                break;
        default:
                pr_crit("Unknown family type");
        }
 
-       json_out->first = 0;
+       json_out->first = false;
        return 0;
 }
 
 /* Print as base64url strings without trailing pad */
 static int
-print_router_key(struct router_key const *key, void *arg)
+print_router_key_csv(struct router_key const *key, void *arg)
 {
        FILE *out = arg;
        char *buf1, *buf2;
@@ -117,6 +126,40 @@ free1:
        return error;
 }
 
+/* Print as base64url strings without trailing pad */
+static int
+print_router_key_json(struct router_key const *key, void *arg)
+{
+       JSON_OUT *json_out = arg;
+       FILE *out;
+       char *buf1, *buf2;
+       int error;
+
+       error = base64url_encode(key->ski, RK_SKI_LEN, &buf1);
+       if (error)
+               return error;
+
+       error = base64url_encode(key->spk, RK_SPKI_LEN, &buf2);
+       if (error)
+               goto free1;
+
+       out = json_out->file;
+       if (!json_out->first)
+               fprintf(out, ",");
+
+       fprintf(out,
+           "\n  { \"asn\" : \"AS%u\", \"ski\" : \"%s\", \"spki\" : \"%s\" }",
+           key->as,
+           buf1,
+           buf2);
+
+       free(buf2);
+free1:
+       free(buf1);
+       json_out->first = false;
+       return error;
+}
+
 static int
 open_file(char const *loc, FILE **out, bool *fopen)
 {
@@ -137,6 +180,7 @@ static void
 print_roas(struct db_table *db)
 {
        FILE *out;
+       JSON_OUT json_out;
        bool fopen;
        int error;
 
@@ -145,33 +189,18 @@ print_roas(struct db_table *db)
        if (error)
                return;
 
-       fprintf(out, "ASN,Prefix,Max prefix length\n");
-       error = db_table_foreach_roa(db, print_roa, out);
-       if (fopen)
-               file_close(out);
-       if (error)
-               pr_op_err("Error printing ROAs");
-}
-
-static void
-print_roas_json(struct db_table *db)
-{
-       FILE *out;
-       bool fopen;
-       int error;
-
-       out = NULL;
-       error = open_file(config_get_output_roa_json(), &out, &fopen);
-       if (error)
-               return;
+       if (config_get_output_format() == OFM_CSV) {
+               fprintf(out, "ASN,Prefix,Max prefix length\n");
+               error = db_table_foreach_roa(db, print_roa_csv, out);
+       } else {
+               json_out.file = out;
+               json_out.first = true;
 
-       JSON_OUT json_out;
-       json_out.file = out;
-       json_out.first = 1;
+               fprintf(out, "{ \"roas\" : [");
+               error = db_table_foreach_roa(db, print_roa_json, &json_out);
+               fprintf(out, "\n]}\n");
+       }
 
-       fprintf(out, "{ \"roas\" : [");
-       error = db_table_foreach_roa(db, print_roa_json, &json_out);
-       fprintf(out, "\n]}\n");
        if (fopen)
                file_close(out);
        if (error)
@@ -182,6 +211,7 @@ static void
 print_router_keys(struct db_table *db)
 {
        FILE *out;
+       JSON_OUT json_out;
        bool fopen;
        int error;
 
@@ -190,8 +220,21 @@ print_router_keys(struct db_table *db)
        if (error)
                return;
 
-       fprintf(out, "ASN,Subject Key Identifier,Subject Public Key Info\n");
-       error = db_table_foreach_router_key(db, print_router_key, out);
+       if (config_get_output_format() == OFM_CSV) {
+               fprintf(out,
+                   "ASN,Subject Key Identifier,Subject Public Key Info\n");
+               error = db_table_foreach_router_key(db, print_router_key_csv,
+                   out);
+       } else {
+               json_out.file = out;
+               json_out.first = true;
+
+               fprintf(out, "{ \"router_keys\" : [");
+               error = db_table_foreach_router_key(db, print_router_key_json,
+                   &json_out);
+               fprintf(out, "\n]}\n");
+       }
+
        if (fopen)
                file_close(out);
        if (error)
@@ -202,6 +245,5 @@ void
 output_print_data(struct db_table *db)
 {
        print_roas(db);
-       print_roas_json(db);
        print_router_keys(db);
 }