return error;
}
+static int
+parse_notification_snapshot(xmlTextReaderPtr reader,
+ struct update_notification *notif)
+{
+ int error;
+
+ error = parse_file_metadata(reader, NULL, HR_MANDATORY, ¬if->snapshot);
+ if (error)
+ return error;
+
+ if (!uri_same_origin(notif->uri, notif->snapshot.uri))
+ return pr_val_err("Notification '%s' and Snapshot '%s' are not hosted by the same origin.",
+ uri_get_global(notif->uri), uri_get_global(notif->snapshot.uri));
+
+ return 0;
+}
+
static int
parse_notification_delta(xmlTextReaderPtr reader,
struct update_notification *notif)
return error;
error = parse_file_metadata(reader, NULL, HR_MANDATORY, &delta.meta);
- if (error) {
- serial_cleanup(&delta.serial);
- return error;
+ if (error)
+ goto srl;
+
+ if (!uri_same_origin(notif->uri, delta.meta.uri)) {
+ error = pr_val_err("Notification %s and Delta %s are not hosted by the same origin.",
+ uri_get_global(notif->uri), uri_get_global(delta.meta.uri));
+ goto mta;
}
notification_deltas_add(¬if->deltas, &delta);
return 0;
+
+mta: metadata_cleanup(&delta.meta);
+srl: serial_cleanup(&delta.serial);
+ return error;
}
static int
if (xmlStrEqual(name, BAD_CAST RRDP_ELEM_DELTA)) {
return parse_notification_delta(reader, notif);
} else if (xmlStrEqual(name, BAD_CAST RRDP_ELEM_SNAPSHOT)) {
- return parse_file_metadata(reader, NULL, HR_MANDATORY,
- ¬if->snapshot);
+ return parse_notification_snapshot(reader, notif);
} else if (xmlStrEqual(name, BAD_CAST RRDP_ELEM_NOTIFICATION)) {
/* No need to validate session ID and serial */
return parse_session(reader, ¬if->session);
return (get_rrdp_workspace(&pb, tal, notif) == 0) ? pb.string : NULL;
}
+bool
+uri_same_origin(struct rpki_uri const *uri1, struct rpki_uri const *uri2)
+{
+ char const *str1, *str2;
+ size_t c, slashes;
+
+ str1 = uri1->global;
+ str2 = uri2->global;
+ slashes = 0;
+
+ for (c = 0; str1[c] == str2[c]; c++) {
+ switch (str1[c]) {
+ case '/':
+ slashes++;
+ if (slashes == 3)
+ return true;
+ break;
+ case '\0':
+ return slashes == 2;
+ }
+ }
+
+ if (str1[c] == '\0')
+ return (slashes == 2) && str2[c] == '/';
+ if (str2[c] == '\0')
+ return (slashes == 2) && str1[c] == '/';
+
+ return false;
+}
+
DEFINE_ARRAY_LIST_FUNCTIONS(uri_list, struct rpki_uri *, static)
void