1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-07-03 06:13:13 +02:00
Commit Graph

10355 Commits

Author SHA1 Message Date
Bram Matthys 4c6e259681 You can now use "password" multiple times in the conf (eg in allow::password).
allow {
	mask *;
	password "secret";
	password "letmein";
}

This is always an "OR" type of match, any match means you pass.

I was actually doing this for the dual-cert stuff from previous commit,
where this can come in handy:

link irc1.example.org {
...
    password "AHMYBevUxXKU/S3pdBSjXP4zi4VOetYQQVJXoNYiBR0=" { spkifp; };
    password "jNw8P4QMg9tqjEJ4/lFikXBNHdIGSeN2B4/T322VjIo=" { spkifp; };
...
}
2025-09-21 11:42:59 +02:00
Bram Matthys 877d151da4 Support multiple TLS certificates/keys, e.g. ECDSA + ML-DSA (PQC).
In the past a dual cert/key setup could have been useful for RSA + ECDSA
but nowadays all clients support ECDSA so that makes little sense.
The reason it is added now is so you can use ECDSA + ML-DSA or some
other [regular crypto] + [post quantum crypto] combination.
Actually, you could even use more than two.

To use this in the config file, simply use the certificate and key
directive multiple times. Just be sure to load the certificates and keys
in the same order. We will print a helpful error if you fail to do so.

Note that for Post Quantum Cryptography the most important step today
was/is to protect against the "Harvest now, decrypt later" scenario
https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later which is a
"passive attack". That's why in UnrealIRCd 6.2.0 we enabled
X25519MLKEM768 if it is available (OpenSSL 3.5.0 and later).
While, this commit, and this talk about dual ECDSA and ML-DSA, is about
when a quantum computer exists and actively does a man in the middle
attack. That's not a realistic scenario in 2025 and according to experts
also not in the next few years. We just make the UnrealIRCd code-
base ready to have this feature for when it is needed / will be used,
and to get this tested properly.

For testing the dual ECDSA and ML-DSA setup I used the following
command to create the 2nd cert/key (self-signed):

openssl req -x509 -nodes -newkey mldsa65 \
  -keyout ~/unrealircd/conf/tls/server.key.mdsa65.pem \
  -out ~/unrealircd/conf/tls/server.cert.mdsa65.pem \
  -days 3650

And then:

listen {
        ip *;
        port 6697;
        options { tls; }
        tls-options {
                certificate "ssl/server.cert.pem";
                key "ssl/server.key.pem";
                certificate "ssl/server.cert.mdsa65.pem";
                key "ssl/server.key.mdsa65.pem";
        }
}

When running openssl s_client -connect 127.0.0.1:6697 it shows ML-DSA is used:
...
Peer signature type: mldsa65
Negotiated TLS1.3 group: X25519MLKEM768
...

And with openssl s_client -connect 127.0.0.1:6697 -sigalgs "RSA+SHA256:RSA+SHA384:ECDSA+SHA256:ECDSA+SHA384"
it shows ECDSA is used:
..
Peer signature type: ecdsa_secp384r1_sha384
Negotiated TLS1.3 group: X25519MLKEM768
..

This is just for testing purposes (self signed cert). As of right
now (Sep 2025), you can not get a trusted certificate with ML-DSA,
as the CA/Browser Forum only allows issueing RSA and ECDSA keys.
Also, all the trusted Certificate Authorities use RSA or ECDSA.
And, again, all this is not ML-DSA specific, it should work for
other dual/multi combinations, and.. who knows they even go for
something hybrid.

A downside of dual certs is that this makes the whole spkifp thing more
complicated because if you use 2 certs/keys you now have 2 possible
fingerprints (spkifp) that could match in e.g. server linking.

While coding this, I also changed the 'STATS P' output to use the txt
numeric instead of notice, and be more verbose in its output for TLS
listeners: printing the certificate(s) and key(s).
2025-09-21 10:32:29 +02:00
Bram Matthys ccc80477ef Fix OOB read in UTF8ONLY code from today. 2025-09-20 17:40:34 +02:00
Bram Matthys b4e65b1414 Fix various "too early" cutoffs with new set::utf8-only feature 2025-09-20 15:52:31 +02:00
Bram Matthys dbb2d1a5c8 Move isupport_check_for_changes() to the 'isupport' module.
This function was added a short while ago, and well it seems to be
able to be possible in a module. Since the 'isupport' module is mandatory
and this is ISUPPORT related, it is the right place.
Can't move isupport_snapshot() because modules might not be loaded yet
or things are currently unloading, i think. Not important anyway.

