This is mainly due to licensing. The libmaxminddb library uses the
Apache license, which meant if we would compile it in by default it
would effectively transform our "GPLv2 or later" to "GPLv3 or later".
Our implementation is ISC licensed, so we can include and enable it
by default and keep things at "GPLv2 or later". This is also why we
used geoip_classic in the first place as default and compiled in,
and not the mmdb variant.
The mmdb.c is based on the specification, using the Go implementation
as a reference during development (ISC licensed), initially implemented
with the help of Claude Opus 4.6. After that substantial changes were
made to make it match UnrealIRCd's style and to make things less error
prone: C style changes, allocation and zero termination of strings in
the library, auto-NULL in variadic functions so the caller cannot
forget NULL there (similar to our unreal_log/do_unreal_log), using
enums as the return type instead of int (similar to curl), adding
doxygen docs, etc.
This also means the old mmdb library dependency has been dropped,
including from configure/autoconf.
At the moment we still use the geoip classic library by default,
including those DB files. The idea is we will switch over sometime
later after this current new MMDB stuff has received more testing.
This also makes us more flexible, since .mmdb files have become the
de-facto standard for pretty much all geoip vendors.
This module is rarely used but analysis showed that there was an
OOB write in the country name, and two small off-by-ones in code
and continent.
Again, this only matters if the CSV file you are importing is bad
or malicious. And we use stack protection in UnrealIRCd so this
should then "only" cause a crash.
which already ensures in bounds, so not an issue. But who knows in the
future there will be other functions that use it and then the check
is misleading as it doesn't cover all cases.
or rehashing if there is an error loading them (at least try harder).
Right now they are only in CONFIG LOAD, which is too late to stop things.
Previously "./unrealircd configtest" showed an error but still said
"Configuration test passed OK". And REHASH passed similar. Now, it
is a real error.
This is not to be confused with a "file does not exist" error, which
we already handled properly. It's the less usual ones, like wrong key.
Only downside is more init_ctx() calls, which can be a bit heavy on
various platforms, slowing boot or REHASH down. Should be fine though...
This isn't really important, as you can read below, but was a FIXME item.
This function checks for RSA keys that are less than 2048 bits, so
RSA 1024 is rejected. This was added in UnrealIRCd 5.0.0 (Dec 2019).
RSA 1024 was already looong considered insecure. And those using it
should have been flagged from there on.
OpenSSL 3 changed the API, and this function was never updated to have
the same check with OpenSSL 3+ until now. Fortunately, OpenSSL 3.0.0
onwards reject 1024 bit RSA by default, so that doesn't really matter.
For reference, OpenSSL 3 was released in Sep 2021 and first appeared
in Ubuntu LTS 22.04 (Apr 2022) and Debian 12 (Jun 2023).
However, if you set SECLEVEL to 0 (eg in system-wide openssl.cnf),
it would allow those keys, which is pretty much expected but also not
what we want at UnrealIRCd. From now on, for those rare situations,
we reject it as well.
even if it costs an extra round-trip due to HRR (Hello Retry Request).
This is IRC after all, where connections live minutes, hours, days,
so that extra round trip is worth it if it means better security.
The TL;DR is: we try harder to use X25519MLKEM768.
The longer story is as follows:
In TLSv1.3, the client will indicate which groups it supports (eg
a list of 4 items) and which ones it speculates to be used (very
often just 2 items). Some TLS clients may not include X25519MLKEM768
in this initial speculation, but only f.e. X25519 and prime256v1
even though X25519MLKEM768 is communicated via their "supported" list.
Without this patch, we would then settle with one of those 2.
With this patch, we will send a Hello Retry Request, allowing to
use X25519MLKEM768.
This is rare, though, most TLS client implementations that have
X25519MLKEM768 will bet on it to be used (the 2 they bet on is
often X25519MLKEM768 & X25519). That's many browsers like Chrome,
OpenSSL, Go, etc.
GnuTLS usually will do this as well, but under some configurations
it may bet on 2 classic crypto to be used. For that specific (type
of) situation, this patch will help to use X25519MLKEM768.
This can be tested with OpenSSL to simulate such an implementation:
openssl s_client -connect 127.0.0.1:6697 -groups X25519MLKEM768:*X25519
Before this patch, it would result in X25519 (because that is the
speculated group, with the asterisk). After this patch it will
cause X25519MLKEM768 to be used.
The tuple syntax is in 3.5.0+ and our UNREALIRCD_DEFAULT_TLS_GROUPS_PRIMARY
with X25519MLKEM768 also requires 3.5.0+ so this is an easy change.
Oh and, this commit comment is rather long for a 1 byte change :D
For the extbans that we ship, no problem, as this isn't used in
any of our extbans, but for third party it may matter, or for us
in the future.
Just something we came across while looking into the issue from
previous commit.
This affects servers without NEXTBANS, such as anope 2.0.x series
(anope 2.1.x is not affected as it supports NEXTBANS).
Non-NEXTBANS servers only support letter extbans so we are supposed
to convert ~security-group:known-users to ~G:known-users when sending
to such a server, in unreal_server_compat. And we did this well for
the MODE command for +beI. In SJOIN we did this correctly for +b/+e
but not for +I due to a silly code mistake.
This bug is present since 6.0.0 but wasn't noticed until now.
To be a real problem you need something like:
1. Anope 2.0.x series (or other services without NEXTBANS)
2. A channel with +I extbans
3. KEEPMODES set on that channel
Then what happens is when services boot:
1. UnrealIRCd will sync with anope 2.0.x and incorrectly send
named bans, which will confuse anope. But nothing strange
happens yet at this point.
2. Then on next server sync (eg anope restart or unreal restart)
anope will try to restore these but they end up with weird
entries like +I *!*@~security-group:known-users
(note the *!*@ prefix)
And it should be noted that this would also happen in a situation
with UnrealIRCd 5 + UnrealIRCd 6 servers, but UnrealIRCd 5 is
End Of Life anyway.
Reported by BlackBishop and Sadie two days ago. Thanks!
NOTE: Linked servers are considered trusted in UnrealIRCd.
This is not exploitable beyond a crash, due to -fstack-protector-all,
a hardening compiler flag we added many years ago. Even without
that flag it would be rather difficult, and i didn't manage to,
but this should never happen anyway since this flag is only
missing in gcc/clang versions that are more than 15 years old.
This issue was introduced by the move to CMD_BIGLINES in
6c5de62c18 in 6.2.2 release.
Mention tested systems as well (which is narrower than supported systems).
And merge documentation and support, since users will usually be after both.
In particular, this disables default +F for #__SYNC__ channels.
The test suite has a "+F off" but when on 3 servers, each 75
clones are connecting, the MODE is too late and the join limit
is already reached sometimes. Causing tests to fail.
because it has no internet access, like when fetching the repository
(modules.list file) of 3rd party modules.
Previously I had..
url_start_async(request);
synchronous_http_request_in_progress = 1;
.. which worked fine for the "cannot connect case", like port blocked
or timeout connecting. But if DNS fails then the step of setting
synchronous_http_request_in_progress = -1 (so failed) already happens
during the url_start_async(request); call, and then the line after it
sets 'synchronous_http_request_in_progress = 1;' so we miss that it
failed and wait in the I/O loop forever.
Simply swapping the two lines of code fixes this.
The other change is that when running the ModuleManager in "make" we should
ignore the exit code. I probably broke that while refactoring and adding
non-zero exit codes in de modulemanager past few months for this release.
Previously we didn't and that means that if any shipped lib was used,
without hardening, this would cause non-CET libraries to silently disable
CET for the entire process, and partial RELRO on the libs means the
full RELRO in UnrealIRCd is much less useful.
Actually, system libs on Debian/Ubuntu don't even have full RELRO atm,
but hey, we try to do better, also.. some other OS/distro might
have it on and who knows Debian/Ubuntu change their mind later..
as useful as initially thought. I thought kernel hardening checker
was in favor of it, and they were, but they dropped it in Oct 2023.
(i added it 2-3hrs ago in 0ab1221a38)
This zeroes out variables that COULD be accessed before being set
(so to prevent access to unitialized variables). We are generally
very careful about this in our code, but in 3rd party modules this
is less the case. And still useful in case we ourselves screw up.
Is defense in depth to make ROP harder. In general this is reported to
have a performance impact of 2% worst-case. Linux kernel reports 1%.
Should be closer to 0% for us, or that 1% if i am wrong.
https://lwn.net/Articles/870045/ has some background on this.