Allow rpki-client to display more than one file in -f mode.
authorclaudio <claudio@openbsd.org>
Sun, 23 Jan 2022 07:21:12 +0000 (07:21 +0000)
committerclaudio <claudio@openbsd.org>
Sun, 23 Jan 2022 07:21:12 +0000 (07:21 +0000)
Change -f to be a mode flag and pass one or multiple files as arguments
to rpki-client. Some extra checks need to be done to not load the same
certificate or CRL multiple times.
Input and OK tb@

usr.sbin/rpki-client/main.c
usr.sbin/rpki-client/parser.c
usr.sbin/rpki-client/rpki-client.8

index bad5685..2031572 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: main.c,v 1.181 2022/01/21 18:49:44 tb Exp $ */
+/*     $OpenBSD: main.c,v 1.182 2022/01/23 07:21:12 claudio Exp $ */
 /*
  * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -726,7 +726,6 @@ main(int argc, char *argv[])
        char            *bind_addr = NULL;
        const char      *cachedir = NULL, *outputdir = NULL;
        const char      *errs, *name;
-       const char      *file = NULL;
        struct vrp_tree  vrps = RB_INITIALIZER(&vrps);
        struct brk_tree  brks = RB_INITIALIZER(&brks);
        struct rusage   ru;
@@ -754,7 +753,7 @@ main(int argc, char *argv[])
            "proc exec unveil", NULL) == -1)
                err(1, "pledge");
 
-       while ((c = getopt(argc, argv, "b:Bcd:e:f:jnorRs:t:T:vV")) != -1)
+       while ((c = getopt(argc, argv, "b:Bcd:e:fjnorRs:t:T:vV")) != -1)
                switch (c) {
                case 'b':
                        bind_addr = optarg;
@@ -772,7 +771,6 @@ main(int argc, char *argv[])
                        rsync_prog = optarg;
                        break;
                case 'f':
-                       file = optarg;
                        filemode = 1;
                        noop = 1;
                        break;
@@ -823,26 +821,29 @@ main(int argc, char *argv[])
 
        argv += optind;
        argc -= optind;
-       if (argc == 1)
-               outputdir = argv[0];
-       else if (argc > 1)
-               goto usage;
 
-       signal(SIGPIPE, SIG_IGN);
+       if (!filemode) {
+               if (argc == 1)
+                       outputdir = argv[0];
+               else if (argc > 1)
+                       goto usage;
+
+               if (outputdir == NULL) {
+                       warnx("output directory required");
+                       goto usage;
+               }
+       } else {
+               if (argc == 0)
+                       goto usage;
+               outputdir = NULL;
+       }
 
        if (cachedir == NULL) {
                warnx("cache directory required");
                goto usage;
        }
-       if (file != NULL) {
-               if (rtype_from_file_extension(file) == RTYPE_INVALID)
-                       errx(1, "unsupported or invalid file: %s", file);
 
-               outputdir = NULL;
-       } else if (outputdir == NULL) {
-               warnx("output directory required");
-               goto usage;
-       }
+       signal(SIGPIPE, SIG_IGN);
 
        if ((cachefd = open(cachedir, O_RDONLY | O_DIRECTORY)) == -1)
                err(1, "cache directory %s", cachedir);
@@ -1059,8 +1060,10 @@ main(int argc, char *argv[])
        for (i = 0; i < talsz; i++)
                queue_add_file(tals[i], RTYPE_TAL, i);
 
-       if (file != NULL)
-               queue_add_file(file, RTYPE_FILE, 0);
+       if (filemode) {
+               while (*argv != NULL)
+                       queue_add_file(*argv++, RTYPE_FILE, 0);
+       }
 
        /* change working directory to the cache directory */
        if (fchdir(cachefd) == -1)
@@ -1279,7 +1282,8 @@ usage:
        fprintf(stderr,
            "usage: rpki-client [-BcjnoRrVv] [-b sourceaddr] [-d cachedir]"
            " [-e rsync_prog]\n"
-           "                   [-f file] [-s timeout] [-T table] [-t tal]"
-           " [outputdir]\n");
+           "                   [-s timeout] [-T table] [-t tal]"
+           " [outputdir]\n"
+           "       rpki-client -f [-Vv] [-d cachedir] [-t tal] file ...\n");
        return 1;
 }