Also, make things work if there are more changes than would fit
on one isupport line. Although I didn't really test this..
Ended up splitting things in 3 helper functions to avoid some
goto and/or duplicate code and stuff. The alternative was, surprisingly,
even more ugly.
2025-09-20 15:44:56 +02:00
Bram Matthys 595f56007b Add the ISUPPORT command, which simply calls the efunction.
Call the efunction from 005 introduction as well, so it uses the
batch, if needed. And yeah we opt to send the 005's always, even
if it was already sent in the handshake (or not).

Some re-indenting (spaces to tabs).

And call the efunction from VERSION as well.

For "VERSION remote.server" we don't send them in a batch as these
are not numeric 005 but 105. These are for information purposes only
and should not confuse the client (eg not to act upon).
2025-09-20 14:56:26 +02:00
Bram Matthys 5cb2428567 Some code cleanup to previous, and apparently the batch type is 'draft/isupport'
and not 'draft/extended-isupport'.
2025-09-20 14:40:16 +02:00
Bram Matthys e78a6a6dbf isupport & extended-isupport module, work in progress.
This is mostly from Valware PR https://github.com/unrealircd/unrealircd/pull/310
Will do more changes in later commits..
2025-09-20 14:34:28 +02:00
Bram Matthys 9e490196a8 set::send-isupport-updates: Valware added this, but this is now expanded
to all ISUPPORT tokens, instead of only CHANMODES, PREFIX and STATUSMSG.
E.g. changing set::min-nick-length would also broadcast the change.

Technically we will call isupport_snapshot() before the rehash (or before
delayed module unload) and then after modules were reloaded/unloaded we
call isupport_check_for_changes(). This uses the ISUPPORT system in a
general way, so works the same for all tokens.

https://www.unrealircd.org/docs/Set_block#set::send-isupport-updates

TODO: Deal with more than X changes (is currently an abort, crash)

TODO: batch for draft/extended-isupport
2025-09-20 14:05:35 +02:00
Bram Matthys f22f8d0dcd Add set::utf8-only: if set to 'yes' this means all IRC traffic is UTF only.
See https://www.unrealircd.org/docs/Set_block#set::utf8-only and the
UTF8ONLY specification at https://ircv3.net/specs/extensions/utf8-only
for more information.

Reported by PeGaSuS, who reported it based on a #unreal-support message
from uMut, who reported it based on a message from itsonlybinary.
This closes https://bugs.unrealircd.org/view.php?id=6458

This feature still needs to go through our internal tests.
2025-09-20 09:00:52 +02:00
Bram Matthys d763b9c1e3 Some crash reporter tweaks like TLSv1.3+ and max size
(will still use TLSv1.2 if OpenSSL does not support TLSv1.3,
 though.. OpenSSL 1.1.1 that introduced it is from Sep 2018)
2025-09-17 20:11:18 +02:00
Bram Matthys 0c17276039 Move https_new_ctx() from src/url_unreal.c to src/tls.c so it is
always available (also w/cURL) so it can be used by the crash
reporter. And delete duplicate code crashreport_init_tls()
function since it is now unused.

As always, duplicate code causes problems when one is changed and
the other is not. This also happened here, where the curves or
TLS groups where set in url_unreal but not in the crash reporter.
Now that one is minor, but the danger is clear.
2025-09-17 19:57:03 +02:00
Bram Matthys 1685d5243f Write some early release notes
[skip ci]
2025-09-17 13:05:00 +02:00
Bram Matthys 5e54ab5ed7 Remove some old #ifdef SO_ERROR. That's always available on POSIX and Windows. 2025-09-17 11:01:46 +02:00
Bram Matthys a6ae945499 Fix built-in https fetcher to also try IPv6.
Without this fix, on an IPv6-only host UnrealIRCd would give you:
[warn] /home/ircd/unrealircd/conf/modules.default.conf:309: Failed to download 'https://www.unrealircd.org/files/geo/classic/GeoIP.dat': Could not connect: Network is unreachable
[warn] Continuing anyway...

This fixes https://bugs.unrealircd.org/view.php?id=6249, which was
also similarly reported by progval in https://bugs.unrealircd.org/view.php?id=6073

