diff options
Diffstat (limited to 'usr.sbin/rpki-client')
-rw-r--r-- | usr.sbin/rpki-client/Makefile | 6 | ||||
-rw-r--r-- | usr.sbin/rpki-client/cert.c | 53 | ||||
-rw-r--r-- | usr.sbin/rpki-client/extern.h | 26 | ||||
-rw-r--r-- | usr.sbin/rpki-client/io.c | 54 | ||||
-rw-r--r-- | usr.sbin/rpki-client/ip.c | 16 | ||||
-rw-r--r-- | usr.sbin/rpki-client/main.c | 224 | ||||
-rw-r--r-- | usr.sbin/rpki-client/mft.c | 19 | ||||
-rw-r--r-- | usr.sbin/rpki-client/roa.c | 30 | ||||
-rw-r--r-- | usr.sbin/rpki-client/rsync.c | 44 | ||||
-rw-r--r-- | usr.sbin/rpki-client/tal.c | 12 |
10 files changed, 246 insertions, 238 deletions
diff --git a/usr.sbin/rpki-client/Makefile b/usr.sbin/rpki-client/Makefile index ba83ccaa3c9..151d4889d8a 100644 --- a/usr.sbin/rpki-client/Makefile +++ b/usr.sbin/rpki-client/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.15 2020/12/09 11:29:04 claudio Exp $ +# $OpenBSD: Makefile,v 1.16 2021/01/08 08:09:07 claudio Exp $ PROG= rpki-client SRCS= as.c cert.c cms.c crl.c gbr.c io.c ip.c log.c main.c mft.c output.c \ @@ -6,8 +6,8 @@ SRCS= as.c cert.c cms.c crl.c gbr.c io.c ip.c log.c main.c mft.c output.c \ roa.c rsync.c tal.c validate.c x509.c MAN= rpki-client.8 -LDADD+= -lcrypto -DPADD+= ${LIBCRYPTO} +LDADD+= -lcrypto -lutil +DPADD+= ${LIBCRYPTO} ${LIBUTIL} CFLAGS+= -Wall -I${.CURDIR} CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes diff --git a/usr.sbin/rpki-client/cert.c b/usr.sbin/rpki-client/cert.c index 3023c5a25c7..1d9c2b7b956 100644 --- a/usr.sbin/rpki-client/cert.c +++ b/usr.sbin/rpki-client/cert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cert.c,v 1.21 2020/12/21 11:35:55 claudio Exp $ */ +/* $OpenBSD: cert.c,v 1.22 2021/01/08 08:09:07 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -1207,7 +1207,6 @@ ta_parse(X509 **xp, const char *fn, const unsigned char *pkey, size_t pkeysz) void cert_free(struct cert *p) { - if (p == NULL) return; @@ -1223,35 +1222,31 @@ cert_free(struct cert *p) } static void -cert_ip_buffer(char **b, size_t *bsz, - size_t *bmax, const struct cert_ip *p) +cert_ip_buffer(struct ibuf *b, const struct cert_ip *p) { - - io_simple_buffer(b, bsz, bmax, &p->afi, sizeof(enum afi)); - io_simple_buffer(b, bsz, bmax, &p->type, sizeof(enum cert_ip_type)); + io_simple_buffer(b, &p->afi, sizeof(enum afi)); + io_simple_buffer(b, &p->type, sizeof(enum cert_ip_type)); if (p->type != CERT_IP_INHERIT) { - io_simple_buffer(b, bsz, bmax, &p->min, sizeof(p->min)); - io_simple_buffer(b, bsz, bmax, &p->max, sizeof(p->max)); + io_simple_buffer(b, &p->min, sizeof(p->min)); + io_simple_buffer(b, &p->max, sizeof(p->max)); } if (p->type == CERT_IP_RANGE) - ip_addr_range_buffer(b, bsz, bmax, &p->range); + ip_addr_range_buffer(b, &p->range); else if (p->type == CERT_IP_ADDR) - ip_addr_buffer(b, bsz, bmax, &p->ip); + ip_addr_buffer(b, &p->ip); } static void -cert_as_buffer(char **b, size_t *bsz, - size_t *bmax, const struct cert_as *p) +cert_as_buffer(struct ibuf *b, const struct cert_as *p) { - - io_simple_buffer(b, bsz, bmax, &p->type, sizeof(enum cert_as_type)); + io_simple_buffer(b, &p->type, sizeof(enum cert_as_type)); if (p->type == CERT_AS_RANGE) { - io_simple_buffer(b, bsz, bmax, &p->range.min, sizeof(uint32_t)); - io_simple_buffer(b, bsz, bmax, &p->range.max, sizeof(uint32_t)); + io_simple_buffer(b, &p->range.min, sizeof(uint32_t)); + io_simple_buffer(b, &p->range.max, sizeof(uint32_t)); } else if (p->type == CERT_AS_ID) - io_simple_buffer(b, bsz, bmax, &p->id, sizeof(uint32_t)); + io_simple_buffer(b, &p->id, sizeof(uint32_t)); } /* @@ -1259,24 +1254,24 @@ cert_as_buffer(char **b, size_t *bsz, * See cert_read() for the other side of the pipe. */ void -cert_buffer(char **b, size_t *bsz, size_t *bmax, const struct cert *p) +cert_buffer(struct ibuf *b, const struct cert *p) { size_t i; - io_simple_buffer(b, bsz, bmax, &p->valid, sizeof(int)); - io_simple_buffer(b, bsz, bmax, &p->ipsz, sizeof(size_t)); + io_simple_buffer(b, &p->valid, sizeof(int)); + io_simple_buffer(b, &p->ipsz, sizeof(size_t)); for (i = 0; i < p->ipsz; i++) - cert_ip_buffer(b, bsz, bmax, &p->ips[i]); + cert_ip_buffer(b, &p->ips[i]); - io_simple_buffer(b, bsz, bmax, &p->asz, sizeof(size_t)); + io_simple_buffer(b, &p->asz, sizeof(size_t)); for (i = 0; i < p->asz; i++) - cert_as_buffer(b, bsz, bmax, &p->as[i]); + cert_as_buffer(b, &p->as[i]); - io_str_buffer(b, bsz, bmax, p->mft); - io_str_buffer(b, bsz, bmax, p->notify); - io_str_buffer(b, bsz, bmax, p->crl); - io_str_buffer(b, bsz, bmax, p->aki); - io_str_buffer(b, bsz, bmax, p->ski); + io_str_buffer(b, p->mft); + io_str_buffer(b, p->notify); + io_str_buffer(b, p->crl); + io_str_buffer(b, p->aki); + io_str_buffer(b, p->ski); } static void diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h index 8d1510642eb..d0cfdc2a65b 100644 --- a/usr.sbin/rpki-client/extern.h +++ b/usr.sbin/rpki-client/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.36 2020/12/09 11:29:04 claudio Exp $ */ +/* $OpenBSD: extern.h,v 1.37 2021/01/08 08:09:07 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -284,30 +284,32 @@ struct stats { struct timeval system_time; }; +struct ibuf; + /* global variables */ extern int verbose; /* Routines for RPKI entities. */ -void tal_buffer(char **, size_t *, size_t *, const struct tal *); +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_read(int); -void cert_buffer(char **, size_t *, size_t *, const struct cert *); +void cert_buffer(struct ibuf *, const struct cert *); void cert_free(struct cert *); struct cert *cert_parse(X509 **, const char *, const unsigned char *); struct cert *ta_parse(X509 **, const char *, const unsigned char *, size_t); struct cert *cert_read(int); -void mft_buffer(char **, size_t *, size_t *, const struct mft *); +void mft_buffer(struct ibuf *, const struct mft *); void mft_free(struct mft *); struct mft *mft_parse(X509 **, const char *); int mft_check(const char *, struct mft *); struct mft *mft_read(int); -void roa_buffer(char **, size_t *, size_t *, const struct roa *); +void roa_buffer(struct ibuf *, const struct roa *); void roa_free(struct roa *); struct roa *roa_parse(X509 **, const char *, const unsigned char *); struct roa *roa_read(int); @@ -344,9 +346,8 @@ int ip_addr_parse(const ASN1_BIT_STRING *, enum afi, const char *, struct ip_addr *); void ip_addr_print(const struct ip_addr *, enum afi, char *, size_t); -void ip_addr_buffer(char **, size_t *, size_t *, - const struct ip_addr *); -void ip_addr_range_buffer(char **, size_t *, size_t *, +void ip_addr_buffer(struct ibuf *, const struct ip_addr *); +void ip_addr_range_buffer(struct ibuf *, const struct ip_addr_range *); void ip_addr_read(int, struct ip_addr *); void ip_addr_range_read(int, struct ip_addr_range *); @@ -385,14 +386,11 @@ void cryptoerrx(const char *, ...) void io_socket_blocking(int); void io_socket_nonblocking(int); -void io_simple_buffer(char **, size_t *, size_t *, const void *, - size_t); +void io_simple_buffer(struct ibuf *, const void *, size_t); +void io_buf_buffer(struct ibuf *, const void *, size_t); +void io_str_buffer(struct ibuf *, const char *); void io_simple_read(int, void *, size_t); -void io_simple_write(int, const void *, size_t); -void io_buf_buffer(char **, size_t *, size_t *, const void *, - size_t); void io_buf_read_alloc(int, void **, size_t *); -void io_str_buffer(char **, size_t *, size_t *, const char *); void io_str_read(int, char **); /* X509 helpers. */ diff --git a/usr.sbin/rpki-client/io.c b/usr.sbin/rpki-client/io.c index 9b2b8feb021..cade2aa1128 100644 --- a/usr.sbin/rpki-client/io.c +++ b/usr.sbin/rpki-client/io.c @@ -1,4 +1,4 @@ -/* $OpenBSD: io.c,v 1.11 2020/12/18 16:58:59 claudio Exp $ */ +/* $OpenBSD: io.c,v 1.12 2021/01/08 08:09:07 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -24,6 +24,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <imsg.h> #include "extern.h" @@ -50,62 +51,37 @@ io_socket_nonblocking(int fd) } /* - * Blocking write of a binary buffer. - * Buffers of length zero are simply ignored. - */ -void -io_simple_write(int fd, const void *res, size_t sz) -{ - ssize_t ssz; - - if (sz == 0) - return; - if ((ssz = write(fd, res, sz)) == -1) - err(1, "write"); - else if ((size_t)ssz != sz) - errx(1, "write: short write"); -} - -/* * Like io_simple_write() but into a buffer. */ void -io_simple_buffer(char **b, size_t *bsz, - size_t *bmax, const void *res, size_t sz) +io_simple_buffer(struct ibuf *b, const void *res, size_t sz) { - - if (*bsz + sz > *bmax) { - if ((*b = realloc(*b, *bsz + sz)) == NULL) - err(1, NULL); - *bmax = *bsz + sz; - } - - memcpy(*b + *bsz, res, sz); - *bsz += sz; + if (ibuf_add(b, res, sz) == -1) + err(1, NULL); } /* - * Like io_buf_write() but into a buffer. + * Add a sz sized buffer into the io buffer. */ void -io_buf_buffer(char **b, size_t *bsz, - size_t *bmax, const void *p, size_t sz) +io_buf_buffer(struct ibuf *b, const void *p, size_t sz) { - - io_simple_buffer(b, bsz, bmax, &sz, sizeof(size_t)); + if (ibuf_add(b, &sz, sizeof(size_t)) == -1) + err(1, NULL); if (sz > 0) - io_simple_buffer(b, bsz, bmax, p, sz); + if (ibuf_add(b, p, sz) == -1) + err(1, NULL); } /* - * Like io_str_write() but into a buffer. + * Add a string into the io buffer. */ void -io_str_buffer(char **b, size_t *bsz, size_t *bmax, const char *p) +io_str_buffer(struct ibuf *b, const char *p) { - size_t sz = (p == NULL) ? 0 : strlen(p); + size_t sz = (p == NULL) ? 0 : strlen(p); - io_buf_buffer(b, bsz, bmax, p, sz); + io_buf_buffer(b, p, sz); } /* diff --git a/usr.sbin/rpki-client/ip.c b/usr.sbin/rpki-client/ip.c index de1f1df5e42..c9c5c2ad914 100644 --- a/usr.sbin/rpki-client/ip.c +++ b/usr.sbin/rpki-client/ip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip.c,v 1.13 2020/09/12 15:46:48 claudio Exp $ */ +/* $OpenBSD: ip.c,v 1.14 2021/01/08 08:09:07 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -276,13 +276,13 @@ ip_addr_print(const struct ip_addr *addr, * Matched with ip_addr_read(). */ void -ip_addr_buffer(char **b, size_t *bsz, size_t *bmax, const struct ip_addr *p) +ip_addr_buffer(struct ibuf *b, const struct ip_addr *p) { size_t sz = PREFIX_SIZE(p->prefixlen); assert(sz <= 16); - io_simple_buffer(b, bsz, bmax, &p->prefixlen, sizeof(unsigned char)); - io_simple_buffer(b, bsz, bmax, p->addr, sz); + io_simple_buffer(b, &p->prefixlen, sizeof(unsigned char)); + io_simple_buffer(b, p->addr, sz); } /* @@ -290,12 +290,10 @@ ip_addr_buffer(char **b, size_t *bsz, size_t *bmax, const struct ip_addr *p) * Matched with ip_addr_range_read(). */ void -ip_addr_range_buffer(char **b, size_t *bsz, size_t *bmax, - const struct ip_addr_range *p) +ip_addr_range_buffer(struct ibuf *b, const struct ip_addr_range *p) { - - ip_addr_buffer(b, bsz, bmax, &p->min); - ip_addr_buffer(b, bsz, bmax, &p->max); + ip_addr_buffer(b, &p->min); + ip_addr_buffer(b, &p->max); } /* diff --git a/usr.sbin/rpki-client/main.c b/usr.sbin/rpki-client/main.c index d1ad28fa925..3c20e2edb3e 100644 --- a/usr.sbin/rpki-client/main.c +++ b/usr.sbin/rpki-client/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.88 2020/12/21 11:35:55 claudio Exp $ */ +/* $OpenBSD: main.c,v 1.89 2021/01/08 08:09:07 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -66,6 +66,7 @@ #include <limits.h> #include <syslog.h> #include <unistd.h> +#include <imsg.h> #include <openssl/err.h> #include <openssl/evp.h> @@ -141,7 +142,8 @@ struct filepath_tree fpt = RB_INITIALIZER(&fpt); /* * Mark that our subprocesses will never return. */ -static void entityq_flush(int, struct entityq *, const struct repo *); +static void entityq_flush(struct msgbuf *, struct entityq *, + const struct repo *); static void proc_parser(int) __attribute__((noreturn)); static void build_chain(const struct auth *, STACK_OF(X509) **); static void build_crls(const struct auth *, struct crl_tree *, @@ -240,20 +242,19 @@ entity_read_req(int fd, struct entity *ent) * Matched by entity_read_req(). */ static void -entity_buffer_req(char **b, size_t *bsz, size_t *bmax, - const struct entity *ent) +entity_buffer_req(struct ibuf *b, const struct entity *ent) { - io_simple_buffer(b, bsz, bmax, &ent->id, sizeof(size_t)); - io_simple_buffer(b, bsz, bmax, &ent->type, sizeof(enum rtype)); - io_str_buffer(b, bsz, bmax, ent->uri); - io_simple_buffer(b, bsz, bmax, &ent->has_dgst, sizeof(int)); + io_simple_buffer(b, &ent->id, sizeof(ent->id)); + io_simple_buffer(b, &ent->type, sizeof(ent->type)); + io_str_buffer(b, ent->uri); + io_simple_buffer(b, &ent->has_dgst, sizeof(int)); if (ent->has_dgst) - io_simple_buffer(b, bsz, bmax, ent->dgst, sizeof(ent->dgst)); - io_simple_buffer(b, bsz, bmax, &ent->has_pkey, sizeof(int)); + io_simple_buffer(b, ent->dgst, sizeof(ent->dgst)); + io_simple_buffer(b, &ent->has_pkey, sizeof(int)); if (ent->has_pkey) - io_buf_buffer(b, bsz, bmax, ent->pkey, ent->pkeysz); - io_str_buffer(b, bsz, bmax, ent->descr); + io_buf_buffer(b, ent->pkey, ent->pkeysz); + io_str_buffer(b, ent->descr); } /* @@ -261,14 +262,14 @@ entity_buffer_req(char **b, size_t *bsz, size_t *bmax, * Simply a wrapper around entity_buffer_req(). */ static void -entity_write_req(int fd, const struct entity *ent) +entity_write_req(struct msgbuf *msgq, const struct entity *ent) { - char *b = NULL; - size_t bsz = 0, bmax = 0; + struct ibuf *b; - entity_buffer_req(&b, &bsz, &bmax, ent); - io_simple_write(fd, b, bsz); - free(b); + if ((b = ibuf_dynamic(sizeof(*ent), UINT_MAX)) == NULL) + err(1, NULL); + entity_buffer_req(b, ent); + ibuf_close(msgq, b); } /* @@ -276,14 +277,14 @@ entity_write_req(int fd, const struct entity *ent) * repo, then flush those into the parser process. */ static void -entityq_flush(int fd, struct entityq *q, const struct repo *repo) +entityq_flush(struct msgbuf *msgq, struct entityq *q, const struct repo *repo) { struct entity *p; TAILQ_FOREACH(p, q, entries) { if (p->repo < 0 || repo->id != (size_t)p->repo) continue; - entity_write_req(fd, p); + entity_write_req(msgq, p); } } @@ -291,13 +292,12 @@ entityq_flush(int fd, struct entityq *q, const struct repo *repo) * Look up a repository, queueing it for discovery if not found. */ static const struct repo * -repo_lookup(int fd, const char *uri) +repo_lookup(struct msgbuf *msgq, const char *uri) { const char *host, *mod; size_t hostsz, modsz, i; struct repo *rp; - char *b = NULL; - size_t bsz = 0, bmax = 0; + struct ibuf *b; if (!rsync_uri_parse(&host, &hostsz, &mod, &modsz, NULL, NULL, NULL, uri)) @@ -334,12 +334,13 @@ repo_lookup(int fd, const char *uri) if (!noop) { logx("%s/%s: pulling from network", rp->host, rp->module); - io_simple_buffer(&b, &bsz, &bmax, &i, sizeof(size_t)); - io_str_buffer(&b, &bsz, &bmax, rp->host); - io_str_buffer(&b, &bsz, &bmax, rp->module); + if ((b = ibuf_dynamic(128, UINT_MAX)) == NULL) + err(1, NULL); + io_simple_buffer(b, &i, sizeof(i)); + io_str_buffer(b, rp->host); + io_str_buffer(b, rp->module); - io_simple_write(fd, b, bsz); - free(b); + ibuf_close(msgq, b); } else { rp->loaded = 1; logx("%s/%s: using cache", rp->host, rp->module); @@ -387,18 +388,16 @@ entityq_next(int fd, struct entityq *q) } static void -entity_buffer_resp(char **b, size_t *bsz, size_t *bmax, - const struct entity *ent) +entity_buffer_resp(struct ibuf *b, const struct entity *ent) { - - io_simple_buffer(b, bsz, bmax, &ent->id, sizeof(size_t)); + io_simple_buffer(b, &ent->id, sizeof(size_t)); } /* * Add the heap-allocated file to the queue for processing. */ static void -entityq_add(int fd, struct entityq *q, char *file, enum rtype type, +entityq_add(struct msgbuf *msgq, struct entityq *q, char *file, enum rtype type, const struct repo *rp, const unsigned char *dgst, const unsigned char *pkey, size_t pkeysz, char *descr, size_t *eid) { @@ -434,7 +433,7 @@ entityq_add(int fd, struct entityq *q, char *file, enum rtype type, */ if (rp == NULL || rp->loaded) - entity_write_req(fd, p); + entity_write_req(msgq, p); } /* @@ -442,7 +441,7 @@ entityq_add(int fd, struct entityq *q, char *file, enum rtype type, * These are always relative to the directory in which "mft" sits. */ static void -queue_add_from_mft(int fd, struct entityq *q, const char *mft, +queue_add_from_mft(struct msgbuf *msgq, struct entityq *q, const char *mft, const struct mftfile *file, enum rtype type, size_t *eid) { char *cp, *nfile; @@ -461,7 +460,7 @@ queue_add_from_mft(int fd, struct entityq *q, const char *mft, * that the repository has already been loaded. */ - entityq_add(fd, q, nfile, type, NULL, file->hash, NULL, 0, NULL, eid); + entityq_add(msgq, q, nfile, type, NULL, file->hash, NULL, 0, NULL, eid); } /* @@ -473,8 +472,8 @@ queue_add_from_mft(int fd, struct entityq *q, const char *mft, * check the suffix anyway). */ static void -queue_add_from_mft_set(int fd, struct entityq *q, const struct mft *mft, - size_t *eid) +queue_add_from_mft_set(struct msgbuf *msgq, struct entityq *q, + const struct mft *mft, size_t *eid) { size_t i, sz; const struct mftfile *f; @@ -485,7 +484,7 @@ queue_add_from_mft_set(int fd, struct entityq *q, const struct mft *mft, assert(sz > 4); if (strcasecmp(f->file + sz - 4, ".crl")) continue; - queue_add_from_mft(fd, q, mft->file, f, RTYPE_CRL, eid); + queue_add_from_mft(msgq, q, mft->file, f, RTYPE_CRL, eid); } for (i = 0; i < mft->filesz; i++) { @@ -494,7 +493,7 @@ queue_add_from_mft_set(int fd, struct entityq *q, const struct mft *mft, assert(sz > 4); if (strcasecmp(f->file + sz - 4, ".cer")) continue; - queue_add_from_mft(fd, q, mft->file, f, RTYPE_CER, eid); + queue_add_from_mft(msgq, q, mft->file, f, RTYPE_CER, eid); } for (i = 0; i < mft->filesz; i++) { @@ -503,7 +502,7 @@ queue_add_from_mft_set(int fd, struct entityq *q, const struct mft *mft, assert(sz > 4); if (strcasecmp(f->file + sz - 4, ".roa")) continue; - queue_add_from_mft(fd, q, mft->file, f, RTYPE_ROA, eid); + queue_add_from_mft(msgq, q, mft->file, f, RTYPE_ROA, eid); } for (i = 0; i < mft->filesz; i++) { @@ -512,7 +511,7 @@ queue_add_from_mft_set(int fd, struct entityq *q, const struct mft *mft, assert(sz > 4); if (strcasecmp(f->file + sz - 4, ".gbr")) continue; - queue_add_from_mft(fd, q, mft->file, f, RTYPE_GBR, eid); + queue_add_from_mft(msgq, q, mft->file, f, RTYPE_GBR, eid); } for (i = 0; i < mft->filesz; i++) { @@ -532,7 +531,8 @@ queue_add_from_mft_set(int fd, struct entityq *q, const struct mft *mft, * Add a local TAL file (RFC 7730) to the queue of files to fetch. */ static void -queue_add_tal(int fd, struct entityq *q, const char *file, size_t *eid) +queue_add_tal(struct msgbuf *msgq, struct entityq *q, const char *file, + size_t *eid) { char *nfile, *buf; @@ -552,7 +552,7 @@ queue_add_tal(int fd, struct entityq *q, const char *file, size_t *eid) } /* Not in a repository, so directly add to queue. */ - entityq_add(fd, q, nfile, RTYPE_TAL, NULL, NULL, NULL, 0, buf, eid); + entityq_add(msgq, q, nfile, RTYPE_TAL, NULL, NULL, NULL, 0, buf, eid); /* entityq_add makes a copy of buf */ free(buf); } @@ -561,8 +561,8 @@ queue_add_tal(int fd, struct entityq *q, const char *file, size_t *eid) * Add URIs (CER) from a TAL file, RFC 8630. */ static void -queue_add_from_tal(int proc, int rsync, struct entityq *q, - const struct tal *tal, size_t *eid) +queue_add_from_tal(struct msgbuf *procq, struct msgbuf *rsyncq, + struct entityq *q, const struct tal *tal, size_t *eid) { char *nfile; const struct repo *repo; @@ -580,10 +580,10 @@ queue_add_from_tal(int proc, int rsync, struct entityq *q, errx(1, "TAL file has no rsync:// URI"); /* Look up the repository. */ - repo = repo_lookup(rsync, uri); + repo = repo_lookup(rsyncq, uri); nfile = repo_filename(repo, uri); - entityq_add(proc, q, nfile, RTYPE_CER, repo, NULL, tal->pkey, + entityq_add(procq, q, nfile, RTYPE_CER, repo, NULL, tal->pkey, tal->pkeysz, tal->descr, eid); } @@ -591,8 +591,8 @@ queue_add_from_tal(int proc, int rsync, struct entityq *q, * Add a manifest (MFT) found in an X509 certificate, RFC 6487. */ static void -queue_add_from_cert(int proc, int rsync, struct entityq *q, - const char *rsyncuri, const char *rrdpuri, size_t *eid) +queue_add_from_cert(struct msgbuf *procq, struct msgbuf *rsyncq, + struct entityq *q, const char *rsyncuri, const char *rrdpuri, size_t *eid) { char *nfile; const struct repo *repo; @@ -601,10 +601,10 @@ queue_add_from_cert(int proc, int rsync, struct entityq *q, return; /* Look up the repository. */ - repo = repo_lookup(rsync, rsyncuri); + repo = repo_lookup(rsyncq, rsyncuri); nfile = repo_filename(repo, rsyncuri); - entityq_add(proc, q, nfile, RTYPE_MFT, repo, NULL, NULL, 0, NULL, eid); + entityq_add(procq, q, nfile, RTYPE_MFT, repo, NULL, NULL, 0, NULL, eid); } /* @@ -1044,10 +1044,9 @@ proc_parser(int fd) struct entity *entp; struct entityq q; int c, rc = 1; + struct msgbuf msgq; struct pollfd pfd; - char *b = NULL; - size_t bsz = 0, bmax = 0, bpos = 0; - ssize_t ssz; + struct ibuf *b; X509_STORE *store; X509_STORE_CTX *ctx; struct auth_tree auths = RB_INITIALIZER(&auths); @@ -1064,12 +1063,18 @@ proc_parser(int fd) TAILQ_INIT(&q); + msgbuf_init(&msgq); + msgq.fd = fd; + pfd.fd = fd; - pfd.events = POLLIN; io_socket_nonblocking(pfd.fd); for (;;) { + pfd.events = POLLIN; + if (msgq.queued) + pfd.events |= POLLOUT; + if (poll(&pfd, 1, INFTIM) == -1) err(1, "poll"); if ((pfd.revents & (POLLERR|POLLNVAL))) @@ -1095,29 +1100,16 @@ proc_parser(int fd) err(1, NULL); entity_read_req(fd, entp); TAILQ_INSERT_TAIL(&q, entp, entries); - pfd.events |= POLLOUT; io_socket_nonblocking(fd); } - if (!(pfd.revents & POLLOUT)) - continue; - - /* - * If we have a write buffer, then continue trying to - * push it all out. - * When it's all pushed out, reset it and get ready to - * continue sucking down more data. - */ - - if (bsz) { - assert(bpos < bmax); - if ((ssz = write(fd, b + bpos, bsz)) == -1) + if (pfd.revents & POLLOUT) { + switch (msgbuf_write(&msgq)) { + case 0: + errx(1, "write: connection closed"); + case -1: err(1, "write"); - bpos += ssz; - bsz -= ssz; - if (bsz) - continue; - bpos = bsz = 0; + } } /* @@ -1133,14 +1125,16 @@ proc_parser(int fd) entp = TAILQ_FIRST(&q); assert(entp != NULL); - entity_buffer_resp(&b, &bsz, &bmax, entp); + if ((b = ibuf_dynamic(256, UINT_MAX)) == NULL) + err(1, NULL); + entity_buffer_resp(b, entp); switch (entp->type) { case RTYPE_TAL: assert(!entp->has_dgst); if ((tal = tal_parse(entp->uri, entp->descr)) == NULL) goto out; - tal_buffer(&b, &bsz, &bmax, tal); + tal_buffer(b, tal); tal_free(tal); break; case RTYPE_CER: @@ -1151,9 +1145,9 @@ proc_parser(int fd) cert = proc_parser_root_cert(entp, store, ctx, &auths, &crlt); c = (cert != NULL); - io_simple_buffer(&b, &bsz, &bmax, &c, sizeof(int)); + io_simple_buffer(b, &c, sizeof(int)); if (cert != NULL) - cert_buffer(&b, &bsz, &bmax, cert); + cert_buffer(b, cert); /* * The parsed certificate data "cert" is now * managed in the "auths" table, so don't free @@ -1163,9 +1157,9 @@ proc_parser(int fd) case RTYPE_MFT: mft = proc_parser_mft(entp, store, ctx, &auths, &crlt); c = (mft != NULL); - io_simple_buffer(&b, &bsz, &bmax, &c, sizeof(int)); + io_simple_buffer(b, &c, sizeof(int)); if (mft != NULL) - mft_buffer(&b, &bsz, &bmax, mft); + mft_buffer(b, mft); mft_free(mft); break; case RTYPE_CRL: @@ -1175,9 +1169,9 @@ proc_parser(int fd) assert(entp->has_dgst); roa = proc_parser_roa(entp, store, ctx, &auths, &crlt); c = (roa != NULL); - io_simple_buffer(&b, &bsz, &bmax, &c, sizeof(int)); + io_simple_buffer(b, &c, sizeof(int)); if (roa != NULL) - roa_buffer(&b, &bsz, &bmax, roa); + roa_buffer(b, roa); roa_free(roa); break; case RTYPE_GBR: @@ -1187,6 +1181,7 @@ proc_parser(int fd) abort(); } + ibuf_close(&msgq, b); TAILQ_REMOVE(&q, entp, entries); entity_free(entp); } @@ -1203,7 +1198,7 @@ out: X509_STORE_CTX_free(ctx); X509_STORE_free(store); - free(b); + msgbuf_clear(&msgq); exit(rc); } @@ -1215,8 +1210,8 @@ out: * In all cases, we gather statistics. */ static void -entity_process(int proc, int rsync, struct stats *st, - struct entityq *q, const struct entity *ent, +entity_process(int proc, struct msgbuf *procq, struct msgbuf *rsyncq, + struct stats *st, struct entityq *q, const struct entity *ent, size_t *eid, struct vrp_tree *tree) { struct tal *tal; @@ -1236,7 +1231,7 @@ entity_process(int proc, int rsync, struct stats *st, case RTYPE_TAL: st->tals++; tal = tal_read(proc); - queue_add_from_tal(proc, rsync, q, tal, eid); + queue_add_from_tal(procq, rsyncq, q, tal, eid); tal_free(tal); break; case RTYPE_CER: @@ -1254,7 +1249,7 @@ entity_process(int proc, int rsync, struct stats *st, * we're revoked and then we don't want to * process the MFT. */ - queue_add_from_cert(proc, rsync, + queue_add_from_cert(procq, rsyncq, q, cert->mft, cert->notify, eid); } else st->certs_invalid++; @@ -1270,7 +1265,7 @@ entity_process(int proc, int rsync, struct stats *st, mft = mft_read(proc); if (mft->stale) st->mfts_stale++; - queue_add_from_mft_set(proc, q, mft, eid); + queue_add_from_mft_set(procq, q, mft, eid); mft_free(mft); break; case RTYPE_CRL: @@ -1430,6 +1425,7 @@ main(int argc, char *argv[]) int fd[2]; struct entityq q; struct entity *ent; + struct msgbuf procq, rsyncq; struct pollfd pfd[2]; struct roa **out = NULL; char *rsync_prog = "openrsync"; @@ -1609,14 +1605,10 @@ main(int argc, char *argv[]) if (pledge("stdio rpath wpath cpath fattr", NULL) == -1) err(1, "pledge"); - /* - * Prime the process with our TAL file. - * This will contain (hopefully) links to our manifest and we - * can get the ball rolling. - */ - - for (i = 0; i < talsz; i++) - queue_add_tal(proc, &q, tals[i], &eid); + msgbuf_init(&procq); + msgbuf_init(&rsyncq); + procq.fd = proc; + rsyncq.fd = rsync; /* * The main process drives the top-down scan to leaf ROAs using @@ -1626,9 +1618,24 @@ main(int argc, char *argv[]) pfd[0].fd = rsync; pfd[1].fd = proc; - pfd[0].events = pfd[1].events = POLLIN; + + /* + * Prime the process with our TAL file. + * This will contain (hopefully) links to our manifest and we + * can get the ball rolling. + */ + + for (i = 0; i < talsz; i++) + queue_add_tal(&procq, &q, tals[i], &eid); while (!TAILQ_EMPTY(&q) && !killme) { + pfd[0].events = POLLIN; + if (rsyncq.queued) + pfd[0].events = POLLOUT; + pfd[1].events = POLLIN; + if (procq.queued) + pfd[1].events = POLLOUT; + if ((c = poll(pfd, 2, verbose ? 10000 : INFTIM)) == -1) { if (errno == EINTR) continue; @@ -1656,6 +1663,23 @@ main(int argc, char *argv[]) (pfd[1].revents & POLLHUP)) errx(1, "poll: hangup"); + if (pfd[0].revents & POLLOUT) { + switch (msgbuf_write(&rsyncq)) { + case 0: + errx(1, "write: connection closed"); + case -1: + err(1, "write"); + } + } + if (pfd[1].revents & POLLOUT) { + switch (msgbuf_write(&procq)) { + case 0: + errx(1, "write: connection closed"); + case -1: + err(1, "write"); + } + } + /* * Check the rsync process. * This means that one of our modules has completed @@ -1678,7 +1702,7 @@ main(int argc, char *argv[]) "fallback to cache", rt.repos[i].host, rt.repos[i].module); stats.repos++; - entityq_flush(proc, &q, &rt.repos[i]); + entityq_flush(&procq, &q, &rt.repos[i]); } /* @@ -1688,7 +1712,7 @@ main(int argc, char *argv[]) if ((pfd[1].revents & POLLIN)) { ent = entityq_next(proc, &q); - entity_process(proc, rsync, &stats, + entity_process(proc, &procq, &rsyncq, &stats, &q, ent, &eid, &v); if (verbose > 2) fprintf(stderr, "%s\n", ent->uri); diff --git a/usr.sbin/rpki-client/mft.c b/usr.sbin/rpki-client/mft.c index 3b0d06635a4..767a84da490 100644 --- a/usr.sbin/rpki-client/mft.c +++ b/usr.sbin/rpki-client/mft.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mft.c,v 1.22 2020/12/21 11:35:55 claudio Exp $ */ +/* $OpenBSD: mft.c,v 1.23 2021/01/08 08:09:07 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -519,22 +519,21 @@ mft_free(struct mft *p) * See mft_read() for the other side of the pipe. */ void -mft_buffer(char **b, size_t *bsz, size_t *bmax, const struct mft *p) +mft_buffer(struct ibuf *b, const struct mft *p) { size_t i; - io_simple_buffer(b, bsz, bmax, &p->stale, sizeof(int)); - io_str_buffer(b, bsz, bmax, p->file); - io_simple_buffer(b, bsz, bmax, &p->filesz, sizeof(size_t)); + io_simple_buffer(b, &p->stale, sizeof(int)); + io_str_buffer(b, p->file); + io_simple_buffer(b, &p->filesz, sizeof(size_t)); for (i = 0; i < p->filesz; i++) { - io_str_buffer(b, bsz, bmax, p->files[i].file); - io_simple_buffer(b, bsz, bmax, - p->files[i].hash, SHA256_DIGEST_LENGTH); + io_str_buffer(b, p->files[i].file); + io_simple_buffer(b, p->files[i].hash, SHA256_DIGEST_LENGTH); } - io_str_buffer(b, bsz, bmax, p->aki); - io_str_buffer(b, bsz, bmax, p->ski); + io_str_buffer(b, p->aki); + io_str_buffer(b, p->ski); } /* diff --git a/usr.sbin/rpki-client/roa.c b/usr.sbin/rpki-client/roa.c index b6044d13681..98985b15a42 100644 --- a/usr.sbin/rpki-client/roa.c +++ b/usr.sbin/rpki-client/roa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roa.c,v 1.10 2020/12/21 11:35:55 claudio Exp $ */ +/* $OpenBSD: roa.c,v 1.11 2021/01/08 08:09:07 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -388,29 +388,25 @@ roa_free(struct roa *p) * See roa_read() for reader. */ void -roa_buffer(char **b, size_t *bsz, size_t *bmax, const struct roa *p) +roa_buffer(struct ibuf *b, const struct roa *p) { size_t i; - io_simple_buffer(b, bsz, bmax, &p->valid, sizeof(int)); - io_simple_buffer(b, bsz, bmax, &p->asid, sizeof(uint32_t)); - io_simple_buffer(b, bsz, bmax, &p->ipsz, sizeof(size_t)); + io_simple_buffer(b, &p->valid, sizeof(int)); + io_simple_buffer(b, &p->asid, sizeof(uint32_t)); + io_simple_buffer(b, &p->ipsz, sizeof(size_t)); for (i = 0; i < p->ipsz; i++) { - io_simple_buffer(b, bsz, bmax, - &p->ips[i].afi, sizeof(enum afi)); - io_simple_buffer(b, bsz, bmax, - &p->ips[i].maxlength, sizeof(size_t)); - io_simple_buffer(b, bsz, bmax, - p->ips[i].min, sizeof(p->ips[i].min)); - io_simple_buffer(b, bsz, bmax, - p->ips[i].max, sizeof(p->ips[i].max)); - ip_addr_buffer(b, bsz, bmax, &p->ips[i].addr); + io_simple_buffer(b, &p->ips[i].afi, sizeof(enum afi)); + io_simple_buffer(b, &p->ips[i].maxlength, sizeof(size_t)); + io_simple_buffer(b, p->ips[i].min, sizeof(p->ips[i].min)); + io_simple_buffer(b, p->ips[i].max, sizeof(p->ips[i].max)); + ip_addr_buffer(b, &p->ips[i].addr); } - io_str_buffer(b, bsz, bmax, p->aki); - io_str_buffer(b, bsz, bmax, p->ski); - io_str_buffer(b, bsz, bmax, p->tal); + io_str_buffer(b, p->aki); + io_str_buffer(b, p->ski); + io_str_buffer(b, p->tal); } /* diff --git a/usr.sbin/rpki-client/rsync.c b/usr.sbin/rpki-client/rsync.c index 5d4bee0e98e..dfe15e04600 100644 --- a/usr.sbin/rpki-client/rsync.c +++ b/usr.sbin/rpki-client/rsync.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rsync.c,v 1.12 2020/12/21 11:35:55 claudio Exp $ */ +/* $OpenBSD: rsync.c,v 1.13 2021/01/08 08:09:07 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -15,6 +15,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <sys/queue.h> #include <sys/stat.h> #include <sys/wait.h> #include <netinet/in.h> @@ -28,6 +29,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <imsg.h> #include "extern.h" @@ -171,21 +173,25 @@ proc_child(int signal) void proc_rsync(char *prog, char *bind_addr, int fd) { - size_t id, i, idsz = 0, bsz = 0, bmax = 0; + size_t id, i, idsz = 0; ssize_t ssz; char *host = NULL, *mod = NULL, *uri = NULL, - *dst = NULL, *path, *save, *cmd, *b = NULL; + *dst = NULL, *path, *save, *cmd; const char *pp; pid_t pid; char *args[32]; int st, rc = 0; struct stat stt; struct pollfd pfd; + struct msgbuf msgq; + struct ibuf *b; sigset_t mask, oldmask; struct rsyncproc *ids = NULL; pfd.fd = fd; - pfd.events = POLLIN; + + msgbuf_init(&msgq); + msgq.fd = fd; /* * Unveil the command we want to run. @@ -236,6 +242,10 @@ proc_rsync(char *prog, char *bind_addr, int fd) err(1, NULL); for (;;) { + pfd.events = POLLIN; + if (msgq.queued) + pfd.events |= POLLOUT; + if (ppoll(&pfd, 1, NULL, &oldmask) == -1) { if (errno != EINTR) err(1, "ppoll"); @@ -265,12 +275,12 @@ proc_rsync(char *prog, char *bind_addr, int fd) ok = 0; } - io_simple_buffer(&b, &bsz, &bmax, - &ids[i].id, sizeof(size_t)); - io_simple_buffer(&b, &bsz, &bmax, - &ok, sizeof(ok)); - io_simple_write(fd, b, bsz); - bsz = 0; + b = ibuf_open(sizeof(size_t) + sizeof(ok)); + if (b == NULL) + err(1, NULL); + io_simple_buffer(b, &ids[i].id, sizeof(size_t)); + io_simple_buffer(b, &ok, sizeof(ok)); + ibuf_close(&msgq, b); free(ids[i].uri); ids[i].uri = NULL; @@ -282,6 +292,18 @@ proc_rsync(char *prog, char *bind_addr, int fd) continue; } + if (pfd.revents & POLLOUT) { + switch (msgbuf_write(&msgq)) { + case 0: + errx(1, "write: connection closed"); + case -1: + err(1, "write"); + } + } + + if (!(pfd.revents & POLLIN)) + continue; + /* * Read til the parent exits. * That will mean that we can safely exit. @@ -370,7 +392,7 @@ proc_rsync(char *prog, char *bind_addr, int fd) free(ids[i].uri); } - free(b); + msgbuf_clear(&msgq); free(ids); exit(rc); /* NOTREACHED */ diff --git a/usr.sbin/rpki-client/tal.c b/usr.sbin/rpki-client/tal.c index f3db5d4f2eb..a724e5de2e6 100644 --- a/usr.sbin/rpki-client/tal.c +++ b/usr.sbin/rpki-client/tal.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tal.c,v 1.25 2020/12/21 11:35:55 claudio Exp $ */ +/* $OpenBSD: tal.c,v 1.26 2021/01/08 08:09:07 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -301,16 +301,16 @@ tal_free(struct tal *p) * See tal_read() for the other side of the pipe. */ void -tal_buffer(char **b, size_t *bsz, size_t *bmax, const struct tal *p) +tal_buffer(struct ibuf *b, const struct tal *p) { size_t i; - io_buf_buffer(b, bsz, bmax, p->pkey, p->pkeysz); - io_str_buffer(b, bsz, bmax, p->descr); - io_simple_buffer(b, bsz, bmax, &p->urisz, sizeof(size_t)); + io_buf_buffer(b, p->pkey, p->pkeysz); + io_str_buffer(b, p->descr); + io_simple_buffer(b, &p->urisz, sizeof(size_t)); for (i = 0; i < p->urisz; i++) - io_str_buffer(b, bsz, bmax, p->uri[i]); + io_str_buffer(b, p->uri[i]); } /* |