Version in base suite: 1.6.6-1 Base version: fort-validator_1.6.6-1 Target version: fort-validator_1.6.8-0+deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/f/fort-validator/fort-validator_1.6.6-1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/f/fort-validator/fort-validator_1.6.8-0+deb13u1.dsc configure.ac | 3 debian/changelog | 21 + debian/control | 6 debian/fort-validator.postrm | 15 - debian/fort-validator.purge | 1 debian/patches/documentation | 4 debian/patches/paths | 22 + debian/salsa-ci.yml | 3 debian/watch | 8 docker/Dockerfile | 8 docs/_config.yml | 2 docs/_layouts/default.html | 1 docs/css/screen.css | 20 + docs/installation.md | 408 ++++++++---------------------------- docs/intro-fort.md | 8 docs/stats.md | 42 +++ docs/usage.md | 69 ++++-- man/fort.8 | 34 ++- src/Makefile.am | 4 src/algorithm.c | 1 src/alloc.c | 3 src/alloc.h | 6 src/as_number.h | 3 src/asn1/asn1c/ANY.c | 1 src/asn1/asn1c/BIT_STRING.c | 1 src/asn1/asn1c/BOOLEAN.c | 2 src/asn1/asn1c/GeneralizedTime.c | 1 src/asn1/asn1c/INTEGER.c | 1 src/asn1/asn1c/NULL.c | 2 src/asn1/asn1c/OBJECT_IDENTIFIER.c | 1 src/asn1/asn1c/OBJECT_IDENTIFIER.h | 2 src/asn1/asn1c/OCTET_STRING.c | 1 src/asn1/asn1c/OPEN_TYPE.c | 2 src/asn1/asn1c/UTCTime.c | 1 src/asn1/asn1c/asn_codecs.h | 4 src/asn1/asn1c/asn_codecs_prim.c | 1 src/asn1/asn1c/asn_internal.h | 2 src/asn1/asn1c/asn_system.h | 3 src/asn1/asn1c/ber_tlv_tag.h | 4 src/asn1/asn1c/constr_CHOICE.c | 1 src/asn1/asn1c/constr_SEQUENCE.c | 1 src/asn1/asn1c/constr_SEQUENCE_OF.c | 2 src/asn1/asn1c/constr_SET_OF.c | 1 src/asn1/asn1c/constraints.c | 1 src/asn1/asn1c/der_encoder.c | 1 src/asn1/asn1c/xer_encoder.c | 2 src/asn1/oid.c | 2 src/common.c | 2 src/config.c | 69 +++++- src/config.h | 5 src/config/boolean.c | 1 src/config/curl_offset.c | 1 src/config/file_type.c | 1 src/config/filename_format.c | 1 src/config/log_conf.c | 4 src/config/mode.c | 1 src/config/output_format.c | 1 src/config/str.c | 38 +++ src/config/str.h | 1 src/config/string_array.c | 1 src/config/types.h | 5 src/config/uint.c | 1 src/crypto/base64.c | 2 src/crypto/base64.h | 6 src/data_structure/array_list.h | 3 src/data_structure/common.h | 6 src/data_structure/path_builder.h | 9 src/data_structure/uthash.h | 5 src/file.h | 2 src/http/http.c | 3 src/incidence/incidence.c | 1 src/json_handler.c | 1 src/json_util.c | 1 src/json_util.h | 8 src/line_file.c | 2 src/line_file.h | 5 src/main.c | 20 + src/nid.c | 42 +-- src/object/certificate.c | 51 ++++ src/object/tal.c | 6 src/object/vcard.c | 3 src/prometheus.c | 165 ++++++++++++++ src/prometheus.h | 7 src/resource/ip6.c | 2 src/rrdp.c | 54 +++- src/rsync/rsync.c | 2 src/rtr/db/db_table.c | 33 ++ src/rtr/db/db_table.h | 2 src/rtr/db/delta.c | 1 src/rtr/err_pdu.c | 1 src/rtr/pdu.h | 9 src/rtr/pdu_sender.c | 1 src/rtr/pdu_stream.c | 4 src/rtr/pdu_stream.h | 2 src/rtr/primitive_writer.h | 1 src/rtr/rtr.c | 5 src/slurm/db_slurm.c | 1 src/slurm/slurm_parser.c | 3 src/sorted_array.c | 4 src/sorted_array.h | 6 src/stats.c | 187 ++++++++++++++++ src/stats.h | 16 + src/str_token.c | 1 src/str_token.h | 6 src/thread/thread_pool.c | 2 src/types/address.h | 1 src/types/bio_seq.c | 2 src/types/router_key.h | 3 src/types/serial.h | 3 src/types/uri.c | 32 ++ src/types/uri.h | 3 src/types/vrp.h | 1 test/rrdp_test.c | 2 test/tal_test.c | 3 114 files changed, 1059 insertions(+), 546 deletions(-) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpa17x6bkq/fort-validator_1.6.6-1.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpa17x6bkq/fort-validator_1.6.8-0+deb13u1.dsc: no acceptable signature found diff -Nru fort-validator-1.6.6/configure.ac fort-validator-1.6.8/configure.ac --- fort-validator-1.6.6/configure.ac 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/configure.ac 2026-05-29 21:08:32.000000000 +0000 @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) -AC_INIT([fort],[1.6.6],[validadorfort@fortproject.net]) +AC_INIT([fort],[1.6.8],[validadorfort@fortproject.net]) AC_CONFIG_SRCDIR([src/main.c]) AM_INIT_AUTOMAKE([subdir-objects]) @@ -45,6 +45,7 @@ PKG_CHECK_MODULES([JANSSON], [jansson]) PKG_CHECK_MODULES([CURL], [libcurl]) PKG_CHECK_MODULES([XML2], [libxml-2.0]) +PKG_CHECK_MODULES([MICROHTTPD], [libmicrohttpd]) PKG_CHECK_MODULES([CHECK], [check], [usetests=yes], [usetests=no]) AM_CONDITIONAL([USE_TESTS], [test "x$usetests" = "xyes"]) diff -Nru fort-validator-1.6.6/debian/changelog fort-validator-1.6.8/debian/changelog --- fort-validator-1.6.6/debian/changelog 2025-02-13 22:17:39.000000000 +0000 +++ fort-validator-1.6.8/debian/changelog 2026-09-07 23:28:39.000000000 +0000 @@ -1,8 +1,27 @@ +fort-validator (1.6.8-0+deb13u1) trixie-security; urgency=medium + + * Rebuild for trixie-security. + + Fixes CVE-2026-53499. + + -- Marco d'Itri Tue, 08 Sep 2026 01:28:39 +0200 + +fort-validator (1.6.8-1) unstable; urgency=medium + + * New upstream release. + + -- Marco d'Itri Mon, 01 Jun 2026 20:44:17 +0200 + +fort-validator (1.6.7-1) unstable; urgency=medium + + * New upstream release. + + -- Marco d'Itri Sun, 21 Sep 2025 20:33:40 +0200 + fort-validator (1.6.6-1) unstable; urgency=medium * New upstream release. - -- Marco d'Itri Thu, 13 Feb 2025 23:17:39 +0100 + -- Marco d'Itri Thu, 13 Feb 2025 23:23:37 +0100 fort-validator (1.6.5-1) unstable; urgency=medium diff -Nru fort-validator-1.6.6/debian/control fort-validator-1.6.8/debian/control --- fort-validator-1.6.6/debian/control 2025-02-13 22:09:45.000000000 +0000 +++ fort-validator-1.6.8/debian/control 2026-08-07 16:19:44.000000000 +0000 @@ -1,18 +1,18 @@ Source: fort-validator Section: net -Priority: optional Maintainer: Marco d'Itri Build-Depends: debhelper-compat (= 13), + dh-sequence-cruft, dh-sequence-installsysusers, debhelper (>= 13.9), check, pkgconf, libcurl4-openssl-dev, libjansson-dev, + libmicrohttpd-dev, libssl-dev, libxml2-dev, rsync, -Standards-Version: 4.7.0.0 -Rules-Requires-Root: no +Standards-Version: 4.7.4.1 Homepage: https://nicmx.github.io/FORT-validator/ Vcs-Git: https://salsa.debian.org/md/fort-validator.git Vcs-Browser: https://salsa.debian.org/md/fort-validator diff -Nru fort-validator-1.6.6/debian/fort-validator.postrm fort-validator-1.6.8/debian/fort-validator.postrm --- fort-validator-1.6.6/debian/fort-validator.postrm 2025-02-13 22:09:45.000000000 +0000 +++ fort-validator-1.6.8/debian/fort-validator.postrm 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -#!/bin/sh -e - -clean_var() { - echo "Deleting the fort-validator repository..." - rm -rf /var/lib/fort/ -} - -case "$1" in - purge) - clean_var "$@" - ;; -esac - -#DEBHELPER# - diff -Nru fort-validator-1.6.6/debian/fort-validator.purge fort-validator-1.6.8/debian/fort-validator.purge --- fort-validator-1.6.6/debian/fort-validator.purge 1970-01-01 00:00:00.000000000 +0000 +++ fort-validator-1.6.8/debian/fort-validator.purge 2026-08-07 16:19:44.000000000 +0000 @@ -0,0 +1 @@ +/var/lib/fort/ diff -Nru fort-validator-1.6.6/debian/patches/documentation fort-validator-1.6.8/debian/patches/documentation --- fort-validator-1.6.6/debian/patches/documentation 2025-02-13 22:09:45.000000000 +0000 +++ fort-validator-1.6.8/debian/patches/documentation 2026-08-07 16:19:44.000000000 +0000 @@ -1,3 +1,7 @@ +From: Marco d'Itri +Subject: Document the default usage of CAP_NET_BIND_SERVICE +Forwarded: not-needed + --- a/man/fort.8 +++ b/man/fort.8 @@ -416,9 +416,9 @@ alias are commonly located at \fI/etc/se diff -Nru fort-validator-1.6.6/debian/patches/paths fort-validator-1.6.8/debian/patches/paths --- fort-validator-1.6.6/debian/patches/paths 2025-02-13 22:12:24.000000000 +0000 +++ fort-validator-1.6.8/debian/patches/paths 2026-09-07 23:23:51.000000000 +0000 @@ -1,3 +1,7 @@ +From: Marco d'Itri +Subject: Update the file paths for Debian +Forwarded: not-needed + --- a/man/fort.8 +++ b/man/fort.8 @@ -237,7 +237,7 @@ Fort's entire validation process operate @@ -9,7 +13,7 @@ .RE .P -@@ -1047,23 +1047,23 @@ Download the 5 RIR TALs into the /tmp/ta +@@ -1066,23 +1066,23 @@ Download the 5 RIR TALs into the /tmp/ta .RE .P @@ -37,7 +41,7 @@ .fi .RS 4 Run FORT as standalone and using a SLURM file. -@@ -1077,10 +1077,10 @@ Run FORT using the JSON configuration fi +@@ -1096,10 +1096,10 @@ Run FORT using the JSON configuration fi .P .nf @@ -50,7 +54,7 @@ .fi .RS 4 Run FORT with RTR server listening on IPv6 address \fI::1\fR, port 9323, -@@ -1094,10 +1094,10 @@ This is an example of a valid JSON confi +@@ -1113,10 +1113,10 @@ This is an example of a valid JSON confi to a specific value: .nf { @@ -64,16 +68,16 @@ "mode": "server", "work-offline": false, "daemon": false, -@@ -1162,7 +1162,7 @@ to a specific value: +@@ -1185,7 +1185,7 @@ to a specific value: "low-speed-limit": 100000, "low-speed-time": 10, "max-file-size": 2000000000, -- "ca-path": "/usr/local/ssl/certs" -+ "ca-path": "/etc/ssl/certs" +- "ca-path": "/usr/local/ssl/certs", ++ "ca-path": "/etc/ssl/certs", + "proxy": "https://example.com:1234" }, - "log": { -@@ -1208,8 +1208,8 @@ to a specific value: +@@ -1232,8 +1232,8 @@ to a specific value: ], "output": { @@ -86,7 +90,7 @@ --- a/src/config.c +++ b/src/config.c -@@ -937,8 +937,8 @@ set_default_values(void) +@@ -968,8 +968,8 @@ set_default_values(void) * duplicates. */ diff -Nru fort-validator-1.6.6/debian/salsa-ci.yml fort-validator-1.6.8/debian/salsa-ci.yml --- fort-validator-1.6.6/debian/salsa-ci.yml 1970-01-01 00:00:00.000000000 +0000 +++ fort-validator-1.6.8/debian/salsa-ci.yml 2026-08-07 16:19:44.000000000 +0000 @@ -0,0 +1,3 @@ +--- +include: + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml diff -Nru fort-validator-1.6.6/debian/watch fort-validator-1.6.8/debian/watch --- fort-validator-1.6.6/debian/watch 2025-02-13 22:09:45.000000000 +0000 +++ fort-validator-1.6.8/debian/watch 2026-08-07 16:19:44.000000000 +0000 @@ -1,3 +1,5 @@ -version=4 -opts=filenamemangle=s/.+\/v(\d\S+)\.tar\.gz/fort-validator-$1\.tar\.gz/ \ - https://github.com/NICMx/FORT-validator/tags .*/(\d+\.\S+)\.tar\.gz +Version: 5 + +Template: Github +Owner: NICMx +Project: FORT-validator diff -Nru fort-validator-1.6.6/docker/Dockerfile fort-validator-1.6.8/docker/Dockerfile --- fort-validator-1.6.6/docker/Dockerfile 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/docker/Dockerfile 2026-05-29 21:08:32.000000000 +0000 @@ -1,10 +1,10 @@ #--- Alpine build container --- FROM alpine:latest AS builder -ARG FORT_VERSION=1.6.6 +ARG FORT_VERSION=1.6.8 # Install compiler and dependencies RUN apk --update --no-cache add build-base autoconf automake pkgconfig jansson-dev check-dev \ - openssl-dev openssl bsd-compat-headers rsync wget curl-dev libxml2 libxml2-dev + openssl-dev openssl bsd-compat-headers rsync wget curl-dev libxml2 libxml2-dev libmicrohttpd-dev # Download FORT source code WORKDIR /root @@ -20,7 +20,7 @@ FROM alpine:latest # Install dependencies -RUN apk --update --no-cache add openssl jansson rsync tini libxml2 libcurl rtrlib +RUN apk --update --no-cache add openssl jansson rsync tini libxml2 libcurl rtrlib libmicrohttpd # Install FORT COPY --from=builder /usr/local/bin/fort /usr/local/bin/fort @@ -30,7 +30,7 @@ RUN mkdir -p /var/local/fort && mkdir -p /etc/fort/tal # Create default configuration -RUN yes yes | fort --init-tals --tal /etc/fort/tal +RUN fort --init-tals --tal /etc/fort/tal RUN echo '{ "tal":"/etc/fort/tal", "local-repository":"/var/local/fort" }' > /etc/fort/fort.conf diff -Nru fort-validator-1.6.6/docs/_config.yml fort-validator-1.6.8/docs/_config.yml --- fort-validator-1.6.6/docs/_config.yml 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/docs/_config.yml 2026-05-29 21:08:32.000000000 +0000 @@ -8,7 +8,7 @@ layout: "default" image: "/img/logo_validador_og.png" -fort-latest-version: 1.6.6 +fort-latest-version: 1.6.8 plugins: - jekyll-seo-tag - jekyll-sitemap diff -Nru fort-validator-1.6.6/docs/_layouts/default.html fort-validator-1.6.8/docs/_layouts/default.html --- fort-validator-1.6.6/docs/_layouts/default.html 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/docs/_layouts/default.html 2026-05-29 21:08:32.000000000 +0000 @@ -58,6 +58,7 @@
  • Compilation and Installation
  • Basic Usage
  • Program Arguments
  • +
  • Stats
  • Logging
  • SLURM
  • Incidences
  • diff -Nru fort-validator-1.6.6/docs/css/screen.css fort-validator-1.6.8/docs/css/screen.css --- fort-validator-1.6.6/docs/css/screen.css 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/docs/css/screen.css 2026-05-29 21:08:32.000000000 +0000 @@ -378,17 +378,21 @@ font-size: 90%; margin: 0; } -.language-bash > .c { - color: #3CB371; } +.language-bash .c { + color: #3CB371; +} -.language-bash > .nt { - color: #DDA0DD; } +.language-bash .nt { + color: #DDA0DD; +} -.language-bash > .s2 { - color: #00bfFF; } +.language-bash .s2 { + color: #00bfFF; +} -.language-bash > .nb { - color: white; } +.language-bash .nb { + color: white; +} .highlighter-rouge { border: solid 1px rgba(51, 137, 255, 0.2); diff -Nru fort-validator-1.6.6/docs/installation.md fort-validator-1.6.8/docs/installation.md --- fort-validator-1.6.6/docs/installation.md 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/docs/installation.md 2026-05-29 21:08:32.000000000 +0000 @@ -11,33 +11,24 @@ 2. [Option 1: Installing the package](#option-1-installing-the-package) 1. [Debian package](#debian-package) 2. [FreeBSD package](#freebsd-package) - 3. [Gentoo package](#gentoo-package) - 4. [RHEL/CentOS package](#rhelcentos-package) + 3. [RHEL package](#rhel-package) 3. [Option 2: Compiling and installing the release tarball](#option-2-compiling-and-installing-the-release-tarball) - 1. [Debian version](#debian-version) - 2. [OpenBSD version](#openbsd-version) - 3. [RHEL/CentOS version](#rhelcentos-version) - 4. [Fedora version](#fedora-version) - 5. [openSUSE Leap version](#opensuse-leap-version) - 6. [FreeBSD version](#freebsd-version) - 7. [Slackware version](#slackware-version) - 8. [Gentoo version](#gentoo-version) - 9. [Alpine version](#alpine-version) + 1. [Debian](#debian) + 2. [OpenBSD](#openbsd) + 3. [RHEL](#rhel) + 4. [FreeBSD](#freebsd) 4. [Option 3: Compiling and installing the git repository](#option-3-compiling-and-installing-the-git-repository) -5. [Option 4: Running from a Docker container](#option-4-running-from-a-docker-container) +5. [Option 4: Docker container](#option-4-docker-container) 6. [Fetching the TALs](#fetching-the-tals) ## Dependencies -> Note: This section is included in case you intend to install Fort in an unlisted OS (and therefore need a little research). For Debians, OpenBSD, RHEL/CentOS, Fedora, openSUSE Leap, FreeBSD, and Slackware just follow the steps in the sections below. - -The dependencies are - 1. [jansson](http://www.digip.org/jansson/) 2. libcrypto (Either [LibreSSL](http://www.libressl.org/) or [OpenSSL](https://www.openssl.org/) >= 1.1) 3. [rsync](http://rsync.samba.org/) 4. [libcurl](https://curl.haxx.se/libcurl/) 5. [libxml2](http://www.xmlsoft.org/) +6. [libmicrohttpd](https://www.gnu.org/software/libmicrohttpd/) Fort currently supports *64-bit* Operating Systems. A 32-bit OS may face the [Year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) when handling certificate dates, and there's no workaround for this at the moment. @@ -45,189 +36,98 @@ ### Debian package -Currently, there are 2 alternatives to install a debian package: -- [Latest version](#latest-version): this package is created as part of the latest release (currently {{ site.fort-latest-version }}) and is manually installed. -- [Debian repository version](#debian-repository-version): this package is at Debian repositories, so it can be fetched from there. - -#### Latest version +Last tested in Debian 12: -Just download the .deb package and install it. The fort service is automatically started once the installation is done. - -{% highlight bash %} +```bash wget https://github.com/NICMx/FORT-validator/releases/download/{{ site.fort-latest-version }}/fort_{{ site.fort-latest-version }}-1_amd64.deb sudo apt install ./fort_{{ site.fort-latest-version }}-1_amd64.deb -{% endhighlight %} - -> If a dependency can't be found at the repositories (i.e. libcurl4), try using a newer repository, such as Debian Buster. -> -> Add the following line to `/etc/apt/sources.list`, replacing the mirror (_http://ftp.mx.debian.org/debian_) with your [preferred one](https://www.debian.org/mirror/list): -> -> `deb http://ftp.mx.debian.org/debian buster main` - -This version ships with 4 of the 5 TALs, so in order to get the missing one, the [`--init-tals` argument](#--init-tals-argument) can be utilized using also the argument `--tal=/etc/fort/tal`: - -{% highlight bash %} -sudo fort --init-tals --tal=/etc/fort/tal -# Don't forget to restart fort service -sudo service fort restart -{% endhighlight %} - -Aside from the `fort` binary documented elsewhere in this documentation, the Debian package also ships with a systemd service, which is just the binary ran as a daemon. You can [configure](usage.html#--configuration-file) it at `/etc/fort/config.json`. - -{% highlight bash %} -sudo service fort start -service fort status -tail /var/log/syslog -sudo service fort stop -{% endhighlight %} - -Or, using systemctl: - -{% highlight bash %} -sudo systemctl start fort -systemctl status fort -sudo systemctl stop fort - -# In case you don't need to run fort on start -sudo systemctl disable fort -sudo systemctl enable fort -{% endhighlight %} - -#### Debian repository version - -Special thanks to [Marco d'Itri](https://github.com/rfc1036) for this collaboration. - -To know the current status of this package, visit [`fort-validator` debian package tracker](https://tracker.debian.org/pkg/fort-validator). - -The main differences between this version (fort-validator package) and the [Latest version](#latest-version) package are: -- [`rpki-trust-anchors`](https://tracker.debian.org/pkg/rpki-trust-anchors) dependency: this package has such dependency, while [Latest version](#latest-version) doesn't. -- Since this package isn't maintained by FORT validator's team, it could be at least one version behind than [Latest version](#latest-version). -- This version reads the TALs from `/etc/tals`, while [Latest version](#latest-version) reads them from `/etc/fort/tal`. - -Assuming that the package is still at the `testing` repository, such repository can be added to the APT sources list in order to do a simple `apt install`. - -First, check if the file `/etc/apt/apt.conf` exists, otherwise create it. The file should have the following line to keep using the stable repository as the default: +``` -{% highlight bash %} -APT::Default-Release "stable"; -{% endhighlight %} +The Debian package includes a systemd service that kicks off automatically after installation: -Now add the Debian `testing` repositories, add the following lines to `/etc/apt/sources.list`: +```bash +$ service fort status +● fort.service - FORT RPKI validator + Loaded: loaded (/lib/systemd/system/fort.service; enabled; preset: enabled) + Active: active (running) since Wed 2025-09-17 10:12:26 CDT; 1min 39s ago + Docs: man:fort(8) + https://nicmx.github.io/FORT-validator/ + Main PID: 690 (fort) + Tasks: 29 (limit: 1093) + Memory: 608.6M + CPU: 22.960s + CGroup: /system.slice/fort.service + ├─690 /usr/bin/fort --configuration-file /etc/fort/config.json + ├─741 rsync -rtz --delete --omit-dir-times --contimeout=20 --max-size=20MB --timeout=15 "--include=*/" "--include=*.cer" "--include=> + └─743 rsync -rtz --delete --omit-dir-times --contimeout=20 --max-size=20MB --timeout=15 "--include=*/" "--include=*.cer" "--include=> -{% highlight bash %} -deb http://deb.debian.org/debian/ testing main -deb-src http://deb.debian.org/debian/ testing main -{% endhighlight %} +Sep 17 10:12:26 debian12 systemd[1]: Started fort.service - FORT RPKI validator. +``` -Finally, just run: +You can [configure](usage.html#--configuration-file) it at `/etc/fort/config.json`. -{% highlight bash %} -sudo apt update -sudo apt -t testing install fort-validator -{% endhighlight %} +There's also a version [available in the official Debian repositories](https://tracker.debian.org/pkg/fort-validator), though it's not maintained by the Fort team. Fetch it like a normal package: -FORT validator is now installed as a service, check the status with `sudo service fort start`. +```bash +sudo apt install fort-validator +``` ### FreeBSD package FORT Validator is available in the FreeBSD ports tree since October 2021. The port maintainer closely follows the development of FORT. Updates to the FreeBSD port appear shortly after FORT releases. Binary packages can be installed in the usual way: -{% highlight bash %} +```bash pkg install fort -{% endhighlight %} +``` If you prefer to build software from ports, this works too: -{% highlight bash %} +```bash cd /usr/ports/net/fort make install clean -{% endhighlight %} +``` A default configuration will be installed in `/usr/local/etc/fort/fort-config.json`. The package is careful not to overwrite an existing configuration. To use FORT on FreeBSD, you will need the Trust Anchor Locator (TAL) files. You can download these by running `fort --init-tals` as follows: -{% highlight bash %} +```bash fort --init-tals --tal /usr/local/etc/fort/tal -{% endhighlight %} +``` When you have downloaded the TAL files, you can start the RTR server and validator with the included service script: -{% highlight bash %} +```bash sysrc fort_enable=YES # or edit /etc/rc.conf manually service fort start -{% endhighlight %} +``` The default configuration will bind the RTR server to localhost on port 8323. -### Gentoo package - -Thanks to [@alarig](https://github.com/alarig) for [his collaboration](https://github.com/NICMx/FORT-validator/issues/23) creating this package. +### RHEL package -> ![img/warn.svg](img/warn.svg) The package is currently at the [GURU repository](https://wiki.gentoo.org/wiki/Project:GURU), it could be at least one version behind the latest version, so please check first which version is the latest at the repository '[net-misc/FORT-validator](https://gitweb.gentoo.org/repo/proj/guru.git/tree/net-misc/FORT-validator)'. - -Layman will be utilized, so it must be installed in order to add the GURU repository: +Last tested in Rocky 8.9 and 9.3: ```bash -root# emerge --ask app-portage/layman -root# layman -a guru +curl -O https://github.com/NICMx/FORT-validator/releases/download/{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}-1.el8.x86_64.rpm +sudo dnf install fort-{{ site.fort-latest-version }}-1.el8.x86_64.rpm ``` -Now, allow to install the unstable FORT validator package (use according to your architecture). The following lines can be used for **amd64** arch: +The FORT validator service is not started by default: ```bash -root# nano /etc/portage/package.accept_keywords -## Add the following line and save -net-misc/FORT-validator ~amd64 -``` - -FORT validator can now be installed. Don't forget to update the TALs and restart the validator: - -```bash -root# emerge --ask net-misc/FORT-validator -root# su -s /bin/sh -c '/usr/bin/fort --init-tals --tal /usr/share/fort/tal/' fort" -root# rc-service fort restart -``` - -The configuration file utilized by the service can be found at `/etc/fort/config.json` (see more about [configuration file](usage.html#--configuration-file)). - -### RHEL/CentOS package - -> **RHEL/CentOS 7** users: the EPEL repository must be enabled to successfully install FORT validator. -> -> The following command will do: `sudo yum install epel-release` - -Download the .rpm and install it (currently tested at CentOS 7 and 8): - -{% highlight bash %} -wget https://github.com/NICMx/FORT-validator/releases/download/{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}-1.el8.x86_64.rpm -sudo yum install fort-{{ site.fort-latest-version }}-1.el8.x86_64.rpm -{% endhighlight %} - -This version ships with 4 of the 5 TALs, so in order to get the missing one, the [`--init-tals` argument](#--init-tals-argument) can be utilized using also the argument `--tal=/etc/fort/tal`: - -{% highlight bash %} -sudo fort --init-tals --tal=/etc/fort/tal -{% endhighlight %} - -By default, FORT validator service isn't initialized once it's installed; so, initialize the service: - -{% highlight bash %} sudo systemctl start fort -systemctl status fort - -# In case you want to stop it -sudo systemctl stop fort -{% endhighlight %} +``` -The configuration file utilized by the service can be found at `/etc/fort/config.json` (see more about [configuration file](usage.html#--configuration-file)). +Configuration at [`/etc/fort/config.json`](usage.html#--configuration-file). ## Option 2: Compiling and installing the release tarball -### Debian version +### Debian -{% highlight bash %} -sudo apt install autoconf automake build-essential libjansson-dev libssl-dev pkg-config rsync libcurl4-openssl-dev libxml2-dev +```bash +sudo apt install -y build-essential pkg-config rsync libjansson-dev \ + libssl-dev libcurl4-openssl-dev libxml2-dev libmicrohttpd-dev wget https://github.com/NICMx/FORT-validator/releases/download/{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}.tar.gz tar xvzf fort-{{ site.fort-latest-version }}.tar.gz @@ -235,114 +135,55 @@ ./configure make sudo make install -{% endhighlight %} +``` + +Last tested in Debian 12.12. -### OpenBSD version +### OpenBSD -{% highlight bash %} +```bash su -pkg_add curl jansson libexecinfo rsync libxml # OpenBSD already ships with LibreSSL +pkg_add curl jansson rsync libmicrohttpd libxml exit ftp https://github.com/NICMx/FORT-validator/releases/download/{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}.tar.gz tar xzf fort-{{ site.fort-latest-version }}.tar.gz cd fort-{{ site.fort-latest-version }}/ -# clang is needed because of gnu11. -env CC=clang CFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./configure +./configure make su make install exit -{% endhighlight %} - -Last tested on OpenBSD 7.2. - -### RHEL/CentOS version - -#### RHEL/CentOS 8 - -The following steps are for RHEL/CentOS 8. - -{% highlight bash %} -sudo dnf install autoconf automake gcc jansson-devel libcurl-devel libxml2-devel make openssl-devel pkgconfig rsync tar wget - -wget https://github.com/NICMx/FORT-validator/releases/download/{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}.tar.gz -tar xvzf fort-{{ site.fort-latest-version }}.tar.gz -cd fort-{{ site.fort-latest-version }}/ -./configure -make -sudo make install -{% endhighlight %} - -#### RHEL/CentOS 7 - -The following steps are for RHEL/CentOS 7. - -This OS requires additional steps due to its default GCC version (currently 4.8.5, fort needs >= 4.9) and its default OpenSSL version (currently 1.0.2k, fort needs >= 1.1.0). - -**Upgrade OpenSSL from 1.0.2k to 1.1.1c** - -There are two options to upgrade OpenSSL: -1. Compile and install a newer version >= 1.1.0 (manual process). -2. Use the [EPEL](https://fedoraproject.org/wiki/EPEL) repository (indicated at the following steps). - -**Upgrade GCC** +``` -There are two options to upgrade GCC: -1. Compile and install a newer version >= 4.9 (slow process). -2. Use [Software Collections](https://www.softwarecollections.org) (indicated at the following steps). +Last tested in OpenBSD 7.7. -{% highlight bash %} -sudo yum install centos-release-scl epel-release -sudo yum install autoconf automake devtoolset-8-gcc jansson-devel libcurl-devel libxml2-devel make openssl11-devel pkgconfig rsync tar wget -# Start a session using the upgraded GCC -scl enable devtoolset-8 bash -cd ~ -wget https://github.com/NICMx/FORT-validator/releases/download/{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}.tar.gz -tar xvzf fort-{{ site.fort-latest-version }}.tar.gz -cd fort-{{ site.fort-latest-version }}/ -# Insert paths from newer OpenSSL version -export CFLAGS+=" $(pkg-config --cflags openssl11)" LDFLAGS+=" $(pkg-config --libs openssl11)" -./configure -make -sudo make install -# Close the 'devtoolset' session -exit -{% endhighlight %} +### RHEL -### Fedora version +```bash +# Needed by crb enable. +sudo dnf install -y epel-release +# Needed by libmicrohttpd-devel. +# In rockylinux9, it's also needed by jansson-devel. +sudo crb enable -The following steps are for Fedora 30 (and later). +sudo dnf install -y gcc make pkgconfig rsync jansson-devel \ + openssl-devel libcurl-devel libxml2-devel libmicrohttpd-devel -{% highlight bash %} -sudo dnf install autoconf automake gcc jansson-devel libcurl-devel libxml2-devel make openssl-devel pkgconfig rsync tar wget wget https://github.com/NICMx/FORT-validator/releases/download/{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}.tar.gz -tar xvzf fort-{{ site.fort-latest-version }}.tar.gz +tar xzf fort-{{ site.fort-latest-version }}.tar.gz cd fort-{{ site.fort-latest-version }}/ ./configure make sudo make install -{% endhighlight %} - -### openSUSE Leap version - -The following steps are for openSUSE Leap 15.1. - -{% highlight bash %} -sudo zypper install autoconf automake gcc libopenssl-devel libjansson-devel libcurl-devel libxml2-devel +``` -wget https://github.com/NICMx/FORT-validator/releases/download/{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}.tar.gz -tar xvzf fort-{{ site.fort-latest-version }}.tar.gz -cd fort-{{ site.fort-latest-version }}/ -./configure -make -sudo make install -{% endhighlight %} +Last tested in rockylinux 8.9 and 9.3. -### FreeBSD version +### FreeBSD -{% highlight bash %} -sudo pkg install autotools curl jansson pkgconf rsync libxml2 +```bash +sudo pkg install autotools curl jansson pkgconf rsync libxml2 libmicrohttpd fetch https://github.com/NICMx/FORT-validator/releases/download/{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}.tar.gz tar xzf fort-{{ site.fort-latest-version }}.tar.gz cd fort-{{ site.fort-latest-version }}/ @@ -351,105 +192,46 @@ ./configure make sudo make install -{% endhighlight %} - -Last tested on FreeBSD 13.1. - -### Slackware version - -The following steps are for Slackware "current" release (as of 2020-07-13). - -All dependencies are included in the current release, so there's no need to install any dependency. - -{% highlight bash %} -wget https://github.com/NICMx/FORT-validator/releases/download/{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}.tar.gz -tar xvzf fort-{{ site.fort-latest-version }}.tar.gz -cd fort-{{ site.fort-latest-version }}/ -./configure -make -sudo make install -{% endhighlight %} - -### Gentoo version - -The following steps are for Gentoo "current" release (as of 2020-07-13). - -It's very likely that most of the dependencies are already installed (except `dev-libs/jansson`), still you can execute the following commands. - -{% highlight bash %} -su -emerge sys-devel/autoconf sys-devel/automake net-misc/rsync net-misc/curl dev-libs/jansson -exit - -wget https://github.com/NICMx/FORT-validator/releases/download/{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}.tar.gz -tar xvzf fort-{{ site.fort-latest-version }}.tar.gz -cd fort-{{ site.fort-latest-version }}/ -./configure -make -su -make install -exit -{% endhighlight %} - -### Alpine version - -The following steps are for Alpine Linux 3.12.0 - -{% highlight bash %} -su -apk add build-base autoconf automake pkgconfig openssl-dev jansson-dev curl-dev libxml2-dev bsd-compat-headers rsync -exit +``` -wget https://github.com/NICMx/FORT-validator/releases/download/{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}.tar.gz -tar xvzf fort-{{ site.fort-latest-version }}.tar.gz -cd fort-{{ site.fort-latest-version }}/ -./configure -make -su -make install -exit -{% endhighlight %} +Last tested in FreeBSD 14.3. ## Option 3: Compiling and installing the git repository -In case you wan't a fresh version of Fort validator, there's this third option. The steps are mostly the same as in [Option 2](#option-2-compiling-and-installing-the-release-tarball), just another dependency (as minimum) must be installed: "git"; and a few steps are included in order to get the source code and generate configuration scripts. +First, get the dependencies, and also `git` and the autotools. For Debian, this would be -The following example is the process to clone, compile and install in Debian OS. +```bash +# Git, autotools +sudo apt install -y autoconf automake build-essential git +# Fort dependencies +sudo apt install -y pkg-config rsync libjansson-dev libssl-dev \ + libcurl4-openssl-dev libxml2-dev libmicrohttpd-dev +``` -{% highlight bash %} -sudo apt install autoconf automake build-essential git libjansson-dev libssl-dev pkg-config rsync libcurl4-openssl-dev libxml2-dev +Then download, compile and install: +```bash git clone https://github.com/NICMx/FORT-validator.git cd FORT-validator/ ./autogen.sh ./configure make sudo make install -{% endhighlight %} - -## Option 4: Running from a Docker container +``` -There's also the option to run FORT validator from a Docker container. The image can be pulled from [Docker Hub](https://hub.docker.com/r/nicmx/fort-validator) or built from the official Github repository: [FORT-validator/docker](https://github.com/NICMx/FORT-validator/tree/main/docker). +## Option 4: Docker container -To pull the image from the official repository, run: +It's in [Docker Hub](https://hub.docker.com/r/nicmx/fort-validator). Pull with -{% highlight bash %} +```bash docker pull nicmx/fort-validator:latest -{% endhighlight %} - -Or to build from the source Dockerfile, just run (from the same directory where the Dockerfile is): - -{% highlight bash %} -docker build -t fort-validator:latest . -{% endhighlight %} +``` A basic example to run the container using the default values, reading from a local TAL directory (i.e. `host/path/to/tals`), and binding to the local port `8323`: -{% highlight bash %} +```bash docker run --name fort-validator -v host/path/to/tals:/etc/fort/tal:ro -p 8323:323 -d fort-validator -{% endhighlight %} - -Read more about the Docker container at the Github repository [FORT-validator/docker](https://github.com/NICMx/FORT-validator/tree/main/docker). +``` ## Fetching the TALs diff -Nru fort-validator-1.6.6/docs/intro-fort.md fort-validator-1.6.8/docs/intro-fort.md --- fort-validator-1.6.6/docs/intro-fort.md 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/docs/intro-fort.md 2026-05-29 21:08:32.000000000 +0000 @@ -20,13 +20,13 @@ | Issue | Title | Urgency | Due release | |-------|-------|---------|-------------| | [issue82](https://github.com/NICMx/FORT-validator/issues/82) | Reach 100% RFC 9286 compliance | Critical | 2.0.0 | -| [issue112](https://github.com/NICMx/FORT-validator/issues/112) | Enforce same origin for RRDP files | High | 2.0.0 | | [issue149](https://github.com/NICMx/FORT-validator/issues/149) | Lock the cache during updates | High | 2.0.0 | | [issue113](https://github.com/NICMx/FORT-validator/issues/113) | Detect and properly respond to subtler RRDP session desynchronization | Medium | 2.0.0 | | [issue124](https://github.com/NICMx/FORT-validator/issues/124) | Atomize output files (`--output.roa` and `--output.bgpsec`) | Medium | 2.0.0 | +| [issue129](https://github.com/NICMx/FORT-validator/issues/129) | Rethink the thread pools | Medium | 2.0.0 | | [issue114](https://github.com/NICMx/FORT-validator/issues/114) | Support automatic TA key rollover | Very High | 2.0.1 | -| [issue50](https://github.com/NICMx/FORT-validator/issues/50) | Provide prometheus endpoint | Very High | 2.0.2 | -| [issue58](https://github.com/NICMx/FORT-validator/issues/58) | Fort's validation produces no router keys | Very High | 2.0.3 | +| [issue58](https://github.com/NICMx/FORT-validator/issues/58) | Fort's validation produces no router keys | Very High | 2.0.2 | +| [issue132](https://github.com/NICMx/FORT-validator/issues/132) | Implement RTRv2 | Very High | - | | [issue116](https://github.com/NICMx/FORT-validator/issues/116) | SLURM review | High | - | | [issue118](https://github.com/NICMx/FORT-validator/issues/118) | Implement validation re-reconsidered | High | - | | [issue119](https://github.com/NICMx/FORT-validator/issues/119) | Review IRIs to file names transition | High | - | @@ -42,7 +42,6 @@ | [issue126](https://github.com/NICMx/FORT-validator/issues/126) | Exhaustive URL validation | Medium | - | | [issue127](https://github.com/NICMx/FORT-validator/issues/127) | Stream RRDP files | Medium | - | | [issue128](https://github.com/NICMx/FORT-validator/issues/128) | Reuse TCP connections for HTTP requests to same server | Medium | - | -| [issue129](https://github.com/NICMx/FORT-validator/issues/129) | Rethink the thread pools | Medium | - | | [issue130](https://github.com/NICMx/FORT-validator/issues/130) | Improve documentation | Medium | - | | [issue151](https://github.com/NICMx/FORT-validator/issues/151) | [Enhancement]: Add ability to set ACLs for router connections | Medium | - | | [issue152](https://github.com/NICMx/FORT-validator/issues/152) | compliance issue: Fort accepts GeneralizedTime with fractional seconds | Medium | - | @@ -52,5 +51,4 @@ | [issue70](https://github.com/NICMx/FORT-validator/issues/70) | Do a quick temporary offline validation to prevent `No Data Available` | Low | - | | [issue123](https://github.com/NICMx/FORT-validator/issues/123) | New invocation mode: Validate single file | Low | - | | [issue131](https://github.com/NICMx/FORT-validator/issues/131) | Implement vCard validation | Low | - | -| [issue132](https://github.com/NICMx/FORT-validator/issues/132) | Implement RTRv2 | Low | - | | [issue134](https://github.com/NICMx/FORT-validator/issues/134) | Add support RFC 9589 (On the Use of the CMS Signing-Time Attribute in RPKI Signed Objects) | Low | - | diff -Nru fort-validator-1.6.6/docs/stats.md fort-validator-1.6.8/docs/stats.md --- fort-validator-1.6.6/docs/stats.md 1970-01-01 00:00:00.000000000 +0000 +++ fort-validator-1.6.8/docs/stats.md 2026-05-29 21:08:32.000000000 +0000 @@ -0,0 +1,42 @@ +--- +title: Stats +--- + +# {{ page.title }} + +Enable the Prometheus server with [`--prometheus.port`](usage.html#--prometheusport) and [`--mode=server`](usage.html#--mode): + +```bash +$ fort --mode=server --prometheus.port=8000 /path/to/tal +$ curl localhost:8000/metrics +fort_rtr_ready 1 1757646873 +fort_rtr_current_connections 0 1757646873 +fort_valid_vrps_total{ta="test",proto="ipv4"} 44 1757646873 +fort_valid_vrps_total{ta="test",proto="ipv6"} 66 1757646873 +# EOF +``` + +The implementation is still very fresh, and prioritizes minimal monitoring over exhaustive reporting. Therefore, there are not many stats yet. Please request your preferred values via the [issue tracker](https://github.com/NICMx/FORT-validator/issues). + +## `fort_rtr_ready` + +- Type: Gauge (effectively boolean) + +Starts as 0, becomes 1 when the validator has a complete VRP table to serve via RTR. + +## `fort_rtr_current_connections` + +- Type: Gauge + +Number of presently open connections with RTR clients. + +## `fort_valid_vrps_total{ta="",proto=""}` + +- Type: Gauge + +Total number of VRPs generated from TA `` and protocol `` during the previous validation cycle. + +Labels: + +- `` is the TAL's file name, minus extension. (The `` of "`/etc/fort/tal/ripe-ncc.tal`" would be `ripe-ncc`.) +- `IP` is either `ipv4` or `ipv6`. diff -Nru fort-validator-1.6.6/docs/usage.md fort-validator-1.6.8/docs/usage.md --- fort-validator-1.6.6/docs/usage.md 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/docs/usage.md 2026-05-29 21:08:32.000000000 +0000 @@ -29,6 +29,7 @@ 17. [`--server.interval.retry`](#--serverintervalretry) 18. [`--server.interval.expire`](#--serverintervalexpire) 18. [`--server.deltas.lifetime`](#--serverdeltaslifetime) + 18. [`--prometheus.port`](#--prometheusport) 19. [`--slurm`](#--slurm) 20. [`--log.enabled`](#--logenabled) 21. [`--log.level`](#--loglevel) @@ -56,6 +57,7 @@ 41. [`--http.low-speed-time`](#--httplow-speed-time) 41. [`--http.max-file-size`](#--httpmax-file-size) 42. [`--http.ca-path`](#--httpca-path) + 42. [`--http.proxy`](#--httpproxy) 43. [`--output.roa`](#--outputroa) 44. [`--output.bgpsec`](#--outputbgpsec) 45. [`--output.format`](#--outputformat) @@ -93,13 +95,14 @@ [--work-offline=true|false] [--daemon=true|false] [--server.address=] - [--server.port=] + [--server.port=] [--server.backlog=] [--server.interval.validation=] [--server.interval.refresh=] [--server.interval.retry=] [--server.interval.expire=] [--server.deltas.lifetime=] + [--prometheus.port=] [--rsync.enabled=true|false] [--rsync.priority=] [--rsync.retry.count=] @@ -117,6 +120,7 @@ [--http.low-speed-time=] [--http.max-file-size=] [--http.ca-path=] + [--http.proxy=] [--log.enabled=true|false] [--log.output=syslog|console] [--log.level=error|warning|info|debug] @@ -373,13 +377,13 @@ ### `--server.port` -- **Type:** String +- **Type:** String or integer - **Availability:** `argv` and JSON -- **Default:** `"323"` +- **Default:** `323` TCP port or service the server address(es) will be bound to, if [`--server.address`](#--serveraddress) doesn't override it. -This is a string because a service alias can be used as a valid value. The available aliases are commonly located at `/etc/services`. (See '`$ man 5 services`'.) +This can be a string because it's not necessarily a port; it's technically a service alias. (For example, if you enter "`http`," it will be resolved to 80). The available aliases are commonly located at `/etc/services`. (See '`$ man 5 services`'.) > ![img/warn.svg](img/warn.svg) The default port is privileged. To improve security, either change or jail it. See [Non root port binding](run.html#non-root-port-binding). @@ -461,6 +465,21 @@ If a router lags behind, to the point Fort has already deleted the deltas it needs to update the router's snapshot, Fort will have to fall back to fetch the entire latest snapshot instead. +### `--prometheus.port` + +- **Type:** Integer +- **Availability:** `argv` and JSON +- **Default:** `NULL` +- **Range:** [1, 65535] + +TCP port the Prometheus server will be bound to. + +The Prometheus server requires `--prometheus.port` to be defined, and [`--mode`](#--mode) to be `server`. Otherwise it will not start. + +Stats are served in openmetrics format. See [stats](stats.html). + +Unlike [`--server.port`](#--serverport), `--prometheus.port` is strictly a number. (It will not be resolved.) + ### `--slurm` - **Type:** String (path to file or directory) @@ -792,6 +811,26 @@ The value specified is utilized in libcurl's option [CURLOPT_CAPATH](https://curl.haxx.se/libcurl/c/CURLOPT_CAPATH.html). +### `--http.proxy` + +- **Type:** String (HTTPS URL) +- **Availability:** `argv` and JSON +- **Default:** `NULL` (disabled) + +Set a proxy to use for HTTP transfers. + +It can be a hostname, a dotted numerical IPv4 address or a numerical IPv6 address enclosed in brackets. The port defaults to 1080; append `:` to override. + +Alternatively, invoke the usual environment variable (EV): + +``` +https_proxy=https://example.com:1234 fort --tal=/path/to/tal +``` + +`--http.proxy` takes precedence over the `https_proxy` EV, which in turn takes precedence over the `HTTPS_PROXY` EV. + +> There's no `--rsync.proxy` counterpart. For rsync connections, use the `RSYNC_PROXY` EV as usual. + ### `--output.roa` - **Type:** String (Path to file) @@ -964,17 +1003,14 @@ "tal": "/tmp/fort/tal/", "local-repository": "/tmp/fort/repository", "maximum-certificate-depth": 32, - "slurm": "/tmp/fort/test.slurm", + "slurm": null, "mode": "server", "work-offline": false, "daemon": false, "server": { - "address": [ - "192.0.2.1", - "2001:db8::1" - ], - "port": "8323", + "address": [ "::" ], + "port": 323, "backlog": 4096, "interval": { "validation": 3600, @@ -987,6 +1023,10 @@ } }, + "prometheus": { + "port": 0 + }, + "rsync": { "enabled": true, "priority": 50, @@ -1029,14 +1069,15 @@ "low-speed-limit": 100000, "low-speed-time": 10, "max-file-size": 2000000000, - "ca-path": "/usr/local/ssl/certs" + "ca-path": null, + "proxy": null }, "log": { "enabled": true, "output": "console", "level": "warning", - "tag": "Op", + "tag": null, "facility": "daemon", "file-name-format": "global-url", "color-output": false @@ -1075,8 +1116,8 @@ ], "output": { - "roa": "/tmp/fort/roas.csv", - "bgpsec": "/tmp/fort/bgpsec.csv", + "roa": null, + "bgpsec": null, "format": "csv" }, diff -Nru fort-validator-1.6.6/man/fort.8 fort-validator-1.6.8/man/fort.8 --- fort-validator-1.6.6/man/fort.8 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/man/fort.8 2026-05-29 21:08:32.000000000 +0000 @@ -1,4 +1,4 @@ -.TH fort 8 "2025-02-05" "v1.6.6" "FORT validator" +.TH fort 8 "2026-05-29" "v1.6.8" "FORT validator" .SH NAME fort \- RPKI validator and RTR server @@ -452,6 +452,16 @@ .RE .P +.B \-\-prometheus.port=\fIUNSIGNED_INTEGER\fR +.RS 4 +TCP port the Prometheus server will be bound to. +.P +The Prometheus server requires \fI--prometheus.port\fR to be defined, and \fI--mode\fR to be \fIserver\fR. Otherwise it will not start. +.P +Stats are served in openmetrics format. +.RE +.P + .B \-\-log.enabled=\fItrue\fR|\fIfalse\fR .RS 4 Enables the operation logs. @@ -854,6 +864,15 @@ .RE .P +.B \-\-http.proxy=\fIURL\fR +.RS 4 +.P +Set a proxy to use for HTTP transfers. +.P +It can be a hostname, a dotted numerical IPv4 address or a numerical IPv6 address enclosed in brackets. The port defaults to 1080; append \fI:\fR to override. +.RE +.P + .B \-\-rsync.enabled=\fItrue\fR|\fIfalse\fR .RS 4 Enables RSYNC requests. @@ -1107,7 +1126,7 @@ "192.0.2.1", "2001:db8::1" ], - "port": "8323", + "port": 8323, "backlog": 4096, "interval": { "validation": 3600, @@ -1120,6 +1139,10 @@ } }, + "prometheus": { + "port": 0 + }, + "rsync": { "enabled": true, "priority": 50, @@ -1155,14 +1178,15 @@ "count": 1, "interval": 4 }, - "user-agent": "fort/1.6.4", + "user-agent": "fort/1.6.7", "max-redirs": 10, "connect-timeout": 30, "transfer-timeout": 900, "low-speed-limit": 100000, "low-speed-time": 10, "max-file-size": 2000000000, - "ca-path": "/usr/local/ssl/certs" + "ca-path": "/usr/local/ssl/certs", + "proxy": "https://example.com:1234" }, "log": { @@ -1294,7 +1318,7 @@ .P .\".SH COPYRIGHT -.\" FORT-validator 2025 +.\" FORT-validator 2026 .\" MIT License .SH SEE ALSO diff -Nru fort-validator-1.6.6/src/Makefile.am fort-validator-1.6.8/src/Makefile.am --- fort-validator-1.6.6/src/Makefile.am 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/Makefile.am 2026-05-29 21:08:32.000000000 +0000 @@ -24,11 +24,13 @@ fort_SOURCES += nid.h nid.c fort_SOURCES += output_printer.h output_printer.c fort_SOURCES += print_file.h print_file.c +fort_SOURCES += prometheus.h prometheus.c fort_SOURCES += resource.h resource.c fort_SOURCES += rpp.h rpp.c fort_SOURCES += rrdp.h rrdp.c fort_SOURCES += sorted_array.h sorted_array.c fort_SOURCES += state.h state.c +fort_SOURCES += stats.h stats.c fort_SOURCES += str_token.h str_token.c fort_SOURCES += thread_var.h thread_var.c fort_SOURCES += json_handler.h json_handler.c @@ -124,7 +126,7 @@ fort_CFLAGS += -DBACKTRACE_ENABLED endif fort_LDFLAGS = $(LDFLAGS_DEBUG) -fort_LDADD = ${JANSSON_LIBS} ${CURL_LIBS} ${XML2_LIBS} +fort_LDADD = ${JANSSON_LIBS} ${CURL_LIBS} ${XML2_LIBS} ${MICROHTTPD_LIBS} # I'm tired of scrolling up, but feel free to comment this out. GCC_WARNS = -fmax-errors=1 diff -Nru fort-validator-1.6.6/src/algorithm.c fort-validator-1.6.8/src/algorithm.c --- fort-validator-1.6.6/src/algorithm.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/algorithm.c 2026-05-29 21:08:32.000000000 +0000 @@ -3,6 +3,7 @@ #include #include #include +#include #include "log.h" diff -Nru fort-validator-1.6.6/src/alloc.c fort-validator-1.6.8/src/alloc.c --- fort-validator-1.6.6/src/alloc.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/alloc.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,5 +1,8 @@ #include "alloc.h" +#include +#include + #include "log.h" void * diff -Nru fort-validator-1.6.6/src/alloc.h fort-validator-1.6.8/src/alloc.h --- fort-validator-1.6.6/src/alloc.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/alloc.h 2026-05-29 21:08:32.000000000 +0000 @@ -2,12 +2,6 @@ #define SRC_ALLOC_H_ #include -#include -#include -#include -#include -#include -#include /* malloc(), but panic on allocation failure. */ void *pmalloc(size_t size); diff -Nru fort-validator-1.6.6/src/as_number.h fort-validator-1.6.8/src/as_number.h --- fort-validator-1.6.6/src/as_number.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/as_number.h 2026-05-29 21:08:32.000000000 +0000 @@ -1,9 +1,6 @@ #ifndef SRC_AS_NUMBER_H_ #define SRC_AS_NUMBER_H_ -#include -#include -#include #include struct asn_range { diff -Nru fort-validator-1.6.6/src/asn1/asn1c/ANY.c fort-validator-1.6.8/src/asn1/asn1c/ANY.c --- fort-validator-1.6.6/src/asn1/asn1c/ANY.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/ANY.c 2026-05-29 21:08:32.000000000 +0000 @@ -6,6 +6,7 @@ #include #include +#include #include "asn1/asn1c/asn_internal.h" #include "asn1/asn1c/ber_decoder.h" diff -Nru fort-validator-1.6.6/src/asn1/asn1c/BIT_STRING.c fort-validator-1.6.8/src/asn1/asn1c/BIT_STRING.c --- fort-validator-1.6.6/src/asn1/asn1c/BIT_STRING.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/BIT_STRING.c 2026-05-29 21:08:32.000000000 +0000 @@ -6,6 +6,7 @@ #include "asn1/asn1c/BIT_STRING.h" #include +#include #include "asn1/asn1c/asn_internal.h" #include "asn1/asn1c/xer_encoder.h" diff -Nru fort-validator-1.6.6/src/asn1/asn1c/BOOLEAN.c fort-validator-1.6.8/src/asn1/asn1c/BOOLEAN.c --- fort-validator-1.6.6/src/asn1/asn1c/BOOLEAN.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/BOOLEAN.c 2026-05-29 21:08:32.000000000 +0000 @@ -4,6 +4,8 @@ */ #include "asn1/asn1c/BOOLEAN.h" +#include + #include "asn1/asn1c/asn_internal.h" #include "asn1/asn1c/ber_decoder.h" #include "asn1/asn1c/der_encoder.h" diff -Nru fort-validator-1.6.6/src/asn1/asn1c/GeneralizedTime.c fort-validator-1.6.8/src/asn1/asn1c/GeneralizedTime.c --- fort-validator-1.6.6/src/asn1/asn1c/GeneralizedTime.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/GeneralizedTime.c 2026-05-29 21:08:32.000000000 +0000 @@ -10,6 +10,7 @@ #include #include +#include #include "asn1/asn1c/asn_internal.h" #include "asn1/asn1c/xer_encoder.h" diff -Nru fort-validator-1.6.6/src/asn1/asn1c/INTEGER.c fort-validator-1.6.8/src/asn1/asn1c/INTEGER.c --- fort-validator-1.6.6/src/asn1/asn1c/INTEGER.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/INTEGER.c 2026-05-29 21:08:32.000000000 +0000 @@ -7,6 +7,7 @@ #include #include +#include #include "asn1/asn1c/asn_internal.h" #include "json_util.h" diff -Nru fort-validator-1.6.6/src/asn1/asn1c/NULL.c fort-validator-1.6.8/src/asn1/asn1c/NULL.c --- fort-validator-1.6.6/src/asn1/asn1c/NULL.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/NULL.c 2026-05-29 21:08:32.000000000 +0000 @@ -4,6 +4,8 @@ */ #include "asn1/asn1c/NULL.h" +#include + #include "asn1/asn1c/asn_internal.h" #include "asn1/asn1c/ber_decoder.h" #include "asn1/asn1c/der_encoder.h" diff -Nru fort-validator-1.6.6/src/asn1/asn1c/OBJECT_IDENTIFIER.c fort-validator-1.6.8/src/asn1/asn1c/OBJECT_IDENTIFIER.c --- fort-validator-1.6.6/src/asn1/asn1c/OBJECT_IDENTIFIER.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/OBJECT_IDENTIFIER.c 2026-05-29 21:08:32.000000000 +0000 @@ -10,6 +10,7 @@ #include #include #include +#include #include "asn1/asn1c/INTEGER.h" #include "asn1/asn1c/asn_internal.h" diff -Nru fort-validator-1.6.6/src/asn1/asn1c/OBJECT_IDENTIFIER.h fort-validator-1.6.8/src/asn1/asn1c/OBJECT_IDENTIFIER.h --- fort-validator-1.6.6/src/asn1/asn1c/OBJECT_IDENTIFIER.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/OBJECT_IDENTIFIER.h 2026-05-29 21:08:32.000000000 +0000 @@ -5,8 +5,6 @@ #ifndef _OBJECT_IDENTIFIER_H_ #define _OBJECT_IDENTIFIER_H_ -#include - #include "asn1/asn1c/OCTET_STRING.h" #include "asn1/asn1c/asn_codecs_prim.h" diff -Nru fort-validator-1.6.6/src/asn1/asn1c/OCTET_STRING.c fort-validator-1.6.8/src/asn1/asn1c/OCTET_STRING.c --- fort-validator-1.6.6/src/asn1/asn1c/OCTET_STRING.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/OCTET_STRING.c 2026-05-29 21:08:32.000000000 +0000 @@ -7,6 +7,7 @@ #include #include +#include #include "alloc.h" #include "asn1/asn1c/BIT_STRING.h" diff -Nru fort-validator-1.6.6/src/asn1/asn1c/OPEN_TYPE.c fort-validator-1.6.8/src/asn1/asn1c/OPEN_TYPE.c --- fort-validator-1.6.6/src/asn1/asn1c/OPEN_TYPE.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/OPEN_TYPE.c 2026-05-29 21:08:32.000000000 +0000 @@ -4,6 +4,8 @@ */ #include "asn1/asn1c/OPEN_TYPE.h" +#include + #include "asn1/asn1c/asn_internal.h" asn_TYPE_operation_t asn_OP_OPEN_TYPE = { diff -Nru fort-validator-1.6.6/src/asn1/asn1c/UTCTime.c fort-validator-1.6.8/src/asn1/asn1c/UTCTime.c --- fort-validator-1.6.6/src/asn1/asn1c/UTCTime.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/UTCTime.c 2026-05-29 21:08:32.000000000 +0000 @@ -7,6 +7,7 @@ #include #include +#include #include "asn1/asn1c/GeneralizedTime.h" #include "asn1/asn1c/asn_internal.h" diff -Nru fort-validator-1.6.6/src/asn1/asn1c/asn_codecs.h fort-validator-1.6.8/src/asn1/asn1c/asn_codecs.h --- fort-validator-1.6.6/src/asn1/asn1c/asn_codecs.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/asn_codecs.h 2026-05-29 21:08:32.000000000 +0000 @@ -6,10 +6,6 @@ #define ASN_CODECS_H #include -#include -#include -#include -#include #include #include diff -Nru fort-validator-1.6.6/src/asn1/asn1c/asn_codecs_prim.c fort-validator-1.6.8/src/asn1/asn1c/asn_codecs_prim.c --- fort-validator-1.6.6/src/asn1/asn1c/asn_codecs_prim.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/asn_codecs_prim.c 2026-05-29 21:08:32.000000000 +0000 @@ -5,6 +5,7 @@ #include "asn1/asn1c/asn_codecs_prim.h" #include +#include #include "asn1/asn1c/asn_internal.h" #include "asn1/asn1c/ber_decoder.h" diff -Nru fort-validator-1.6.6/src/asn1/asn1c/asn_internal.h fort-validator-1.6.8/src/asn1/asn1c/asn_internal.h --- fort-validator-1.6.6/src/asn1/asn1c/asn_internal.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/asn_internal.h 2026-05-29 21:08:32.000000000 +0000 @@ -10,6 +10,8 @@ #ifndef __EXTENSIONS__ #define __EXTENSIONS__ /* for Sun */ #endif +#include + #include "asn1/asn1c/asn_codecs.h" #include "asn1/asn1c/asn_system.h" diff -Nru fort-validator-1.6.6/src/asn1/asn1c/asn_system.h fort-validator-1.6.8/src/asn1/asn1c/asn_system.h --- fort-validator-1.6.6/src/asn1/asn1c/asn_system.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/asn_system.h 2026-05-29 21:08:32.000000000 +0000 @@ -14,9 +14,6 @@ #include #include #include -#include -#include -#include #include #include diff -Nru fort-validator-1.6.6/src/asn1/asn1c/ber_tlv_tag.h fort-validator-1.6.8/src/asn1/asn1c/ber_tlv_tag.h --- fort-validator-1.6.6/src/asn1/asn1c/ber_tlv_tag.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/ber_tlv_tag.h 2026-05-29 21:08:32.000000000 +0000 @@ -5,13 +5,9 @@ #ifndef _BER_TLV_TAG_H_ #define _BER_TLV_TAG_H_ -#include #include #include #include -#include -#include -#include #include #include diff -Nru fort-validator-1.6.6/src/asn1/asn1c/constr_CHOICE.c fort-validator-1.6.8/src/asn1/asn1c/constr_CHOICE.c --- fort-validator-1.6.6/src/asn1/asn1c/constr_CHOICE.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/constr_CHOICE.c 2026-05-29 21:08:32.000000000 +0000 @@ -5,6 +5,7 @@ #include "asn1/asn1c/constr_CHOICE.h" #include +#include #include "asn1/asn1c/asn_internal.h" #include "asn1/asn1c/ber_decoder.h" diff -Nru fort-validator-1.6.6/src/asn1/asn1c/constr_SEQUENCE.c fort-validator-1.6.8/src/asn1/asn1c/constr_SEQUENCE.c --- fort-validator-1.6.6/src/asn1/asn1c/constr_SEQUENCE.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/constr_SEQUENCE.c 2026-05-29 21:08:32.000000000 +0000 @@ -7,6 +7,7 @@ #include "asn1/asn1c/constr_SEQUENCE.h" #include +#include #include "asn1/asn1c/OPEN_TYPE.h" #include "asn1/asn1c/asn_internal.h" diff -Nru fort-validator-1.6.6/src/asn1/asn1c/constr_SEQUENCE_OF.c fort-validator-1.6.8/src/asn1/asn1c/constr_SEQUENCE_OF.c --- fort-validator-1.6.6/src/asn1/asn1c/constr_SEQUENCE_OF.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/constr_SEQUENCE_OF.c 2026-05-29 21:08:32.000000000 +0000 @@ -5,6 +5,8 @@ */ #include "asn1/asn1c/constr_SEQUENCE_OF.h" +#include + #include "asn1/asn1c/asn_SEQUENCE_OF.h" #include "asn1/asn1c/asn_internal.h" #include "asn1/asn1c/der_encoder.h" diff -Nru fort-validator-1.6.6/src/asn1/asn1c/constr_SET_OF.c fort-validator-1.6.8/src/asn1/asn1c/constr_SET_OF.c --- fort-validator-1.6.6/src/asn1/asn1c/constr_SET_OF.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/constr_SET_OF.c 2026-05-29 21:08:32.000000000 +0000 @@ -7,6 +7,7 @@ #include "asn1/asn1c/constr_SET_OF.h" #include +#include #include "asn1/asn1c/asn_SET_OF.h" #include "asn1/asn1c/asn_internal.h" diff -Nru fort-validator-1.6.6/src/asn1/asn1c/constraints.c fort-validator-1.6.8/src/asn1/asn1c/constraints.c --- fort-validator-1.6.6/src/asn1/asn1c/constraints.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/constraints.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,7 @@ #include "asn1/asn1c/constraints.h" #include +#include int asn_generic_no_constraint(const asn_TYPE_descriptor_t *type_descriptor, diff -Nru fort-validator-1.6.6/src/asn1/asn1c/der_encoder.c fort-validator-1.6.8/src/asn1/asn1c/der_encoder.c --- fort-validator-1.6.6/src/asn1/asn1c/der_encoder.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/der_encoder.c 2026-05-29 21:08:32.000000000 +0000 @@ -5,6 +5,7 @@ #include "asn1/asn1c/der_encoder.h" #include +#include #include "asn1/asn1c/asn_internal.h" diff -Nru fort-validator-1.6.6/src/asn1/asn1c/xer_encoder.c fort-validator-1.6.8/src/asn1/asn1c/xer_encoder.c --- fort-validator-1.6.6/src/asn1/asn1c/xer_encoder.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/asn1c/xer_encoder.c 2026-05-29 21:08:32.000000000 +0000 @@ -4,6 +4,8 @@ */ #include "asn1/asn1c/xer_encoder.h" +#include + #include "asn1/asn1c/asn_internal.h" /* diff -Nru fort-validator-1.6.6/src/asn1/oid.c fort-validator-1.6.8/src/asn1/oid.c --- fort-validator-1.6.6/src/asn1/oid.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/asn1/oid.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,8 @@ #include "asn1/oid.h" #include +#include +#include #include "alloc.h" #include "log.h" diff -Nru fort-validator-1.6.6/src/common.c fort-validator-1.6.8/src/common.c --- fort-validator-1.6.6/src/common.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/common.c 2026-05-29 21:08:32.000000000 +0000 @@ -3,7 +3,9 @@ #include #include #include +#include #include +#include #include "alloc.h" #include "config.h" diff -Nru fort-validator-1.6.6/src/config/boolean.c fort-validator-1.6.8/src/config/boolean.c --- fort-validator-1.6.6/src/config/boolean.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/config/boolean.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,7 @@ #include "config/boolean.h" #include +#include #include "log.h" diff -Nru fort-validator-1.6.6/src/config/curl_offset.c fort-validator-1.6.8/src/config/curl_offset.c --- fort-validator-1.6.6/src/config/curl_offset.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/config/curl_offset.c 2026-05-29 21:08:32.000000000 +0000 @@ -3,6 +3,7 @@ #include #include #include +#include #include "log.h" diff -Nru fort-validator-1.6.6/src/config/file_type.c fort-validator-1.6.8/src/config/file_type.c --- fort-validator-1.6.6/src/config/file_type.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/config/file_type.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,7 @@ #include "config/file_type.h" #include +#include #include "config/str.h" #include "log.h" diff -Nru fort-validator-1.6.6/src/config/filename_format.c fort-validator-1.6.8/src/config/filename_format.c --- fort-validator-1.6.6/src/config/filename_format.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/config/filename_format.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,7 @@ #include "config/filename_format.h" #include +#include #include "config/str.h" #include "log.h" diff -Nru fort-validator-1.6.6/src/config/log_conf.c fort-validator-1.6.8/src/config/log_conf.c --- fort-validator-1.6.6/src/config/log_conf.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/config/log_conf.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,10 +1,8 @@ #include "config/log_conf.h" -#include #include -#include -#include #include +#include #include #include "config/str.h" diff -Nru fort-validator-1.6.6/src/config/mode.c fort-validator-1.6.8/src/config/mode.c --- fort-validator-1.6.6/src/config/mode.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/config/mode.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,7 @@ #include "config/mode.h" #include +#include #include "config/str.h" #include "log.h" diff -Nru fort-validator-1.6.6/src/config/output_format.c fort-validator-1.6.8/src/config/output_format.c --- fort-validator-1.6.6/src/config/output_format.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/config/output_format.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,7 @@ #include "config/output_format.h" #include +#include #include "config/str.h" #include "log.h" diff -Nru fort-validator-1.6.6/src/config/str.c fort-validator-1.6.8/src/config/str.c --- fort-validator-1.6.6/src/config/str.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/config/str.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,7 @@ #include "config/str.h" #include +#include #include "alloc.h" #include "log.h" @@ -80,6 +81,43 @@ .arg_doc = "", }; +static int +service_parse_json(struct option_field const *opt, json_t *json, void *result) +{ + json_int_t intval; + char *strval; + int written; + + if (json_is_integer(json)) { + intval = json_integer_value(json); + if (intval < 1 || 65535 < intval) { + return pr_op_err("'%s' is out of range (1-65535).", + opt->name); + } + + strval = pmalloc(6); + written = snprintf(strval, 6, "%" JSON_INTEGER_FORMAT, intval); + if (written < 0 || 6 <= written) + return pr_op_err("Cannot convert '%s' to string: snprintf returned %d", + opt->name, written); + + DEREFERENCE(result) = strval; + return 0; + } + + return string_parse_json(opt, json, result); +} + +const struct global_type gt_service = { + .has_arg = required_argument, + .size = sizeof(char *), + .print = string_print, + .parse.argv = string_parse_argv, + .parse.json = service_parse_json, + .free = string_free, + .arg_doc = "", +}; + /** * *result must not be freed nor long-term stored. */ diff -Nru fort-validator-1.6.6/src/config/str.h fort-validator-1.6.8/src/config/str.h --- fort-validator-1.6.6/src/config/str.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/config/str.h 2026-05-29 21:08:32.000000000 +0000 @@ -4,6 +4,7 @@ #include "config/types.h" extern const struct global_type gt_string; +extern const struct global_type gt_service; int parse_json_string(json_t *, char const *, char const **); diff -Nru fort-validator-1.6.6/src/config/string_array.c fort-validator-1.6.8/src/config/string_array.c --- fort-validator-1.6.6/src/config/string_array.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/config/string_array.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,7 @@ #include "config/string_array.h" #include +#include #include "alloc.h" #include "config/str.h" diff -Nru fort-validator-1.6.6/src/config/types.h fort-validator-1.6.8/src/config/types.h --- fort-validator-1.6.6/src/config/types.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/config/types.h 2026-05-29 21:08:32.000000000 +0000 @@ -4,12 +4,7 @@ #include #include #include -#include #include -#include -#include -#include -#include struct option_field; struct group_fields; diff -Nru fort-validator-1.6.6/src/config/uint.c fort-validator-1.6.8/src/config/uint.c --- fort-validator-1.6.6/src/config/uint.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/config/uint.c 2026-05-29 21:08:32.000000000 +0000 @@ -2,6 +2,7 @@ #include #include +#include #include "log.h" diff -Nru fort-validator-1.6.6/src/config.c fort-validator-1.6.8/src/config.c --- fort-validator-1.6.6/src/config.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/config.c 2026-05-29 21:08:32.000000000 +0000 @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -76,6 +77,10 @@ } server; struct { + unsigned int port; + } prometheus; + + struct { /* Enables the protocol */ bool enabled; /* Protocol preference; compared to http.priority */ @@ -125,6 +130,8 @@ curl_off_t max_file_size; /* Directory where CA certs to verify peers are found */ char *ca_path; + /* See CURLOPT_PROXY */ + char *proxy; } http; struct { @@ -331,7 +338,7 @@ }, { .id = 5001, .name = "server.port", - .type = >_string, + .type = >_service, .offset = offsetof(struct rpki_config, server.port), .doc = "Default port to which RTR server addresses will bind itself to. Can be a string, in which case a number will be resolved. If all of the addresses have a port, this value isn't utilized.", .json_null_allowed = false, @@ -420,6 +427,19 @@ .max = UINT_MAX, }, + /* Prometheus fields */ + { + .id = 14000, + .name = "prometheus.port", + .type = >_uint, + .offset = offsetof(struct rpki_config, prometheus.port), + .doc = "Port to bind the Prometheus server to. " + "Prometheus requires this value and 'server' mode to start. " + "Unlike server.port, prometheus.port will not be resolved.", + .min = 0, + .max = 0xFFFF, + }, + /* RSYNC fields */ { .id = 3000, @@ -590,7 +610,15 @@ .offset = offsetof(struct rpki_config, http.ca_path), .doc = "Directory where CA certificates are found, used to verify the peer", .arg_doc = "", - .json_null_allowed = false, + .json_null_allowed = true, + }, { + .id = 9013, + .name = "http.proxy", + .type = >_string, + .offset = offsetof(struct rpki_config, http.proxy), + .doc = "Name of proxy to use", + .arg_doc = "", + .json_null_allowed = true, }, /* Logging fields */ @@ -895,10 +923,13 @@ struct option_field const *opt; pr_op_info(PACKAGE_STRING); - pr_op_info(" libcrypto: " OPENSSL_VERSION_TEXT); - pr_op_info(" jansson: " JANSSON_VERSION); - pr_op_info(" libcurl: " LIBCURL_VERSION); - pr_op_info(" libxml: " LIBXML_DOTTED_VERSION); + pr_op_info(" libcrypto: " OPENSSL_VERSION_TEXT); + pr_op_info(" jansson: " JANSSON_VERSION); + pr_op_info(" libcurl: " LIBCURL_VERSION); + pr_op_info(" libxml: " LIBXML_DOTTED_VERSION); + pr_op_info(" libmicrohttpd: %x.%x.%x-%x", + MHD_VERSION >> 24, (MHD_VERSION >> 16) & 0xFF, + (MHD_VERSION >> 8) & 0xFF, MHD_VERSION & 0xFF); pr_op_info("Configuration {"); @@ -917,6 +948,7 @@ "--contimeout=20", "--max-size=20MB", "--timeout=15", + "--exclude=.*", "--include=*/", "--include=*.cer", "--include=*.crl", "--include=*.gbr", "--include=*.mft", "--include=*.roa", "--exclude=*", @@ -955,6 +987,8 @@ rpki_config.server.interval.expire = 7200; rpki_config.server.deltas_lifetime = 2; + rpki_config.prometheus.port = 0; + rpki_config.rsync.enabled = true; rpki_config.rsync.priority = 50; rpki_config.rsync.strategy = pstrdup(""); @@ -980,6 +1014,7 @@ rpki_config.http.low_speed_time = 10; rpki_config.http.max_file_size = 2000000000; rpki_config.http.ca_path = NULL; /* Use system default */ + rpki_config.http.proxy = NULL; rpki_config.log.enabled = true; rpki_config.log.tag = NULL; @@ -1013,6 +1048,8 @@ static int validate_config(void) { + char const *proxy; + if (rpki_config.mode == PRINT_FILE) return 0; @@ -1040,6 +1077,14 @@ if (rpki_config.slurm != NULL && !valid_file_or_dir(rpki_config.slurm, true)) return pr_op_err("Invalid slurm location."); + if (rpki_config.http.proxy == NULL) { + proxy = curl_getenv("https_proxy"); + if (proxy == NULL) + proxy = curl_getenv("HTTPS_PROXY"); + if (proxy != NULL && proxy[0] != '\0') + rpki_config.http.proxy = pstrdup(proxy); + } + return 0; } @@ -1228,6 +1273,12 @@ return rpki_config.server.deltas_lifetime; } +unsigned int +config_get_prometheus_port(void) +{ + return rpki_config.prometheus.port; +} + char const * config_get_slurm(void) { @@ -1403,6 +1454,12 @@ } char const * +config_get_http_proxy(void) +{ + return rpki_config.http.proxy; +} + +char const * config_get_http_user_agent(void) { return rpki_config.http.user_agent; diff -Nru fort-validator-1.6.6/src/config.h fort-validator-1.6.8/src/config.h --- fort-validator-1.6.6/src/config.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/config.h 2026-05-29 21:08:32.000000000 +0000 @@ -1,10 +1,7 @@ #ifndef SRC_CONFIG_H_ #define SRC_CONFIG_H_ -#include #include -#include -#include #include #include "config/file_type.h" @@ -27,6 +24,7 @@ unsigned int config_get_interval_retry(void); unsigned int config_get_interval_expire(void); unsigned int config_get_deltas_lifetime(void); +unsigned int config_get_prometheus_port(void); char const *config_get_slurm(void); char const *config_get_tal(void); @@ -52,6 +50,7 @@ unsigned int config_get_http_priority(void); unsigned int config_get_http_retry_count(void); unsigned int config_get_http_retry_interval(void); +char const *config_get_http_proxy(void); char const *config_get_output_roa(void); char const *config_get_output_bgpsec(void); enum output_format config_get_output_format(void); diff -Nru fort-validator-1.6.6/src/crypto/base64.c fort-validator-1.6.8/src/crypto/base64.c --- fort-validator-1.6.6/src/crypto/base64.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/crypto/base64.c 2026-05-29 21:08:32.000000000 +0000 @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include "alloc.h" diff -Nru fort-validator-1.6.6/src/crypto/base64.h fort-validator-1.6.8/src/crypto/base64.h --- fort-validator-1.6.6/src/crypto/base64.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/crypto/base64.h 2026-05-29 21:08:32.000000000 +0000 @@ -4,12 +4,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include bool base64_decode(BIO *, unsigned char *, bool, size_t, size_t *); bool base64url_decode(char const *, unsigned char **, size_t *); diff -Nru fort-validator-1.6.6/src/data_structure/array_list.h fort-validator-1.6.8/src/data_structure/array_list.h --- fort-validator-1.6.6/src/data_structure/array_list.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/data_structure/array_list.h 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,9 @@ #ifndef SRC_DATA_STRUCTURE_ARRAY_LIST_H_ #define SRC_DATA_STRUCTURE_ARRAY_LIST_H_ +#include +#include + #include "alloc.h" #include "data_structure/common.h" diff -Nru fort-validator-1.6.6/src/data_structure/common.h fort-validator-1.6.8/src/data_structure/common.h --- fort-validator-1.6.6/src/data_structure/common.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/data_structure/common.h 2026-05-29 21:08:32.000000000 +0000 @@ -2,12 +2,6 @@ #define SRC_DATA_STRUCTURE_COMMON_H_ #include -#include -#include -#include -#include -#include -#include typedef size_t array_index; diff -Nru fort-validator-1.6.6/src/data_structure/path_builder.h fort-validator-1.6.8/src/data_structure/path_builder.h --- fort-validator-1.6.6/src/data_structure/path_builder.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/data_structure/path_builder.h 2026-05-29 21:08:32.000000000 +0000 @@ -1,18 +1,9 @@ #ifndef SRC_DATA_STRUCTURE_PATH_BUILDER_H_ #define SRC_DATA_STRUCTURE_PATH_BUILDER_H_ -#include -#include -#include #include #include #include -#include -#include -#include -#include -#include -#include struct path_builder { char *string; diff -Nru fort-validator-1.6.6/src/data_structure/uthash.h fort-validator-1.6.8/src/data_structure/uthash.h --- fort-validator-1.6.6/src/data_structure/uthash.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/data_structure/uthash.h 2026-05-29 21:08:32.000000000 +0000 @@ -26,16 +26,11 @@ #define UTHASH_VERSION 2.1.0 -#include -#include -#include #include #include #include #include #include -#include -#include #include #if !defined(DECLTYPE) && !defined(NO_DECLTYPE) diff -Nru fort-validator-1.6.6/src/file.h fort-validator-1.6.8/src/file.h --- fort-validator-1.6.6/src/file.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/file.h 2026-05-29 21:08:32.000000000 +0000 @@ -5,9 +5,7 @@ #include #include #include -#include #include -#include #include #include #include diff -Nru fort-validator-1.6.6/src/http/http.c fort-validator-1.6.8/src/http/http.c --- fort-validator-1.6.6/src/http/http.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/http/http.c 2026-05-29 21:08:32.000000000 +0000 @@ -213,6 +213,9 @@ CURL_TIMECOND_IFMODSINCE); } + if (config_get_http_proxy()) + setopt_str(result, CURLOPT_PROXY, config_get_http_proxy()); + handler->curl = result; return 0; } diff -Nru fort-validator-1.6.6/src/incidence/incidence.c fort-validator-1.6.8/src/incidence/incidence.c --- fort-validator-1.6.6/src/incidence/incidence.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/incidence/incidence.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,7 @@ #include "incidence/incidence.h" #include +#include #include "common.h" #include "data_structure/common.h" diff -Nru fort-validator-1.6.6/src/json_handler.c fort-validator-1.6.8/src/json_handler.c --- fort-validator-1.6.6/src/json_handler.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/json_handler.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,7 @@ #include "json_handler.h" #include +#include #include "alloc.h" #include "config.h" diff -Nru fort-validator-1.6.6/src/json_util.c fort-validator-1.6.8/src/json_util.c --- fort-validator-1.6.6/src/json_util.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/json_util.c 2026-05-29 21:08:32.000000000 +0000 @@ -2,6 +2,7 @@ #include #include +#include #include #include "log.h" diff -Nru fort-validator-1.6.6/src/json_util.h fort-validator-1.6.8/src/json_util.h --- fort-validator-1.6.6/src/json_util.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/json_util.h 2026-05-29 21:08:32.000000000 +0000 @@ -1,20 +1,12 @@ #ifndef SRC_JSON_UTIL_H_ #define SRC_JSON_UTIL_H_ -#include #include -#include -#include #include #include #include -#include -#include -#include -#include #include #include -#include /* * Contract of get functions: diff -Nru fort-validator-1.6.6/src/line_file.c fort-validator-1.6.8/src/line_file.c --- fort-validator-1.6.6/src/line_file.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/line_file.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,5 +1,7 @@ #include "line_file.h" +#include + #include "alloc.h" #include "file.h" #include "log.h" diff -Nru fort-validator-1.6.6/src/line_file.h fort-validator-1.6.8/src/line_file.h --- fort-validator-1.6.6/src/line_file.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/line_file.h 2026-05-29 21:08:32.000000000 +0000 @@ -10,11 +10,6 @@ #include #include -#include -#include -#include -#include -#include struct line_file; diff -Nru fort-validator-1.6.6/src/main.c fort-validator-1.6.8/src/main.c --- fort-validator-1.6.6/src/main.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/main.c 2026-05-29 21:08:32.000000000 +0000 @@ -6,7 +6,9 @@ #include "log.h" #include "nid.h" #include "print_file.h" +#include "prometheus.h" #include "rtr/rtr.h" +#include "stats.h" #include "thread_var.h" #include "xml/relax_ng.h" @@ -47,11 +49,9 @@ rtr_notify(); - /* - * See issue #133. - * TODO (#50) Remove this message once the stats server is implemented. - */ + /* TODO (#133) Stats ready; remove this message in a couple versions. */ pr_op_warn("First validation cycle successfully ended, now you can connect your router(s)"); + stats_gauge_set(stat_rtr_ready, 1); do { pr_op_info("Main loop: Sleeping."); @@ -127,9 +127,15 @@ error = handle_flags_config(argc, argv); if (error) goto revert_log; - error = nid_init(); + error = stats_setup(); if (error) goto revert_config; + error = prometheus_setup(); + if (error) + goto revert_stats; + error = nid_init(); + if (error) + goto revert_prometheus; error = extension_init(); if (error) goto revert_nid; @@ -167,6 +173,10 @@ http_cleanup(); revert_nid: nid_destroy(); +revert_prometheus: + prometheus_teardown(); +revert_stats: + stats_teardown(); revert_config: free_rpki_config(); revert_log: diff -Nru fort-validator-1.6.6/src/nid.c fort-validator-1.6.8/src/nid.c --- fort-validator-1.6.6/src/nid.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/nid.c 2026-05-29 21:08:32.000000000 +0000 @@ -25,18 +25,20 @@ /* Note: Object has to be registered for OBJ_txt2nid to work. */ nid = OBJ_txt2nid(oid); - if (nid == NID_undef) { - /* Note: Implicit object registration happens in OBJ_create. */ - nid = OBJ_create(oid, sn, ln); - if (nid == 0) - return op_crypto_err("Unable to register the %s NID.", sn); - pr_op_debug("%s registered. Its nid is %d.", sn, nid); + if (nid != NID_undef) { + pr_op_debug("%s retrieved. NID: %d", sn, nid); + return nid; + } - } else { - pr_op_debug("%s retrieved. Its nid is %d.", sn, nid); + /* Note: Implicit object registration happens in OBJ_create. */ + nid = OBJ_create(oid, sn, ln); + if (nid != NID_undef) { + pr_op_debug("%s registered. NID: %d", sn, nid); + return nid; } - return nid; + op_crypto_err("Unable to register the %s NID.", sn); + return NID_undef; } /** @@ -50,67 +52,67 @@ ct_roa_nid = register_oid("1.2.840.113549.1.9.16.1.24", "id-ct-routeOriginAuthz", "RPKI ROA (Content type)"); - if (ct_roa_nid == 0) + if (ct_roa_nid == NID_undef) return -EINVAL; ct_mft_nid = register_oid("1.2.840.113549.1.9.16.1.26", "id-ct-rpkiManifest", "RPKI Manifest (Content type)"); - if (ct_mft_nid == 0) + if (ct_mft_nid == NID_undef) return -EINVAL; ct_gbr_nid = register_oid("1.2.840.113549.1.9.16.1.35", "id-ct-rpkiGhostbusters", "RPKI Ghostbusters (Content type)"); - if (ct_gbr_nid == 0) + if (ct_gbr_nid == NID_undef) return -EINVAL; rpki_manifest_nid = register_oid("1.3.6.1.5.5.7.48.10", "rpkiManifest", "RPKI Manifest (RFC 6487)"); - if (rpki_manifest_nid == 0) + if (rpki_manifest_nid == NID_undef) return -EINVAL; signed_object_nid = register_oid("1.3.6.1.5.5.7.48.11", "signedObject", "RPKI Signed Object (RFC 6487)"); - if (signed_object_nid == 0) + if (signed_object_nid == NID_undef) return -EINVAL; rpki_notify_nid = register_oid("1.3.6.1.5.5.7.48.13", "rpkiNotify", "RPKI Update Notification File (RFC 8182)"); - if (rpki_notify_nid == 0) + if (rpki_notify_nid == NID_undef) return -EINVAL; cert_policy_rpki_nid = register_oid("1.3.6.1.5.5.7.14.2", "id-cp-ipAddr-asNumber (RFC 6484)", "Certificate Policy (CP) for the Resource PKI (RPKI)"); - if (cert_policy_rpki_nid == 0) + if (cert_policy_rpki_nid == NID_undef) return -EINVAL; cert_policy_rpki_v2_nid = register_oid("1.3.6.1.5.5.7.14.3", "id-cp-ipAddr-asNumber-v2 (RFC 8360)", "Certificate Policy for Use with Validation Reconsidered in the RPKI"); - if (cert_policy_rpki_v2_nid == 0) + if (cert_policy_rpki_v2_nid == NID_undef) return -EINVAL; ip_addr_blocks_v2_nid = register_oid("1.3.6.1.5.5.7.1.28", "id-pe-ipAddrBlocks-v2", "Amended IP Resources (RFC 8360)"); - if (ip_addr_blocks_v2_nid == 0) + if (ip_addr_blocks_v2_nid == NID_undef) return -EINVAL; autonomous_sys_ids_v2_nid = register_oid("1.3.6.1.5.5.7.1.29", "id-pe-autonomousSysIds-v2", "Amended AS Resources (RFC 8360)"); - if (autonomous_sys_ids_v2_nid == 0) + if (autonomous_sys_ids_v2_nid == NID_undef) return -EINVAL; bgpsec_router_nid = register_oid("1.3.6.1.5.5.7.3.30", "id-kp-bgpsec-router", "BGPsec Extended Key Usage (RFC 8209)"); - if (bgpsec_router_nid == 0) + if (bgpsec_router_nid == NID_undef) return -EINVAL; return 0; diff -Nru fort-validator-1.6.6/src/object/certificate.c fort-validator-1.6.8/src/object/certificate.c --- fort-validator-1.6.6/src/object/certificate.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/object/certificate.c 2026-05-29 21:08:32.000000000 +0000 @@ -139,6 +139,11 @@ if (log_val_enabled(LOG_DEBUG)) debug_serial_number(number); + if (BN_is_negative(number)) { + BN_free(number); + return pr_val_err("Serial number is negative."); + } + state = state_retrieve(); x509stack_store_serial(validation_certstack(state), number); return 0; @@ -154,11 +159,42 @@ return validate_certificate_signature_algorithm(nid, "Certificate"); } +static bool +is_valid_printable_string_char(char c) +{ + if ('A' <= c && c <= 'Z') + return true; + if ('a' <= c && c <= 'z') + return true; + if ('0' <= c && c <= '9') + return true; + if (c == ' ') + return true; + if ('\'' <= c && c <= ')') + return true; + if ('+' <= c && c <= '/') + return true; + if (c == ':' || c == '=' || c == '?') + return true; + return false; +} + +static int +validate_printable_string(char const *str, char const *what) +{ + for (; *str != '\0'; str++) + if (!is_valid_printable_string_char(*str)) + return pr_val_err("Invalid character in '%s' PrintableString: 0x%X", + what, *str); + return 0; +} + static int validate_issuer(X509 *cert, bool is_ta) { X509_NAME *issuer; struct rfc5280_name *name; + char const *commonName; int error; issuer = X509_get_issuer_name(cert); @@ -171,10 +207,13 @@ error = x509_name_decode(issuer, "issuer", &name); if (error) return error; - pr_val_debug("Issuer: %s", x509_name_commonName(name)); + + commonName = x509_name_commonName(name); + pr_val_debug("Issuer: %s", commonName); + error = validate_printable_string(commonName, "Issuer"); x509_name_put(name); - return 0; + return error; } /* @@ -221,12 +260,16 @@ validate_subject(X509 *cert) { struct rfc5280_name *name; + char const *commonName; int error; error = x509_name_decode(X509_get_subject_name(cert), "subject", &name); if (error) return error; - pr_val_debug("Subject: %s", x509_name_commonName(name)); + + commonName = x509_name_commonName(name); + pr_val_debug("Subject: %s", commonName); + error = validate_printable_string(commonName, "Subject"); x509_name_put(name); return error; @@ -506,7 +549,7 @@ if ((evppkey = X509_get0_pubkey(cert)) == NULL) return val_crypto_err("X509_get0_pubkey() returned NULL"); if (X509_verify(cert, evppkey) != 1) - return -EINVAL; + return val_crypto_err("TA validation failed."); } return 0; diff -Nru fort-validator-1.6.6/src/object/tal.c fort-validator-1.6.8/src/object/tal.c --- fort-validator-1.6.6/src/object/tal.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/object/tal.c 2026-05-29 21:08:32.000000000 +0000 @@ -10,6 +10,7 @@ #include "crypto/base64.h" #include "line_file.h" #include "log.h" +#include "stats.h" #include "thread_var.h" typedef int (*foreach_uri_cb)(struct tal *, struct rpki_uri *, void *); @@ -528,6 +529,11 @@ } if (!error) { + stats_set_tal_vrps(thread->tal_file, "ipv4", + db_table_roa_count_v4(thread->db)); + stats_set_tal_vrps(thread->tal_file, "ipv6", + db_table_roa_count_v6(thread->db)); + if (db == NULL) { db = thread->db; thread->db = NULL; diff -Nru fort-validator-1.6.6/src/object/vcard.c fort-validator-1.6.8/src/object/vcard.c --- fort-validator-1.6.6/src/object/vcard.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/object/vcard.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,9 @@ #include "object/vcard.h" #include +#include +#include +#include #include "alloc.h" #include "log.h" diff -Nru fort-validator-1.6.6/src/prometheus.c fort-validator-1.6.8/src/prometheus.c --- fort-validator-1.6.6/src/prometheus.c 1970-01-01 00:00:00.000000000 +0000 +++ fort-validator-1.6.8/src/prometheus.c 2026-05-29 21:08:32.000000000 +0000 @@ -0,0 +1,165 @@ +#include "prometheus.h" + +#include +#include +#include +#include + +#include "config.h" +#include "log.h" +#include "stats.h" + +#if MHD_VERSION > 0x00097000 +#define MHD_RESULT enum MHD_Result +#else +#define MHD_RESULT int +#endif + +#define OPENMETRICS_CT \ + "application/openmetrics-text; version=1.0.0; charset=utf-8" +#define PLAINTEXT_CT \ + "text/plain; version=0.0.4; charset=utf-8" + +static struct MHD_Daemon *prometheus_daemon; + +static MHD_RESULT +respond(struct MHD_Connection *conn, char *msg, unsigned int status) +{ + struct MHD_Response *response; + MHD_RESULT result; + + response = MHD_create_response_from_buffer(strlen(msg), msg, + MHD_RESPMEM_PERSISTENT); + result = MHD_queue_response(conn, status, response); + MHD_destroy_response(response); + + return result; +} + +static float +find_q(char const *accept, char const *ct) +{ + char const *value; + char const *limit; + char const *qstr; + float q; + + value = strstr(accept, ct); + if (!value) + return 0; + + limit = strchr(value, ','); + if (!limit) + limit = value + strlen(value); + + qstr = strstr(value, ";q="); + if (!qstr || qstr > limit) + return 1; + return (sscanf(qstr, ";q=%f", &q) == EOF) ? 0.5 /* Shrug */ : q; +} + +static void +set_content_type(struct MHD_Connection *conn, struct MHD_Response *res) +{ + char const *accept; + float om_q, txt_q; + char const *ct; + MHD_RESULT ret; + + accept = MHD_lookup_connection_value(conn, MHD_HEADER_KIND, + MHD_HTTP_HEADER_ACCEPT); + if (accept != NULL) { + om_q = find_q(accept, "application/openmetrics-text"); + txt_q = find_q(accept, "text/plain"); + + if (om_q < 0.001f && txt_q < 0.001f) + /* Likely a browser; these tend to prefer plaintext. */ + ct = PLAINTEXT_CT; + else + ct = (om_q >= txt_q) ? OPENMETRICS_CT : PLAINTEXT_CT; + } else { + ct = OPENMETRICS_CT; + } + + ret = MHD_add_response_header(res, "Content-Type", ct); + if (ret != MHD_YES) { + pr_op_debug("Could not set Content-Type HTTP header."); + /* Keep going; maybe the client won't care. */ + } +} + +static MHD_RESULT +send_metrics(struct MHD_Connection *conn) +{ + char *stats; + struct MHD_Response *res; + MHD_RESULT ret; + + pr_op_debug("Handling Prometheus request..."); + + stats = stats_export(); + +#if MHD_VERSION > 0x00096000 + res = MHD_create_response_from_buffer_with_free_callback(strlen(stats), + stats, free); +#else + res = MHD_create_response_from_buffer(strlen(stats), stats, + MHD_RESPMEM_MUST_FREE); +#endif + + set_content_type(conn, res); + + ret = MHD_queue_response(conn, MHD_HTTP_OK, res); + MHD_destroy_response(res); + + pr_op_debug("Prometheus request handled."); + return ret; +} + +static MHD_RESULT +handle_prometheus_req(void *cls, struct MHD_Connection *conn, + const char *url, const char *method, const char *version, + const char *upload, size_t *uplen, void **state) +{ + if (strcmp(method, "GET") != 0) + return respond(conn, "Invalid HTTP Method\n", MHD_HTTP_BAD_REQUEST); + + if (strcmp(url, "/") == 0) + return respond(conn, "OK\n", MHD_HTTP_OK); + if (strcmp(url, "/metrics") == 0) + return send_metrics(conn); + + return respond(conn, "Bad Request\n", MHD_HTTP_BAD_REQUEST); +} + +int +prometheus_setup(void) +{ + unsigned int port; + + port = config_get_prometheus_port(); + if (config_get_mode() != SERVER || port == 0) + return 0; + + pr_op_debug("Starting Prometheus server..."); + + prometheus_daemon = MHD_start_daemon( + MHD_USE_THREAD_PER_CONNECTION, /* flags */ + port, /* port */ + NULL, NULL, /* accept policy */ + &handle_prometheus_req, NULL, /* handler */ + MHD_OPTION_END /* options */ + ); + + if (prometheus_daemon == NULL) + return pr_op_err("Could not start Prometheus server; Unknown error"); + + pr_op_debug("Prometheus server started."); + return 0; +} + +void +prometheus_teardown(void) +{ + MHD_stop_daemon(prometheus_daemon); +} diff -Nru fort-validator-1.6.6/src/prometheus.h fort-validator-1.6.8/src/prometheus.h --- fort-validator-1.6.6/src/prometheus.h 1970-01-01 00:00:00.000000000 +0000 +++ fort-validator-1.6.8/src/prometheus.h 2026-05-29 21:08:32.000000000 +0000 @@ -0,0 +1,7 @@ +#ifndef SRC_PROMETHEUS_H_ +#define SRC_PROMETHEUS_H_ + +int prometheus_setup(void); +void prometheus_teardown(void); + +#endif /* SRC_PROMETHEUS_H_ */ diff -Nru fort-validator-1.6.6/src/resource/ip6.c fort-validator-1.6.8/src/resource/ip6.c --- fort-validator-1.6.6/src/resource/ip6.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/resource/ip6.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,5 +1,7 @@ #include "resource/ip6.h" +#include + #include "sorted_array.h" static int diff -Nru fort-validator-1.6.6/src/rrdp.c fort-validator-1.6.8/src/rrdp.c --- fort-validator-1.6.6/src/rrdp.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/rrdp.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,7 @@ #include "rrdp.h" #include +#include #include #include @@ -659,6 +660,23 @@ } 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) { @@ -670,13 +688,21 @@ 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 @@ -779,8 +805,7 @@ 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); @@ -870,28 +895,27 @@ { struct validation *state; struct rpki_uri *uri; + bool changed; int error; state = state_retrieve(); - - delete_rpp(tal_get_file_name(validation_tal(state)), notif->uri); - uri = notif->snapshot.uri; pr_val_debug("Processing snapshot '%s'.", uri_val_get_printable(uri)); fnstack_push_uri(uri); /* - * TODO (performance) Is there a point in caching the snapshot? - * Especially considering we delete it 4 lines afterwards. - * Maybe stream it instead. - * Same for deltas. + * TODO (performance) There's no point in caching the snapshot. + * Stream it instead. Same for deltas. */ - error = cache_download(validation_cache(state), uri, NULL); + error = cache_download(validation_cache(state), uri, &changed); if (error) goto end; - error = parse_snapshot(notif); - delete_file(uri); + if (changed) { + delete_rpp(tal_get_file_name(validation_tal(state)), notif->uri); + error = parse_snapshot(notif); + delete_file(uri); + } end: fnstack_pop(); diff -Nru fort-validator-1.6.6/src/rsync/rsync.c fort-validator-1.6.8/src/rsync/rsync.c --- fort-validator-1.6.6/src/rsync/rsync.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/rsync/rsync.c 2026-05-29 21:08:32.000000000 +0000 @@ -4,8 +4,10 @@ #include #include #include +#include #include #include +#include #include "alloc.h" #include "common.h" diff -Nru fort-validator-1.6.6/src/rtr/db/db_table.c fort-validator-1.6.8/src/rtr/db/db_table.c --- fort-validator-1.6.6/src/rtr/db/db_table.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/rtr/db/db_table.c 2026-05-29 21:08:32.000000000 +0000 @@ -19,18 +19,15 @@ struct db_table { struct hashable_roa *roas; struct hashable_key *router_keys; + + unsigned int total_roas_v4; + unsigned int total_roas_v6; }; struct db_table * db_table_create(void) { - struct db_table *table; - - table = pmalloc(sizeof(struct db_table)); - table->roas = NULL; - table->router_keys = NULL; - - return table; + return pzalloc(sizeof(struct db_table)); } void @@ -64,13 +61,21 @@ errno = 0; HASH_REPLACE(hh, table->roas, data, sizeof(new->data), new, old); error = errno; + if (error) { pr_val_err("ROA couldn't be added to hash table: %s", strerror(error)); return -error; } - if (old != NULL) + + if (old == NULL) { + switch (new->data.addr_fam) { + case AF_INET: table->total_roas_v4++; break; + case AF_INET6: table->total_roas_v6++; break; + } + } else { free(old); + } return 0; } @@ -158,6 +163,18 @@ } unsigned int +db_table_roa_count_v4(struct db_table *table) +{ + return table->total_roas_v4; +} + +unsigned int +db_table_roa_count_v6(struct db_table *table) +{ + return table->total_roas_v6; +} + +unsigned int db_table_router_key_count(struct db_table *table) { return HASH_COUNT(table->router_keys); diff -Nru fort-validator-1.6.6/src/rtr/db/db_table.h fort-validator-1.6.8/src/rtr/db/db_table.h --- fort-validator-1.6.6/src/rtr/db/db_table.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/rtr/db/db_table.h 2026-05-29 21:08:32.000000000 +0000 @@ -12,6 +12,8 @@ int db_table_join(struct db_table *, struct db_table *); unsigned int db_table_roa_count(struct db_table *); +unsigned int db_table_roa_count_v4(struct db_table *); +unsigned int db_table_roa_count_v6(struct db_table *); unsigned int db_table_router_key_count(struct db_table *); int db_table_foreach_roa(struct db_table const *, vrp_foreach_cb, void *); diff -Nru fort-validator-1.6.6/src/rtr/db/delta.c fort-validator-1.6.8/src/rtr/db/delta.c --- fort-validator-1.6.6/src/rtr/db/delta.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/rtr/db/delta.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,7 @@ #include "rtr/db/delta.h" #include +#include #include "data_structure/array_list.h" #include "log.h" diff -Nru fort-validator-1.6.6/src/rtr/err_pdu.c fort-validator-1.6.8/src/rtr/err_pdu.c --- fort-validator-1.6.6/src/rtr/err_pdu.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/rtr/err_pdu.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,7 @@ #include "rtr/err_pdu.h" #include +#include #include "alloc.h" #include "rtr/pdu_sender.h" diff -Nru fort-validator-1.6.6/src/rtr/pdu.h fort-validator-1.6.8/src/rtr/pdu.h --- fort-validator-1.6.6/src/rtr/pdu.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/rtr/pdu.h 2026-05-29 21:08:32.000000000 +0000 @@ -1,17 +1,8 @@ #ifndef RTR_PDU_H_ #define RTR_PDU_H_ -#include -#include -#include #include #include -#include -#include -#include -#include -#include -#include enum rtr_version { RTR_V0 = 0, diff -Nru fort-validator-1.6.6/src/rtr/pdu_sender.c fort-validator-1.6.8/src/rtr/pdu_sender.c --- fort-validator-1.6.6/src/rtr/pdu_sender.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/rtr/pdu_sender.c 2026-05-29 21:08:32.000000000 +0000 @@ -2,6 +2,7 @@ #include #include +#include #include "alloc.h" #include "config.h" diff -Nru fort-validator-1.6.6/src/rtr/pdu_stream.c fort-validator-1.6.8/src/rtr/pdu_stream.c --- fort-validator-1.6.6/src/rtr/pdu_stream.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/rtr/pdu_stream.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,10 @@ #include "rtr/pdu_stream.h" #include +#include +#include +#include +#include #include "alloc.h" #include "log.h" diff -Nru fort-validator-1.6.6/src/rtr/pdu_stream.h fort-validator-1.6.8/src/rtr/pdu_stream.h --- fort-validator-1.6.6/src/rtr/pdu_stream.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/rtr/pdu_stream.h 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,8 @@ #ifndef SRC_RTR_PDU_STREAM_H_ #define SRC_RTR_PDU_STREAM_H_ +#include +#include #include #include "rtr/pdu.h" diff -Nru fort-validator-1.6.6/src/rtr/primitive_writer.h fort-validator-1.6.8/src/rtr/primitive_writer.h --- fort-validator-1.6.6/src/rtr/primitive_writer.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/rtr/primitive_writer.h 2026-05-29 21:08:32.000000000 +0000 @@ -2,7 +2,6 @@ #define RTR_PRIMITIVE_WRITER_H_ #include -#include #include #include diff -Nru fort-validator-1.6.6/src/rtr/rtr.c fort-validator-1.6.8/src/rtr/rtr.c --- fort-validator-1.6.6/src/rtr/rtr.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/rtr/rtr.c 2026-05-29 21:08:32.000000000 +0000 @@ -2,7 +2,9 @@ #include #include +#include #include +#include #include "common.h" #include "config.h" @@ -11,6 +13,7 @@ #include "rtr/db/vrps.h" #include "rtr/pdu_handler.h" #include "rtr/pdu_sender.h" +#include "stats.h" #include "thread/thread_pool.h" struct rtr_server { @@ -644,6 +647,8 @@ mutex_lock(&lock); apply_pollfds(pollfds, nclients); mutex_unlock(&lock); + + stats_gauge_set(stat_rtr_connections, clients.len); /* Fall through */ success: diff -Nru fort-validator-1.6.6/src/slurm/db_slurm.c fort-validator-1.6.8/src/slurm/db_slurm.c --- fort-validator-1.6.6/src/slurm/db_slurm.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/slurm/db_slurm.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,6 +1,7 @@ #include "slurm/db_slurm.h" #include +#include #include #include "common.h" diff -Nru fort-validator-1.6.6/src/slurm/slurm_parser.c fort-validator-1.6.8/src/slurm/slurm_parser.c --- fort-validator-1.6.6/src/slurm/slurm_parser.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/slurm/slurm_parser.c 2026-05-29 21:08:32.000000000 +0000 @@ -2,6 +2,9 @@ #include #include +#include +#include +#include #include "algorithm.h" #include "alloc.h" diff -Nru fort-validator-1.6.6/src/sorted_array.c fort-validator-1.6.8/src/sorted_array.c --- fort-validator-1.6.6/src/sorted_array.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/sorted_array.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,5 +1,9 @@ #include "sorted_array.h" +#include +#include +#include + #include "alloc.h" #include "log.h" diff -Nru fort-validator-1.6.6/src/sorted_array.h fort-validator-1.6.8/src/sorted_array.h --- fort-validator-1.6.6/src/sorted_array.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/sorted_array.h 2026-05-29 21:08:32.000000000 +0000 @@ -3,12 +3,6 @@ #include #include -#include -#include -#include -#include -#include -#include /* * This implementation is not a generic sorted array; It's intended to store RFC diff -Nru fort-validator-1.6.6/src/stats.c fort-validator-1.6.8/src/stats.c --- fort-validator-1.6.6/src/stats.c 1970-01-01 00:00:00.000000000 +0000 +++ fort-validator-1.6.8/src/stats.c 2026-05-29 21:08:32.000000000 +0000 @@ -0,0 +1,187 @@ +#include "stats.h" + +#include +#include + +#include "alloc.h" +#include "common.h" +#include "data_structure/uthash.h" +#include "log.h" + +struct stats_gauge { + char *name; + unsigned int value; + time_t timestamp; + + UT_hash_handle hh; +}; + +static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; +static struct stats_gauge *gauges; + +struct stats_gauge *stat_rtr_ready; +struct stats_gauge *stat_rtr_connections; + +/* Steals ownership of @name */ +static struct stats_gauge * +add_gauge(char *name, size_t namelen, unsigned int value) +{ + struct stats_gauge *old; + struct stats_gauge *new; + struct stats_gauge *delete; + struct stats_gauge *result; + + new = pzalloc(sizeof(struct stats_gauge)); + new->name = name; + new->value = value; + new->timestamp = time(NULL); + + if (namelen == 0) + namelen = strlen(name); + + mutex_lock(&lock); + HASH_FIND(hh, gauges, name, namelen, old); + if (old != NULL) { + old->value = value; + old->timestamp = new->timestamp; + delete = new; + result = old; + } else { + HASH_ADD_KEYPTR(hh, gauges, name, namelen, new); + delete = NULL; + result = new; + } + mutex_unlock(&lock); + + if (delete) { + free(delete->name); + free(delete); + } + + return result; +} + +#define ADD_GAUGE(name) add_gauge(pstrdup(name), 0, 0) + +int +stats_setup(void) +{ + stat_rtr_ready = ADD_GAUGE("fort_rtr_ready"); + stat_rtr_connections = ADD_GAUGE("fort_rtr_current_connections"); + return 0; +} + +void +stats_teardown(void) +{ + struct stats_gauge *gauge, *tmp; + + HASH_ITER(hh, gauges, gauge, tmp) { + HASH_DEL(gauges, gauge); + free(gauge->name); + free(gauge); + } +} + +void +stats_gauge_set(struct stats_gauge *gauge, unsigned int value) +{ + time_t now = time(NULL); + + mutex_lock(&lock); + gauge->value = value; + gauge->timestamp = now; + mutex_unlock(&lock); +} + +void +stats_set_tal_vrps(char const *tal_path, char const *proto, unsigned int value) +{ + char const *ta, *dot; + size_t talen; + + size_t baselen; + size_t keylen; + char *key; + int chars; + + ta = strrchr(tal_path, '/'); + ta = (ta == NULL) ? tal_path : (ta + 1); + dot = strrchr(ta, '.'); + talen = dot ? (dot - ta) : strlen(ta); + + baselen = strlen("fort_valid_vrps_total{ta=\"\",proto=\"\"}"); + keylen = baselen + talen + strlen(proto) + 1; + + key = pmalloc(keylen); + chars = snprintf(key, keylen, + "fort_valid_vrps_total{ta=\"%.*s\",proto=\"%s\"}", + (int)talen, ta, proto); + if (chars < 0 || keylen <= chars) { + free(key); + pr_op_warn("Cannot create valid_vrps_total stat: %d", chars); + return; + } + + add_gauge(key, keylen - 1, value); +} + +struct stats_buffer { + char *str; + char *cursor; + size_t capacity; +}; + +static bool +printf_buf(struct stats_buffer *buf, char const *fmt, ...) +{ + size_t available; + int written; + va_list ap; + + available = buf->capacity - (buf->cursor - buf->str); + + va_start(ap, fmt); + written = vsnprintf(buf->cursor, available, fmt, ap); + va_end(ap); + + if (written < 0 || available <= written) + return false; + + buf->cursor += written; + return true; +} + +char * +stats_export(void) +{ + struct stats_buffer buf; + struct stats_gauge *gauge, *tmp; + + buf.capacity = 1024; + buf.str = buf.cursor = pmalloc(buf.capacity); + + HASH_ITER(hh, gauges, gauge, tmp) { + if (!printf_buf(&buf, "%s %u", gauge->name, gauge->value)) + goto cancel; + if (gauge->timestamp != ((time_t)-1)) + if (!printf_buf(&buf, " %jd", (intmax_t)gauge->timestamp)) + goto cancel; + if (!printf_buf(&buf, "\n")) + goto cancel; + } + + if (!printf_buf(&buf, "# EOF\n")) + goto cancel; + + if (buf.cursor >= buf.str + buf.capacity) + goto cancel; + *buf.cursor = '\0'; + + return buf.str; + +cancel: + free(buf.str); + pr_op_err("Cannot create Prometheus response: Too many stats"); + return NULL; +} diff -Nru fort-validator-1.6.6/src/stats.h fort-validator-1.6.8/src/stats.h --- fort-validator-1.6.6/src/stats.h 1970-01-01 00:00:00.000000000 +0000 +++ fort-validator-1.6.8/src/stats.h 2026-05-29 21:08:32.000000000 +0000 @@ -0,0 +1,16 @@ +#ifndef SRC_STATS_H_ +#define SRC_STATS_H_ + +struct stats_gauge; +extern struct stats_gauge *stat_rtr_ready; +extern struct stats_gauge *stat_rtr_connections; + +int stats_setup(void); +void stats_teardown(void); + +void stats_gauge_set(struct stats_gauge *, unsigned int); +void stats_set_tal_vrps(char const *, char const *, unsigned int); + +char *stats_export(void); + +#endif /* SRC_STATS_H_ */ diff -Nru fort-validator-1.6.6/src/str_token.c fort-validator-1.6.8/src/str_token.c --- fort-validator-1.6.6/src/str_token.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/str_token.c 2026-05-29 21:08:32.000000000 +0000 @@ -2,6 +2,7 @@ #include #include +#include #include "alloc.h" #include "log.h" diff -Nru fort-validator-1.6.6/src/str_token.h fort-validator-1.6.8/src/str_token.h --- fort-validator-1.6.6/src/str_token.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/str_token.h 2026-05-29 21:08:32.000000000 +0000 @@ -5,12 +5,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include int ia5s2string(ASN1_IA5STRING *, char **); int BN2string(BIGNUM *, char **); diff -Nru fort-validator-1.6.6/src/thread/thread_pool.c fort-validator-1.6.8/src/thread/thread_pool.c --- fort-validator-1.6.6/src/thread/thread_pool.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/thread/thread_pool.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,5 +1,7 @@ #include "thread/thread_pool.h" +#include +#include #include #include "alloc.h" diff -Nru fort-validator-1.6.6/src/types/address.h fort-validator-1.6.8/src/types/address.h --- fort-validator-1.6.6/src/types/address.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/types/address.h 2026-05-29 21:08:32.000000000 +0000 @@ -1,7 +1,6 @@ #ifndef SRC_TYPES_ADDRESS_H_ #define SRC_TYPES_ADDRESS_H_ -#include #include #include diff -Nru fort-validator-1.6.6/src/types/bio_seq.c fort-validator-1.6.8/src/types/bio_seq.c --- fort-validator-1.6.6/src/types/bio_seq.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/types/bio_seq.c 2026-05-29 21:08:32.000000000 +0000 @@ -1,5 +1,7 @@ #include "types/bio_seq.h" +#include + #include "alloc.h" #include "log.h" diff -Nru fort-validator-1.6.6/src/types/router_key.h fort-validator-1.6.8/src/types/router_key.h --- fort-validator-1.6.6/src/types/router_key.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/types/router_key.h 2026-05-29 21:08:32.000000000 +0000 @@ -1,9 +1,6 @@ #ifndef SRC_TYPES_ROUTER_KEY_H_ #define SRC_TYPES_ROUTER_KEY_H_ -#include -#include -#include #include /* diff -Nru fort-validator-1.6.6/src/types/serial.h fort-validator-1.6.8/src/types/serial.h --- fort-validator-1.6.6/src/types/serial.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/types/serial.h 2026-05-29 21:08:32.000000000 +0000 @@ -1,9 +1,6 @@ #ifndef SRC_TYPES_SERIAL_H_ #define SRC_TYPES_SERIAL_H_ -#include -#include -#include #include #include diff -Nru fort-validator-1.6.6/src/types/uri.c fort-validator-1.6.8/src/types/uri.c --- fort-validator-1.6.6/src/types/uri.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/types/uri.c 2026-05-29 21:08:32.000000000 +0000 @@ -136,7 +136,7 @@ || (chara == '_'); } -/* RFC 6486bis, section 4.2.2 */ +/* RFC 9286, section 4.2.2 */ static int validate_mft_file(IA5String_t *ia5) { @@ -594,6 +594,36 @@ 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 diff -Nru fort-validator-1.6.6/src/types/uri.h fort-validator-1.6.8/src/types/uri.h --- fort-validator-1.6.6/src/types/uri.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/types/uri.h 2026-05-29 21:08:32.000000000 +0000 @@ -2,6 +2,7 @@ #define SRC_TYPES_URI_H_ #include +#include #include "asn1/asn1c/IA5String.h" #include "data_structure/array_list.h" @@ -58,6 +59,8 @@ char *uri_get_rrdp_workspace(char const *, struct rpki_uri *); +bool uri_same_origin(struct rpki_uri const *, struct rpki_uri const *); + /* Plural */ DEFINE_ARRAY_LIST_STRUCT(uri_list, struct rpki_uri *); diff -Nru fort-validator-1.6.6/src/types/vrp.h fort-validator-1.6.8/src/types/vrp.h --- fort-validator-1.6.6/src/types/vrp.h 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/src/types/vrp.h 2026-05-29 21:08:32.000000000 +0000 @@ -2,7 +2,6 @@ #define SRC_TYPES_VRP_H_ #include -#include #include #include #include diff -Nru fort-validator-1.6.6/test/rrdp_test.c fort-validator-1.6.8/test/rrdp_test.c --- fort-validator-1.6.6/test/rrdp_test.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/test/rrdp_test.c 2026-05-29 21:08:32.000000000 +0000 @@ -36,6 +36,8 @@ MOCK_ABORT_PTR(uri_refget, rpki_uri, struct rpki_uri *uri) MOCK_VOID(uri_refput, struct rpki_uri *uri) MOCK(uri_val_get_printable, char const *, "uri", struct rpki_uri *uri) +__MOCK_ABORT(uri_same_origin, bool, false, struct rpki_uri const *u, + struct rpki_uri const *v) MOCK_ABORT_PTR(validation_cache, rpki_cache, struct validation *state) MOCK_ABORT_PTR(validation_tal, tal, struct validation *state) diff -Nru fort-validator-1.6.6/test/tal_test.c fort-validator-1.6.8/test/tal_test.c --- fort-validator-1.6.6/test/tal_test.c 2025-02-05 22:29:48.000000000 +0000 +++ fort-validator-1.6.8/test/tal_test.c 2026-05-29 21:08:32.000000000 +0000 @@ -30,6 +30,8 @@ MOCK_ABORT_PTR(db_table_create, db_table, void) MOCK_VOID(db_table_destroy, struct db_table *table) MOCK_ABORT_INT(db_table_join, struct db_table *dst, struct db_table *src) +__MOCK_ABORT(db_table_roa_count_v4, unsigned int, 0, struct db_table *t) +__MOCK_ABORT(db_table_roa_count_v6, unsigned int, 0, struct db_table *t) MOCK_ABORT_INT(deferstack_pop, struct cert_stack *stack, struct deferred_cert *result) MOCK_ABORT_VOID(fnstack_cleanup, void) @@ -44,6 +46,7 @@ MOCK_ABORT_VOID(rpp_refput, struct rpp *pp) MOCK_ABORT_INT(rrdp_update, struct rpki_uri *uri) MOCK(state_retrieve, struct validation *, NULL, void) +MOCK_ABORT_VOID(stats_set_tal_vrps, char const *t, char const *p, unsigned int v) MOCK_ABORT_PTR(validation_certstack, cert_stack, struct validation *state) MOCK_ABORT_VOID(validation_destroy, struct validation *state) MOCK_ABORT_INT(validation_prepare, struct validation **out, struct tal *tal,