This implements only a simple try-IPv4-then-IPv6 approach in case of
clear connect errors. There is no happy eyeball like approach (where it
gives IPv6 a 250ms head start and then tries IPv4 in parallel), if there
is really a 15sec timeout then it doesn't retry IPv6 either (in case you
have IPv4, there is a route, but packets end up blackholed), nor does it
try all IP addresses that the resolver returns (then again, that's not
strictly related to happy eyeballs or IPv4/IPv6).
That would require some major overhaul that is not planned in U6. If you
want better/great protocol support you can always enable cURL in ./Config.
2025-09-17 10:59:04 +02:00
Bram Matthys 82bf4a6beb Add logging category "advice" that is used by best practices (color: blue).
Maybe a bit odd since only <10 things use this category but it makes it
stand out as a separate thing much better. As for a level (not that it
matters) it is between 'info' and 'warn'.
2025-09-15 14:21:51 +02:00
Bram Matthys 2798276316 add -Wno-unterminated-string-initialization
Without this on some new compilers this raises a warning (or error with -Werror):
const char hexchars[16] = "0123456789abcdef";

The alternative is to add __attribute__((nonstring)) at the various places
that need it. But 1) that requires various ifdefs to support old compilers, and
2) This doesn't catch anything meaningful in our code anyway and the odds of
it doing so seem slim.
2025-09-15 07:47:44 +02:00
Bram Matthys 0b147e8044 Probably helps if i include the file that i added in the Makefile
(fix broken compile)
2025-09-14 18:05:09 +02:00
Bram Matthys 817abc4101 Add security-group::server-port and similary in match item, to match
users by server port (eg 6667, 6697, 8000, etc).

This also adds security-group::exclude-server-port for consistency.

And in crules the function server_port() returns the server port number,
so you can use rule 'server_port()>6690' for example.

