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

10741 Commits

Author SHA1 Message Date
Bram Matthys fea60e8fc7 And add the link.
[skip ci]
2026-07-05 13:16:13 +02:00
Bram Matthys e77eb9e923 Add reformat notes. Maintaining a fork or patches? Read this commit!
This commit adds a release notes entry about the reformat, and this
commit message also contains migration instructions for people who
maintain a fork or maintain a set of patches. See further below.

== BACKGROUND ==

In July 2026 the entire UnrealIRCd 6 source tree was reformatted with
clang-format. The main commit is:
  548d66d26c
That commit is exactly what 'make format' produces with clang-format
version 21.1.8, with nothing else mixed in. It only changes whitespace:
we verified that the code itself is exactly the same as before, down to
the last character. It was preceded by a few small preparation commits
(the first being 2d8df60e14) and followed
by one more commit with whitespace fixes
(b785d69309).

== GIT BLAME ==
All the commits mentioned above are listed in .git-blame-ignore-revs,
so 'git blame' and the blame view on GitHub ignore them, giving a
more usable blame view. To get that behavior locally, run this once
in your working copy:

  git config blame.ignoreRevsFile .git-blame-ignore-revs

== MIGRATION INSTRUCTIONS FOR FORKS AND LOCAL PATCH SETS ==

