Skip to content

Commit

Permalink
New cache design
Browse files Browse the repository at this point in the history
For #82.

It seems I'm finally done making dramatic wide-reaching changes to the
codebase. There's still plenty to add and test, but I would like to
start pushing atomic commits from now on.

This is a squashed version of development brach "issue82". It includes
a few merges with main.

```
cache/
    rsync/              # rsync refresh
        0/              # rsync module: rsync://a.b.c/mod1
            rpp1/       # Repository Publication Point 1
                d.mft
                d.crl
                d1.roa
            rpp2/
                e.mft
                e.crl
            ta.cer      # Trust Anchor
        1/              # rsync module: rsync://a.b.c/mod2
            ...
        2/              # rsync module: rsync://x.y.z/mod1
            ...
    https/              # HTTPS refresh
        0               # https://a.b.c/repo/ta.cer
        1               # https://x.y.z/repo/ta.cer
    rrdp/               # RRDP refresh
        0/              # https://m.n.o/notification.xml
            0           # rsync://m.n.o/mod1/rpp1/a.mft
            1           # rsync://m.n.o/mod1/rpp1/b.crl
            2           # rsync://m.n.o/mod1/rpp2/c.mft
            3           # rsync://m.n.o/mod1/rpp2/d.cer
        1/              # https://p.q.r/notification.xml
            ...
    fallback/           # Committed RPPs
        0/              # Fallback of rsync://a.b.c/mod1/rpp1
            0           # Hard link: cache/rsync/0/rpp1/d.mft
            1           # Hard link: cache/rsync/0/rpp1/d.crl
            2           # rsync://a.b.c/mod1/rpp1/d2.roa
                        # (Unique because of refresh)
        1               # Hard link: cache/https/0
        2/              # Fallback of m.n.o's rsync://m.n.o/mod1/rpp1
            0           # Hard link: cache/rrdp/0/0
            1           # Hard link: cache/rrdp/0/1
    index.json          # URL/path mappings and some metadata
```

- `cache/rsync`, `cache/https` and `cache/rrdp` contain "refreshes"
  (the exact latest files according to the servers). RRDP withdraws are
  honored, and rsyncs run without --compare-dest.
- "Refresh" files marked as valid are backed up in `cache/fallback`
  at the end of each validation cycle.
- Validation first tests fallback+refresh. (If a file exists in both,
  refresh wins.) If that fails, it retries with fallback only.
- The index is not a tree; everything is caged in numbered directories
  and indexed by exact URL, to prevent file overriding by URL hacking.

There's also a `cache/tmp` directory, where Fort temporarily dumps
notifications, snapshots and deltas. This directory will be removed
once #127 is fixed.
  • Loading branch information
ydahhrk committed Oct 7, 2024
1 parent 447f261 commit c7be17b
Show file tree
Hide file tree
Showing 164 changed files with 6,227 additions and 6,631 deletions.
12 changes: 1 addition & 11 deletions Makefile.am
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
# GNU wants us to include some files that we really don't want; therefore
# "foreign". The files are
#
# - AUTHORS: This should be inferred from the (automatic) git history, not some
# error prone, manually-maintained file!
# - ChangeLog: This is included in the main page of the site, which can be found
# in the gh-pages branch. Don't want to (nor should I) repeat myself.
# - NEWS: Same as ChangeLog.
# - README: We prefer the much gayer "README.md" version, so no thanks.
#
# Man, GNU conventions need a 21 century overhaul badly.
# Don't want AUTHORS, ChangeLog, NEWS, README.
AUTOMAKE_OPTIONS = foreign

SUBDIRS = src man test
Expand Down
59 changes: 59 additions & 0 deletions docs/CVE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
title: CVE
---

# CVEs

## CVE-2024-45238

Certificate containing a malformed `subjectPublicKey` crashes Fort 1.6.2-, when compiled with OpenSSL < 3.

