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

3304 Commits

Author SHA1 Message Date
Bram Matthys db6476e1ab ModData API (internal): split the single linked list into 7 lists, to speed
up moddata_client_get() etc -> findmoddata_byname().
Apparently we have 52 moddata registrations (that is without 3rd party modules)
so otherwise it is a loooong linked list.
2025-09-29 16:22:08 +02:00
Bram Matthys 51625592cb Get rid of a memset() of 16k in labeled response implementation.
This was done in lr_pre_command() and lr_post_command().
Nowadays we have BIGLINES stuff from servers that cause MAXLINELENGTH
to be 16k, so the LabeledResponseContext ended up being 16k+.
Although we normally have the policy to zero out complete structs
in UnrealIRCd instead of only individual members (for safety,
easy to overlook security bugs), in this case we will do zeroing
of struct members explicitly. Added some warnings about this too
in the source code. Zeroing 16k twice for each command is a bit
too much waste.
2025-09-28 18:24:23 +02:00
Bram Matthys e3b92cc084 away_join() optimization: don't bother if user is not away.
Otherwise we are iterating <num channel members> all for nothing.
2025-09-28 16:20:19 +02:00
Bram Matthys a2e099bf47 Extbans: fix various syntax error / usage examples where old single letter
is used instead of the full name (eg ~S instead of ~certfp).
We have named extended bans since UnrealIRCd 6.0.0 (2021) already...
2025-09-25 19:27:34 +02:00
Bram Matthys ddfe7c535c Make TLINE use server_ban_parse_mask() so it uses the same logic as GLINE.
This fixes something like TLINE ~country:us not automatically converting
to ~country:US, since previously conv_param() was not called. But it also
means other code is used in the same way as GLINE (other type of rejections),
for example invalid server ext ban will print a better error with syntax
info (e.g. TLINE ~certfp:xx).

That ~country issue was reported by adamus1red in https://bugs.unrealircd.org/view.php?id=6581
2025-09-25 19:16:11 +02:00
Bram Matthys 65b69f9164 Sync away_since in S2S traffic from now on.
See also comment in f42bab778e
about away_since in JSON-RPC.
2025-09-24 13:47:53 +02:00
Bram Matthys 602f6c7238 URL API: add .minimum_tls_version, and use TLS1_3_VERSION for central-blocklist.
Something like:

 #ifdef TLS1_3_VERSION
        w->minimum_tls_version = TLS1_3_VERSION;
 #endif
        url_start_async(w);

Require TLSv1.3 for central-blocklist and spamreport calls, unless your
OpenSSL does not support it, which should be rare.

