]> git.ipfire.org Git - thirdparty/FORT-validator.git/log
thirdparty/FORT-validator.git
14 months agoagregada rtrlib en la imagen de docker 111/head
Carlos Martinez [Thu, 18 Apr 2024 11:28:42 +0000 (11:28 +0000)] 
agregada rtrlib en la imagen de docker

15 months agoFix date parsing from TAL cachefiles
Alberto Leiva Popper [Fri, 15 Mar 2024 22:44:07 +0000 (16:44 -0600)] 
Fix date parsing from TAL cachefiles

The code was writing dates in Zulu format, which was fine. But then, to
read them back, it was loading them with mktime(), which is a local
timezone function. The effects of this bug depend on the time zone.
Files would expire from the cache up to 12 hours too early (UTC+) or
late (UTC-), or be updated up to 12 hours late (UTC-). (There's no such
thing as "updating too early" in this context, since Fort cannot refresh
before the present.)

I fixed this by swapping mktime() for timegm(), which is not great,
because the latter is still a nonstandard function. But it'll have to
do, because the other options are worse.

Below is my thought process on timegm() and the other options:

==================================================

Problem:

1. I want to store timestamps as human-readable strings.
2. Converting a timestamp to Zulu string is trivial: time_t ->
   gmtime_r() -> struct tm (GMT) -> strftime() -> char*.
3. But converting a string to timestamp relies on timegm(), which is
   nonstandard: char* -> strptime() -> struct tm (GMT) -> timegm() ->
   time_t.

Brainstorm:

1. Store the dates in local time.

Hideous option, but not ENTIRELY insane.

Storing in local time will render the dates up to 24 hours off, I think.
But this only happens when the cache changes timezone, which isn't
really often.

But it's still pretty clumsy, and also not future-proof, as new date
fields would have to be constrained by the same limitation.

2/10 at best.

2. Ditch time_t, use struct tm in UTC for everything.

So I would rely on gmtime_r() only to get out of time_t, and never need
timegm() for anything.

Comparing field by field would be a pain, but it's interesting to note
that Fort is actually already doing it somewhere: tm_cmp(). I guess I
have to admire the audaciousness of past me.

What mainly scares me is that mktime() seems to be the only standard
function that is contractually obligated to normalize the tm, which
means I would have to keep mktime()ing every time I need to compare
them.

And mktime() is... a local time function. Probably wouldn't actually
work.

4/10. I hate this API.

3. Bite the bullet: Go modern POSIX; assume time_t is integer seconds
   since the 1970 epoch.

I'm fantasizing about an early environment assertion that checks the
gmtime_r() for a known time_t, that shows people the door if the
implementation isn't sane. Would work even in POSIX-adjacent systems
like most Linuxes.

This would have other benefits, like the ability to ditch difftime(),
and perform arithmetic operations on time_t's.

All the officially supported platforms get this aspect of POSIX right,
so what's stopping me?

Well, it would mean I would have to store the date as a seconds-since-
epoch integer, which is not as human-friendly and defeats the whole
point of the JSON format.

And yet... this feels so right, I might end up doing it even regardless
of the JSON data type and timegm().

But not today. 7/10.

4. Bite the bullet: Use timegm().

Interesting. timegm() might be added to C23:

> Changes integrated into the latest working draft of C23 are listed
> below.
> (...)
> - Add timegm() function in <time.h> to convert time structure into
> calendar time value - similar to function in glibc and musl libraries.

https://en.wikipedia.org/wiki/C23_(C_standard_revision)

So this has some probability of not needing future tweaking. Also, it's
very clean. (Except for the feature test macros.)

8/10.

16 months agoFix bad usage of strtol()
Alberto Leiva Popper [Sat, 24 Feb 2024 01:18:55 +0000 (19:18 -0600)] 
Fix bad usage of strtol()

Someone didn't RTFM.

1. Error code wasn't being catched.
2. Second argument was NULL, so the caller had no way of knowing
   whether the string was fully consumed.
2. The code wasn't making sure the input was a clean hex string.
3. The input string wasn't NULL-terminated.

In the end, I ditched strtol(). It's too dangerous and cluttered for
this purpose.

16 months agoMerge branch 'job-main'
Alberto Leiva Popper [Fri, 23 Feb 2024 16:11:41 +0000 (10:11 -0600)] 
Merge branch 'job-main'

16 months agoUpdate comment 109/head
Job Snijders [Fri, 23 Feb 2024 12:59:54 +0000 (12:59 +0000)] 
Update comment

At this point in time I'm not aware of specific differences between
LibreSSL and OpenSSL in relationship to RFC 6487.

16 months agoUpdate comment
Job Snijders [Fri, 23 Feb 2024 12:51:35 +0000 (12:51 +0000)] 
Update comment

16 months agoWarn if server.address has more than one wildcard
Alberto Leiva Popper [Thu, 8 Feb 2024 21:58:25 +0000 (15:58 -0600)] 
Warn if server.address has more than one wildcard

Consider the following three definitions of server.address:

[a] "address": [ "0.0.0.0" ]
[b] "address": [ "::" ]
[c] "address": [ "0.0.0.0", "::" ]

We expect [a] to bind the socket to any IPv4 address,
[b] to bind the socket to any IPv6 address,
and [c] to bind the socket to any IPv4 and IPv6 address.

Right? The BSDs work that way.

But Linux doesn't. For Linux,

[a] binds to any IPv4 address,
[b] binds to any IPv4 and IPv6 address,
and [c] is an error.

But I don't want to override the behavior because some admins are
probably used to it:

linux$ nc -6lknv :: 7890
Listening on :: 7890
Connection received on ::1 52814
Hello from IPv6!
Connection received on ::ffff:127.0.0.1 55456
Hello from IPv4!

Instead, let's print a warning.

Thanks to Benjamim Pinheiro for reporting this quirk.