The following instructions were suggested by Claude (AI) and are
completely untested (as I, Syzop, don't maintain a fork myself).

Do not merge straight across the reformat: you would get whitespace
conflicts in nearly every file you ever touched. Instead, first bring
your own tree into the same formatting, as described below. You need
clang-format major version 21 (upstream used 21.1.8); other versions
format slightly differently. Check with: clang-format --version

If your fork is a branch that merges upstream from time to time:

  1. Merge upstream up to just BEFORE the reformat (note the ^):
       git fetch upstream
       git merge 548d66d26c3e8e52ada71de84f07569fcee33f69^
     Resolve ordinary conflicts as usual.
  2. Reformat your own tree with the same tool and commit it:
       make format
       git commit -a -m "Reformat to match upstream clang-format"
     After this, all code that you share with upstream is formatted
     exactly the same as upstream, so git has nothing left to fight
     over there.
  3. Merge the rest, which is now nearly conflict-free:
       git merge upstream/unreal60_dev
  4. Add YOUR reformat commit hash from step 2 to
     .git-blame-ignore-revs and commit that.
  5. Verify: 'make format' followed by 'git diff' must show nothing.

If your fork is a rebased patch series instead: rebase onto
548d66d26c3e8e52ada71de84f07569fcee33f69^ first and fix ordinary
conflicts there, then continue with:

  git rebase -X ignore-space-change

onto the current upstream tip, run 'make format', and fold the result
into your patches or keep it as one extra commit at the end of the
series. Then verify here too: 'make format' plus 'git diff' must show
nothing.

From then on, run 'make format' before committing (or use your
editor's clang-format integration with the in-tree .clang-format
config) and your merges will contain less whitespace noise than ever.
2026-07-05 13:13:37 +02:00
Bram Matthys e2ae87911d Bump version to 6.2.7-git and add placeholder/empty release notes 2026-07-05 12:56:10 +02:00
Bram Matthys b3c867405d Add .git-blame-ignore-revs so 'git blame' and the GitHub blame view
skip the big clang-format commit and the whitespace followup commit.
2026-07-05 12:49:51 +02:00
Bram Matthys b785d69309 Fixes after clang-format, as planned. These are whitespace only.
These were not a surprise, but deliberate: we let the previous
clang-format commit be 100% clang-format job (so reproducable)
and after that we planend and did this commit, because we chose
to leave some stuff alone and do it manually.

This commit will (also) be added to .git-blame-ignore-revs
2026-07-05 12:28:37 +02:00
Bram Matthys 548d66d26c Reformat all source code, using 'make format' (clang-format 21.1.8)
This reformats entire UnrealIRCd source code, according to
.clang-format which was previously commited.

This is reproducable using clang-format version 21.1.8.

These are only visual changes, they have no effect on code.

This commit will be added to .git-blame-ignore-revs so 'git blame'
and the similar blame view on GitHub will ignore this commit.
2026-07-05 12:11:51 +02:00
Bram Matthys 678aeb5c17 clang-format preparations: add some clang-format off
to a couple of tables, SetXX/ClearXX macros in struct.h
and RPL_* and ERR_* in numeric.h.
Also merge MSG_* block so they align the same.
2026-07-05 11:27:46 +02:00
Bram Matthys 391a94cdd4 clang-format preparations: trailing comma in structs/lists and such:
* Add a trailing comma after the last element. Without it clang-format
  glues the closing brace onto the last element, like "NULL};".
* Write '= {' on the declaration line instead of a lone '{' on the next
  line. clang-format keeps such a lone '{' as-is but gives it and the
  whole body an extra continuation indent, which looks weird.
2026-07-05 10:01:22 +02:00
Bram Matthys f820c86285 More clang-format preparations: some // comments in structs that
actually don't belong to a variable but are like instructions
if someone is adding new members, or they are for grouping,
move these to the top doxygen comment because otherwise future
clang-format would align them in separate groups which looks ugly
2026-07-05 09:26:30 +02:00
Bram Matthys 3c6b552df5 More preparations for clang-format: a few long and multi-line comments
were changed so when we run 'make format' in the future it looks better.
2026-07-05 09:13:56 +02:00
Bram Matthys 27f6eaf474 More preparations for clang-format: move some #define outside of a group
Because otherwise they all line up.. even though they are completely
unrelated (clang-format doesn't know that :D, it needs a empty line)
2026-07-04 21:17:56 +02:00
Bram Matthys eb19896628 clang-format: AlignTrailingComments::Kind: include/ vs src/
If we have this on "Always" then in .c files it will also align /* comments */
which is very shitty, you get things like:
    n = callsomefunc(hfdshfsd, fdhshfsdhsfd, fdshsfdhfsd, fsdhsfdh); /* try this first */
    if (n == 1)                                                      /* n is one! */
something we definately do NOT want.

But in include/ the results is quite pretty, in all the structs, enums, etc

So we now have different settings in src/ vs include/ and this means that
in src/ we loose it for structs, but manual alignment is already good there,
just something to keep in mind if adding new stuff.
In include/ it is a real benefit when we run make format, so keep it there..
2026-07-04 21:14:48 +02:00
Bram Matthys 2d8df60e14 More clang-format preparations
* We will have #ifdef.. then space+#define etc.. indentation.. but
  we obviously don't want that for include guards like
  #ifndef __struct_include__ because then like 3000+ lines in
  include/struct.h will start with a space. Now, clang-format has
  detection for this, but it doesn't kick in at 2 files (including
  include/struct.h) because of a minor thingy we fix here.
* Add clang-format off to a few tables, who were auto generated
  or copied anyway.
2026-07-04 20:18:44 +02:00
Bram Matthys 68e5ce7cbb ** UnrealIRCd 6.2.6 ** 2026-07-02 18:11:11 +02:00
Bram Matthys a289fbf14f Fix possible crash in multiline implementation 2026-07-02 18:10:49 +02:00
Bram Matthys e3bf09622a Add .clang-format and "make format" target. Not running it yet though...
The actual mass reformat is planned post-release.
2026-06-24 09:58:25 +02:00
Bram Matthys 4011da6d98 Preparations before clang-format 2026-06-24 09:35:44 +02:00
Bram Matthys 684f6515d4 "CAP LS" may only respond 1 line, we now advertise less. "CAP LS 302" unaffected.
When not using version 302, such as with "CAP LS", the specification does not
allow us to use continuation lines. This means all advertised caps must fit
into one line. That is no longer always the case, especially if you load 3rd
party capabilities. So we need to scratch advertising some capabilities to
<302 clients.

"CAP LS 302" is unaffected. Note that version 302 in the specification exists
since at least November 2017, so most clients use that one.

According to https://ircv3.net/software/clients the following clients are
affected by this change:

Desktop Clients
* KVIrc
* Circe
* catgirl
* BitchX
* Pidgin
* LimeChat

Mobile Clients
* IRC for Android
* LimeChat

And various older versions of other clients (obviously).

NOTE: The source is only that IRCv3 page. I did not check manually.

For this particular commit. We filter out various unrealircd.org informative
CAPs and the vendor specific json-log. So that isn't much of a problem.
However, in the future we may be forced to filter out more capabilities to
make room. It would be much better if all clients are on >=302. Also, I
should mention we are not the only IRCd out there, so I can't vouch on what
other IRCds (will) do when hitting this non-302-limit.

Reported by ProgVal in https://bugs.unrealircd.org/view.php?id=6630
2026-06-22 09:19:38 +02:00
Bram Matthys 12d92fcba5 a more minor update:
1) obviously only provide ASan report if relevant (eg memory issue),
   not for like priv escalation :)
