]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Add '--output-file-name-format' option
authorAlberto Leiva Popper <ydahhrk@gmail.com>
Tue, 5 Mar 2019 16:51:46 +0000 (10:51 -0600)
committerAlberto Leiva Popper <ydahhrk@gmail.com>
Tue, 5 Mar 2019 21:12:40 +0000 (15:12 -0600)
Decides which version of the file name should be printed during
most debug and error messages.

Also found myself starting the manpage.

18 files changed:
man/rpki-validator.8 [new file with mode: 0644]
src/Makefile.am
src/asn1/signed_data.c
src/config.c
src/config.h
src/main.c
src/object/certificate.c
src/object/crl.c
src/object/ghostbusters.c
src/object/manifest.c
src/object/roa.c
src/rpp.c
src/str.c
src/str.h
src/thread_var.c
src/thread_var.h
src/uri.c
src/uri.h

diff --git a/man/rpki-validator.8 b/man/rpki-validator.8
new file mode 100644 (file)
index 0000000..9ff8eac
--- /dev/null
@@ -0,0 +1,150 @@
+.TH rpki-validator 8 2019-03-5 v0.0.1-beta "RPKI certificate path validator"
+
+.SH NAME
+rpki-validator - Actually still unnamed officially.
+
+.SH OPTIONS
+
+--help
+.RS 4
+Print long usage message.
+.RE
+.P
+
+--usage
+.RS 4
+Print short usage message.
+.RE
+.P
+
+--version
+.RS 4
+Print program version.
+.RE
+.P
+
+--configuration-file=<file>
+.RS 4
+Path to a TOML file from which additional configuration will be read.
+.RE
+.P
+
+--local-repository=<directory>
+.RS 4
+Path to a directory where the local cache of the repository will be stored
+and/or read.
+.RE
+.P
+
+--sync-strategy=(off|strict|root)
+.RS 4
+RSYNC download strategy.
+.P
+off
+.RS 4
+Skip all RSYNCs. (Validate the existing cache repository pointed by --local-repository.)
+.RE
+.P
+strict
+.RS 4
+RSYNC every repository publication point separately. Only skip publication
+points that have already been downloaded during the current validation cycle.
+(Assuming each synchronization is recursive.)
+.P
+For example, suppose the validator gets certificates whose caRepository access
+methods (in their Subject Information Access extensions) point to the following
+publication points:
+.P
+1. rsync://rpki.example.com/foo/bar/
+.br
+2. rsync://rpki.example.com/foo/qux/
+.br
+3. rsync://rpki.example.com/foo/bar/
+.br
+4. rsync://rpki.example.com/foo/corge/grault/
+.br
+5. rsync://rpki.example.com/foo/corge/
+.br
+6. rsync://rpki.example.com/foo/corge/waldo/
+.P
+A validator following the `strict` strategy would download `bar`, download
+`qux`, skip `bar`, download `corge/grault`, download `corge` and skip
+`corge/waldo`.
+.P
+This is the slowest, but also the strictly correct sync strategy.
+.RE
+.P
+root
+.RS 4
+For each publication point found, guess the root of its repository and RSYNC
+that instead. Then skip any subsequent children of said root.
+.P
+(To guess the root of a repository, the validator counts four slashes, and
+prunes the rest of the URL.)
+.P
+Reusing the caRepository URLs from the `strict` strategy (above) as example, a
+validator following the `root` strategy would download
+`rsync://rpki.example.com/foo`, and then skip everything else.
+.P
+Assuming that the repository is specifically structured to be found within as
+few roots as possible, and they contain minimal RPKI-unrelated noise files, this
+is the fastest synchronization strategy. At time of writing, this is true for
+all the current official repositories.
+.RE
+.RE
+.P
+
+--maximum-certificate-depth=<unsigned integer>
+.RS 4
+Maximum allowable certificate chain length.
+.P
+(Required to prevent loops and "other degenerate forms of the logical RPKI
+hierarchy." (RFC 6481))
+.RE
+.P
+
+--tal=<file>
+.RS 4
+Path to the TAL file the validation will sprawl from.
+.P
+The TAL ("Trust Anchor Locator") is a text file that lists a few URLs which can
+be used to access the "Trust Anchor" (the root of a particular RPKI tree) and
+its public key. (See RFC 7730.)
+.RE
+.P
+
+--shuffle-uris
+.RS 4
+Shuffle URIs in the TAL before accessing them.
+.RE
+.P
+
+--color-output
+.RS 4
+Print ANSI color codes?
+.RE
+.P
+
+--output-file-name-format=(global-url|local-path|file-name)
+.RS 4
+Decides which version of file names should be printed during most debug/error
+messages.
+.P
+Suppose a certificate was downloaded from `rsync://rpki.example.com/foo/bar/baz.cer` into the local cache `repository/`:
+.P
+global-url
+.RS 4
+will print the certificate's name as `rsync://rpki.example.com/foo/bar/baz.cer`.
+.RE
+.P
+local-path
+.RS 4
+will print the certificate's name as `repository/rpki.example.com/foo/bar/baz.cer`.
+.RE
+.P
+file-name
+.RS 4
+will print the certificate's name as `baz.cer`.
+.RE
+.P
+.RE
\ No newline at end of file
index a9bb0410c0fee841101dabf6d3472daf01048f52..0d521a449a3052ab612b8c67d6ba5d3671a6083a 100644 (file)
@@ -122,7 +122,7 @@ GCC_WARNS += -Whsa
 
 # I don't mind too much increasing these.
 # Just make sure that you know what you're doing.
-GCC_WARNS += -Wlarger-than=1024 -Walloc-size-larger-than=4096
+GCC_WARNS += -Wlarger-than=2048 -Walloc-size-larger-than=4096
 GCC_WARNS += -Wframe-larger-than=1024 -Wstack-usage=1024
 
 # Can't use because of dependencies: -Waggregate-return
index 26790feb6ff12cd638161ed92295b05555cb4564..745f5db6cd8c925dd3ad29e0745f7d1fa73fb3cb 100644 (file)
@@ -397,8 +397,8 @@ validate(struct SignedData *sdata, struct signed_object_args *args)
         *
         * So, nothing to do for now.
         *
-        * TODO "In the certificate, the OID appears in the signature and
-        * signatureAlgorithm fields [RFC4055]." So it has to be the same as
+        * TODO (field) "In the certificate, the OID appears in the signature
+        * and signatureAlgorithm fields [RFC4055]." So it has to be the same as
         * some other field?
         */
 
index 87a8cd8751354b90ff73730868740d3706fa105c..e787d05e600f446e55074a382c00352a4a6e620a 100644 (file)
@@ -48,15 +48,19 @@ struct rpki_config {
         * Prevents arbitrarily long paths and loops.
         */
        unsigned int maximum_certificate_depth;
-       /** Print ANSI color codes? */
-       bool color_output;
 
        struct {
                char *program;
                struct string_array args;
        } rsync;
-};
 
+       struct {
+               /** Print ANSI color codes? */
+               bool color;
+               /** Format in which file names will be printed. */
+               enum filename_format filename_format;
+       } output;
+};
 
 static void print_usage(FILE *, bool);
 