16 months agoRTR server bind review
Alberto Leiva Popper [Thu, 8 Feb 2024 21:29:35 +0000 (15:29 -0600)] 
RTR server bind review

- Hint SOCK_STREAM on getaddrinfo(), not on socket().
  I guess this means it was attempting some redundant binds on failure?
- Print the "Attempting to bind socket to address '%s', port '%s'"
  message in every addrinfo, not just the first one. (Improves log
  legibility.)
- Improve the algorithm that produces the printable version of the
  address (used to dereference ai_addr->sa_data like the previous
  commit), and fall back to whatever the user provided if it fails.
- Weird inconsistency: Most errors used to cause create_server_socket()
  to try the next addrinfo candidate, but getsockname() and listen()
  induced immediate abortion. I've no idea what that was about;
  getsockname() isn't even a mandatory step.
- Attempt to bind all addrinfo candidates; they must all succeed.
  (It used to stop on the first success.)

I'm conflicted with the last point. The old behavior appears to have
been inherited from the Linux manual page example, but doesn't make any
sense from where I'm standing.

If `/etc/hosts` defines

127.0.0.1    localhost
::1          localhost

And server.address is "localhost", shouldn't we attempt to bind to both
addresses?

16 months agoRemove > 65535 validation from --server.port
Alberto Leiva Popper [Wed, 7 Feb 2024 19:08:09 +0000 (13:08 -0600)] 
Remove > 65535 validation from --server.port

While trying to implement the upcoming patch, I found myself trying to
refactor this validation. The implementation was awkward; instead of
ntohs'ing sockaddr_in.sin_port, it extracted the bytes manually:

port = (unsigned char)((*result)->ai_addr->sa_data[0]) << 8;
port += (unsigned char)((*result)->ai_addr->sa_data[1]);

But on second thought, I'm not seeing this validation eye to eye.
It's intended to prevent `getaddrinfo()` from parsing
`--server.port=120000` like `--server.port=54464` (120000 % 65536) on
Linux, but... thing is, this "port out of bounds" quirk looks like an
everyday Linux idiosyncrasy.

Linux being Linux:

$ nc -lv 127.0.0.1 120000
Listening on localhost 54464

It's weird but seems inoffensive, and some beardos might even expect it.

`getaddrinfo()` returns proper errors in the BSDs, so the validation is
redundant there.

16 months agos/fort-validator@nic.mx/validadorfort@fortproject.net/g
Alberto Leiva Popper [Wed, 7 Feb 2024 17:03:02 +0000 (11:03 -0600)] 
s/fort-validator@nic.mx/validadorfort@fortproject.net/g

Curious. It looks like we've had both aliases since forever, and they
have the same purpose.

They both work, but I don't have any control over the former anymore.
So let's phase it out.

17 months agoMake sure d2i_X509() consumed all data 108/head
Job Snijders [Mon, 5 Feb 2024 19:10:11 +0000 (19:10 +0000)] 
Make sure d2i_X509() consumed all data

An artefact of d2i_*() functions is that once they're satisfied,
there still might be trailing garbage in the field that's being
decoded.

Callers of d2i_*() functions generally should conform that all
data has been consumed.

17 months agoTreat X509_ALGOR as opaque structure 107/head
Theo Buehler [Fri, 19 Jan 2024 13:36:47 +0000 (14:36 +0100)] 
Treat X509_ALGOR as opaque structure

Unfortunately, X509_ALGOR is still a public struct, and it only has the
slightly awkward accessor X509_ALGOR_get0(), already used elsewhere in
FORT. This converts two codepaths that reach into the struct to using
X509_ALGOR_get0() so that X509_ALGOR can be made opaque in the future.

17 months agoFix header version for Code 4 Error PDUs
Alberto Leiva Popper [Mon, 15 Jan 2024 16:47:13 +0000 (10:47 -0600)] 
Fix header version for Code 4 Error PDUs

Fixes #106.

18 months agoUpdate Docker
Alberto Leiva Popper [Sat, 16 Dec 2023 00:10:31 +0000 (18:10 -0600)] 
Update Docker

18 months agoProtocolary updates for release 1.6.1 1.6.1
Alberto Leiva Popper [Thu, 14 Dec 2023 21:49:29 +0000 (15:49 -0600)] 
Protocolary updates for release 1.6.1

18 months agoCreate tmp/ before CACHEDIR.TAG
Alberto Leiva Popper [Wed, 13 Dec 2023 22:24:15 +0000 (16:24 -0600)] 
Create tmp/ before CACHEDIR.TAG

tmp/'s creation is (C's equivalent of) a `mkdir -p`. It ensures the
cache directory exists by the time Fort attempts to create CACHEDIR.TAG.

18 months agoImprove HTTP info logging
Alberto Leiva Popper [Wed, 13 Dec 2023 21:40:35 +0000 (15:40 -0600)] 
Improve HTTP info logging

Before:

  Downloading 'https://test.rpki/notification.xml'.
  HTTP GET: https://test.rpki/notification.xml -> cache/tmp/1

The first line was redundant, and the target wasn't very helpful.

Now:

  HTTP GET: https://test.rpki/notification.xml -> cache/test.tal/https/test.rpki/notification.xml

18 months agoMerge branch 'job-main'
Alberto Leiva Popper [Wed, 13 Dec 2023 18:01:59 +0000 (12:01 -0600)] 
Merge branch 'job-main'

18 months agoDisable normal error messages during tests
Alberto Leiva Popper [Tue, 12 Dec 2023 22:58:28 +0000 (16:58 -0600)] 
Disable normal error messages during tests

These error messages weren't showing up because of failing assertions;
it was because the tests were checking error pipelines.

Hide them by default. They can be restored in a pinch by compiling with
-DPRINT_PRS ("-D print prints"):

CFLAGS=-DPRINT_PRS make check