2) "If you are submitting issues and fail to follow the procedure above"
   was in the AI/tooling paragraph, but just in case someone reads it
   out of that context we now scope AGAIN it to that ONLY.
   This so normal users (that have nothing to do with AI/tooling)
   are not scared off in reporting real issues.

[skip ci]
2026-06-21 10:15:38 +02:00
Bram Matthys 5a93480976 SECURITY.md: add "Scope" and "Use of AI or other tools"
And a minor README.md update to add a few more links.
2026-06-21 09:47:21 +02:00
Bram Matthys cf5703fec0 Windows packager: get rid of in-innosetup-signing (handled outside this now) 2026-06-20 14:01:41 +02:00
Bram Matthys 2475f25596 ** UnrealIRCd 6.2.6-rc1 ** 2026-06-20 10:53:01 +02:00
Bram Matthys 3fafd32067 Fix end marker missing for 0 result in some CHATHISTORY BETWEEN. 2026-06-20 09:35:16 +02:00
Bram Matthys 8d1df6a823 Make nofakelag also mean that deliberate add_fake_lag() does not lag up.
Eg on failed oper attempts, that sort of things. Previously it was still
adding fake lag. This complicated unrealircd-tests :).

As always, nofakelag should never be used in normal conditions, it
disables the most important protection we have (fake lag bumping).
If you want lower lag for a group of users, the right tool is
set::anti-flood::name-of-security-group::lag-penalty and ::lag-penalty-bytes
See https://www.unrealircd.org/docs/Special_users
2026-06-20 09:22:20 +02:00
Bram Matthys 09a732e2c1 Redo draft/chathistory-end from yesterday in a different way.
The previous mechanism (from yesterday) was a bit too simple at the
chathistory.c where returned_lines < limit would set the end tag but
it would not deal with the situation where returned_lines == limit
which is ambigious. So we had to move up a layer (or is it down?),
don't handle this in chathistory.c but in the backend. A new struct
field r->reached_end was added for this (set by backend).
2026-06-20 08:32:28 +02:00
Bram Matthys 570c32ea67 Fix CHATHISTORY TARGETS sending one target too little if limit is hit
And attach draft/chathistory-end when exactly 'limit' targets exist
and nothing more.
2026-06-19 21:33:49 +02:00
Bram Matthys 37977fcfe6 Don't send draft/chathistory-end for AROUND. As around does not have
a directorion, but is a midpoint, and we send X lines above Y under,
so end does not make sense there anyway (which of the two ends?).