| Description | A malicious RPKI repository that descends from a (trusted) Trust Anchor can serve (via rsync or RRDP) a resource certificate containing a bit string that doesn't properly decode into a Subject Public Key. OpenSSL does [not report this problem during parsing](https://github.com/openssl/openssl/blob/OpenSSL_1_1_1w/crypto/x509/x_pubkey.c#L152-L157), and when compiled with OpenSSL libcrypto versions below 3, Fort was recklessly dereferencing the pointer. |
| Impact | Crash. (Potential unavailability of Route Origin Validation.) |
| Patch | Commit [5689dea](https://github.com/NICMx/FORT-validator/commit/5689dea5e878fed28c5f338a27d7cda4151a14f1), released in Fort 1.6.3. |
| Acknowledgments | Thanks to Niklas Vogel and Haya Schulmann for their research and disclosure. |

## CVE-2024-45237

Certificate containing a Key Usage bit string longer than 2 bytes causes buffer overflow on Fort 1.6.2-.

| Description | A malicious RPKI repository that descends from a (trusted) Trust Anchor can serve (via rsync or RRDP) a resource certificate containing a [Key Usage extension](https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.3) consisting of more than two bytes of data. Fort used to write this string on a 2-byte buffer without properly sanitizing its length, leading to buffer overflow. |
| Impact | Depending on compilation options, the vulnerability would lead to a crash (which might in turn lead to unavailability of Route Origin Validation), incorrect validation results or arbitrary code execution. |
| Patch | Commit [939d988](https://github.com/NICMx/FORT-validator/commit/939d988551d17996be73f52c376a70a3d6ba69f9), released in Fort 1.6.3. |
| Acknowledgments | Thanks to Niklas Vogel and Haya Schulmann for their research and disclosure. |

## CVE-2024-45235

Certificate containing an Authority Key Identifier missing a `keyIdentifier` crashes Fort 1.6.2-.

| Description | A malicious RPKI repository that descends from a (trusted) Trust Anchor can serve (via rsync or RRDP) a resource certificate containing an [Authority Key Identifier extension](https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.1) missing the `keyIdentifier` field. Fort was referencing the pointer without sanitizing it first. |
| Impact | Crash. (Potential unavailability of Route Origin Validation.) |
| Patch | Commit [b1eb3c5](https://github.com/NICMx/FORT-validator/commit/b1eb3c507ae920859bbe294776ebc2bb30bb7e56), released in Fort 1.6.3. |
| Acknowledgments | Thanks to Niklas Vogel and Haya Schulmann for their research and disclosure. |

## CVE-2024-45236

Signed Object containing empty `signedAttrs` crashes Fort 1.6.2-.

| Description | A malicious RPKI repository that descends from a (trusted) Trust Anchor can serve (via rsync or RRDP) a signed object containing an empty [`signedAttributes`](https://datatracker.ietf.org/doc/html/rfc6488#section-2.1.6.4). Fort was accessing the set's elements without sanitizing it first. |
| Impact | Crash. (Potential unavailability of Route Origin Validation.) |
| Patch | Commit [4dafbd9](https://github.com/NICMx/FORT-validator/commit/4dafbd9de64a5a0616af97365bc1751465b29d2e), released in Fort 1.6.3. |
| Acknowledgments | Thanks to Niklas Vogel and Haya Schulmann for their research and disclosure. |

## CVE-2024-45239

Signed Object containing null `eContent` crashes Fort 1.6.2-.

| Description | A malicious RPKI repository that descends from a (trusted) Trust Anchor can serve (via rsync or RRDP) a ROA or Manifest containing a null [`eContent`](https://datatracker.ietf.org/doc/html/rfc6488#section-2.1.3.2). Fort was dereferencing the pointer without sanitizing it first. |
| Impact | Crash. (Potential unavailability of Route Origin Validation.) |
| Patch | Commit [942f921](https://github.com/NICMx/FORT-validator/commit/942f921ba7244cdcf4574cedc4c16392a7cc594b), released in Fort 1.6.3. |
| Acknowledgments | Thanks to Niklas Vogel and Haya Schulmann for their research and disclosure. |

## CVE-2024-45234

Certificate containing `signedAttrs` not in canonical form crashes Fort 1.6.2-.

| Description | A malicious RPKI repository that descends from a (trusted) Trust Anchor can serve (via rsync or RRDP) a ROA or Manifest containing a `signedAttrs` encoded in non-canonical form. This bypassed the BER-decoder, reaching a point in the code that panicked when faced with data not encoded in DER. |
| Impact | Crash. (Potential unavailability of Route Origin Validation.) |
| Patch | Commit [521b1a0](https://github.com/NICMx/FORT-validator/commit/521b1a0db5041258096fbabdf8fc1e10ecc793cf), released in Fort 1.6.3. |
| Acknowledgments | Thanks to Niklas Vogel and Haya Schulmann for their research and disclosure. |
45 changes: 12 additions & 33 deletions docs/_layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@
<div class="navigation">
<nav class="site-nav">
<ul>
<li>
<a class="active-item" href="./index.html">FORT Validator</a>
</li>
<li><a class="active-item" href="./index.html">FORT Validator</a></li>
</ul>
</nav>

Expand All @@ -54,36 +52,17 @@
<div class="col-lg-3">
<aside class="site-aside">
<ul class="list-bullet">
<li>
<a class="item-menu{% if page.url == '/' or page.url == '/index.html' %} active{% endif %}" href="index.html">Home</a>
</li>
<li>
<a class="item-menu{% if page.url == '/intro-rpki.html' %} active{% endif %}" href="intro-rpki.html">Introduction to RPKI</a>
</li>
<li>
<a class="item-menu{% if page.url == '/intro-fort.html' %} active{% endif %}" href="intro-fort.html">Introduction to Fort</a>
</li>
<li>
<a class="item-menu{% if page.url == '/installation.html' %} active{% endif %}" href="installation.html">Compilation and Installation</a>
</li>
<li>
<a class="item-menu{% if page.url == '/run.html' %} active{% endif %}" href="run.html">Basic Usage</a>
</li>
<li>
<a class="item-menu{% if page.url == '/usage.html' %} active{% endif %}" href="usage.html">Program Arguments</a>
</li>
<li>
<a class="item-menu{% if page.url == '/logging.html' %} active{% endif %}" href="logging.html">Logging</a>
</li>
<li>
<a class="item-menu{% if page.url == '/slurm.html' %} active{% endif %}" href="slurm.html">SLURM</a>
</li>
<li>
<a class="item-menu{% if page.url == '/incidence.html' %} active{% endif %}" href="incidence.html">Incidences</a>
</li>
<li>
<a class="item-menu{% if page.url == '/routers.html' %} active{% endif %}" href="routers.html">Routers</a>
</li>
<li><a class="item-menu{% if page.url == '/' or page.url == '/index.html' %} active{% endif %}" href="index.html">Home</a></li>
<li><a class="item-menu{% if page.url == '/intro-rpki.html' %} active{% endif %}" href="intro-rpki.html">Introduction to RPKI</a></li>
<li><a class="item-menu{% if page.url == '/intro-fort.html' %} active{% endif %}" href="intro-fort.html">Introduction to Fort</a></li>
<li><a class="item-menu{% if page.url == '/installation.html' %} active{% endif %}" href="installation.html">Compilation and Installation</a></li>
<li><a class="item-menu{% if page.url == '/run.html' %} active{% endif %}" href="run.html">Basic Usage</a></li>
<li><a class="item-menu{% if page.url == '/usage.html' %} active{% endif %}" href="usage.html">Program Arguments</a></li>
<li><a class="item-menu{% if page.url == '/logging.html' %} active{% endif %}" href="logging.html">Logging</a></li>
<li><a class="item-menu{% if page.url == '/slurm.html' %} active{% endif %}" href="slurm.html">SLURM</a></li>
<li><a class="item-menu{% if page.url == '/incidence.html' %} active{% endif %}" href="incidence.html">Incidences</a></li>
<li><a class="item-menu{% if page.url == '/routers.html' %} active{% endif %}" href="routers.html">Routers</a></li>
<li><a class="item-menu{% if page.url == '/CVE.html' %} active{% endif %}" href="CVE.html">CVEs</a></li>
</ul>
</aside>
</div>
Expand Down
34 changes: 25 additions & 9 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ description: Guide to use arguments of FORT Validator.
51. [`--rsync.priority`](#--rsyncpriority)
53. [`--rsync.retry.count`](#--rsyncretrycount)
54. [`--rsync.retry.interval`](#--rsyncretryinterval)
40. [`--rsync.transfer-timeout`](#--rsynctransfer-timeout)
55. [`--configuration-file`](#--configuration-file)
56. [`rsync.program`](#rsyncprogram)
57. [`rsync.arguments-recursive`](#rsyncarguments-recursive)
Expand Down Expand Up @@ -103,6 +104,7 @@ description: Guide to use arguments of FORT Validator.
[--rsync.priority=<unsigned integer>]
[--rsync.retry.count=<unsigned integer>]
[--rsync.retry.interval=<unsigned integer>]
[--rsync.transfer-timeout=<unsigned integer>]
[--http.enabled=true|false]
[--http.priority=<unsigned integer>]
[--http.retry.count=<unsigned integer>]
Expand Down Expand Up @@ -305,6 +307,7 @@ Assuming not much time has passed since the last time the repository was cached,

- **Type:** Boolean (`true`, `false`)
- **Availability:** `argv` and JSON
- **Default:** `false`

Skip the repository cache update?

Expand All @@ -316,6 +319,7 @@ Mostly intended for debugging. See [`--rsync.enabled`](#--rsyncenabled) and [`--

- **Type:** Boolean (`true`, `false`)
- **Availability:** `argv` and JSON
- **Default:** `false`

Send process to the background?

Expand Down Expand Up @@ -646,7 +650,7 @@ See [`--rsync.priority`](#--rsyncpriority).

- **Type:** Integer
- **Availability:** `argv` and JSON
- **Default:** 0
- **Default:** 1
- **Range:** [0, [`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)]

Number of additional HTTP requests after a failed attempt.
Expand All @@ -657,7 +661,7 @@ If a transient error is returned when Fort tries to perform an HTTP transfer, it

- **Type:** Integer
- **Availability:** `argv` and JSON
- **Default:** 5
- **Default:** 4
- **Range:** [0, [`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)]

Period of time (in seconds) to wait between each retry to request an HTTP URI.
Expand Down Expand Up @@ -704,7 +708,7 @@ The value specified (either by the argument or the default value) is utilized in

- **Type:** Integer
- **Availability:** `argv` and JSON
- **Default:** 0
- **Default:** 900
- **Range:** [0, [`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)]

_**All requests are made using HTTPS, verifying the peer and the certificate name vs host**_
Expand Down Expand Up @@ -774,6 +778,7 @@ Watch out for the following warning in the operation logs:

- **Type:** String (Path to directory)
- **Availability:** `argv` and JSON
- **Default:** `NULL` (disabled)

_**All requests are made using HTTPS, verifying the peer and the certificate name vs host**_

Expand All @@ -790,6 +795,7 @@ The value specified is utilized in libcurl's option [CURLOPT_CAPATH](https://cur

- **Type:** String (Path to file)
- **Availability:** `argv` and JSON
- **Default:** `NULL` (disabled)

File where the ROAs (found during each validation run) will be stored. See [`--output.format`](#--outputformat).

Expand Down Expand Up @@ -822,6 +828,7 @@ If `--output.roa` is omitted, the ROAs are not printed.

- **Type:** String (Path to file)
- **Availability:** `argv` and JSON
- **Default:** `NULL` (disabled)

> ![Warning!](img/warn.svg) BGPsec certificate validation has been disabled in version 1.5.2 because of [this bug](https://github.com/NICMx/FORT-validator/issues/58).
Expand Down Expand Up @@ -913,7 +920,7 @@ See [`--http.priority`](#--httppriority).

- **Type:** Integer
- **Availability:** `argv` and JSON
- **Default:** 0
- **Default:** 1
- **Range:** [0, [`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)]

Maximum number of retries whenever there's an error executing an RSYNC.
Expand All @@ -926,15 +933,27 @@ Whenever is necessary to execute an RSYNC, the validator will try at least one t

- **Type:** Integer
- **Availability:** `argv` and JSON
- **Default:** 5
- **Default:** 4
- **Range:** [0, [`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)]

Period of time (in seconds) to wait between each retry to execute an RSYNC.

### `--rsync.transfer-timeout`

- **Type:** Integer
- **Availability:** `argv` and JSON
- **Default:** 900
- **Range:** [0, [`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)]

Maximum time in seconds that the rsync transfer can last.

Once the connection is established with the server, the request will last a maximum of `rsync.transfer-timeout` seconds. A value of 0 means unlimited time.

### `--configuration-file`

- **Type:** String (Path to file)
- **Availability:** `argv` only
- **Default:** `NULL` (disabled)

Path to a JSON file from which additional configuration will be read.

Expand Down Expand Up @@ -974,6 +993,7 @@ The configuration options are mostly the same as the ones from the `argv` interf
"<a href="#--rsyncretrycount">count</a>": 1,
"<a href="#--rsyncretryinterval">interval</a>": 4
},
"<a href="#--rsynctransfer-timeout">transfer-timeout</a>": 0,
"<a href="#rsyncprogram">program</a>": "rsync",
"<a href="#rsyncarguments-recursive">arguments-recursive</a>": [
"-rtz",
Expand Down Expand Up @@ -1146,7 +1166,6 @@ Does nothing as of Fort 1.6.0.

- **Type:** Integer
- **Availability:** `argv` and JSON
- **Default:** 43200 (12 hours)
- **Range:** [0, [`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)]

> ![img/warn.svg](img/warn.svg) This argument **is DEPRECATED**.
Expand All @@ -1157,7 +1176,6 @@ Does nothing as of Fort 1.6.0.

- **Type:** Enumeration (`strict`, `root`, `root-except-ta`)
- **Availability:** `argv` and JSON
- **Default:** `root-except-ta`

> ![img/warn.svg](img/warn.svg) This argument **is DEPRECATED**.
Expand All @@ -1167,7 +1185,6 @@ Does nothing as of Fort 1.6.0.

- **Type:** String array
- **Availability:** JSON only
- **Default:** `[ "--times", "--contimeout=20", "--timeout=15", "--max-size=20MB", "--dirs", "$REMOTE", "$LOCAL" ]`

> ![img/warn.svg](img/warn.svg) This argument **is DEPRECATED**.
Expand All @@ -1177,7 +1194,6 @@ Does nothing as of Fort 1.6.0.

- **Type:** Integer
- **Availability:** `argv` and JSON
- **Default:** 5
- **Range:** [1, 100]

> ![img/warn.svg](img/warn.svg) This argument **is DEPRECATED**.
Expand Down
1 change: 1 addition & 0 deletions examples/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"count": 2,
"interval": 5
},
"transfer-timeout": 900,
"program": "rsync",
"arguments-recursive": [
"--recursive",
Expand Down
16 changes: 14 additions & 2 deletions man/fort.8
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.TH fort 8 "2024-05-24" "v1.6.2" "FORT validator"
.TH fort 8 "2024-08-19" "v1.6.3" "FORT validator"

.SH NAME
fort \- RPKI validator and RTR server
Expand Down Expand Up @@ -813,7 +813,7 @@ unlimited time (default value).
The value specified (either by the argument or the default value) is utilized
in libcurl’s option \fICURLOPT_TIMEOUT\fR.
.P
By default, it has a value of \fI0\fR.
By default, it has a value of \fI900\fR.
.RE
.P

Expand Down Expand Up @@ -1022,6 +1022,18 @@ By default, the value is \fI5\fR.
.RE
.P

.B \-\-rsync.transfer\-timeout=\fIUNSIGNED_INTEGER\fR
.RS 4
Maximum time in seconds that the rsync process can last.
.P
Once the connection is established with the server, the request will last a
maximum of \fBrsync.transfer-timeout\fR seconds. A value of \fI0\fR means
unlimited time (default value).
.P
By default, it has a value of \fI900\fR.
.RE
.P

.B \-\-output.roa=\fIFILE\fR
.RS 4
File where the ROAs will be printed in the configured format (see
Expand Down
Loading

0 comments on commit c7be17b

Please sign in to comment.