@@ -71,6 +75,7 @@ DECLARE_PRINT_FN(print_u_int);
 DECLARE_PRINT_FN(print_string);
 DECLARE_PRINT_FN(print_string_array);
 DECLARE_PRINT_FN(print_sync_strategy);
+DECLARE_PRINT_FN(print_filename_format);
 
 #define DECLARE_PARSE_ARGV_FN(name)                                    \
        static int name(                                                \
@@ -82,6 +87,7 @@ DECLARE_PARSE_ARGV_FN(parse_argv_bool);
 DECLARE_PARSE_ARGV_FN(parse_argv_u_int);
 DECLARE_PARSE_ARGV_FN(parse_argv_string);
 DECLARE_PARSE_ARGV_FN(parse_argv_sync_strategy);
+DECLARE_PARSE_ARGV_FN(parse_argv_filename_format);
 
 #define DECLARE_PARSE_TOML_FN(name)                                    \
        static int name(                                                \
@@ -94,6 +100,7 @@ DECLARE_PARSE_TOML_FN(parse_toml_u_int);
 DECLARE_PARSE_TOML_FN(parse_toml_string);
 DECLARE_PARSE_TOML_FN(parse_toml_sync_strategy);
 DECLARE_PARSE_TOML_FN(parse_toml_string_array);
+DECLARE_PARSE_TOML_FN(parse_toml_filename_format);
 
 #define DECLARE_HANDLE_FN(name)                                                \
        static int name(                                                \
@@ -158,6 +165,15 @@ static const struct global_type gt_sync_strategy = {
        .arg_doc = SYNC_VALUE_OFF "|" SYNC_VALUE_STRICT "|" SYNC_VALUE_ROOT,
 };
 
+static const struct global_type gt_filename_format = {
+       .has_arg = required_argument,
+       .size = sizeof(enum filename_format),
+       .print = print_filename_format,
+       .parse.argv = parse_argv_filename_format,
+       .parse.toml = parse_toml_filename_format,
+       .arg_doc = FNF_VALUE_GLOBAL "|" FNF_VALUE_LOCAL "|" FNF_VALUE_NAME,
+};
+
 /**
  * An option that takes no arguments, is not correlated to any rpki_config
  * fields, and is entirely managed by its handler function.
@@ -193,7 +209,7 @@ static const struct option_field global_fields[] = {
                .name = "configuration-file",
                .type = &gt_string,
                .handler = handle_toml,
-               .doc = "TOML file the configuration will be read from.",
+               .doc = "TOML file additional configuration will be read from",
                .arg_doc = "<file>",
                .availability = AVAILABILITY_GETOPT,
        }, {
@@ -201,21 +217,27 @@ static const struct option_field global_fields[] = {
                .name = "local-repository",
                .type = &gt_string,
                .offset = offsetof(struct rpki_config, local_repository),
-               .doc = "Local repository path.",
+               .doc = "Directory where the repository local cache will be stored/read",
                .arg_doc = "<directory>",
        }, {
                .id = 1001,
                .name = "sync-strategy",
                .type = &gt_sync_strategy,
                .offset = offsetof(struct rpki_config, sync_strategy),
-               .doc = "RSYNC download strategy.",
+               .doc = "RSYNC download strategy",
        }, {
-               .id = 'c',
-               .name = "color-output",
-               .type = &gt_bool,
-               .offset = offsetof(struct rpki_config, color_output),
-               .doc = "Print ANSI color codes?",
-               .availability = AVAILABILITY_GETOPT,
+               .id = 1002,
+               .name = "maximum-certificate-depth",
+               .type = &gt_u_int,
+               .offset = offsetof(struct rpki_config,
+                   maximum_certificate_depth),
+               .doc = "Maximum allowable certificate chain length",
+               .min = 1,
+               /**
+                * It cannot be UINT_MAX, because then the actual number will
+                * overflow and will never be bigger than this.
+                */
+               .max = UINT_MAX - 1,
        },
        { 0 },
 };
@@ -226,27 +248,14 @@ static const struct option_field tal_fields[] = {
                .name = "tal",
                .type = &gt_string,
                .offset = offsetof(struct rpki_config, tal),
-               .doc = "TAL file path",
-               .arg_doc = "<file name>",
+               .doc = "Path to the TAL file",
+               .arg_doc = "<file>",
        }, {
                .id = 2000,
                .name = "shuffle-uris",
                .type = &gt_bool,
                .offset = offsetof(struct rpki_config, shuffle_uris),
-               .doc = "Shuffle URIs in the TAL.",
-       }, {
-               .id = 2001,
-               .name = "maximum-certificate-depth",
-               .type = &gt_u_int,
-               .offset = offsetof(struct rpki_config,
-                   maximum_certificate_depth),
-               .doc = "Prevents arbitrarily long paths and loops.",
-               .min = 1,
-               /**
-                * It cannot be UINT_MAX, because then the actual number will
-                * overflow and will never be bigger than this.
-                */
-               .max = UINT_MAX - 1,
+               .doc = "Shuffle URIs in the TAL before accessing them",
        },
        { 0 },
 };
