From aef00ae0fc918d53eb999acb7b04c6c4bd958887 Mon Sep 17 00:00:00 2001 From: claudio Date: Wed, 24 Nov 2021 15:24:16 +0000 Subject: [PATCH] Move some functions from rrdp.c to rrdp_util.c and hex_decode to encoding.c. This will make it easier to write a RRDP regress test. OK job@ deraadt@ --- usr.sbin/rpki-client/Makefile | 6 +- usr.sbin/rpki-client/encoding.c | 41 +++++- usr.sbin/rpki-client/extern.h | 3 +- usr.sbin/rpki-client/rrdp.c | 180 ++++------------------- usr.sbin/rpki-client/rrdp.h | 22 ++- usr.sbin/rpki-client/rrdp_notification.c | 15 +- usr.sbin/rpki-client/rrdp_util.c | 120 +++++++++++++++ 7 files changed, 220 insertions(+), 167 deletions(-) create mode 100644 usr.sbin/rpki-client/rrdp_util.c diff --git a/usr.sbin/rpki-client/Makefile b/usr.sbin/rpki-client/Makefile index be678c810d1..df64ea00d1f 100644 --- a/usr.sbin/rpki-client/Makefile +++ b/usr.sbin/rpki-client/Makefile @@ -1,11 +1,11 @@ -# $OpenBSD: Makefile,v 1.22 2021/10/25 14:08:34 claudio Exp $ +# $OpenBSD: Makefile,v 1.23 2021/11/24 15:24:16 claudio Exp $ PROG= rpki-client SRCS= as.c cert.c cms.c crl.c encoding.c gbr.c http.c io.c ip.c log.c \ main.c mft.c mkdir.c output.c output-bgpd.c output-bird.c \ output-csv.c output-json.c parser.c print.c repo.c roa.c rrdp.c \ - rrdp_delta.c rrdp_notification.c rrdp_snapshot.c rsync.c tal.c \ - validate.c x509.c + rrdp_delta.c rrdp_notification.c rrdp_snapshot.c rrdp_util.c \ + rsync.c tal.c validate.c x509.c MAN= rpki-client.8 LDADD+= -lexpat -ltls -lssl -lcrypto -lutil diff --git a/usr.sbin/rpki-client/encoding.c b/usr.sbin/rpki-client/encoding.c index 269f861be53..372489a81fd 100644 --- a/usr.sbin/rpki-client/encoding.c +++ b/usr.sbin/rpki-client/encoding.c @@ -1,4 +1,4 @@ -/* $OpenBSD: encoding.c,v 1.9 2021/10/31 16:00:14 claudio Exp $ */ +/* $OpenBSD: encoding.c,v 1.10 2021/11/24 15:24:16 claudio Exp $ */ /* * Copyright (c) 2020 Claudio Jeker * @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -185,3 +186,41 @@ hex_encode(const unsigned char *in, size_t insz) return out; } + +/* + * Hex decode hexstring into the supplied buffer. + * Return 0 on success else -1, if buffer too small or bad encoding. + */ +int +hex_decode(const char *hexstr, char *buf, size_t len) +{ + unsigned char ch, r; + size_t pos = 0; + int i; + + while (*hexstr) { + r = 0; + for (i = 0; i < 2; i++) { + ch = hexstr[i]; + if (isdigit(ch)) + ch -= '0'; + else if (islower(ch)) + ch -= ('a' - 10); + else if (isupper(ch)) + ch -= ('A' - 10); + else + return -1; + if (ch > 0xf) + return -1; + r = r << 4 | ch; + } + if (pos < len) + buf[pos++] = r; + else + return -1; + + hexstr += 2; + } + return 0; +} + diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h index 8729863ed51..a41e2ccd1d6 100644 --- a/usr.sbin/rpki-client/extern.h +++ b/usr.sbin/rpki-client/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.96 2021/11/10 08:34:48 job Exp $ */ +/* $OpenBSD: extern.h,v 1.97 2021/11/24 15:24:16 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -538,6 +538,7 @@ int base64_decode(const unsigned char *, size_t, int base64_encode_len(size_t, size_t *); int base64_encode(const unsigned char *, size_t, char **); char *hex_encode(const unsigned char *, size_t); +int hex_decode(const char *, char *, size_t); /* Functions for moving data between processes. */ diff --git a/usr.sbin/rpki-client/rrdp.c b/usr.sbin/rpki-client/rrdp.c index 9b338bad16a..67cc67d0823 100644 --- a/usr.sbin/rpki-client/rrdp.c +++ b/usr.sbin/rpki-client/rrdp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rrdp.c,v 1.17 2021/10/29 09:27:36 claudio Exp $ */ +/* $OpenBSD: rrdp.c,v 1.18 2021/11/24 15:24:16 claudio Exp $ */ /* * Copyright (c) 2020 Nils Fisher * Copyright (c) 2021 Claudio Jeker @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -76,14 +75,6 @@ struct rrdp { TAILQ_HEAD(,rrdp) states = TAILQ_HEAD_INITIALIZER(states); -struct publish_xml { - char *uri; - char *data; - char hash[SHA256_DIGEST_LENGTH]; - size_t data_length; - enum publish_type type; -}; - char * xstrdup(const char *s) { @@ -93,43 +84,6 @@ xstrdup(const char *s) return r; } -/* - * Hex decode hexstring into the supplied buffer. - * Return 0 on success else -1, if buffer too small or bad encoding. - */ -int -hex_decode(const char *hexstr, char *buf, size_t len) -{ - unsigned char ch, r; - size_t pos = 0; - int i; - - while (*hexstr) { - r = 0; - for (i = 0; i < 2; i++) { - ch = hexstr[i]; - if (isdigit(ch)) - ch -= '0'; - else if (islower(ch)) - ch -= ('a' - 10); - else if (isupper(ch)) - ch -= ('A' - 10); - else - return -1; - if (ch > 0xf) - return -1; - r = r << 4 | ch; - } - if (pos < len) - buf[pos++] = r; - else - return -1; - - hexstr += 2; - } - return 0; -} - /* * Report back that a RRDP request finished. * ok should only be set to 1 if the cache is now up-to-date. @@ -187,6 +141,31 @@ rrdp_state_send(struct rrdp *s) io_close_buffer(&msgq, b); } +/* + * Send a blob of data to the main process to store it in the repository. + */ +void +rrdp_publish_file(struct rrdp *s, struct publish_xml *pxml, + unsigned char *data, size_t datasz) +{ + enum rrdp_msg type = RRDP_FILE; + struct ibuf *b; + + /* only send files if the fetch did not fail already */ + if (s->file_failed == 0) { + b = io_new_buffer(); + io_simple_buffer(b, &type, sizeof(type)); + io_simple_buffer(b, &s->id, sizeof(s->id)); + io_simple_buffer(b, &pxml->type, sizeof(pxml->type)); + if (pxml->type != PUB_ADD) + io_simple_buffer(b, &pxml->hash, sizeof(pxml->hash)); + io_str_buffer(b, pxml->uri); + io_buf_buffer(b, data, datasz); + io_close_buffer(&msgq, b); + s->file_pending++; + } +} + static struct rrdp * rrdp_new(size_t id, char *local, char *notify, char *session_id, long long serial, char *last_mod) @@ -584,110 +563,3 @@ proc_rrdp(int fd) exit(0); } - -/* - * Both snapshots and deltas use publish_xml to store the publish and - * withdraw records. Once all the content is added the request is sent - * to the main process where it is processed. - */ -struct publish_xml * -new_publish_xml(enum publish_type type, char *uri, char *hash, size_t hlen) -{ - struct publish_xml *pxml; - - if ((pxml = calloc(1, sizeof(*pxml))) == NULL) - err(1, "%s", __func__); - - pxml->type = type; - pxml->uri = uri; - if (hlen > 0) { - assert(hlen == sizeof(pxml->hash)); - memcpy(pxml->hash, hash, hlen); - } - - return pxml; -} - -void -free_publish_xml(struct publish_xml *pxml) -{ - if (pxml == NULL) - return; - - free(pxml->uri); - free(pxml->data); - free(pxml); -} - -/* - * Add buf to the base64 data string, ensure that this remains a proper - * string by NUL-terminating the string. - */ -int -publish_add_content(struct publish_xml *pxml, const char *buf, int length) -{ - size_t newlen, outlen; - - /* - * optmisiation, this often gets called with '\n' as the - * only data... seems wasteful - */ - if (length == 1 && buf[0] == '\n') - return 0; - - /* append content to data */ - if (SIZE_MAX - length - 1 <= pxml->data_length) - return -1; - newlen = pxml->data_length + length; - if (base64_decode_len(newlen, &outlen) == -1 || - outlen > MAX_FILE_SIZE) - return -1; - - pxml->data = realloc(pxml->data, newlen + 1); - if (pxml->data == NULL) - err(1, "%s", __func__); - - memcpy(pxml->data + pxml->data_length, buf, length); - pxml->data[newlen] = '\0'; - pxml->data_length = newlen; - return 0; -} - -/* - * Base64 decode the data blob and send the file to the main process - * where the hash is validated and the file stored in the repository. - * Increase the file_pending counter to ensure the RRDP process waits - * until all files have been processed before moving to the next stage. - * Returns 0 on success or -1 on errors (base64 decode failed). - */ -int -publish_done(struct rrdp *s, struct publish_xml *pxml) -{ - enum rrdp_msg type = RRDP_FILE; - struct ibuf *b; - unsigned char *data = NULL; - size_t datasz = 0; - - if (pxml->data_length > 0) - if ((base64_decode(pxml->data, pxml->data_length, - &data, &datasz)) == -1) - return -1; - - /* only send files if the fetch did not fail already */ - if (s->file_failed == 0) { - b = io_new_buffer(); - io_simple_buffer(b, &type, sizeof(type)); - io_simple_buffer(b, &s->id, sizeof(s->id)); - io_simple_buffer(b, &pxml->type, sizeof(pxml->type)); - if (pxml->type != PUB_ADD) - io_simple_buffer(b, &pxml->hash, sizeof(pxml->hash)); - io_str_buffer(b, pxml->uri); - io_buf_buffer(b, data, datasz); - io_close_buffer(&msgq, b); - s->file_pending++; - } - - free(data); - free_publish_xml(pxml); - return 0; -} diff --git a/usr.sbin/rpki-client/rrdp.h b/usr.sbin/rpki-client/rrdp.h index a2ef3861274..7c7258a47e2 100644 --- a/usr.sbin/rpki-client/rrdp.h +++ b/usr.sbin/rpki-client/rrdp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rrdp.h,v 1.6 2021/10/29 09:27:36 claudio Exp $ */ +/* $OpenBSD: rrdp.h,v 1.7 2021/11/24 15:24:16 claudio Exp $ */ /* * Copyright (c) 2020 Nils Fisher * Copyright (c) 2021 Claudio Jeker @@ -35,14 +35,22 @@ enum rrdp_task { DELTA, }; -/* rrdp generic */ -char *xstrdup(const char *); -int hex_decode(const char *, char *, size_t); - -/* publish or withdraw element */ struct rrdp; -struct publish_xml; +struct publish_xml { + char *uri; + char *data; + char hash[SHA256_DIGEST_LENGTH]; + size_t data_length; + enum publish_type type; +}; + +/* rrdp generic */ +char *xstrdup(const char *); +void rrdp_publish_file(struct rrdp *, struct publish_xml *, + unsigned char *, size_t); + +/* rrdp util */ struct publish_xml *new_publish_xml(enum publish_type, char *, char *, size_t); void free_publish_xml(struct publish_xml *); diff --git a/usr.sbin/rpki-client/rrdp_notification.c b/usr.sbin/rpki-client/rrdp_notification.c index 28f01a0c552..9bc415585ff 100644 --- a/usr.sbin/rpki-client/rrdp_notification.c +++ b/usr.sbin/rpki-client/rrdp_notification.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rrdp_notification.c,v 1.11 2021/11/09 11:01:04 claudio Exp $ */ +/* $OpenBSD: rrdp_notification.c,v 1.12 2021/11/24 15:24:16 claudio Exp $ */ /* * Copyright (c) 2020 Nils Fisher * Copyright (c) 2021 Claudio Jeker @@ -464,6 +464,19 @@ notification_delta_done(struct notification_xml *nxml) void log_notification_xml(struct notification_xml *nxml) { + struct delta_item *d; + char *hash; + logx("session_id: %s, serial: %lld", nxml->session_id, nxml->serial); logx("snapshot_uri: %s", nxml->snapshot_uri); + hash = hex_encode(nxml->snapshot_hash, sizeof(nxml->snapshot_hash)); + logx("snapshot hash: %s", hash); + free(hash); + + TAILQ_FOREACH(d, &nxml->delta_q, q) { + logx("delta serial %lld uri: %s", d->serial, d->uri); + hash = hex_encode(d->hash, sizeof(d->hash)); + logx("delta hash: %s", hash); + free(hash); + } } diff --git a/usr.sbin/rpki-client/rrdp_util.c b/usr.sbin/rpki-client/rrdp_util.c new file mode 100644 index 00000000000..0565493b8c5 --- /dev/null +++ b/usr.sbin/rpki-client/rrdp_util.c @@ -0,0 +1,120 @@ +/* $OpenBSD: rrdp_util.c,v 1.1 2021/11/24 15:24:16 claudio Exp $ */ +/* + * Copyright (c) 2020 Nils Fisher + * Copyright (c) 2021 Claudio Jeker + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include +#include + +#include +#include + +#include "extern.h" +#include "rrdp.h" + +/* + * Both snapshots and deltas use publish_xml to store the publish and + * withdraw records. Once all the content is added the request is sent + * to the main process where it is processed. + */ +struct publish_xml * +new_publish_xml(enum publish_type type, char *uri, char *hash, size_t hlen) +{ + struct publish_xml *pxml; + + if ((pxml = calloc(1, sizeof(*pxml))) == NULL) + err(1, "%s", __func__); + + pxml->type = type; + pxml->uri = uri; + if (hlen > 0) { + assert(hlen == sizeof(pxml->hash)); + memcpy(pxml->hash, hash, hlen); + } + + return pxml; +} + +void +free_publish_xml(struct publish_xml *pxml) +{ + if (pxml == NULL) + return; + + free(pxml->uri); + free(pxml->data); + free(pxml); +} + +/* + * Add buf to the base64 data string, ensure that this remains a proper + * string by NUL-terminating the string. + */ +int +publish_add_content(struct publish_xml *pxml, const char *buf, int length) +{ + size_t newlen, outlen; + + /* + * optmisiation, this often gets called with '\n' as the + * only data... seems wasteful + */ + if (length == 1 && buf[0] == '\n') + return 0; + + /* append content to data */ + if (SIZE_MAX - length - 1 <= pxml->data_length) + return -1; + newlen = pxml->data_length + length; + if (base64_decode_len(newlen, &outlen) == -1 || + outlen > MAX_FILE_SIZE) + return -1; + + pxml->data = realloc(pxml->data, newlen + 1); + if (pxml->data == NULL) + err(1, "%s", __func__); + + memcpy(pxml->data + pxml->data_length, buf, length); + pxml->data[newlen] = '\0'; + pxml->data_length = newlen; + return 0; +} + +/* + * Base64 decode the data blob and send the file to the main process + * where the hash is validated and the file stored in the repository. + * Increase the file_pending counter to ensure the RRDP process waits + * until all files have been processed before moving to the next stage. + * Returns 0 on success or -1 on errors (base64 decode failed). + */ +int +publish_done(struct rrdp *s, struct publish_xml *pxml) +{ + unsigned char *data = NULL; + size_t datasz = 0; + + if (pxml->data_length > 0) + if ((base64_decode(pxml->data, pxml->data_length, + &data, &datasz)) == -1) + return -1; + + rrdp_publish_file(s, pxml, data, datasz); + + free(data); + free_publish_xml(pxml); + return 0; +} -- 2.20.1