Note that for remote clients this will only work after previous
commit (b2d0ec1af3) is loaded on all
servers, otherwise all remote clients are seen as having a server_port
of zero (0). Though you probably usually only care about this on local
users anyway.
2025-09-14 17:28:04 +02:00
Bram Matthys b2d0ec1af3 Move/add local_port & server_port to ModData, so remote clients can be tracked.
This is sent over the wire as early moddata, just like "operlogin" and "operclass"
2025-09-14 17:03:34 +02:00
Bram Matthys f73dbfd7ee Remove previous UnrealIRCd PGP key from doc/KEYS (key expired and succeeded) 2025-09-14 15:41:54 +02:00
Valerie Liu a08d1faba7 JSON-RPC: Use issuer in set_by by default (PR #317 from Valware)
In TKLs like server bans, spamfilter, etc.
2025-09-14 15:38:35 +02:00
Bram Matthys f42bab778e Include 'away' information in JSON-RPC users object.
Reported/requested by CrazyCat: https://forums.unrealircd.org/viewtopic.php?p=40990
Inspired by Valware's PR: https://github.com/unrealircd/unrealircd/pull/319

This adds "away_reason" and "away_since". Note that the latter may not be as
reliable for remote users at the moment, because in case there was a split and
the server (re)connects, the away_since will be the time of the server resync
and not the original time that the user went away.
2025-09-14 15:27:10 +02:00
Bram Matthys 7a63239dde Fix memory leak with DEBUGMODE enabled (should only be used by devs).
In debug mode we also - in the JSON log - log the source file and
line number in every log message. This requires special care. A good
start was made earlier but that fix was incorrect.
Should be good now... at least when i ran tests the leak that was
previously there was gone.

The original issue was that I used (again, only in DEBUGMODE):
 #define unreal_log(...) do_unreal_log(__VA_ARGS__, log_data_source(__FILE__, __LINE__, __FUNCTION__), NULL)
But, some functions call unreal_log with something like:
unreal_log(.....
           xyz ? log_data_client("xyz", xyz) : NULL);
And then the expanded function arguments may become:
NULL,
log_data_source(...)
And since it is a vararg list the first NULL already terminates it and the
log_data_source() is never iterated, stays unseen, and thus stays unfreed.

A fix for that was made in 42caa34b5c:
do {
	LogData *lds = log_data_source(__FILE__, __LINE__, __FUNCTION__);
	do_unreal_log(__VA_ARGS__, lds, NULL); log_data_free(lds);
} while(0)

but in practice we still freed at the wrong place... it was still being
freed in the do_unreal_log() (or a child) function and the log_data_free()
actually didn't free anything.

All that is now fixed in this commit.
2025-09-14 15:08:48 +02:00
Bram Matthys 8c26cec5fc Fix 'const' in various functions: various arguments were const char *
in the EFunction but not in the actual function. That's bad since it
means the "const guarantee" got lost. And one or two similar cases with
incorrect parameter types and mismatching return types. This was
found with some analyzer, we had no bugreports with regards to this.
2025-09-14 15:01:39 +02:00
Bram Matthys 13217cc6ff Bump version to 6.2.1-git 2025-09-14 14:57:43 +02:00
Bram Matthys 9042dd21c0 ** UnrealIRCd 6.2.0.2 ** 2025-09-14 14:21:47 +02:00
Bram Matthys 64eab2c6ae antimixedutf8: fix extended latin, like éí accents leading to a high score.
The 4 unicode blocks are now treated as one big Latin block
Latin-1 Supplement, Latin Extended-A, Latin Extended-B ==mapped=to==> Basic Latin

Reported by CrazyCat in https://bugs.unrealircd.org/view.php?id=6576
2025-09-13 18:54:25 +02:00
Bram Matthys 4cc51af280 ** UnrealIRCd 6.2.0.1 **
This version (only) fixes some incorrect "best practices" warnings
2025-09-12 07:55:33 +02:00
Bram Matthys 74538e77d4 Another best practices fix: this one is with listen-nontls-port.
It could cause a spurious
"Your config has NO errors, but you received some best practices tips above, in summary"
even though no best practices were displayed... which was a bit mysterious.

Also, ::listen-nontls-port was actually meant to be called ::listen-tls-only
so accept both forms from now on. The reason it was supposed to be like that
is that all best-practices options are... best practices...
hashed passwords, trusted cert, trusted cert with valid hostname,
listening on a nontls port... ? NOPE! listen-tls-only! Aaaaa.
2025-09-10 16:45:52 +02:00
Bram Matthys 400a6080ab Actually make it possible for set::best-practices::trusted-cert-valid-hostname
to be turned off (it was seen as an unknown option). Reported by PeGaSuS.
2025-09-10 16:30:57 +02:00
Bram Matthys 76934cb815 Fix incorrect message about non-trusted SSL/TLS certificate when you use
the default certificate/key (conf/tls/server.cert.pem) even when that
cert is valid and issued by a trusted CA (like Let's Encrypt).
You would get such an incorrect "best practices advice" on-boot, but
(fortunately) not on each subsequent REHASH.

This was because the TLS system was not yet initialized completely at
the time of the best practices checks, ctx_server was NULL. This is
now solved by re-ordering some function calls.
This does change some win_error() and config_load_failed() stuff for
Windows so I hope that's okay.

Reported by Bun-Bun.
2025-09-10 07:35:50 +02:00
Bram Matthys bc27eb48fb ** UnrealIRCd 6.2.0 ** 2025-09-09 18:10:49 +02:00
Bram Matthys 399dfde33e Update curl-ca-bundle.crt to Tue Aug 12 03:12:01 2025 GMT 2025-09-08 20:10:11 +02:00
Bram Matthys 256308a707 Switch back to OpenSSL for the Windows build:
* In 2016 we switched from OpenSSL to LibreSSL because the OpenSSL
  codebase was in a bit of bad shape and LibreSSL promised to be a
  more modern codebase. Now, almost a decade later, OpenSSL has had
  many code cleanups and is more security aware (code audits etc),
  especially since OpenSSL v3 things are looking OK and it seems
  LibreSSL doesn't have much progress nowadays. Which is understandable
  as they have a lot fewer coders available but has an effect on things
  like how long it took for TLSv1.3 to appear and for other new things
  like PQC. It also seems like security fixes are now slower than
  OpenSSL instead of the other way around. Anyway, I think they did their
  job well (together with other people) in "triggering" the OpenSSL
  project to get things back on track. Let's switch back now.
* For context: it seems several Linux distro's that used to do go for
  LibreSSL have also switched back to OpenSSL.
* LibreSSL is still and will continue to be a supported library to
  use with UnrealIRCd (especially with OpenBSD and FreeBSD in mind).
  So, if there are any issues (compile problems, configuration problems,
  some feature not detected), then please report it on our bug tracker
  at https://bugs.unrealircd.org/ ! We will have to rely more on such
  user-reports now that the main devs will likely only work with OpenSSL.

Also... i have cleaned up the Makefile.windows a bit to be more consistent
Hopefully i didn't make a mistake there...

[skip ci]
2025-09-08 17:02:56 +02:00
Bram Matthys e58768eb65 antimixedutf8: ignore general punctuation block transitions
Since those can happen in ordinary text.
2025-09-06 14:02:31 +02:00
Bram Matthys e8673a06df Fix crash with "STATS tld" if tld::motd is not set. (Only IRCOps can do STATS
requests normally, unless the niche feature set::allow-user-stats is used)

The tld::motd was made optional in Jun 2022 commit 1fe6119026.
Not setting it is probably a bit rare, which explains why this bug was only
reported yesterday (Aug 2025) via the crash reporter.
2025-08-30 08:38:21 +02:00
Bram Matthys ed5bbe6ecb Stop sending 'draft/bot', and only send 'bot' (ratified 26-apr-2022)
This, obviously, only for umode +B users.
2025-08-02 17:15:43 +02:00
Bram Matthys 7603317c9b Fix some potentially confusing wording in release notes.
Just in case someone thinks we are going to msg users on plaintext ports
by default, no we don't that, or at least not this year.
This is purely a "best practices" advice to admins on config load.
[skip ci]
2025-08-01 12:09:30 +02:00
Bram Matthys 5b2c9a9890 Re-order some release notes items (mention spamfilter enhancements earlier)
[skip ci]
2025-08-01 11:43:46 +02:00
Bram Matthys aa8a8ee135 ** UnrealIRCd 6.2.0-beta3 **
This one will also be announced on the mailing list (beta1 and beta2 were not)
2025-08-01 11:28:37 +02:00
Bram Matthys 19e4a6fee9 Crash reporter: shut down TLS session gracefully
It seems like otherwise the request may not come through fully, not sure
but this seems to fix it in my tests.
2025-08-01 11:21:43 +02:00
alice 2c7bcebaca Make spamfilter:input-conversion accept deconfuse and deconfused for confusables (#316) 2025-08-01 07:39:43 +00:00
Bram Matthys 24fde4f889 Fix crash on "REHASH -dns" (IRCOp only)
Reported by vectr0n in https://bugs.unrealircd.org/view.php?id=6538
2025-07-31 17:53:40 +02:00
Bram Matthys 5e6bcaea33 After netsplit, wait for class::connfreq seconds before connecting to server.
Isn't that what it was supposed to do? Well, yes and no, previously
it only guaranteed that between reconnects (so the 2nd try not being
before class::connfreq than the 1st try), but there were no guarantees
for the first time period directly after a squit.

* When a netsplit happens and
  [set::server-linking::autoconnect-strategy](https://www.unrealircd.org/docs/Set_block#set::server-linking)
  is `sequential` (which is the default) or `sequential-fallback`
  (which is a good value for leafs) then we now consistently wait for
  [class::connfreq](https://www.unrealircd.org/docs/Class_block)
  seconds before trying to connect to the (same or next) server.
  By default this is 15 seconds in the example configuration
  server class. The reason for this is to provide a consistent behavior.
  Previously we waited semi-randomly for 0 to class::connfreq seconds.
  The previous behavior caused the picking of 'next server to try' to
  be inconsistent, which especially caused issues for `sequential-fallback`.
  If you want quicker recovery times in case of a netsplit, simply lower
  the value of [class::connfreq](https://www.unrealircd.org/docs/Class_block)
  in your configuration file, e.g. to 5 instead of 15 seconds.

Oh yeah and for connect-strategy 'parallel' things stay as is, with
the wait of 0 to class::connfreq per-server, which seems fine for that.
Unless you want a 'BOOM!' effect of mass reconnects instantly, in
which case you can just set class::connfreq very low.
2025-07-30 09:10:22 +02:00
Bram Matthys 84a1e59a44 Best practices: check if the certificate is actually valid for me::name.
That is, if the set::best-practices::trusted-cert check is on and passed
("certificate is valid and issued by a trusted CA") then we also
do this new set::best-practices::trusted-cert-valid-hostname check:

/* If the trusted-cert check passes, then we do another check to see if
 * the certificate is valid for me::name. Since users usually connect to your
 * server by your server name it is important for the certificate to be
 * valid for that name. Unless you really only care about e.g. irc.example.net,
 * and not about individual irc2.example.net server names, in which case you
 * can turn this off, but not sure if that is good practice.
 */
trusted-cert-valid-hostname yes;
2025-07-28 09:55:01 +02:00
Bram Matthys 44177f8c86 No valid trusted cert: change wording a bit ("you don't have any valid certificate"...)
Expired: this is a warning, not an error (we still want to boot the ircd)
Expired: handle the case for link::verify-certificate explicitly to avoid confusion
2025-07-28 09:19:27 +02:00
Bram Matthys 5abea8d4d2 Update release notes a bit with recent changes
[skip ci]
2025-07-27 09:52:37 +02:00
Bram Matthys 7c66adf196 Don't warn plaintext ports open if set::plaintext-policy::user is 'deny'
(.. since users won't get online then anyway)
2025-07-27 08:38:08 +02:00
Bram Matthys f39269c518 Fix uninitialized variable in config test for listen { }
Caused by previous commit 990fe22e64
2025-07-27 08:33:46 +02:00