This will make it easier to write a RRDP regress test.
OK job@ deraadt@
-# $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
-/* $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 <claudio@openbsd.org>
*
#include <err.h>
#include <errno.h>
+#include <ctype.h>
#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>
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;
+}
+
-/* $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 <kristaps@bsd.lv>
*
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. */
-/* $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 <nils_fisher@hotmail.com>
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
#include <sys/stat.h>
#include <assert.h>
-#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
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)
{
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.
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)
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;
-}
-/* $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 <nils_fisher@hotmail.com>
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
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 *);
-/* $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 <nils_fisher@hotmail.com>
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
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);
+ }
}
--- /dev/null
+/* $OpenBSD: rrdp_util.c,v 1.1 2021/11/24 15:24:16 claudio Exp $ */
+/*
+ * Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com>
+ * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
+ *
+ * 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;
+}