index 7b4724a..491151c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: parser.c,v 1.51 2022/01/23 05:59:35 claudio Exp $ */
+/*     $OpenBSD: parser.c,v 1.52 2022/01/23 07:21:12 claudio Exp $ */
 /*
  * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -494,8 +494,7 @@ proc_parser_crl(char *file, const unsigned char *der, size_t len)
        if ((x509_crl = crl_parse(file, der, len)) != NULL) {
                if ((crl = malloc(sizeof(*crl))) == NULL)
                        err(1, NULL);
-               if ((crl->aki = x509_crl_get_aki(x509_crl, file)) ==
-                   NULL) {
+               if ((crl->aki = x509_crl_get_aki(x509_crl, file)) == NULL) {
                        warnx("x509_crl_get_aki failed");
                        goto err;
                }
@@ -518,7 +517,8 @@ proc_parser_crl(char *file, const unsigned char *der, size_t len)
                        errx(1, "%s: mktime failed", file);
 
                if (RB_INSERT(crl_tree, &crlt, crl) != NULL) {
-                       warnx("%s: duplicate AKI %s", file, crl->aki);
+                       if (!filemode)
+                               warnx("%s: duplicate AKI %s", file, crl->aki);
                        goto err;
                }
        }
@@ -846,10 +846,15 @@ parse_load_certchain(char *uri)
                        warnx("failed to build authority chain");
                        return;
                }
+               if (auth_find(&auths, cert->ski) != NULL) {
+                       assert(i == 0);
+                       cert_free(cert);
+                       return; /* cert already added */
+               }
                stack[i] = cert;
                filestack[i] = uri;
                if (auth_find(&auths, cert->aki) != NULL)
-                       break;  /* found the TA */
+                       break;  /* found chain to TA */
                uri = cert->aia;
        }
 
@@ -906,6 +911,7 @@ parse_load_ta(struct tal *tal)
 static void
 proc_parser_file(char *file, unsigned char *buf, size_t len)
 {
+       static int num;
        X509 *x509 = NULL;
        struct cert *cert = NULL;
        struct mft *mft = NULL;
@@ -916,8 +922,11 @@ proc_parser_file(char *file, unsigned char *buf, size_t len)
        char *aia = NULL, *aki = NULL, *ski = NULL;
        unsigned long verify_flags = X509_V_FLAG_CRL_CHECK;
 
-       if ((type = rtype_from_file_extension(file)) == RTYPE_INVALID)
-               errx(1, "%s: unsupported file type", file);
+       if (num++ > 0)
+               printf("--\n");
+       printf("File: %s\n", file);
+
+       type = rtype_from_file_extension(file);
 
        switch (type) {
        case RTYPE_CER:
@@ -968,6 +977,7 @@ proc_parser_file(char *file, unsigned char *buf, size_t len)
                break;
        case RTYPE_CRL: /* XXX no printer yet */
        default:
+               printf("%s: unsupported file type\n", file);
                break;
        }
 
index c7320e5..262a165 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: rpki-client.8,v 1.52 2022/01/19 16:33:36 job Exp $
+.\"    $OpenBSD: rpki-client.8,v 1.53 2022/01/23 07:21:12 claudio Exp $
 .\"
 .\" Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
 .\"
@@ -14,7 +14,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: January 19 2022 $
+.Dd $Mdocdate: January 23 2022 $
 .Dt RPKI-CLIENT 8
 .Os
 .Sh NAME
 .Op Fl b Ar sourceaddr
 .Op Fl d Ar cachedir
 .Op Fl e Ar rsync_prog
-.Op Fl f Ar file
 .Op Fl s Ar timeout
 .Op Fl T Ar table
 .Op Fl t Ar tal
 .Op Ar outputdir
+.Nm
+.Fl f
+.Op Fl Vv
+.Op Fl d Ar cachedir
+.Op Fl t Ar tal
+.Ar file ...
 .Sh DESCRIPTION
 The
 .Nm
@@ -93,7 +98,7 @@ It must accept the
 and
 .Fl -address
 flags and connect with rsync-protocol locations.
-.It Fl f Ar file
+.It Fl f
 Validate the
 .Em Signed Object
 in