Move some functions from rrdp.c to rrdp_util.c and hex_decode to encoding.c.
authorclaudio <claudio@openbsd.org>
Wed, 24 Nov 2021 15:24:16 +0000 (15:24 +0000)
committerclaudio <claudio@openbsd.org>
Wed, 24 Nov 2021 15:24:16 +0000 (15:24 +0000)
This will make it easier to write a RRDP regress test.
OK job@ deraadt@

usr.sbin/rpki-client/Makefile
usr.sbin/rpki-client/encoding.c
usr.sbin/rpki-client/extern.h
usr.sbin/rpki-client/rrdp.c
usr.sbin/rpki-client/rrdp.h
usr.sbin/rpki-client/rrdp_notification.c
usr.sbin/rpki-client/rrdp_util.c [new file with mode: 0644]

index be678c8..df64ea0 100644 (file)
@@ -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
index 269f861..372489a 100644 (file)
@@ -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 <claudio@openbsd.org>
  *
@@ -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_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;
+}
+
index 8729863..a41e2cc 100644 (file)
@@ -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 <kristaps@bsd.lv>
  *
@@ -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. */
index 9b338ba..67cc67d 100644 (file)
@@ -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 <nils_fisher@hotmail.com>
  * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
@@ -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)
 {
@@ -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;
-}
index a2ef386..7c7258a 100644 (file)
@@ -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 <nils_fisher@hotmail.com>
  * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
@@ -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 28f01a0..9bc4155 100644 (file)
@@ -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 <nils_fisher@hotmail.com>
  * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
@@ -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 (file)
index 0000000..0565493
--- /dev/null
@@ -0,0 +1,120 @@
+/*     $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;
+}