diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2021-10-26 16:12:55 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2021-10-26 16:12:55 +0000 |
commit | 2cad8975ccb468e7c45b2e66a6571484f87bf3c4 (patch) | |
tree | acdb542db635cb243ad3c7fd642d3398b373cc1a /usr.sbin | |
parent | f9beed2be59f579cdb8b1c38b95d6230bb7cd74c (diff) |
Refactor the tal parsing code to use the same load_file() and buffer
passing as done for the other parsers.
OK job@ tb@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/rpki-client/encoding.c | 7 | ||||
-rw-r--r-- | usr.sbin/rpki-client/extern.h | 24 | ||||
-rw-r--r-- | usr.sbin/rpki-client/main.c | 85 | ||||
-rw-r--r-- | usr.sbin/rpki-client/parser.c | 48 | ||||
-rw-r--r-- | usr.sbin/rpki-client/rrdp.c | 5 | ||||
-rw-r--r-- | usr.sbin/rpki-client/tal.c | 95 |
6 files changed, 107 insertions, 157 deletions
diff --git a/usr.sbin/rpki-client/encoding.c b/usr.sbin/rpki-client/encoding.c index ff6d8731b70..5208598ed29 100644 --- a/usr.sbin/rpki-client/encoding.c +++ b/usr.sbin/rpki-client/encoding.c @@ -1,4 +1,4 @@ -/* $OpenBSD: encoding.c,v 1.4 2021/10/11 16:06:36 claudio Exp $ */ +/* $OpenBSD: encoding.c,v 1.5 2021/10/26 16:12:54 claudio Exp $ */ /* * Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org> * @@ -29,11 +29,11 @@ * Returns 0 on success or -1 for any errors. */ int -base64_decode(const unsigned char *in, unsigned char **out, size_t *outlen) +base64_decode(const unsigned char *in, size_t inlen, + unsigned char **out, size_t *outlen) { static EVP_ENCODE_CTX *ctx; unsigned char *to; - size_t inlen; int tolen; if (ctx == NULL && (ctx = EVP_ENCODE_CTX_new()) == NULL) @@ -42,7 +42,6 @@ base64_decode(const unsigned char *in, unsigned char **out, size_t *outlen) *out = NULL; *outlen = 0; - inlen = strlen(in); if (inlen >= INT_MAX - 3) return -1; tolen = ((inlen + 3) / 4) * 3 + 1; diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h index 7c3cb3ed26b..8e77b68a4d8 100644 --- a/usr.sbin/rpki-client/extern.h +++ b/usr.sbin/rpki-client/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.79 2021/10/26 13:31:05 claudio Exp $ */ +/* $OpenBSD: extern.h,v 1.80 2021/10/26 16:12:54 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -337,12 +337,12 @@ enum publish_type { * and parsed. */ struct entity { - enum rtype type; /* type of entity (not RTYPE_EOF) */ - char *file; /* local path to file */ - int has_pkey; /* whether pkey/sz is specified */ - unsigned char *pkey; /* public key (optional) */ - size_t pkeysz; /* public key length (optional) */ - char *descr; /* tal description */ + enum rtype type; /* type of entity (not RTYPE_EOF) */ + char *file; /* local path to file */ + int has_data; /* whether data blob is specified */ + unsigned char *data; /* optional data blob */ + size_t datasz; /* length of optional data blob */ + char *descr; /* tal description */ TAILQ_ENTRY(entity) entries; }; TAILQ_HEAD(entityq, entity); @@ -397,8 +397,7 @@ extern int verbose; void tal_buffer(struct ibuf *, const struct tal *); void tal_free(struct tal *); -struct tal *tal_parse(const char *, char *); -char *tal_read_file(const char *); +struct tal *tal_parse(const char *, char *, size_t); struct tal *tal_read(struct ibuf *); void cert_buffer(struct ibuf *, const struct cert *); @@ -534,8 +533,8 @@ void cryptoerrx(const char *, ...) /* Encoding functions for hex and base64. */ -int base64_decode(const unsigned char *, unsigned char **, - size_t *); +int base64_decode(const unsigned char *, size_t, + unsigned char **, size_t *); int base64_encode(const unsigned char *, size_t, char **); char *hex_encode(const unsigned char *, size_t); @@ -595,8 +594,9 @@ int output_csv(FILE *, struct vrp_tree *, struct brk_tree *, int output_json(FILE *, struct vrp_tree *, struct brk_tree *, struct stats *); -void logx(const char *fmt, ...) +void logx(const char *fmt, ...) __attribute__((format(printf, 1, 2))); +unsigned char *load_file(const char *, size_t *); int mkpath(const char *); diff --git a/usr.sbin/rpki-client/main.c b/usr.sbin/rpki-client/main.c index f83a4bad05f..775b3212999 100644 --- a/usr.sbin/rpki-client/main.c +++ b/usr.sbin/rpki-client/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.154 2021/10/24 21:24:19 deraadt Exp $ */ +/* $OpenBSD: main.c,v 1.155 2021/10/26 16:12:54 claudio Exp $ */ /* * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org> * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> @@ -20,6 +20,7 @@ #include <sys/queue.h> #include <sys/socket.h> #include <sys/resource.h> +#include <sys/stat.h> #include <sys/statvfs.h> #include <sys/tree.h> #include <sys/wait.h> @@ -82,13 +83,46 @@ logx(const char *fmt, ...) } } +unsigned char * +load_file(const char *name, size_t *len) +{ + unsigned char *buf = NULL; + struct stat st; + ssize_t n; + size_t size; + int fd; + + *len = 0; + + if ((fd = open(name, O_RDONLY)) == -1) + return NULL; + if (fstat(fd, &st) != 0) + goto err; + if (st.st_size < 0) + goto err; + size = (size_t)st.st_size; + if ((buf = malloc(size)) == NULL) + goto err; + n = read(fd, buf, size); + if (n < 0 || (size_t)n != size) + goto err; + close(fd); + *len = size; + return buf; + +err: + close(fd); + free(buf); + return NULL; +} + void entity_free(struct entity *ent) { if (ent == NULL) return; - free(ent->pkey); + free(ent->data); free(ent->file); free(ent->descr); free(ent); @@ -104,10 +138,10 @@ entity_read_req(struct ibuf *b, struct entity *ent) { io_read_buf(b, &ent->type, sizeof(ent->type)); io_read_str(b, &ent->file); - io_read_buf(b, &ent->has_pkey, sizeof(ent->has_pkey)); - if (ent->has_pkey) - io_read_buf_alloc(b, (void **)&ent->pkey, &ent->pkeysz); io_read_str(b, &ent->descr); + io_read_buf(b, &ent->has_data, sizeof(ent->has_data)); + if (ent->has_data) + io_read_buf_alloc(b, (void **)&ent->data, &ent->datasz); } /* @@ -128,10 +162,10 @@ entity_write_req(const struct entity *ent) b = io_new_buffer(); io_simple_buffer(b, &ent->type, sizeof(ent->type)); io_str_buffer(b, ent->file); - io_simple_buffer(b, &ent->has_pkey, sizeof(int)); - if (ent->has_pkey) - io_buf_buffer(b, ent->pkey, ent->pkeysz); io_str_buffer(b, ent->descr); + io_simple_buffer(b, &ent->has_data, sizeof(int)); + if (ent->has_data) + io_buf_buffer(b, ent->data, ent->datasz); io_close_buffer(&procq, b); } @@ -169,7 +203,7 @@ entityq_flush(struct entityq *q, struct repo *rp) */ static void entityq_add(char *file, enum rtype type, struct repo *rp, - const unsigned char *pkey, size_t pkeysz, char *descr) + unsigned char *data, size_t datasz, char *descr) { struct entity *p; @@ -178,12 +212,10 @@ entityq_add(char *file, enum rtype type, struct repo *rp, p->type = type; p->file = file; - p->has_pkey = pkey != NULL; - if (p->has_pkey) { - p->pkeysz = pkeysz; - if ((p->pkey = malloc(pkeysz)) == NULL) - err(1, NULL); - memcpy(p->pkey, pkey, pkeysz); + p->has_data = data != NULL; + if (p->has_data) { + p->data = data; + p->datasz = datasz; } if (descr != NULL) if ((p->descr = strdup(descr)) == NULL) @@ -388,11 +420,13 @@ queue_add_from_mft_set(const struct mft *mft) static void queue_add_tal(const char *file) { - char *nfile, *buf; + unsigned char *buf; + char *nfile; + size_t len; if ((nfile = strdup(file)) == NULL) err(1, NULL); - buf = tal_read_file(file); + buf = load_file(file, &len); /* Record tal for later reporting */ if (stats.talnames == NULL) { @@ -408,9 +442,7 @@ queue_add_tal(const char *file) } /* Not in a repository, so directly add to queue. */ - entityq_add(nfile, RTYPE_TAL, NULL, NULL, 0, buf); - /* entityq_add makes a copy of buf */ - free(buf); + entityq_add(nfile, RTYPE_TAL, NULL, buf, len, buf); } /* @@ -420,13 +452,17 @@ static void queue_add_from_tal(struct tal *tal) { struct repo *repo; + unsigned char *data; assert(tal->urisz); /* Look up the repository. */ repo = ta_lookup(tal); - entityq_add(NULL, RTYPE_CER, repo, tal->pkey, + /* steal the pkey from the tal structure */ + data = tal->pkey; + tal->pkey = NULL; + entityq_add(NULL, RTYPE_CER, repo, data, tal->pkeysz, tal->descr); } @@ -683,6 +719,7 @@ main(int argc, char *argv[]) char *bind_addr = NULL; const char *cachedir = NULL, *outputdir = NULL; const char *tals[TALSZ_MAX], *errs, *name; + const char *file = NULL; struct vrp_tree vrps = RB_INITIALIZER(&vrps); struct brk_tree brks = RB_INITIALIZER(&brks); struct rusage ru; @@ -709,7 +746,7 @@ main(int argc, char *argv[]) "proc exec unveil", NULL) == -1) err(1, "pledge"); - while ((c = getopt(argc, argv, "b:Bcd:e:jnorRs:t:T:vV")) != -1) + while ((c = getopt(argc, argv, "b:Bcd:e:f:jnorRs:t:T:vV")) != -1) switch (c) { case 'b': bind_addr = optarg; @@ -726,6 +763,10 @@ main(int argc, char *argv[]) case 'e': rsync_prog = optarg; break; + case 'f': + file = optarg; + noop = 1; + break; case 'j': outformats |= FORMAT_JSON; break; diff --git a/usr.sbin/rpki-client/parser.c b/usr.sbin/rpki-client/parser.c index cc2f15161f0..acafeb235d9 100644 --- a/usr.sbin/rpki-client/parser.c +++ b/usr.sbin/rpki-client/parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.c,v 1.19 2021/10/26 13:31:05 claudio Exp $ */ +/* $OpenBSD: parser.c,v 1.20 2021/10/26 16:12:54 claudio Exp $ */ /* * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org> * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> @@ -17,13 +17,11 @@ */ #include <sys/queue.h> -#include <sys/stat.h> #include <sys/tree.h> #include <sys/types.h> #include <assert.h> #include <err.h> -#include <fcntl.h> #include <poll.h> #include <stdio.h> #include <stdlib.h> @@ -201,7 +199,7 @@ proc_parser_cert(const struct entity *entp, const unsigned char *der, STACK_OF(X509) *chain; STACK_OF(X509_CRL) *crls; - assert(!entp->has_pkey); + assert(!entp->has_data); /* Extract certificate data and X509. */ @@ -294,11 +292,11 @@ proc_parser_root_cert(const struct entity *entp, const unsigned char *der, struct auth *na; char *tal; - assert(entp->has_pkey); + assert(entp->has_data); /* Extract certificate data and X509. */ - cert = ta_parse(&x509, entp->file, der, len, entp->pkey, entp->pkeysz); + cert = ta_parse(&x509, entp->file, der, len, entp->data, entp->datasz); if (cert == NULL) return NULL; @@ -510,39 +508,6 @@ build_crls(const struct crl *crl, STACK_OF(X509_CRL) **crls) err(1, "sk_X509_CRL_push"); } -static unsigned char * -load_file(const char *name, size_t *len) -{ - unsigned char *buf = NULL; - struct stat st; - ssize_t n; - size_t size; - int fd; - - *len = 0; - - if ((fd = open(name, O_RDONLY)) == -1) - return NULL; - if (fstat(fd, &st) != 0) - goto err; - if (st.st_size < 0) - goto err; - size = (size_t)st.st_size; - if ((buf = malloc(size)) == NULL) - goto err; - n = read(fd, buf, size); - if (n < 0 || (size_t)n != size) - goto err; - close(fd); - *len = size; - return buf; - -err: - close(fd); - free(buf); - return NULL; -} - static void parse_entity(struct entityq *q, struct msgbuf *msgq) { @@ -571,14 +536,15 @@ parse_entity(struct entityq *q, struct msgbuf *msgq) switch (entp->type) { case RTYPE_TAL: - if ((tal = tal_parse(entp->file, entp->descr)) == NULL) + if ((tal = tal_parse(entp->file, entp->data, + entp->datasz)) == NULL) errx(1, "%s: could not parse tal file", entp->file); tal_buffer(b, tal); tal_free(tal); break; case RTYPE_CER: - if (entp->has_pkey) + if (entp->has_data) cert = proc_parser_root_cert(entp, f, flen); else cert = proc_parser_cert(entp, f, flen); diff --git a/usr.sbin/rpki-client/rrdp.c b/usr.sbin/rpki-client/rrdp.c index 579353fb167..9271881a2e8 100644 --- a/usr.sbin/rpki-client/rrdp.c +++ b/usr.sbin/rpki-client/rrdp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rrdp.c,v 1.14 2021/10/23 20:01:16 claudio Exp $ */ +/* $OpenBSD: rrdp.c,v 1.15 2021/10/26 16:12:54 claudio Exp $ */ /* * Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com> * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org> @@ -661,7 +661,8 @@ publish_done(struct rrdp *s, struct publish_xml *pxml) size_t datasz = 0; if (pxml->data_length > 0) - if ((base64_decode(pxml->data, &data, &datasz)) == -1) + if ((base64_decode(pxml->data, pxml->data_length, + &data, &datasz)) == -1) return -1; /* only send files if the fetch did not fail already */ diff --git a/usr.sbin/rpki-client/tal.c b/usr.sbin/rpki-client/tal.c index b6a0890f82b..8875d285800 100644 --- a/usr.sbin/rpki-client/tal.c +++ b/usr.sbin/rpki-client/tal.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tal.c,v 1.31 2021/10/23 16:06:04 claudio Exp $ */ +/* $OpenBSD: tal.c,v 1.32 2021/10/26 16:12:54 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -41,7 +41,7 @@ tal_cmp(const void *a, const void *b) * The pointer must be freed with tal_free(). */ static struct tal * -tal_parse_buffer(const char *fn, char *buf) +tal_parse_buffer(const char *fn, char *buf, size_t len) { char *nl, *line, *f, *file = NULL; unsigned char *der; @@ -49,18 +49,31 @@ tal_parse_buffer(const char *fn, char *buf) int rc = 0; struct tal *tal = NULL; EVP_PKEY *pkey = NULL; + int optcomment = 1; if ((tal = calloc(1, sizeof(struct tal))) == NULL) err(1, NULL); /* Begin with the URI section, comment section already removed. */ - while ((nl = strchr(buf, '\n')) != NULL) { + while ((nl = memchr(buf, '\n', len)) != NULL) { line = buf; + + /* replace LF and optional CR with NUL */ *nl = '\0'; + if (nl > line && nl[-1] == '\r') + nl[-1] = '\0'; /* advance buffer to next line */ + len -= nl + 1 - buf; buf = nl + 1; + if (optcomment) { + /* if this is a comment, just eat the line */ + if (line[0] == '#') + continue; + optcomment = 0; + } + /* Zero-length line is end of section. */ if (*line == '\0') break; @@ -112,7 +125,7 @@ tal_parse_buffer(const char *fn, char *buf) qsort(tal->uri, tal->urisz, sizeof(tal->uri[0]), tal_cmp); /* Now the Base64-encoded public key. */ - if ((base64_decode(buf, &der, &dersz)) == -1) { + if ((base64_decode(buf, len, &der, &dersz)) == -1) { warnx("%s: RFC 7730 section 2.1: subjectPublicKeyInfo: " "bad public key", fn); goto out; @@ -144,13 +157,13 @@ out: * Returns the encoded data or NULL on syntax failure. */ struct tal * -tal_parse(const char *fn, char *buf) +tal_parse(const char *fn, char *buf, size_t len) { struct tal *p; const char *d; size_t dlen; - p = tal_parse_buffer(fn, buf); + p = tal_parse_buffer(fn, buf, len); if (p == NULL) return NULL; @@ -170,76 +183,6 @@ tal_parse(const char *fn, char *buf) } /* - * Read the file named "file" into a returned, NUL-terminated buffer. - * This replaces CRLF terminators with plain LF, if found, and also - * elides document-leading comment lines starting with "#". - * Files may not exceeds 4096 bytes. - * This function exits on failure, so it always returns a buffer with - * TAL data. - */ -char * -tal_read_file(const char *file) -{ - char *nbuf, *line = NULL, *buf = NULL; - FILE *in; - ssize_t n, i; - size_t sz = 0, bsz = 0; - int optcomment = 1; - - if ((in = fopen(file, "r")) == NULL) - err(1, "fopen: %s", file); - - while ((n = getline(&line, &sz, in)) != -1) { - /* replace CRLF with just LF */ - if (n > 1 && line[n - 1] == '\n' && line[n - 2] == '\r') { - line[n - 2] = '\n'; - line[n - 1] = '\0'; - n--; - } - if (optcomment) { - /* if this is comment, just eat the line */ - if (line[0] == '#') - continue; - optcomment = 0; - /* - * Empty line is end of section and needs - * to be eaten as well. - */ - if (line[0] == '\n') - continue; - } - - /* make sure every line is valid ascii */ - for (i = 0; i < n; i++) - if (!isprint((unsigned char)line[i]) && - !isspace((unsigned char)line[i])) - errx(1, "getline: %s: " - "invalid content", file); - - /* concat line to buf */ - if ((nbuf = realloc(buf, bsz + n + 1)) == NULL) - err(1, NULL); - if (buf == NULL) - nbuf[0] = '\0'; /* initialize buffer */ - buf = nbuf; - bsz += n + 1; - if (strlcat(buf, line, bsz) >= bsz) - errx(1, "strlcat overflow"); - /* limit the buffer size */ - if (bsz > 4096) - errx(1, "%s: file too big", file); - } - - free(line); - if (ferror(in)) - err(1, "getline: %s", file); - fclose(in); - if (buf == NULL) - errx(1, "%s: no data", file); - return buf; -} - -/* * Free a TAL pointer. * Safe to call with NULL. */ |