Pending work from #101.

18 months agoCreate CACHEDIR.TAG during cache initialization
Alberto Leiva Popper [Tue, 12 Dec 2023 21:16:39 +0000 (15:16 -0600)] 
Create CACHEDIR.TAG during cache initialization

To hint backup software not to copy the cache.
https://bford.info/cachedir/

Fixes #104.

19 months agoEmpty cache whenever Fort's version changes
Alberto Leiva Popper [Tue, 5 Dec 2023 21:16:21 +0000 (18:16 -0300)] 
Empty cache whenever Fort's version changes

Because people might have missed the release notes, and also because I
expect to keep improving the cache code, possibly in ways that are not
backwards compatible.

Case in point: I already had to tweak the TAL metadata file in the
previous commit.

I will probably downgrade this to something less aggressive later.

19 months agoStop trying to cage non-notification URLs during cleanup
Alberto Leiva Popper [Tue, 5 Dec 2023 13:01:33 +0000 (10:01 -0300)] 
Stop trying to cage non-notification URLs during cleanup

Fixes the new issue reported in #103.

19 months agoStop printing logging severity in syslog
Alberto Leiva Popper [Mon, 4 Dec 2023 22:02:05 +0000 (19:02 -0300)] 
Stop printing logging severity in syslog

Second half of #103.

19 months agoRemove the log switching cacophony on startup
Alberto Leiva Popper [Mon, 4 Dec 2023 20:56:54 +0000 (17:56 -0300)] 
Remove the log switching cacophony on startup

Resolves the first complaint of #103:

> I believe that if syslog output is enabled on the command line then
> fort should be able to not report these useless messages about
> switching the output back and forward.
>
> Also, there is no point in reporting in syslog that messages are
> being sent to syslog and on the console that messages are being sent
> to the console because this is self-evident.

Looking back at the history, it seems these messages were born because
a long time ago, sys-logging was hardcoded to "server" mode, while
console "logging" was tied to "standalone" mode. Default was "server,"
which meant a newcomer who managed to kickstart Fort in the foreground
with minimal arguments ended up with a validator that, on account of
looking silent, seemed to be doing absolutely nothing.

Given than logmode and runmode are completely independent now, and log
output defaults to "console," it would appear that these messages are,
as a matter of fact, completely useless.

19 months agoStop dropping old deltas when there are no new deltas
Alberto Leiva Popper [Mon, 4 Dec 2023 20:25:38 +0000 (17:25 -0300)] 
Stop dropping old deltas when there are no new deltas

__vrps_update() wasn't properly differentiating between a validation
cycle that errored from one that generated no deltas. Both were being
handled as failure.

Therefore, Fort might have been inducing more RTR Cache Resets than it
was supposed to. Although, iterations in which no deltas are generated
seem to be rare.

The removal of surplus error propagation in the previous commit
revealed that compute_deltas() cannot actually fail, which made
the solution here trivial.

19 months agoFix compilation on Mac OS
Alberto Leiva Popper [Mon, 4 Dec 2023 18:55:06 +0000 (15:55 -0300)] 
Fix compilation on Mac OS

Not really trying to add formal support for Mac OS at the moment;
this is just to be able to debug a little more efficiently in this
laptop I'm stuck with right now.

19 months agoTake advantage of autotools in BSD environments 102/head
Job Snijders [Mon, 4 Dec 2023 12:56:35 +0000 (12:56 +0000)] 
Take advantage of autotools in BSD environments

Taken from https://github.com/bgp/bgpq4/blob/main/bootstrap

19 months agoFix default rsync arguments in the documentation
Alberto Leiva Popper [Mon, 4 Dec 2023 07:06:36 +0000 (04:06 -0300)] 
Fix default rsync arguments in the documentation

Looks like these got messed up during the merge.

19 months agoRemove usage of newer check API
Alberto Leiva Popper [Mon, 4 Dec 2023 06:10:41 +0000 (03:10 -0300)] 
Remove usage of newer check API

The distant virtual machine I used to replicate #101 had what I assume
is an older version of check, so I had to tweak some validations.

Looks like I have to expand my VM repertoire.

19 months agoImprove portability of timestamps in JSON
Alberto Leiva Popper [Mon, 4 Dec 2023 06:03:14 +0000 (03:03 -0300)] 
Improve portability of timestamps in JSON

It looks like %F, %T and %z are not portable conversion specification
characters for strptime() and strftime(). Therefore, change date format
from "%FT%T%z" to "%Y-%m-%dT%H:%M:%SZ".

This means the JSON now employs Zulu, which also fixes a unit test that
used to be hardcoded to my own timezone. Yaay.

Fixes #101.

19 months agoUpdate Docker
Alberto Leiva Popper [Fri, 1 Dec 2023 04:30:50 +0000 (22:30 -0600)] 
Update Docker

Alpine no longer supports libexecinfo...

19 months agoProtocolary updates for release 1.6.0 1.6.0
Alberto Leiva Popper [Wed, 29 Nov 2023 23:43:04 +0000 (17:43 -0600)] 
Protocolary updates for release 1.6.0

19 months agoAllow some nulls in the configuration JSON
Alberto Leiva Popper [Wed, 29 Nov 2023 23:13:22 +0000 (17:13 -0600)] 
Allow some nulls in the configuration JSON

While playing with the configuration sample, I found out that setting
a `null` slurm property in the JSON was rejected, even though the SLURM
file itself is not mandatory.

So rethink this, and for a few other fields as well.

19 months agoFix unit tests in the BSDs
Alberto Leiva Popper [Wed, 29 Nov 2023 18:03:03 +0000 (12:03 -0600)] 
Fix unit tests in the BSDs

...Except for the __VA_ARGS__ warning. That can wait.

19 months agoMerge branch 'main' into fort-1.6.0
Alberto Leiva Popper [Tue, 28 Nov 2023 17:14:06 +0000 (11:14 -0600)] 
Merge branch 'main' into fort-1.6.0

