Ensure that RRDP snapshot and delta files are fetched from the same host
authorclaudio <claudio@openbsd.org>
Fri, 29 Oct 2021 09:27:36 +0000 (09:27 +0000)
committerclaudio <claudio@openbsd.org>
Fri, 29 Oct 2021 09:27:36 +0000 (09:27 +0000)
as the notification file.
OK tb@ job@

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/validate.c

index 77a3aa2..c8c4cfa 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: extern.h,v 1.85 2021/10/28 13:51:42 job Exp $ */
+/*     $OpenBSD: extern.h,v 1.86 2021/10/29 09:27:36 claudio Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -444,6 +444,7 @@ int          valid_roa(const char *, struct auth_tree *, struct roa *);
 int             valid_filename(const char *);
 int             valid_filehash(const char *, const char *, size_t);
 int             valid_uri(const char *, size_t, const char *);
+int             valid_origin(const char *, const char *);
 
 /* Working with CMS. */
 unsigned char  *cms_parse_validate(X509 **, const char *,
index 5883d9c..9b338ba 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rrdp.c,v 1.16 2021/10/28 11:57:00 claudio Exp $ */
+/*     $OpenBSD: rrdp.c,v 1.17 2021/10/29 09:27:36 claudio Exp $ */
 /*
  * Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com>
  * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
@@ -208,7 +208,8 @@ rrdp_new(size_t id, char *local, char *notify, char *session_id,
        if ((s->parser = XML_ParserCreate("US-ASCII")) == NULL)
                err(1, "XML_ParserCreate");
 
-       s->nxml = new_notification_xml(s->parser, &s->repository, &s->current);
+       s->nxml = new_notification_xml(s->parser, &s->repository, &s->current,
+           notify);
 
        TAILQ_INSERT_TAIL(&states, s, entry);
 
index 9a230b7..a2ef386 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rrdp.h,v 1.5 2021/10/28 11:57:00 claudio Exp $ */
+/*     $OpenBSD: rrdp.h,v 1.6 2021/10/29 09:27:36 claudio Exp $ */
 /*
  * Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com>
  * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
@@ -54,7 +54,8 @@ int                    publish_done(struct rrdp *, struct publish_xml *);
 struct notification_xml;
 
 struct notification_xml        *new_notification_xml(XML_Parser,
-                           struct rrdp_session *, struct rrdp_session *);
+                           struct rrdp_session *, struct rrdp_session *,
+                           const char *);
 void                    free_notification_xml(struct notification_xml *);
 enum rrdp_task          notification_done(struct notification_xml *,
                            char *);
index 09eac7c..654dbf3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rrdp_notification.c,v 1.8 2021/10/24 17:16:09 claudio Exp $ */
+/*     $OpenBSD: rrdp_notification.c,v 1.9 2021/10/29 09:27:36 claudio Exp $ */
 /*
  * Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com>
  * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
@@ -54,6 +54,7 @@ struct notification_xml {
        XML_Parser               parser;
        struct rrdp_session     *repository;
        struct rrdp_session     *current;
+       const char              *notifyuri;
        char                    *session_id;
        char                    *snapshot_uri;
        char                     snapshot_hash[SHA256_DIGEST_LENGTH];
@@ -172,7 +173,8 @@ start_snapshot_elem(struct notification_xml *nxml, const char **attr)
        for (i = 0; attr[i]; i += 2) {
                if (strcmp("uri", attr[i]) == 0 && hasUri++ == 0) {
                        if (valid_uri(attr[i + 1], strlen(attr[i + 1]),
-                           "https://")) {
+                           "https://") &&
+                           valid_origin(attr[i + 1], nxml->notifyuri)) {
                                nxml->snapshot_uri = xstrdup(attr[i + 1]);
                                continue;
                        }
@@ -217,7 +219,8 @@ start_delta_elem(struct notification_xml *nxml, const char **attr)
        for (i = 0; attr[i]; i += 2) {
                if (strcmp("uri", attr[i]) == 0 && hasUri++ == 0) {
                        if (valid_uri(attr[i + 1], strlen(attr[i + 1]),
-                           "https://")) {
+                           "https://") &&
+                           valid_origin(attr[i + 1], nxml->notifyuri)) {
                                delta_uri = attr[i + 1];
                                continue;
                        }
@@ -307,7 +310,7 @@ notification_xml_elem_end(void *data, const char *el)
 
 struct notification_xml *
 new_notification_xml(XML_Parser p, struct rrdp_session *repository,
-    struct rrdp_session *current)
+    struct rrdp_session *current, const char *notifyuri)
 {
        struct notification_xml *nxml;
 
@@ -317,6 +320,7 @@ new_notification_xml(XML_Parser p, struct rrdp_session *repository,
        nxml->parser = p;
        nxml->repository = repository;
        nxml->current = current;
+       nxml->notifyuri = notifyuri;
 
        XML_SetElementHandler(nxml->parser, notification_xml_elem_start,
            notification_xml_elem_end);
index 0e4e254..a6df8e6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: validate.c,v 1.19 2021/10/27 21:56:58 beck Exp $ */
+/*     $OpenBSD: validate.c,v 1.20 2021/10/29 09:27:36 claudio Exp $ */
 /*
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -341,3 +341,27 @@ valid_uri(const char *uri, size_t usz, const char *proto)
 
        return 1;
 }
+
+/*
+ * Validate that a URI has the same host as the URI passed in proto.
+ * Returns 1 if valid, 0 otherwise.
+ */
+int
+valid_origin(const char *uri, const char *proto)
+{
+       const char *to;
+
+       /* extract end of host from proto URI */
+       to = strstr(proto, "://");
+       if (to == NULL)
+               return 0;
+       to += strlen("://");
+       if ((to = strchr(to, '/')) == NULL)
+               return 0;
+
+       /* compare hosts including the / for the start of the path section */
+       if (strncasecmp(uri, proto, to - proto + 1) != 0)
+               return 0;
+
+       return 1;
+}