summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2021-10-26 16:12:55 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2021-10-26 16:12:55 +0000
commit2cad8975ccb468e7c45b2e66a6571484f87bf3c4 (patch)
treeacdb542db635cb243ad3c7fd642d3398b373cc1a /usr.sbin
parentf9beed2be59f579cdb8b1c38b95d6230bb7cd74c (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.c7
-rw-r--r--usr.sbin/rpki-client/extern.h24
-rw-r--r--usr.sbin/rpki-client/main.c85
-rw-r--r--usr.sbin/rpki-client/parser.c48
-rw-r--r--usr.sbin/rpki-client/rrdp.c5
-rw-r--r--usr.sbin/rpki-client/tal.c95
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.
*/