19 months agoRemove unrecognized files during cache cleanup
Alberto Leiva Popper [Sat, 25 Nov 2023 22:22:55 +0000 (16:22 -0600)] 
Remove unrecognized files during cache cleanup

Before, it used to clean old abandoned files, and nodes for which the
files seemed to have disappeared. Now it also deletes files for which
the node seems to have disappeared.

Been postponing this tweak since ee47fe9d43614a929d591ba6039d751d7577070d.

19 months agoMirror #100 in the documentation
Alberto Leiva Popper [Fri, 24 Nov 2023 17:12:13 +0000 (11:12 -0600)] 
Mirror #100 in the documentation

19 months agoDon't set directory modtimes to match the source 100/head
Job Snijders [Fri, 24 Nov 2023 09:46:37 +0000 (09:46 +0000)] 
Don't set directory modtimes to match the source

When syncing against remote repositories, the modtimes of the
remote directories is irrelevant. In the RRDP protocol the directory
modtimes aren't signalled either. This should save some IOPS.

19 months agoPatch FIXME: Call cache_cleanup() on the regular
Alberto Leiva Popper [Thu, 23 Nov 2023 18:59:30 +0000 (12:59 -0600)] 
Patch FIXME: Call cache_cleanup() on the regular

I realized I don't have much reason to not call it at the end of every
validation cycle. It's not particularly slow, and it doesn't do anything
risky.

19 months agoPatch FIXME: Review usage of enomem_panic()
Alberto Leiva Popper [Thu, 23 Nov 2023 17:59:56 +0000 (11:59 -0600)] 
Patch FIXME: Review usage of enomem_panic()

Geezus.

I'm finding lots of problems with the error reports:

- Some error messages are getting logged with what appears to be the
  wrong severity, variant (normal vs libcrypto) or type (val vs op).
  Also, the line between val and op is sometimes blurry.
- Some error messages are extremely ambiguous, which makes them useless.
  It's hard to fix them because they tend to be caused by library utils
  that either refuse to spit details, or export them through
  undocumented, unreliable and/or inconsistent means.
- Another consequence of the generic errors is that it's hard to tell
  the ENOMEMs apart, which sucks because we're supposed to handle them
  differently.
- Some error messages aren't printing the offending function arguments,
  which will make them hard to debug when they happen.

I'm anticipating another redesign of the framework, but I'm also trying
very hard not to do any new major rewrites before the next release.

19 months agoRegular update of system #includes
Alberto Leiva Popper [Wed, 22 Nov 2023 17:00:27 +0000 (11:00 -0600)] 
Regular update of system #includes

19 months agoSynchronize rsync modules instead of RPPs again
Alberto Leiva Popper [Sun, 19 Nov 2023 23:57:33 +0000 (17:57 -0600)] 
Synchronize rsync modules instead of RPPs again

rsync-ing every RPP separately is prohibitely expensive when RRDP is
unavailable.

As it turns out, rsync-ing the repository root happens to be an
unwritten standard. Fort was far from the only one doing it, and people
expect it.

This means I will eventually have to come up with a different way to box
RRDP RPPs, as the current implementation induces too many redownloads
when rsync needs to be fall-backed into.

I will have to leave that outside of 1.6.0 however, as I've fixed too
much stuff already, and I need a new release urgently.

Sort of reverts #80, though the flag will remain deleted. I don't think
there's a point in offloading this decision to the user.

19 months agoPatch some memory leaks
Alberto Leiva Popper [Fri, 17 Nov 2023 22:04:28 +0000 (16:04 -0600)] 
Patch some memory leaks

19 months agoImplement HTTP redirects
Alberto Leiva Popper [Fri, 17 Nov 2023 19:14:46 +0000 (13:14 -0600)] 
Implement HTTP redirects

Fixes #71.

19 months agoBump version number already
Alberto Leiva Popper [Thu, 16 Nov 2023 17:32:35 +0000 (11:32 -0600)] 
Bump version number already

19 months agoAdjust metadata.json's namespace
Alberto Leiva Popper [Thu, 16 Nov 2023 02:37:15 +0000 (20:37 -0600)] 
Adjust metadata.json's namespace

Rename some tags:

"flags" -> "direct-download", "successful-download", "is-file"
"ts_success" -> "success-timestamp"
"ts_attempt" -> "attempt-timestamp"
"error" -> "latest-result"

Only "basename" is mandatory now.

Also, move JSON operations to the JSON module.

19 months agoWrite metadata.json whenever validation iteration ends
Alberto Leiva Popper [Wed, 15 Nov 2023 18:30:39 +0000 (12:30 -0600)] 
Write metadata.json whenever validation iteration ends

The file was only being written during cache cleanup, which wasn't often
enough.

19 months agostat() to find out if a file is cached in offline mode
Alberto Leiva Popper [Tue, 14 Nov 2023 22:39:18 +0000 (16:39 -0600)] 
stat() to find out if a file is cached in offline mode

The offline code used to assume files were always cached when
--http.enabled/--rsync.enabled were false.

Now it returns a more informed answer, depending on whether the file is
actually cached.

With this, offline mode more closely resembles online mode.

19 months agoImprove HTTP 204 error message
Alberto Leiva Popper [Tue, 14 Nov 2023 21:41:23 +0000 (15:41 -0600)] 
Improve HTTP 204 error message

Looks like Afrinic disabled RRDP, and they're returning 204 instead of
4xx or 5xx.

This was fooling Fort into thinking the file downloaded successfully,
which induced a crappier error message.

But regardless of Afrinic, an empty file is not a valid RPKI file,
so 204 (No Content) should probably be handled as an error anyway.

