Shuffling approved.
Claudio Jeker <[email protected]> wrote:
> For a RRDP regress test I would like to move some functions to better
> places. hex_decode() belongs into encoding.c and the publish XML code
> is now in rpki_util.c.
>
> --
> :wq Claudio
>
> Index: Makefile
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/Makefile,v
> retrieving revision 1.22
> diff -u -p -r1.22 Makefile
> --- Makefile 25 Oct 2021 14:08:34 -0000 1.22
> +++ Makefile 24 Nov 2021 12:43:19 -0000
> @@ -4,8 +4,8 @@ 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
> Index: encoding.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/encoding.c,v
> retrieving revision 1.9
> diff -u -p -r1.9 encoding.c
> --- encoding.c 31 Oct 2021 16:00:14 -0000 1.9
> +++ encoding.c 24 Nov 2021 12:53:23 -0000
> @@ -18,6 +18,7 @@
>
> #include <err.h>
> #include <errno.h>
> +#include <ctype.h>
> #include <fcntl.h>
> #include <limits.h>
> #include <stdlib.h>
> @@ -185,3 +186,41 @@ hex_encode(const unsigned char *in, size
>
> 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;
> +}
> +
> Index: extern.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
> retrieving revision 1.96
> diff -u -p -r1.96 extern.h
> --- extern.h 10 Nov 2021 08:34:48 -0000 1.96
> +++ extern.h 24 Nov 2021 12:53:04 -0000
> @@ -538,6 +538,7 @@ int base64_decode(const unsigned char
> 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. */
> Index: rrdp.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/rrdp.c,v
> retrieving revision 1.17
> diff -u -p -r1.17 rrdp.c
> --- rrdp.c 29 Oct 2021 09:27:36 -0000 1.17
> +++ rrdp.c 24 Nov 2021 12:53:18 -0000
> @@ -19,7 +19,6 @@
> #include <sys/stat.h>
>
> #include <assert.h>
> -#include <ctype.h>
> #include <err.h>
> #include <errno.h>
> #include <fcntl.h>
> @@ -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)
> {
> @@ -94,43 +85,6 @@ xstrdup(const char *s)
> }
>
> /*
> - * 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)
> @@ -583,111 +562,4 @@ 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;
> }
> Index: rrdp.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/rrdp.h,v
> retrieving revision 1.6
> diff -u -p -r1.6 rrdp.h
> --- rrdp.h 29 Oct 2021 09:27:36 -0000 1.6
> +++ rrdp.h 24 Nov 2021 12:52:56 -0000
> @@ -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 *);
> Index: rrdp_notification.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/rrdp_notification.c,v
> retrieving revision 1.11
> diff -u -p -r1.11 rrdp_notification.c
> --- rrdp_notification.c 9 Nov 2021 11:01:04 -0000 1.11
> +++ rrdp_notification.c 24 Nov 2021 13:26:02 -0000
> @@ -464,6 +464,19 @@ notification_delta_done(struct notificat
> 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);
> + }
> }
> Index: rrdp_util.c
> ===================================================================
> RCS file: rrdp_util.c
> diff -N rrdp_util.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ rrdp_util.c 24 Nov 2021 12:50:03 -0000
> @@ -0,0 +1,120 @@
> +/* $OpenBSD$ */
> +/*
> + * Copyright (c) 2020 Nils Fisher <[email protected]>
> + * Copyright (c) 2021 Claudio Jeker <[email protected]>
> + *
> + * 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 <assert.h>
> +#include <err.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#include <expat.h>
> +#include <openssl/sha.h>
> +
> +#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;
> +}
>