@@ -257,7 +266,7 @@ static const struct option_field rsync_fields[] = {
                .name = "program",
                .type = &gt_string,
                .offset = offsetof(struct rpki_config, rsync.program),
-               .doc = "Name of the program needed to execute an RSYNC.",
+               .doc = "Name of the program needed to execute an RSYNC",
                .arg_doc = "<path to program>",
                .availability = AVAILABILITY_TOML,
        }, {
@@ -265,12 +274,29 @@ static const struct option_field rsync_fields[] = {
                .name = "arguments",
                .type = &gt_string_array,
                .offset = offsetof(struct rpki_config, rsync.args),
-               .doc = "Arguments to send to the RSYNC program call.",
+               .doc = "Arguments to send to the RSYNC program call",
                .availability = AVAILABILITY_TOML,
        },
        { 0 },
 };
 
+static const struct option_field output_fields[] = {
+       {
+               .id = 'c',
+               .name = "color-output",
+               .type = &gt_bool,
+               .offset = offsetof(struct rpki_config, output.color),
+               .doc = "Print ANSI color codes?",
+       }, {
+               .id = 4000,
+               .name = "output-file-name-format",
+               .type = &gt_filename_format,
+               .offset = offsetof(struct rpki_config, output.filename_format),
+               .doc = "File name variant to print during debug/error messages",
+       },
+       { 0 },
+};
+
 static const struct group_fields groups[] = {
        {
                .name = "root",
@@ -281,6 +307,9 @@ static const struct group_fields groups[] = {
        }, {
                .name = "rsync",
                .options = rsync_fields,
+       }, {
+               .name = "output",
+               .options = output_fields,
        },
        { NULL },
 };
@@ -366,6 +395,28 @@ print_sync_strategy(struct group_fields const *group,
        pr_info("%s.%s: %s", group->name, field->name, str);
 }
 
+void
+print_filename_format(struct group_fields const *group,
+    struct option_field const *field, void *value)
+{
+       enum filename_format *format = value;
+       char const *str = "<unknown>";
+
+       switch (*format) {
+       case FNF_GLOBAL:
+               str = FNF_VALUE_GLOBAL;
+               break;
+       case FNF_LOCAL:
+               str = FNF_VALUE_LOCAL;
+               break;
+       case FNF_NAME:
+               str = FNF_VALUE_NAME;
+               break;
+       }
+
+       pr_info("%s.%s: %s", group->name, field->name, str);
+}
+
 static int
 parse_argv_bool(struct option_field const *field, char const *str, void *result)
 {
@@ -451,6 +502,24 @@ parse_argv_sync_strategy(struct option_field const *field, char const *str,
        return 0;
 }
 
+static int
+parse_argv_filename_format(struct option_field const *field, char const *str,
+    void *_result)
+{
+       enum filename_format *result = _result;
+
+       if (strcmp(str, FNF_VALUE_GLOBAL) == 0)
+               *result = FNF_GLOBAL;
+       else if (strcmp(str, FNF_VALUE_LOCAL) == 0)
+               *result = FNF_LOCAL;
+       else if (strcmp(str, FNF_VALUE_NAME) == 0)
+               *result = FNF_NAME;
+       else
+               return pr_err("Unknown file name format: '%s'", str);
+
+       return 0;
+}
+
 static int
 parse_toml_bool(struct option_field const *opt, struct toml_table_t *toml,
     void *_result)
@@ -577,6 +646,23 @@ fail:
        return error;
 }
 
+static int
+parse_toml_filename_format(struct option_field const *opt,
+    struct toml_table_t *toml, void *_result)
+{
+       int error;
+       char *string;
+
+       error = parse_toml_string(opt, toml, &string);
+       if (error)
+               return error;
+
+       error = parse_argv_filename_format(opt, string, _result);
+
+       free(string);
+       return error;
+}
+
 static int
 handle_help(struct option_field const *field, char *arg)
 {
@@ -737,7 +823,6 @@ set_default_values(void)
        rpki_config.sync_strategy = SYNC_STRICT;
        rpki_config.shuffle_uris = false;
        rpki_config.maximum_certificate_depth = 32;
-       rpki_config.color_output = false;
 
        rpki_config.rsync.program = strdup("rsync");
        if (rpki_config.rsync.program == NULL)
@@ -755,6 +840,9 @@ set_default_values(void)
                        goto revert_rsync_args;
        }
 
+       rpki_config.output.color = false;
+       rpki_config.output.filename_format = FNF_GLOBAL;
+
        return 0;
 
 revert_rsync_args:
@@ -784,7 +872,6 @@ print_usage(FILE *stream, bool print_doc)
        char const *arg_doc;
 
        fprintf(stream, "Usage: %s\n", program_name);
-
        FOREACH_OPTION(groups, group, option, AVAILABILITY_GETOPT) {
                fprintf(stream, "\t[");
                fprintf(stream, "--%s", option->name);
@@ -923,9 +1010,14 @@ config_get_max_cert_depth(void)
 bool
 config_get_color_output(void)
 {
-       return rpki_config.color_output;
+       return rpki_config.output.color;
 }
 
+enum filename_format
+config_get_filename_format(void)
+{
+       return rpki_config.output.filename_format;
+}
 
 char *
 config_get_rsync_program(void)
index f127798bcc42271130f70c06710294bdcd164c15..4243a0c7de9561dff9b0c451a3bdff8fae389bae 100644 (file)
@@ -58,6 +58,19 @@ enum sync_strategy {
 #define SYNC_VALUE_STRICT      "strict"
 #define SYNC_VALUE_ROOT                "root"
 
+enum filename_format {
+       /** Example: "rsync://repository.lacnic.net/rpki/foo/bar/baz.cer" */
+       FNF_GLOBAL,
+       /** Example: "/tmp/repo/repository.lacnic.net/rpki/foo/bar/baz.cer" */
+       FNF_LOCAL,
+       /** Example: "baz.cer" */
+       FNF_NAME,
+};
+
+#define FNF_VALUE_GLOBAL "global-url"
+#define FNF_VALUE_LOCAL "local-path"
+#define FNF_VALUE_NAME "file-name"
+
 struct rpki_config;
 
 struct group_fields;
@@ -166,7 +179,9 @@ struct option_field {
        handler_function handler;
 
        /**
-        * Explanation of the field, for user consumption.
+        * Explanation of the field, for user consumption during --help.
+        * Meant to be short; the bulk of it should be found in the manpage.
+        * Probably should not include punctuation at the end.
         * Mandatory.
         */
        const char *doc;
@@ -203,6 +218,7 @@ enum sync_strategy config_get_sync_strategy(void);
 bool config_get_shuffle_uris(void);
 unsigned int config_get_max_cert_depth(void);
 bool config_get_color_output(void);
+enum filename_format config_get_filename_format(void);
 char *config_get_rsync_program(void);
 struct string_array const *config_get_rsync_args(void);
 
index a6a067b944f75a690d0e8a3bc8ee17be975b8761..049b339087ed919552a4386b67e77b8db152dfe8 100644 (file)
@@ -47,11 +47,11 @@ handle_tal_uri(struct tal *tal, struct rpki_uri const *uri)
        if (error)
                return -abs(error);
 
-       pr_debug_add("TAL URI %s {", uri->global);
+       pr_debug_add("TAL URI '%s' {", uri_get_printable(uri));
 
        if (!uri_is_certificate(uri)) {
                pr_err("TAL file does not point to a certificate. (Expected .cer, got '%s')",
-                   uri->global);
+                   uri_get_printable(uri));
                error = -EINVAL;
                goto end;
        }
index 629cc6c489e8efd65c3244c47d0941fdf8f91b3b..6602c1dc1fe9b098241412c3d340aead54c5fbef 100644 (file)
@@ -584,7 +584,7 @@ handle_rpkiManifest(struct rpki_uri *uri, void *arg)
 static int
 handle_caRepository(struct rpki_uri *uri, void *arg)
 {
-       pr_debug("caRepository: %s", uri->global);
+       pr_debug("caRepository: %s", uri_get_printable(uri));
        return download_files(uri);
 }
 
@@ -592,7 +592,7 @@ static int
 handle_signedObject(struct rpki_uri *uri, void *arg)
 {
        struct certificate_refs *refs = arg;
-       pr_debug("signedObject: %s", uri->global);
+       pr_debug("signedObject: %s", uri_get_printable(uri));
        refs->signedObject = uri->global;
        uri->global = NULL;
        return 0;
@@ -1152,9 +1152,9 @@ certificate_traverse(struct rpp *rpp_parent, struct rpki_uri const *cert_uri,
        if (sk_X509_num(validation_certs(state)) >= config_get_max_cert_depth())
                return pr_err("Certificate chain maximum depth exceeded.");
 
-       pr_debug_add("%s Certificate %s {", is_ta ? "TA" : "CA",
-           cert_uri->global);
-       fnstack_push(cert_uri->global);
+       pr_debug_add("%s Certificate '%s' {", is_ta ? "TA" : "CA",
+           uri_get_printable(cert_uri));
+       fnstack_push_uri(cert_uri);
        memset(&refs, 0, sizeof(refs));
 
        /* -- Validate the certificate (@cert) -- */
index 10808ad93f14221d5ca7acd5b8fe6606936f1142..e36b49f659e305b21e8c42f091d670a5b8d31fe2 100644 (file)
@@ -138,7 +138,7 @@ int
 crl_load(struct rpki_uri const *uri, X509_CRL **result)
 {
        int error;
-       pr_debug_add("CRL %s {", uri->global);
+       pr_debug_add("CRL '%s' {", uri_get_printable(uri));
 
        error = __crl_load(uri, result);
        if (!error)
index 26ea77b5c8883a40739b3c36e40f4236bfbad136..e39634fb62a5b9e0742634728daf15ad588c126d 100644 (file)
@@ -22,8 +22,8 @@ handle_ghostbusters(struct rpki_uri const *uri, struct rpp *pp,
        struct signed_object_args sobj_args;
        int error;
 
-       pr_debug_add("Ghostbusters %s {", uri->global);
-       fnstack_push(uri->global);
+       pr_debug_add("Ghostbusters '%s' {", uri->global);
+       fnstack_push_uri(uri);
 
        error = signed_object_args_init(&sobj_args, uri, crls, true);
        if (error)
index c9f766ce46bab34f49430283c593cb8d4a614a3d..21211eb0249c72b4195674c595fc6dfb08a701fa 100644 (file)
@@ -185,8 +185,8 @@ handle_manifest(struct rpki_uri const *uri, STACK_OF(X509_CRL) *crls,
        struct manifest mft;
        int error;
 
-       pr_debug_add("Manifest %s {", uri->global);
-       fnstack_push(uri->global);
+       pr_debug_add("Manifest '%s' {", uri_get_printable(uri));
+       fnstack_push_uri(uri);
 
        error = signed_object_args_init(&sobj_args, uri, crls, false);
        if (error)
index b3aee4e2fb11240fdf417f0daae5caa69be667ba..05f82d565cc7e7f2fd21245d15c94bb5ce9e40a3 100644 (file)
@@ -211,8 +211,8 @@ handle_roa(struct rpki_uri const *uri, struct rpp *pp,
        struct RouteOriginAttestation *roa;
        int error;
 
-       pr_debug_add("ROA %s {", uri->global);
-       fnstack_push(uri->global);
+       pr_debug_add("ROA '%s' {", uri_get_printable(uri));
+       fnstack_push_uri(uri);
 
        error = signed_object_args_init(&sobj_args, uri, crls, false);
        if (error)
index 289fa334034d36d3159e0d31a5d63abb956fde35..be3a029113780bd8a664aac0c58de75bade0fd61 100644 (file)
--- a/src/rpp.c
+++ b/src/rpp.c
@@ -91,7 +91,6 @@ rpp_add_crl(struct rpp *pp, struct rpki_uri *uri)
 
        pp->crl = *uri;
        pp->crl_set = true;
-       pr_debug("Manifest CRL: %s", uri->global);
        return 0;
 }
 
@@ -102,7 +101,7 @@ add_crl_to_stack(struct rpp *pp, STACK_OF(X509_CRL) *crls)
        int error;
        int idx;
 
-       fnstack_push(pp->crl.global);
+       fnstack_push_uri(&pp->crl);
 
        error = crl_load(&pp->crl, &crl);
        if (error)
index 1ae6170c2e8141765a3dd5397ca9c8886d61bd48..8d6991aeccaf7d5367d300c28d58eec8a6188faa 100644 (file)
--- a/src/str.c
+++ b/src/str.c
@@ -7,7 +7,7 @@
 /**
  * Does not assume that @string is NULL-terminated.
  */
-int
+static int
 string_clone(void const *string, size_t size, char **clone)
 {
        char *result;
index acfd301e114767b968bbbf0c1df2664dfa268be2..ec1db1c6da3915623b8e9658bc6be3a9cae0145c 100644 (file)
--- a/src/str.h
+++ b/src/str.h
@@ -6,7 +6,6 @@
 #include <openssl/asn1.h>
 #include <openssl/x509.h>
 
-int string_clone(void const *, size_t, char **);
 int ia5s2string(ASN1_IA5STRING *, char **);
 int BN2string(BIGNUM *, char **);
 
index 7b0ab8b52fbe875261c988d6ab7a44f4813257e6..16ced79c1bcff284229e5a6dc0323d87d741a5f6 100644 (file)
@@ -6,9 +6,10 @@
 #include <stdlib.h>
 #include <string.h>
 #include <arpa/inet.h>
-
 #include <sys/socket.h>
 
+#include "config.h"
+
 static pthread_key_t state_key;
 static pthread_key_t filenames_key;
 
@@ -113,20 +114,14 @@ get_file_stack(void)
        return files;
 }
 
-static char const *
-get_filename(char const *file_path)
-{
-       /* char *slash = strrchr(file_path, '/'); */
-       return /* (slash != NULL) ? (slash + 1) : */ file_path;
-}
-
 /**
  * Call this function every time you're about to start processing a new file.
  * Any pr_err()s and friends will now include the new file name.
  * Use fnstack_pop() to revert back to the previously stacked file name.
+ * @file is not cloned; it's expected to outlive the push/pop operation.
  */
 void
-fnstack_push(char const *file_path)
+fnstack_push(char const *file)
 {
        struct filename_stack *files;
        char const **tmp;
@@ -148,7 +143,14 @@ fnstack_push(char const *file_path)
                files->size *= 2;
        }
 
-       files->filenames[files->len++] = get_filename(file_path);
+       files->filenames[files->len++] = file;
+}
+
+/** See fnstack_push(). */
+void
+fnstack_push_uri(struct rpki_uri const *uri)
+{
+       fnstack_push(uri_get_printable(uri));
 }
 
 /* Returns the file name on the top of the file name stack. */
index 074148a7af8f2faac9a31e35150cc09f5d94fea5..fe53f72de8d7ea06d0392e5a9c88263b23b87bc6 100644 (file)
@@ -10,6 +10,7 @@ struct validation *state_retrieve(void);
 
 void fnstack_store(void);
 void fnstack_push(char const *);
+void fnstack_push_uri(struct rpki_uri const *);
 char const *fnstack_peek(void);
 void fnstack_pop(void);
 
index da645ec3f53124c24b274bc547a727b12206b2e5..55b0bc1db36fae7ba4f04653492e63183c0f5b40 100644 (file)
--- a/src/uri.c
+++ b/src/uri.c
@@ -49,22 +49,22 @@ validate_url_character(int character)
  * This function does not assume that @str is null-terminated.
  */
 static int
-str2global(void const *str, size_t str_len, struct rpki_uri *uri)
+str2global(char const *str, size_t str_len, struct rpki_uri *uri)
 {
        int error;
        size_t i;
 
-       error = string_clone(str, str_len, &uri->global);
-       if (error)
-               return error;
-       uri->global_len = str_len;
-
        for (i = 0; i < str_len; i++) {
-               error = validate_url_character(uri->global[i]);
+               error = validate_url_character(str[i]);
                if (error)
                        return error;
        }
 
+       uri->global = strdup(str);
+       if (uri->global == NULL)
+               return pr_enomem();
+       uri->global_len = str_len;
+
        return 0;
 }
 
@@ -318,3 +318,29 @@ uri_is_certificate(struct rpki_uri const *uri)
 {
        return uri_has_extension(uri, ".cer");
 }
+
+static char const *
+get_filename(char const *file_path)
+{
+       char *slash = strrchr(file_path, '/');
+       return (slash != NULL) ? (slash + 1) : file_path;
+}
+
+char const *
+uri_get_printable(struct rpki_uri const *uri)
+{
+       enum filename_format format;
+
+       format = config_get_filename_format();
+       switch (format) {
+       case FNF_GLOBAL:
+               return uri->global;
+       case FNF_LOCAL:
+               return uri->local;
+       case FNF_NAME:
+               return get_filename(uri->global);
+       }
+
+       pr_crit("Unknown file name format: %u", format);
+       return uri->global;
+}
index 757589aaf4ee33fbd1b71245809d07922dad67da..abd41d149611365bbc99f2d0f2175196bccba24d 100644 (file)
--- a/src/uri.h
+++ b/src/uri.h
@@ -15,7 +15,7 @@
  * Because we need to generate @local from @global, @global's allowed character
  * set must be a subset of @local. Because this is Unix, @local must never
  * contain NULL (except as a terminating character). Therefore, even though IA5
- * allows NULL, @global won't. TODO (NOW) validate this on constructors.
+ * allows NULL, @global won't.
  *
  * Because we will simply embed @global (minus "rsync://") into @local, @local's
  * encoding must be IA5-compatible. In other words, UTF-16 and UTF-32 are out of
@@ -64,5 +64,6 @@ void uri_cleanup(struct rpki_uri *);
 
 bool uri_has_extension(struct rpki_uri const *, char const *);
 bool uri_is_certificate(struct rpki_uri const *);
+char const *uri_get_printable(struct rpki_uri const *);
 
 #endif /* SRC_URI_H_ */