19 months agoRemove tmp directory step from --init-tals/--init-as0-tals
Alberto Leiva Popper [Tue, 14 Nov 2023 21:41:11 +0000 (15:41 -0600)] 
Remove tmp directory step from --init-tals/--init-as0-tals

The code that handles these flags does not run with a cache context,
so the temporal file step was causing cache download issues despite
being completely unneeded.

19 months agoPatch FIXME: Fix concurrency in local cache
Alberto Leiva Popper [Tue, 14 Nov 2023 00:17:38 +0000 (18:17 -0600)] 
Patch FIXME: Fix concurrency in local cache

Tried to protect access via mutex, but oh boy. That escalated quickly.

Instead, restore tree workspace isolation. Since the 1-thread-per-TAL
architecture has survived, this allows the validation to merrily read
and write the local cache without any locking.

Each thread now builds its own resource table. The main thread joins
them.

This basically zeroizes resource sharing between validation threads.
Great from an engineering perspective, maybe not so much from the
performance angle.

19 months agoImprove selection of cache RPP fallback
Alberto Leiva Popper [Sun, 12 Nov 2023 18:27:20 +0000 (12:27 -0600)] 
Improve selection of cache RPP fallback

Corner case. Suppose the cache has (for whatever reason) downloaded the
two following URLs separately:

rsync://a.b.c/d
rsync://a.b.c/d/e/f

(This might happen if the latter is downloaded in one iteration, then
the former is downloaded the next, and the cleanup timer hasn't kicked
in yet.)

This commit extends the existing priority selection algorithm to this
situation.

(The old way was to choose the most specific URL, which would go on to
lose to a different URL which might have lost to the less specific
version.)

Honestly, this is a micro-correction. It hopefully slightly increases
the chances of the cache fallback being useful in very specific unusual
situations, rather than guarantee it. But it's more consistent, future-
proof and looks more sensible in the tests.

19 months agoUpdate flags documentation
Alberto Leiva Popper [Fri, 10 Nov 2023 17:27:13 +0000 (11:27 -0600)] 
Update flags documentation

19 months agoFix new RRDP memory leak
Alberto Leiva Popper [Fri, 10 Nov 2023 16:48:05 +0000 (10:48 -0600)] 
Fix new RRDP memory leak

Introduced by 6d8081c992da9d677e3bd9cdf21bb63e604f0b4d.

19 months agoPatch FIXME: Delete existing RPP before expanding snapshot
Alberto Leiva Popper [Fri, 10 Nov 2023 00:01:44 +0000 (18:01 -0600)] 
Patch FIXME: Delete existing RPP before expanding snapshot

19 months agoPatch FIXME: Fall back to snapshot when deltas fail
Alberto Leiva Popper [Thu, 9 Nov 2023 23:51:43 +0000 (17:51 -0600)] 
Patch FIXME: Fall back to snapshot when deltas fail

19 months agoPatch TODO: Change RRDP serials into BIGNUMs
Alberto Leiva Popper [Wed, 8 Nov 2023 23:14:12 +0000 (17:14 -0600)] 
Patch TODO: Change RRDP serials into BIGNUMs

Serials used to be unsigned longs. RFC 8182:

> The serial attribute MUST be an unbounded, unsigned positive
> integer in decimal format indicating the current version of the
> repository.

19 months agoPatch FIXME: Raise severity of RRDP INFO messages
Alberto Leiva Popper [Wed, 8 Nov 2023 18:17:33 +0000 (12:17 -0600)] 
Patch FIXME: Raise severity of RRDP INFO messages

These are supposed to be errors, not infos.

19 months agoFix traversal result code
Alberto Leiva Popper [Wed, 8 Nov 2023 17:47:30 +0000 (11:47 -0600)] 
Fix traversal result code

handle_tal_uri() was returning 0 on soft errors and positive on success.
It's supposed to be the other way around.

This resulted in the main loop dropping successful tree traversals.

It also resulted in TA public key mismatches causing traversal
termination, which was a violation of RFC 8630:

> If the connection to the preferred URI fails or the retrieved CA
> certificate public key does not match the TAL public key, the RP
> SHOULD retrieve the CA certificate from the next URI, according to
> the local preference ranking of URIs.

This bug was introduced by 604f845ce6b9eb596dc9f1fdff7a7fa5752fcc87.

19 months agoAnother RRDP review, startup
Alberto Leiva Popper [Tue, 7 Nov 2023 21:25:06 +0000 (15:25 -0600)] 
Another RRDP review, startup

- Improve usage of `xmlChar *`
  (Was being casted to/from `char *` rather contract-breakingly.)
- Bunch of renames
- notification_metadata -> rrdp_session
  (These are not exclusive to Notifications.)
