suggest to use Let's Encrypt.
This can be turned off via set::best-practices::trusted-cert, see
https://www.unrealircd.org/docs/Set_block#set::best-practices
Oh yeah, and this only works at OpenSSL 1.1.0 and higher, i didn't bother
with people running ancient versions.
I totally agree with the goal to have this enabled, but let's do some more
testing with more clients first to see if they misbehave. Last thing I want
is a similar situation to when we were the first IRCd that sent "CAP DEL sasl"
and "CAP NEW sasl" when services went offline and online and it caused all
mIRC clients to reconnect. I don't expect this one to be so bad (also because
users would get the 005's when they typed /VERSION) but... let's test to be sure.
Should probably deploy this with enabled on irc.unrealircd.org and such :)
* Calling from source is now in a separate function: int can_use_nick(Client *client, const char *nick)
* For hooks: don't free the reject reason, must use static storage like all other hooks
(TODO: clarify in all hooks?)
* Move it up a bit, right before find_qline
TODO (not necessarily me :D):
* Make it an efunc
* Also call it from some other places that do find_qline, like rpc/user.c
* You may want to prod 3rd party modules like SANICK
This will return the number of characters that are in the unicode block
with that name.
spamfilter {
rule "unicode_count('Emoticons')>2";
target { private; channel; private-notice; channel-notice; }
action block;
reason "Too much emotion";
}
In this commit we also make it so we pass the ClientContext (including
clictx->textanalysis) in crule_context.
Example output:
*** SPAMINFO ***
This will show the original text and the deconfused text which can be used in a spamfilter block with input-conversion deconfused;
Original spam text: ẔŽŽẐ𝞕ȤℤΖℨℨ𝒁𝓩ẒŹƵᏃŻẒŽℨŹ𝒵𝛧Ż𝝛𝛧ℨℤ𝜡Ƶ𝞕𝘡ŹẐ𝑍ẔẐẐΖ𝜡Ẕ𝜡Ẕ𝞕ꓜ𝚭ᏃẐẔ𝙕
Deconfused spam text: ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
AntiMixedUTF8 points: 64
Number of Unicode characters in total: 50
Number of different Unicode blocks used: 8
Unicode Block breakdown (name: bytes [capped at 255]):
- Latin Extended-A: 8
- Latin Extended-B: 3
- Greek and Coptic: 2
- Cherokee: 2
- Latin Extended Additional: 12
- Letterlike Symbols: 6
- Lisu: 1
- Mathematical Alphanumeric Symbols: 16
In CommandAdd() the flag CMD_TEXTANALYSIS now means that the last
parameter of the command will run through the text analysis system.
This flag is set in PRIVMSG NOTICE PART QUIT AWAY SETNAME TOPIC
Make match_spamfilter use the clictx->textanalysis->deconfused rather than
calculating its own. The latter will probably disappear altogether.
Unrelated but also fixed: properly set e->unicode_blocks.
switches like antimixedutf8 did, and counts the number of characters
used per unicode block. Potentially more can be added later, this is
flexible and modules can add stuff (..well not yet.. the struct is
missing some members..).
Use it from antimixedutf8 so that it now uses the new code, which is
similar to what I made and then reverted in July 2023:
https://github.com/unrealircd/unrealircd/commit/3e2f668f10fccedfd035526d7b20d7ca6819a8ae
..except that it now calculated in src/modules/utf8functions.c.
But yeah, this needs more testing and possibly (default) score
adjustments to deal with false positives !! And a warning in release notes :D
Put the text analysis in ClientContext member textanalysis,
so typically accessed through clictx->textanalysis.
Note that this struct can (and often is) NULL, for example if it is
a remote client, if it is not a PRIVMSG/NOTICE (will improve later)
or if the utf8functions module is not loaded (to keep things optional).
BREAKING CHANGE is that ClientContext is now passed in the
HOOKTYPE_CAN_SEND_TO_CHANNEL and HOOKTYPE_CAN_SEND_TO_USER hooks.
So HOOKTYPE_CAN_SEND_TO_USER prototype changed from:
int hooktype_can_send_to_user(Client *client, Client *target, const char **text, const char **errmsg, SendType sendtype);
To:
int hooktype_can_send_to_user(Client *client, Client *target, const char **text, const char **errmsg, SendType sendtype, ClientContext *clictx);
And HOOKTYPE_CAN_SEND_TO_CHANNEL prototype changes from:
int hooktype_can_send_to_channel(Client *client, Channel *channel, Membership *member, const char **text, const char **errmsg, SendType sendtype);
To:
int hooktype_can_send_to_channel(Client *client, Channel *channel, Membership *member, const char **text, const char **errmsg, SendType sendtype, ClientContext *clictx);
A side-affect of this change for antimixedutf8 purposes is that,
while the analysis is only done once per line, the 'actions' are
performed for each target, so the action will run 4 times for
"PRIVMSG a,b,c,d :text" although that may not be important in
practice. Just mentioning.
I started work on this back then but didn't finalize it. Now I
have to figure out what was left to be done :D. Other than the
obvious case of seeing some debugging code that prints out for
every converted character. Not yet visible / usable by end-users!
Also fix documentation for ~10 hooks to mention the hook name.
Obviously, the maxperip module is loaded by default (in modules.default.conf)
but it is nice to have the 400+ lines contained in a separate module
rather than being in the nick module that does NICK/UID handling.
Will look at moving more later..
It now passes 'clictx' which at the moment only has clictx->cmd which
points to the command handler. So only useful in very few cases where
you have like a generic command handler and thus have no idea for which
command you are being called. In the future, with this new ClientContext
struct, we can simply add new fields to the struct without breaking
things in the core and in (third party) modules.
If you use the magic functions in your modules CMD_FUNC(cmd_mycmd),
OVERRIDE_FUNC(myoverride), CALL_NEXT_COMMAND_OVERRIDE() and such then
you shouldn't have any compile errors as these will use the correct
prototypes and variable names automatically. In a few cases you can't
use these, in which case you will need to update your modules.
mostly with regards to memory leaks if duplicate config directives are used.
Eg using allow::password twice in the same allow block, or using
link::outgoing::tls-options twice in the same link block. Unusual stuff.
Previously if a new history item was added (because someone sent a message)
we would always append at the end of chat history buffer of the channel.
Now we put the message at the position decided by the "time" message tag,
which could be at the end but also slightly before that.
* Upside: should result in a consistent chat history on all servers
* Downside: if your server time is off for several seconds then it
could look a little weird. Then again, it would already have looked weird
in real live chat with timestamps and when replaying chat history probably.
Also add some simple optimizations: in the log line object we now have direct
pointers to the msgid and time strings, so the code doesn't need to do a
find_mtag() all the time. This should lower CPU usage during log playback
and also makes things more simple in the source code.
I did some testing with various history injection variants but this needs
more extensive testing.
I was dumb: with an RSA cert you need ECDHE-RSA-* and i had
only included ECDHE-ECDSA-*. Long story short: TLSv1.2 didn't work
if you had an RSA certificate. Reported by BlackBishop, and in
hindsight also by Mi_92. Thanks for the quick reports, this should
be a quick fix :-)
For reference, the established TLS connections at irc*.unrealircd.org
over the past 6 months were:
14379 TLSv1.3-TLS_CHACHA20_POLY1305_SHA256
368 TLSv1.2-ECDHE-ECDSA-AES256-GCM-SHA384
160 TLSv1.2-ECDHE-ECDSA-CHACHA20-POLY1305
3 TLSv1.3-TLS_AES_256_GCM_SHA384
There is nobody connecting with AES CBC in those statistics
(ECDHE-ECDSA-AES256-SHA256 and ECDHE-ECDSA-AES128-SHA384)
In config.h we had a:
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
#define UNREALIRCD_DEFAULT_ECDH_CURVES "X25519:secp521r1:secp384r1:prime256v1"
#else
#define UNREALIRCD_DEFAULT_ECDH_CURVES "secp521r1:secp384r1:prime256v1"
#endif
...which is fine in theory, but openssl headers are not included at that point,
so OPENSSL_VERSION_NUMBER was not defined.
From now on, we have:
#define UNREALIRCD_DEFAULT_ECDH_CURVES_PRIMARY "X25519:secp521r1:secp384r1:prime256v1"
#define UNREALIRCD_DEFAULT_ECDH_CURVES_SECONDARY "secp521r1:secp384r1:prime256v1"
...and we try them in that order. If both fail, we exit with an error (like before).
This because X25519 is not available in OpenSSL before 1.1.0 (so really old)
and may also not be available when running in FIPS mode.
+#define HAS_ASN1_TIME_diff
+#define HAS_SSL_CTX_SET_MIN_PROTO_VERSION
+#define HAS_SSL_CTX_SET_SECURITY_LEVEL
+#define HAS_X509_check_host
+#define HAS_X509_get0_notAfter
In practice, this only adds that we now do certificate expiry checks
and give warnings, like on *NIX.
The HAS_X509_check_host is good because then OpenSSL/LibreSSL code is
used instead of the one we have from cURL and the ssl conservatory.
To be honest I wanted to rip out this fallback completely at first,
but let's do that in next major version of UnrealIRCd and not during
an existing series.
The HAS_SSL_CTX_SET_* would have given an admin the option to downgrade
to TLSv1.0 or TLSv1.1 but LibreSSL no longer builds with these since
LibreSSL 3.8.1, which is sensible, so... no actual change there.
I'll document the behavior in the docs (wiki), though.
Also the previous claim in b653c68df0 with
regards to what curves were actually enabled in our LibreSSL UnrealIRCd 6
builds was incorrect, an hour ago I claimed X448 would show up as an extra,
but that is not the case (that was with OpenSSL). The correct statement is:
"This also meant the default curves that were offered were up to LibreSSL,
which meant the following list in practice:
Elliptic curves offered: prime256v1 secp384r1 X25519
Instead of:
Elliptic curves offered: prime256v1 secp384r1 secp521r1 X25519"
So it was only missing secp521r1. Nothing major.
"[error] ecdh-curves specified but your OpenSSL/LibreSSL library does not
support setting curves manually by name. Either upgrade to a newer library
version or remove the 'ecdh-curves' directive from your configuration file"
This also meant the default curves that were offered were up to LibreSSL,
which meant the following list in practice:
Elliptic curves offered: prime256v1 secp384r1 secp521r1 X25519 X448
Instead of:
Elliptic curves offered: prime256v1 secp384r1 secp521r1 X25519
Not that X448 is considered bad, it just didn't match what we claimed in
the docs at https://www.unrealircd.org/docs/TLS_Ciphers_and_protocols
Fixed by: #define HAS_SSL_CTX_SET1_CURVES_LIST
* [Security group blocks](https://www.unrealircd.org/docs/Security-group_block)
are now hidden in lists by default. If you want the security group to be shown
in things like `MODE #channel +b ~security-group:x` (which shows a list)
then you need to use `public yes;`. The default security groups
like known-users, webirc-users, etc. are public by default.
Eg: vhost "$operlogin@$operclass.example.net";
Also add potentially_valid_vhost() function which can be used in
config code to ignore invalid $vars. Then at runtime you use the
real valid_vhost() function after variable expansion by
unreal_expand_string().
and use it not only from vhost { } block code but also for like
blacklist::reason.
This so the same variables with the same names are available at
those places.
Supported are:
$nick, $username, $realname, $ip, $hostname, $server, $account,
$operlogin, $operclass, $country_code (xx for unknown),
$asn (0 for unknown).
* Convert to use module-based config handling
* Split part of VHOST command into do_vhost() for later
* Use AppendListItem instead of AddListItem so they are in config-order.
This is not really important atm but will matter later if we go auto.
* No other code changes at this point
This so if there is ever an issue, we can hot-patch it. This affects
exit_client(), exit_client_fmt(), exit_client_ex(), banned_client(),
and various (internal) help functions.
This also means you cannot call these functions during TEST/INIT (eg
during REHASH) since the 'quit' module which provides these modules
may not be loaded yet. I don't think that's a situation/problem but
this needs some more testing.
This was in src/hash.c, src/list.c and src/modules/stats.c.
Now all in src/modules/nick.c... or should this go into a new module?
Again, this needs some more testing, like previous commit.