At some point in the future I will make this endpoint TLSv1.3+ only.
2025-09-21 14:24:06 +02:00
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 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 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 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
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 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 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 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
alice 2c7bcebaca Make spamfilter:input-conversion accept deconfuse and deconfused for confusables (#316) 2025-08-01 07:39:43 +00: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 eae1a2e99a Remove some check for U4 (<4.0.16+). Shouldn't matter but otherwise
one could possibly miss this cert verification warning. And since
that will later become an error, it is even more important to
notice such a (hopefully unusual) case quickly.
2025-07-26 13:34:40 +02:00
Bram Matthys 6b0d81fb77 Make a warning actually a warning 2025-07-26 13:31:50 +02:00
Bram Matthys a73186362b * Add link::options::no-certificate-verification
* Code cleanup: split connect flags in CONNECT_OUTGOING_* and CONNECT_*
* Don't print tls_link_notification_verify() stuff for localhost conns
2025-07-26 13:26:46 +02:00
Bram Matthys 26fb6b70d6 Fix localhost S2S link downgrading link-security.
On the incoming side it was correctly identified as link sec 2,
but on the outgoing side the localhost check failed and caused link sec 1 or 0.

Bug has beent here for a while but I don't think many people
link two UnrealIRCd servers over localhost that are on production
(i do, when dev'ing, but then I don't care about linksec, obviously)

Also, this wouldn't flag services from 2 to 0 because this bug only
affected outgoing UnrealIRCd server connections.
2025-07-26 13:24:00 +02:00
Bram Matthys 8f23550122 Since 2017[*] we warn about active MITM risks if a cert of a server link is
not verified. This changes the wording from "You may want to consider" to
a warning, makes it more strong and that in the future we will reject this
by default.

Actually still pondering to reject it now already by default, but let's start
with this commit first...
2025-07-26 12:22:49 +02:00
Bram Matthys 8a4dae71fb Fix compile problem with LibreSSL (and possibly OpenSSL <3.0.0).
Caused by 31d51fbb04
2025-07-24 15:40:43 +02:00
Bram Matthys 9035859f0e Channel flood protection is now on by default. You can use +F to override.
[Channel flood protection by default](https://www.unrealircd.org/docs/Channel_anti-flood_settings):
This is an important change that IRCOps and chanops should know about:
* By default we now apply the anti-flood profile "normal", which should be fine for most channels.
* If a chanop does not want this they can override this by setting
  `MODE +F` with [another profile](https://www.unrealircd.org/docs/Channel_anti-flood_settings#Channel_mode_F_profiles).
* For example, for a channel with hundreds of users and lots of activity
  `+F relaxed` may be more appropriate. Or, chanops can turn anti-flood
  off entirely by setting `+F off`
* The reason for this change is that many admins and chanops in practice
  don't seem to use `+f` or `+F`. With this change they are now protected "by default"
  when no MODE `+f` or `+F` is set.
* Advanced users can can grab the detailed effective settings with `MODE #test F`
2025-07-16 14:59:42 +02:00
Bram Matthys 31d51fbb04 * UnrealIRCd can now be used if your OpenSSL does not provide MD5
(there will be an error if you use `cloak_md5`, but everything
  will work fine if you use `cloak_sha256`).

We phased out MD5 usage years ago, so it is only contained to
the old cloaking module. In fact that was the only reason we
started to provide the SHA256 cloaking module, simply so it
isn't using old MD5.

Of course, for module coders this means they should not call
DoMD5() or md5hash(), but that would be rare. Currently zero
modules in unrealircd contrib do this and it makes no sense
to start using it nowadays anyway.
2025-07-15 19:09:32 +02:00
Bram Matthys 93980ee004 Include TextAnalysis in antimixedutf8 hit as well. And use "text_analysis"
and not "textanalysis" for the JSON, to keep naming of multi-word stuff
consistent.

Example:
--snip--
  "text_analysis": {
    "antimixedutf8_points": 20,
    "unicode_blocks": 9,
    "num_bytes": 55,
    "num_unicode_characters": 20,
    "deconfused": "Valware is ualwaring",
    "deconfused": "This is a testtestte",
    "unicode_blockmap": {
      "Basic Latin": 2,
      "Latin Extended-B": 2,
      "IPA Extensions": 1,
      "Greek and Coptic": 1,
      "Latin Extended Additional": 2,
      "Greek Extended": 1,
      "Number Forms": 1,
      "Tifinagh": 1,
      "Mathematical Alphanumeric Symbols": 7
    }
  },
2025-07-14 18:41:04 +02:00
Bram Matthys d135e687c3 Add TextAnalysis on spamfilter hit in the JSON logs. 2025-07-14 18:11:59 +02:00
Bram Matthys 93720a9533 Fix OS JUPE still allowing server in.
Since UnrealIRCd 6.0.0 when a server connects, we like to drop the
existing link so they don't need to wait on "Ping timeout".
However, that goes against the JUPE stuff that Services tend to use,
it basically negates it.

We now check if the uplink is u-lined (like for services) and if that
is the case we deny the link with "Server Exists (Juped)". So just
like before U6, and with a slightly more helpful message even.

Reported by Jellis in https://bugs.unrealircd.org/view.php?id=6498
2025-07-13 10:53:46 +02:00
Bram Matthys 97a87bdca8 Fix reputation score not expiring after 30 days of inactivity.
We now expire after 30d if score is <12 (so 1 hour of being online)
and we expire after 90d regardless of score.

Note that for this to work, all servers would need to be running
UnrealIRCd 6.2.0+ because when a score for an IP is still present
on any of the servers on a network, and a user with that IP connects,
then the score will be broadcasted from the server that still has
the score and it will be re-added by all servers with that score.

But eventually it should be like this... :D

Reported by armyn in https://bugs.unrealircd.org/view.php?id=6536
2025-07-13 10:22:40 +02:00
Bram Matthys cd2deeb1e7 Add spamreport::on-server-ban. If set to yes, then the spamreport
block runs when a user is *LINEd.

TODO: avoid double sending on spamfilter with action { report; gline; }
2025-07-12 18:14:40 +02:00
Bram Matthys 96a2ea5c02 Add HOOKTYPE_BANNED_CLIENT 2025-07-12 18:06:52 +02:00
Bram Matthys 301fb911e8 When submitting to Central Spamreport, include TextAnalysis and
bump sending of last commands from "last 10" to "last 20".
2025-07-12 17:21:56 +02:00
Bram Matthys cb17d58db0 Some small changes to previous commit:
* 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
2025-07-06 09:19:04 +02:00
Valerie Liu 6a6dd66c84 Add HOOKTYPE_CAN_USE_NICK to allow modules to reject certain nicks (#313)
* Add `HOOKTYPE_CAN_USE_NICK` for modules to disallow certain "internal-use" nicks
* Run the hook on local NICK commands
2025-07-06 07:10:58 +00:00
Bram Matthys c836f394e5 Central Blocklist: make "error contacting CBL" error message more verbose
Show the actual error, like connection timed out, HTTP 500, etc.
2025-04-22 08:00:46 +02:00
Bram Matthys 30ff1bf09e Add a TODO item 2025-03-27 17:51:32 +01:00
Bram Matthys 641413cfa9 Update Unicode block lists with Unicode 16.0.0 from 2024-02-02.
And provide instructions on how to generate this thing.
2025-03-24 09:32:50 +01:00
Bram Matthys cc75840189 Add unicode_count() crule, e.g. unicode_count('Emoticons')
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.
2025-03-23 18:14:32 +01:00
Bram Matthys fafe16a673 AntiMixedUTF8: change emoticon transition score from 1 to 0
You will still get a score of +1 if afterwards changing back to Latin
or anything else, but at least the Latin/anything -> Emoticon
transition is free now (score 0). And if ending with an emoji it
also means a score 0 (as far as this is concerned).
2025-03-23 13:21:01 +01:00
Bram Matthys 74e17b7a26 Make SPAMINFO show the UTF8 block names a text uses.
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
2025-03-23 13:03:58 +01:00
Bram Matthys 6bd6e974d4 Add num_bytes and num_unicode_characters to TextAnalysis struct.
Also so you can easily put the unicode_blockmap[] in perspective
e.g. if you want to do percentages.
2025-03-23 12:43:01 +01:00