- delta_head -> notification_delta
  (The object specifically refers to Notification delta tags,
  I don't know what "head" is supposed to allude.)
- rdr_snapshot_ctx, rdr_delta_ctx -> rrdp_ctx
  (Slightly tweaked the semantics of this, to reduce argument
  lists.)
- Remove redundant fnstack pushes and pops
  (Rather comically, snapshots and deltas were being stacked twice:
  parse_snapshot() + rrdp_parse_snapshot(), parse_delta() +
  process_delta().)

There are still a few FIXMEs in RRDP yet.

20 months agoMerge the RRDP modules
Alberto Leiva Popper [Tue, 7 Nov 2023 18:40:05 +0000 (12:40 -0600)] 
Merge the RRDP modules

I don't really have any strong arguments to justify this. Been
progressively convincing myself to do it over time, and at this point I
think it's inevitable.

It's not that much code, most of this stuff doesn't need to be exported,
and the reduced API simplifies the review.

I'm becoming a minimalist, I suppose.

20 months agoPrivatize struct publish and struct withdraw
Alberto Leiva Popper [Mon, 6 Nov 2023 23:24:17 +0000 (17:24 -0600)] 
Privatize struct publish and struct withdraw

20 months agoDelete struct snapshot and struct delta
Alberto Leiva Popper [Mon, 6 Nov 2023 17:39:12 +0000 (11:39 -0600)] 
Delete struct snapshot and struct delta

Weird code design.

I originally meant to privatize and de-heap these structures,
but it turns out they were not just used by a single module;
they were only used by `parse_metadata()`.

(Their domain seemed larger than it was, because they were being
initialized elsewhere, for no apparent reason.)

Then, while trying to clean up the global namespace, I noticed that the
hack was actually intertwined with another one: `parse_metadata()` was
being used for two purposes that are never actually used simultaneously.
This cluttered it.

So also separate `parse_metadata()` from `validate_metadata()`.

20 months agoImprove the cache fallback algorithm
Alberto Leiva Popper [Tue, 31 Oct 2023 18:17:34 +0000 (12:17 -0600)] 
Improve the cache fallback algorithm

If all of a RPP's URLs fail, fall back to most sensible cached
candidate.
It seems this used to be only implemented for TAs, and the heuristics
for choosing a suitable fallback were rudimentary.
Elaborate, centralize and extend implementation to all cache content.

Side maintenance tweaks:

- Remove EREQFAILED, because it largely evolved from meaning "don't try
  again" to "try again." So now it was just a redundant EAGAIN.
- Ditch redundant arguments from valid_file_or_dir().
- Merge the three URI arraylist implementations (certificate.c, tal.c
  and manifest.c) into one.
- Move RRDP workspace URI, from a thread variable to the stack.
  (Code smell. It used to be awkward to follow this variable's lifespan
  through the tree traversal.)
- Move struct publish and struct withdraw from the heap to the stack.
  (Eliminate pointless allocations. These are not the only RRDP
  structures I want to move to the stack.)
- Change file_metadata.uri from `char *` to `struct rpki_uri *`.
  (This string was forcing the RRDP code to recompute the URI
  repeatedly.)

20 months agoAdd minor/stylistic tweaks to main loop
Alberto Leiva Popper [Mon, 30 Oct 2023 20:47:28 +0000 (14:47 -0600)] 
Add minor/stylistic tweaks to main loop

1. Merge notify and validation_run into main
2. Remove unused structure fields
3. Rename some symbols

20 months agoPrevent pthread_join from hiding some other thread's error
Alberto Leiva Popper [Mon, 30 Oct 2023 20:44:02 +0000 (14:44 -0600)] 
Prevent pthread_join from hiding some other thread's error

20 months agoUpdate unit tests
Alberto Leiva Popper [Mon, 30 Oct 2023 16:47:43 +0000 (10:47 -0600)] 
Update unit tests

20 months agoDelete the validation thread pool
Alberto Leiva Popper [Thu, 26 Oct 2023 21:40:48 +0000 (15:40 -0600)] 
Delete the validation thread pool

My original intent was "deprecate thread-pool.validation.max," but it
turns out it was just a symptom of a (mostly inoffensive)
overcomplication.

thread-pool.validation.max has proven confusing to users, because it
doesn't make sense for it to be configurable. The thread count should
always equal the number of RPKI trees, which in turn equals the number
of TALs. There's no reason why Fort should offload this decision to the
user.

As for the thread pool, the validation cycle is not really a fitting
problem for such an ellaborate solution, because the former involves a
very small amount (typically 5) of long-lived threads that start at the
same time, once every hour or so.

So instead of pooling a configured amount of threads in the beginning,
spawn raw threads as needed.

The RTR server still employs a thread pool.

20 months agoRemove unused includes
Alberto Leiva Popper [Wed, 25 Oct 2023 22:26:26 +0000 (16:26 -0600)] 
Remove unused includes

20 months agoUn-deprecate http.priority and rsync.priority
Alberto Leiva Popper [Wed, 25 Oct 2023 21:09:36 +0000 (15:09 -0600)] 
Un-deprecate http.priority and rsync.priority

Reverts relevant tweak from c717043aad5bf8306a437ac0020bdfceeb8d2234,
though it rewrites the mechanism.

Orders from above. But also, RRDP seems to be much faster than rsync.
Best prefer the former at all times by default.

20 months agoValidate Error Reports harder
Alberto Leiva Popper [Tue, 24 Oct 2023 21:28:11 +0000 (15:28 -0600)] 
Validate Error Reports harder

- Reject overly small Error Reports earlier and more clearly on the logs
- Compare Length of Encapsulated PDU to header length earlier

It seems both issues caused relevant malformed Error Reports to be
considered fragmentend rather than invalid.

20 months agoTruncate erroneos PDU if incomplete
Alberto Leiva Popper [Tue, 24 Oct 2023 18:52:09 +0000 (12:52 -0600)] 
Truncate erroneos PDU if incomplete

This can happen if eg. the client parrots length 512 in header, but only
sends 8 bytes.

Fort was trying to assemble a 512 length erroneous PDU using an 8 byte
buffer, and therefore leaking raw memory contents to the client.

20 months agoRemove PDU queuing
Alberto Leiva Popper [Sat, 21 Oct 2023 03:08:46 +0000 (21:08 -0600)] 
Remove PDU queuing

Tweak ideated during the commit message of the previous commit.

- If the read() yields at least one Error Report, drop the connection.

This is because all the server-received error codes currently defined
are supposed to result in immediate connection termination.

If a future RFC defines a nonfatal error code, Error Reports should
probably be downgraded to the 'last PDU' rule below.

- Otherwise, if a read() yields multile PDUs, drop all except for the
  last one.

Since it's what the client is most likely expecting, I guess. Serial
Queries and Reset Queries are alternate means to achieve the same goal,
so it doesn't make sense to queue them.

20 months agoRTR server maintenance
Alberto Leiva Popper [Fri, 20 Oct 2023 22:18:39 +0000 (16:18 -0600)] 
RTR server maintenance

Someone reported a security vulnerability in the server, but the details
are muddy, and clarifications have not arrived yet. I haven't been able
to reproduce it, but the review did yield room for improvement:

1. Buffer request bytes better

The old code seemed to assume each socket read consumed exactly one
(nonempty) TCP packet, and each such packet contained exactly one PDU.

I'm scratching my head at this, but I guess for most intents and
purposes, this assumption is not as lunatic as it seems. Benign RTR PDUs
are very small, and it doesn't make sense for a request packet to
contain multiple of them. Error Reports aside, it doesn't even make
sense for the client to send multiple PDUs in quick succession at all.

Regardless, I'm flushing that assumption down the toilet:

- If read() yields multiple PDUs, queue and handle them in sequence.

Although as I'm writing this I'm realizing that queuing PDUs is a dumb
idea, because Serial Queries and Reset Queries are alternate means to
achieve the same goal. If the client sent a new request, it's most
likely given up on the old one. Plus, queuing PDUs brings additional
complexity and risks. I'm going to have to change this in the next
commit.

- If a read() yields a fragmented PDU, buffer and prepend it to the next
  successful read.

This will probably never happen, but it's nice to handle it properly
anyway.

2. Drop unused PDU parsers

An RTR server only needs to handle PDU types Serial Query, Reset Query
and Error Report. Fort also had dead code meant for the other PDU types.

I'm guessing they were intended for the Error Report internal PDU field,
but it turns out that's also unused.

3. Improve PDU validation

Since Serial Queries and Reset Queries are supposed to have constant
length, Fort was often ignoring the PDU header length field.

Fort now punishes incorrect lengths more aggressively.

20 months agoPatch errors detected by unit tests
Alberto Leiva Popper [Fri, 20 Oct 2023 22:14:21 +0000 (16:14 -0600)] 
Patch errors detected by unit tests

21 months agoFix rsync target location
Alberto Leiva Popper [Fri, 6 Oct 2023 21:47:21 +0000 (15:47 -0600)] 
Fix rsync target location

Was downloading rsync://a.b/c into rsync://a.b/c/c, because of an rsync
complication (from rsync(1)):

> A trailing slash on the source changes this behavior to avoid creating
> an additional directory level at the destination. You can think of a
> trailing / on a source as meaning "copy the contents of this
> directory" as opposed to "copy the directory by name", but in both
> cases the attributes of the containing directory are transferred to
> the containing directory on the destination. In other words, each of
> the following commands copies the files in the same way, including
> their setting of the attributes of /dest/foo:
>
> rsync -av /src/foo /dest
> rsync -av /src/foo/ /dest/foo

21 months agoRestore certificate stack push
Alberto Leiva Popper [Thu, 5 Oct 2023 17:16:19 +0000 (11:16 -0600)] 
Restore certificate stack push

I had temporarily removed this code during the tree traversal review,
and forgot to restore it.

Push current certificate into certificate stack, so child objects can
validate themselves against it.

21 months agoFix global to local URI mapping on manifest entries
Alberto Leiva Popper [Thu, 5 Oct 2023 00:22:34 +0000 (18:22 -0600)] 
Fix global to local URI mapping on manifest entries

Straightforward bug; was neither downloading to the intended location
nor attempting to locate the file there afterwards.

21 months agoAdd some debug logs to RRDP
Alberto Leiva Popper [Thu, 5 Oct 2023 00:18:34 +0000 (18:18 -0600)] 
Add some debug logs to RRDP

21 months agoPrevent string from being released before it's returned
Alberto Leiva Popper [Wed, 4 Oct 2023 23:31:11 +0000 (17:31 -0600)] 
Prevent string from being released before it's returned

21 months agoMemorize notification URI before handling RRDP objects
Alberto Leiva Popper [Wed, 4 Oct 2023 23:20:09 +0000 (17:20 -0600)] 
Memorize notification URI before handling RRDP objects

The URI is needed both by RRDP objects and Manifest; it seems I was not
taking the former into account.

21 months agoRestore GeneralizedTime_constraint()
Alberto Leiva Popper [Wed, 4 Oct 2023 21:21:00 +0000 (15:21 -0600)] 
Restore GeneralizedTime_constraint()

Turns out this is being used, and trivial to implement.

21 months agoFix usage of incorrect configuration field
Alberto Leiva Popper [Wed, 4 Oct 2023 20:57:32 +0000 (14:57 -0600)] 
Fix usage of incorrect configuration field

21 months agoInclude cache dir in local counterpart of URIs
Alberto Leiva Popper [Wed, 4 Oct 2023 20:37:33 +0000 (14:37 -0600)] 
Include cache dir in local counterpart of URIs

Before:

- URI: https://a.b.c/d/e.xml
- Local path: https/a.b.c/d/e.xml

Now:

- URI: https://a.b.c/d/e.xml
- Local path: /path/to/cache/https/a.b.c/d/e.xml

Is a bit more memory-gluttonous, but prints a more helpful string,
and simplifies user code by taking care of the task up front.

21 months agoFeature test macro review (cont.)
Alberto Leiva Popper [Tue, 3 Oct 2023 21:26:08 +0000 (15:26 -0600)] 
Feature test macro review (cont.)

I found a couple of symbols I missed during the previous macro review:

- getline(). This forces POSIX >= 2008.
- IN6_ARE_ADDR_EQUAL(). I can't find where this is supposed to be
  standardized, so I decided to ditch it.

Also, declaring these macros in every dependent file is scaling poorly,
so I moved them to the CC directives, unifying them in the process.
_POSIX_C_SOURCE is now 200809L, and _XOPEN_SOURCE is 700 (to match).

Also, reduce -std to c99. I don't really have an issue with gnu11, but
it looks like the delta is heavily underutilized in the project.
Might revert it later.

Finally, update the unit tests.

21 months agoReduce severity of metadata.json not found
Alberto Leiva Popper [Tue, 3 Oct 2023 20:07:26 +0000 (14:07 -0600)] 
Reduce severity of metadata.json not found

Also improve the error messages by including the actual name of the
file.

21 months agoInit basic cache structure on validation start
Alberto Leiva Popper [Tue, 3 Oct 2023 18:52:51 +0000 (12:52 -0600)] 
Init basic cache structure on validation start

Perform a token attempt to create the cache directory, as well as a more
reasonable one to create its tmp/ subdirectory, whenever the validation
cycle begins.

21 months agoReview strchr() and strrchr() usage
Alberto Leiva Popper [Tue, 3 Oct 2023 18:49:00 +0000 (12:49 -0600)] 
Review strchr() and strrchr() usage

The code was sometimes falling into the strchr() const trap.

This wasn't really a problem because literals were never involved,
and the strings were not thread-shared.

But better be safe than sorry.

21 months agoCall X509_ALGOR_get0() instead of dereferencing ASN1_OBJECT
Alberto Leiva Popper [Tue, 3 Oct 2023 17:17:21 +0000 (11:17 -0600)] 
Call X509_ALGOR_get0() instead of dereferencing ASN1_OBJECT

Seems to be the formal way of doing it.

21 months agoZeroize validation.notification_uri on initialization
Alberto Leiva Popper [Tue, 3 Oct 2023 15:43:06 +0000 (09:43 -0600)] 
Zeroize validation.notification_uri on initialization

21 months agoRelease CRL on error branch
Alberto Leiva Popper [Tue, 3 Oct 2023 15:37:57 +0000 (09:37 -0600)] 
Release CRL on error branch

Fixes memory leak.

21 months agoRevert Autoconf version
Alberto Leiva Popper [Tue, 3 Oct 2023 15:34:33 +0000 (09:34 -0600)] 
Revert Autoconf version

Looks like 2.71 is not that widespread yet, and Fort is not using any
features past 2.69 anyway.

Revert from 62c65a79e142012067a76acf70b86438d56636e1.

21 months agoRemove timegm() and tm_gmtoff
Alberto Leiva Popper [Mon, 2 Oct 2023 16:20:27 +0000 (10:20 -0600)] 
Remove timegm() and tm_gmtoff

Perfects portability. Still missing some testing.

I hope this is not too aggressive. If there are RPKI objects not using
Zulu, this is going to need further tweaking.

21 months agoStop assuming time_t is long and represents seconds
Alberto Leiva Popper [Fri, 29 Sep 2023 20:43:53 +0000 (14:43 -0600)] 
Stop assuming time_t is long and represents seconds

21 months agoFeature test macro review
Alberto Leiva Popper [Thu, 28 Sep 2023 22:49:19 +0000 (16:49 -0600)] 
Feature test macro review

Stop relying on default features; explicitely define the macros that
enable the symbols we need.

It appears POSIX.1 usage is fairly widespread through the code, and its
minimum required version is 2001.

We also have one GNU extension: getopt_long().

And we also have one GNU extension marked as nonstandard: timegm().
I'm going to try to remove it in a future commit.

21 months agoRemove SO_REUSEPORT from the RTR socket bind
Alberto Leiva Popper [Thu, 28 Sep 2023 22:32:53 +0000 (16:32 -0600)] 
Remove SO_REUSEPORT from the RTR socket bind

This option is causing portability issues, and I can't figure out why it
was introduced. None of the Github issues mention it, and
6401a4739ac512985158e63499e037dc2f2078db says

> Use SO_REUSEPORT at sockopts so that the RTR port can be reused

But reused when? For what purpose?

I think this might be an allusion to
ac56d70c954caf49382f5f28ff4a017e859e2e0a:

> SO_REUSEADDR sockopt allows to reuse server address and port at once
> when the service has been stoped (or killed).

But that doesn't need SO_REUSEPORT for anything.

21 months agoSystem #include overhaul
Alberto Leiva Popper [Wed, 27 Sep 2023 21:49:57 +0000 (15:49 -0600)] 
System #include overhaul

Reorganize `#include <>`s in accordance with the IEEE Std 1003.1,
the Linux man pages (which do a pretty good job explaining portability
nuances), the documentation of the dependencies and some common sense.
(Since it seems some of this stuff is undefined.)

The algorithm still induces some unnecessary includes. (eg. the `NULL`
symbol induces `stddef.h`, `string.h`, `stdlib.h`, `stdio.h`, `unistd.h`
AND `locale.h`, because the standard states it should be defined in all
of them.) I don't think this is a problem for now; I'll optimize it
later.

21 months agoRemove some of the asn1c and uthash glue code
Alberto Leiva Popper [Wed, 27 Sep 2023 20:50:26 +0000 (14:50 -0600)] 
Remove some of the asn1c and uthash glue code

The asn1c stuff was autogenerated, and the uthash stuff was copy-pasted
from its source project.

None of it serves any purpose. I'm not allergic to the possibility of
supporting these other environments, but this is not the time for it.
Also, it probably doesn't work anyway, since it has never been tested
in the context of Fort.

This doesn't delete all the glue code; only the necessary parts needed
for the upcoming commit.

21 months agoUnify working directory #includes
Alberto Leiva Popper [Wed, 27 Sep 2023 20:30:56 +0000 (14:30 -0600)] 
Unify working directory #includes

I'm currently reviewing the system includes. There are some unnecesary
ones, as well as a few nonstandard quirks complicating portability.

This is the first of possibly quite a few commits intended to refactor
this relative mess. It makes all `#include ""`s relative to the root of
the source directory.

This makes them easier to analyze and copy-paste.

21 months agoTesting on the local cache code
Alberto Leiva Popper [Wed, 20 Sep 2023 00:08:15 +0000 (18:08 -0600)] 
Testing on the local cache code

- Recover from more errors
- Test more error paths