We simply avoid sending it.
2026-06-19 21:28:15 +02:00
Valerie Liu 59d497726b chathistory: implement draft/chathistory-end tag (PR #337)
Signals to the client that it has reached the end of the history and
there are no more messages to fetch. The tag is attached to the BATCH
opener when the server returns the last page of results.

Only sent to clients that negotiated the draft/chathistory capability.
2026-06-19 21:19:10 +02:00
Valerie Liu f5d59dd152 Support ratified tags for reply-tag and no-implicit-names (PR #336)
The IRCv3 specifications for these have been ratified:
- https://ircv3.net/specs/client-tags/reply
- https://ircv3.net/specs/extensions/no-implicit-names

Both the draft and ratified names are supported during a transition period.
2026-06-19 20:17:02 +02:00
Bram Matthys ecde1b6479 Add bounds checking to message_tag_escape().
This fixes an OOB write that cannot be reached by users. Only a
hostile server could cause it in some situations. Even then, in
my tests this did not cause a crash (it goes into bss too, not
heap or stack).
2026-06-19 19:43:13 +02:00
Bram Matthys b5f45d0160 Update NULL check in config_item_allowed_for_config_file() - no real issue.
This is unreachable in current code paths, but could be some day.
2026-06-18 19:55:59 +02:00
Bram Matthys 320d2c28ef Fix theoretical OOB write in chmode_str(). In practice this is no issue.
Not in UnrealIRCd itself: it is only used in one place, STATS with a
big buffer. And unrealircd-contrib 3rd party modules has no consumers.
2026-06-18 19:20:26 +02:00
Bram Matthys d7962e1bbb Fix crash (NULL pointer) with old-style set::anti-flood block
(we should actually remove this one day :D)
2026-06-17 20:43:18 +02:00
Bram Matthys e7459df725 Another URL API fix 2026-06-17 20:38:46 +02:00
Bram Matthys 4966b59812 Update release notes
[skip ci]
2026-06-17 19:49:35 +02:00
Bram Matthys c100059fa7 Add new function: append_name_list(). Use it at two places where we
print copy-pastable config blocks. Previously we used add_name_list(),
which uses insert at beginning, which would reverse the order.

Also changed duplicate_name_list() to preserve order. Previously
it reversed the order of all items.
2026-06-17 18:41:09 +02:00
Bram Matthys ce6f078262 Deal better with multiple spkifp, such as ECC + ML-DSA. We now cache them
and "./unrealircd genlinkblock" outputs multiple password ".." { spkifp; }
lines in such a case.

Other than that some cleaning up of recently-added-functions that are
now no longer needed: we now create ctx_link_server and ctx_link_client
that represent set::server-linking::tls-options for incoming and outgoing
links. Which can be NULL, and then we use ctx_server / ctx_client (set::tls).
Also add proper documentation on this.

When using ./unrealircd spkifp, tell ./unrealircd genblock is cooler.
Nah.. it takes more factors into account, genlinkblock, so is preferred :D
2026-06-17 15:45:01 +02:00
Bram Matthys 1162da4a9e * Server linking and certificates: we now treat listener blocks that are
`serversonly` (such as port 6900 in the example.conf) and link { } blocks
  in a different way than regular listen { } blocks:
  * If there are different certificates used in the serversonly listen block
    vs link blocks, then this is almost always means server linking is broken,
    so we now print a warning on boot and rehash.
  * We also print an 'advice' if any of these are not using (long-lived)
    self-signed certificate. This is because CA issued certificates are
    typically not suitable because they typically rotate keys and thus change
    the `spkifp`. Changing spkifp breaks server linking. We will now print
    an advice along with command and config block instructions to fix it.
  * We now use `set::server-linking::tls-options` for link { } blocks
    and listen { } blocks that are `serversonly`. All the rest uses the
    `set::tls` settings by default (eg the regular listen { } block on 6697).
    * This means our guide on
      [Using Let's Encrypt with UnrealIRCd](https://www.unrealircd.org/docs/Using_Let's_Encrypt_with_UnrealIRCd)
      and generic usage is more intuitive. You just set both set settings
      and then no longer need to use any tls-options in listen blocks or link
      blocks. The example conf has also been updated with this.
    * If `set::server-linking::tls-options` is not configured, it defaults
      to `set::tls`, so there is no unexpected behavior change for anyone.
  * In a future release we will make server linking with `spkifp` mandatory,
    so all of this helps with getting people ready for that, making such
    a future transition smooth.

TODO: Update wiki, better wording in release notes, etc.

This also changes the default example conf:

/* RECOMMENDED:
 * Everyone should be using IRC over SSL/TLS on port 6697. However, to use
 * it properly, you have to get a "real" certificate instead of the
 * self-signed default certificate that was generated by the installer.
 * The Let's Encrypt initiative allows you to get a free certificate that is
 * issued by a trusted Certificate Authority. Instructions are at:
 * https://www.unrealircd.org/docs/Using_Let's_Encrypt_with_UnrealIRCd
 *
 * When you follow that guide you will have a "dual certificate" setup:
 * set::tls:
 *   Your trusted CA certificate, served to clients on port 6697.
 *   (key and certificate change and renew every xx days automatically)
 * set::server-linking::tls-options
 *   A long-lived self-signed certificate for server linking, with
 *   a stable 'spkifp' signature that you use in link blocks.
 *   This certificate is used automatically in "serversonly" listen blocks
 *   (port 6900 in this configuration file) and automatically used for all
 *   link { } blocks.
 *
 */
//set {
//      tls {
//              certificate "/etc/letsencrypt/live/irc.example.org/fullchain.pem";
//              key "/etc/letsencrypt/live/irc.example.org/privkey.pem";
//      }
//      server-linking {
//              tls-options {
//                      certificate "tls/server.cert.pem";
//                      key "tls/server.key.pem";
//              }
//      }
//}
2026-06-16 20:50:56 +02:00
Bram Matthys 8d783204dd JSON-RPC: Remote RPC was broken and causing "not authorized" error messages.
This was used by `server.rehash` and `server.module_list`. Plus,
this release `user.get` under some circumstances. This is now
fixed but requires the target server to be on UnrealIRCd 6.2.6.
If the target server does not meet this condition then we error
telling the server "does not support remote JSON-RPC".

This was first reported by AdmiraL- in https://bugs.unrealircd.org/view.php?id=6611
2026-06-13 16:04:43 +02:00
Bram Matthys 2089aa4ec4 In RPC_CALL_ERROR show the actual error 2026-06-13 14:49:11 +02:00
Bram Matthys 7667307b0e JSON-RPC user.get can now expose more fields by forwarding the request
to the server where the user is actually on. Think of idle time etc.

* JSON-RPC: We can now route `user.get` requests to the server that user is
  on. This so we can fetch all fields for that user (including flood
  counters, idle time, snomask) that are normally not available remotely.
  * We do this automatically in `user.get` when `object_detail_level` is 5+.
  * You can force this explicitly with `object_remote_fetch` set to `true`.
    So you can also use it with detail level 2 if you want, e.g. if you
    don't need the flood counters but do want the idle time.
  * When RRPC is not available we answer ourselves (so safe fallback, but
    you won't have the local-only fields).

Oh and we deliberately don't do this in `user.list`, as doing it there
would mean a single request could result in hundreds of semi-`user.get`
calls across multiple servers.
2026-06-13 12:40:44 +02:00
Bram Matthys 65f918e8e9 Add json_expand_flood_counts() and make available in Central Spamreport
and JSON-RPC.

This exposes the newly added flood counters from
4384f1127b and
029675f867 in JSON.

I didn't want to put it in every JSON log message. So right now it
is only in:
* JSON-RPC with object_detail_level >= 5.
* Central Spamreport

I may expand it later to one or a few other areas.
2026-06-13 12:09:09 +02:00
Bram Matthys 3000381493 Fix multiline-concat behavior for fallback clients.
We were merging draft/multiline-concat lines together server-side before
sending them to non-multiline clients. This could truncate oversized merged
lines. We now simply send them as separate lines.

Reported by ProgVal in https://bugs.unrealircd.org/view.php?id=6628
2026-06-13 10:29:46 +02:00
Bram Matthys 029675f867 Similar to previous, add total_channel_flood_count() for +f/+F limits exceeded
* `total_channel_flood_count('..setting..')` returns the number of
  times `+f`/`+F` limits were exceeded by that user in all channels
  the user is or was in. Available are: `nick`, `join`, `knock`, `msg`,
  `ctcp`, `text`, `repeat` and `paste` (and `all` for the sum).
2026-06-13 07:46:51 +02:00
Bram Matthys 4384f1127b Crule: new server_flood_count() for nick, away, join etc floods.
Suggested by westid in https://bugs.unrealircd.org/view.php?id=6477

* New [crule function](https://www.unrealircd.org/docs/Crule) that return
  the number of times a flood was blocked for that user. For example,
  `server_flood_count('away')` returns the number of time away-flood
  was exceeded. Aslo available: `nick`, `join`, `invite`, `knock`,
  `vhost` and `conversations`. Plus, there is `all` for a total of all.
  * This can be used in a security-group::rule or spamfilter::rule.
    Eg: `spamfilter { rule "server_flood_count('nick')>4"; action gline; }`

This also - internally - adds a mechanism to run spamfilter rule-only-
filters after the command handler, whenever a tag value or other thing
changed. That's part of this commit.
2026-06-12 17:43:51 +02:00
Bram Matthys e2ed1ceca2 Load multiline by default and update release notes a little. 2026-06-11 19:57:53 +02:00
Bram Matthys 57ca415c26 Add whitespace deletion in buildvarstring() so template can have a space.
Basically if a $variable is empty, and there is a space before it in the
template string then we delete that space.

May seem (or is) a bit over the top but this way the template stays clean,
and it may be used/useful in other places as well.

This is a behavior change, but I think we can live with it. One can opt-
out via BUILDVARSTRING_KEEP_SPACE_FOR_EMPTY_VAR.
2026-06-11 19:19:53 +02:00
Bram Matthys 5850ec9434 Show TKL IDs (and related spamfilter TKL ID, if any) in TKL_ADD, TKL_DEL,
TKL_EXPIRE and SPAMFILTER_MATCH messages.

This uses the newly added functions log_data_optional_string() and
log_data_optional_name_value(). The first shows the optional string
like "abc" and the second expands to "[name: value]". What's also new
is that both of these will swallow a preceding space if there is no value.
This so you can just use "Something. $optional_string" and it will
expand to "Something." if $optional_string is empty. This makes things
less hacky and more human readable :)
2026-06-10 19:48:38 +02:00
Bram Matthys 62f3cda8f2 Make spamfilter IDs start with "SPAM" to be more visible. And this also
means shun IDs now start with "H". Update release notes.

This, after i realized that for like *LINEs that are added by spamfilter
the two ID fields in "STATS gline" are a bit confusing as to which ID is
what. Now the spamfilter one starts with "SPAM" so there can be no
confusion. The gline one still starts with "G" as before.

Since I kept the generated ID length the same, this means there is less
bits available for the spamfilter ID, but there are rarely more than 1000
spamfilters, and in that scenario there's just as little birthday attack
collision % as with 200k glines, just to illustrate (~0.0015% vs ~0.0018%)
2026-06-10 15:37:20 +02:00
Bram Matthys faecdd66cd Config-file based *LINES/Spamfilter: preserve hit counters between rehashes.
Unlike non-config-based TKLs - which go through tkldb - they are still not
preserved through restarts. But at least they are not lost due to REHASH.
This is done via a save+restore, a bit complicated, but we have little
choice (other than not doing this at all).

This also moves remove_config_tkls() from conf.c to tkl.c
2026-06-10 14:30:39 +02:00