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.
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
`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";
// }
// }
//}
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
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.
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.
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
* `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).
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.
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.
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 :)
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%)
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
of the last hit, eg in `STATS gline` for GLINEs. These counts happen on
each individual server and are not network-wide. This allows IRCOps to see
which entries never get any hits and can potentially be removed.
* Important exception: config-based spamfilters/bans lose their counters
on `REHASH` and restart atm.
* For non-config TKLs, the hit count and last hit timestamp are preserved
across reboots (via tkldb).
* Again, see *Developers and protocol* for the exact STATS field.
The spamfilter hits already existed but all the rest is new.
Suggested by BlackBishop in https://bugs.unrealircd.org/view.php?id=6304
(in particular, time of the last hit)
By default - assuming you don't set set::reject-message things by yourself -
the *LINE id is appended at the end of the rejection that is shown to the
user, like: [ID: G7K2MP9WQX3].
Also new is spamfilter to *LINE mapping, so you can see which *LINE was
set by which SPAMFILTER. For this STATS gline and friends were enhanced.
In fact, multiple fields were added there, including some that are 0
(zero) placeholders at the moment. These will be set in a future commit.
Some things were combined here so we only have to break STATS and tkldb
database format once (unless i made a mistake, then the follow up commit
will correct that i guess :D).
This was requested by Hero in https://bugs.unrealircd.org/view.php?id=4397
in 2015. Again by musk in https://bugs.unrealircd.org/view.php?id=4397
in 2022. And on IRC by Chris and others.
As you can see it was not SUPER easy and a lot of thought went into this
(and in terms of S2S traffic it is part of something bigger too)
Only for ~/unrealircd/lib/ we had this ommision, and for ~/unrealircd itself.
I doubt this means a change for users, as all subdirs were already 0700
so then tightening of ~/unrealircd is not very important.
And only upsides... making things safer..
and refer to this as well.
Suggested by PeGaSuS in https://bugs.unrealircd.org/view.php?id=6610
This also moves extras/tls.cnf to doc/conf/tls/tls.cnf which
also gets installed in ~/unrealircd/conf/tls/ (or whatever CONFDIR is)
And just to be clear: this means you can run "./unrealircd makecert"
without needing to go into BUILDDIR (or even having it at all).
At the same time, the generation commands have been modified slightly
so two warnings during certificate generation are no longer there.
This is after PRE_LOCAL_CONNECT hook and can be useful in case some
module in there did something to the user that made them known-users.
And mention explicitly to module devs if they have things like
authentication mods that may move users between known<->unknown
that they should update the cache.
And the defines are more clear now (if .max_size is not set by caller.
DOWNLOAD_MAX_SIZE_MEMORY_BACKED: 1M
DOWNLOAD_MAX_SIZE_FILE_BACKED: 50M
The file-backed is mostly a defense-in-depth measure, so we don't
store infinite amounts of data in a download. Even though, in practice,
these - at least at the moment in unrealircd itself - all come from
trusted paths like remote includes.
In url_unreal.c we do the counting ourselves. In url_curl.c we use the
option CURLOPT_MAXFILESIZE_LARGE but this does not ensure it in all
cases so we still do our own counting as well in that file as well.
Install default maxperip/connect-flood exception for IRC platforms
that are so big that they are known to trip default maxperip restrictions
(per IPv4 IP or per IPv6 /64: 3 local users, 4 network-wide users)
on dozens of networks and that publish a stable list of IP ranges.
Currently only IRCCloud qualifies for this.
IRCCloud is in example conf since May 2023 (commit 82dbc4a297) as:
except ban { mask *.irccloud.com; type { maxperip; connect-flood; } }.
Unfortunately DNS sometimes fails to resolve. We have seen this happen
during an outage or server restart. People then mass-connect, but DNS
is not fully working (yet), leading to unresolved hostnames.
Recent stricter maxperip treatment for /64 IPv6 and the new /56, /48
and /32 restrictions in connthrottle make this problem worse. Without
these IP exceptions it would cause unwanted rejections.
If you don't want this, use: set { known-cloud-services no; }
(And then presumably you also don't want the except ban block
that example conf has been shipping since 2023)
(connect-flood). Those users are exempt and not counted towards new users.
And the new ipv6-unknown-users-limit in connthrottle (which has nothing
do with rates, but counts, similar to maxperip, but only on unknown-users)
now checks tkl type 'm' (maxperip). Those are counted as "except unknowns".
This is more of what the admin would expect.
was stated in docs at https://www.unrealircd.org/docs/Connthrottle but
if this item was not there then the default was actually zero (0).
Now, that isn't too common, since we ship with example.conf with the
connthrottle block as shown there, so lots of users have the proper
default, but just in case someone hand-writes or removed that connthrottle
settings block ("because they are the default)"... :)
And ship with these by default (no need to copy this set block):
set {
log-throttle {
CONNTHROTTLE_IPV6_LIMIT 100:60;
MAXPERIP_LIMIT 100:60;
};
};
You can do the same for other events, or even override existing ones,
and use the special value "unlimited" to turn default set ratelimits off:
set {
log-throttle {
CONNTHROTTLE_IPV6_LIMIT 50:60;
MAXPERIP_LIMIT unlimited;
};
};
Suggested in 2020 at https://bugs.unrealircd.org/view.php?id=5523
(and keeping it simple)
When a client is rejected by maxperip (not new) or connthrottle
ipv6-unknown-users-limit (that one is new), a notice to +s +x will be sent.
maxperip ipv4 example:
*** Client testuser4 with IP 1.2.3.4 rejected: maxperip limit exceeded (4 global, max 3)
maxperip ipv6 with /64 example:
*** Client testuser4 with IP 2001:dbe:0:0:0:0:0:4 rejected: maxperip limit exceeded for 2001:dbe::/64 (4 local, max 3)
connthrottle example where /56 limit is exceeded:
*** Client testuser5 with IP 2001:db8:cafe:abcd:0:0:0:5 rejected:
connthrottle ipv6-unknown-users-limit (cidr-56, max 4) exceeded for
2001:db8:cafe::/56 (5 unknown / 0 excepted / 0 known)
Oh and this commit also fixes a typo in existing CONNTHROTTLE events,
which previously were CONNTHROTLE (a missing T).
Changed "Too many connections from your IP" to have "[maxperip]" at the end.
Also create new setting and swap it with existing-one-during-development.
Long story short, we now have 3 different messages for these limits:
set::reject-message::too-many-connections
"Too many connections from your IP [maxperip]"
set::reject-message::too-many-connections-ipv6-range
"Too many connections from your IPv6 range ($prefix_addr/$prefix_len) [maxperip]"
set::reject-message::too-many-new-connections-ipv6-range
"Too many new connections from this IPv6 range ($prefix_addr/$prefix_len) [connthrottle]"
So we explicitly mention whether it is maxperip or connthrottle limiting the
user, that should provide enough clue to the IRCOp if the user pastes the
message to them.
connect-flood and maxperip module. This so they actually take
set::default-ipv6-clone-mask into account.
This also changes the maxperip module to a more simple method of
just freeing all entries and rebuilding the hash table on load.
That's necessary since now set::default-ipv6-clone-mask can change.
We previously upgraded to 1.0.21 and then downgraded to 1.0.20.
Benefit of 1.0.22 is that they also claim to have fixed a warning flood
i am getting with clang 22.
uses their pkg.m4 which made pkg-config a hard requirement.
Such a hard requirement is probably fine later, but.. i don't want
to suddenly require that of users during UnrealIRCd 6 series.
The OOB write did not happen on file-backed downloads, such as remote
includes. It only happened for memory-backed requests, which are only
these 4 in standard UnrealIRCd: centralblocklist, central spam report,
other spamreport blocks (eg to dronebl) and the log block with
destination webhook. All those 4 cases are very likely to be trusted
web servers, given the nature of the data you are sending to them.
The fix was to extend the size fields everywhere to 64 bits. It was
applied to both URL backends: url_unreal.c and url_curl.c.
The new API feature is a 'max_size' in OutgoingWebRequest, which
defaults to 1MB. This is only used for memory-backed responses,
so not for real file downloads. This fixes not only the reported
bug but also the case where a rogue webserver was unbounded in
terms of what response it could send back, potentially filling
up gigabytes of server memory.
Reported by Link420.
This does two things:
* We now only compile src/openssl_hostname_validation.c on
really old OpenSSL's. This was already unused/dead code
for most OpenSSL's but we always compiled it in until now.
* Added 'const' to please OpenSSL 4.0.0 while not breaking
OpenSSL 1.0.x. And yeah i'm happy to drop OpenSSL 1.0.x
support real soon... but not this month yet.
The "not setting +F" stuff didn't work, as due to netmerge - which
can even happen without a split when joining clients on both sides -
this would revert to +F normal basically.
So we just explicitly exempt in the join and msg code.
All this is for unrealircd-tests.
This XML code is only used for DroneBL submission with no user-
controlled variables (except $ip). Still, silly mistake to make
and who knows what other XML stuff will happen in the future.
Version 1.0.21 which we shipped with 6.2.3 has this bug, reported
by PhotoJim at https://bugs.unrealircd.org/view.php?id=6615.
And yes, libsodium also has this weird -stable thing, which does
have the fix, but that's basically just a snapshot of their git
version, it's a .tar.gz that gets updated every X time and it does
not have a GPG signature, while I have the policy nowadays to
verify GPG signatures for libraries we ship. So I am option to just
downgrade a version, for now, which is fine since we shipped with
1.0.20 for quite some time until recently.
There is no hard cap on batch reference length, so we had to make one up.
It is now a clear #define MAXBATCHREFLEN 48, which should be plenty.
No sane client is going to use like a 64 byte batch reference :D
So we did use 48, but we also accidentally used BATCHLEN at another
place. BATCHLEN is 22 and refers to how many bytes we generate, so
that is not appropritate.
Thanks to Valware for spotting this.
This wasn't done before, because optimizing stuff can always introduce
nice new issues. But is kinda necessary now since the previous way was
very inefficient. This now builds all the necessary buffers for multiline
clients and for non-multiline clients. And then iterates through both
types of clients, sending what they need. Instead of doing it the other
way around.
I had the dillema to either expose the linecache API and have everything
in multiline.c. Or, i do not expose linecache, and we do everything in
send.c. The downside of the latter is that if there is mistake then we
can't simply reload (or unload) the module to solve it. So, I have chosen
to expose the linecache API (sure, less clean) since that leaves us with
options if we screw up, plus it means everything related to multiline
sending is nicely in multiline.c, which is i guess just as good as an
argument as well ;)
Add a little fake lag based on history result: 400ms for 50 lines
under normal conditions where 50 lines = 50 lines. But this can go
up to 5000ms for worst-case amplification attacks where requesting
50 lines actually returns 50*15=750 lines when each line is a multiline
with max-lines, which gets you close to 350k+. This would only happen
if someone on the channel is doing evil stuff (with presumably consent
of the ops).
Also guard against hiting max sendq. If we are too close, then we
reject the CHATHISTORY request rather than quiting with "Max SendQ
exceeded". This protects against an attack where someone would be
tricked into joining a channel with amplified history (as explained
in previous paragraph), their client would do an automatic CHATHISTORY
request and then the victim would exceed max sendq and thus be killed.
And yes, this and maaaaany other multiline + history interactions
and many "buts" and security/flood concerns are why this implemtnation
took (and still takes) a lot of hours to get right :D.
For +H we now temporarily allow overshooting. This only matters for low limits.
Multiline batches are atomic so we have to choose to keep them as a whole
or remove the complete batch. So if +H 5:1h and the last message was a 15-line
multiline event, what do we do? We allow temporary overshooting to store the
15 lines. As said, the alternative would be to store 0 lines which would be
worse in terms of functionality, and the small overshoot is defensible.
For higher limits (where the +H line limit is bigger than multiline max-lines),
we always stay under the +H limit. Eg if all history in a channel consists
of 15 line multiline events and we have +H 100 then we will store 90, not 105.
It's only for +H linelimit < max-lines that this matters, because there the
zero-lines consequence sucks too much ;)
This way you can limit the number of pastes going on in a channel, as
this is from everyone in that channel (like 'm') not individual (like 't').
If it is exceeded then we will simply reject the BATCH, similar to
how action d(rop) works for some other subtypes. You won't see the paste
on the channel, only the sending user receives an error (MULTILINE_PASTE_LIMIT).
Small note: a multiline BATCH of just 2 lines is not considered a paste.
We consider a multiline of 3+ lines as a paste. I think that is reasonable,
since a two-line-multiline is not that much of a paste ;).
In the default anti-flood profile (+F normal) we also set 2p per 15s,
so this means channels are by default limited to 2 pastes per 15s max.
Of course, you can override this with +f [4p]:15 or whatever you like.
In terms of +F profiles, the defaults are (maximum x pastes per 15 seconds):
very-strict: 1p
strict: 1p
normal: 2p
relaxed: 2p
very-relaxed: 3p
and 7 for unknown-users (with max-bytes 5250 and 1500 respectively). This
allows pasting a short snippet of code, config file, text from a site, etc.
With multiline you have the guarantee that:
1) You will see the entire text with no delay between lines
2) You won't see another persons chat half-way through such a paste
3) For multiline supporting clients it is now clear that all the text
belongs to each other, which can make selecting/copying it easier.
This basically means short snippets/pastes like that can be completely on
IRC again. No need for a pastebin for it. Though, you may still need such
a service if you are pasting more lines.
Regarding the implementation in UnrealIRCd:
* Clients without multiline get individual fallback lines (concat lines
merged, blank lines skipped, as per spec). And we know that clients like
weechat - which does support multiline - also shows all lines and not
only a few plus snippet style "[.."]. That is another reason for only
allowing 15 lines by default and not something much more. Otherwise all
those clients would get a big wall of text, which just sucks.
* Spamfilter (also) runs on the full text of all lines together, so
splitting a phrase across lines does not evade spamfilter.
* Fakelag: a client can send the BATCH start+PRIVMSG (or NOTICE)+BATCH end
at full speed. We impose no fake lag there. Also, the multiline default
max-lines and max-bytes are lower than the example class::recvq of 8000,
so should be perfectly safe. If the entire BATCH is accepted then we
will impose fake-lag afterwards, with a cap of 15 seconds maximum.
If the BATCH is rejected, we impose half the fakelag plus 2sec.
* If the time between BATCH start and BATCH end is more than 15 seconds
then the BATCH is rejected (set::multiline::batch-timeout).
* The BATCH is atomic (either you see it all, or you see none of it):
* When the client sends it to server, it is buffered first.
* Only after the batch close the server indicates if it is accepted
or rejected. This has various reasons, two of them are: 1) The client
is going to send everything in one go anyway and not wait for a
response between each PRIVMSG, and 2) we can't do many checks in the
buffering stage and skip those after, that would cause a TOCTOU
problem (eg. a banned user still being able to speak).
* If any line gets rejected due to spamfilter or other case
(eg +c, +b ~text with block, etc etc), the entire batch is rejected
* Locally we deliver all or nothing (as said)
* S2S we buffer the batch as well, so if a server splits after having
received 10 lines out of 15, then clients will not see anything.
* We send max-lines and max-bytes, this is the hard upper limit.
* A multiline can still be limited more tight if:
* +f with 't' or 'm' restricts to fewer lines,
eg +f [5t]:15, which means max 5 lines per 15 seconds,
means the max accepted multiline is 5 for that channel.
* +F works the same, except that default +F normal does not
have a 't' at the moment and 'm' is very high (50) so
practically not limited by default.
* There will be a future +f flood subtype for some more control
TODO: we will send CAP NEW on unknown-users <-> known-users to
indicate the new max-lines value if you transition security groups
TODO: chat history does not yet include multiline batches.
As usual, this is mostly for configuration templates that you use for
multiple servers, that sort of things, eg.
@if !environment("ADMIN")
@error "Environment variable ADMIN is not set"
@endif
This also adds a change in conf.c so @define, @error and
@warning are skipped in @if blocks that evaluate to false
(that's obviously what everyone wants :D). So that fixes a
previous bug with @define in @if.
to check environment variables.
This also means functions can now return values, so some changes
under the hood. This also moves the <=, >=, <, > ops code.
loadmodule + set config items
This checks the file on-disk, which is slightly different than
@if module-loaded("third/coolmod") which checks if it is loaded.
geoip_classic and geoip_mmdb in modules.default.conf with Conditional
Config, a dynamic loadmodule line, and auto-updates.
Somewhere in a later version, probably 6.2.5, we will default to mmdb
for all cases.
When using nested @if blocks (e.g. @if module-loaded() inside
@if defined()), only the outermost condition was evaluated.
Inner conditions were silently ignored, causing blocks to be
included even when the inner condition was false.
Also walk the full chain in the loadmodule @if module-loaded()
restriction check.
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.
This should help gcc/clang with finding more OOB write bugs.
It does mean that 3rd party modules can no longer use the something like:
struct { char name[1]; }
and then alloc(sizeof(struct) + length of name)
instead the struct element needs to be name[];
...and they would need to alloc(sizeof(struct) + length of name + 1)
No 3rd party modules in unrealircd-contrib use this so.. hopefully fine.
in NameList, Tag, Watch and HistoryLogLine.
This does mean the allocation routines need a +1 everywhere, but
I think I got all of them. I also don't see them being used directly
in such a way in 3rd party modules (which is logical, as they
should use the API and not allocate such structs directly).
Also, SpamExcept has been removed as it was not used anywhere.
Previously, due to HARDEN_LDFLAGS missing in MODULEFLAGS we were
only partial RELRO instead of full RELRO. This is a defense-in-
depth measure but is good to have and the ommission was unintended.
the particular extended ban module if you don't want it.
For example, if you include the default modules.default.conf and, say,
you don't want ~quiet extbans then you add this in your unrealircd.conf:
blacklist-module "extbans/quiet";
instead of arbitrary 256 and such. Also makes it so other people
reading this code will understand better that MAXBANLEN is the
real limit here and not 256 (which is never reached because
the cut off already happens at 200).
This shouldn't be needed except for some corner cases, like if some
third party module does not limit their stuff properly, in S2S
or if channeldb contains some weird long entry or something.
allow bans of NICKLEN+USERLEN+HOSTLEN+3. Previously NICKLEN was
ommitted for some reason, which also explains why this ban-
simplification-routine exists in the first place. I think we can
make it use this full n!u@h space. Especially since we already allow
this for bans like ~quiet (the full n!u@h) and other extbans can be
quite long as well, it no longer makes sense to limit it here.
Small detail: in extban_conv_param_nuh() we used +32 which i think
is from the times when we had to deal with prefixes like ~quiet,
which is no longer the case, this routine is only about the final
suffix after the last : in a ban.
This would cause a bit of a mess, that usually would be resolved a few
seconds later, but still a mess. I had this on irc*.unrealircd.org
myself when rerouting a server from a backup-hub to primary-hub
a few months ago.
This is not an issue now in all code paths, but if someone accidentally uses
SupportXYZ() without checking IsServer() then it would be an issue.
In the past we used client->local->proto for client flags as well, but this
has been split off to client->local->caps a while ago.
I guess we should rename client->local->proto to something more server-ish
in a later major release to indicate this as well.
if (cmptr->flags != 0) { /* temporary until all commands are updated */
But that is impossible, as CommandAdd()->CommandAddInternal() already has:
if (!flags)
{
config_error("CommandAdd(): Could not add command '%s': flags are 0", cmd);
And this is the case since commit ceb04cc3eb
from July 15, 2015.
and callback data in non-DEBUGMODE. Also because exposing pointers like
this can defeat ASLR. These STATS are oper-only though, but hey, defense in
depth... and the pointer values don't make sense to non-devs anyway,
so why show them in the first place.
We use mtag_add_issued_by() to prepare it but then pass NULL
in do_cmd() so it was basically useless.
Also compile fix for previous (forgot to git ammend)
Every time compression has been used in TLS it has been a source of
trouble. We don't care about such optimizations anyway since connections
are long-lived in IRC. We are not some kind of webserver where every
millisecond counts.
This one has DNS caching enabled[*], which makes sense for this case.
[*] If using c-ares 1.31.0 or later. That version was released in June 2024.
The shipped-with-UnrealIRCd library version is 1.34.6, so qualifies.
However, if using system c-ares (which is automatically the case, if detected)
then many systems don't have it. The first Linux distro versions that qualify:
* Fedora 40
* Debian 13
* Ubuntu 25.04 (non-LTS) and future Ubuntu 26.04 (LTS)
* Etc...
Previously it showed this warning and said "Allowing user .. in unchecked"
when the user got shunend by CBL. Usually harmless but.. had a report
where it possibly was not (though that was an older UnrealIRCd version).
In any case, confusing, solved now!
This was a long standing requests by devs.
So if third/something is version 1.2.3 in the repository, and you have
src/modules/third/something.c which is version 1.2.4 then neither
'./unrealircd module upgrade' nor './unrealircd module upgrade third/something'
will overwrite the module. It will stay the local 1.2.4 version.
A new status inst/LOCAL was added "module installed, local version is newer
than available online"
The command './unrealircd install third/something' would still (re)install
the online version, though, i think that makes sense.
When working on this I noticed that './unrealircd module upgrade' previously
always recompiled the module, even if it was not updated. This is no longer so.
Reject it with an ERR_INVALIDMODEPARAM, just like we do for +k.
I think the higher number transforming is fine, but this <=0 transformation
is odd as it almost never is what the user actually intended.
In S2S traffic we still transform, as rejecting there is more problematic,
(causing a desync) and transforming it there is not a major issue, anyway.
Reported by ProgVal in https://bugs.unrealircd.org/view.php?id=6602
since the message/notice would not make it through either.
This also means someone can no longer iterate through users to see who
is +D/+R by sending a "silent" TAGMSG. (Silent in the sense that the
end-user usually would not have noticed)
Suggested in https://bugs.unrealircd.org/view.php?id=6579 by zw32h (I think)
This also means HOOKTYPE_CAN_SEND_TO_USER now allows you to NOT to
set errmsg, to silently drop a message. Previously we would crash
deliberately on such a situation to enforce that all modules would
set a proper errmsg.
(commit 0cf0c0faa2)
This was caused by register_user() being called twice, while it should
only have been called if !IsUser().
Reported by ProgVal in https://bugs.unrealircd.org/view.php?id=6606
My BuildBot screen was also all red :D.
1) We now always look at the module { } block even for unmanaged modules
(so .c files that you put manually in src/modules/third)
2) New module::compile-flags to allow specifying compile flags / libraries / etc.
See https://www.unrealircd.org/docs/Special_module_manager_block_in_source_file
So the new stuff is:
module {
.....
// Simple library dependency:
compile-flags "-lsomelib";
// Can even use:
compile-flags "$(mysql_config --cflags) $(mysql_config --libs)";
.....
}
This was requested long ago by various people.
And yes, this allows shell commands to be executed if the 3rd party indicates so.
The added risk should be small, since the module could do similarly evil stuff at
runtime, unless you compile with a totally different user compared to runtime.
The most common case where compile time vs runtime is completely different would
be for packaging (deb/rpm/whatever), which presumably ship with zero 3rd party
modules, so then there shouldn't be a concern either.
Obviously, for 3rd party modules in the unrealircd-contrib repository we screen
modules to make sure they don't do anything evil: "No malicious code or intent"
in https://www.unrealircd.org/docs/Rules_for_3rd_party_modules_in_unrealircd-contrib
This gets rid of src/buildmod and unifies the process a little, which
i need later.
We still compile the 3rd party modules unconditionally and twice (during
both make and make install). Which is a quirk that is in there since U6
and maybe U5 already :D. That's because we don't check if header files
have changed. There was previously a "is the .c file newer than the .so"
in there, though, that is gone now. Anyway, that's something for later.
Another quirk is that we do not halt compile if a 3rd party module fails
to compile. Which was sortof intentional at one point but.. is not ideal,
so will probably changed as well.
Anyway, that's not why i am doing all this stuff right now...
This is to guard against clients that do like CAP LS 302, NICK, USER,
AUTHENTICATE, CAP END, without waiting for the SASL result.
Previously "CAP END" would abort SASL if the response was not in yet.
Now "CAP END" will cause us to wait for SASL success/fail/timeout
and when that happens we will end the handshake and the user will
come online (or not, if e.g. banned).
In other words, SASL is no longer canceled upon premature CAP END.
And yeah, clients should wait, as is mentioned in
https://ircv3.net/specs/extensions/sasl-3.1
"it is RECOMMENDED to only send CAP END when the SASL exchange is
completed or needs to be aborted"
But since it is a recommendation and not a hard requirement, we'll
be nice and handle this situation server-side.
Of course, clients could still misbehave then by sending stuff
blindly after CAP END, like JOIN events, without even checking
if they got numeric 001 and so on... so in that sense it shifts
the problem a bit.. but.. at least that type of waiting is
hopefully more common :D
Int32x32To64 macro internally truncates the arguments to int32,
while time_t is 64-bit on most/all modern platforms.
Therefore, usage of this macro creates a Year 2038 bug.
Set known_users=NULL during a very limited period, just to be safe.
(Note that it can also be NULL during initial boot, which is a
longer period, which is why we always NULL-check in the code that
accesses it, but this aside)
threshold.
* Possible transition to known-users:
* - logged in is already handled by HOOKTYPE_ACCOUNT_LOGIN so we don't care about those
* - score reached (or just over) the minimum reputation score
* Caveat: if having multiple connections from the same IP then
* the first one may theoretically not have crossed in some cases.
* Ah well, it is a cache, not some precise thingy.
user is in known-users or in unknown-users. Not used anywhere yet.
Every 2 minutes we rescore all users. Or more specifically: every
5 seconds we rescore 1/24th of all users. That's the slow update path.
On certain events that cause a likely/possible transition, we update
the cache immediately. At the moment that is on IP change and account
login/logout. More will be added later.
or elsewhere. I don't think this is an actual problem, but at least the
fix from 1abf73309a was inconsistent,
if we check for b->client further down, then we should not be reading
from it a few lines up. As said, don't think this code is reached in
practice, but hey...
thus removing commands that are only supposed to be used by IRC clients.
We don't intend to document things like CAP, PONG, etc here.
Remove ISON, PONG, WATCH. Also remove DALINFO which no longer exists.
Re-index the USERCMDS and OPERCMDS table. This removes no longer existing
commands and may also have added some that were not in the index.
Moved STATS from USERCMDS to OPERCMDS since by default it is Oper-only
(and very likely is so effectively in practice).
Maybe PRIVMSG is a bit inconsistent in all this, since users don't type
that but usually it is like MSG. But yeah.. okay.. i can live with that.
As an aside, I don't like services commands being documented in HELPOP,
but that is another matter. These should be 100% documented in the wiki
first before they are scratched in the HELPOP. Right now some are still
missing.
the config file, without having to resort to things like mask %~asn:XXX;
Now you can just use:
ban user {
asn { 11111; 22222; 33333; 44444; }
soft yes;
reason "This ASN is not allowed. If you have an account you can still bypass";
}
Requested by nobody but sounds like a good idea :)
Previously these showed up as "name":"<match item>", now they show
up properly like this:
"match": {
"account": "Syzop"
},
(... and have no "name" item)
Also expand spamfilter::except while we are at it.
* I changed "state":"active" to "state":"monitoring" to make clear it is
not throttling at that moment but actively monitoring the situation.
* The config::except stuff was previously shown directly under config
and only 3 particular items (that are most popular). Now we expand to
sub-item "except" and use json_expand_security_group() to expand all
the mask items, in a consistent way, just like for security groups.
{
"jsonrpc": "2.0",
"method": "connthrottle.status",
"id": 123,
"result": {
"enabled": true,
"throttling_this_minute": false,
"throttling_previous_minute": false,
"state": "monitoring",
"start_delay_remaining": 0,
"reputation_gathering": false,
"counters": {
"local_count": 0,
"global_count": 0
},
"stats_last_minute": {
"rejected_clients": 0,
"allowed_except": 0,
"allowed_unknown_users": 0
},
"config": {
"local_throttle_count": 20,
"local_throttle_period": 60,
"global_throttle_count": 30,
"global_throttle_period": 60,
"start_delay": 180,
"except": {
"identified": true,
"reputation_score": 24
}
}
}
}
* Add some missing fields, such as destination, but mostly in the
exclude- area where a bunch were missing (some of those are a bit
far fetched, but hey, they exist, so should be shown if in use).
* Re-order fields to more closely match the struct (still not 100%)
* Extended fields, such as "account" and "country", now show up
directly under the security group, just like the other fields,
such as "reputation_score". This is also how they show up in the
config file, so hide the the fact that internally in the struct it
is stored differently.
* Add a comment in SecurityGroup struct in include/struct.h to make
it clear you have to add/update stuff at 7 places if you are adding
something new.
certificate or key. It added the cert/key to the list of certs, like a
"dual cert" approach.
This was caused by commit 877d151da4,
which indeed adds support for "dual cert" (or more).
I have now deferred setting the default to happen only if no
set::tls::certificate is specified, as you would expect.
We (already) used a similar delayed-initialization / deferred setting
approach in the ::tls-options inheritance code (for blocks like
listen, sni, link, etc.)
Just as a slightly related reminder, we do normally suggest keeping the
conf/tls/server.cert.pem and conf/tls/server.key.pem for server linking
and then use a cert from a trusted CA in the listen block for 6697 etc.
See https://www.unrealircd.org/docs/Using_Let's_Encrypt_with_UnrealIRCd
for more information (and the 'why').
New RPC methods:
- security_group.list: List all security groups
- security_group.get: Get details of a specific security group
- connthrottle.status: Get full connection throttle status, counters, and config
- connthrottle.set: Enable/disable connection throttling
- connthrottle.reset: Reset connection throttling counts
This also adds json_expand_mask_list(), json_expand_name_list(), and
json_expand_nvplist() to src/json.c for reuse by RPC modules.
A link to https://www.unrealircd.org/docs/JSON-RPC and such is nice.
And also explain that not all JSON-RPC modules will be in rpc/*.
Sometimes it makes more sense to just put everything in the same
module, such as connthrottle RPC stuff in the connthrottle module.
It should be perfectly fine if you choose not to load these modules but,
while optimizing / speeding up the find_user_mode() function, i made
it crash in case the hunted user mode does not exist. Oops.
We still propagate in a non-biglines way, no plan to change that atm.
This is just future-proofing. More testing/auditing needs to be done,
especially to see if buffers are sufficient.
delayjoin was setting +d if there are invisible users still,
but it should only do that if the channel was +D earlier and
not in all cases (like if some other module is dealing with
invisible users).
* We try to keep the dynconf variables the same name as in the conf
(well, with hyphens to underscores, and there are some exceptions)
* Remove unnecessary but otherwise harmless second safe_free()
* The URL could have been too long. It is now limited to 360 characters,
which should be plenty.
throw an error (JSON_RPC_ERROR_USERNOTINCHANNEL) if this is not the case.
Previously we returned success.
Also, if using DEBUGMODE (never on production servers), the server
would crash if the user is not in the channel.
This required two members on the same server and channel mode +H to be set
(or set::broadcast-channel-messages 'always', then also with -H).
The cause was a (normally harmless) optimization in
1473f52603 which meant we would loop
through remote servers for the case of +H.
And then the real cause a bug in the linecache system, which
caused servers to be seen as LCUT_NORMAL because locally
connected servers are MyConnect()->true.
And then on the wire (S2S) a message would look like..
:nick!user@host PRIVMSG ...
But nick!user@host is not valid in normal S2S traffic and on the receiving
server is seen as a nick@server message (and 'nick!user' is never found
on 'server' where server is actually a user host)... seems like an
old relic, but this aside.
This in turn, causing the message to be dropped (unknown source),
and the PRIVMSG handler is not called at all.
Bug reported by CrazyCat and then PeGaSuS managed to reproduce the
issue later on irc.unrealircd.org. Thanks!
As said, this only affects 6.1.2-rc2 and chmode +H.
Use extras/startup/unrealircd.service if you want a system-wide unit
file, which is normally what people tend to use. The benefit of this
is that it allows setting some security options.
Use extras/startup/unrealircd_user.service if you want a user unit
file. This works if you don't have root on the machine.
./unrealircd [start|stop|restart] commands if unrealircd is running
but without a pid, which will be the case if running through systemd.
The systemd example unit files will be in a future commit.
namely via "MODE #channel +F".
Enhance "MODE #channel +F" by explaining a bit more (like, actions a chanop
can do to change things).
Example of protection kicking in:
*** Channel CTCPflood detected (limit is 7 per 15 seconds), setting mode +C. Type "/MODE #test +F" to get more information on channel flood protection.
Then if you type "MODE #test +F":
Channel '#test' has effective flood setting '[7c#C15,30j#R10,10k#K15,40m#M10,8n#N15]:15' (flood profile 'normal')
-
You are currently using the default anti-flood profile normal.
If you want to change to a different anti-flood profile, for example because flood protection is kicking in too quickly
or too late, then you can use MODE #test +F <profile>. See the list of profiles below (ordered from lax to strict).
List of available flood profiles for +F:
off: []:0
very-relaxed: [7c#C15,60j#R10,10k#K15,90m#M10,10n#N15]:15
relaxed: [7c#C15,45j#R10,10k#K15,60m#M10,10n#N15]:15
normal: [7c#C15,30j#R10,10k#K15,40m#M10,8n#N15]:15
strict: [7c#C15,15j#R10,10k#K15,40m#M10,8n#N15]:15
very-strict: [7c#C15,10j#R10,10k#K15,30m#M10,5n#N15]:15
See also https://www.unrealircd.org/docs/Channel_anti-flood_settings
(And actually there is some bold text there too)
Indirectly suggested in https://bugs.unrealircd.org/view.php?id=6580
by rafaelgrether and PeGaSuS (being more clear to IRCOps what is happening).
(both AddressSanitizer and UndefinedBehaviorSanitizer)
This previously helped finding 8c26cec5fc
Also update the ./Config text a bit, eg about ASan not running OK on FreeBSD,
which only affects <14.2 as per https://bugs.unrealircd.org/view.php?id=6470#c23412
about an overflow with eg 'STATS maxperip' (IRCOp-only command).
Also, STATS maxperip failed to return 1 in the hook, resulting in
unnecessary STATS help output after the list.
We already run CI since 2014, first via Travis CI, then when it became
paid we switched to self-hosted BuildBot in 2019. Later that year
GitHub Actions came also in existence, but we already switched over to
BuildBot by then so didn't use it.
We will still use BuildBot on self-hosted to test various Ubuntu and
Debian distro versions, FreeBSD and Windows. Also, in the BuildBot we
have our own pre-build environment where we run Services tests (with
both anope and atheme), we run TLS there (again on all those distros
with various OpenSSL versions). And we also test both clang and gcc.
So what is new? Well, now we will also run a "quick test" via GitHub
Actions, like most projects out there on GitHub. Not the services test,
not the TLS tests, but simply latest Ubuntu and then clang+gcc.
The main benefit of this is that it will also show up on Pull Requests
and makes it "public" as our BuildBot page is restricted.
Previous was way too confusing where user was actually a client and
channels was actually a membership struct. And then you got like
user->user and channels->channel. No, let's make this conform to
the same style that we use elsewhere. Who the hell wrote this !??
Oh, it seems I did :D
1) Similar to sendto_local_common_channels() go through local_members
instead of all channel members
2) We have the membership info, so use user_can_see_member_fast()
This mainly affects MODE #channel +vhoaq and such. And as with all these
optimizations it mostly affects channels with more than 10 people (eg
hundreds or thousands).
Also did add_member_mode() and del_member_mode() but those are not
used by our own code because we always use fast versions anyway.
Oh yeah and the +D invisibility shit via set_user_invisible():
that one i didn't benchmark but should be better as well for
large channels.
Only downside is that mtags would be NULL, but we don't use it in
cmd_uid() so that's okay. This saves us from generating mtags in
do_cmd() when we don't need it. And also a command handler lookup
and all that. Saves around 8% of unrealircd CPU for 100k connects.
synched. Both need to be checked, because:
* The "far" server may be fully synched to "near" (and thus tagged as synced)
but the "near" server may be introducing the "far" server, when
we are connecting to "near"
* The "near" server may be fully synched but the "far" server is connecting
in and may thus not be synched yet
In reality, things are even more complex, since one would have to verify
the whole chain of links. But.. yeah.
Long-story short: this fixes things like "User xyz joined #xxxxx" logging
where this showed up while the server was linking in. It is not supposed to
log that, similar to how we not log all 1000 users as newly connecting when
a 1000-user-server links in. In fact, it didn't already log that for
directly-connected-servers, but for far servers it did previously.
And... that again gave performance issues if you were connecting like a
100k-user far server.. since you suddenly had 100k * numchannels join events
being logged (which surprisingly still only took 6 seconds for 100k entries,
but still, it is wrong to do so and can be avoided).
This didn't show up in initial profiling, but now that other areas
are faster, this one starts to show up with 15% for 100k-clone remote
server traffic. Easy change :D
This also makes them proper list items, again to make certain fast operations
possible. Main thing is that removing an entry does not require us to walk
all of those lists. Not all code has been modified yet to benefit this,
actually only very little, the most performance-impacting ones.
This fixes SQUIT of a server with 100k users in a single channel taking
40 seconds of 100% CPU. It now takes only 1 second.
Reported by craftxbox in https://bugs.unrealircd.org/view.php?id=6484
(Can't make member & membership one entry atm, that would be too much change in U6)
The first one iterates through all channel members (can be hundreds or thousands)
and the latter goes through the channels a user is in (typically <15).
This so we can use fast(er) techniques here and there.
New functions are:
channel_has_invisible_users(client)
set_user_invisible(client, channel, 1|0)
Existing functions:
invisible_user_in_channel(client, channel)
user_can_see_member(user, target, channel)
user_can_see_member_fast()
This is work in progress, although the tests seem to pass atm.
When the channel is +H we broadcast to all servers, so we can simplify
that case and don't need to iterate the channel->members.
The same is true if set::broadcast-channel-messages is set to 'always',
though that is not known to be used much.
This too should be a significant performance improvement for multi-
server networks. Especially since this isn't just num_channel_members
of 1 channel, but about common channels, so could easily be like all
channel members of 10 channels combined.
This function is used for NICK, QUIT, and notification for CAP-
enabled clients for setname, account and away changes.
This makes things a lot faster on multi-server networks, especially for
big channels where most of the clients in the channel are remote users.
This should be non-module-API-breaking, as all code uses the
add_user_to_channel() and remove_user_from_channel() functions.
Still need to spread this to other code, more optimizations possible.
That is, during my tests with 1000 TLS clients doing a couple of commands,
including one big one (WHO #channel on a 1000 user channel).
I also tested an SSL_writev() implementation (which would gather up to 16k)
but it gives very comparable speed and caries more risk of doing so in a
stable series. I think we can live with the 4 kilobyte extra per local
client in the year 2025 (and later).
The whox one saves a lookup for each channel member (so eg 500 for a
channel with 500 members). The extended-monitor saves it on delivering
watch/monitor notifications, so depends on the # of subscriptions.
And that's each time such a command is called. We now only lookup on
MOD_LOAD.
things by making the keys with the most lookups first, e.g. "reputation",
"geoip", "certfp". This order is based on actual lookup counts during a
quick test with 250 clones doing some typical IRC traffic.
Key: Lookups: Position before: After split: After split+order:
"reputation" 20362 37 14 1
"geoip" 10555 44 15 2
"certfp" 9264 23 8 3
"webirc" 7407 27 10 4
"websocket" 7110 55 19 5
We could also consider going for a hash table, but this may be "good enough" for now.
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.
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.
simply by re-using the context.
The slowdown happened due to commit a541b8f4ad
in June 2021 when converting to OpenSSL 3+ code. Now it is basically
back to the pre-openssl-v3 speeds.
and find_user_mode(). That's one array of 256 elements, instead of
iterating a linked list where - if you are unfortunate - one may
need like 26 iterations.
In sendto_channel() we did the check for user mode +T before the
sendflags & SKIP_CTCP, that makes no sense and caused useless CPU.
We now do it the other way around, and also only lookup the user
mode just once (if needed).
The umode_letter_to_handler[] code may crash, it is not well tested
yet, only had two runs so far. Seems to work ok even with REHASH tho,
but have not tested delayed module unloading for example.
This was previously a "long", which could cause issues on 32 bit archs.
We ship with 28 CAPs now, and that's without 3rd party modules, so...
This is similar to the client->flags bumping in 2023
(a3ed1eabd9).
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
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.
We don't set it in UnrealIRCd at the moment, so this is just to override
the OpenSSL defaults at the moment. It is good to have this exposed, in
case some vulnerability is discovered or you need some flexibility in
tweaking this.
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; };
...
}
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).
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.
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).
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
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.
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.
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'.
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.
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.
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.
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.
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.
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
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.
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.
* 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]
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.
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]
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.
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;
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
Ports that listen on 127.0.0.1 or ::1 are ignored (useful for e.g. services)
Looks like this:
[info] You have at least one IRC plaintext port open (such as 5668). Nowadays, everyone should be using SSL/TLS (on port 6697). See https://www.unrealircd.org/docs/Use_TLS.
See that https://www.unrealircd.org/docs/Use_TLS for more info (feedback welcome)
All this is in addition to somewhat related 29ce0ce29a:
[info] Your SSL/TLS certificate is not issued by a trusted Certificate Authority.
[info] It is highly recommended to use a 'real certificate'. To get a free one, see: https://www.unrealircd.org/docs/Using_Let's_Encrypt_with_UnrealIRCd
If applicable, that message is printed first, the 6667 one comes after ;)
Suggested in https://bugs.unrealircd.org/view.php?id=6500
and numerous times / discussions on IRC over the past years
It's finally time.. no.. it's overdue..
/* Standard IRC port 6667:
* Insecure plaintext (NOT for production servers)
* This listen block is here only for quick testing.
* Delete or comment out this listen block on production servers
* and use TLS on port 6697 instead.
*/
Also throw it in translated example*conf's (in English),
the translators can translate it.
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.
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.
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...
Is same as baseline.txt but with this line added:
+"FS_KEMs","127.0.0.1/127.0.0.1","5901","OK","X25519MLKEM768","",""
This so debian 13 test succeeds (and other future distros with OpenSSL 3.5+)
* [set::tls](https://www.unrealircd.org/docs/TLS_Ciphers_and_protocols):
Rename `ecdh-curves` to `groups` (the old name will continue to work)
* Add (and prefer) the `X25519MLKEM768` hybrid group, which is a mix
of `X25519` that is commonly used today and quantum-safe `ML-KEM-768`.
This to protect against
["harvest now, decrypt later"](https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later).
* To benefit from this, OpenSSL 3.5.0 or later (released April 2025)
is required on the server, and similarly a client that supports this.
At the time of writing, almost all Linux distros don't have such an
OpenSSL version yet (which is not a problem, this new feature will simply
not be available). Notably Debian 13 (when released in August
2025) will have it. LibreSSL does not support it either yet, so our
Windows build does not have this feature.
* Also, change the TLS information on-connect and in WHOIS etc. from
something like `TLSv1.3-TLS_CHACHA20_POLY1305_SHA256` to
`TLSv1.3/X25519/TLS_CHACHA20_POLY1305_SHA256`. In other words: using
slashes as separators and showing the group / key exchange in the middle.
The group is only shown on newer OpenSSL versions. If someone would
use the new PQC hybrid group mentioned above then their TLS info would
start with `TLSv1.3/X25519MLKEM768/`.
* TL;DR: better secrecy against future quantum attacks, even though
not many clients or servers support it at the moment.
[skip ci]
Previously this was like:
TLSv1.3-TLS_CHACHA20_POLY1305_SHA256
It is now changed to be like:
TLSv1.3/X25519/TLS_CHACHA20_POLY1305_SHA256
So:
* Changed from '-' to '/' because sometimes the cipher(suite)
contains a hyphen (TLSv1.2 and earlier)
* Show the key exchange "group" in the middle, such as X25519
for the usual non-PQC case and X25519MLKEM768 for hybrid group
with PQC.
* The group is shown in OpenSSL 3.0.0+ (and obviously you need
OpenSSL 3.5.0 to ever see X25519MLKEM768 there, but that is
something different)
[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`
(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.
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
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
are not (always) affected by this. We now check if there is any client port
exposed (to non-localhost). So if you have a hub with no client ports or
only at localhost then you won't get this bestpractices advice.
And also fix compile error on OpenSSL < 1.1.0 (undeclared var, duh)
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 :)
This re-sends these ISUPPORT tokens to let users know about important changes that may affect their display, most notably `PREFIX` can be problematic; for example if you have a server running and wish to load a module like ojoin or something else that relies on the client knowing the correlation between the mode and the prefix char, and without it the client just doesn't display the nicklist properly from then on until the client reconnects, which as we know can be a while until that happens.
The expected client reaction to duplicate ISUPPORT tokens according to the spec is to overwrite the current values. I have tested this in mIRC only and it works as expected.
* 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.
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).
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.
generators/sources plus some manual tweaking.
This is not complete and not always correct. Sometimes there are
simple mistakes like ф -> f because that is a cyrillic f but it
should be seen as an o or something like that. Those still need to
be polished out. And some other things are just plain weird but
probably similar cases. In any case, with this commit things are
getting better. It will never be perfect or anything close to perfect
anyway!
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.
even though this makes little sense and I doubt this is getting negotiated.
Depends on the OpenSSL version apparently, this is on Ubuntu 18.04
(and possibly 16.04) but not on Ubuntu 20.04/22.04/24.04.
Also not an issue on Debian 10/11/12.
Added to ignore at the moment.
GCC 15 is not released yet and is scheduled for April/May 2025.
We now have a ./configure check. If a func() declaration is interpreted
as meaning 0 arguments, so C23 style, then we now add -std=gnu17 to
CFLAGS. If not, then we don't set an explicit C standard version.
Closes https://bugs.unrealircd.org/view.php?id=6495
Changed the log/snomask message from, for example:
Flood blocked (target-flood-user) from evil!xyz@localhost [127.0.0.1] to victim
To:
Flood blocked (target-flood-user) from evil!xyz@localhost [127.0.0.1] to victim (TAGMSG)
The set_usermode() result is not used, so useless.
The if (themotd) motdline = ... makes no sense since themotd is
already dereferenced in the code above it (eg: themotd->last_modified.tm_year)
and consequently the motdline = NULL becomes useless too.
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.
These are optional after all. Not everyone links multiple servers
and not everyone uses Services. Fits with the rest that is //'ed
out now. Indirectly suggested by jwheare.
In addition to regular logging, also add a JSON log file.
This includes lots of information about every event so is great
for auditing purposes and is machine readable. It is, however
less readable for humans.
This so there is an offline version of the documentation from
https://www.unrealircd.org/docs/.
I'm not 100% satisfied with the layout but it is workable.
The ZIM file can be opened with tools liki Kiwix.
https://en.wikipedia.org/wiki/ZIM_(file_format)https://en.wikipedia.org/wiki/Kiwix
This does add 1.5 megabyte to the repository (and .tar.gz) but I
doubt anyone cares about that nowadays. The upside is that each
UnrealIRCd release will have the documentation of that time point
included, which can be used for historical purposes but also if
you don't have an internet connection or when for some other
reason the unrealircd wiki is unreachable.
The idea is that the .zim file is rebuild before each release,
i use mwoffliner (dev version) for that.
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.
People should preferrably go through the example conf line by line, but
if they are in a hurry or just want to get started quickly initially they
could CTRL+F on that.
because we send 9 character uids. However, IDLEN is defined as 12 so it is
natural for other people (services and other pseudo server writers) to assume
you could send 12, which failed until now, as it only accepted 11 characters.
Just to be clear:
* We generate and send 9 character uids in UnrealIRCd ourselves, this
works perfectly fine
* In 114d54ac61 in 2021 (UnrealIRCd 5.2.1) i
enlarged the buffers to allow INCOMING ids of up to 12 characters.
The reason for that is that I want the option to allow slightly larger
uids and could start doing that several years later without causing
desynchs and other problems.
* That didn't work properly, it only allowed up to 11 chars at this point.
* From now on it allows 12 chars. I do NOT recommend sending that though, if
you want to send bigger ids from your services/pseudo server then use
11, or... actually just use 9 like in normal unrealircd traffic at the
moment.
Reported on IRC by craftxbox
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 :-)
pub rsa4096 2024-11-18 [SC] [expires: 2030-11-17]
36E6F65706E36B0937280299101001DAF48BB56D
uid UnrealIRCd releases and patches (for verification of software downloads only!) <releases@unrealircd.org>
The old key is still valid until 2025-06-29:
pub rsa4096 2015-07-02 [SC] [expires: 2025-06-29]
1D2D2B03A0B68ED11D68A24BA7A21B0A108FF4A9
uid UnrealIRCd releases (for verification of software downloads only!) <releases@unrealircd.org>
The new key is signed by the old key and uploaded to keyserver.ubuntu.com.
The old key will still be used for signing releases for now. Somewhere around
the summer of 2025 i will switch to the new key.
Posted in https://forums.unrealircd.org/viewtopic.php?t=9397 for transparency
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)
and set our default ciphers and ciphersuites. Note that by default in
UnrealIRCd 6 the built-in (non-cURL) implementation is used for remote
includes, which already uses the same defaults since 6.0.0. Also note
that most distros, like Ubuntu and Debian, already disabled TLSv1.2
in the default openssl conf and thus it was already disabled in cURL.
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.
In all my tests on real servers this was never a reported leak,
because the dbuf_delete() already happens at other places where the
client is marked dead.
However, with my (private) fuzzing patches I need this freeing because
of a slightly different code path.
I'm putting the patch in mainline just in case I'm wrong and it does
trigger in some kind of niche situation.
The IRCd is still responsive (as the bad I/O is not prioritzed) but this
isn't good either. Only happens with some rare triggers.
This was previously reported over e-mail in an older UnrealIRCd version
but after 6-8 hours of debugging I was never able to trigger it.
Later it finally happened on one of my servers and I could debug it.
Reported by bss on IRC.
Changed:
r->ipv6 = IsIPV6(client);
To:
r->ipv6 = IsIPV6(client) ? 1 : 0;
The problem is that:
#define IsIPV6(x) ((x)->flags & CLIENT_FLAG_IPV6)
(..so without ?1:0..)
made this effectively:
r->ipv6 = CLIENT_FLAG_IPV6;
..which is..
#define CLIENT_FLAG_IPV6 0x800000000 /**< client is using IPv6 */
.. and 0x800000000 doesn't fit in r->ipv6, which is of size 'char' (so max is 0xff)
+#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
Now this works like:
if the time param exists, even without a reason, it will be checked if it's a time param. if it's not a time param, it'll be considered to be the reason (or the first part of it anyway)
Reported by PeGaSuS in https://bugs.unrealircd.org/view.php?id=6105
... and make set::max-inherit-extended-bans::ban-exception default to 0
because that functionality is not implemented
The +e's are already checked when using +b ~inherit though..
lookup fails the old result stays there which is confusing.
Reported on IRC where 10.x.x.x was shown as "Poland" which was a
leftover from the "real IP" before WEBIRC spoofing was used to set
the IP to 10.x.x.x. Reported by Jellis.
* [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.
ban ip {
mask { 1.1.1.1; 2.2.2.2; 3.3.3.3; }
reason "Go away";
}
Or the alternate form:
ban ip {
mask 1.1.1.1;
mask 2.2.2.2;
mask 3.3.3.3;
reason "Go away";
}
Suggested by magic000 in https://bugs.unrealircd.org/view.php?id=4599
Note that this is not a Mask item, these are special, hence the
special code.
There was a typo where it was inheriting exclude-ip entries as
ip entries. This could have been very dangerous but fortunately
exclude-ip was broken so it was impossible to add exclude-ip
entries and that list was always empty / NULL.
This only affected proxy { } blocks with type forwarded/x-forwarded/
cloudflare. The proxy block worked fine, but we also tried to exempt
these IPs from blacklist checking and connect-flood and this was
NOT effective due to this bug... even though the entries were shown
in "STATS except" with these IPs (because 'printable_list' was
correctly duplicated).
Other than that very particular use-case, this function is not used
at the moment.
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).
$nick, $username, $realname, $ip, $account, $operlogin, $operclass,
$country_code (xx for unknown), $asn (0 for unknown).
Note that if a $variable fails to expand, eg $operlogin but the
user is not oper, then the vhost will not be applied. A warning
is sent to the vhost snomask (+s +v) in such a case.
Examples:
/* Set authenticated users to $account.example.org */
vhost { auto-login yes; vhost $account.example.org; mask { identified yes; } }
/* Obviously not really a good idea, but.. to illustrate: */
vhost { auto-login yes; vhost $country_code.example.org; mask *; }
Also, when vhost { } blocks are read and need to be matched, they
are read top-down now, which is the most logical way. First match wins.
All this needs testing :)
and if so, it sets the vhost on the user. Except when the user already
has a vhost (eg from anope during SASL).
If vhost::auto-login is 'yes' then you don't need ::login and ::password.
Suggested by PeGaSuS.
Support for variables like $account in vhost::vhost, more examples and
a release notes entry will follow in later commit(s).
* 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.
Better to have this all in one place. Though, must admit, the
config checking is still in src/conf.c and a bit of a hassle to move.
Some testing may be wise to see if everything still works ;)
waiting DNS lookups. This had to do with c-ares query cache causing a
different (unexpected) code path in UnrealIRCd.
And, somewhat related, c-ares also didn't obey our DNS timeout, as that
value is a "hint" nowadays, so now we set the "max timeout" value.
Fun.
Several notes:
* This only checks on-JOIN (not on nick change, message, etc)
for performance reasons
* If the #channel in ~inherit:#channel also contains ~inherit
entries then those are not processed (no recursion and no looping)
* Only a limited number of ~inherit entries is permitted.
This will be moved to set:: items in a future commit so you
can set different amounts for +b/+e/+I ~inherit.
* This is work in progress, UnrealIRCd or the entire world could explode
* Documentation will follow later
Developers:
* Sadly, clean_ban_mask() needed to be changed to have two more
parameters, 'ban_type' and 'channel' were added at different positions.
This because the module needs the ban type (EXBTYPE_BAN, EXBTYPE_EXCEPT,
EXBTYPE_INVEX) and channel because it rejects based on number of
existing ~inherit entries in the channel... and while is_ok() is called
for local clients and has all this information, for services clients
is_ok() is not called so the only way to reject the +beI is through
xxx_conv_param() which comes from clean_ban_mask().
6.1.7.2 does not exist in git and will be:
* Version bumped from 6.1.7.1 to 6.1.7.2
* 5092fa985d (cbl-timeout-fix)
* 624d1d189c (remove curlinstall)
[skip ci]
Such a file is served if the UnrealIRCd version is unaffected.
It printed "This UnrealIRCd version does not require that patch"
but then instead of stopping it continued.. which wasn't all
that bad before GPG/PGP but now it causes failures and scary
warnings.
(See also 035f487684 which
introduced GPG/PGP)
[skip ci]
We already allow users in after 10 seconds if CBL is too slow, and
that part worked correctly. However 5 seconds later, when the URL
API 15 second timeout hits, it would try to allow the user in AGAIN.
This caused the user to be introduced twice, causing remote servers
to kill the user, and also screwing up user counts.
Reported by multiple people, including Jellis who actually filed
a report with logs, and alice providing logs as well, all when CBL
was temporarily down for a few hours in August 2024. In hindsight
this bug was already reported by k4be back in November 2023 but
was more rare at the time and mistaken for another very similar
bug that was fixed in 6.1.3.
With this patch, we check before we call cbl_allow(), but also
cbl_allow() itself checks the "user already allowed in?".
Oh yeah and this is hot patchable, within the hour I will make
this work: ./unrealircd hot-patch cbl-timeout-fix
most people don't need cURL support anymore anyway.
For those who do, they can install curl as a system library.
This also warns and unsets curl on ./unrealircd upgrade
and during ./Config when upgrading, but only for the 'curlinstall'
cases. Not for people who use system curl, since that is
totally fine to use :).
This to replace the scattered IP setting. It is very important to always
use set_client_ip() from this point. Everywhere!
Also, in addition to client->ip, this adds client->rawip that contains
the IP in network byte order. In older UnrealIRCd versions we always had
the raw IP but not the IP as a string, so we moved to IP as a string,
but it can be useful to have both in terms of optimizations.
Of course, then the client->ip and client->rawip always need to 100% match,
hence the set_client_ip().
This also changes IsIPV6() to do A BUGFIX, it changes it from:
* if local user is the user connected over IPv6? Otherwise, does it have ':' in the IP?
To:
* check if the IPv6 flag is set (which is set if IP contains ':')
This may seem insignificant but it means that for spoofed IP addresses,
such as WEBIRC or transparant proxy, we use the correct transport.
Previously, if the proxy was IPv6 then even if the spoofed user was using
IPv4, the ident check would still be tried over IPv6. That sort of fun.
From now in, in such a situation client->local->socket_type will be
SOCKET_TYPE_IPV6 but since client->ip (and rawip) will contain IPv4
the IsIPV6() will actually return false, as it should be.
Also, in the HOOKTYPE_IP_CHANGE, enforce that if HOOK_DENY is returned,
the the user is killed by dead_link(). The user must be killed because
that is what we expect, and you cannot use exit_client() because from
some code paths that would be too much freed structures / hassle,
as a comment in src/modules/connect-flood.c correctly states:
/* There are two reasons why we can't use exit_client() here:
* 1) Because the HOOKTYPE_IP_CHANGE call may be too deep.
* Eg: read_packet -> webserver_packet_in ->
* webserver_handle_request_header -> webserver_handle_request ->
* RunHook().... and then returning without touching anything
* after an exit_client() would not be feasible.
* 2) Because in HOOKTYPE_ACCEPT we always need to use dead_socket
* if we want to print a friendly message to TLS users.
*/
Because c-ares is now caching request/responses, the DNS result may come in
immediately, causing some events to occur that were previously impossible.
And yeah, the warning was harmless, other than it being a possible nuisance
to IRCOps.
Contrary to retrieving country code / country name, the AS organisation
name that was returned needs to be freed by *US*. Makes sense, though
a bit inconsistent, heh.
[skip ci]
Was previously shown as like :0 when removing/adding a listen block
with a UNIX socket. Now shows the file, as you would expect.
And in the boot screen it was like:
[info] IPv4: 127.0.0.1:6697(TLS), 127.0.0.1:6667
[info] IPv6: *:6667, *:6697(TLS)
And now also:
[info] Unix Sockets: /home/unrealircd/unrealircd/data/rpc.socket
Yeah not really important except for like SVSMODE -b nick, which
removes all bans that affect nick. That's the only type of code
that runs bans against external users.
instead of ban user { }. Has a bit more use.
Also mention that +b/+e is possible but of little use in the
normal / default configuration. It can be if you don't do cloaking
though and change set::whois-details::geo.. eg everyone full;
[skip ci]
This also automatically adds it as a security group and mask item:
ban user {
mask { asn 64496; }
reason "Testing ASN ban";
}
And yeah, it is a normal extban too (in +b and +I). Users usually
don't know the AS Number of other users, though, unless you change
the default configuration (at the cost of privacy).
Updated release notes a bit... more will follow.
* Including default download via unrealircd.org
* Shown in WHOIS - currently in RLP_WHOISCOUNTRY, not sure
if that is correct.
* Shown in connect notices [asn: XYZ] [asname: BLAH BLAH]
* Shown in json user expansion (JSON logging and JSON-RPC)
* Only via geoip_classic at the moment
* Structs and serializing in geoip_base done
* Extbans not added yet
To reproduce, boot with:
listen {
ip *;
port 6000;
options { websocket { type text; } }
}
And after that, comment out the options and REHASH. You'll crash.
Reported anonymously through crash reporter.
The list is as follows with the number of bytes in the test leaked,
but this can vary depending on your configuration:
* charsys with multibyte ranges (112 bytes)
* set::whois-details (909 bytes)
* +F default profile (7 bytes)
The whois one is in the default configuration, so likely
affected everyone. It's nothing catastrophic, as you need a 1000
REHASHes in order to reach 1MB but.. we shouldn't leak, of course.
but was removed several years ago. I think this is a better place.
This also removes doc/Donation which was out of date and probably
not many people knew about it at all.
[skip ci]
at selected places (there needs to be explicit code in place to handle this).
At the moment it is supported at two places only:
* For spamfilters (was already possible via crules via ::rule with
a destination('xyz') but now non-crule destination "#xyz"; works as well, eg:
spamfilter {
...
except {
destination "#main";
}
}
Note that if you want to exempt a destination in all spamfilters,
we already have set::spamfilter::except for that!
* In restrict commands for like channel-message and such:
set {
restrict-commands {
channel-message {
except {
connect-time 600;
destination "#test";
}
}
}
}
Allow passing a crule_context via user_allowed_by_security_group_context()
and make user_allowed_by_security_group() call that.
Actually document spamfilter::except online in the docs (yeah you
won't see it in this commit, just mentioning...)
And yeah, by now i wonder if we should really call it crule_context
since it is more like a security group matching context, but.. whatever.
The reason for the warning is that in some future UnrealIRCd version I want the
rpc-user::rpc-class to become a required item.
This commit also adds rpc-class.default.conf which is by default
included from rpc.modules.default.conf.
This also completes the TODO list from b9de933378
(the rpc.add_timer was never a loophole and i kept rpc.info as-is)
This wasn't caught by Address Sanitizer because we simply never removed
it from the linked list, and thus it was a reachable pointer.
Found this bug when adding the rpc-class { } stuff.
This so you can restrict the JSON Methods that can be called, eg:
rpc-class limited {
privileges {
server { list; get; }
channel { list; get; }
user { list; get; }
}
}
rpc-user xyz {
match { ip 127.0.0.1; }
password "test";
rpc-class limited;
}
NOTE: This is work in progress
1) Things are NOT yet fully contained, as i need to lock down
rpc.add_timer still :)
2) Some more work, eg rpc.info would be nice to show some
information about the restriction (??)
3) Need to fix a memory leak
4) Possibly more
The build tests were failing for tkldb save & restore. Cause was this:
if (tkl->ptr.serverban->match)
^ this is wrong.. because it doesn't check if tkl is a server ban
So it could be tkl->ptr.spamfilter->whatever_is_at_that_memory_offset
which is non-NULL.
Could have updated the code to an if (IsServerBan... && tkl->..etc..)
but decided to ditch this needless code altogether.
As this wasn't needed at all since it already skips config-based.
And all mask items bans are config-based.
One of those rare cases where trying to be extra careful actually
causes a fuckup.
Ignore these for entire src/dns.c.
Quoting https://github.com/c-ares/c-ares/pull/732#issuecomment-2028454381:
"Those deprecated functions will remain available until there is an ABI
break, which honestly will likely never happen. It's more to encourage
integrators to move to the more modern functions."
Also, keep in mind that several of these 'deprecations' happened in early 2024
while the new function was introduced in March 2020, like for ares_getaddrinfo().
That isn't all that long ago, only 4 years. So we would need compatibility code
for both the old and new function for a while.
So: we can look into that in some major new UnrealIRCd version, nothing urgent,
and perhaps by then it is long enough that we don't need the fallback to older
functions.
Hmm... we should probably use json_expand_tkl() differently for match items
instead of returning "<match-item>" literally. Consider this a TODO item :D
This only happens for config-based bans that can't be removed anyway, so..
This so you can get the same spamreport data to your own custom system.
It works similar to set::central-blocklist::url but then on a
spamreport { } basis which is better, since then you can still
submit to UnrealIRCd central spamreport too.
So you can have two blocks:
spamreport unrealircd { type central-spamreport; }
spamreport custom { type central-spamreport; url 'https://www.example.org/xyz'; }
And then a /SPAMREPORT or 'report;' action will report it to BOTH.
Requested by Chris
* restrict-commands: add option 'channel-create' for managing who may create new channels.
This has been a commonly requested feature with different requested options, I think it makes sense to do it properly from here
Reported by Valware. E.g. if HOOKTYPE_CAN_JOIN rejects the join
when it is a new channel.
( And yeah... +P channels are not destroyed... handled in
sub1_from_channel() -> HOOKTYPE_CHANNEL_DESTROY already. )
There was an incorrect OperOverride message if you were had +h, +a or +q
and was kicking someone that you should normally be able to (without override).
This requires quite a bit of further testing, though, it's so easy to get
this wrong. The FIXME still stands to fix this for good some day.
Reported by Valware in https://bugs.unrealircd.org/view.php?id=6423
Reported by hnj in https://bugs.unrealircd.org/view.php?id=6418
Appears to have been introduced as part of the 6.x refactor of secret/private channel modes in 8066c13876
Also adjust message for ERR_OPERSPVERIFY to include channel name.
This is to correspond closer to other similar numerics around this area, as well as agreeing with the definition within modern.
crule is used outside security groups / spamfilter, like in
deny link { }.
Also update the match_realname() since via the extban code it would
use match_esc() which is rather confusing if you have double (or
perhaps even triple) escaping when using this in the conf.
match_user_extended_server_ban except that it works by name/value.
This can then be used by crules or in other mods, like:
user_matches_extended_server_ban(client, "country", "NL");
If the performance impact isn't too bad (of the extra work) then
this prevents duplicate code in the handler for things like
that: account, country, certfp, and whatever we add in the future..
Otherwise in pre-connect-stage is_identified(), is_webirc()
and is_websocket() will always return false due to the
IsUser() check.
One should always be careful with accessing things in pre-
connect-stage, but in this case the IsLoggedIn() and
moddata_client_get() are safe to use. The former checks
client->user and the latter does not access anything within
client->user at all.
Note that this is still a dumb interface and not a real proper
authentication framework.
This adds HOOKTYPE_SASL_AUTHENTICATE and HOOKTYPE_SASL_MECHS and
also provides 3 functions: sasl_succeeded(), sasl_failed() and
a helper function decode_authenticate_plain() for AUTHENTICATE PLAIN.
* Add more [Crule](https://www.unrealircd.org/docs/Crule) functions:
* `is_tls()` returns true if the client is using SSL/TLS
* `in_security_group('known-users')` returns true if the user is in the
specified [security group](https://www.unrealircd.org/docs/Security-group_block).
* `match_mask('*@*.example.org')` or `match_mask('*.example.org')`
returns true if client matches mask.
* `match_ip('192.168.*')` or with CIDR like `match_ip('192.168.0.0/16')`
returns true if IP address of client matches.
Reported by BlackBishop.
This rename free_config_defines() to init_config_defines and calls it from
config_read_start() so caller doesn't have to think about it.
And this is easily mistaken with "REHASH -global" which rehashes all
the IRC servers on the network.
In fact, who knows some year(s) from now we may map "REHASH -all"
to "REHASH -global", but... not yet...
* When booting for the first time (without any cached files) the IRCd
downloads GeoIP.dat. If that fails, e.g. due to lack of internet connectivity,
we now show a warning and continue booting instead of it being a hard error.
Note that we already dealt with this properly after the file has been cached
(so after first download), see "What if your web server is down" in
[Remote includes](https://www.unrealircd.org/docs/Remote_includes#What_if_your_web_server_is_down).
Otherwise you get something like:
[info] /home/irc/unrealircd/conf/unrealircd.conf:166: oper::password: Advice: it is not recommended to use plaintext passwords in the config file. You can replace this password with the following password hash:
[info] password "$argon2id$v=19$m=6144,t=2,p=2$fIxnffmGpvcMkXaLcbttfw$b549yTafLVG27K4fPvre2DSacTm/px2hVMdI0KmQqZU";
[error] /home/irc/unrealircd/conf/unrealircd.conf:156: please change the the name and password of the default 'bobsmith' oper block
[error] 1 errors encountered
Which is a tad confusing, since you shouldn't hash that default dummy password at all :D. Now it is only:
[error] /home/syzop/unrealircd/conf/unrealircd.conf:156: please change the the name and password of the default 'bobsmith' oper block
[error] 1 errors encountered
[skip ci]
And update release notes:
* Add more [Crule](https://www.unrealircd.org/docs/Crule) functions:
* `is_away()` returns true if the client is currently away
* `has_user_mode('x')` returns true if all the user modes are set on the
client.
* `has_channel_mode('x')` can be used for spamfilters with a destination
channel, such as messages: it returns true if all specified channel modes
are set on the channel.
This adds two new functions to Crule:
- `has_umode()` which expects a parameter of one or more mode chars, returns true (1) if all of them match, otherwise returns false (0)
- `is_away()` which expects no parameter which simply matches whether the user is set as away as a boolean
could result in a crash if you ran the 'SPAMFILTER' command as IRCOp.
Apparently not widespread since nobody reported it and I found it
while debugging another issue. Not sure when it was introduced,
I'm pretty sure it was working before. Or maybe there is/was some
second factor involved.
Anyway, fixed now and previous commit also adds extra code for in
case i screw up again with this, so it is not silently ignored.
or require authentication { } block.
And the connecting user would get a message every second, which was
a bit floody ;D.
Repoerted by GHF in https://bugs.unrealircd.org/view.php?id=6375
This fixes a bug where if you run ./Config with 'auto' file descriptors,
and then have an unusually low 'ulimit -n' of like 150, you would end up
with a negative amount of file descriptors available for use.
This fix moves it from compile-time setting of reserved fd's to runtime
setting.
All this is wrong, by the way, but that is for another major overhaul,
at least this bug is fixed now :D
https://github.com/unrealircd/unrealircd/pull/265 by Valware
"This is an IRCv3 extension which lets clients opt-out of receiving /names on join.
This is useful for bots on large channels who do not need to know who is in the channel.
Specification: https://ircv3.net/specs/extensions/no-implicit-names"
+ module rename from 'no-implicit-names-cap' to 'no-implicit-names'
(simply because no other modules has that -cap suffix)
+ update to Makefile.windows
Calling spamfilter for TAGMSG makes no sense as the text is "" (empty) :D
If you want to filter message tags, have a look at spamfilter type 'T',
which filters individual message-tags (not just the ones in TAGMSG but
also for PRIVMSG and NOTICE).
[skip ci]
Previously the same code caused no problem, but then
2fcb5b4669 changed the read buffer
size to 16384.
Since then (6.1.2.x) the webserver_handle_request_header() function
was sometimes cutting 1 byte off the packet due to sizeof(netbuf)-1
which was 16383 bytes. We now no longer use a fixed value and
allocate memory dynamically on the heap.
This fixes the bug that I was seeing but this change still needs
serious extra testing as it may affect websockets and RPC!
* The [Central Spamfilter](https://www.unrealircd.org/docs/Central_Spamfilter),
which provides spamfilter { } blocks that are centrally managed, is
now fetched from a different URL if you have an Central API key set.
This way, we can later provide spamfilter { } blocks that build on
central blocklist scoring functionality, and also don't have to reveal
the central spamfilter blocks to 100% of the world.
listen {
websocket {
allow-origin { *.example.net; }
}
}
This allows you to limit websockets to a particular domain, IF the
user is using a normal browser.
Note that any non-browser (eg a websocket command line program) could
just spoof the Origin header, so for that case it doesn't really add
any security or real restriction.
set::central-blocklist::spamreport and ::spamreport-enabled are now GONE.
We now require a normal spamreport block, just like for other spamreport
functionality. So, if you want to enable this feature, use:
spamreport unrealircd { type central-spamreport; }
See https://www.unrealircd.org/docs/Central_spamreport for all info.
You can use CBL with central spamreport or central spamreport without CBL.
All explained at that URL.
This is mainly for the (less usual) case when someone wants to
use SPAMREPORT but does NOT want to use CBL:
set {
central-blocklist {
blocklist-enabled no;
spamreport-enabled yes;
}
}
Also documented at https://www.unrealircd.org/docs/Central_spamreport
under 'Configuration'
... in case you want to do fine-tuning.
Defaults to DOWNLOAD_CONNECT_TIMEOUT (15 seconds) and
DOWNLOAD_TRANSFER_TIMEOUT (20 seconds).
For example, the module manager uses a shorter timeout of 7 and 20.
(that was already the case, but now it uses the generic api so
it needed an option to set it to those values)
"./unrealircd module upgrade" is called by "make install" and now that
we use generic URL framework, the src/url_curl.c did not take into
account that at that stage ~/unrealircd/conf/tls/curl-ca-bundle.crt
may not exist yet, so fallback to <source>/doc/conf/tls/curl-ca-bundle.crt.
The src/url_unreal.c already did that. As did the old modulemanager
code that was removed an hour ago.
No longer url_start_async(a,b,c,d,e,f,g,...) but usings structs so
simply url_start_async(tehstruct);
makes it easy to add fields later without forcing all modules to
change the prototype.
Work in progress....
The effect it had was actually *@host, so ident@* became *@* -grin-.
Was caused by add=0 at the server_ban_parse_mask() causing a check
not to happen. Fixed now.
Reported by Jellis in https://bugs.unrealircd.org/view.php?id=6358
This will hide the *LINE reason to other users if the *LINE contains the
IP of the user. This to protect the privacy of the user for cases such
as a KLINE due to a blacklist with a DroneBL URL.
Other possible settings are `no` (never hide, the previous default) and
`yes` to always hide the *LINE reason. In all cases the user affected by
the server ban can still see the reason and IRCOps too.
https://bugs.unrealircd.org/view.php?id=6362
The `watch-check` function now has a new argument which can be used to pass data to watch_notify callbacks.
New `watch_add` and `watch_del` hooks are called whenever new entries are created or removed.
New `monitor_notification` hook is called whenever a RPL_MONONLINE or RPL_MONOFFLINE is being sent, so a module can add its own notification besides it.
Nevermind, the solution to that problem was easy, can just
compare with the 'ircd' binary and in that way, leverage the
Makefile system decisions :D
https://bugs.unrealircd.org/view.php?id=6365
This is a quick fix for https://bugs.unrealircd.org/view.php?id=6365
The quick fix which causes 3rd party modules to be compiled always in
'make' and again in 'make install' (the latter is unintended).
Can look for something better later, I want to work on other stuff now ;D
That is, if a nick is specified. For an IP address obviously we won't.
This is needed later for when unrealircd api SPAMREPORT becomes
available, since remote servers don't have all the info.
Side-effect is that, if you only configured one server to do
spamreporting, that won't work anymore. But that is an unusual
case anyway, and now unsupported :D.
The LoadPersistent*()/SavePersistent*() functions caused moddata to be
tagged with ->unloaded=1. Though it seems it caused no real issues this
is not good... we now properly tag them as 0 and the like. Also did a
code cleanup / overhaul on that system as well.
For other ModData we now handle the case where a module is loaded with
with a newer version and that newer version is no longer having certain
moddata, eg the name changed or it no longer needs it.
KNOWN ISSUE:
Unfortunately we cannot call the free function for the old moddata that
is no longer being handled by the newer version of the module, since the
module is already unloaded. So this will result in a memory leak, but
not in a crash.
KNOWN ISSUE:
Similarly, for SavePersistentPointer() there is a free function, again
this is called just fine if the module is permanently unloaded but NOT
if the module is reloaded with the same name and no longer is interested
in the persistent pointer object. Again, here too, that would result
in a memory leak but not in a crash.
Fortunately the "known issues" are rare. Fixing these is impossible
with the current module API because modules are unloaded after MOD_TEST
and before MOD_INIT, and only after MOD_INIT we know which moddata
is handled by the new version of the module. To change that we would
need to keep the old module around until after MOD_INIT of the new
module (so we can call free functions in the old module), but that
means delaying the MOD_UNLOAD for the old modules until after MOD_INIT
of the new modules, which changes the sequence too much that i don't
dare to do that. For example, it would mean a database save routine
in the old module would only be called after MOD_INIT finished in the
new module, which may be unexpected since right now MOD_UNLOAD is
called before MOD_INIT and maybe the db loading is done in MOD_INIT,
which would need to be moved to MOD_LOAD. That's just one example,
there may be others. I think such a change can only be done on a major
UnrealIRCd version change, so we will have to live this for now.
As said, fortunately it is a corner case.
When a module was unloaded (for good) that used MODDATATYPE_CLIENT
or MODDATATYPE_LOCAL_CLIENT we walked the client_list/lclient_list
and freed the moddata entry for all these clients, but we did not
walk the unknown_list, so connections in process.
That's bad, because sometimes such moddata is allocated in
HOOKTYPE_HANDSHAKE or in other routines pre-connect and since
we skipped freeing them while the module was still loaded, it
means we leak memory since it is also not freed on user exit.
Since unloading modules permanently is not a common procedure,
combined with the timing of it happening during a handshake, it
took a while before this issue was found (and then easily fixed).
There's also another moddata issue, but that is for next commit.
[skip ci]
Post-handshake this was working fine, but before register_user() it was
always using nick!user@host, never using the ident and never ~ prefixing.
Now it just uses the usual rules that we have, which are: prefixing
with a ~ if ident lookups are enabled and failed, and without a ~
prefix if ident lookup succeeded or set::options::identd-check is off.
Reported by k4be.
This so you can match a literal * or ? via \* and \?
And do the same for allow channel { }.
This can break current configs if you have a deny channel for a channel
with a slash in it, since a \ which already sortof needed to be \\ in
the config file, now needs to be \\\\ (doesn't that look great?).
Fortunately slashes are not really common in channel names, let alone
deny channel { } configuration.
Since 10k+ fd's available is the common situation, this means we then have
250 fd's reserved for non-clients, such as HTTPS callbacks and other things.
Previously:
<1024: reserve 4 fd's
1024+: reserve 8 fd's
Now:
<1024: reserve 8 fd's
1024-2047: reserve 16 fd's
2048-10000: reserve 32 fd's
10000+: reserve 250 fd's
This fixes the issue where +e/+I ~operclass:name gets cut off if the
name contains any digits.
Reported by BlackBishop in https://bugs.unrealircd.org/view.php?id=6353
Also, we previously allowed any characters in the operclass, which is not
a great idea.
This is quite a bit higher than client DNS lookups (1500ms first, on retry 3000ms)
and is because some DNSBL are reported to be quite a bit slower than ordinary DNS.
(Maybe just some, but.. the higher timeout does not hurt anyone anyway)
Note that all this has no effect on client handshake times, as DNSBL checks are
done in the background. Only side-effect is that if we do get a "late hit" then
you may now see a kill a few seconds after the client is online (which was actually
already possible before too for quick clients, but.. yeah...)
These settings can be overriden via set::dns, these are the defaults:
set {
dns {
client {
timeout 1500;
retry 2;
}
dnsbl {
timeout 3000;
retry 2;
}
}
}
When you REHASH we will check if the values are different than the current
c-ares settings and if so, reinitialize the resolver. Reinitializing the
resolver will destroy outstanding DNS requests, eg DNS lookups for clients
currently connecting, but so be it. Not a super-huge issue since changing
this is rare.
Requested by BlackBishop in https://bugs.unrealircd.org/view.php?id=6306
With error messages about it possibly but also possibly not (silently failing).
This is actually quite bad because when the ircd is running, you could
happily add spamfilters with UTF8 like stuff, REHASH fine, but if you
then restart the IRCd would fail to boot due to a config error.
Reported by BlackBishop.
If you make a parser mistake in the config file, like a missing semicolon,
then under some circumstances the server may crash. Not always, it seems,
which explains why this bug is not reported that much.
For config-based spamfilters, the reason was not escaped, meaning that
spaces and underscores did not work as expected.
For example, in "STATS spamfilter" the spaces were displayed as-is
which means that the numeric output was not really parsable.
Apparently this bug exists since UnrealIRCd 5 already...
For example, because of a different version of PCRE2, or because of the switch
from non-UTF8 to UTF8 (or vice versa) which disallows certain byte sequences.
This happens when !, || or && are used, though the exact requirements
for the crash may also require a function with arguments.
Reported by BlackBishop.
when they are only in channel(s) with very low member counts.
This because some typical bot/drone behavior is not to join any channels.
This kinda forces them to expose themselves a bit more (and if they don't,
they don't get more reputation).
The downside is for the unusual case where a legit chatter would be on
the network but not joining any channels, but that is rare. In any case,
this setting can be adjusted if that is typical or more normal behavior
on your network :D.
* The [reputation score](https://www.unrealircd.org/docs/Reputation_score)
of connected users (actually IP's) is increased every 5 minutes. We still
do this, but only for users who are at least in one channel that has 3
or more members. This setting is tweakable via
[set::reputation::score-bump-timer-minimum-channel-members](https://www.unrealircd.org/docs/Set_block#set::reputation).
Setting this to 0 means to bump scores also for people who are in no
channels at all, which was the behavior in previous UnrealIRCd versions.
action { set REPUTATION--; } and similar.
Also enhancement to reputation S2S traffic, to support decreasing:
*
+ * Since UnrealIRCd 6.0.2+ there is now also asterisk-score-asterisk:
+ * :server REPUTATION 1.2.3.4 *2*
+ * The leading asterisk means no reply will be sent back, ever, and the
+ * trailing asterisk will mean it is a "FORCED SET", which means that
+ * servers should set the reputation to that value, even if it is lower.
+ * This way reputation can be reduced and the reducation can be synced
+ * across servers, which was not possible before 6.0.2.
+ *
So if you are actually decreasing reputation, you need all servers on
6.0.2 or higher for it to work properly, otherwise the other servers
don't decrease it, and next connect the highest wins again, etc.
even when multiple modules were upgraded.
Actually not sure about the cause and how this is possible, but running
'make install' only once at the end is the solution, which is something
that should be done that way anyway.
Reported by westor in https://bugs.unrealircd.org/view.php?id=5919
In the config file, when not using quotes, a slash at the beginning of a
variable name or value was silently discarded (eg `file /tmp/xyz;` resulted
in a file `tmp/xyz`).
Reported by BlackBishop in https://bugs.unrealircd.org/view.php?id=6325
This is a mandatory module to load, and included in modules.default.conf.
This also meant that the crule_test() etc efunctions are available
before running config test routines, so we now have a flag for
early efuncs. I guess we could consider doing that for all efuncs
though, so not sure if this flag is really needed.
and that nick could be on someones watch list. In such a case we
should not only send RPL_LOGON but also a RPL_GONEAWAY.
Reported by Khaled and fix suggested by Khaled & Sadie.
for this is that system argon2 is often much slower (2x slower
on Ubuntu and Debian, for instance), which is not good.
You can still use the system library with the configure option:
--with-system-argon2
Often you have default values for the config, and then a subsequent config
parsing run would overwrite the return value (= memory leak), merging/appending
would make no sense either, so it would force a free in all code before
calling us, well... let's just deal with it ourselves instead then ;)
The spamfilter::action stop ill prevent processing other spamfilters.
This would normally be a bit unusual, and potentially dangerous when you
do exclude things this way, but can be useful in some circumstances.
Stopping only affects the same type of spamfilters (general or central
spamfilters), so they don't interfere.
The tkldb write DB bug had to do with that it was processing
central spamfilters, which should be skipped just like config
based spamfilters were already skipped.
you can now configure to hide the message content in spamfilter hit
messages. Generally it is very useful to see if a spamfilter hit is
correct or not, so the default is 'always', but it also has privacy
implications so there is now this option to disable it.
Suggested by alice, quite a while ago.
https://www.unrealircd.org/docs/Set_block#set::spamfilter::show-message-content-on-hit
Also as mentioned there:
UnrealIRCd has the following spying countermeasure (for many years) to help
that spamfilters are not abused for spying. When a spamfilter hit happens
that has an action like gline or blocking, it is visible to the user that an
action was taken. There is also the action 'warn', which means: take no
action and only warn IRCOps, that one would be easy to use as a spy tool, so
when this happens and message content was revealed, numeric 659
(RPL_SPAMCMDFWD) is sent to the client to indicate that the message is
allowed through but IRCOps were informed.
With this new set::spamfilter::show-message-content-on-hit feature, when
the message content was hidden due to this setting (eg due to 'never' or
'channel-only'), the warn message will not be sent as there is no need to
inform the user in such a case.
to limit actions to limit-ban-action as the highest, and limit
ban times to limit-ban-time the highest, see
https://www.unrealircd.org/docs/Central_Spamfilter
This also changes highest_spamfilter_action() to highest_ban_action().
* This means we always run spamfilters, even if users are exempts
* This way we can gather hits for exempted users on individual
spamfilter entries, and possibly detect false positives
(which relies on the assumption that those users are innocent)
* The hit counters are shown in in RPL_STATSSPAMF and also
exposed via the JSON-RCP API.
* This commit also adds set::central-spamfilter::except but more
on that later since i still want to set a default for that in
a future commit.
* This also changes take_action() to take flags and adds the
option TAKE_ACTION_SIMULATE_USER_ACTION which i intended to
use but didn't in the end... not sure if i should keep it :D
Not sure if that could possibly get triggered, actually, as
it would mean the (async) SSL_connect() would have to succeed
instantly and then the SSL_write() would have to fail, but
better safe than sorry.
This uses the RPC2 API. Tested with staging.
Note that there are likely some bugs here or there, like memory leaks,
but the functionality is there.
Also still need to implement various stuff, including spamreport::rate-limit
The former didn't make much sense:
if (!rejected_deletes && *rejected_deletes > max_rejected_deletes)
The most simple fix would have been removing the '!' there.
However, i chose to rewrite part of the function so we only set
*rejected_deletes once, and use normal integers (not pointer to integers)
in all the preceding code. Less room for error.
Only match was working earlier, and for now both are accepted,
like everywhere else. Reported by BlackBishop.
Also, added a missing check for unknown rpc-user items, so a
proper "Unknown directive" error is thrown.
(this missing check made the first issue worse)
that was added late in 6.1.1 development to fix a crash with removing
websocket listeners. Now replaced with a generic HOOKTYPE_CONFIG_LISTENER
that is not only called for removed listeners, but for all listeners.
The whole point of (G)ZLINEs is that it rejects instantly upon
accept, that's what makes them different from KLINE/GLINE.
Commit 89075e532a made it
accidentally use the slow path for this as well.
Without CMD_BIGLINES: parameters to commands can be 510 bytes max
(but eg. strlen(parv[1])+strlen(parv[2]) can be >510, like 510*2,
when received from servers with BIGLINES support).
If someone does set CMD_BIGLINES in their CommandAdd() then the
parameter(s) size is not limited an can be up to 16k.
This is a bit more risky than previous but i think most command
handlers can handle parameters of max BUFSIZE/512 just fine
and care less about the grand total. Also, the risk is only
from server traffic and not from user traffic. Still, we will
keep going through the source to check for issues.
to avoid a crash in todays code which was like:
1) exit_client gets called
2) close_connection() sets client->direction to NULL
3) a bit further it calls remove_dependents()
4) a sendto is attempted and the new code accesses
client->direction which is unexpected to be NULL
Actually i should probably trace the cause of the sendto_one()
but that is another story ;)
previously it was set to 'nick'
Also allow the full topic length for the nick-user-host case, now that
we have BIGLINES support. For non-BIGLINES-servers this could mean a
potential cutoff of the last 20 characters of the topic, which is why we
restricted it to 340 instead of 360 for nick-user-host previously, but
that is really only in the corner case / worst case, like with max NICKLEN,
max USERLEN, max HOSTLEN, max CHANNELLEN, etc... i think we can live
with that small "problem" until all servers upgrade.
when it is not possible, mixed server scenario).
Now a big RRPC response like server.module_list for a remote server
(44KB) fits in only 3 lines, instead of almost 100 lines.
`PROTOCTL BIGLINES` is set. This will allow us to do things more
efficiently and possibly raise some other limits in the future.
This 16k is the size of the complete line, including sender,
message tags, content and \r\n. Also, in server-to-server traffic
we now allow 30 parameters (MAXPARA*2).
The original input size limits for non-servers remain the same: the
complete line can be 4k+512, with the non-mtag portion limit set
at 512 bytes (including \r\n), and MAXPARA is still 15 as well.
* I chose 16k because I don't want to first raise it to like 8k
and then realize later that 16k would be better and raise it again.
* To receive BIGLINES in a command, you need to `CommandAdd()` with
flags `CMD_BIGLINES`, without it you still get regular 512 max.
This is so, because a lot of the code does not expect longer than
512 bytes lines or in parameters, so we can gradually change that
(where needed).
https://ircv3.net/specs/extensions/chathistory#isupport-tokens
The spec says they should be 'in order of decreasing preference'.
As currently the only backend is in-memory, this doesn't matter so I
picked `msgid` first (as it's less ambiguous); but this can be revisited
later if/when adding a backend which is more efficient with timestamps.
Has to do with running HOOKTYPE_SERVER_CONNECT too soon, before
introducing ourselves to the other side. This bug was created in
commit ddf639836b so exists in
all UnrealIRCd 6 versions (-beta1 and up).
The hook call is now moved further down.
unreal_duplicate_masks()
duplicate_nvplist()
duplicate_name_list()
And use this for when proxy::type is web, to duplicate the
exact criteria to the ban exception as mentioned in previous
commit.
for blacklist, connect-flood, handshake-data-flood
(Well, unless mask::ip is used with a wildcard, due to current
technical limitations, that will be resolved later)
and also for safety when redoing DNS and ident due to IP change,
we now:
ClearIdentLookupSent(client);
ClearIdentLookup(client);
ClearDNSLookup(client);
depending on what we get from the proxy, so it can be used later
in the websocket module for setting the user secure or not
(the latter similar to what k4be already did in the old code).
This now requires a proxy { } block -- docs follow soon
This uses part of k4be's code still, to do the parsing,
so still only "Forwarded" and quick workaround for bug
when for=XXX is the final item.
a function called start_dns_and_ident_lookup(). This can then
be easily called from other places as well, like the code k4be
did in src/modules/websocket.c to handle proxies.
Side-effect is that ident lookups would now be done, if we are
configured to do so, for forwarded webirc stuff (not that I
think many people use that feature at the moment...).
It is now possible to override some set settings per-security group by
having a set block with a name, like `set unknown-users { }`
* You could use this to set more limitations for unknown-users:
```
set unknown-users {
max-channels-per-user 5;
static-quit "Quit";
static-part yes;
}
```
* Or to set higher values (higher than the normal set block)
for trusted users:
```
security-group trusted-bots {
account { BotOne; BotTwo; }
}
set trusted-bots {
max-channels-per-user 25;
}
```
* Currently the following settings can be used in a set xxx { } block:
set::auto-join, set::modes-on-connect, set::restrict-usermodes,
set::max-channels-per-user, set::static-quit, set::static-part.
That file has such a clear warning in it but still people
manage to load old ones. That being said, usually it is not
deliberate, like an cp ../unrealircd.old/conf/* conf/
the default set::max-channels-per-user (also called set::maxchannelsperuser).
This way you can give known-users a higher max-channels-per-user,
or even a special security group for trusted users (that you may
already have given a more lax flood setting and lower lag-penalty
etc. etc. so that fits in nicely)
And yeah this also:
* Makes it both in set and the anti-flood block accept both
maxchannelsperuser and max-channels-per-user.
* Removes old MAXCHANNELS= in 005, as we already have CHANLIMIT=
This does not:
* Re-announce the 005 CHANLIMIT= if someone transitions from a security
group with a different max-channels-per-user. We don't do that for
IRCOps either, and I think no IRCd does that actually...
To be honest i wonder if sending the limit in 005 is useful at all,
do client really track this and limit their GUI based on it?? Doubt it!
(or changing the port number). Reported by Nini.
Rather complex case: when the listen block is removed, obviously
the config hooks are not called for the (now non-existing) listen
block, and thus the websocket->request_handler and such are not
set to the new address of the websocket handler.
We now use a slightly silly workaround / new hook to fix this
corner case. Ideally there would be an extra layer in-between
like a handler lookup by name, or something like that.
(Or make the websocket module PERM but we don't want that!)
This so you can use throttling exceptions (eg in ELINE) on hostnames.
That is, the above is during normal circumstances. Similar to previous
commit we will turn this feature of during high connection rates.
That is a TODO item.
This is the start of "be more friendly to TLS users with disconnect
error messages" from https://bugs.unrealircd.org/view.php?id=5532
As that bug explains:
Consider doing the SSL/TLS handshake even for throttling errors and such
when the (reject) connection rate is below a certain amount per second. If
it is higher than a certain rate, then fall back to the original behavior to
reject the user instantly without handshake or looking at any data.
Rationale: the current/original behavior is there so the ircd can handle
floods, both in terms of traffic and in terms of CPU usage (the SSL/TLS
handshake is quite costly after all). The downside of the current behavior
is that TLS users don't see the error message, usually. This feature
request tries to find a middle ground.
Still a TODO item:
* We don't detect high rates yet, so we only do this new behavior atm
and not yet the old behavior during high connection rates.
* Verify that error messages/behavior hasn't changed (too) much,
like the throttling and the banning disconnect messages.
This adds user_can_see_member_fast() which is used in at least 3 places
now, more places may follow later. It has extra paramters for membership
and membership modes that is very likely already looked up by the caller
(or if not, it is worth doing so by the caller).
This is work in progress so if everything crashes or people mysteriously
seem not present in channels (or the other way around) i would not be
surprised :D.
When sending to channel members this will cache full IRC protocol
lines, including message tags and \r\n, for similar clients.
This avoid the need for many mtags_to_string() calls and also
entire parts of sendbuf_to_one() can be skipped as well.
The "Similar clients" cache entries are defined as clients that:
1) Are of the same type: normal local client, ircop local client
or remote client.
2) Have the same CAPs set, that is: we only look at CAPs that actually
have anything to do with message tags ('clicaps_affecting_mtag')
3) Optionally there can be an explicit line_opts. It is not used yet
but could be used when there are different type of lines sent
depending on other criteria, such as chanop status or something
else that doesn't fit in #1 and #2.
a bug when two servers merge, you could see +beI items being set that
already exist, if the timestamp or setter differed between servers.
Now they are updated but no +beI is shown.
https://bugs.unrealircd.org/view.php?id=5681
https://www.unrealircd.org/docs/Set_block#set%3A%3Ahandshake-boot-delay
which allows server linking autoconnects to kick in (and incoming
servers on serversonly ports), before allowing clients in. This
potentially avoids part of the mess when initially linking on-boot.
This option is not turned on by default, you have to set it explicitly.
* This is not a useful feature on hubs, as they don't have clients.
* It can be useful on client servers, if you `autoconnect` to your hub.
* If you connect services to a server with clients this can be useful
as well, especially in single-server setups. You would have to set
a low `retrywait` in your anope conf (or similar services package)
of like `5s` instead of the default `60s`.
Then after an IRCd restart, your services link in before your clients
and your IRC users have SASL available straight from the start.
This results in less write calls (lower load) and more data per packet
(more efficient network traffic). It helps for the webserver (JSON-RPC)
but should also help IRC traffic when returning more than a line or so.
Previously the first TCP packet was not always filled fully, eg it was
close to 512 bytes instead of being close to 1500 bytes (MTU). Strange
that this happened in the first place, by the way, as we don't set
TCP_NODELAY. But whatever...
"Too many unknown connections from your IP".
Need to check 'c' in the loop, not 'client', duh!
If you have multiple tabs of the webpanel open and the panel is
not hosted on the same machine as the ircd (does not connect over
127.0.0.1) then you will experience this bug. Pages or content
will fail to load or will load very slowly.
conf/rpc.modules.default.conf. This because:
1) It matches the default in example.conf for ircd.log
2) It is a more privacy-friendly setting
3) The log entries are spammy / fill the memory log buffer quickly
other remote included files still being downloaded.
This issue exists both with and without cURL, so in both url interfaces.
Was finally able to reproduce this on my own machine. This bug exists
since at least 6.0.0 and perhaps even before that. Just doesn't get
triggered that often due to needing an error and a certain timing
condition (well, and ASan catches it, but on some systems it may
go unnoticed).
Actually I presume 'make install' properly removes the file first
before installing a new one, but.. not entirely sure. Better safe
than sorry.
We have had new reports of someone who had the original UnrealIRCd
crash while building the new UnrealIRCd. Similar to what we had
a few years ago, which was caused by a 'cp' instead of an rm+cp.
This because with simple cp the existing file contents is changed
and the processes holding the .so file open (usually mmapped)
suddenly have the new .so file loaded in effect, which causes a
crash whenever next function is called in that library.
We now rm explicit before 'make install' so running processes
simply have that fd point to a deleted file, which is fine.
as that is the same method we use in connect-flood.
I don't think the client->local && client->local->listener checks
are needed, but since we are post last RC (I hope): better safe
than sorry...
This fixes you no longer being able to get on to the IRC network if you
also run the webpanel from your same source IP (and other similarly
weird errors, of course)
They are similar to sendnumeric/sendnumericfmt, but allow an array of message
tags are parameter.
sendnumeric/sendnumericfmt are now shorthands for sendtaggednumeric/sendtaggednumericfmt
which pass NULL as mtags.
(so listen::file). This way you can override the IP address that users come
online with when they use the socket (default was and still is `127.0.0.1`).
Add a new guide https://www.unrealircd.org/docs/Running_Tor_hidden_service_with_UnrealIRCd
which uses the new listen::spoof-ip and optionally requires a services account.
for the add, like: nick-change, quit, server terminating. Add logon time.
I also think i will move from user.get_whowas to a whowas.XXX since the
returned object is not a user object and getting more different each commit :D.
* We now only exempt `127.0.0.1` and `::1` by default (hardcoded in the source).
Previously we exempted whole `127.*` but that gets in the way if you want
to allow Tor with a
[require authentication](https://www.unrealircd.org/docs/Require_authentication_block)
block or soft-ban. Now you can just tell Tor to bind to `127.0.0.2`
so its not affected by the default exemption.
Reported on IRC and by PeGaSuS in
https://bugs.unrealircd.org/view.php?id=6258
This way things like the TOPIC will keep their color codes if they have it.
Reported by armyn in https://bugs.unrealircd.org/view.php?id=6259
(And yeah i used a global to achieve this, otherwise it has too much
of a cascading effect in XYZ functions)
RFC6455 clearly says:
Defines whether the "Payload data" is masked. If set to 1, a
masking key is present in masking-key, and this is used to unmask
the "Payload data" as per Section 5.3. All frames sent from
client to server have this bit set to 1.
But ok, we'll make an exception for PONG.
This caused the websocket connection to be dropped after a while from
the unrealircd-rpc-php library that uses textalk/websocket.
Probably a bug in textalk/websocket or one of its dependencies,
that should be reported...
It also has an object_detail_level like some other calls.
The "top_countries" are included from object_detail_level 1 and above.
The default object_detail_level is actually 1, so it is included by
default. You can use object_detail_level if you don't want it.
Idea for this was from Valware.
https://www.unrealircd.org/docs/JSON-RPC:Stats#stats.get
will be updated in a minute...
the replacement character (good) but then stop processing the rest
of the string (bad).
This only happened if called with strict=0, which only happens in
the JSON and logging routines. So not in user-exposed stuff like
the websocket code.
Suggested by Chris_dc in https://bugs.unrealircd.org/view.php?id=6252
This uses unrealircd.org/real-quit-reason internally, but is only
exposed to servers, never to users. It results in using that quit
reason for IRCOps, while using the regular quit reason for normal users.
For example: +e ~flood:*:~account:TrustedBot
Suggested by PeGaSuS in https://bugs.unrealircd.org/view.php?id=6204
Will refine the checking and perhaps sorting of floodtype(s) later...
can be used from +f/+F as an action. You need to specify for which
flood type your mode is, eg `cmode.flood_type_action = 'j';` for joinflood.
Currently a mode can only choose one flood type action due to +f/+F
timer fights that could otherwise occur, but that shouldn't be too
much of an issue since we can live with that in core as well.
These were already not counted for set::anti-flood::xx::nick-flood
and it makes sense.
Benefit of this is that limits for floodtype 'n' can be set tighter,
as now it is really only about manual (voluntarily) nick changes.
From: [rpc] Client RPC:adminpanel (Syzop): RPC call channel.set_mode: channel='#test', modes='+b', parameters='some!silly@ban'
To: [rpc] RPC call channel.set_mode by RPC:adminpanel (Syzop): channel='#test', modes='+b', parameters='some!silly@ban'
This so the most important information is shown first (generally a good principle :D)
This so multiple parallel requests can be handled properly.
JSON-RPC over websockets is unchanged, as every JSON-RPC
requests goes into its own websocket frame there (easy).
This will communicate the original issuer of a command.
For example an "SAMODE #test +s" results in a SAMODE coming from
:maintest.test.net MODE ....etc....
And with this feature, we will communicate the IRCOp who did it:
@unrealircd.org/issued-by=OPER:Syzop..etc....
This tag is only sent to servers and to IRCOps, not to ordinary users.
The plan is to support the following variants:
Services: unrealircd.org/issued-by=SERVICES:NickServ@services.test.net
IRCOp: unrealircd.org/issued-by=OPER:Syzop@maintest.test.net:Operblock_name
JSON-RPC: unrealircd.org/issued-by=RPC:adminpanel@irc1.test.net:Adminpanel_Actual_User
This first commit only adds SERVICES and OPER in the handlers of the
SVSNICK and SAMODE commands. The JSON-RPC variant and all of the other
commands have not been done yet.
instead of the server executing the MODE. Eg unrealircd.org/userhost
was set. This occured because the client = &me; was done after
the message tag preparation, now moved up so it's done before.
See release notes:
+* The RPC modules are enabled by default now. This so remote RPC works
+ from other IRC servers for calls like `modules.list`. The default
+ configuration does not enable the webserver nor does it cause
+ listening on any socket for RPC, for that you need to follow the
+ [JSON-RPC](https://www.unrealircd.org/docs/JSON-RPC) instructions.
[skip ci]
for this amount of seconds (default: 75) when a server splits.
This helps in case a server dies and the clients reconnect to the
other servers, causing a join-flood to be triggered needlessly.
Of course, OTOH disabling a flood protection temporarily is not
ideal, but after seeing it being triggered too often and requiring
manual intervention in many +f/+F channels, this is the best option
I think, if we want +f/+F to work as painless as possible.
If you have a large network (eg: >5 servers) with equal user
spreading then you could disable this by setting it to 0, since then
1 server dieing may not have enough impact on +f join floods
for this to be needed.
TODO: Documentation and release notes
This is an integer which decides the amount of details in the response object.
See https://www.unrealircd.org/docs/JSON-RPC:User#Structure_of_a_client_object
Especially for user.list it can be a good idea to ask for less detail if
you don't need all the information. It's up to you...
When 'object_detail_level' is not specified in the request, then:
* For user.list it defaults to 2, which is a "breaking change" in the sense
that it leaves out the "channels" field. To see the "channels" field you
would have to use level 4.
* For user.get it defaults to 4, which results in the same output as 6.0.7.
* This makes sense so user.list is shorter than user.get, just like we
already did in channel.list and channel.get.
By the way, this is all documented in the API calls at
https://www.unrealircd.org/docs/JSON-RPC:User
and for channels at https://www.unrealircd.org/docs/JSON-RPC:Channel
This also changes the Detail level (object_detail_level) for the channel.* calls.
See https://www.unrealircd.org/docs/JSON-RPC:Channel_Object for latest info.
In short: at level 5, we now still hide the members.user.channels because
in general that object is not useful. When you do a channel.* API call
you want a list of users in the channel, and don't really care about
what other channels the user is in, other than the channel you already know.
This is an integer which decides the amount of details in the response object.
For the channel.* calls the object_detail_level is one of:
0: only return the channel name, nothing else
1: basic channel information only
2: this adds bans, ban_exemptions, invite_exceptions
3: also show members, but only level/name/id
4: also show members, level/name/id/hostname/ip/details/geoip
5: also show members, level and full user details like user.get
When no object_detail_level is specified, the following defaults are used:
For channel.list the default is 1 (matches current 6.0.6 behavior)
For channel.get the default is 3 (matches current 6.0.6 behavior)
Using channel.list with object_detail_level=5 is forbidden because
it would cause way too much output (and processing time).
Actually it accepts the following variations for this query:
MODE #test f
MODE #test +f
MODE #test F
MODE #test +F
As long as it is like that (with no parameter) we will show details.
Details are shown for all of the four possible combinations of having
or not having +f and +F.
For example "+F normal" and "+f [1k,20t]:10" result in this output:
Channel '#test' uses flood profile 'normal', without action(s) 'k' as they are overridden by +f.
Effective flood setting via +F: '[7c#C15,30j#R10,40m#M10,10n#N15]:15'
Plus flood setting via +f: '[1k,20t]:10'
-
List of available flood profiles for +F:
none: []:0
very-relaxed: [7c#C15,60j#R10,10k#K15,90m#M10,10n#N15]:15
relaxed: [7c#C15,45j#R10,10k#K15,60m#M10,10n#N15]:15
normal: [7c#C15,30j#R10,10k#K15,40m#M10,10n#N15]:15
strict: [7c#C15,15j#R10,10k#K15,40m#M10,10n#N15]:15
very-strict: [7c#C15,10j#R10,10k#K15,30m#M10,10n#N15]:15
See also https://www.unrealircd.org/docs/Channel_anti-flood_settings
When a channel CTCP flood happens and there is an +f with the 'c' floodtype,
we set channel mode +C by default. Alternative action possiblities
were +m and +M. I don't think anyone really used those alt actions for CTCP
because makes little sense to set the channel +m/+M on a CTCP flood when
there is +C which has far less impact.
More important, the fact that +m/+M could be set both upon CTCP flood
and upon message flood, this 'dual timer' thing, makes it rather
complex when we now have both +f and +F, so easiest solution is just
to scratch this possibility :)
if the join flood is caused by >75% of "unknown-users". This
to see if that will take care of the flood without harming
the "known-users" group. And naturally, do something similar
for message floods and nick floods.
If the flood persists, because they are caused by known-users,
then the +i/+m/etc actions are still taken.
This is work in progress, and some things are set to useful-
for-testing values, such as an unsettime of 1 minute.
for OpenSSL 1.0.2 anymore, 1.0.2 will use the fallback version.
This changes the include file.
(OpenSSL 1.0.2 is out of support since Jan 1 2020 so one may wonder
why care at all, but i'm trying not to break that during minor
UnrealIRCd releases)
the realhost/IP is communicated on a separate line. This so you now
can see both vhost/cloakedhost and realhost as an IRCOp in a single
WHOWAS request.
This also adds the MAXLINELENGTH define which is set to 4K+4K+512,
it can be used when you are dealing with complete lines (quite rare
in the code, mostly in socket code and labeled response).
And now also #define READBUFSIZE MAXLINELENGTH
but it is used beyond read buffers, als in write buffers of course.
Actually make them both use this same function, even thought he original
vhost::vhost check was a bit more informational.
This also checks the vhost in other paths that lead to oper vhost setting.
Reported by ji in https://bugs.unrealircd.org/view.php?id=5910
This was a counting bug in src/socket.c. The socket itself was actually
freed though, so it's purely counting that was wrong.
There could still be counting bugs elsewhere, it's always hard to get
this right, for 20 years already :D
This was previously tried at 19-apr-2020 in bc70882bd3
in UnrealIRCd 5.0.5. Sadly it had to be reverted immediately with a quick 5.0.5.1
release, all because of a PCRE2 100% CPU usage. Since then that bug has been fixed,
plus another bug. I'm now readding it "as an option" that is marked experimental.
Hopefully people test it out and can report back if it works well and then we can
make it the default someday.
This makes it a runtime setting so makes it much easier to switch back/forth if
there are any issues without recompiling anything. Had to use a bit more code now
though to handle the recompiling of spamfilters if the setting is changed.
Original issue was https://bugs.unrealircd.org/view.php?id=5187
* [Spamfilter](https://www.unrealircd.org/docs/Spamfilter) can be made UTF8-aware.
* This is experimental, to enable: `set { spamfilter { utf8 yes; } }``
* Case insensitive matches will then work better. For example, with extended
Latin, a spamfilter on `ę` then also matches `Ę`.
* Other PCRE2 features such as [\p](https://www.pcre.org/current/doc/html/pcre2syntax.html#SEC5)
can then be used. For example you can then set a spamfilter with the regex
`\p{Arabic}` to block all Arabic script.
Please do use these new tools with care. Blocking an entire language
or script is quite a drastic measure.
* As a consequence of this we require PCRE2 10.36 or newer. If your system
PCRE2 is older than this will mean the UnrealIRCd-shipped-library version
will be compiled and `./Config` may take a little longer than usual.
Reported by westor in https://bugs.unrealircd.org/view.php?id=6104
The code was there but the order of which the checks were done was
wrong, so first it was checking which CAP's were unloaded and after
that it was unloading the CAP, instead of the other way around.
Also renamed the function to clicap_check_for_changes()
to be consistent with other runtime change detection functions
like extcmodes_check_for_changes(), umodes_check_for_changes()
and charsys_check_for_changes().
entries that have the tag "oper", IOTW: the ones that are added
through the oper { } block, and not the ones added through
different means like a vhost { } block.
Really minor thingy but suggested by JanisB in
https://bugs.unrealircd.org/view.php?id=4233 and actually
possible nowadays when swhois items are tagged.
Hint: if you use SVSO to make someone oper, and then add swhois
entries, be sure to tag them with a setby of "oper" too, that
way they are hidden in +H and also automatically removed from
the user when the user does "MODE nick -o" to de-oper.
if you do actually have 1 snomask configured (a single one).
Although this is rather rare and unusual, it should be possible.
Previously we required at least 2 snomasks and the counter
did not properly reset during rehashes. Not sure why we required
2 and not 1, and the counter reset was a bug.
Reported by westor in https://bugs.unrealircd.org/view.php?id=5994
Reported in https://bugs.unrealircd.org/view.php?id=6100
Actually this only works if you have a:
blacklist-module geoip_classic;
in your conf and that conf is read before modules.default.conf
This is true if you have that blacklist-module line in your
unrealircd.conf, so should cover most cases.
Reported by 9pfs in https://bugs.unrealircd.org/view.php?id=6248
This is completely untested (other than ./unrealircd start), so
feedback from people who actually use crule like in deny link { }
is very much welcomed.
due to flood attacks, back then we changed the argument silently to
point to our own server, eg 'INFO some.remote.server' ended up being
'INFO' (local server) when requested by non-IRCOps.
Now, we simply return "Permission denied" in such cases, which is
more clear and explicit.
Reported by progval in https://bugs.unrealircd.org/view.php?id=6004
Reported by westor in https://bugs.unrealircd.org/view.php?id=6122
This because is_module_loaded() returned the 'current state' rather than
the 'future state', as mentioned in is_module_loaded() in a comment there.
Fix was swappping two lines.
Thanks to Noisytoot for https://github.com/unrealircd/unrealircd/pull/227
who suggested displaying account and provided a partial patch, and
armyn in https://bugs.unrealircd.org/view.php?id=6153 suggesting IP.
I chose to use the existing RPL_WHOIS* numerics that we also use for
returning WHOIS data. We already use RPL_WHOISSERVER in WHOWAS for
ages and the use of it is mentioned in RFC1459, so seems like that
was the idea right from the beginning of times. The only change I did
was from "is" to "was" in like "was logged in" and "was connecting from"
in the text of the numerics.
and other systems where 'make' was not GNU Make.
It now uses the same detection mechanism as in ./Config, which
should be known to work.
Reported by Valware and rj1 in https://bugs.unrealircd.org/view.php?id=6195
during MOD_INIT, while an IRCOp is listening. Or any log call, really.
This causes the code path: config_warn() -> do_unreal_log_opers() -[..]->
sendto_one() -[..]-> client_accepts_tag() for a client tag handler that is
no longer loaded.
The fix is to unload very late and load very early, a trick
we did earlier with websockets as well (c3824ad47d).
This so users can come online directly with the correct vhost set,
and not first with a standard (usually cloaked) host while auto-(re-)joining
followed by a CHGHOST later.
This is a long outstanding wish from users, I think.
Services can simply send a CHGHOST/CHGIDENT to the UID, for example
right before they send the SASL ... D S message (SASL succeeded)
they can send like: CHGHOST 002ABCDEF some.nice.host
Then UnrealIRCd 6.0.7-git and later will handle the CHGHOST even if
the user is not known yet. Technically, the server where the UID is
on will handle the message. And remote servers that don't know the
user with this UID yet will forward to the server with the SID-portion
of the UID. The CHGHOST will not be a broadcast but the vhost will
show up in the UID protocol message that introduces the user.
For CHGIDENT it is a similar story.
Light testing has been done but more extensive testing is welcomed.
Not sure if this is the best name, maybe I come up with a better one later.
The purpose of this function is so we can deliver certain messages to
pre-auth users, that is: users that are not fully registered yet.
This would mostly be used (perhaps exclusively) in SASL stage.
This is checked for both local and remote services linking in.
Naturally, the list can be expanded to include more services that
really need ulines { }, and not statistical services or some other
purpose non-unrealircd servers, which is the reason why cannot
blindly assume all non-unrealircd servers require ulines.
This should hopefully help users a lot with "mysterious" issues
with services that we see too often in the support channel.
Suggested in https://bugs.unrealircd.org/view.php?id=5742
Note that this does require services to communicate their software
version via EAUTH. Anope does this for years already, but atheme only
does so since 10 days ago (git only, presumably not released yet)
after Valware filed a PR.
This ensures that strings are of maximum 510 characters in length
and do not contain \n or \r.
Solves a lot of theoretical problems in many modules that .add
things or do other non-list/non-get actions.
This behavior can be turned off per-method (per handler) by setting
handler->flags = RPC_HANDLER_FLAGS_UNFILTERED;
This is currently not done in any of the modules.
since these are rather noisy and generally not very interesting to log.
Of course, DO log them if they are like add/delete/etc.
The way this works is a new property in the RPCHandler, eg:
memset(&r, 0, sizeof(r));
r.method = "server.list";
+ r.loglevel = ULOG_DEBUG;
r.call = rpc_server_list;
if (!RPCHandlerAdd(modinfo->handle, &r))
All of the .list and .get (and things like .module_list) now use
the debug facility, which is not logged by default.
You can still log ALL the JSON-RPC calls if you wish, for example
to a separate file, through something like:
log {
source { rpc; }
destination {
file "rpc.log" { maxsize 100M; }
}
}
including Lord255, armyn and others.
The issue was not there when running with ASan, which is why it
was non-reproducible for so long. Valgrind picked it up correctly.
The bug was that in rpc_response() and rpc_error() I do:
id = json_object_get(request, "id");
[..]
json_object_set_new(j, "id", id);
which is wrong, since json_object_get() "borrows the reference"
and json_object_set_new "steals the reference".
In this particular case it should be:
json_object_set(j, "id", id);
Fixed in both functions. Would have to audit the code if the mistake
is made elsewhere too though. On first sight, it seems not.
* If the remote server (and all servers in-between) support RRPC
then forward the RPC request as RRPC and let remote handle the
response. The response will be the verbose rehash response.
* If not supported, then simply return boolean true as a response,
and use oldskool :source_server REHASH dest_server over the wire
remote server does not have the JSON-RPC module(s) loaded.
Internally this uses the "rrpc" moddata property that each server will
now set on themselves if the rpc/rpc module is loaded.
Actually I am going to make this more verbose and better later...
(Required RPC modules to be loaded on the remote server, tho)
This adds support for remote async RPC requests that take a little longer,
in such a case we don't call free_client() upon return of rpc_call().
Inform the RPC client that the request timed out / server is gone.
The timeout is fixed at 15 seconds, which is fine, I think.
New rpc error codes:
JSON_RPC_ERROR_SERVER_GONE = -32001, /**< The request was forwarded to a remote server, but this server went gone while processing the request */
JSON_RPC_ERROR_TIMEOUT = -32002, /**< The request was forwarded to a remote server, but the request/response timed out (15 seconds) */
Unfortunately we cannot say for sure the action did not succeed at all.
It could be that the request never reached the server, but it could also
be that the request DID reach the server and we timed out during
retrieving the response. Nothing we can do about that.
sent over the IRC network. This makes it possible to fetch information
from remote servers that is not known locally, and also it makes it
possible to do more things, or do it easier.
This does require the remote servers to enable RPC as well, though,
eg: include "rpc.modules.default.conf";
(They don't need any listener or rpc-user blocks)
Code-wise it looks nice, like from rpc_server_module_list it is a simple:
/* Forward to remote */
rpc_send_request_to_remote(client, targetserver, request);
This is work in progress. In particular, there is no handling yet of
timeouts (eg if the request to the remote server, or the response
from it takes ages). Nor does it handle the case where the server
quits half-way through the request/response... that is: it does free
the request and such, but does not notify the RPC client about it.
That will need to be added, of course, likely soon.
Over the IRC network this uses the new RRPC command:
:<server> RRPC <REQ|RES> <source> <destination> <requestid> [S|C|F] :<request data>
A request looks like this (assuming it is short):
:001 RRPC REQ 001ABCDEF 002 abc SF :..this is the json request...
And then the response (assuming it is long) is like:
:001 RRPC REQ 001ABCDEF 002 abc S :..this is the json response...
:001 RRPC REQ 001ABCDEF 002 abc C :..more...
:001 RRPC REQ 001ABCDEF 002 abc C :..more...
:001 RRPC REQ 001ABCDEF 002 abc F :..and that was it.
There is currently no request/response limit, it is limited by memory.
Right now the only call using this is server.module_list when called
with a param of "server":"some.remote.server"
so we can deal with empty fields that get sent f.e. by anope,
like EAUTH=services.test.net,,,Anope-2.0.11
Apparently this is similar to strsep(), or actually hypothetical
strsep_r(), a function which does not seem to exist.
(directly connected server only at the moment)
This also cleans up the linking procedure (now) at 3 places,
to use find_link() and check_deny_link() everywhere.
RPC clients with the RPC user and such.
Most of this work is for server.rehash which causes the request to
be saved, then a rehash begins, and a few seconds later (or whenever)
the entire rehash log and success/failure is indicated in the
JSON-RPC response.
TODO: all documentation for this
This bug exists since 5.2.1 already, so i guess the functionality is
not used much ;). Makes sense, since for simple ~account:* you have +R already,
so it is only useful in stacked bans such as +e ~nickchange:~account:*
We now have a test case so that this bug won't "ever" reoccur.
Reported by rafaelgrether in https://bugs.unrealircd.org/view.php?id=6211
so in name_ban, server_ban, server_ban_exception and spamfilter.
This could be used, for example, by an admin panel to tell which
end-user that authenticated to the panel (eg 'OperX') added/removed
the TKL, instead of showing up as 'RPC:xyz' in the logs and bans.
This gets rid of duplicate code in SETIDENT, CHGIDENT, and soon
in the RPC call. It does not get rid of make_valid_username()
in src/modules/nick.c which does something slightly different.
I don't think it should return the whole channel struct here as if it
was a channel.get. Only thing is that, especially or only with set_mode,
it may actually be 100% success... eg if your mode line is wrong :D.
Also bump API versions on user.* and channel.*
This also makes the "forced nick change" message a bit more
generic, leaving out the "by services" or "due to Services",
since it is now possible to do it via JSON-RPC.
as requested in https://bugs.unrealircd.org/view.php?id=6206
And also for channel.get, in "members", include the UID in "id".
This breaks the current format but we don't have many users yet anyway.
Something tells me that will happen more ;)
This also bumps the user and channel RPC modules from 1.0.0 to 1.0.1
In user.get (and currently user.list too) this shows as:
"channels": [
{
"name": "#test",
"level": "o"
}
]
And in channel.get (not .list) this shows as:
"members": [
{
"name": "abc",
"id": "00129BP02",
"level": "o"
},
{
"name": "def",
"id": "001LFMB05"
}
]
This because for JSON-RPC you expect all accurate data, while in contrast
with JSON logging the channels are just there for convenience and only
show the first X channels, since otherwise the data gets too long
and gets truncated (JSON logging uses channel detail level 0).
keep them open, but do a websocket ping/pong to check if the
connection is alive.
This is usually handled by browsers themselves, but if you are using
websockets from a non-browser then you may have to PONG back on
a PING, see https://www.rfc-editor.org/rfc/rfc6455#section-5.5.2
(note that PING-PONG is a requirement there)
Eg if there are 10.000 users online and you do user.list.
The old websocket framing assumed no response was >64Kb.
This also creates a new function websocket_create_packet_ex()
Valid choices are 0700, 0770 and 0777, see the documentation at
https://www.unrealircd.org/docs/Listen_block
Unrelated: this also documents the ConfigItem_listen struct in struct.h.
socket listening in data/rpc.socket, because why not... only the
ircd user has access to it by default (well, and root).
Don't add the external listener HTTP(S) port by default though,
because not everyone may want that exposed to the outside world.
The default creation of data/rpc.socket can be prevented by a
@define $NO_DEFAULT_RPC_SOCKET "1"
Something like "1h" was intepreted as unixtime 3600 (=expired long ago).
For absolute times there is already "expire_at" (JSON timestamp).
Now, "1h" is properly interpreted as meaning 1 hour from now, as intended.
This bumps the version of rpc/server_ban to 1.0.1.
Reported by armyn.
This was documented as optional in include/modules.h but on
https://www.unrealircd.org/docs/Dev:Extended_Bans_API it
was always mentioned as required.
In practice, I know of no module that does not have this,
in UnrealIRCd or third party (doing zero filtering is
quite a bad idea).
Anyway, long story short: this also means we can remove some
(flawed) logic in src/api-extban.c in case conv_param was
NULL, which raised a compiler warning:
api-extban.c: In function ‘extban_conv_param_nuh_or_extban’:
cc1: error: function may return address of local variable [-Werror=return-local-addr]
api-extban.c:382:14: note: declared here
382 | char tmpbuf[USERLEN + NICKLEN + HOSTLEN + 32];
| ^~~~~~
This fixes the fix in 8d228f5dbe.
(--enable-opt in sodium enables additional CPU-specific optimization,
--enable-opt in jansson does not exist and raised a warning)
from the *LINE (or other ban type).
Eg /GLINE %*@192.168.* 0 :Please authenticate using SASL
would now, if the user has authprompt enabled and the connection times
out, exit the client after ~30 secs with "Please authenticate using SASL",
instead of "Registration timeout" (pre 6.0.5-rc2) or
the generic "Account required to login" (6.0.5-rc2).
This to help clients and users who do not type or display anything.
This is an enhancement to https://bugs.unrealircd.org/view.php?id=6202
This also fixes a bug in 6.0.5-rc2 where "Registration timeout" was
always showing up as "Account required to connect", even if there
was no softban or authprompt intervention at all.
More ideally it would show the full *LINE reason but that is something
for a later release. Inspired by https://bugs.unrealircd.org/view.php?id=6202
This also fixes a silly typo that prevents compiling btw :D
Clang 16 makes -Wimplicit-function-declaration error by default.
Unfortunately, this can lead to misconfiguration or miscompilation of software as configure
tests may then return the wrong result.
We also fix -Wstrict-prototypes while here as it's easy to do and it prepares us for C23.
* The `./unrealircd start` command will now refuse to start if UnrealIRCd
is already running.
* The `./unrealircd restart` command will validate the configuration file
(it will call `./unrealircd configtest`). If there is a configuration
error then the restart will not go through and the current UnrealIRCd
process is kept running.
leading to duplicates. The effect was that in the 005 EXTBAN= string some
letters showed up twice like EXTBAN=~,aacfjmnpqrrtCCGGOSST.
Reported by jesse in https://bugs.unrealircd.org/view.php?id=6199
Otherwise things get installed in ~/unrealircd/lib/x86_64-linux-gnu/
which confuses the rest of the system and has no added value whatsoever
in our case.
Get rid of the basic instructions, as people should really follow the installation
guide on the wiki. Too often we see people using these half-instructions (since
they are not fully complete) and get themselves into trouble.
This also fixes a bug with OpenSSL 3.x where, when the ircd was
configured to still allow old TLSv1.0 / TLSv1.1, it would still
only allow TLSv1.2+.
But, as said, allowing TLSv1.0/TLSv1.1 is now no longer the default.
See release notes for more information or the documentation at
https://www.unrealircd.org/docs/TLS_Ciphers_and_protocols
This changes the work of commit 2cf60f66a3.
$ip: IP address of the banned user
$server: name of the IRC server
$blacklist: name of the blacklist block (eg. xyz for blacklist xyz { })
$dnsname: the blacklist::dns::name
$dnsreply: DNS reply code
Previously there was a $name which was ambigious in the sense that
it could mean blacklist name or dns name, now we simply avoid using
$name altogether and use $dnsname and (new) $blacklist.
Added the ability to specify `$name` and `$reply` variables on ban reason,
`$name` would be filled with blacklist dns name data
`$reply` would be filled with blacklist dns reply data.
is 2.13 or newer, as this requires jansson_version_str().
And no, we don't use macro's (eg JANSSON_MAJOR_VERSION). We never do that for
any of the displayed library versions (OpenSSL, libsodium, c-ares, curl, etc)
as macro's only reflect the compile-time library version and not runtime,
and thus are misleading... which can be especially problematic in case of a
security issue. So good that jansson added this function.
This makes websocket_common unload last (and near-last: rpc & websocket)
and makes us call Mod_Init for these three modules first.
This way, the period where the websocket handler is unavailable is kept
to a minimum.
This also renames the ModuleSetOptions option MOD_OPT_UNLOAD_PRIORITY
to MOD_OPT_PRIORITY since it dynamically changes the module priority
in the list. For 6.x compatibility, MOD_OPT_UNLOAD_PRIORITY can still
be used.
when there is already another established link with a server with the same name.
For example, when there is a network issue and the "old server" is still
waiting to be timed out and the "new server" is already linking in.
This is only for calls within the same module, as otherwise you
should use do_cmd().
Benefit of this way is that it is short and you don't have to worry
about passing the right command parameters, which may change over time.
Example as used in src/modules/nick.c:
- cmd_nick_remote(client, recv_mtags, parc, parv);
+ CALL_CMD_FUNC(cmd_nick_remote);
This is an easier way to call the next command override handler from command
override functions. It passes the standard parameters so you don't have to
worry about which parameters a CMD_OVERRIDE_FUNC() contains.
This so it is easier to change command parameters in future UnrealIRCd versions,
should it be needed, then it may be possible without any source code changes
on the module developer side.
- CallCommandOverride(ovr, client, recv_mtags, parc, parv);
+ CALL_NEXT_COMMAND_OVERRIDE();
This fixes a possible crash when using RPC with unix domain sockets,
reported by Valware.
This also adds a configure check so we use our own strlncat if the
C library does not have one, e.g. some non-Linux.
and as it should be IMO. Both for invites by channel ops and for OperOverride.
This also fixes a bug where an IRCOp with OperOverride could not bypass +l
and other restrictions. Only +b and +i could be bypassed.
Module coders: HOOKTYPE_OPER_INVITE_BAN is now gone and HOOKTYPE_INVITE_BYPASS
is now new. The HOOKTYPE_INVITE_BYPASS is called when the user is joining
a channel to which they were invited to. If you return HOOK_DENY there then
the join is still blocked, otherwise it is allowed.
Using this hook would be sortof unusual since usually you would want users
to be able to bypass restrictions when they were invited by another user
or when they invited themselves using OperOverride.
The only example where we use it in UnrealIRCd is for +O channels so an
IRCOp cannot use OperOverride to join +O channels when they would otherwise
not be allowed to do so. Actually even that is a corner case that you could
debate about, but.. whatever.
You could already have something like:
log { source { !debug; all; } destination { file "ircd.%Y-%m-%d.log"; } }
But now you can also have:
log { source { !debug; all; } destination { file "%Y-%m-%d/ircd.log"; } }
This is especially useful if you output to multiple log files and then
want them grouped by date in a directory.
Hopefully this fixes a crash when linking (succesfully authenticated) servers,
something which only happens with GCC and only for some people in some cases.
for a channel they are not in, if they have the channel:see:mode:remote
permission. This permission is included in all operclasses by default,
just like how this is already the case for channel:see:mode:remotebanlist
and other related permissions.
Reported by alice.
Reported by armyn in https://bugs.unrealircd.org/view.php?id=6147
This also adds a new function convert_regular_ban() which is now
used by both clean_ban_mask() and extban_conv_param_nuh().
More precise, for extended server bans, usermask/hostmask was set to
a local variable that was not defined as static char[]. This would lead
to corrupt data and/or crashes.
Bug introduced a few days ago with 3d9b7e4b70
This also moves some of the adding code (sending notice, broadcasting to
other servers, etc) to a function tkl_added().
We should probably do the same for deletion and not use the tkllayer
anymore for that?
Currently available:
* server_ban.list
* server_ban.get with params: name="*@1.2.3.4", type="kline"
This also adds server_ban_parse_mask() which is now used by both GLINE/etc
and the RPC API to parse the same way and convey the same error messages.
Previously we did show a warning but we could crash a millisecond
later so that wasn't particularly helpful.
Now, is_module_loaded() can be used from HOOKTYPE_CONFIGPOSTTEST
to detect if a module is loaded or not, contrary to us having to
do it in MOD_LOAD when it is too late. So now the requirement is
really enforced and also works for hot-loading as well as
unloading of required modules is now prevented.
chunked encoding stuff is copied from the modulemanager and #if'd out.
The non-chunked is not OK yet either, as it must check the Content-Length,
while we currently assume a single packet == the complete request.
This is start_of_normal_client_handshake() by default, but is
start_of_control_client_handshake() for the control channel
(for './unrealircd rehash' and such). Previously that was hardcoded.
It is also used by the RPC code now.
Things like setting the client->status to CLIENT_STATUS_CONTROL
and list_add(&client->lclient_node, &control_list);
This does mean that we now add clients earlier to the unknown list,
even ones that are going to be control sockets and clients that are
going to be z-lined etc, but it should be a minimal performance hit
since it are just 1-4 insertions in a circular list.
At the same time it makes the code more cleaner and more maintainable
especially with all the "special cases" and such that are there now
and will only become more and more...
This makes other code safer as well since they can assume that if the
client is local (client->local) that the listener (client->local->listener)
is non-NULL and safe to access until the client is completely destroyed.
These deal with set::anti-flood::everyone::connect-flood and
set::max-unknown-connections-per-ip respectively.
This adds a new hook HOOKTYPE_ACCEPT, that is mostly meant for internal
usage by UnrealIRCd. Most module coders will want to use the existing
hook HOOKTYPE_HANDSHAKE instead.
This also gets of check_banned() which is now spread over the individual
modules (eg: checking banned is done in tkl on HOOKTYPE_ACCEPT and
HOOKTYPE_IP_CHANGE).
This should be:
security-group Syzop { certfp "1234etc."; }
As this is wrong:
security-group Syzop { mask { certfp "1234etc."; } }
Reported by Han`.
This also makes us throw a config error on the wrong case.
no longer expand shorter versions of a variable. It previously had some
unintended form of magic autocomplete where $serv was handled the same
way as if it was $server. This could cause issues in the long run when
variables are added and the meaning of the short form changes.
Reported by westor in https://bugs.unrealircd.org/view.php?id=6123
but it seems there were still a couple left. These are now gone as well.
There seem to be no issues with the ones that were left, but it is just
too easy to get it wrong. Declaring buf in function now. This should be
faster anyway, since it is located on nearby memory (stack).
Inspired by previous find from westor (c708a99955c034e842f913479cc597d87b311394).
Use the new options in the new ::except block, fix broken English
and trim down the text a bit.
This also lowers the threshold from 7 to 6. It was already 5 in
the example block on the wiki, now the wiki and this are the same
again.
if the oper block permits, the user does not have to send "OPER xyz".
Eg:
security-group Syzop { certfp "xyz"; }
oper Syzop {
auto-login yes;
mask { security-group Syzop; }
operclass netadmin-with-override;
class opers;
}
Then, if you connect with SSL with that certificate fingerprint,
you become IRCOp automatically.
and other selectors in 'mask'. This allows for things like:
security-group Syzop { certfp "xyz"; }
oper Syzop {
mask { security-group Syzop; }
operclass netadmin-with-override;
class opers;
}
except ban {
mask { security-group Syzop; }
type all;
}
allow {
mask { security-group Syzop; }
class special;
maxperip 32;
}
etc...
We do error on the obvious case of mask * and mask *@* when no password
is set, but otherwise try not to stop all cases of user stupidity
(there are just too many...).
Reported by ZarTek-Creole in https://bugs.unrealircd.org/view.php?id=6114
We now call HOOKTYPE_LOCAL_CHANMODE on the modes we set in modes-on-join,
where 'client' is '&me'. Should be fine, as we already did the same for
+P modes (indirectly) in channeldb.
across servers if they differed, however the individual IP of users
was not updated until next add_scores() run. So, there would be an
up to 5 minute delay during which scores for individual users were
possibly too low, with all the effects that it could possibly have
nowadays such as restrict-commands, more stringent flood limits, etc.
If your servers are all linked all the time then you would not have
noticed this issue. It mostly matters if you are linking in a new
server or if the server has been delinked or out of order for days
or weeks.
So you can just use mask { ip { 127.*; 192.168.*; } } without
having to worry about hostnames like 127.example.net.
(Of course you could also have used CIDR notation)
Another benefit is that, since we are dealing with IP's only,
the matching is faster than going through the more universal
match_user() routine.
So now the example in the release notes actually works:
except ban {
mask { security-group irccloud; }
type { blacklist; connect-flood; handshake-data-flood; }
}
The list of channels (which is an array) is limited to a total
of 384 characters after JSON expansion. If it is limited then
the last item will be "...".
Suggested by westor in https://bugs.unrealircd.org/view.php?id=6083
The "vhost" field is added if the visible host of the user differs
from the real hostname, such as +x with cloaking or +xt with a vhost.
The "cloakedhost" is always included, even if the user does not
currently have a cloaked host at all (eg is -x or using a vhost).
Both make it easier to search log files based on user reports.
Eg a user mentions a vhost or cloaked host from their user logs
and then a server admin searches the UnrealIRCd logs on this to
retrieve the real host / ip / user based on that.
Suggested by westor in https://bugs.unrealircd.org/view.php?id=6083
(It is not under "user" because the info can be useful before someone
is considered a user, eg when flooding/rejected/etc)
clients etc. are expanded in the logging routines.
HOOKTYPE_JSON_EXPAND_CLIENT - for all clients
HOOKTYPE_JSON_EXPAND_CLIENT_USER - for clients that are users
HOOKTYPE_JSON_EXPAND_CLIENT_SERVER - for clients that are servers
HOOKTYPE_JSON_EXPAND_CHANNEL - for channels
on each string. Note that the entire JSON dump may still be much larger,
this is just about each individual string item within an object.
This commit also adds a more flexible StripControlCodesEx() function
to the core (which is used by the logging system), the existing
StripControlCodes() function is unchanged and can still be used.
+/** Strip color, bold, underline, and reverse codes from a string.
+ * @param text The input text
+ * @param output The buffer for the output text
+ * @param outputlen The length of the output buffer
+ * @param strip_all_low_ascii If set to 1 then all ASCII < 32 is stripped
+ * (the ASCII control codes), otherwise we only
+ * strip the IRC control- and color codes.
+ * @returns The new string, which will be 'output', or in unusual cases (outputlen==0) will be NULL.
+ */
+const char *StripControlCodesEx(const char *text, char *output, size_t outputlen, int strip_all_low_ascii)
{
When someone is trying to connect and he/she is shunned , it will be displayed on connection server notice, yeah sometimes it might be helpful, why not..
Suggested by armyn https://bugs.unrealircd.org/view.php?id=6106
this is a https://www.unrealircd.org/docs/Mask_item so very flexible.
Note that most people would want to use except ban { } instead to
simply exempt from ALL blacklists. (that one does not yet have the
flexible mask capability though.. but it wil have it soon..)
Pretty much everywhere we had:
0001 userhost_changed(client);
0002 if (MyUser(client))
0003 sendnumeric(client, RPL_HOSTHIDDEN, client->user->virthost);
Lines 2-3 are now integrated in userhost_changed().
Also fix two issues with CHGHOST in make_oper():
* if user was -x, modes had +x and a vhost, it would send the cloaked
host in the original vhost, while it should have been the real host
* if user was -x and went +x without vhost (so only uncloaked to cloaked)
then no CHGHOST message was sent at all
Automatically convert the old options ::sasl-bypass, ::webirc-bypass
and ::minimum-reputation-score, so nobody needs to update their config.
The example.conf has been updated.
(Also call it allow::match in the future, but accept allow::mask still)
This is the first of several commits to convert all ::mask items.
See https://www.unrealircd.org/docs/Mask_item for the consequences.
In short, you can now use all of the security-group items directly
in a mask, eg:
allow {
mask { account TrustedUser; }
class clients;
maxperip 10;
}
The extban module API is used behind the scenes. To the server admin
the functionality appears in a more natural way:
account { <list>; };
country { <list>; };
realname { <list>; };
certfp { <list>; };
In the same way, they appear as exclude-xxx options too:
exclude-account { <list>; };
exclude-country { <list>; };
exclude-realname { <list>; };
exclude-certfp { <list>; };
Modules can add additional fields (3rd party modules too!).
Module coders:
See src/modules/extbans/realname.c for a simple example. In short:
1) You need to register your extban in both MOD_TEST and MOD_INIT
2) Other than that, the existing rules for extended server bans apply:
a) Your req.is_banned_events needs to include BANCHK_TKL
b) Your req.options needs to include EXTBOPT_TKL
Be advised that for modules that are called in extended server bans
the client may be missing several fields, for example client->user could
be NULL, so be careful with accessing everything in your module.
security-group { mask ~security-group:xyz; }
Module coders (again, slightly unrelated):
Added unreal_add_names() function which can be used to transform
a list of names in the config to a linked list (NameList).
security group that references another (or itself), eg:
security-group abc {
include-mask ~security-group:abc;
}
We now give up after a recursion depth of >8 and log a warning.
been connected to IRC. See https://www.unrealircd.org/docs/Security-group_block
Slightly unrelated, for modules coders: new function get_connected_time(),
to see how long a client has been online. This works for local clients, in
which case it would just return TStime()-client->local->creationtime.
It also works for remote clients, for which it will use the newly added
"creationtime" moddata (commit f1a18ce37e),
so the info is only available for remote clients on newer servers.
If the info cannot be found it will return 0 (zero).
The set::whois-details name for this is: security-groups.
https://www.unrealircd.org/docs/Set_block#set::whois-details
By default it is shown ONLY to IRCOps, not even to 'self' for normal users.
If you want to hide it for everyone, even to IRCOps, eg because you
feel it is useless information, then you can use:
set {
whois-details {
security-groups { everyone none; self none; oper none; }
}
}
or later. This updates the include/license.h file, which is used for the
/LICENSE command, to say "GPLv2 or later".
The 'LICENSE' file shipped with UnrealIRCd since at least the year 2000
has always been the GPLv2.
In the copyright headers of individual .c and .h files we have a mix of
"GPLv1 or later" and "GPLv2 or later", so "GPLv2 or later" is the common
denominator.
This existed in UnrealIRCd 3.2.x but was later removed when
switching to the new operclass system.
Requested by Valware in https://bugs.unrealircd.org/view.php?id=6041
Syntax: SVSO <uid|nick> <oper account> <operclass> <class> <modes> <snomask> <vhost>
All these parameters need to be set, you cannot leave any of them out,
HOWEVER some can be set to "-" to skip setting them, this is true for:
<class>, <modes>, <snomask>, <vhost>
In UnrealIRCd the <operclass> will be prefixed by "services:" if not already
present. It is up to you to include or omit it.
If you want to set any swhoises you need to use the SWHOIS s2s command,
other than that this command basically does everything for you,
in fact it uses the same code as the OPER command does.
Most of the "user is now ircop" code has been moved out of cmd_oper() to
a new function make_oper() that is called by both cmd_oper() and cmd_svso().
This function also changes the hook HOOKTYPE_LOCAL_OPER:
It no longer passes a ConfigItem_oper struct, since we can't do that for
remote opers. Instead it passes oper name and oper class.
The complete definition is now:
int hooktype_local_oper(Client *client, int add, const char *oper_block, const char *operclass);
thus the 'unset time' would be stripped.
This was because the timedban module was seen as 'unavailable' when
checking the +f syntax so early in the booting process.
We now assume timedban is available during config testing, if it later
turns out it is not available the 'unset time' is still stripped
when setting the mode on JOIN.
Reported by ctcp.
This makes us no longer call the .is_ok() function for extbans
that are added through except ban { }. This because normally
the is_ok() function communicates to 'client', which is NULL
when it is called from the config code.
The alternative would have been to update all the extban modules
to check for a NULL client and deal with that but that would
need stupid amounts of code and it would not be of much value
as the error would not end up displaying on the console.
So, we now only on the .conv_param() function, which was already
only used for cases such as remote bans and such, and is already
known to have a NULL 'client' in TKL cases. Note that conv_param()
could still reject the ban, but it does it generally only in
the more extreme cases.
Reported by musk / PeGaSuS.
1) Give an exact link to https://www.unrealircd.org/docs/UnrealIRCd_releases
which describes the supported versions and EOL stuff in more detail.
2) Make clear that we have better instructions on the wiki with regards to installation
and that users should use that one instead (the ones in the README are really meant as fall-back)
3) Some nicer formatting here and there (minor)
This module will work the same way as `userip-tag` or `userhost-tag` modules work now, the 90% of this code is part from these modules.
It will help especially the irc bots (AdiIRC/mIRC) to detect the geoip country code directly and easy when someone is talking on a channel and take actions, i hope this will help on most people.
Thanks @Valware for testing it out.
Short Example: `@unrealircd.org/geoip=GR;account=tester;msgid=tPTHDgymv9pgdGdYkI3WBd;time=2022-03-30T16:34:26.780Z :tester!Username@3765DB68:3AE9CB6C:B0540131:IP PRIVMSG #Test :test message`
This was caused by the transition from letter extbans (eg ~a) to
named extbans (eg ~account) and a combination of the bug fix in 6.0.2
(60a70acd86) and the 'channeldb' module
not checking for duplicates while reading the database.
Reported by PeGaSuS in https://bugs.unrealircd.org/view.php?id=6091
It often takes a while for the actual crash to occur but eventually an
attempt would be made to access inaccessible memory of the previously
freed .so module.
Reported by and traced with the help of both Wick and Krstarica.
On Linux we still show the usage info as for "unrealircd" (not unrealircdctl)
since on Linux we have the "unrealircd" script that manages all this and
"unrealircdctl" is not really meant to be called directly by end-users.
What is a SVSMOTD? The SVSMOTD are MOTD lines that are shown at the end of
an existing MOTD. These lines are added remotely through services.
Previously the SVSMOTD lines were never shown in the MOTD-on-connect, which
was a bug. We were only supposed to hide it if a short motd is in use.
Reported by Valware in https://bugs.unrealircd.org/view.php?id=6070
The spec <https://datatracker.ietf.org/doc/html/draft-hardy-irc-isupport-00#section-4.8>
is a little unclear on the semantics, and Unreal interprets 'C<val' as
a request for all chans created before <val> minutes ago, ditto.
This is a legitimate interpretation, but I think the other on makes more
sense (ie. that 'C<val' means all chans created less than <val> minutes
ago).
Additionally, the documentation for T did not match the implementation
before this commit.
Before this commit, Unreal was consistent with Hybrid/Plexus4 on ELIST C.
After this commit, Unreal will be consistent with Charybdis/Solanum,
InspIRCd, and ircu2 (and Hybrid/Plexus4 on ELIST T).
Reported by Jaka in https://bugs.unrealircd.org/view.php?id=6077 and
Valware and buayadarat in https://bugs.unrealircd.org/view.php?id=6078
This commit also makes the halfop rules for +h/-h match the ones in U5:
Previously in 6.0.0 - 6.0.2 it was:
* halfops can set +h on others
* halfops cannot set -h on others
* halfops can set -h on themselves
Now in 6.0.3+ it matches 5.x behavior again:
* halfops cannot set -h or +h on others
* halfops can set -h on themselves
missing other functionality.
Reported by DarthGandalf in https://bugs.unrealircd.org/view.php?id=5918
The cause was that all fd's were closed, including 0/1/2. We now reopen
those and map them to /dev/null, like we do later again.
the server name. Nowadays we receive and log lines from remote servers
so without this extra information it can be unclear where events
(eg: problems) are happening which can be rather confusing.
rehash errors such as error: set::geoip-classic::ipv6-database:
cannot open file "/home/xxxx/unrealircd/data/https://www.unrealircd...
and possibly even a crash.
The initial boot of UnrealIRCd, however, was always fine, this only
happened when rehashing.
It also seemed to occur more with ftp:// includes or at least with
multiple parallel includes, that may or may not have different or
more latency. In any case it seemed to affect some remote includes
setups semi-consistently, and others not at all.
The root cause was a complex code path causing a read-after-free.
We now use a simplified code path which can no longer cause this.
The only downside is that rehashing may be delayed up to an extra
250ms (quarter of a second), but that should hardly be noticeable,
if at all.
Issue reported by Bun-Bun.
as it complicates things too much. The c-ares build options that we use in
UnrealIRCd cause curl not to recongize c-ares, and the other way around is not
good either. Also, self-compiled ("unrealircd shipped") c-ares may not be
used/required by main unrealircd (thus rm'd) while it is still needed by
self-compiled curled. Blehh, what a mess.
Now we simply don't compile curl with c-ares and rely on cURL to enable async
DNS support via system c-ares or via the another way, with the use of threads,
which is standard in curl now for many years and should work on most, if not
all platforms.
If this is somehow problematic for you then install libcurl/libcurl-dev(el)
on your system itself, via your package manager or other means.
in 6.0.2+ we can inform the user whether the rehash actually succeeded
or not. This was already shown in the output, but we now also change
the last few lines of output to make very clear if the rehash failed
that the currently running UnrealIRCd is not patched.
like /home/xyz/unrealircd/unrealircd hot-patch instead. In other words,
if the current working directory is not the location of the unrealircd
script. Then calling ./unrealircd rehash, so the last step in the patching
process, would fail. Reported by k4be.
[skip ci]
parts of the code later on, in particular the upgrade code.
Eg: a base path of "/home/xyz/unrealircd/"
Side note: this also assumes no path is / (root), which seems a
reasonable assumption.
./configure script from us. That is, using the correct private lib dir
and using --disable-tests and so on.
Should fix a bug on CentOS where c-ares could not be built due to
the test suite requirements from c-ares, reported by Bun-Bun.
including version, description, author, flags. The output is
pretty much identical to "MODULE -all" on IRC as IRCOp.
Useful for the future if you want to verify a module has been
upgraded from the command line.
or another type of proxy request.
This fixes a problem where ban user { } or except ban { } is not working
for ~country:XX when the request comes via a WEBIRC or other proxy.
Reported by CaoS in https://bugs.unrealircd.org/view.php?id=6058
It should also fix security-group being incorrect for ~security-group bans
or exempts.
the rest of the hooks, most of which do not use the past tense.
Only affects HOOKTYPE_USERHOST_CHANGE / HOOKTYPE_REALNAME_CHANGE.
This does, however, make it inconsistent with the userhost_changed()
call, though :D.
synced by the server the user is on, and this way the country will be
consistently the same on all servers (and not BE on one, and NL on another,
which would be confusing for the ban matching code, giving different
results on each server).
When you set this to 'yes' you get more options...
See next (modified) copy-paste from April 2020, which had to be reverted
because PCRE2 was broken. Now it's an opt-in and hopefully matured a bit.
This means:
* Case insensitive matches work better in UTF8 now, such as extended Latin.
For example, a spamfilter on "ę" now also matches "Ę", while previously
it did not catch this.
* Other PCRE2 features such as https://www.pcre.org/current/doc/html/pcre2syntax.html#SEC5
are now available. For example you can now set a spamfilter with the regex
\p{Arabic} to block all Arabic script, or
\p{Cyrillic} to block all Cyrillic script (such as Russian)
Use these new tools with care, of course. Blocking an entire language,
or script, is quite a drastic measure.
All of this was possible because of the new PCRE2_MATCH_INVALID_UTF
compile time option which was introduced in PCRE2 10.34. Now, that
version turned out to be buggy. As recent as PCRE 10.36 some major bugs
were fixed. This also means we now require at least PCRE2 10.36 version
so everyone can benefit from this new spamfilter UTF8 feature, IF they
enable set::spamfilter::utf8-support, that is.
Many systems come with older PCRE2 versions so this means we will
fall back to the shipped PCRE2 version in UnrealIRCd. This means
./Config will take a little longer to compile things.
For packagers (rpm/deb/ports): if you choose to patch configure to
not require such a recent PCRE2, then please do not allow enabling
of set::spamfilter::utf8-support since it will likely cause crashes
and misbehavior. Check PCRE2 changelog, CTRL+F at PCRE2_MATCH_INVALID_UTF
is done behind-the-scenes (the command is still ./unrealircd mkpasswd).
For Windows users it finally means they can generate passwords via the CLI
using: unrealircdctl mkpasswd pwdhere
dbuf->length to be unitialized.
This wasn't an actual problem until yesterday in UnrealIRCd code,
since the whole client struct was initialized to zero, including
client->local->sendQ(->length) etc.
However, now we use the dbuf code elsewhere too (on the stack) and
3rd party modules can use it too, so fix this bug.
"./unrealircd reloadtls" and there is now also a "./unrealircd status"
The output is colorized if the terminal supports it (just like on the
boot screen) and also the exit status is 0 for success and non-0 for
failure. The purpose of all this is that you can easily detect rehash
errors on the command line.
These three commands communicate to UnrealIRCd via the new control
UNIX socket, which is in ~/data/unrealircd.ctl.
This also does a lot of other stuff because we now have an internal
tool called bin/unrealircdctl which is called by ./unrealircd for
some of the commands to communicate to the unrealircd.ctl socket.
Later on more of the existing functionality may be moved to that
tool and we may also provide it on Windows in CLI mode so people
have more of the same functionality as on *NIX.
It was missing for a lot of extbans (removing too little) and
for ~t it was removing too much (eg quiet bans).
Bug reported and changes suggested by k4be.
Coders:
Setting extban.options to EXTBOPT_CHSVSMODE has no effect anymore,
just didn't want to remove it so modules would still compile.
We now purely match based on .is_banned_events including BANCHK_JOIN.
Various things still need to be done: a lot more testing, ability to
set permissions on the file, #ifdef's because of lack of support
on Windows (currently won't compile), etc.
One thing that I don't intend to change is that I chose not to display
the socket in the host but have clients show up as 'localhost' (and
ip '127.0.0.1'). Doing it this way keeps things easy, otherwise we risk
a lot of breakage for nearly nothing gained, really.
Things can be tested via:
listen {
file "/tmp/listen";
}
and then with netcat:
nc -U /tmp/listen
USER x x x x
NICK hai
etc...
For example if the 1st DNS resolver is refusing or ignoring requests.
We forgot to call unrealdns_timeout() in the waiting loop, so DNS requests
never timed out and c-ares didn't try the 2nd/3rd server either.
Issue reported by Elodie.
and give a hint to do that so they are not misinterpreted by an URL
since that may happen for other spamfilters (not the one included
in this file though). Suggested by Lord255.
First, what we call local-curl is a situation where the system does not have
the cURL library installed and UnrealIRCd offers to compile and use it.
The problem is that CURLDIR in config.settings may refer to an old directory
such as /home/xyz/unrealircd-5.2.1/extras/curl and UnrealIRCd 6 would try to
use it. That would be problematic as it would result in: 1) no cURL updates
anymore since it is only half-detected as local-curl, and 2) once you remove
the unrealircd-5.2.1 directory (since you are on U6) it breaks as well.
So, we now check for this situation and in case of something that looks like
a local-curl situation, change the path to <currentunreal>/extras/curl and
download and compile cURL fresh, as expected.
All this is only for the like 1% users that uses local-curl, which then
used ./unrealircd upgrade or ./Config -quick.
Reported by CrazyCat on the forums.
Exit status is now documented at https://www.unrealircd.org/docs/Upgrading
and can be used to see the difference between:
* upgrade+configtest OK,
* upgrade OK but configtest failed
* some other failure
* no newer version available
Handy for scripting...
later on, because unload_extcmode_commit() would call extcmode_para_delslot()
even though member modes don't use a parameter slot, and hence it
would NULLify a wrong slot, usually for the +H parameter mode. Fun.
We now no longer crash and mass-unset the modes on everyone in the
channel when such a mode is unloaded, just like we do when unloading
any of the other channel modes. It is not done in an efficient way
(one mode per line) but this should be an extremely rare event anyway.
Crash reported by CrazyCat.
locations, and inform the user that they can specify a file.
This doesn't solve https://bugs.unrealircd.org/view.php?id=6021 completely
but at least makes the user aware of this.
Reported by arcanefeenix and crazycat.
the [expires: ZZZZZZZZZZZZZZZZZZZZ GMT] string.
This because most people are interested in the length of the ban (so
relative time) and the exact time a TKL expires is less interesting
(the absolute time) and due to GMT/UTC requires calculating to the
local timezone too.
This also makes the tkl expiry messages be more like the add message,
with []'s, while previous it used more free text at the end of the line.
Not that anything is this particular code path should trigger it (OK,
maybe if some 3rd party module kills the user from HOOKTYPE_SECURE_CONNECT)
better safe than sorry.
That is, until the first REHASH happened, after that all is good.
This was caused by update_throttling_timer_settings() being
called before init_throttling().
UnrealIRCd 6 server would expand it into two different mode lines
with IDENTICAL msgid values. Obviously message ids must be different
for different events.
Introduced by b078a9c8b5.
using mixed UnrealIRCd 5 and UnrealIRCd 6 networks.
This is a slightly complex rewrite of make_mode_str() and do_mode(),
as we nog go from single mode lines to potentially multiple mode lines.
In short: whenever we would be near buffer cut-off point (the famous
512 byte limit) then previously we would prevent the mode, though not
succesfully in all cases where a network consists of mixed 5.x and 6.x.
From this point onward we no longer do that. Instead we convert one
MODE command to two MODE lines if that is needed.
The benefit of this is that we no longer prevent it BEFORE processing
the MODE, which is a flawed method and could be wrong (causing desyncs).
And also, we no longer partially ignore MODE lines from clients when
they would cause the limit to be exceeded, as we replace them with
two MODE lines instead.
These are more changes than I wanted at such a late point but.. they seem
to be necessary to prevent U5-U6 compatibility issues.
In the config file if you have a value that is 100% an URL (eg no
spaces and all that) then it is seen as a remote include and will
be fetched. Eg: file "https://something/"
We already had that.
Now we add a new option to make it NOT interpret this as an URL.
Probably only used in rare cases, but, it is needed for modules
like extjwt where you configure an URL.
The solution is simple: use single quotes instead of double:
Eg: url 'https://something/'
Note that single quotes are only supported in this version onwards,
they were not supported in earlier UnrealIRCd versions.
It is also only supported in values at the moment (not names),
since that is the only place where URLs are actually fetched for.
1) Don't forward link.SERVER_LINKED since we already generate
link.SERVER_LINKED_REMOTE ourselves.
2) Fix using wrong server name(s) in link.SERVER_LINKED_REMOTE
reported by flo in https://bugs.unrealircd.org/view.php?id=5988
3) Don't show link.SERVER_LINKED_REMOTE messages when we
are syncing to a network, otherwise you would get eg 50 of
such messages for 50 servers when you link in 1 server.
This is due to \r being replaced with a space in config_parse_with_offset().
Didn't even know that.. yeah.. ugly ugly... but first time i see it
causing a problem in 20 years.
An URL that did not need to be fetched (due to url-refresh time) could
cause a download complete message ending up in a call to rehash_internal().
This was too soon, as we were still adding and processing other config
files.
from unrealircd.org if it is less than 14 days old.
If the file was up to date then it already never fully downloaded it,
thanks to hashing and receiving the "304 Not Modified" HTTP header.
But with this url-refresh it won't even do the HTTP(S) request at all.
Ah okay, the `continue` in the switch was used as a `break 2`.
Changed to a `return` now as no memory is allocated anyway and
nothing further needs to be done. Also makes it immediately clear
(if you read the code) that processing ends there.
one (extjwt_hash_val) to just a simply safe_free() as well which is less
error prone (just needs the value to be initialized to NULL at the beginning
but that is already done).
PROTOCTL SERVERS=xxx which all servers send, so if these are all
UnrealIRCd servers then we should not reach this, BUT.. you never know
and non-unreal servers don't send this, so it matters for eg services.
This so you can just load the whole file but still use blacklist-module to not use some of it. Not sure if that is always a great idea, but it is now an option.
Polsaker in https://github.com/unrealircd/unrealircd/pull/158
Have not tested this thoroughly on a larg(er) network, but if
there is any time to apply this patch, then it is now during
6.0.0 beta.
You can still use blacklist-module if you don't want to load it.
In future versions the exact config stuff will likely be different, but
this is just to get more test expore / make things Just work for now (tm)
to expose to which users and in what detail.
The default configuration is as follows:
set {
whois-details {
basic { everyone full; }
modes { everyone none; self full; oper full; }
realhost { everyone none; self full; oper full; }
registered-nick { everyone full; }
channels { everyone limited; self full; oper full; }
server { everyone full; }
away { everyone full; }
oper { everyone limited; self full; oper full; }
secure { everyone limited; self full; oper full; }
bot { everyone full; }
services { everyone full; }
reputation { everyone none; self none; oper full; }
geo { everyone none; self none; oper full; }
certfp { everyone full; }
shunned { everyone none; self none; oper full; }
account { everyone full; }
swhois { everyone full; }
idle { everyone limited; self full; oper full; }
}
}
Oh, yeah, and for "secure" this also adds displaying of the TLS cipher
in /WHOIS for ircops and self by default. For all others it is limited
to just "is using a Secure Connection".
This also removes the newly added set::geoip::whois-for-anyone since
it is now configured via set::whois-details::geo.
Module coders: HOOKTYPE_WHOIS changed and you may no longer send
directly to the client from this hook. Instead, you should use
add to the NameValuePrioList, usually via the functions
add_nvplist_numeric() and add_nvplist_numeric_fmt().
For inspiration see bot_whois in src/modules/usermodes/bot.c
and reputation_whois in src/modules/reputation.c
Just like already done for Usermode_Table[] and Channelmode_Table[].
This also adds support for ->unloading=1 and re-use etc etc,
something that seemed to be missing before (but also wasn't
an issue apparently...).
admin needs to make a choice.
Also update example conf to load the new cloaking module (cloak_sha256)
and update the text there to require at a key of 80 characters.
This is based on the old MD5 module, it uses SHA256 instead.
Some re-indenting, replacing hardcoded values with a define,
and some other small changes due to the different hash size.
It's usage would be rare, but this is f.e. used from channeldb.
Other uses may be in some 3rd party module.
Example: set_channel_mode(channel, "+k", "key")
* Now ban_check_types (previously checktype):
this is one or more of BANCHK_* OR'd together, eg BANCHK_JOIN, BANCHK_MSG..
* Now ban_type (previously what2):
this is the type of the ban, eg EXBTYPE_BAN, EXBTYPE_EXCEPT, etc.
* Now is_ok_check (previously is_ok_checktype)
this is one of EXBCHK_* for is_ok, eg EXBCHK_PARAM to check parameter.
not a format string (eg ":%s LUSERS %s"). It now simply concats all parv[]'s.
That is, up to parc count. And it automatically does the :stuff for the
last parameter if it contains spaces or starts with a : etc.
This gets rid of a bit sketchy code with an arbitrary maximum etc.
Now it's just:
if (hunt_server(client, NULL, "REHASH", 1, parc, parv) != HUNTED_ISME)
return;
This has one side effect, though:
Previously we used the format string, so it may be possible for S2S
traffic to now have more arguments then before here and there.
Eg:
* It could be that the caller was using a format string to
intentionally cut off an extra parameter at the end.
You can still do that if you call with eg parc-1 instead of parc.
I don't think there were any such cases though, but hard to rule out.
* Extranous parameters may show up in S2S traffic where it was
previously unexpected.
and used for auditting purposes across servers (assuming the servers
itself can be trusted).
This is done via the 'operlogin' module which is loaded by default.
Obviously for opers of U5 and below this information is not available.
This also changes the HOOKTYPE_LOCAL_OPER hook to include oper block info:
-int hooktype_local_oper(Client *client, int add);
+int hooktype_local_oper(Client *client, int add, ConfigItem_oper *oper_block);
Move checking of +t restrictions to chanmodes/topiclimit.
Move checking for +m restrictions to chanmodes/moderated.
Now the only check remaining in topic is for +b (banned users)
which is fine I think.
would normally use sendnumeric() instead.
The buildnumeric() function prepares a buffer but does not send it.
It is used in eg CAN_KICK / CAN_SET_TOPIC, where you need to set an
'errbuf' with a full IRC protocol line to reject the request (which
then may or may not be sent depending on operoverride privileges).
In configure remove AC_FUNC_MALLOC and AC_FUNC_REALLOC.
These don't do anything, except they cause a build failure on
Ubuntu 21 and later (together with openssl 3.0.0 anyway).
This also changes the remove_user_from_channel() function to have an
extra parameter to hide it from logs. This is used for KICK (already
logged) and QUIT (which would be stupid to generate 10 part log lines for).
No longer log to all ircops if no matching snomasks.
So yeah, if you don't load snomask.default.conf you will see nothing
(TODO: some warning / error for this)
We use char *member_modes like we now have at all the other places,
which contains eg "o".
TODO: fix prefix sending rules or remove some if 0'd out code
And not sure if we want to do it entirely this way :D
joins in such a case, code was wrong (things being done in the wrong
scope).
This also fixes a bug where an OperOverride message was generated
for SAJOIN nick @#test
1) All IRC clients support prefixes nowadays
2) People generally misunderstand the question and think this
disabled +q (channel owner) and +a (channel admin), when
in fact it does not. It only enables/disables the showing
of prefixes, and it changes some of the rules eg requiring
+qo / +ao for actions that normally only require +q / +a.
3) We now have the modularized +q and +a, so you can actually
disable channel owner and channel admin, which is what most
users want(ed) that previously disabled PREFIX_AQ.
For all users (95%+) that enable PREFIX_AQ there is no effective
change. For the other 5% it is likely only for the better.
sendnumeric_legacy() calls.
This also fixes some small format string bugs (eg: argument too much and
some time_t fun, like the previous commits elsewhere... nothing fancy).
an extra char **errmsg argument. Upon failure (non zero return value)
this should contain a format string to be sent to the client
(with the return value denoting the number of the numeric).
This gets rid of sendnumeric_legacy() in join.c
This already found a few issues.
As a side-effect, this also means you can only use RPL_xxx and
ERR_xxx in the 2nd argument from now on. You can no longer use
a dynamic integer (eg 'reply') at runtime, since then the format
string cannot be checked.
More to follow, after making sure it works on Windows too.
I don't think there were more than a handful of people who disabled
this, and it clutters the source badly (not to mention that this
should not be a compile time option at all).
trying to disable warnings in pragma's that are unknown to the
compiler.
We prefer -Wno-unknown-warning-option, which does exactly what
we want. If not available then fallback to -Wno-unknown-pragmas.
That way on recent clang/gcc's we keep the useful pragma warnings,
while still being able to compile on older compiler versions.
the existence of -Wno-unknown-warning-option so we can add these since
we use pragma's occasionally to suppress compiler warnings and some
of these may exist in gcc but not in clang or vice versions (and..
versions of course), which would otherwise yield an error.
side. This was due to channel->creationtime being set to TStime() but
then not adjusted/set later, (also) resulting in some adding/removing
action of modes as well.
It *seems* the other few cases were OK though: equal TS, lower TS,
higher TS, just not the "channel only exists on one side"-case.
Guess we need more test coverage!
This also removes the "TS for #channel changed" message that was sent
to channel members. I doubt regular users understand these messages.
I did add a message (unreal_log) to IRCOps, which may or may not be
useful or too noisy... unsure about this one :)
It means you can no longer modify eg parv[1] in-place with strtoken and such.
The main reason for this is that as a command handler you have no idea
where the arguments may come from. It could be from a do_cmd() with
read-only storage (eg a string literal) and so on.
It started with an experiment of how far I could get and how annoying the
side-effects would be, but they seem to be quite managable, so I'm
committing this stuff.
Hopefully this catches/solves some stupid bugs somewhere :)
- For HOOKTYPE_LOCAL_JOIN and HOOKTYPE_REMOTE_JOIN: drop parv[] argument
as it was useless anyway, it only contained the channel name in parv[1]
but never the key, sometimes was entirely NULL even.
- For HOOKTYPE_PRE_LOCAL_JOIN instead of char *parv[] we now pass
const char *key. As predicted more than a year ago when fixing
0902ed7a99
argument which specifies how many characters to copy max.
strlncpy(dest, src, sizeof(dest), maxcopybytes);
vs
strlcpy(dest, src, MIN(sizeof(dest),maxcopybytes+1));
We already had a strlncat() vs strlcat()
server where the client is (or was) on. Just like we did in UnrealIRCd 5.
Not sure if API-wise and variable-name-wise I want to do it this way,
but whatever...
Also, check for GNU make (which can be either 'make' or 'gmake')
early in ./Config and print out an error to install prerequisites
from https://www.unrealircd.org/docs/Installing_from_source
This also replaces 'make' with ${MAKE} (and such) everywhere.
can't have dependencies, so if you change a .h file, it fails to
recompile the other dependencies. Grmpf!
This does mean that we require GNU Make (gmake) from now on.
only partially a server yet: IsServer() is true but client->server is NULL.
Fixes a crash when called from PROTOCTL.
Actually not entirely sure if this happens in practice, but better safe
than sorry.
already were in extban_conv_param_nuh_or_extban().
The recursion check was already there, but not the "rule 2 violation"
if ((extban->options & EXTBOPT_ACTMODIFIER) || (extban->options & EXTBOPT_NOSTACKCHILD))
This also backs out the temporary fix 5df1b1b889.
I wanted to use pattern rules in Makefiles, which worked great, but..
i also want to be able to use parallel builds, and JOM does not seem
to support it. So....
Listing all the objects again, all the module rules are autogenerated
(yeah need to store those scripts somewhere..), though the list itself
needs updating in a later commit.
Using /FS /MP1 when creating the object files for UnrealIRCd.exe,
as due to the parallel JOM build it accesses the intermediate vs140.pdb.
Then, for all the modules, we can do without /FS because we now
explicitly set /Fdsrc/modules/xxxxx.pdb and thus don't have this
file access contention to vs140.pdb.
[skip ci]
do_mode_char_list_mode() and do_mode_char_member_mode(), which are
two quite different things.
And rewrite do_mode_char_member_mode() to get rid of switch/case
style and the goto.
Also add do_mode_char_write() which is used at 5 places (could be
expanded, probably).
* channel->mode.extmode to channel->mode.mode
* channel->mode.extmodeparams to channel->mode.mode_params
This because all channel modes that are set there are extended channel
modes, only lists are still in core atm and they never get set here.
Eg no longer need to walk through the corechannelmodetable for
single param channel modes...
Also fix sjoin comments about "their" and "our" modes. In the merge
case this was not correct, it was "our old" and "merged modes".
(the new fallback https-only implementation).
./configure will set URL= to either url_curl.o or url_unreal.o
depending on whether curl is enabled or not.
The 3 functions that both implementations had in common are now in
src/misc.c: url_is_valid(), displayurl() and url_getfilename().
This is work in progress. It current lacks a number of features
that we would like to have, but most of them are relatively easy
now that most of the work has been done:
1) Support for caching based on timestamps, like curl ("not modified")
2) IPv6 support
3) HTTP redirects (with limit)
4) Timeouts for connect and reads (15 / 45 for curl atm)
5) HTTP downgrades
6) Chunked transfer encoding
7) Verify openssl hostname check
8) SNI
9) Ideally some progressbar for large transfers such as the geoip db
(for cURL too by the way)
And.. finally we should use this stuff from the modulemanager so we
don't have duplicate code.
longer raise an error and we will simply load the include only once.
I left some tracing code in case we have a bug in the code that
handles this, but testing shows it works well both for files and
URLs.
as it REQUESTS to rehash the server, but it may not be done immediately.
And making it void makes sure nobody relies on some sort of return
value which will differ between with vs without remote includes.
Also get rid of sig and loop.rehash_save_sig, as a NULL client
already indicates the same (or at least does so now).
not used by 3rd party authors):
* conf_start() -> config_read_start()
* conf_check_complete() -> is_config_read_finished()
* load_conf() -> config_read_file()
* config_test() -> config_test_blocks()
* config_run() -> config_run_blocks()
* init_conf() -> config_test()
* run_configuration() -> config_run()
This so things look like:
if (config_read_start() < 0)
exit(-1);
while (!is_config_read_finished())
; // do something
if (config_test(1) == 0)
config_run();
always compiled in, both regardless of cURL support or not.
Obviously the cURL functions are not available without cURL and there
are now some #ifdef USE_LIBCURL in url.c
This also fixes the current build to work without cURL
unnecessary. Get rid of load_includes() which did the marking
and unload_notloaded_includes() and unload_loaded_includes()
accordingly. There's now one single free_all_includes().
asynchronous on start, which is achieved by this 1st commit.
For this to work, the init_conf() stuff has been split to an
earlier call to conf_start() and then a loop where you can
check for conf_check_complete().
This means init_conf() no longer calls load_conf, as that
is moved to conf_start() and conf_check_complete().
Thus, init_conf() is now only called when all includes are in the
linked list 'conf_include'.
This is work in progress and breaks:
1) rehashes
2) compiling without curl
3) possibly cached remote includes
This requires both servers to be using UnrealIRCd 6 and there
should be no UnrealIRCd 5 server in-between (eg an old hub).
This also changes tls_cipher() to expect a Client * argument.
And tls_get_cipher() can now safely be called on any client,
including remote clients, and it will return the cipherstring
if it is known via moddata.
We used to always send the long version:
SJOIN ts #channel +sntkl key 999 :xxx
From now on we only send that for the first SJOIN for a channel
when syncing. For any subsequent SJOINs (so for larger channels or
with lots of bans/exempts/invexes) we will use the short version:
SJOIN ts #channel :xxx
We now do it that way because the remote side already received
all the modes the first time, so they are redundant in the
subsequent SJOINs for the same channel.
Especially if you have a channel with a large mode string, such as
+lLfH 99 #redirectchan [30j#i10,40m#m10,7c#C15,10n#N15,30k#K10]:15 100:1d
it was previously 1) wasting bandwidth and 2) unnecessary CPU
trying to merge channel modes that were already the same.
which BANCHK_* events you want to listen, eg BANCHK_JOIN, BANCHK_MSG.
You can use BANCHK_ALL to watch on all events.
Only BANCHK_TKL is not included there and needs an explicit
BANCHK_ALL|BANCHK_TKL.
The caller will now take care of BANCHK_* filtering so we won't
waste any CPU on calling an is_banned() function that isn't
interested at all in the event that we have.
Also, no longer require an extban->is_banned function, since some
extbans don't use it. This too saves useless calls.
Currently only supported option is:
BCTX_CONV_OPTION_WRITE_LETTER_BANS: always write letter bans
This removes the NULL pointer magic that i was not happy about.
If you don't indicate NEXTBANS support then we will send old fashioned
extended bans to you.
Note that eventually we will likely require named extended bans support,
but that will be UnrealIRCd 7 / 8.... ;)
server to server traffic to be letter extbans.
Yeah this is a tad ugly, but the alternative was worse, see
header of the file for the full story.
Module is loaded by default (obviously).
Still to do: only do this for non-U6 servers (add some PROTOCTL)
And probably alter clean_ban_mask because I don't like the
magic on NULL client at the moment.
In U5 channel->creationtime could be 0 momentarily, eg for a new
channel, but nowadays we set channel->creationtime to TStime()
if the channel gets created in make_channel() [*]
[*] which was previously called get_channel() by the way
Also update some comments in mode.c to make things more clear.
The only stuff we still have is if a bounce servermode is detected
(incoming) then we just ignore it.
All this bounce stuff wasn't used much, and didn't even work
(was always sending empty bounce string). It was only complicating
the code everywhere with stupid stuff like:
*x++ = bounce ? '+' : '-';
what = MODE_DEL;
caused a bounce, or was supposed to (never really worked either).
We now ignore the mode (which was de-facto what we did anyway)
and also log it in that way.
configuration file via set::named-extended-bans <yes|no>; and now
defaults to yes.
Still to do:
* explicitly set names instead of using stupid module names
* update test suite to check for these new names (other git tree)
* backwards compatible sending to U5 and lower using ugly shit
The .conv_param() now receives the ban minus the ~own-extban.
And it should also return the part minus the ~own-extban.
Changes to findmod_by_bantype():
1) Takes a string now, rather than a single char value,
so it is ready for named extbans.
2) Second parameter added so you can easily jump to the remainder.
Eg:
extban = findmod_by_bantype(b->banstr, &nextbanstr);
[..check if extban is non-NULL and then..]
b->banstr = nextbanstr;
When extban->is_ok() is called the banstr now no longer points
to "~x:something" but to "something".
Just like we did for extban->is_banned().
Again, need this for later too...
have that in dns.c. Also remove verify_hostname() from dns.c and
integrate it in valid_host() which now takes a second argument
named 'strict'. Call valid_host() with strict set to 1 if the
hostname should be checked to be a valid DNS hostname, eg the
host may not contain stuff like ':' or '/'. Use 0 otherwise
for the loose check, eg if you are not sure if the passed host
is an IP address or a host, or if it is for a vhost.
The last 3 were always NULL after the remote/local split from a few commits ago.
And nick and username were useless as well as client->name and
client->user->username were always already set.
Without this, I think otherwise we need too many checks everywhere
for the IsMe() case. And this behavior matches me.direction which
also points to &me.
Then again, will doing it this way cause issues? We will see...
And also make this print the number of users and not (both) users+servers
which is generally a metric nobody is interested in and only causes
confusion when you get a message about a record of 30 and there are only
28 clients connected.
eg LINK_REJECTED_SID_COLLISION -> LINK_DENIED_SID_COLLISION
since 15+ other ones also start with LINK_DENIED...
Expand it to other areas as well eg antirandom.
* New macro IsInvalidChannelTS() which evaluates to ts < 750000
* Check for faulty creation time ("fishy timestamp") at ALL places
where channel->creationtime is set.
* Also, important, changed behavior:
if !IsInvalidChannelTS then:
1) We print our warning
2) We pretend ts is our channel creationtime (which may be
TStime() if the channel did not previously exist)
3) We allow the command through and allow it to merge (in case of SJOIN)
This makes it so we still log the error (noisy) but on the other hand
we won't get "infected" by fishy timestamps since we will never set
them, no matter what happens.
This because "can send" is ambigious and could be interpreted to
mean that the client may send this mtag to us, while in fact this
function decided whether to send TO the client.
relationship, make the issuer "client" (this was already so) and
the target is "target" (and no longer sometimes "victim").
For consistency, of course :D
IP address in the message. We now use ip:port from the link block
if we failed to connect, and otherwise we use the ip from the
connection if the connection is established (also because it
can be a remote connection, not linked directly to us)
these "network settings" and other settings has been lost in time.
Rename some of these variables and macro's.
ircnetwork -> NETWORK_NAME
ircnet005 -> NETWORK_NAME_005
defserv ->? DEFAULT_SERVER
hidden_host -> CLOAK_PREFIX
helpchan -> HELP_CHANNEL
Also one config change (visible to admins):
set::hiddenhost-prefix is now set::cloak-prefix
We still accept the old name, though.
The example conf has been updated as well, but not the wiki yet.
just like client->user is set if the client is a user.
Rename client->srvptr to client->uplink: this is the uplink that the client
is connected to. If the client is a user then it is set to the server that
the client is connected to, if the client is a server then it is set to the
server that the server is connected to (the.. tadah.. uplink).
For local clients it is always set to &me.
for fake lag calculations only (well, except for 1 corner case).
As said, modules should use the new function:
void add_fake_lag(Client *client, long msec)
We now also correctly disable color support if someone is on
a color-capable terminal but redirects the output of the boot
to a file, eg: bin/unrealircd >boot.log 2>&1
Just as a reminder: don't blindly assume that if anything is set here
that the user is logged in, there is IsLoggedIn(client) for that.
Reason: if the account name starts with a digit or is "*" then the
user isn't actually logged in ;)
to match the order on IRC. IOTW: subsystem.EVENT_ID and loglevel are
now swapped. New log format on disk is:
[timestamp] subsystem.EVENT_ID loglevel: message
This because in UnrealIRCd we may encounter non-UTF8 sequences,
which this function will censor out.
Also, this takes care of returning json_null() if the string was
NULL, which is usually what we want as well.
name, handy when the old server is a zombie waiting for ping timeout.
NOTE: atm this only works if someone links directly to us and there is
an existing server local or remote.
There is no code yet for a remote & remote scenario, which requires (or
at least prefers) having a creationtime for server connects, requiring
a SID command change.
we will now only send the JSON in the first message.
Also fix log file timestamp missing with multiline.
And rename do_unreal_log_ircops() to do_unreal_log_opers()
Add safe_free_message_tags()
Any \n's will be expanded to multiple lines.
* For JSON disk logging there is no change.
* For text disk logging it will show as:
[time] facility subsys.CODE+
[time] facility subsys.CODE+
[time] facility subsys.CODE
So a plus sign is added if another message is to follow.
* For notices to opers/snomasks exactly the same (plus sign if needed).
Untested. More changes to follow eg to notice dropping the json
in the followup msgs.
This also changes the logging format for text disk to match
the output on server notices, we no longer log as:
[TS] facility subsystem event_code: msg....
But as:
[TS] facility subsystem.event_code: msg....
Saves a bit of room, especially when the JSON travels over network this
maybe save some "crucial" bytes (and in that case it looks better too,
since the \s's in message tags only make it less readable).
This basically enhances the regular snomask/ircop notices with
JSON logs, the same logs that are logged to disk (with type 'json').
This allows bots/machines to much more easily parse server notices
such as connect notices or.. anything.
Note that JSON logs are quite large, so make sure the ircop has
a BIG class::sendq!
Also, everyone can set the cap but it is only effective for IRCOps.
This makes it use OUR timestamp, so timestamps in logs are properly
sequential. The originial timestamp is saved in "original_timestamp".
Finally, we (over)write "log_source" with the remote server name.
snomasks, opers, global (remote), ..
For disk logs we currently ignore the sources and log everything.
NOTE: REHASH is untested and will memory leak for sure.
This means we now have $client.user.username but the expansion system
does not allow items more than 2 deep atm (only $client.something
but not $client.something.other). Will fix later. (TODO)
In the meantime the connection notice will look weird :D
Also rename them to describe better what they do.
ConfigFile:
cf_filename -> filename
cf_next -> next
cf_entries -> items
ConfigEntry:
ce_fileptr -> file
ce_varlinenum -> line_number
ce_fileposstart -> file_position_start
ce_fileposend -> file_position_end
ce_sectlinenum -> section_linenumber
ce_varname -> name
ce_vardata -> value
ce_cond -> conditional_config
ce_entries -> items
ce_next -> next
ce_prevlevel -> parent
Also add doxygen docs for both structs.
Note that without such a block nothing will be sent to ircops at all
(anything that comes from unreal_log anyway).
In a later commit either a snomasks.default.conf will be added and/or
an internal default mapping.
This also moves the recursion trap to earlier in the logging code,
which has the side effect that debug traffic regarding snomasks is
no longer logged.
when any of these are wrong. Obviously this should probably be changed to
only do it in DEBUGMODE in a final stable release :D
We also crash if 'msg' contains a percent sign ('%'). This is to avoid
mistakes where someone uses eg '%s' in there, which is not supported.
Unfortunately it also prevents stuff like '100%' so this should probably
be removed too at some point.
The former is an integer and may not always be available (eg: very early
before the user is connected). The latter is an array.
TODO: opt-in/out of all these expansions as they come at a performance penalty
a wrapper that will return a 'null' JSON object for null strings and
otherwise a string object for non-NULL. It seems by default this is
not the case which is a bit annoying. Maybe we should re-wrap all
code to use this. We'll see.
The problem is when this is not done, then a $variable won't be
expanded and would show up like literally "$variable" as if the
variable was never passed on.
being NULL. This is a vararg argument and it causes a leak when
running in debug mode because we add some magic source file,
source line number and function.
Note to self: don't put NULL there :D
change some more calls to make_channel() to use find_channel().
Also make it take 1 argument instead of 3.
Needed to be careful in sjoin code since the previous code set
channel->creationtime to 0 if client was a remote. Now merged
a few if's into one. Should be correct :D.
logging. We already did so for the "timestamp" of the log message,
but now also do it in other log messages that have a timestamp,
such as "set_at" and "expire_at" in TKL entries.
CONFIG_WARNING_GENERIC and CONFIG_INFO_GENERIC from
config_error(), config_warn() and config_status() respectively.
...not that i like these generic ones, but it is a start.
This will likely reduce performance, but this should not matter in modern times.
Also added flags to let modules know which one the entry belongs to, and what
to do with it.
Now modules should be able to add their own WATCH methods (like IRCv3 MONITOR),
or extend functionality to notify about other changes than the default log on,
log off and away statuses (like SETNAMEs).
Normally, channel operators are only notified when another chanop
invites someone to their channel - as this would allow the user to
join the channel later if it becomes invite-only. This is still
the default behaviour. But now, it can be configured to notify
operators about any invitation done to their channel, eitner by
another op or by normal user. This will allow them to see whether
someone floods others with invitations to their channels.
Enable the option with set::normal-user-invite-notification yes;
* Converted 90% of the socket and linking errors to use unreal_log()
* Add log_data_socket_error(fd) and $socket_error
* This also makes connect_server() 'void' and removes all of the error
reporting from the callers (there was 3x code duplication due to that)
* Don't use report_error and report_baderror anymore in socket.c
* More to follow...
This adds __attribute__((format(printf,X,Y))) to several functions.
It also adds checking only for the non-literal case to some functions
such as unreal_log/unreal_do_log.
This so we can more easily detect format string issues. Especially now with
the recoding of the logger and with possible future mistakes in this area
in UnrealIRCd 6 itself or in third party modules.
The check is currently disabled in these files, which are TODO items:
* src/send.c: still much work to do
* src/socket.c: due to report_error and report_baderror().
I want to get rid of these functions and integrate them
in the new logger anyway.
* src/serv.c: only disable for hunt_server()
Broken now:
- All filtering (log::flags)
- Everything is seen as error unknown UNKNOWN
Working:
- log::type json
- logging still works, other than the limitations of above
This broke SASL services autodetection and also sasl=x,y,z in CAP.
Reported by Valware in https://bugs.unrealircd.org/view.php?id=5960
Of course the easiest solution would be just to set .remote_write=1
for this, which is what I've just done for the 5.2.1.1 release.
But there seems to be a pattern here. When a server wants to write
its own object (irc1.example.net writing to the MD object of
irc1.example.net) we have the problem that that object is both
"our client" and from the other server POV it is "themselves".
On one hand you may want to allow that (eg for 'saslmechlist'), on
the other hand a server writing its own 'certfp' sounds like a bad
idea in principle.
So we now add a new option for the 'self' case and make some MD
objects use it. In fact, in the core we now have zero MD objects
using remote_write. We keep the option available though, for example
for k4be's geoip modules and possibly future features.
Module API change:
* .self_write added which allows a server to write to its own object
(irc1.example.net writing to the MD object of irc1.example.net)
* .remote_write still exists too if you want to allow remote servers
to write to your own objects
* Note that in all cases, servers can always write to their own
(child) client objects.
Changes:
* The link-security MD changed from .remote_write=1 to .self_write=1
* The salmechslist MD now has .self_write=1, this fixes the actual bug
instead of standard wildcard.
In this case, since it's antirandom, it is not really important
as someone is not going to add DNS records specially to avoid
triggering antirandom. That makes no sense since it is much
easier to avoid using a random looking name.
Main reason of changing it here is to set a good example.
arbitrary hosts that have a host starting with "127.". A rather stupid
oversight on my part, really.
In the meantime, if this happens, then you can still resort to using
ZLINE/GZLINE as a workaround to ban such a user. (The exemption won't
match against the host because DNS lookups are not done for zlines)
Reported by armyn in https://bugs.unrealircd.org/view.php?id=5957
This was more of a oversight because the cmdbytes calculation happens
in a different function after message tags have already been processed.
Also, wasn't really important up to now since we only allow quite short
tags at the moment.
Instead of just counting these in cmdbytes, as would be the most logical
and easiest fix, we use a different strategy:
We use a separate counter for message-tags so clients benefit from the
"rounding down rule". In other words: the first xyz bytes give you
no extra penalty compared to before (eg they are "free"). Useful for
clients who use eg @label heavily.
By default this is 90 bytes for unknown-users and 180 bytes for
known-users. See lag-penalty-bytes in set::anti-flood.
(often completely unrelated to channel history) and you then rehashed again
UnrealIRCd would crash. Reported by gh0st.
May be the same issue as reported by adamus1red in
https://bugs.unrealircd.org/view.php?id=5943
This has to do with SavePersistentPointer/LoadPersistentPointer calls
which normally work fine but this particular module uses it in MOD_TEST
causing a certain sequence of events causing a double free or read-
after-free if you do it slightly differently.
later fd_close() call. This also removes fd_map() since fd_open w/FDCLOSE_NONE
now does that.
* If you use fd_socket() or fd_accept(), then no change.
When fd_close() is called we call close() on *NIX and closesocket() on Win.
* If you use fd_fileopen(), then no change.
When fd_close() is called we will call close() on both *NIX and Win.
* If you used fd_open() and then fd_unmap() because you didn't want us
to close the socket, then use fd_open() with FDCLOSE_NONE and
just call fd_close() instead of fd_unmap().
We will not actually close the fd in fd_close() (FDCLOSE_NONE).
* If you called fd_open() with other intentions then either specify a
FDCLOSE_SOCKET / FDCLOSE_FILE as the last argument, or more likely:
don't use fd_open() at all and use fd_socket() or fd_fileopen() instead.
For reasons on this change, see previous patch. This way is more sane and
makes it harder to make mistakes even beyond Windows-specific issues.
This fixes a file descriptor leak in Windows that happened in the
logging code. The most visible effect of this was if you had a
log::maxsize set then on Windows you would see:
"Max file size reached, starting new log file"
Every other line, forever (and not actually starting a new log).
fd_close() previously did not close the file descriptor of a file
on Windows because on Windows it needs to call close() for a file
and closesocket() for a socket, and it always did the latter.
On *NIX it's more easy and you can just always close() any fd.
if on OpenSSL 1.1.1 or later.
We trust OpenSSL 1.1.1 and later to be good enough to handle all
the reference counting and freeing nowadays, which is something that
was not done correctly in (much) older OpenSSL versions, leading
to crashes on one hand and on memory leaks on the other hand.
In OpenSSL 1.1.0 and earlier we do not rehash tls on simple "REHASH",
since that code has not been vetted. However, nobody should be
running those old OpenSSL versions anyway, since they are out of
official OpenSSL support.
Based on previous reports and patches from k4be in
https://github.com/unrealircd/unrealircd/pull/129
Looks much cleaner now.
This also filters out the edge case where user_account_login()
could have been called when a user transitioned from "not logged in"
to "unconfirmed account". It did not cause any issues AFAICT but
it is not really expected either.
that only set +r on people. To my knowledge, practically no services are
out there anymore that do not use proper SVIDs (and that can link with
UnrealIRCd 5).
services account.
This adds set::authentication-prompt::unconfirmed-message with
a default of:
unconfirmed-message "You are trying to use an unconfirmed services account.";
unconfirmed-message "This services account can only be used after it has been activated/confirmed.";
See https://www.unrealircd.org/docs/Set_block#set::authentication-prompt
Note that this is only shown for services which allow SASL from
unconfirmed services account in the first place, like atheme.
Anope does not allow it, which is something that could very well
be considered 'correct' as well. In that case you would simply
get the "Authentication failed" message instead
(set::authentication-prompt::fail-message).
I would like a bit more room for this in the future,
but until then we will keep sending UIDs of length 9 in
server to server traffic, so no change at all.
https://bugs.unrealircd.org/view.php?id=5925
This does two things in cmd_uid() now:
* It checks if parameter 6 in UID is a valid UID, using valid_uid()
* It checks if the first 3 characters of the UID match the SID
Modules can still opt-in via mreq.remote_write=1 to allow it for
certain moddata.
For example, k4be may want to do this for his geoip-base module which
allows a single server to set moddata "geoip" for all connecting clients,
including remote clients.
If you are a moddata provider then you can enable it like this:
ModDataInfo mreq;
[..]
#if UNREAL_VERSION_TIME >= 202125
mreq.remote_write = 1;
#endif
[..]
See discussion on https://github.com/unrealircd/unrealircd/pull/142
This also allows known-users to execute slightly more commands per second.
For people who want their trusted users/bots to allow even more commands
per second (eg 20cmds/sec) we now have a nice FAQ item that uses this:
https://www.unrealircd.org/docs/FAQ#high-command-rate
* New block [set::server-linking](https://www.unrealircd.org/docs/Set_block#set::server-linking)
* For link blocks with autoconnect we now default to the strategy
'sequential', meaning we will try the 1st link block first,
then the 2nd, then the 3rd, then the 1st again, etc.
* We now have different and lower timeouts for the connect and
the handshake. So we give up a bit more early on servers that
are currently down or extremely lagged.
set {
server-linking {
autoconnect-strategy parallel;
connect-timeout 10s;
handshake-timeout 20s;
}
}
Right now the only autoconnect-strategy is 'parallel', which is simply
the existing behavior since 4.x. A future commit will add other
strategies and may or may not change the default as well.
The bit that is working already is that you can now specify different
timeouts for the connect()/TLS_connect() call and for the rest of
the handshake (when the "SERVER" message is seen), this so the connect
timeout can be relatively short.
All this will be documented later in the wiki and release notes.
They were already ignored in MODE by remote UnrealIRCd servers,
but this makes it so local modes (+Z and +d at the moment)
are not sent across the wire.
This also changes the channel_modes() function to have an additional
'hide_local_modes' argument. Set this to 1 if you are building a
buffer that will be sent to remote servers, otherwise use 0,
which is far more common.
Also, this will skip saving of local channel modes to channeldb
since all of these are temporary, or at the moment anyway.
Thanks to alice for reporting this bug and providing a good test
case to help fix this issue and the previous ones.
~a:0: match all unauthenticated users
~a:*: match all authenticated users
~a:SomeUser: match only SomeUser, also allow wildcards here, even
though that is usually a very bad idea :D
- If you have only negating entries, like '!abc' and '!def', then
we assume an implicit * rule first, since that is clearly what
the user wants.
- If you have a mix, like '*.com', '!irc1*', '!irc2*', then the
implicit * is dropped and we assume you only want to match *.com,
with the exception of irc1*.com and irc2*.com.
- If you only have normal entries without ! then things are
as they always are.
This patch also makes the behavior for unreal_mask_match() and
unreal_mask_match_string() the same.
If you had a spamfilter on type 'c' but not on 'p' then it would not
trigger. Reported by armyn in https://bugs.unrealircd.org/view.php?id=5913
This probably went unnoticed because most people add spamfilters
on 'pc' (or even 'pcnN').
Reported by Ariadne Conill in https://bugs.unrealircd.org/view.php?id=5906
This patch applies cleanly against 5.2.0-rc1 and 5.0.9.x.
Needs more testing, though, as fiddling with SQUIT code and the
various directions and far/near server distinctions can be tricky.
of an error. Also the warning will differ depending on whether you use
the defaults that were in example.conf for a long time, or some custom
settings.
It's not perfect but should help people with migrating from 5.0.x to 5.2.x.
Replace it with a reference to the documentation instead of trying
to include some or all of the defaults since 1) the block is huge
nowadays with all the settings, and 2) this way we can tweak the
defaults over time in newer versions rather than having people
change their configuration file.
Suggested by westor in https://bugs.unrealircd.org/view.php?id=5838
This also fixes a bug where output from modules for 'STATS S' was
shown twice (eg: modef-default-unsettime shown twice).
for "unknown-users" and "known-users".
As a reminder, by default, "known-users" are users who are identified
to services OR are on an IP that has been connected for over 2 hours
in the past X days.
See https://www.unrealircd.org/docs/FAQ#new-anti-flood-block
for more information on the layout of the new block.
NOTE: This actual feature, the relase notes and the documentation
are all work in progress.
I think people will understand both and it is currently rather long.
And a bit confusing too with all the spaces, easy to overlook something eg
in /STATS S where it is being used.
See https://ircv3.net/specs/client-tags/reply for the draft.
Can be used by clients to indicate to which message they are writing
a reply. This can be especially useful for bots, to indicate that
a response belongs to a user request, eg a !trigger.
The new target type is called 'T' and we match against "name=value"
of each message tag (or just "name" if it is without value).
Example: SPAMFILTER ADD -simple T kill 0 this_is_a_test +typing=active
(No this is not a suggestion :D)
This probably won't be used much at all, but it is good to have the
option available in case there is some massive problem,
especially since more message tags may pop up sooner or later.
Caveat: this is actually a bit slow as we may have to check multiple
message tags for a single line.
If there are zero message-tag spamfilters then we will automatically
short-circuit and save all this CPU, which will be the most common case.
in case you want to disable this feature.
Note that clients that are using CHATHISTORY will already no longer
receive history-on-join ("push") since they REQ a CAP that will inhibit
this and they will "pull" the history instead when they want/need to.
So... this option is really only there if you want to disable it for
non-CHATHISTORY-clients.
loaded. The code to raise this warning was already present but it
was not being shown in many cases (when it actually should).
It now looks like this, if you run ./unrealircd start and previously
crashed AND have any 3rd party mods loaded:
The IRCd has been started now (and is running), but it did crash 1 seconds ago.
Crash report generated in: /home/ircd/unrealircd/tmp/crash.report.core.1621838267.txt
** IMPORTANT **
Your UnrealIRCd crashed and you have 3rd party modules loaded (modules created
by someone other than the UnrealIRCd team). If you installed new 3rd party
module(s) in the past few weeks we suggest to unload these modules and see if
the crash issue dissapears. If so, that module is probably to blame.
If you keep crashing without any 3rd party modules loaded then please do report
it to the UnrealIRCd team.
The reason we ask you to do this is because MORE THAN 95% OF ALL CRASH ISSUES
ARE CAUSED BY 3RD PARTY MODULES and not by an UnrealIRCd bug.
Shall I send a crash report to the UnrealIRCd developers?
NOTE: If the crash is caused by a 3rd party module then UnrealIRCd devs can't fix that.
is now 5000 lines / 31 days. For unregistered it is 200 lines / 31 days.
Previous setting was 200 lines / 7 days for both.
Admins can tweak these settings, see:
https://www.unrealircd.org/docs/Set_block#set::history
More code to deal with corner issues will follow later.
UnrealIRCd module coders [!]:
This also changes the channel mode API conv_param. You can use
the UNREAL_VERSION_TIME >= 202120 condition to detect this.
Eg:
#if UNREAL_VERSION_TIME < 202120
int my_conv_param(char *para, Client *client);
#else
int my_conv_param(char *para, Client *client, Channel *channel);
#endif
possible if it rounds off nicely, eg +H 100:7d. Note that the
existing syntax is still accepted, eg +H 20:1440 and +H 20:1440m
are both converted to 20:1d.
With potentially higher time values this change makes the mode
parameter a lot more readable.
Support for translating timevalues is already in UnrealIRCd 5.0.2
and higher, so should be fine for nearly everyone.
from https://ircv3.net/specs/extensions/chathistory
Current status of the module in UnrealIRCd:
* A significant part of this is done and working
* Currently in modules.optional.conf to get test exposure,
not yet loaded by default.
* CHATHISTORY subcommands implemented: BEFORE, AFTER, LATEST, AROUND
* It does not implement the subcommand "BETWEEN" yet
* It does not announce or recognize the (draft) CAP's yet
* It does not announce the ISUPPORT token CHATHISTORY=xx yet
* Testcases need to be written to validate everything
* There will be bugs, now, and also while implementing the rest
in the days to come.
the file is allowed to no longer exist. This so you can do things
like only connecting an USB stick during UnrealIRCd boot and then
pull it out once booted.
* Fix channel history issues with writing on terminate
* Change tkldb and reputation to only write the db
on terminate and not on every REHASH anymore
..all this thanks to the new loop.ircd_terminating, so modules can
see the difference between regular rehash and terminating.
so modules can indicate if they wish to be unloaded before or after others.
This is used by the channel and history modules so they can save their
databases before the chanmodes modules are unloaded.
Also, made ModuleSetOptions() a void function. I don't think anyone
used the returned value and it now no longer is strictly bitmask add/del
so returning an unsigned int would be a tad confusing.
we may have more database writing to do on terminate.
Actually 10 seconds would be really long, but 2-3 seconds may be
quite realistic if you have lots of TKLs, permanent channels,
reputation entries (users), etc.
Oh yeah, and I really hate writing PORTABLE shell code...
configuration on how history is stored (in memory and/or on disk).
This is similar to other disclosing policies like
unrealircd.org/link-security and unrealircd.org/plaintext-policy.
The reason for this cap (and similarly the other caps) is that
the user can make an informed decision on whether it finds the
policy/safety/privacy of an acceptable level or not.
Fixes for turning persist on/off on the fly (REHASH)
Make release notes a bit more clear.
on what hardware people end up running UnrealIRCd.
Also (unrelated) add a check for >64kb strings in unrealdb_write_str()
and return an API error. That too is unlikely to ever happen, but..
better be correct.
src/unrealdb.c(462): error C2220: warning treated as error - no 'object' file generated
src\unrealdb.c(379) : warning C6029: Possible buffer overrun in call to 'fread': use of unchecked value 'c'.
[..fread of c->config->saltlen..]
if (c->config->saltlen > 1024)
{
unrealdb_set_error(c, UNREALDB_ERROR_HEADER, "Header is corrupt (saltlen=%d)", (int)c->config->saltlen);
goto unrealdb_open_fail; /* Something must be wrong, this makes no sense. */
}
c->config->salt = safe_alloc(c->config->saltlen);
if (fread(c->config->salt, 1, c->config->saltlen, c->fd) != c->config->saltlen)
VS2019 doesn't understand that this is safe.
And set the error message/code properly. Didn't set it before because of
'c' being freed, but we have unrealdb_get_error_code() and
unrealdb_get_error_string() now that can (and should) still be used
in such cases.
not always kicking in on *line either.
We now check for shuns/*lines in user_account_login(), so upon
SASL or NS IDENTIFY etc. This also means that the client could
now be killed in that function, so callers should take extra
care and take that into account. We check for IsDead() in our
calls now (if it's our client anyway).
Hopefully this doesn't break anything.........
I forgot to include message tags earlier, so this is a breaking change:
-int hooktype_local_nickchange(Client *client, char *newnick);
-int hooktype_remote_nickchange(Client *client, char *newnick);
+int hooktype_local_nickchange(Client *client, MessageTag *mtags, char *newnick);
+int hooktype_remote_nickchange(Client *client, MessageTag *mtags, char *newnick);
Be sure to update your hooks!
You can use something like: #if UNREAL_VERSION_TIME>=202115
This library provides easy to use functions for encryption/decryption
among other things. There is some overlap with things that
OpenSSL also provides but not all.
The new display field is called 'R', use something like:
WHO * %cuhsnfmdaRr
At the moment only "displaying" is available and not "searching"
on reputation. If you need that, you're stuck with the /REPUTATION
command at the moment. Too much hassle to implement that.
About reputation: https://www.unrealircd.org/docs/Reputation_score
Note: the only change between 5.0.9 and 5.0.9.1 is:
* Build improvements on *NIX (faster compiling and lower memory requirements)
* Windows version is unchanged and still 5.0.9
Type: Parallel build: Non-parallel build:
Before change 92 seconds 304 seconds
After change 7 seconds 21 seconds
All this thanks to a simple --disable-tests being passed to c-ares' configure.
(that is, MemAvailable, not MemFree). The ./Config script with
all shipped libs compiled actually has a memory peak of 450M
in my tests with -j4, but let's err on the safe side...
Reason for all this:
This helps on shells with limited memory, especially if they
don't have swap.
We actually don't take swapping into account, so even if you
have plenty of swap but "low" on memory then we won't force a
parallel build. That's okay, since in such a case a parallel
build is not so useful anyway with (slow!) swapping.
This code only works on Linux. Let's hope *BSD guys are smart
enough to have a decent system setup.
need this and it slows things down for servers.
For clients it's not much of an issue, since traffic rates are low.
However, for server-to-server links it is an entirely different matter.
It is (only) noticeable if you have lots of traffic, such as when there
is a lot to sync while linking two servers, and especially when the two
servers are geographically further apart.
Tested with 100,000 G-lines on both sides being synced (20MB traffic):
* 20ms RTT (same country/state): speed up of x3
* 200ms RTT (transpacific): speed up of x6
We moved from LibreSSL 3.1.4 to 3.2.4.
Support for TLSv1.3 was added in LibreSSL 3.2.2 from Oct 2020,
but it had some issues, hopefully by now they are resolved.
[skip ci]
Suggested by Amiga600 in https://bugs.unrealircd.org/view.php?id=5784
This also fixes a bug with log::maxsize on Windows (cannot overwrite
existing file with .old).
It simplifies the logging code a little and makes it a tad more readable.
And it adds an unreal_strftime() function to make things easy.
the spamfilter. Only after a rehash it showed the me::name as the
setter. From now on we just display -config- in the setter field,
like we do for all the other TKLs as well (ELINE, ban xyz, etc).
if running multiple ircds from the same directory you sometimes get
weird messages otherwise (not that we really support such a thing
but i use it while dev'ing).
Not reported by anyone, but yeah.. who knows there is someone out there
that does this :D.
Also make it work the same like channeldb by spreading the event.
If a module returns 0 ("UnrealIRCd please do not process this packet")
then don't call the next module in line (also because that one might
then change the return value to something different, which is bad).
That is, when in "auto" mode, which is like for 99% of the users.
NOTE: the sytem may still limit the actual number of FD's to
a lower value, depending on the value of "ulimit -n -H".
notices to IRCOps and in ircd.log.
See the release notes for more details.
Module coders:
You can use HOOKTYPE_CONNECT_EXTINFO to add your own additional
information as well. See get_connect_extinfo() for inspiration.
Use nvplist_add() or nvplist_add_fmt() to easily add your info
to the list.
Module coders II:
Small note: this moves the sending of the far connect notice
to /under/ HOOKTYPE_REMOTE_CONNECT instead of /above/.
When booting no log files are open yet as we have not parsed any log { }
entries yet. On *NIX we log to stderr during that stage.
On Windows it varies: when running in GUI mode we save the log to a
buffer and display it after booting in a dialog.
When running as a service on Windows we previously wrote SOME entries
to service.log, but other entries were not logged or shown anywhere.
This makes both GUI and Service-mode on windows log all ircd_log()
calls with LOG_ERROR, instead of only config_status(), config_warn()
and config_error() messages.
This also removes config_progress() which isn't used by anything.
Oh, and it also fixes a memory leak in the Windows boot code, a leak
that nobody would have noticed anyway, but still.
The handshake delay exists so results from DNSBL's can be checked before
the user is fully online. Whenever someone is exempt from DNSBL checking
it serves no purpose, so we mark it that the user has no handshake delay.
This will speed up connecting by up to 2 seconds (by default).
Also updated WebIRC example to suggest this now:
https://www.unrealircd.org/docs/WebIRC_block#UnrealIRCd-side
The exempted ban types are only ones that will affect other connections as well,
such as gline, and/but not policy decissions such as bypassing qlines or maxperip.
Currently the list is: gline, kline, gzline, zline, shun, blacklist,
connect-flood, unknown-data-flood.
Suggested by PeGaSuS and others in https://bugs.unrealircd.org/view.php?id=5806
And if it is actually used/installed then make it a little bit
harder to bypass the case where the digitale signature does not match.
And yes, the bypass option does exist because in the future we
may have a different signing key. Who knows from what old version
people may upgrade years from now, after all.
Previously it rejected ! for all type of *LINES to avoid users
making the mistake of banning nick!user@host in a *LINE.
Note that for non-extended-server-bans the ! is still forbidden.
* There are two security groups by default: known-users and unknown-users.
See https://www.unrealircd.org/docs/Security-group_block
* New extended ban ~G:securitygroupname, with the typical usage being
MODE #chan +b ~G:unknown-users, which will ban all users from the
channel that are not identified to services and have a reputation
score below 25.
It is highly recommended that services pseudo users all have +o since
there are likely many places where ULines don't bypass a restriction while
opers do. But still, this particular issue has been fixed, it caused
unexplained loss of messages which looked rather mysterious.
Reported by severinmueller in https://bugs.unrealircd.org/view.php?id=5799
The reputation command (IRCOp-only) has been extended to make it
easier to look for potential troublemakers:
* ```REPUTATION Nick``` shows reputation about the nick name
* ```REPUTATION IP``` shows reputation about the IP address
* ```REPUTATION #channel``` lists users in channel with their reputation score
* ```REPUTATION <NN``` lists users with reputation scores below value NN
to the specified number of lines. This defaults to 1000.
This will prevent IRCOps from being flooded off ("Max SendQ exceeded")
if they list all *LINES and there are thousands.
In the newly introduced error message, after too many matches,
we also kindly point out to use filters like '/STATS gline +m *.nl'
When packaging UnrealIRCd as RPM, 'make install' needs to install
the files into $RPM_BUILD_ROOT rather into '/'. Just changing the
paths via ./Config or ./configure does not fit, because otherwise
UnrealIRCd is finally looking for $RPM_BUILD_ROOT/etc/unrealircd/
rather /etc/unrealircd/. It's fully backwards-compatible, because
normally $DESTDIR is not being passed.
Thank you BuildBot.
This means on older OpenSSL's we are not going to have certificate
expiry checks. Those OpenSSL versions were deprecated by the OpenSSL
team itself, so yeah then you will miss out a few things.
by armyn in https://bugs.unrealircd.org/view.php?id=5769.
The default behavior in 5.x is to continue matching:
allow { ip *@*; class clients; maxperip 2; }
allow { ip *@*; password "iwantmore"; class clients; maxperip 10; }
This so users who provide a password get additional rights,
such as a higher maxperip or a different class, etc.
If the user connects without a password then we simply continue
to the next block and use the general block with only 2 maxperip.
However, some people want to use passwords to keep other users out.
That is entirely understandable as it is an 'allow block' after all.
For example:
allow { ip *@*; class clients; maxperip 2; }
allow { ip *@*.nl; password "tehdutch"; class clients; maxperip 2; options { reject-on-auth-failure; } }
In this case anyone without the correct password will be rejected access.
if someone searches explicitly on a nick name and that user exists.
This fixes a bug where doing '/who name a' would return only 1 result
if 'name' exists as a nick, even though multiple people with the
same account 'name' are online and visible to the user, as
reported in https://bugs.unrealircd.org/view.php?id=5761 by Koragg.
Reported by Adanaran in https://bugs.unrealircd.org/view.php?id=5698
Although voiced users normally bypass bans, it is not really logical
for them to bypass filtering of banned words, since that is normally
a policy decission by channel management. So +v will not bypass it.
1) The problem is that this is enforced at the ban layer API. The extban
routines, textban in this case, are not called when the user is voiced,
because voiced users bypass bans. If we would change that in the ban API
then voiced users can also no longer talk through (=bypass) regular +b or
other extended +b such as ~a (account) etc.
2) I figured we would then make +T not use the ban API but the
can_send_to_channel hook instead. However, then you have to do manual
looping through bans and such, it's rather ugly from a coding point of view,
and you risk "missing" things like ~T stacked with ~t.
3) Then I went back to look if the ban API could be changed by having the
textban module set a flag and then the ban api would call that specific
module still for voiced users. While starting on that, unfortunately things
(variables, arguments) cascaded quickly into having to change all kinds of
underlying functions that would break the module API.
4) I then went back to option 2 and implemented it, trying to deal
with all its caveats.
reported by Koragg in https://bugs.unrealircd.org/view.php?id=5757.
This changes the following in the code of who_global():
1) We initialize all the 'marked' users to zero at the beginning,
and remove the previously unmarking in the bottom loop that
shouldn't have anything to do with it. Now there's "no way"
to screw up initialization of marked users.
2) Check for marked users in the bottom loop.
3) Thanks to #1 and #2 we can now easily add simple logic like
not skipping when client==acptr.
4) Similarly, we can remove checks for +i/-i in who_common_channel(),
and as a bonus we will list common channel results altogether
in the WHO result, rather than first +i on common and then at the
very end the remaining -i (which may also be in common channels).
All in all, the code is now more like how I would write it, rather
than the original. It's now harder to screw things up if you change
some visibility or searching logic here or there.
That option specified a Diffie Hellman parameter file. Since
UnrealIRCd 5.0.0 we no longer process this option.
This option has never been documented in the wiki docs.
We prefer and use ECDHE/EECDH with SSL_OP_SINGLE_ECDH_USE since 2015
to provide Forward Secrecy in SSL/TLS. And indeed, by now in 2020,
any properly maintained software uses it and old DH(E) usage has
fallen to less than 1%.
What this patch does is remove the unused code (since Dec 2019) and
show a warning if you have a ::dh config directive, so that at least
you are informed that it is unused/ignored. Since it was undocumented
it probably hardly affects anyone, but still, it is proper to inform.
numbers only. This makes things more logical for end-users.
This fixes https://bugs.unrealircd.org/view.php?id=5746,
bug reported by KindOne.
The same issue was also fixed by previous commit, but still:
it is better to limit things to a narrower range, this so you
don't get different behavior depending on the CPU a server uses.
This adds support for latvian-utf8, estonian-utf8 and lithuanian-utf8
in set::allowed-nickchars. Patch from moseslecce.
Co-authored-by: David Lecce <3292014+davidlecce@users.noreply.github.com>
This should be rare, since modes-on-connect is in the example
configuration file with +ixw since 2003, but still... just in
case someone completely misses the modes-on-connect configuration
item, then make sure that we have a safe and good default.
set::history::channel::playback-on-join::lines and
set::history::channel::playback-on-join::time were ignored,
the limit in the +H channel mode was used instead.
Reported by k4be in https://bugs.unrealircd.org/view.php?id=5707
happens if all of the following are true:
1) You use link::outgoing::tls-options (or ssl-options)
2) You do a REHASH -tls (or REHASH -ssl)
3) You do NOT do a regular REHASH
4) You try to link to the server in such a link block (outgoing!)
In other words: the problem may happen if you try to link after
a Let's Encrypt cert renewal, unless there has been a regular
REHASH between that and the outgoing linking attempt.
Reported by k4be and Le_Coyoto in https://bugs.unrealircd.org/view.php?id=5607
depending on the module load order. Reported by k4be.
Changes:
* Websocket hooks:
* Input should be run first
* Output should be run last
* Labeled-response also had various hook priorities wrong
* Pre command should be run near-first
* Post command should be run near-last
* Close connection (does the flush) should be run near-last
* Packet should be run near-last
Previously it didn't display correctly on server notice the TLSv* version on local connection.
Before: TLS_CHACHA20_POLY1305_SHA256
After: TLSv1.3-TLS_CHACHA20_POLY1305_SHA256
set {
anti-flood {
target-flood {
channel-privmsg 45:5;
channel-notice 15:5;
channel-tagmsg 15:5;
private-privmsg 30:5;
private-notice 10:5;
private-tagmsg 10:5;
};
};
};
Max 45 messages in 5 seconds means max 540 messages per minute,
with a peak of (surprise) 45 messages per 5 seconds...
That should be sufficient for every legit channel, right?
How can you chat if you get more than 9msgs/sec for 5 seconds straight?
Maybe I am even too liberal with these limits?
NOTICE and TAGMSG get lower limits because they are far less used
and have other concerns (eg: ringing a bell for NOTICE).
The default limits may be changed in later versions of UnrealIRCd
based on feedback and more insight in (big) channel rates.
This provides ROP hardening, which is actually quite nice.
However, it requires CPU hardware support, which is pretty
non existant at the moment. So, right now, on most systems
this option will do nothing.
This is 1,5 years after 459a55245a
and we're on a new series too (5.0), so it was about time.
And YES you may still use }; if you want to. There are no
plans to deprecate or warn about it.
We simply ship with } in the shipped configs because it is
more logical that both { and } don't require a ; rather
than only { not requiring it.
Also, remove unnecessary comment about calling lr_post_command() with
the last two arguments being NULL. We don't use these two variables
inside lr_post_command() after this change anyway.
Then the oper may decide if the original entry should indeed be
removed and re-added, or if (s)he should not touch it. These are
usually done by mistake anyway.
Updating existing entries by end-users was never intended and did
not work properly anyway (see bug comments). Issue reported by
Le_Coyote and armyn in https://bugs.unrealircd.org/view.php?id=5603
This had to do with the queued packet (in the labeled-response module)
not being sent because the client was freed before the
post packet hook was called.
any parameter channel mode module loaded after channeldb.
Reported by GaMbiTo, with help from PeGaSuS, Gottem and k4be
in https://bugs.unrealircd.org/view.php?id=5669
It is not safe to call channel mode parameter functions when
unloading modules. Makes sense I think.
We now no longer write the db on rehash, which is something i
didn't like anyway (wasted CPU cycles). The problem was that
one could not just scratch the write db call, as otherwise if
someone rehashes every minute would cause the db never to
be saved. This is because on each rehash the event to write
the db gets rescheduled to +5 minutes in the future.
We now work around that in the same way as connthrottle does.
Obviously it would be better to make the event system itself
deal with this, but that is (way) too much for now.
This was a FIXME item that should have been addressed earlier.
We didn't use any MODDATATYPE_CHANNEL in the core up to now so
this was overlooked. We do use it from now on, though, and it
may very well have been used in 3rd party modules already.
This is the work from May 3rd.. need to commit it so i can merge the
flood protection that is related to this...
The final implementation will still need tweaking before pushed.
[skip ci]
no connect-delay restriction. Also remove the 'disable' option since
it is unneeded. You now simply use:
set {
restrict-commands {
somecommand {
}
}
}
...and the command is disabled.
And you add exempt-identified or exempt-reputation-score if needed.
See https://www.unrealircd.org/docs/Set_block#set%3A%3Arestrict-commands
Note that this also changes some command blocking logic, so I hope
I made no mistake there... only testing will tell.
version or newer on the sytem, otherwise we fall back to shipped version.
This fixes https://bugs.unrealircd.org/view.php?id=5187 among others.
It means:
* Case insensitive matches work better in UTF8 now, such as extended Latin.
For example, a spamfilter on "ę" now also matches "Ę", while previously
it did not catch this.
* Other PCRE2 features such as https://www.pcre.org/current/doc/html/pcre2syntax.html#SEC5
are now available. For example you can now set a spamfilter with the regex
\p{Arabic} to block all Arabic script, or
\p{Cyrillic} to block all Cyrillic script (such as Russian)
Use these new tools with care, of course. Blocking an entire language,
or script, is quite a drastic measure.
All of this was possible because of the new PCRE2_MATCH_INVALID_UTF
compile time option which was introduced in PCRE2 10.34.
This also means we now require at least that PCRE2 version so
everyone can benefit from this new spamfilter UTF8 feature.
Many systems come with older PCRE2 versions so this means we will
fall back to the shipped PCRE2 version in UnrealIRCd. This means
./Config will take a little longer to compile things.
Although there is no indication as of now, but if this feature would
break things heavily then it might get reverted or configurable.
This is also why it was added just after 5.0.4 release and not right
before it, it needs some heavy testing.
Reported by k4be and others.
For the crash to occur a few specific things had to happen:
1) The system is missing the argon2 dev library (or it is too old)
causing us to use the UnrealIRCd-shipped argon2 library.
2) You ran ./Config while there is an existing IRCd running
3) Now some argon2 hash is being checked (eg due to an OPER attempt)
4) Crash
A very similar crash happens (to a LOT more people) when you
run './unrealircd restart' to do the actual upgrade. In such
a case, the old IRCd crashed (the one that was actually supposed
to die anyway). The annoying thing was that the crash reporter
would kick in to report such a crash which was actually quite
harmless. This is actually the same crash as described earlier
so should be fixed as well now.
This variant was reported by Shillos and others.
TLSv1.0 or TLSv1.1. Otherwise it is impossible to enable by the application.
We are still going to turn off TLSv1.0 and TLSv1.1 by the end of this year
by default. Ubuntu 20.04 is just a couple of months too early. See also
the various browsers who postponed disabling TLSv1.0/TLSv1.1.
Also, regardless of the above, we want the admins running the IRC server
be able to control this and not having such a breaking change be dependant
on some distro default settings.
This results in a more general error message that is easy to google.
Also fix the gmake error to complain about make/gmake since it
may also indicate missing make.
We will extend the option later in UnrealIRCd 5.0.5.
This purely has to do with keeping the changes for 5.0.4 small and
contained since that will be mostly a bug fix release.
Since 5.0.5 will have more configurable options for hide-idle-time, I
have already renamed the single option that is exposed in 5.0.4
to set::hide-idle-time::policy since set::hide-idle-time is a
configuration block now, see docs at:
https://www.unrealircd.org/docs/Set_block#set%3A%3Ahide-idle-time
When connecting, use slightly different wording (and use it consistently):
"Trying to activate link with server xyz"
When the connection is lost before synced:
"Unable to link with server xyz"
When the connection is lost after fully synced (eg: minutes later):
"Lost server link to xyz"
Important small changes (other than text):
* Log ERRORs from remote servers to the log (previously only shown to ircops)
* Some link errors could have been previously suppressed due to
old code assuming other parts of the code would send or log the error
(this would be the case for an error when calling SSL/TLS write functions)
* More?
I think nowadays, with more attention to privacy, we should make this
option settable by users.
See previous commit for more information, or just visit the doc page at
https://www.unrealircd.org/docs/Set_block#set%3A%3Ahide-idle-time
if you want to use a different setting.
connected users for technical reasons, so you will have to use double
whois to see it for remotes (/WHOIS Nick Nick) just like with idle time.
Suggested in https://bugs.unrealircd.org/view.php?id=5519
set::ident::connect-timeout for the read timeout also.
This could lead to failed ident lookups on higher latency connections
because it only gave 3 seconds for the entire ident lookup rather than
the (max) 10 seconds that was intended.
Now both values are properly obeyed (3 for connect, 7 for read
timeouts, by default).
This only happens in some circumstances.
From now on EventDel() will simply mark the event as deleted.
The actual freeing is started in DoEvents() after the event loop.
This makes it safe to use EventDel() everywhere.
The previous attempt to fix that issue was
d29a55a8db but it introduced a
new crash issue for a slightly different case, as mentioned in
https://bugs.unrealircd.org/view.php?id=5553
when used on a multi-server network. This was due to the PART event
inadvertently not being sent towards the SAJOIN direction.
Bug reported by Cheiron in https://bugs.unrealircd.org/view.php?id=5616
form an insecure connection. There we explain a bit on the why and how to
configure some random IRC clients.
This also silently adds support for multi-line messages in
set::plaintext-policy::user-message (for warn) and
set::plaintext-policy::oper-message (for warn and deny).
Eg with anope with the KILL option turned ON, a minute after taking
a registered a nick.
Very similar to c9b88343e2 which was
fixed in 5.0.0-beta1 for non-forced nick changes.
files that end in .core, while on many systems it is just 'core'
without the dot. Reverted back to U4-style core file finding now.
Thanks to DeviL for helping to trace this issue.
off not using this and you'll want to use the three other hooks anyway:
* HOOKTYPE_LOCAL_QUIT - for local quits of registered clients
* HOOKTYPE_REMOTE_QUIT - for remote quits of registered clients
* HOOKTYPE_UNKUSER_QUIT - for local quits of unregistered clients
(that is, before they have completed NICK+USER etc)
and HOOKTYPE_REMOTE_CHANMODE are called from the SJOIN code.
We now set the samode argument to -1 if it is an SJOIN server sync,
so chanmodes/permanent won't destroy the channel while processing
the SJOIN. The SJOIN code already takes care of destroying at the end.
so they can fetch more history than the standard on-join history.
In the future we are also likely to implement IRCv3 CHATHISTORY
once that becomes an official specification. However, until it is
specified and until most major clients support it, several years
are likely to pass. It would be a shame to withhold channel
history to many end-users in the meantime when it takes so little
effort from us to provide an easy command.
See also
https://www.unrealircd.org/docs/Channel_history
And in particular the new section:
https://www.unrealircd.org/docs/Channel_history#Playback_frontends
which explains the relationship between on-join playback,
HISTORY and CHATHISTORY.
This does NOT "fix" https://bugs.unrealircd.org/view.php?id=5538:
WHOIS nick
:localserver.example.com 311 test nick ident host * :realname
WHOIS nick nick
:remoteserver.example.com 311 test nick ident host * realname
.. because your IRC protocol parser should not care about a :
or a lack of :. For text not containing spaces nor :-prefix there
is no difference in meaning and it should parse to the same.
However, this DOES fix an issue if the realname itself started
with a colon, such as "USER x x x ::something":
WHOIS nick
:localserver.example.com 311 test nick ident host * ::something
WHOIS nick nick
:remoteserver.example.com 311 test nick ident host * :something
.. because that does not have the same meaning and is a real
incorrect drop of a character.
Yeah, I took into account spaces, but not a word starting with :, my bad.
Release notes:
+* [Channel history](https://www.unrealircd.org/docs/Channel_history) used
+incorrect time internally, resulting in messages expiring too soon.
+The syntax is now really ```/MODE #chan +H lines:time-in-minutes```.
+To make clear that the time is in minutes, an 'm' will be added
+automatically by the server (eg ```+H 15:1440m```).
Bug reported by k4be.
set::oper-auto-join or tld::channel was broken. It worked for the
very first user since boot or rehash, but after that only the
first channel was joined. Reported by PeGaSuS in
https://bugs.unrealircd.org/view.php?id=5535
useful in the future. This would download a specific patch from
the unrealircd.org site, apply it, recompile, and then:
if it's a hot-patch it would rehash
if it's a cold-patch it would print a message that you should restart
the irc server.
spamfilter (F, not f) and qline (Q, not q).
2) Error out when invalid ban exception types are given, so such errors
don't go undetected anymore. Eg it will now print:
"ERROR: bantype 'f' is unrecognized (in 'fgkz'). Note that the bantypes are case sensitive. Type /ELINE to see a list of all possible bantypes."
Reported by westor and Mi_01 in https://bugs.unrealircd.org/view.php?id=5528
Also, when at it:
3) Remove type 't' from ELINE syntax docs, which is in fact 'c'
(which is already present in the list)
Remove old option set::ban-include-username and replace it with a more
generic option which defines what target a ban should apply to.
Also add some parts of set::manual-ban-target which will follow soon.
Although not entirely true, exempting a user from 'd' when using
an extended server ban or IP or ident is not recommended.
The information needed to exempt the user may not be available
at the time of the flood. Better to reject it than have it partially work.
See https://www.unrealircd.org/docs/Extended_server_bans
Examples with ELINE:
/ELINE ~a:TrustedAccount kg 0 This user can bypass kline/gline when using SASL
/ELINE ~S:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef kgf 0 Trusted user with this certificate fingerprint
It also works with bans, although this would be less common:
/GLINE ~a:EvilAccount
A more useful purpose would be to use ~r (realname):
/GLINE ~r:*some*stupid*real*name*
(Although you could already ban realnames via spamfilter 'u')
For third party module coders:
If you have an extban in group 3 (a "matcher"-extban) then you
can opt-in to support this. You do so at extban registration time:
req.options = EXTBOPT_TKL;
or, if you already had another flag set, like for +I, then:
req.options = EXTBOPT_INVEX|EXTBOPT_TKL;
In any case, you set the .options before you call ExtbanAdd().
Note that if you do indicate support then your is_ok function
will be called like:
extban->is_ok(client, NULL, mask, EXBCHK_PARAM, MODE_ADD, EXBTYPE_TKL);
Important here is the NULL channel (since there is none)
Similarly your is_banned function will be called with BANCHK_CONNECT:
extban->is_banned(client, NULL, banstr, BANCHK_JOIN, &msg, &errmsg);
Here too, it is important to note that channel is NULL.
Add new config option "exempt-webirc yes;" in set::restrict-commands::<commandname> in order to give exceptions in all WEBIRC user. This closes one of the 3 suggestions in https://bugs.unrealircd.org/view.php?id=5506
1) Fix issue if HOOKTYPE_IS_HANDSHAKE_FINISHED rejects the user
2) Fix authprompt issue. We now allow adding the TKL in
place_ban_host() for soft-kline/etc. Previously all the
soft-kline/gline/zline/gzline acted like soft-kill.
3) The blacklist module did not allow clients in with action 'warn',
reported by westor in https://bugs.unrealircd.org/view.php?id=5501
In the configuration item you can now achieve the same via:
except ban { mask 1.2.3.4; type maxperip; }
Or even:
except ban { mask { 1.2.3.4; 8.8.8.8; }; type maxperip; }
etc.
Suggested by The_Myth in https://bugs.unrealircd.org/view.php?id=5507
Also, fixed an issue where the IRCd was counting servers as
clients for maxperip, which doesn't make much sense in practice,
so it only counts users now.
MLOCK restrictions when services are down (set::services-server).
Suggested by westor in https://bugs.unrealircd.org/view.php?id=5273
By default all opers with the *-with-override privilege have this,
which sounds OK to me.
just like hooks now. Yeah we've messed up a few times by now.
Seems only Gottem uses them :D
So now it would call for example: prio -10, prio 0, 10, 20, cmd.
This matches the behavior of hook priorities (and swhois etc.)
Turning these errors into warnings instead should be fine and makes
the upgrade process (and instructions) easier.
* set::oper-only-stats is now a warning
* except tkl is auto-transformed into except ban and is now a warning
Both warnings contain clear instructions on what to do to get rid of
the warning message.
This can still be enabled during ./Config by answering to the last question:
--with-asan
But it is no longer enabled by default since it causes a slowdown of X and
increases memory by a factor Y.
until you restart the server.
Yeah it's really too much hassle atm to make that particular setting
/rehash'able, this will probably never change.
Fortunately changing that is rather rare. At least printing the
warning should help those users doing it.
* Cannot use include within an @if
..but you can just use an include and then within that file use
an if, to work around it.
* Cannot use loadmodule within an @if
For both this is because include & loadmodule are processed before
the rest. I think most people will be fine with those restrictions,
though.
reported in https://bugs.unrealircd.org/view.php?id=5281
It was not removing parts properly if an if didn't match,
leading to a use-after-free bug on-boot (or on rehash).
In the process I renamed config_entry_free to config_entry_free_all
since that is what it does. And I created a new config_entry_free(ce)
to free only 'ce' stuff... which is what we want from the
preprocessor.
if you are running a mixed U4 and U5 network, but it solves the situation
where a knock-flood is only detected locally. Since KNOCK usage isn't
that common and flooding is worse than double notices during the
transition period, I went with this change..
to exist and needs to be -n now.
Previously the logic was the wrong way around which made it message
through +n channels and not work if you were actually in the channel.
Fun.
for the user. Otherwise with post-connect SASL authentication you will
have different login information on server X compared to server Y
(the server with the user on it was always correct, though).
Also, add a function called user_account_login() which is used by both
SVSMODE/SVS2MODE and SVSLOGIN to send ACCOUNT messages to the channel.
This too was missing for SVSLOGIN (post-authentication SASL).
For this fix to be 100% effective, you need 100% UnrealIRCd 5.
in a sending loop if you used a services logging channel.
Reported by The_Myth in https://bugs.unrealircd.org/view.php?id=5469
The same bug was reported and seemingly fixed before, but wasn't
actually.
present in UnrealIRCd 4, and possibly in 3.2.x as well.
This changes:
SILENCE
:irc1.test.net 271 self self evilperson!*@*
To:
SILENCE
:irc1.test.net 271 self evilperson!*@*
under the NetworkService account, rather than LocalSystem (SYSTEM).
Something along those lines was suggested long ago in:
https://bugs.unrealircd.org/view.php?id=2330 with a patch
from BuHHunyx.
The more recent pull request from AlexandraBryant suggested to use
the NetworkService account and also fixed the (major) problem with the
original patch that caused UnrealIRCd to hang for 15 seconds when
UnrealIRCd was started in GUI mode (non-services mode).
The installer was changed to automatically set the appropriate
permissions on the UnrealIRCd 5 folder if "Install as a service"
was selected. This so NetworkService can write, otherwise it would
be unable to copy modules to tmp\, write to log files, etc. etc.
We print a clear warning if you manually install the service at
a later stage, suggesting to run the installer instead or to
manually change the permissions.
Better error checking and reporting was added when running 'unrealsvc'
and when we are unable to connect to the service manager. This is
much more common nowadays as you need elevated admin permissions.
checking repositories and downloading C files (this was a TODO item).
Give a clear hard error if ALL repositories failed
(failed to connect, download or parse).
Make a few commands work regardless of repository status.
In fact, these don't connect to repositories at all since they
don't need to. Thus, these commands are always available:
./unrealircd module [uninstall|generate-repository|parse-c-file]
of which only 'uninstall' is of importance for end-users.
Finally, make parse-c-file print a better error in case the file
could not be opened. Note that this command is only there for
module developers and repository managers, not end-users.
/** Calculate the cloaked host for a client.
* @param client The client
* @param curr The real host or real IP
* @param buf Buffer to store the new cloaked host in
* @param buflen Length of the buffer (should be HOSTLEN+1)
*/
void make_cloakedhost(Client *client, char *curr, char *buf, size_t buflen)
all known flags as well. So you can now add stats via modules.
Only the stats help is currently missing if you do so.
=> Moved dccdeny stats to dccdeny
src/parse.c. Also re-order functions in parse.c so they appear in
logical order (1->2->3->4) rather than various helper functions first
and some random order.
https://bugs.unrealircd.org/view.php?id=5453
It had the match_spamfilter() logic reversed. I audited all other
calls to the function as well and they are fine.
Also, CHGHOST CHGIDENT CHGNAME SETHOST SETIDENT SETNAME are now
tested by the test framework.
session after a 15 seconds timeout. The exact timeout value can be
changed by adjusting set::sasl-timeout, which should be (quite a bit)
less than set::handshake-timeout by the way. 15<30 now, so fine.
than scattered checks - which are sometimes different - everywhere in
the source code.
Also extban handler "is_ok" was being called with EXBTYPE_EXCEPT
rather than EXBTYPE_INVEX for +I. (Not reported by anyone)
deal with servers with different set::allowed-channelchars settings:
* We reject the link if set::allowed-channelchars settings differ between
UnrealIRCd 5 servers.
* For the case where you have a mixed network consisting of UnrealIRCd 4.x
and UnrealIRCd 5.x servers we try not to desync, BUT will not allow
anyone to join the invalid channels locally. For IRCOps a message is
printed with additional information on such a failed JOIN attempt.
See https://www.unrealircd.org/docs/Set_block#set::allowed-channelchars
for the different settings, which are best and U4<->U5 advice.
CAN_SEND_TO_USER rather than HOOKTYPE_PRE_USERMSG (which is now removed).
As for the numeric change: this makes it much easier for client devs.
You rarely need to differentiate in the client code between the various
causes. One only cares about detecting that the message was not sent and
that the user needs to be informed.
This replaces various NOTICEs, ERR_NOCTCP, ERR_NONONREG etc. with just the
new numeric 531, which is taken from InspIRCd. The syntax is:
:server 531 yourname targetname :reason for the block
This makes it similar to numeric 404 (ERR_CANNOTSENDTOCHAN) that is used to
indicate that a channel message was blocked.
For module devs, the new hook CAN_SEND_TO_USER prototype is:
int hooktype_can_send_to_user(Client *client, Client *target, char **text, char **errmsg, int notice);
You can replace the text via this, by setting *text in your function.
You can block the message, by returning HOOK_DENY. If doing so, then
you must also set *errmsg to an appropriate value.
Do not send any error message to the user! UnrealIRCd will take care of
sending the error message for you, if you set *errmsg.
Only if you need something special you could violate this rule, but
preferably not!
As you can see, CAN_SEND_TO_USER works just like CAN_SEND_TO_CHANNEL.
1) HOOKTYPE_CAN_SEND is now called HOOKTYPE_CAN_SEND_TO_CHANNEL
The arguments and return values are unchanged
2) similarly can_send() is now called can_send_to_channel()
3) If you want to block or alter a message you must now
use HOOKTYPE_CAN_SEND_TO_CHANNEL and return HOOK_DENY from
there with an appropriate *errmsg filled (see nocolor and
many other modules for an example)
4) You CANNOT use HOOKTYPE_PRE_USERMSG anymore to block a message.
I actually wanted to rip this hooktype out entirely, but
delayjoin needs it. HOOKTYPE_PRE_USERMSG is only useful for
notification that a message is going to be sent BEFORE it is
actually sent (which is exactly what delayjoin needs, so it
can send a JOIN if the user is currently invisible).
5) This is all to make things more clean:
* HOOKTYPE_PRE_USERMSG is only for delayjoin
* HOOKTYPE_CAN_SEND_TO_CHANNEL is used for exactly what the
name implies. You can also change the message text there,
such as for +G, +S, etc.
This so I - and others - don't constantly have to wonder whether the client
is called sptr, cptr or acptr in a simple routine.
Insane --> 212 files changed, 6814 insertions(+), 6945 deletions(-)
Couldn't just mass-replace of course since there are places where there
are multiple clients involved. So had to check each function.
Also renamed some 'acptr' to 'target' and such.
I will write a page with new style rules later.. but in short if there is
only 1 client involved it will now be called 'client'.
anymore if you run latest anope 2.0.6. You need the fix from Feb 9, 2019:
https://github.com/anope/anope/commit/da6e2730c259d6d6356a0a948e85730ae34663ab
(.. which also fixes SASL problems with anope + UnrealIRCd 4 by the way)
or just run anope latest git (2.0 branch).
Not sure about atheme... should test this.
Technical details: we used a pseudo ID / sasl cookie until recently,
this has always been planned to be phased out when we got UID's.
I didn't phase it out in U4 (but could have done so) but just did now in U5.
This simplifies everything as now you can just refer from the services
side to the user with the UID/SID. This also makes it so services can now
target the user in other functions as well, like NOTICE.
(Feel free to request other functions if something isn't working)
Merge check_init and AllowClient into one single AllowClient()
and make it use the more logic 1 and 0 return values for allow / deny.
Similarly, use logic 1 / 0 return values for verify_link.
Module coders:
HOOKTYPE_CHECK_INIT and HOOKTYPE_PRE_LOCAL_CONNECT, changed the
return value, you should now use HOOK_*, eg HOOK_DENY to stop
processing (eg client killed).
that deal with finding TKL's or spamfilters etc.
More will likely follow, to make things more logical.
Also, run_spamfilter -> match_spamfilter
place_host_ban, can_privmsg, check_dcc, find_tkline_match all impacted.
code changes in UnrealIRCd itself:
1) Clients are no longer freed directly by exit_client. Most fields
are freed, but 'sptr' itself is not, so you can use IsDead() on it.
2) exit_client now returns void rather than int
3) ALL command functions return void rather than int.
Of course this also affects do_cmd, command overrides, etc.
This is a direct consequence of the removal of 'cptr' earlier, as that
was used to signal certain things that are now no longer possible
(and it raises the question if things were always correctly signaled
in the first place, so may fix some bugs).
It also makes the code more resillient against cases where you forgot
to check if the client was freed. Still, you are encouraged to do an
IsDead(sptr) if you are calling functions that may kill clients,
such as command functions or things that may use spamfilter.
More changes will follow, such as the removal of FLUSH_BUFFER.
** Exit this IRC client, and all the dependents (users, servers) if this is a server.
* @param sptr The client to exit.
* @param recv_mtags Message tags to use as a base (if any).
* @param comment The (s)quit message
* @returns FLUSH_BUFFER is returned if a local client disconnects,
* otherwise 0 is returned. This so it can be used from
* command functions like: return exit_client(sptr, ....);
'sptr' is sufficient and in most cases the only one you should care about.
Should you need it, you can access sptr->direction in cases where you
need the old information (usually only for some sendto_* functions
and some protoctl checks), so 'cptr' was redundant too.
[!] This change likely introduces some bugs. This was many hours of work.
I only cut some corners in 4 functions, which will be fixed at a later
stage..... yes, more major changes to come.
On the plus side, I likely fixed some bugs in the process. Situations
where cptr vs sptr usage was incorrect. Eg using cptr->name (near server)
when sptr->name should be used (the actual source server), etc....
In such a case we refuse to run since the consequences are too big.
(Actually I may change the non-UTF8 channel warning to an error as well,
right now it isn't.. simply because I cannot read a certain setting)
From both the non-UTF8 channel and user warning/error, we now refer to:
https://www.unrealircd.org/docs/WebSocket_support#websockets-and-non-utf8
which contains a bit more detailed information as to the WHY.
how you use websockets in the configuration file:
In addition to loading the websocket module you now ALSO have to mark
specific listen blocks with listen::options::websocket, and you have
to specify a type as well. Example:
listen {
ip *;
port 1234;
options {
websocket { type binary; }
}
}
The type 'text' is compatible with kiwi although this is currently
completely untested. Also I should add something to the release notes
about this change. Tomorrow...
We actually have 3 possible settings of set::allowed-channelchars:
utf8: Channel must be valid UTF8, this is the new default
ascii: A very strict setting, for example in use at freenode,
the channel name may not contain high ascii or UTF8
any: A very loose setting, which allows almost all characters
in the channel name. This was the OLD default, up to and
including UnrealIRCd 4. It is no longer recommended.
For most networks this new default setting of utf8 will be fine, since
by far most IRC clients use UTF8 for many years already.
If you have a network that has a significant portion of chatters
that are on old non-UTF8 clients that use a specific character set
then you may want to use set { allowed-nickchars any; }
Some Russian and Ukrainian networks are known to need this.
Devs: src/utf8.c has been added which will be used by this and
by other functionality later.
which specifies the time in milliseconds rather than seconds. This
allows for additional precision, or at least multiple calls per second.
The minimum allowed every_msec value is 100 at this time.
The prototype is now: EventAdd(Module *module, char *name,
vFP event, void *data, long every_msec, int count);
crashes (has a core file) to the crash bug report.
Also, disable leak detection since this is too noisy and would cause
a core dump each time + bothering the user to submit a crash report
+ send this crashreport etc. We still enable this in our own tests
though, but not for end-users.
which would be too much coding effort for such an unusual event.
(Reloading is fine though, for eg upgrading-on-the-fly)
Issue reported by westor in https://bugs.unrealircd.org/view.php?id=5416
that was not supposed to be committed :D
It would also warn about if'd out blocks, which is confusing,
so best to disable the warning altogether for now.
Also, you can escape a $VAR to $$VAR if you really just mean $VAR literally.
Such usage would be very rare though.
Note that the parser is smart enough to know that $var is never a
global variable, it only warns for valid variable names like $VAR and
even then only if it's at the end or has whitespace/dot/comma/etc.
So... false positives should be extremely low...
the variable names to UPPERCASE, digits and underscores (A-Z0-9_).
This makes them easily distinguishable from other items in the conf,
so they don't clash with for example $ip in blacklist::reason.
The @define confusion was reported by Gottem and westor.
extern int strnatcmp(char const *a, char const *b);
extern int strnatcasecmp(char const *a, char const *b);
This will be handy for version comparisons. For example they will
return -1 (=lower) for things like ("1.4.9", "1.4.10"), unlike strcmp.
Also, some loosely related spelling fixes elsewhere.
to be a bit less ugly. The module is loaded by default so you can
still use set::options::identd-check like before, even though I
hate ident... it's old shit... still, other's seem to like it.
More changes will follow later. There is still some ident stuff
in the core at the moment and the module is currently PERM, which
largely (but not entirely) defeats the purpose of being a module.
That will be fixed at a later time as well.
MOD_UNLOAD. And MOD_HEADER(xyz) is now MOD_HEADER even without ()
since this isn't a function, really.
To make things understandable I added the following to the
developer section of the release notes:
* The module header is now as follows:
ModuleHeader MOD_HEADER
= {
"nameofmodule",
"5.0",
"Some description",
"Name of Author",
"unrealircd-5",
};
There's a new author field, the version must start with a digit,
and also the name of the module must match the loadmodule name.
So for example third/funmod must also be named third/funmod.
* The MOD_TEST, MOD_INIT, MOD_LOAD and MOD_UNLOAD functions no longer
take a name argument. So: MOD_INIT(mymod) is now MOD_INIT()
the chanmodes/delayjoin module must be named chanmodes/delayjoin
in the module header.
This because currently we have two module names for each module,
one is the name from the MOD_HEADER and the other is the
relative path, such as used by loadmodule and is_module_loaded().
This commit also (not entirely, but practically) breaks loading
of modules outside the regular modules path. I don't think that's
a problem, although it could use a bit more documentation.
REQMODS Gmodname:version ....
to:
SMOD G:modname:version ....
Also, call the module require-module to be consistent with the
naming of the configuration directive.
Not sure yet of the set name, but call it set::require-module for
now as well.
This so we have a few simple concepts:
Client: this can be a user, server, or something unknown yet
Then the type of clients:
User: this is a user, someone with a nick name.
Server: this is a server
Etc.
as cptr->from is NOT (necessarily) the server where cptr is connected to.
So we now call it cptr->direction since it indicates the directly connected
server (or &me)... in other words: the direction of the client path.
old authentication types that are already deprecated in UnrealIRCd 4.x.
They don't contain any rounds which means they can be cracked at a rate of
millions per second. Use the secure hashing type 'argon2' instead
(or, if you must, use the less secure 'bcrypt' type).
including things like CallCmdoverride() to CallCommandOverride().
Type changes like aTKline -> TKL and many more (in particular
aSomething to Something etc. such as aWatch to Watch) but these are
less used by 3rd party module coders.
aChannel to Channel, and some more. Third party module coders will
love this. But.. it makes things more logical and the doxygen output
will look more clean and logical as well.
(More changes will follow)
Use a more simple hashing algorithm and one that uses 64 bits,
don't allocate any memory dynamically, just use an int64_t.
Also, only do the hashing if 'r' is actually enabled in +f
on the channel, as otherwise it's pointless.
Also get rid of the TS parameter in there, which nobody uses anyway.
It didn't even refer to the channel TS.. quite confusing..
it used user->since... so it seems it was against crossing users
(nick changes)... well, we have UID for that now.
except ban in config).
If you want to play with exceptions, type /ELINE for information.
For the configuration file it is important to know that 'except tkl'
is now called 'except ban'.
Also if you do not specify an except ban::type we now default to
exempt from all regular server ban types (but not qline, spamfilters,
blacklist or throttling)
Still need to fix some FIXME/TODO items and things haven't been
fully tested yet, so server sync issues or crashes are still possible.
Release notes will be updated another day as well..
src/modules/tkl.c is the main one).
Also move DB writing/reading functions to src/misc.c so they can be
removed out of channeldb and tkldb.
Important note to current tkldb users:
Unfortunately due to the major cleanup I had to remove upgrading
for previously saved tkl db files. That seemed not worth the effort
for maybe <15 current users or so. It also makes the tkldb code
a lot more cleaner. Otherwise it would be a huge mess.
Currently a FIXME item: spamfilter support in RMTKL.
and remove old dependency field (never used, was always NULL,
broken since 3.2.x)
I'll add some constraints later on things like names and versions.
IOTW: more changes to follow, don't mass update your own mods yet.
Disable these warnings, though:
C4267: downgrade of size_t to int and such. pointless...
C4101: unreferenced local variable
C4018: signed/unsigned mismatch
C4244: implicit conversions with "possible loss of data".
there are 75+ of them and they are likely all harmless
and/or intentional (usually plain obvious too)
C4996: fixme! warnings about deprecated functions, currently only for GetVersion..
setting the default class::sendq that pretty much everyone overrides
in class (isn't this even required? ;D).
Rename to DEFAULT_SENDQ since we have DEFAULT_RECVQ too.
explicit cast to (long long). On *NIX we could get away with
lazily assuming time_t is of the same length as long (and use %ld),
even though the specification says nothing about it.
Unfortunately on Windows things are not that simple:
'time_t' is 'long long' (64 bits) and both 'int' and 'long'
are 32 bits, even when compiling in 64 bit mode.
This problem could be 'fixed' in multiple ways:
One way would be to minimize the usage of time_t and use 'long long'
or 'uint64_t' everywhere for variables to minimize casting later.
I, however, chose to maintain 'time_t' for most of time grabbing
and time calculations (eg: delta), and do the explicit cast in
any printf-like functions that may be there.
Both solutions work. I mostly like the explicit time_t look, so one
can immediately recognize a variable relates to time.
are IRCOp-only now, they will always be removed on deoper.
-extern Snomask *SnomaskAdd(Module *module, char ch, int unset_on_deoper, int (*allowed)(aClient *sptr, int what), long *mode);
+extern Snomask *SnomaskAdd(Module *module, char ch, int (*allowed)(aClient *sptr, int what), long *mode);
32 to 64 bit transition, visual studio 2019 and some directory name
updates as we now put all the shit in c:\dev\unrealircd-5-libs,
or c:\projects\unrealircd-5-libs in case of buildbot..
1) Clean up check_for_chan_flood()
2) Make the new repeat action kick by default (instead of forcing 'b'
if no action is specified)
3) Also make repeat work with timed bans
Note that the labeled-response implementation currently requires
'batch' and will always start a BATCH if there is any response.
Later on we can implement a simple queue so we don't have to
start a batch for 1-line responses (which works, but looks a bit
silly if you look at raw server traffic). That may be after alpha1,
though, as there are more (important) things to work on right now.
so you can use set::restrict-commands without having to loadmodule.
Restrict the LIST and INVITE commands in the example.conf, which is
often a good idea. Finally, document the configuration/usage at:
https://www.unrealircd.org/docs/Set_block#set::restrict-commands
of match_simple() and match_esc(). So, developers, be aware, this is how
you should use the function in a correct way:
if (match_simple("*fun*", str))
printf("It was fun\n");
Rationale:
I've always been annoyed by the inversed logic, even though it was similar
to strcmp. So I've reverted it.
I could have chosen to maintain match() rather than this match_simple()
name, but this way I force (3rd party module) devs to update their function,
while otherwise everything would mysteriously fail due to the inverted logic.
I suppose what is and what is not an API can be considered a bit arbitrary
but for us it is the stuff we expose via the module api. We now have:
api-clicap
api-command
api-event
api-extbans
api-extcmodes
api-history-backend
api-isupport
api-mtag
api-umodes
I needed the target for echo-message, and also in the history module we no
longer save to the history any @#channel messages, since otherwise they
could be played back to people we shouldn't see them ;)
So rename src/modules/m_*.c to src/modules/*.c and update makefiles
and modules.default.conf. Also remove m_ at various places in the
source files, but not the CMD_FUNC(), just the module name.
if (m->clicap_handler && (acptr->local->caps & m->clicap_handler->cap))
return 1;
... so if messagetaghandler->clicap_handler is NULL then this won't be 1.
UnrealIRCd already protects (for maaaany years) with ping cookies against
this attack. Making the m_nopost redundant.
Also, another module may be more useful (more on this soon...).
explicitly do not want to remember any channel history, such as on
a hub server to save memory.
Also, on Windows, ensure to compile all history_backend_*.c
This determines when UnrealIRCd will use broadcast instead of multicast
for delivering channel messages to servers.
The default is 'auto' which uses multicast but switches to broadcast
when channel mode +H is set. This is what people should normally use.
If you set it to 'never' then +H will not work properly if there are
servers with 0 users on them.
and not just the operating system.
This makes us use SSL_CTX_set_min_proto_version(), which unfortunately is
a less fine-grained control for disabling specific SSL/TLS versions.
However, after that we use SSL_CTX_set_options with SSL_OP_NO_xxx.
The latter is deprecated though. Will revisit this change before U5 release..
Main difference is that the curve used for ECDHE is fixed at prime256v1
rather than a list of multiple choices (this due to an openssl 1.0.1
limitation).
[skip ci]
systems without explicit_bzero. Current usage is only in the PRNG which
is not very important anyway. We can re-visit later by attempting to
provide a fallback portable version, but from what I've seen this is
pretty ugly.
to enter the private key password when UnrealIRCd is (re)started.
Similarly, remove all references to it on Windows as well, where people
thought clicking "Encrypt private key" was a good idea. Can't blame them,
it sounds good on first sight :D
[skip ci]
LoadPersistentPointer(modinfo, removefld_list, floodprot_free_removefld_list);
SavePersistentPointer(modinfo, removefld_list);
The above example was for a pointer, there are also functions for int and long,
which are even more simple:
LoadPersistentInt(modinfo, somevar)
SavePersistentInt(modinfo, somevar)
and
LoadPersistentLong(modinfo, somevar)
SavePersistentLong(modinfo, somevar)
both are untested, but will be tested soon...
make a mistake in the module so we can upgrade it on-the-fly.
Or if someone wants to get rid of it.
TODO: consider abstracting the saving/restoring of vars.
(malicious) server traffic.
Also seems we have a behvior change here: has_voice and such returned
1 for servers, now it returns 0. I can live with that, but may cause
more issues.
These are just remnants of the past, when +a was called channel protection.
It is called channel admin since as long as I can remember, and in 90%
of the code and documentation it is called that way.
in case of a change in the quit comment, such as color stripping / blocking.
The default is 'no', but some users may like this to be 'yes' so things like
+S only affect the channel and not the quit for all channels.
This hereby also lays the groundwork for some next commits of 'i' :)
The configuration item name may still change if I think of a better one....
Make local spamfilter blocks use this too. Already did so for
ban xxx types that will cause kline/gline/zline and qline.
This also simplifies handling in the tkldb module.
file that cannot be deleted via commands such as /KLINE -...
And transform some ban XX entries to use the TKL system
TODO: test & rip out the old stuff
Since UnrealIRCd 4 (and probably before) our instructions always mentioned
that you should not build or run UnrealIRCd as root.
Even system integrators are unlikely to build as root, but just in
case, the safety the check is in ./Config and not in ./configure.
Also, DoAccess() was already commented out in UnrealIRCd 4 or something.
This results in an empty finish_auth() function but that should be OK,
as ident checking takes place before parsing any other input IIRC.
If everything goes correctly then after reading all TKL entries we
should be at the end of file. If there is still data after that,
something went wrong... quite wrong.. :D
This, rather than having the module not loaded at all, which could mean,
especially if missed the warning on boot, that you run for weeks or
months without having your TKL's stored, which would be a shame ;)
Also a failure to rename() is not fatal, as it likely means that we
don't have permissions, in such a case you will see a repeated error
every X minutes due to the write, which is good.
will not be called. This is used, for example, by m_cap when the CAP LS
handshake is still in progress. Modules can add their own requirements
as they see fit.
Note that, as for (CAP) functionality, this adds nothing new, it just
implements it in a cleaner way, rather than all over the place,
like in UnrealIRCd 4.x.
and has various outstanding crash and 100% CPU issues.
We have been encouraging the PCRE2 engine since the start of
UnrealIRCd 4 already.
TRE is being phased out of U4 by the end of the year, so we can
safely remove it in U5 already.
Such a variable suggests that we will never read past that, but that
is not the case, since we (correctly) assume that the buffer is
NUL terminated, which is ensured by dbuf_getmsg().
The 'length' is still available for informational purposes, to avoid
strlen()'s at various places.
Hm, I guess length can cause the same confusion as bufend, but still..
I like it better :D
For example, msgid / message-ids is not a CAP, while server-time is.
There mere fact of something being in CAP or not shouldn't cause
something to be in different directories ;).
Early commit, still cleaning up to do.
But what works is:
$define SERVER "hub.example.org"
$if SERVER == "hub.example.org"
link .... {
....
}
$endif
$if defined(SERVER)
....
$endif
And also we have mod-loaded() which even works half-way in a block
such as in helpop:
help Chmodes {
[..]
$if module-loaded("chanmodes/stripcolor")
" c = Block messages containing mIRC color codes [o]";
$endif
$if module-loaded("chanmodes/noctcp")
" C = No CTCPs allowed in the channel [h]";
$endif
};
As said, still need to cleanups and there are some limitations.
Also the idea is to be able to use defined values in variable names/values
but that has not yet been implemented.
You now call it with a path like is_module_loaded("extbans/timedban").
This, among other reasons, so you can differentiate between modules with
the same name, such as "usermodes/noctcp" and "chanmodes/noctcp".
This also includes buffer modifications to have a larger read buffer
and IRCv3 implementations (partial or not) for:
labeled-response, msgid, server-time, batch and account-tag.
As said, it is the initial and partial implementation.
There are still various FIXME's and TODO's, the API of various
functions may still change (actually that is true for the next
months, even) and some stuff is currently in the core that will
be moved to modules.
always as new users (regardless of reputation), causing the protection
to kick in too quickly for the poor new users. This was noticeable
after for example one server died and new users reconnecting massively
to the remaining servers. Reported by Lord.
have already fully authenticated the server (but when it technically is
not fully linked as a server yet, eg post-EAUTH but pre-SERVER).
Also, send ERRORs to junk snomask from untrusted sources. After all,
the junk snomask is precisely there to enable briefly to debug issues.
In case of link errors we always advice to check BOTH sides of the link
as an IRCOp, and this advice still stands. This may just help a little
for people who do not follow our advice.
password types (eg: plaintext on one side, spkifp on the other side).
Refer to https://www.unrealircd.org/docs/FAQ#auth-fail-mixed
Also, unrelated to the above, don't say "Bad password?" if the
password type is not of type plaintext, since it would be confusing.
Nowadays these are pretty much never proxy attacks. Only scanners and
crawlers trying HTTP commands on IRC connections.. which isn't even that
weird anymore since people tend to open up port 443 for SSL/TLS IRC
to bypass firewall restrictions.
not found then this was not treated as a fatal error. Now it is, since
you will fail later in the installation process when a certificate file
is being made (resulting in mysterious 'req: command not found' errors).
Also, improve the error message both for the missing openssl library
and openssl binary case.
For example for Windows users, or for *NIX users where the automated
patching of the spamfilter.conf did not work.
I've tried to make the error message as clear and big as possible
and the wiki article as clear as possible as to what the user needs
to do. Not much more I can do.... :)
'posix' to 'regex' if the user is using the exact same spamfilter.conf
that shipped with UnrealIRCd 4.x until now. Otherwise, we do not
update anything. Also, custom spamfilters in this file are not touched.
Let's hope this will apply to most of our users to ensure that they
will have no or less issues with the 'posix' to 'regex' conversion
process.
This is mostly to guard 3rd party module writers against making
such a mistake. Up to now such a mistake would silently corrupt
memory without warning or error. That is, until you crashed :D.
usually the fast badwords system is used instead)
* Code deduplication in src/modules/{chanmodes,usermodes}/censor.c
to src/match.c -- which may be moved later again to efuncs.
* Add --without-tre:
This means USE_TRE will be enabled by default right now
but if using --without-tre it will be undef'ed. This so we
can prepare for the TRE phase-out in 2020.
* Remove include/badwords.h, put contents in include/struct.h
that these are just old examples from the year 2005.
Also, no longer include spamfilter.conf from the example*conf by
default as they do not contain any useful spamfilters nowadays.
is another warning being triggered.
-copy paste comment from configure.ac-
We check for the -Woption even though we are going to use -Wno-option.
This is due to the following (odd) gcc behavior:
"When an unrecognized warning option is requested (e.g.,
-Wunknown-warning), GCC emits a diagnostic stating that the option is not
recognized. However, if the -Wno- form is used, the behavior is slightly
different: no diagnostic is produced for -Wno-unknown-warning unless
other diagnostics are being produced. This allows the use of new -Wno-
options with old compilers, but if something goes wrong, the compiler
warns that an unrecognized option is present."
Since we don't want to use any unrecognized -Wno-option, we test for
-Woption instead.
The new question in ./Config now defaults to 'auto' (both for new installs
and for upgrades). You can still specify a manual limit but it is no longer
recommended.
A MAXCONNECTIONS of 'auto' means - at present - that UnrealIRCd will try
to set a limit of 8192. This is quite a bump from the original 1024.
On systems where this is not possible we will simply use the highest amount
possible, such as 4096 on many systems, or 1024.
In fact, we now no longer error when MAXCONNECTIONS is higher than the
'ulimit -n' limit but will adjust ourselves to the limit.
Only if the effective limit is below 100 we will print out a fatal error
since running in such a scenario is highly discouraged.
The reason for this change is that nowadays with drone attacks we may need
to be able to handle more concurrent sockets. Also, many Linux distro's
have a default setting of unlimited or 4096 nowadays, out of the box.
For people packaging UnrealIRCd (not end-users):
The ./configure --with-fd-setsize=xx option was removed and the
optional(!!) --with-maxconnections=xx option has been added.
We recommend you NOT to pass this option. Not passing it means that
the previously mentioned 'auto' mode will be used, which is likely
best for most users.
Module coders:
Although it is unlikely you accessed the 'MAXCLIENTS' variable,
if you did, it is now called 'maxclients' (lowercase) since it is
adjusted at runtime and no longer a macro.
encouraged to use CMD_OVERRIDE_FUNC(override_xyz) rather than declaring
the function themselves. This works similar to CMD_FUNC(somecmd).
Example:
/* Forward declaration */
CMD_OVERRIDE_FUNC(override_xyz);
[..]
MOD_LOAD(somemodule)
{
CmdoverrideAdd(modinfo->module, "XYZ", override_xyz);
[..]
CMD_OVERRIDE_FUNC(override_xyz)
{
/* Do something useful here */
that need to be visible from the outside of the .DLL (symbol export).
Long story short: you never need to use this yourself in a module.
Where needed it is already handled by UnrealIRCd.
enough to clean it up. Also, remove PROTOCTL -<option> support, which is
not used by anything and was only supported on a handful of options
anyway. Also remove some debugging and PROTOCTL_MADNESS.
Finally, add a reference to the technical documentation.
triggered by doing quick server connects (crossing requests), something
that the PROTOCTL SERVERS= code is supposed to prevent (it should be
safe to connect to X servers at the same time, even every second).
Previously various information was only available for directly attached
servers, since it is communicated via PROTOCTL.
Now, we will also communicate information about leafs behind us.
IRCOps can use the /SINFO command to see these server features.
Services codes don't need to do anything, or at least are not expected
to do anything. They can still receive the information and do something
with it, of course...
Read the following technical documentation for full information,
as it will outline very specific rules for using the command S2S:
https://www.unrealircd.org/docs/Server_protocol:SINFO_command
I was wondering why the handshake took 4 seconds for a client which
authenticates using SASL. Turns out that fake lag was kicking in due
to the many "CAP req" commands combined with the other handshake stuff.
Now the first 15 (or so) "CAP" requests are "free", without fake lag.
of targets accepted for a command, eg /MSG nick1,nick2,nick3,nick4 hi.
Also changed the following defaults (previously hardcoded):
* PRIVMSG from 20 to 4 targets, to counter /amsg spam
* NOTICE from 20 to 1 target, to counter /anotice spam
* KICK from 1 to 4 targets, to make it easier for channel operators
to quickly kick a large amount of spambots
See https://www.unrealircd.org/docs/Set_block#set::max-targets-per-command
(actually still need to write the documentation)
maximum number of conversations a user can have with other users at the
same time. Until now this was hardcoded at limiting /MSG and /INVITE to
20 different users in a 15 second period. The new default is 10 users,
which serves as a protection measure against spambots.
See https://www.unrealircd.org/docs/Set_block#maxcc for more details.
such as "WHO +s serv.er.name" to "WHO serv.er.name s".
It also does advanced transformation such as "WHO -m z" to "WHO -z m"
**copy paste from comment in code**
Flag a: user is away << no longer exists
Flag c <channel>: user is on <channel> << no longer exists
Flag g <gcos/realname>: user has string <gcos> in his/her GCOS << now called 'r'
Flag h <host>: user has string <host> in his/her hostname << no change
Flag i <ip>: user has string <ip> in his/her IP address << no change
Flag m <usermodes>: user has <usermodes> set << behavior change
Flag n <nick>: user has string <nick> in his/her nickname << no change
Flag s <server>: user is on server <server> << no change
Flag u <user>: user has string <user> in his/her username << no change
Behavior flags:
Flag M: check for user in channels I am a member of << no longer exists
Flag R: show users' real hostnames << no change (re-added)
Flag I: show users' IP addresses << no change (re-added)
**end of paste**
Of course we cannot convert 100% from classic UnrealIRCd WHO to WHOX-style
because things like "WHO +m r" could mean either "search for +m in realname" (WHOX)
or "search for +r in modes" (classic). In cases like this we assume WHOX, so to not
break any WHOX compatibility.
Added matchers: 'R' (show real host) and 'I' (show IP)
This code will need more testing, both by classic WHO and by WHOX users...
* No longer require a ! prefix for ircops to see users
* "WHO *" is no longer different than the rest
(previously in m_whox would only list users on 1st channel)
Neither is part of the WHOX specs.
not picked up by any other IRCd. The 005 tokens KNOCK MAP USERIP are
now used instead. We do not announce STARTTLS in 005 anymore as this
is way too late (post-handshake, sensitive info already sent and/or
received). Not to mention STARTTLS is not the preferred method to
setup a secure connection in the first place.
Module coders: this means CommandAdd() with M_ANNOUNCE should no
longer be used. If a 3rd party module does use it, then UnrealIRCd
will now raise a warning. In a later UnrealIRCd version the flag
is likely to be removed completely so would cause a compile error.
(I doubt any module uses this anyway... but still..)
* You can now set more custom limits. The default settings are shown below:
set {
topic-length 360; /* maximum: 360 */
away-length 307; /* maximum: 360 */
quit-length 307; /* maximum: 395 */
kick-length 307; /* maximum: 360 */
};
* A new 005 token has been added: QUITLEN. Works similar to KICKLEN.
The ability to adjust the topic length in the configuration file was
requested by Amiga600 in https://bugs.unrealircd.org/view.php?id=4692
At that place is also additional information on why there is a
"maximum" for topic length.
There's now no longer a difference between a rehash or boot.
2) Other cleanups in s_conf.c as well. Looks better now.
3) Sort the 005 tokens alphabetically. Enforcing some other 'logical order'
was futile and this makes things consistent between rehashes.
For module coders this adds some new functions, such as IsupportSet,
IsupportSetFmt and IsupportDelByName. I'll document them later.
to control synchronization of the +beI setter across server links
(that is, the feature just introduced one commit ago):
set {
topic-setter [nick|nick-user-host]; /* nick = default */
ban-setter [nick|nick-user-host]; /* nick = default */
ban-setter-sync [yes|no]; /* yes = default */
};
This also means that --with-topicisnuhost / TOPIC_NICK_IS_NUHOST
is now removed, since this now goes via set::topic-setter.
Also, moved the "first" PROTOCTL from include/common.h to send_proto()
in src/s_serv.c so the bunch of PROTOCTL lines is all in one place
(and so I could conditionally send SJSBY).
Ok, it's not entirely all in one place, PROTOCTL EAUTH is still sent
at another place (early, duh), but still..
when servers link. Thus, you can see the real setter and time also after
a netsplit (/mode #channel b). This, unlike before, when setby was
name.of.server and time was the time of the synch.
This requires the entire network to run UnrealIRCd 4.2.2 or later.
Suggested by k4be in https://bugs.unrealircd.org/view.php?id=5183
Technical details: the PROTOCTL token to enable this is "SJSBY" and see
https://www.unrealircd.org/docs/Server_protocol:SJOIN_command for more
information, in particular the last section there.
for CONFIG_LISTEN. This so a module can have custom options in
the listen block. Like all other CONFIG_* options you are supposed
to return 1 if your module handles this option and 0 if not.
From HOOKTYPE_CONFIGTEST you can also return -1 to indicate error
for an option that is handled by the module.
Note that 'cep' is passed, that is the option for the variable
that is being checked, and not the 'ce', the parent of the listen
block. If you want to access the parent, then use ce->ce_prevlevel.
The script symlinks any missing tmp/xxxx.so's to the real module name but
depends on English statements (ugly, yeah, but it works). With a non-English
locale this did previously not work so the backtrace was screwed.
do with clients that use outdated SSL/TLS protocols (eg: TLSv1.0) and
ciphers. The default settings are to warn in all cases: users connecting,
opers
/OPER'ing up and servers linking in. The user will see a message telling
them to upgrade their IRC client. This should help with migrating such
users, since in the future, say one or two years from now, we would want to
change the default to only allow TSLv1.2+ with ciphers that provide Forward
Secrecy. Instead of rejecting clients without any error message, this
provides a way to warn them and give them some time to upgrade their
outdated IRC client.
https://www.unrealircd.org/docs/Set_block#set::outdated-tls-policy
that use outdated SSL/TLS protocols (eg: TLSv1.0) and ciphers.
The default settings are to warn in all cases: users connecting,
opers /OPER'ing up and servers linking in. The user will see a message
telling them to upgrade their IRC client.
This should help with migrating such users since in the future, say one
or two years from now, we would want to change the default to only allow
TSLv1.2+ with ciphers that provide Forward Secrecy. Instead of rejecting
clients without any error message, this provides a way to warn them and
give them some time to upgrade their outdated IRC client.
https://www.unrealircd.org/docs/Set_block#set::outdated-tls-policy
* Remove LibreSSL versions that are no longer supported (2.5.x and 2.6.x).
* Add LibreSSL 2.8.x (current stable) and 2.9.x (current dev)
* OpenSSL releases only had updates in their 'letter suffixes'
preferring AES-256 over AES-128 (in contrast to the Mozilla "intermediate"
profile which prefers AES-128). Again, this only affects non-PFS cases, as
all modern clients with PFS already had CHACHA20 and AES-256 negotiated.
The portion of non-PFS clients should only be few percent, if any.
I was actually considering removing non-PFS ciphersuites but it seems a bit
early to do so, at least not without more research on affected clients.
The last parv[] array element will be NULL. Accessing any elements after
that is undefined, similar to reading past the nul byte of a string.
This poison will help catch such bugs. Without this poison your code
will also crash, now it just crashes more consistently.
Apparently Debian stretch has 20160821's version which just falls short.
20161029 already has it included. We'll now use shipped libargon2 for
versions below 20161029. Thanks to vectr0n for reporting the issue.
https://www.unrealircd.org/docs/Authentication
And "require sasl" is now "require authentication"
(the old name will only raise a warning, not cause an error)
Note that authprompt currently only does the "require authentication"
stuff and not yet the soft-xx actions. That will be something for
later this week, but I've already documented it as such (here and
there anyway).
We previously introduced the "require sasl" block which allows you to
force users from certain IP addresses to authenticate with their nickname
and password via SASL. We now offer a new experimental module called
'saslemulation' which will help non-SASL users by showing a notice and
asking them to authenticate to their account via /AUTH <user>:<pass>.
See https://www.unrealircd.org/docs/Set_block#set::sasl-emulation
Note that this is work in progress, although the functionality of
already works. Still need to do some cleaning and expand the scope.
And more testing...
* The operclass privileges have been redone. Since there were 50+ changes
to the 100+ privileges it makes little sense to list the changes here.
If, like 99% of the users, you use default operclasses such as "globop"
and "admin-with-override" then you don't need to do anything.
However, if you have custom operclass { } blocks then the privileges
will have to be redone. For more information on the conversion process,
see https://www.unrealircd.org/docs/FAQ#New_operclass_permissions
For the new list of permissions, with much better naming and grouping:
https://www.unrealircd.org/docs/Operclass_permissions
The inconsistency in the privileges was initially reported by webczat in
https://bugs.unrealircd.org/view.php?id=4771
The subsequent reorganization took two full days, so.. hopefully the
people who are using - or plan to use - custom operclasses will like the
new layout... except that they need to redo their work of course ;)
deprecated because they can be cracked at high speeds. They still
work, but a warning will be shown on boot and on rehash.
Please use 'bcrypt' or (even better) the new 'argon2' type instead:
"./unrealircd mkpasswd argon2" or "/mkpasswd argon2 passwd" on IRC.
Also, not in release notes because it would take up too much text:
Unix crypt is a bit more complicated: most types are outright 'bad',
while other types have reasonable security similar to 'bcrypt'.
To be honest these people should probably use 'argon2' since it's
a lot better. Then again, warning about this when it's still such
a common hashing method (now, in 2018) may be a bit overzealous.
So: not warning about crypt types $5/$6 which use SHA256/SHA512
with normally at least 5000 rounds (unless deliberately weakened
by the user), but we do warn about other crypt() usage.
Also, mkpasswd support for those deprecated types has been removed since
there's no good reason to generate new password hashes with these.
Also, make this the default for './unrealircd mkpasswd'.
The Windows version also works.. I just need to create a new library
package, will be done later today or tomorrow.
https://bugs.unrealircd.org/view.php?id=5116
Note that both }; and } forms are accepted now, even mixed, and this
will not raise a warning or error.
I've always found it odd that we required a ; after }. In a language
like C for typedef structs it has some meaning since there could be
an alias between the } and the ;, but in UnrealIRCd there's no such
thing.
however it turns out they were accidentally reversed.
This is now corrected: highest number = highest prioty.
Reported by Gottem in https://bugs.unrealircd.org/view.php?id=5162
This was and still is the default, set::check-target-nick-bans 'yes', however
the feature was broken since UnrealIRCd 4.0.0 (-betaX) by commit
709c7e890e. Reported by PeGaSuS and St3Nl3y.
This module will detect and stop spam containing of characters of
mixed "scripts", where some characters are in Latin script and other
characters are in Cyrillic.
This unusual behavior can be detected easily and action can be taken.
loadmodule "antimixedutf8"; /* or third/antimixedutf8 */
set {
antimixedutf8 {
score 5;
ban-action block;
ban-reason "Possible mixed character spam";
ban-time 4h; // For other types
};
};
Since OpenSSL decided not to use the regular ciphers but make this a
separate option, we now make this a separate option as well.
So there is ::ciphers for <=TLSv1.2 and ::ciphersuites for TLSv1.3
More documentation will follow.
Patch from 'i' in https://bugs.unrealircd.org/view.php?id=5149
Add the ASCII character codes for strikethrough (0x1E, 30) and
monospace (0x11, 17) to the _StripControlCodes function. This
addresses those formatting characters not being filtered when the
"nocodes" module is loaded.
See https://modern.ircdocs.horse/formatting.html#characters
any other bans that will cause the user to be disconnected.
For technical details see the banned_client() function.
It's likely I made some mistakes somewhere => testing required!!
from antirandom checking because they frequently cause false positives.
This new behavior can be disabled via:
set { antirandom { except-webirc no; }; };
Suggested by The_Myth in https://bugs.unrealircd.org/view.php?id=5007
This is meant to blacklist modules that are in modules.default.conf (or
elsewhere). The 'loadmodule' line for any such module is effective ignored.
https://bugs.unrealircd.org/view.php?id=5118
Note: I had to move the loadmodule code. Previously this was done as each
config file (include) was loaded into memory. Now it is done after *ALL*
config files have been read into memory. This shouldn't matter for module
devs, though..
Compiling already works (this is already tested by AppVeyor for quite a
while), but the installer in git required VS 2015. The actual releases
up to now required VS 2012.
To be more precise, either VS 2015 Redist or VS 2017 Redist is enough,
the x86 version that is, as they are binary compatible and both provide
"version 14". So if one of those is installed, the installer just runs.
If neither of these is installed we tell the user to install the VS 2017
Redist package, not mentioning 2015 as it would only cause confusion.
is found. This fixes an issue on Ubuntu 18 where the library is
stored in /usr/include/x86_64-linux-gnu and ./Config doesn't detect
it and thus reverts to using local-curl.
curl enabled but without system curl, the build could fail with
an libCURL configure error. This is is because it imported the
CURLDIR but it referred to an old UnrealIRCd directory.
Reported by The_Myth (#5106)
For example Ubuntu 16.04 LTS with OpenSSL 1.0.2g.
Especially in strict config it would error 'No shared ciphers'.
Had to do with #if(def) ordering. SSL_CTX_set_ecdh_auto() is
still required in 1.0.x even if SSL_CTX_set1_curves_list() is
used. Understandable.
Change from this TLSv1.2 and TLSv1.3 message:
*** You are connected with TLSv1.2-ECDHE-RSA-AES256-GCM-SHA384-256bits
*** You are connected with TLSv1.3-TLS_AES_256_GCM_SHA384-256bits
To this:
*** You are connected with TLSv1.2-ECDHE-RSA-AES256-GCM-SHA384
*** You are connected with TLSv1.3-TLS_AES_256_GCM_SHA384
Since: 1) those bits are redundant (AES 256 is already mentioned),
and 2) Bits are also not an universal method to measure strength across
algorithms (think: elliptic curve).
(Not too surprising when add is 0 and delete is 1)
Not fatal, as error was still handled & send, but it went to
all opers instead of just the one person adding it..
the following remarks:
* We only set these curves if SSL_CTX_set1_curves_list() is available
(OpenSSL 1.0.2 or later, LibreSSL 2.5.1 or later)
* The X25519 curve is only added if it is available (OpenSSL 1.1.0+)
This requires OpenSSL 1.0.2 or newer (released on 22 Jan 2015).
Also fix a bug with OpenSSL 1.1.0+ where - due to removal of an API
function - we accidentally forced curve P-256 rather than automatic
selection. That sucks because the automatic selection (since 1.0.2+)
allows supporting multiple curves and selecting the highest one.
+dnl This is purely for charsys.c... I like it so we can easily read
+dnl this for non-utf8. We can remove it once we ditch non-utf8 some day
+dnl of course, or decide to ignore me and encode them.
-int hooktype_mode_deop(aClient *sptr, aClient *victim, aChannel *chptr, u_int what, char modechar, long my_access, char **badmode);
+int hooktype_mode_deop(aClient *sptr, aClient *victim, aChannel *chptr, u_int what, int modechar, long my_access, char **badmode);
.. this to get rid of a compiler warning and potential problem.
Can't safely use shorts with variable argument functions I think,
or maybe only with reduced type checking which is not what we want.
-void hooktype_channel_synced(aChannel *chptr, unsigned short merge, unsigned short removetheirs, unsigned short nomode);
+void hooktype_channel_synced(aChannel *chptr, int merge, int removetheirs, int nomode);
m_pass and m_topic.c when duplicating strings with a length limit.
+/* strldup(str,max) copies a string and ensures the new buffer
+ * is at most 'max' size, including nul byte. The syntax is pretty
+ * much identical to strlcpy() except that the buffer is newly
+ * allocated.
+ * If you wonder why not use strndup() instead?
+ * I feel that mixing code with strlcpy() and strndup() would be
+ * rather confusing since strlcpy() assumes buffer size including
+ * the nul byte and strndup() assumes without the nul byte and
+ * will write one character extra. Hence this strldup(). -- Syzop
+ */
The output of /IRCOPS isn't meant to be client parsable anyway (which
can be seen by the use of bold text and such), so using a generic
numeric rather than wasting two others seems sensible.
Reported by The_Myth in #5066.
We only parsed the first A record reply, so if the blacklist returned
multiple results /and/ you would not have all those types in your
blacklist { } block then you could miss a hit (false negative).
On *NIX now always redirect stdin, stdout and stderr to /dev/null for
safety and to prevent any ssh hanging as reported by mbw (#5087).
This code needs some testing on non-Linux though it should be all
POSIX, unless I missed something... :)
This is for easier parsing of the "MODE yournick" response.
From:
:maintest.test.net 008 testuser :Server notice mask (+kcfjvGqSso)
To:
:maintest.test.net 008 testuser +kcfjvGqSso :Server notice mask
Reported by emerson in #5079.
listen::ssl-options, sni::ssl-options or link::outgoing::ssl-options
are used. In short: it only reloaded the ones from set::ssl until
now. Bug reported by Mr_Smoke (#5072)
Built-in time synchronization was added in 2006 when many computers did not
do time synchronization by default. Nowadays nearly all operating systems,
including many Linux distro's, Windows and OS X have time synchronization
enabled out-of-the box.
You can still re-enable the built-in timesynch feature via:
set { timesynch { enable yes; }; };
..but you should really use NTP instead.
This affected the following errors:
* Max SendQ exceeded
* Excess Flood
* Flood from unknown connection
* SSL Handshake flood detected
* Rejected link without SSL/TLS
* Various errors from the websocket module
* Other errors generated by 3rd party modules
This posed a limitation with utf8 PROTOCTL NICKCHARS=... and
potentially PROTOCTL SERVERS=... if having more than 32 servers.
The limitation has now been removed (buffer length = 512)
Also call the UTF8 charsys support experimental. Not so much because
of issues in UnrealIRCd that are unique to utf8 but because of the many
"but's" such as lack of services support. And people suddenly waking up
and realizing there never was improved CASEMAPPING and "visually identical
character checks" in original charsys either.
This is the "non breaking space" outside UTF8 and thus was previously
blacklisted. Keeping it blacklisted even if it appears in UTF8 is not
really an option as it means some UTF8 characters can never be used,
like the letter "nun" in Hebrew, and likely others.
module but at least the code can be updated on the fly (or replaced
with some other secondary alternative module in the future).
src/charsys.c -> src/modules/charsys.c
This also means everyone needs to load the modules/charsys module.
See https://www.unrealircd.org/docs/Nick_Character_Sets
Example: set { allowed-nickchars { latin-utf8; }; };
Important remarks:
* All your servers must be on UnrealIRCd 4.0.17 (or later)
* Most(?) services do not support this, so users using UTF8 nicknames
won't be able to register at NickServ.
* In set::allowed-nickchars you must either choose an utf8 language
or a non-utf8 character set. You cannot combine the two.
* You also cannot combine multiple scripts/alphabets, such as:
latin, greek, cyrillic and hebrew. You must choose one.
* If you are already using set::allowed-nickchars on your network
(eg: 'latin1') then be careful when migrating (to eg: 'latin-utf8'):
* Your clients may still assume non-UTF8
* If users registered nicks with accents or other special characters
at NickServ then they may not be able to access their account
after the migration to UTF8.
[!] Work in progress [!]
"SSL_accept(): Internal OpenSSL error or protocol error: tls_process_client_hello: unsupported protocol"
rather than just
"SSL_accept(): Internal OpenSSL error or protocol error"
Perhaps it can be shortened in a later version if this is acceptable.
This can help with tracing server linking errors, and/or
if using the junk snomask (MODE nick +s +j).
Naturally this is only available if the extbans/timedban module is
loaded and you should do so on all your servers on the same network
if you want to avoid confusion/desynchs.
These are bans that are automatically removed by the server.
The duration is in minutes and the mask can be any ban mask.
=> Note that you need to load the extbans/timedban module!
Some examples:
* A 5 minute ban on a host:
+b ~t:5:*!*@host
* A 5 minute quiet ban on a host (unable to speak):
+b ~t:5:~q:*!*@host
* An invite exception for 1440m/24hrs
+I ~t:1440:*!*@host
* A temporary exempt ban for a services account
+e ~t:1440:~a:Account
* Allows someone to speak through +m for the next 24hrs:
+e ~t:1440:~m:moderated:*!*@host
* And any other crazy ideas you can come up with...
For example if you had:
set { restrict-extendedbans "a"; };
Then this would be rejected:
MODE #chan +b ~a:Account
However, you could still set:
MODE #chan +b ~q:~a:Account
Now this is properly rejected as well.
Fix case where conv_param() returns NULL (ban rejected)
causing is_ok() function not to be called so the user
never sees the error. We now try to call the is_ok after
conv_param returns NULL.
So not really an API change, more like a fix.
the WEBIRC gateway gives us some assurance that the
client<->webirc gateway connection is also secure (eg: https).
This is the regular WEBIRC format:
WEBIRC password gateway hostname ip
This indicates a secure client connection (NEW):
WEBIRC password gateway hostname ip :secure
Naturally, WEBIRC gateways MUST NOT send the "secure" option if
the client is using http or some other insecure protocol.
https://github.com/ircv3/ircv3-ideas/issues/12
In 3.2.x we didn't fix these bugs since servers are trusted and
should send correct commands. In 4.0.x we changed this so we would
fix them when we come across such issues at normal priority (not
consider them security issues). I now took it a step further and
actively checked/looked for these issues and a bunch of them were
found. Almost all are NULL pointer dereferences, with some exceptions.
* S2S: MODE: check conv_param return value (NULL ptr crash)
* S2S: MODE: floodprot: More checks (NULL ptr crash)
* S2S: MODE: OOB write of NULL (write NULL past last element in an array)
* S2S: NICK: old compat fixes (NULL ptr crash)
* S2S: PROTOCTL: Check for double SID=
* S2S: SERVER: require at least 3 parameters (NULL ptr crash)
* S2S: SJOIN: require at least 3 parameters (NULL ptr crash)
* S2S: SJOIN: Fix OOB read (read 1 byte past buffer)
* S2S: TKL: validate set_at and expire_at (NULL ptr crash)
* S2S: TKL: require at least 9 parameters for spamf, not 8 (NULL ptr crash)
* S2S: TKL: ignore invalid spamfilter matching type (remove abort() call)
* S2S: TOPIC: querying for topic is not permitted (NULL ptr crash)
* S2S: UID: require 12 parameters (NULL ptr crash)
* S2S: WATCH: this is not a server command (NULL ptr crash)
* Fix OOB read (1 byte beyond string) for timevals. This was reachable
from config code, TKL (S2S) and /*LINE (Oper). In practice no crash.
* MODE: make code less confusing (effectively no change)
* TRACE: remove strange output in case of 0 lines of output
* Fix unimportant memory leak on boot (#4713, reported by dg)
* Fix small memory leak upon 'DNS i' (oper only command)
* Always work on a copy in clean_ban_mask(). This fixes a bug that could
result in a strlcpy(buf, buf, sizeof(buf)). So, overlapping strings,
which is undefined behavior.
* API change for HOOKTYPE_PRE_INVITE:
(aClient *sptr, aClient *target, aChannel *chptr, int *override)
Modules must now send the error message instead of only returning
HOOK_DENY. Also check for operoverride and set *override=1.
This so modules can send their own error messages instead of the
default message being sent ("channel is +V" - which is not true).
Reported by Gottem (#5023).
2) Use 'iscc' rather than 'compil32' since the latter pops up a
dialog box which blocks the entire build process.
3) Apparently the VS2017 image has a broken VS2012 since it bails
on winsock.h. So try to use different images for both builds.
set::handshake-delay of 2 seconds by default. This will allow (most)
DNSBL checking to be finished before the user comes online, while
still allowing a smooth user experience.
If your DNS(BL) is slow then you could raise this setting slightly.
https://www.unrealircd.org/docs/Link_verification
This is only outputted if both sides are 4.0.16+ so we can use spkifp
and use the same instruction on both sides of the link.
(If we would do it for previous versions then we would only give
half of the instructions to the users, which makes no sense)
password "AHMYBevUxXKU/S3pdBSjXP4zi4VOetYQQVJXoNYiBR0=" { spkifp; };
This value will stay the same even for new SSL/TLS certificates,
as long as the key stays the same. This can be useful in case of
Let's Encrypt (if you use a tool that keeps the same key, that is,
certbot does not at the moment). Suggested by grawity (#5014).
Also make auth type 'sslclientcert' available as 'cert' and
make 'sslclientcertfp' available as 'certfp'.
There is now '/spamfilter del' which will output all spamfilter along with
the appropriate command to delete each spamfilter (by unique ID).
This way it should be easy for anyone to delete an existing spamfilter.
We also refer to this new feature from '/spamfilter', '/stats spamfilter',
etc.
places by spamfilters (and some other systems) to be placed not on *@ip
but rather on user@ip. Note that this won't work for ZLINE/GZLINE since
no ident/username lookups are done in such cases.
Bit of a niche feature but okay..
on the IP and thus result in an XX.YY.ZZ.IP cloaked host.
This so you can have "IP cloaking" without disabling DNS lookups.
GLINES on hosts still work and IRCOps (and yourself) can still see
the host in /WHOIS.
Requested in 4957 by Gottem and The_Myth.
and set::sasl-server is not set by the administrator. Looks like this:
*** Services server 'services.test.net' provides SASL authentication, good! I'm setting set::sasl-server to 'services.test.net' internally.
Hopefully this will increase SASL availability significantly.
That is, once anope and atheme start sending the saslmechlist to us,
of course ;) (see commit d6e26d59e5)
This so saslmechs are properly sent in case of services (re)connect,
otherwise the CAP NEW is sent too early when the saslmechs are
not known yet.
NOTE: This makes sending "EOS" mandatory for any SASL servers.
You should be doing this since 14 years ago (it was added
in 3.2beta18 in August 2003) so hopefully that is the case.
Anope is good anyway :)
Fix force-rejoin not working if doing SVSMODE -x/+x (Koragg, #5015).
Note to module coders:
Please use the following procedure in case of an user/host change:
* userhost_save_current(acptr);
* << change username or hostname here (or both) >>
* userhost_changed(acptr);
This function will take care of notifying other clients about
the userhost change, such as doing PART+JOIN+MODE if force-rejoin
is enabled, and sending :xx CHGHOST user host messages to
"CAP chghost" capable clients.
Also, small note to everyone:
If force-rejoin is enabled we will not send the PART+JOIN+MODE to
"CAP chghost" capable clients. Doing so is just a hack to notify
people of a userhost change. "CAP chghost" users can thus benefit
from the reduced noise in this respect.
would allow you to use -f even if the IRCd is suid or sgid.
This is not anything we or you ever want to permit since this is
a major security problem. This setting is now gone. I doubt
anyone used it.
You should always use https://www.unrealircd.org/ for stable releases.
In case you wondered what happened with 4.0.15: that version consists
of cherry-picked / backports of the two crash fixes from this 'unreal40'
development branch. The current code simply wasn't ready yet for a
rushed security release.
Delete CAP CLEAR as it's use is discouraged (too much trouble).
Delete CAP ACK (from client2server) as this is only for CAP's with
ack modifiers. This is something we don't use, and which has been
deprecated in v3.2 of the spec.
This permits multiple blocks like..
webirc {
mask *;
password "....." { sslclientcertfp; };
};
..should you need it.
In other words: we don't stop matching upon an authentication failure.
because so many people had a broken system/wget/curl, that is: without
the appropriate trusted CA certificates installed. If this is still
the case, then: too bad. People who DO have a proper setup shouldn't
be held back with regards to security by such users.
This so upcoming UnrealIRCd version will work with TLSv1.3 whenever it
becomes an official standard and is included in OpenSSL/LibreSSL.
(Verified to work with openssl git master branch)
to validate the certificate of the link, making sure that:
1) The certificate is issued by a trusted Certificate Authority (CA).
2) The name on the certificate matches the name of the link block.
Some things still need to be done: documentation, more testing, and
using the X509_check_host() function when available.
Nobody used this option and it only caused the following confusing
(and potentially insecure) behavior:
Previously if you had 'verify-certificate' enabled then the certificate
would be checked, BUT if it was a self-signed certificate (and thus
not passing verify-cert) it was STILL allowed unless you also
specified the 'no-self-signed' option. This might be correct as per
documentation but is way too confusing for the user.
Now you simply have to choose whether you verify the certificate or
not. No special handling for self-signed certificates.
connected to a server introducing himself as irc2.test.net. This
was rather confusing, of course. Wasn't much of a security issue since
this only happened in outgoing connects and naturally all authentication
need to pass as well.
This is done for users on shared IRCd shells[*] which may be used to (or
forced to) connect services via their alias IP rather than 127.0.0.1
due to bind restrictions. This, in turn, to ease the transition to
set::plaintext-policy::server deny.
[*] Side-note: The UnrealIRCd team recommends using a VPS and not a
shared shell, as the latter is considerably less secure.
* The 'ban too broad' checking was broken. This permitted glines such
as 192.168.0.0/1 being set. Now it rejects CIDR of /15 and lower.
To disable this safety measure you can (still) use:
set { options { allow-insane-bans; }; };
Docs: https://www.unrealircd.org/docs/Set_block#set::ssl::sts-policy::port
Example:
set {
ssl {
certificate "ssl/server.cert.pem";
key "ssl/server.key.pem";
sts-policy {
port 6697;
duration 180d;
};
};
};
IMPORTANT: Only use this if you know what STS is and what the
implications are. The most important things being A) set a correct
port and B) you need a 'real' SSL certificate and not a self-signed
certificate.
More documentation may follow at another place.
Module coders:
* The cap->visible(void) callback function is now cap->visible(aClient *)
* There is a new cap->parameter(aClient *) callback function.
* Various updates to subfunctions to pass 'sptr' (due to the above),
including clicap_find(sptr, ...)
* New CLICAP_FLAGS_UNREQABLE flag
Other:
* There is a new (src/)modules/cap directory containing the sts module,
well.. once I commit it :D
value needs to be much higher than the number of clients the IRCd
should be able to hold. The new value is 10k which should allow
at least 1-2k clients.
and at some other places (any place which uses the 'mask' system).
This allows things like:
deny channel { channel "#help*"; };
allow channel { channel "#help-nolan"; mask !192.168.*; };
allow channel { channel "#help-lan"; mask 192.168.*; };
Similarly in vhost blocks etc etc..
This so you can easily add allow/deny channel blocks for IP ranges.
Possibly not so useful for services-networks (ban/akick is very similar)
but has some use on serviceless networks.
For example: '+f [5j#i1,5m#m1,3n]:3' and then '+f [5j#i1,5m]:3'
In that case the '3n' was not removed and still effective, as
could be seen by a '/MODE #chan'. Reported by The_Myth (#4883).
[warning] Your server is not listening on any SSL ports. It is recommended to listen on port 6697.
[warning] Consider adding this to your unrealircd.conf: listen { ip *; port 6697; options { ssl; }; };
services software send this which cause a crash. Now simply rejecting at
the start of the function.
To services coders: you must maintain client lists/state, not do silly things
Note that they are NOT loaded by default at this time.
The modules are:
* extbans/textban - +b ~T:censor:*badword*
* usermodes/privdeaf - user mode +D: cannot receive PM's
* antirandom - "randomness" detector against drone attacks
* hideserver - hide servers (not real security, but requested)
* jumpserver - redirect users to another server during maintenance
* m_ircops - show which ircops are online (/IRCOPS command)
* m_staff - show custom file (/STAFF command)
* nocodes - don't just strip/block colors, do the same for reverse/bold/..
The existing README and sample configuration files for these modules
will later be added to the official UnrealIRCd documentation on
https://www.unrealircd.org/docs/Main_Page (just search on the module name).
This allows you to for example specify a specific certificate/key on an
serversonly port and in link block (a self-signed 10 year valid certificate)
and use a short-lived (XX day) Let's Encrypt certificate on the other ports.
And several other uses, of course.
so you can use IRC directly from HTML5/JS. It is still considered experimental
but feel free to test it out. To do so, add this to your unrealircd.conf:
loadmodule "websocket";
This module was sponsored by Aberrant Software Inc.
Previously <= 0 would stop processing. Now this has changed to:
>0: continue and parse as-is (this was already the case)
0: don't parse but continue reading next packet (if there's any data)
-1: stop parsing, don't read any packets (client may be killed/FLUSH_BUFFER)
Services coders: you can now set "SVSMODE Nick +d" to set the 'deaf' user
mode. Note that "SVSMODE Nick +d svsidhere" also still works. This should
be a harmless change, unless some services packages are accidentally trying
to set emtpy svsids like "SVSMODE Nick +d "... if you do, then the target
nick will be deaf now..
Only build main binary with -fPIE, not the modules. It's called Position
Independent EXECUTABLE after all. And apparently not all compilers or
linkers ignore the option if building shared objects (mine did..).
as it is the default in 4.0.8+. However, it shouldn't break the build if
specified. Fixed damn silly reversed logic at a few places that caused this...
We now set LDFLAGS during configure with -Wl,-rpath=/home/xyz/unrealircd/lib so
the curl test won't fail (or more precisely, curl's c-ares test).
Could theoretically fix other issues as well, but could not reproduce.
First of all, system-wide curl is much preffered, but if not available
then UnrealIRCd will offer to install curl for you during ./Config.
The prompt looks the same as before but we no longer install the curl
library in ~/curl but rather in ~/unrealircd/lib (or wherever you put
your installation).
Basically, it now behaves exactly the same as c-ares, TRE and PCRE.
Downside: curl will be re-compiled each time you re-run ./Config
Upside: curl will be re-compiled each time... :D.. will thus be kept
more up to date.
**
Also: complain if <curlinstall>/bin/curl-config cannot be found.
This ensures we error after ./Config rather than after the whole of
configure has been ran.
then change the default value to /usr (or similar) during ./Config and
output a warning.
We do this since system-wide cURL is under almost all circumstances
preferred as it is maintained by your OS/distro and hence receives bug
fixes and security updates on a regular basis (or should, anyway).
Experience shows that ~/curl is rarely kept up to date since "it works".
In the past, many years ago, system wide cURL did not have AsynchDNS.
Nowadays nearly all distros build cURL with some sort of AsynchDNS
which makes things much more useable.
this on the basis that cURL may be using one c-ares version and UnrealIRCd
another c-ares version, something which obviously can lead to failure due
to ABI differences..
Many years have passed since then and cURL is now frequently build with
AsynchDNS support but without the help of c-ares (eg: on Debian). We can
support this configuration without requiring --with-system-cares since
c-ares is not used by cURL and there's no conflict.
options by default. This enables full RELRO (GOT and PLT being read-only),
stack protection and address space layout randomization (by enabling PIE,
the actual ASLR is left up to kernel).
Will cleanup some silly stuff later.. and have a go at the libs stuff..
code clutter and was broken anyway (especially CHROOTDIR)...
For a CHROOTDIR replacement we suggest using AppArmor, SELinux, FreeBSD jails, ..
For a IRC_USER/IRC_GROUP replacement you can use start-stop-daemon or similar.
Accepted values are: All (enable all), TLSv1, TLSv1.1, TLSv1.2
You can use + and - modifiers, in fact you are encouraged to.
Example: set { ssl { protocols "All,-TLSv1,-TLSv1.1"; }; };
This will only allow TLSv1.2 at time of writing, and later whenever
TLSv1.3 is released it will allow TLSv1.2 and TLSv1.3.
Note that 'SSLv2' and 'SSLv3' do not exist, as UnrealIRCd 4.x never
supported these old versions (and never will).
Tech: MODE_EXCEPT and MODE_INVEX and had a parameter=0 count in cFlagTab
causing parse_chanmode() not to eat the 'e' and 'I' parameters. Thus
causing the wrong parameter (target) to be returned by parse_chanmode().
users didn't read and close the error screen. Instead they hit the "rehash" command
from the sytem tray and this would crash UnrealIRCd. From now on if you do that a
messagebox will show up saying you should pay attention to the error screen ;)
Fix SQUIT documentation, send ERR_USERSDONTMATCH when trying to change modes for other users, fix some typos, remove old HTM stuff. Resolves#2549, #3691 and more.
Tizen, DBoyz and Valdebrick helped tracing the issue.
Removed MATCH_USE_IDENT since it had no useful purpose.. for all cases one has to check identd first and then non-identd anyway.
* Updates to make UnrealIRCd use LibreSSL
* Fix HTTPS support in cURL
* Forgot to ship curl-ca-bundle.crt
(Note: all 3 points from above only affect Windows)
2) link::outgoing::bind-ip is an IPv4 address, and
3) link::outgoing::hostname is a hostname, and
4) this hostname has both A and AAAA records,
then connect by IPv4 only, which is what the user expects (#4615).
The user is not 'registered' yet at this point, so manually inform
services of their IP address (the syntax is "H <realhost> <ip>").
Services might use this when informing the user of failed auth attempts,
or when ratelimiting bruteforce.
Patch used only with minor changes: one %i should have been %s, some annoying (char *) casts removed which existed in the original code as well, moved 'tmp' variable, collapsed NULL initalization, ..
There were a few flaws in the code: 1) it should close the listener on /rehash,
shouldnt't matter if there are clients or not, 2) then there was a bug where it
would properly close the listener but it would be re-opened by add_listener2.
Also added a "IRCd no longer listening on .." message if you remove a listen block.
You can still see the full list of loaded modules by using "/MODULE -all".
Also fix /MODULE <server>, this was broken in earlier versions by nen.... you know who.
extban +e/+I ~S:xxx worked fine (only checked locally). But this also prevented services from being
informed, IOTW: services could not make use of this new certfp feature yet.
When a user is shunned (eg /tempshun user ), the command PING cannot be used (PONG can so answer server PING).
Some clients like irssi are using PING command to compute the server lag, so when an irssi user is shunned, the lag displayed in irssi start ton increase, giving a way ton know if he is shunned.
After 320 sec of lag, irssi will reconnect, bypassing automatically the tempshun.
This resulted in 5-10 changes in the existing code where parameters were off.
Hopefully I didn't make too many mistakes when writing the hook prototypes as it was a tedious job.
An (unintentional) benefit of this new system is that you can see the hook prototypes in include/modules.h like:
/* Hook prototypes */
int hooktype_local_quit(aClient *sptr, char *comment);
....
Though, the wiki is likely a better place: https://www.unrealircd.org/docs/Dev:Hook_API
PROTOCTL EAUTH=servername,protocolversion,flags,unrealversiontext
This makes deny link { } work again and gives a bit more information too.
Bug reported by GLolol (#4408).
AUTH is a valid nickname so sending notices to it is probably not
a good idea. Use * as the target instead as done with numerics
when the nick is not available.
This mimics the behaviour in Charybdis, IRCD-Hybrid, InspIRCd 2.2,
Plexus 4, etc.
Re-implemented PROTOCTL SERVERS= which nenolod ripped out (#4355).
Add 2nd argument to PROTOCTL EAUTH=servername,unrealprotocol
Change UnrealProtocol from 2350 to 2351
No UnrealIRCd code reads from parv[0] anymore.
Perhaps later, after a few stable versions, we'll turn this into something more useful. Or not. But not soon.
Added swhois_add / swhois_delete functions which also take care of broadcasting
New remove_oper_privileges() function, will move the rest to use this (svsnoop svsmode etc)
Not finished yet...
Change MOD_TEST/MOD_LOAD/etc macro's (this breaks all modules). Now just use this:
MOD_INIT(modulename)
{
// you can access modinfo here.. or other stuff...
}
(Similar to the CMD_FUNC() macro)
Rather than:
DLLFUNC int MOD_INIT(name)(ModuleInfo *modinfo)
{
//...
}
with a default of 3:90 (3 joins per 90 seconds). There's rarely any need
to configure this on a per-channel basis and this way it's enabled by
default for everyone (unless you decide not to load load the module)
easily deal with "parameter eating" of unknown channel modes.
Now, 12 years later, finally added the code to do this.
This prevents some (serious) desynching if you have a parameter-eating
channel mode on one server and not on the other.
Obviously, you should always try to have the same featureset on all
servers, but sometimes this is not possible, like when upgrading..
Will still manage UnrealIRCd as a pref pane probably and system service, but should have an agent present so it's easier to admin when you're _logged in_
2) Call DNS routines more often, not just once per second.
2) Slightly lower the DNS timeout, max 2500 + 5000 = 7500ms now. Previously was 3000 + 6000 = 9000ms.
* remove netadmin, services-admin, admin, co-admin.
* remove all oper flags (there are some placeholders for the next... <24hrs..)
* ADMINCHAT and NACHAT are gone, since admin & netadmin no longer exist
* SVSO used oper flags, but this no longer exists, SVSO removed. maybe later we can add some sort of replacement.. maybe..
* re-style the m_oper code a bit
Not totally tested - I validated it built, I validated ACL validation worked, I validated that most of the ripped out functionality seemed to be absent, eg: we still set the modes (backwards compat w/ services?) but we don't actually check them anywhere, or add them to your whois.
Also make the '?' and '!' prefixes in channels in /WHOIS output more generic:
both mean you only get to see the channel because you are an ircop, but:
'?' means the channel is +s/+p too (so take extra care)
and '!' means the channel is public but for other reasons hidden in /WHOIS, like umode +p (later) or umode +S.
* detect "ircd not running" situations better
* ./unrealircd stop now kills the ircd in a more friendly matter.
* if you run './unrealircd restart' it will now also start the ircd even if it was not presently running.
Apparently neno.. ripped out this code so you could like run './unrealircd
start' 5 times and would then have 5 ircds running, of which 4 were not doing
particularly useful things.
Rather than just stating the error, we now also tell the user what to do.
* Change many configuration parse warnings into errors as this is (much)
more helpful to the user since the config file isn't going to load
properly anyway. Any subsequent 'missing xyz block' errors are not
shown on parse errors. That's good as they are often just missing
because of the parse errors so such errors would be confusing.
* Fix upgrade-conf strange behavior on \\ and \" in spamfilters. Was
actually caused by config parser (and not the updconf code).
* Remove .tmp file file which may be left if we crashed during upgrade-conf
Original file is (of course) backed up as .conf.old.
Currently handled changes in this upgrade: loadmodule, me, link, throttle, spamfilter, allow, vhost, oper.
I think those are all right now. Please report any failures / strange issues on bugs.unrealircd.org
Coders: added generic mask functions: unreal_mask_match(), unreal_add_masks() and unreal_delete_masks().
These deal with one or multiple masks and do all the work for you ;)
Still requires module and core hooks to be added, config test to be added, and to require these for perm validation - this enables core parser and querying of system though
* add general matching framework (aMatch type, unreal_match_xxx functions)
* change spamfilter { } block syntax
* add support for simple wildcard matching (non-regex, just '?' and '*')
This is the initial commit so the new lib is not in yet, 'regex' is not
functional (but 'posix' and 'simple' are working), linking has not been
fully tested and no warnings are printed yet. IOTW: work in progress!
you want to permit re-loading but not complete un-loading of your module.
This way you get the benefits of being able to upgrade code on-the-fly but
can still disallow the user to do something potentially unwise.
For services who allow you to log in by account name but still allow you to
use a different nick: when you're logged in you are now considered
registered as far as channel mode +M (only registered users may speak and
+R (only registered users may join) are concerned. Same for user mode +R
(only allow private messages from registered users).
Tech: whenever services set SVID and it's not * and does not start with a
number, then we consider this user to be 'logged in'.
Whenever a user is set +r (s)he is also considered 'logged in'.
This way it's compatible with both older and new services and doesn't
introduce security issues with older services using servicetimestamp
for nick tracking or other means.
This issue was reported by ShawnSmith (#4318).
1) No arguments: UnrealIRCd will prompt you to enter a password and hash
it with the bcrypt algorithm. This is the recommended method.
2) One argument: It will hash the provided password with bcrypt
3) Two arguments: It will use the hashing algorithm of your choice (1st arg)
to hash the provided password (2nd arg)
We recommend to use syntax #1 as bcrypt is the best algorithm available and
by using the prompt the password won't end up in your bash history (or
whatever shell you use) and can't be snooped by other people with a shell
on the same machine (by looking at the process list)
Now you can just add password "$ZaJw56to$uSEc[etc..]"; to your configuration file without needing an explicit { md5; }; or { sha1; };.
Naturally you can still specify an auth-type if you want to, and for types like 'sslclientcert' it's still required.
We no longer support builds without OpenSSL - consequently we have no reason to keep our custom MD5 implementation, and probably shouldn't keep it around
Parsing of commands based on permissions was incorret - if a command was not a user facing command explicitly, it would be denied for a user, furthermore if it was a server issuing the command, and it also was an oper command, it would be denied for similar reasons - corret parsing now in place.
Modules that take parameters to chanmodes cannot be unloaded at this time, we probably want to investigate adding this capability in the future so we can do dynamic updates of those modules
Modules or other resources could call ircd_log even if we are not fully booted, and we need to not fail in that situation, instead we should just emit the same warnings we usually do.
Not sure how this was supposed to originally work, if the sid is changed
the uid generator is not re-initied, and even if it was it would allow
id collisions if it ever uplinked to another ircd with the old id it
had.
I see no reason for this.
Not sure what this originally was supposed to do, but clicap_find is
normally called multiple times per cap request per client, so this makes
no sense at all.
structs such as Client, Channel, Member and Membership.
- Modules that define channel modes no longer need to be permanent. This
was already true for paramless chmodes, but is now true for all.
- Converted floodprot module (chmode +f) to use MoData. This means some
remains could be purged from the core and the module is now fully
reloadable (no longer permanent).
- This code is experimental, but seems to work...
By default this is set to 'yes' which means that once a spamfilter matches
UnrealIRCd will take action immediately and any additional (other)
spamfilters will not be processed.
When this is set to 'no' then after the first spamfilter match other
spamfilters will still be checked. All of these matches will be logged and a
message will go to IRCOps (snomask +S) for each one. The affected user,
however, will only see one spamfilter action (eg: block or kill) which will
be the spamfilter with the 'gravest action' (gzline is highest, block and
warn are lowest).
- Update example config for pending commands.so removal. (r0cb592422175)
- Implement support for TCP_DEFER_ACCEPT (synflood-hardening). (#4096) (r2ea87de39063)
- remove global flag from oper block as it is implied by netadmin. (#4092) (r491e69c8ede6)
bind to (for example) the loopback interface before connecting to the
remote server.
In addition to that, we now don't bind() at all when bind-ip is not
present or is set to "*".
While here, add a function to mark a range of characters as OK, and close
a possible integer underflow bug in the character attribute code.
Character tables derived from Atheme libguess.
This is technically in violation of RFC1459, however the general consensus
at the IRC3 discussion meetings is that it's the numeric which actually matters.
DH parameters files must be encoded in PEM format, and the path is
set using the ssl::dh config setting. This is based on a patch
submitted by wolfwood, with some modifications to avoid using stdio
unnecessarily and to avoid code duplication.
Instead, run check_tkls() when TKL changes are made directly.
While this is technically slower when more than one TKL is placed
at once, the value of getting it out of the check_pings event is
greater.
This is partially for the sake of Stskeeps, even though he left the
project long ago, but mainly so we can work towards dynamic ticks in
the event loop while guaranteeing latencies for connected clients,
even with fakelag.
are neither read nor write means that c-ares is no longer interested in the
socket. Thusly we unregister it. This is probably wrong, but it seems to
work fine.
With this change, it is possible to completely disconnect read_message() from the mainloop,
and have a fairly responsive ircd (noticably more responsive than what we had before I
started on this).
The "fakelag" stuff has been replaced with charybdis's deferred command processing logic,
which is more efficient and does the same thing without punishing behaving clients.
- Rename Changes to Changes.old
- In the Mercurial repository the Changes file no longer exists (except
for a dummy file). You now need to run ./createchangelog to generate it.
Of course in official releases the Changes file will be present and
contain all details.
- From now on, the Changes file is based on the history of the Mercurial
repository. This means we no longer have to write text manually to the
Changes file. This simple change helps a lot in future development
because patches will no longer break when they are being ported from
one branch to another.
unreal32docs.gr.html (outdated since 2006-12-02), and
unreal32docs.nl.html (outdated since 2009-01-18, possibly 2007-07-12).
These translations are out of date for many years and are causing
problems for the people who are reading this out of date information.
If you want to update these translations, or (maybe better) redo
the translation of unreal32docs in these languages, then send an
e-mail to syzop@unrealircd.com.
Note that for all these languages we have had people in the past
offering to help out, but in the end we never heard back from them,
so please ONLY contact us if you: 1) are serious, and 2) have
sufficient time available to work on this project.
That said, users in your language will greatly appreciate your work!
Of course, if you want to translate documents in any other language
then you are welcome to contact us as well.
method to authenticate users with SSL client certificates based
on SHA256 fingerprints. This can be used instead of the already
existing 'sslclientcert' so you don't have to use an external file.
One way to get the SHA256 fingerprint would be:
openssl x509 -in name-of-pem-file.pem -sha256 -noout -fingerprint
Suggested and patch supplied by Jobe (#4019).
- Added documentation on the new sslclientcertfp
- Moved documentation on authentication types to one place and refer
to it from each section (oper::password, vhost::password,
link::password-receive, etc).
- Disable USE_POLL on Windows, since it doesn't work with XP and has
no advantage anyway. Reported by nenolod (#4129).
- Various updates to makefile.win32 and .iss file, found during
building new versions of zlib, openssl, and curl.
Any attempt to /OPER by someone who doesn't have one of the listed
usermodes is rejected. This can be used to restrict oper blocks to
registered nicks (+r) or secure clients (SSL, +z).
server.cert.pem exists, and check it if the file doesn't exist.
You can still change the setting, just the default is correct now.
The code for this was already there but was not working correctly
causing users to go through the generation process upon each install.
If this is not set, then SASL is off and not advertised.
If the specified server is not connected, then SASL is off as well.
This prevents unnecessary delay (and the inability for some clients to
get online) when SASL is not in use or when the SASL server is down.
This allows the IRCd to enforce MLOCKs that are set by services, which
eliminates clashes between users setting modes and services enforcing
it's mlock on channels. (#3055)
queued data on the receive queue (eg: due to fake lag) was not processed
unless we got new data from the client.
Now, better document this. Also, avoid calling dbuf_put with 0 length.
goes to the boot screen. When we are already booted it's sent to all
IRCOps with a limit of max. 1 message per 5 minutes.
- Refuse to boot when we can't write to any log file.
vmakebuf_local_withprefix. Then use this new function - which creates the
buffer-to-be-sent - at the top of functions like sendto_channel_butserv
and sendto_common_channels and send the prepared buffer in the loop that
comes after it. This means we only prepare the buffer once and then send
it many times, rather than both building and sending it XYZ times.
Benchmarking connect-join-quit of 10k clients:
100 users per channel: no noticeable speed improvement
1000 users per channel: 18% faster
10000 users in one channel: 50% faster
As you can see, unfortunately, for a typical irc network there isn't much
speed improvement. However, if you have a couple of 500+ user channels or
get attacked by clones then you may see some improvement in speed and/or lower
CPU usage.
- UnrealIRCd now supports poll() instead of select().
There are some minor speed benefits if you have more than 1K or 2K
clients, however the main noticeable difference is that on Linux you can
now easily enter a higher maximum connection count than 1024 in ./Config,
without having to edit system header files.
Of course, you still need to be allowed to use the # of sockets (type
'ulimit -n' on the shell).
Support for this is experimental at this stage, but enabled by default
so it can receive all the testing it deserves. If all goes well, it will
be the default for 3.2.10.
Stress testing is very much welcomed!
* use get_client_by_pollfd() function instead of pollfd_to_client[]
directly, so we can easily find and debug any mistakes.
* add some commenting
* add extra debugging and core dumping if fd or slot values are out of bounds
* fix race condition in read_authports() where send_authports() 2 lines up
could have closed the socket, resulting in a read from fd -1.
NOTE: I've updated the select (non-poll) code as well, should be harmless.
* move all (re-)initalization to reset_pollfd(), i'm
much more comfortable with that as it aids debugging a lot.
* add parenthesis.
update my own fd check code for poll support
on OpenFiles to be correct. This fixes a crash when f.e. 3rd party modules
have files open but don't increase OpenFiles. Might also fix a curl crash,
though nobody ever reported one.
and ensures that the user does not have any ircop-only user modes after
de-opering. This (only) fixes the just added +I umode case, but could
also prevent future bugs.
Now the UNREAL_VERSION_GENERATION, UNREAL_VERSION_MAJOR,
UNREAL_VERSION_MINOR, and UNREAL_VERSION_SUFFIX macros are
autogenerated from PACKAGE_VERSION.
now store a string (of max NICKLEN size) as service stamp. See
protoctl.txt and serverprotocol.html in doc/technical for more
information.
Patch from nenotopia (#3966).
connection was never actually sent (due to buffering). Hence, things like
the /SQUIT reason was never seen on the other side (just 'server closed
the connection'). This has now been fixed.
- Win32: Attempt to move to 100% winsock2 (the include, to be precise),
this means includes have to be in a very particular order (!)
- Win32: #define _WIN32_WINNT 0x0501 and force our own inet_ntop/pton,
otherwise you get an ntop runtime error on XP and earlier.
- Win32: Get rid of c-ares includes and library in our tree, and use the
DLL instead of static LIB, just like we do for ssl and zlib.
- Win32: Get rid of TRE lib and includes
- Win32: reorder includes to fix winsock errors with curl
mysterious error 'The specified module could not be found' even though the
file exists. This usually means that it depends on another DLL, but
apparently Microsoft decided not to mention that in the error message.
We now append some small text when such an error happens, saying that it
could be because of a missing dependency. Reported by Phil.
and ZLINE) and 'except tkl' (which can exempt from GLINE, GZLINE, SHUN,
QLINE, GQLINE and SHUN). Reported by Digerati (#0002535).
- Added except tkl::type 'all', which exempts from all TKL types (except
KLINE).
network. You can also specify options like '/REHASH -global -motd' to
rehash only the MOTD/RULES/etc. Just like /REHASH <servername> this is a
NetAdmin-only command. This command is fully backwards compatible with
older UnrealIRCd version in the sense that it will also REHASH old
Unreal's. Suggested by 'P' in #0001522.
'install as service' and 'encrypt SSL certificate', as they are
incompatible (a service cannot ask a user to enter a password).
- Win32 installer: Fixed long outstanding problem with some Vista / Windows 7
installations, which has to do with file permissions of the Unreal3.2
folder. Symptoms were error messages such as:
Unable to create file 'tmp/10D9D743.commands.dll': Permission denied
But also failing to create SSL certificates, nothing being logged, etc.
This is now fixed by setting write access on the Unreal3.2 folder to the
user running the install, unless the user chooses not to use this new
option (it can be unchecked), in which case the user is warned that he
should take care of this himself.
Reported by various persons, special thanks to Bock and goldenwolf for
helping us to track down this issue (#0003943).
- Some small updates to the extended channel mode system: it now has minimal
support for 'local channel modes'. This is really only meant for channel
mode +Z (upcase z), see next.
- Added Channel Mode Z which indicates if a channel is 'secure' or not.
This mode works in conjunction with +z (lower case z).
If +z is set ('only secure users may join'), then the IRCd scans to see
if everyone in the channel is connected through SSL. If so, then the
channel is set +Z as well ('channel is secure').
Whenever an insecure user manages to join, the channel is -Z. And whenever
all insecure users leave, the channel is set +Z.
The 'insecure user being present in a +z channel' can be because:
- An IRCOp joined the channel, and he's not secure
- When servers link together and a user on the other side is not secure
This only happens on net merge (equal time stamp).
On different time stamp, we still kick insecure users on the new side.
- At the time when +z is set, there are insecure users present.
This feature was implemented after a heavy discussion in bug #3720 by fez
and others, and was suggested by Stealth.
Tech note: +Z/-Z is handled locally by each server. Any attempt to
remotely set +Z/-Z (eg: by services) will be ignored.
- As mentioned above, +z can now be set even if any insecure users are
present. Previously, this was not permitted. Now, as soon as the last
non-SSL user leaves, the channel will be set +Z.
- An oper not connected through SSL previously had to /INVITE himself
to a channel and then /JOIN the channel with the key 'override'.
This 'override' key is no longer required, a simple JOIN will suffice.
- Sorted channel modes in /HELPOP ?CHMODES
- Re-enabled 'fishy timestamp' errors in MODE. For some reason this was
commented out, even though the (more annoying and less useful) code in
JOIN was enabled so that did not make a lot of sense. It also now logs to
ircd.log (or whatever you configure). This enables people to easier find
the cause of any timestamp issues (which usually is badly coded services).
commands.so. This module was written to help IRCd maintainers deal
with some sort of ``XPS'' attack in which javascript-initiated HTTP
POST form submissions were able to act as dummy IRC bots. These
simple bots were the cause of much spam. (#3893)
- Add a modules section to the documentation. This was created to put
all documentation specific to the m_post module in one, easy to find
place. The documentation on m_post is likely incomplete, however.
- Added support for "stacked" extbans. Put simply this allows extban combinations
such as ~q:~c:#test to only silence users on #test, for example. This feature
is enabled by default, but can be disabled during ./Config -advanced.
This feature was suggested by Shining Phoenix (#0003193), was then coded
by aquanight for U3.3, and later on backported and partially redone by Syzop.
Module coders:
In an extban ~x:~y:something where we call ~x the 1st, and ~y the 2nd extban:
Since stacked extbans only makes sense where the 1st one is an action
extended ban like ~q/~n/~j, most modules won't have to be changed, as
their extban never gets extended (just like ~c:~q: makes no sense).
However, you may still want to indicate in some cases that the extban your
module introduces also shouldn't be used as 2nd extban.
For example with a textban extban ~T it makes no sense to have ~n:~T.
The module can indicate this by setting EXTBOPT_NOSTACKCHILD in
the ExtbanInfo struct used by ExtbanAdd().
For completeness I note that action modifier extbans are indicated by
EXTBOPT_ACTMODIFIER. However, note that we currently assume all such
extbans use the extban_is_ok_nuh_extban and extban_conv_param_nuh_or_extban
functions. If you don't use these and use EXTBOPT_ACTMODIFIER, then things
will go wrong with regards to stack-counting.
Module coders should also note that stacked extbans are not available if
DISABLE_STACKED_EXTBANS is defined.
- Added extended ban ~R:<nick>, which only matches if <nick> is a registered
user (has identified to services). This is really only useful in ban
exemptions, like: +e ~R:Nick would allow Nick to go through all bans if he
has identified to NickServ. This is often safer than using +e n!u@h.
- Added Extended Invex. This is very much like extended bans, in fact it
supports some of the same flags. Syntax: +I ~character:mask
Currently supported are: ~c (channel), ~r (realname) and ~R (registered).
This can be useful when setting a channel invite only (+i) and then
setting invite exceptions such as +I ~c:#chan (or even ~c:+#chan), while
still being able to ban users.
Because action modifiers (~q/~n/~j) make no sense here, extended invex
stacking (+I ~a:~b:c) makes no sense either, and is not supported.
Suggested by DanPMK (#0002817), parts based on patch from ohnobinki.
Module coders: set EXTBOPT_INVEX in the ExtbanInfo struct used by
ExtbanAdd() to indicate that your extban may also be used in +I.
- Invex (+I) now always checks cloaked hosts as well. Just like with bans,
it checks them also when the user is not currently cloaked (eg: did -x, or
is currently using some VHOST).
- Fixed client desynch caused by (un)banning, reported by Sephiroth (#2837).
two groups: one that specifies ban actions (~q/~n/~j) and one that
introduces new criteria (~c/~r). Also added documentation for ~R which
does not exist yet, but will soon...
- Added information about ``oper::password::auth-type sslclientcert'' and the same for link::password-receive::auth-type. (#3133)
- A little bit more of interlinking and using id="" instead of <a name="" />
curl version is new enough and is not using a c-ares which is binary
incompatible. If the self-compiled curl version is (too) outdated, then we
now suggest to rename it and have the installer re-download and compile
it automatically. This avoids some potential crashes.
was not compiled with c-ares, which is clearly a bad idea as then the
entire IRCd can hang for several seconds or more...
We now check if they support asynch DNS, and skip them if they don't.
- Separate m4 macros into *.m4 files (it is much easier to run aclocal now).
- Remove unused DOMAINNAME macro and --with-hostname= options as the DOMAINNAME macro isn't used anywheres and its use shouldn't be encouraged.
- autogen.sh to bootstrap the buildsystem. We now maintain setup.h with autoheader.
- --disable-blah now does the opposite of --enable-blah. The same for --with-blah and --without-blah. (This makes Gentoo users happier).
- Remote MOTD support. Not adequately tested. Required restructuring of the asynchronous download callback and handler.
- Added some consts throughout url.c, etc.
- Fix segfault where the an include directive specifies a URL and cURL follows redirects, resulting in a different resultant URL. The remote includes code would look for the an include block using the resultant URL and assume that it would be found. The new code searches differently, has new checks, and ignores the resultant URL.
- Removed duplicated m_motd() and friends that were both in modules and s_serv.c. The copies in s_serv.c (core) were overriding the in-module functions.
- IPv6: it seems some recent Linux dists decided to make IPv6 sockets
IPv6-only, instead of accepting both IPv4&IPv6 on them like until now.
FreeBSD (and other *BSD's) already did that move a few years back,
requiring server admins to sysctl.
We now make use of a new option to explicitly disable "IPv6-only".
This should work fine on Linux.
Whether it provides a complete solution for FreeBSD, I don't know, testing
is welcome! In theory setting net.inet6.ip6.v6only to 0 should no longer
be needed, but you might still need to enable ipv6_ipv4mapping.
- Fix stupid issue where current CVS would no longer link TO an earlier
Unreal server (eg: outgoing connect to a 3.2.8 hub). Reported by ohnobinki
(#0003901).
against HTTP POST proxies, now added some extra text to say it also
protects against the Firefox XPS IRC Attack. Also made NOSPOOF enabled by
default on *NIX (this was already the case on Windows).
- Updated ./Config description for DPATH. Seems quite some people answer
this question wrong, and when that happens, you only get some obscure
error when running './unreal start'.
- Fixed 'unreal' script to give a better error if it cannot find the IRCd
binary.
Previously this caused some really odd behavior. Backslashes are now
treated as-is, so no special escaping is necessary. Reported by DelGurth
(#0003002).
- Removed old dgets() function
redundant and confusing. Also removed an old statement saying k-lines would
be erased on rehash which is not true. Documented '/rehash -dns'.
Reported by ohnobinki (#0003881).
curl detection, added checks to see if curl actually works (print out a
clear curl error during configure, instead of getting an error during
'make'), and we now error when using --enable-libcurl without
--with-system-cares if the system curl depends on c-ares. This is because
this can cause ABI incompatability between curl's c-ares and our c-ares,
which leads to odd issues such as:
Could not resolve host: www.example.net (Successful completion)
And possibly other weird issues, perhaps even crashes.
it to 'no', the default is 'yes' (on). Requested by Robin (#0003885) as
UHNAMES may increase the time of the nick list being loaded from 1 to 4
seconds when joining several channels with more than 1000 users. As this
problem is only present on some networks, we keep UHNAMES enabled by
default.
descriptors. Because of this, Unreal did not restart properly as you would
get an "Address already in use" error. This only seemed to happen when
logging to syslog, or when there was something wrong with syslogd.
Reported by Mouse (#0003882).
descriptors. Because of this, Unreal did not restart properly as you would
get an "Address already in use" error. This only seemed to happen when
logging to syslog.
- Fixed a similar issue with syslog (and debugmode) and closing fd's as well:
the first port we listened on would not open up, ircd did not log any error.
- Made ./Config description about remote includes a bit more clear.
- When you now answer Yes to Remote includes in ./Config and $HOME/curl does
not exist, it now asks you if you want to automatically download and
install curl (which is done by ./curlinstall).
This has been tested on Linux, further testing on f.e. FreeBSD is
required.
- Server protocol: added PROTOCTL EATH=servername, which allows us to
authenticate the server very early in the handshake process. That way,
certain commands and PROTOCTL tokens can 'trust' the server.
See doc/technical/protoctl.txt for details.
- Server protocol: between new Unreal servers we now do the handshake a
little bit different, so it waits with sending the SERVER command until
the first PROTOCTL is received. Needed for next.
- Server protocol: added PROTOCTL SERVERS=1,2,3,4,etc by which a server can
inform the other server which servers (server numeric, actually) it has
linked. See doc/technical/protoctl.txt and next for details.
- When our server was trying to link to some server, and at the same time
another server was also trying to link with us, this would lead to a
server collision: the server would link (twice) ok at first, but then a
second later or so both would quit with 'Server Exists' with quite some
mess as a result. This isn't unique to Unreal, btw.
This happened more often when you had a low connfreq in your link blocks
(aka: quick reconnects), or had multiple hubs on autoconnect (with same
connfreq), or when you (re)started all servers at the same time.
This should now be solved by a new server handshake design, which detects
this race condition and solves it by closing one of the two (or more)
connections to avoid the issue.
This also means that it should now be safe to have multiple hubs with low
connfreq's (eg: 10s) without risking that your network falls apart.
This new server handshake (protocol updates, etc) was actually quite some
work, especially for something that only happened sporadically. I felt it
was needed though, because (re)linking stability is extremely important.
This new feature/design/fix requires extensive testing.
This feature can be disabled by: set { new-linking-protocol 0; };
having to use a special SSL-only port, they can simply switch to SSL on
any port. This is currently only supported by few clients (such as KVIrc 4).
This functionality can be disabled by setting set::ssl::options::no-starttls,
for example if you don't want to offer SSL to your users and only want it
to be used for server to server links.
Naturally, the IRCd must be compiled with SSL support for STARTTLS to work.
- Fixed SSL_ERROR_WANT_READ in IRCd_ssl_write()
such as ~q:~c:#test to only silence users on #test, for example. This feature
is enabled by default, but can be disabled during ./Config -advanced. Module
support for this feature must note the following:
- For is_ok function, the extban can either assign extban_is_ok_nuh_extban, which
will deal checking a chained extban (including checking for restricted extbans),
or it can call that function from its own is_ok routine. For the latter case,
remember to pass only the mask part of your ban format (ie, don't just pass para as
otherwise it'll just call your is_ok again).
- For conv_param function, the extban can either assign extban_conv_param_nuh_or_extban,
which will automatically call conv_param for a chained extban, or pretty up a n!u@h mask.
- For is_banned, the extban should call ban_check_mask with the mask part of the parameter.
This will automatically call is_banned for a stacked extban, or match against a n!u@h. n!u@h
is checked against the current user (ie, with the info in the globals ban_ip, etc), so things
can get weird if you call this outside a normal ban check.
Modules must keep in mind that chained extban support is not available (and neither are the three
functions above) if DISABLE_STACKED_EXTBANS is #defined (this is controled by Config). Modules will
not compile/load if they try to use them anyway.
This change should not break extban modules, and should need some more extensive testing.
- Misc fix for disabling extban chains, should've done stuff in our autoconf
stuff instead of hacking configure directly :P .
load (for example when the webserver is down), then the most recent
version of that remote include will be used, and the ircd will still boot
and be able to rehash. Even though this is quite a simple feature, it
can make a key difference when deciding to roll out remote includes on
your network. Previously, servers would be unable to boot or rehash when
the webserver was down, which would be a big problem (often unacceptable).
The latest version of fetched urls are cached in the cache/ directory as
cache/<md5 hash of url>.
Obviously, if there's no 'latest version' and an url fails, the ircd will
still not be able to boot. This would be the case if you added or changed
the path of a remote include and it's trying to fetch it for the first time.
To disable this new behavior, check out REMOTEINC_SPECIALCACHE in
include/config.h.
(HOOKTYPE_PACKET). Replacing the 'text to be sent' to a client is
supported, which allows character(set) conversion in a module.
Note that modifying an incoming message by the hook is not supported.
from not binding to that ip when linking, to not being able to link at
all. Also fixed a very small memory leak upon /REHASH. Bug reported by
Mr_Smoke (#0003858).
timesynch) made autoconnect not work for the duration of the offset
(eg: -60 would make autoconnect wait 60 seconds after boot, instead of
autoconnecting almost immediately). Reported by aragon (#0003853).
* And force the use of at least the version shipped with Unreal
* (or at least one without known security issues).
*/
this text is fcked btw.. whatever...
printed out as a warning, when in fact it's an error (and was treated as
such). Same for ZIP on non-zip compile. Reported by Stealth (#0003833).
..& updated credits..
- When pkg-config is present but does not recognize --static, use
default c-ares library options.
- Set default c-ares library options to -lcares on FreeBSD and others.
Set to -lcares -lrt on Linux (previously was -lcares -lrt for all).
Thanks to goldenwolf for the bugreport (#0003803) and providing a test-
shell to trace this issue down.
such as 3 connections per 60 seconds. Previously that could result in 3
per 90 seconds due to timer inaccuracy, now max 65 seconds (max 5s
inaccuracy).
In the IRCd world correct time is very important. This means that time
should be correct when the IRCd is booted, either by running ntpd/ntpdate
on the system or some other synchronization software, or by using the
built-in timesync feature.
Whenever the clock is adjusted for more than a few seconds AFTER the IRCd
has booted, it can lead to dangerous effects ranging from unfair
timestamps
for nicks and channels (and hence the possibility to takeover channels),
to even completely stalling the IRCd (negative timeshift) or making it so
nobody can connect anymore due to throttling (positive timeshift).
We now try to 'fix' the worst effects such as the IRCd freeze and
throttling. This does not fix the whole problem, so I've added some big
warnings when the clock is adjusted, including an annoying one every 5
minutes if the clock was set backwards, until the time is OK again
(catches up with the original time).
This fixes#0003230 reported by Stealth, and #0002521 reported by durrie.
set::spamfilter::slowdetect-fatal, set::ssl::server-cipher-list,
set::ssl::renegotiate-bytes, set::ssl::renegotiate-timeout,
set::watch-away-notification and ./unreal gencloak. Reported by Bock
(#0003764).
- set::ssl::renegotiate-bytes: fix when specifying a value such as 10m.
- './unreal gencloak' now actually works
- Fix typo in user mode q notice, reported by Strawberry_Kittens and others
(#0003761).
- Possible fix for MAC OS X compile problem - UNCONFIRMED.
(NickServ client, NULL if not present). You can return 1 (HOOK_DENY) to
make the IRCd not send IDENTIFY to NickServ. Suggested by tabrisnet
(#0003739).
(sorry, previous half-commit to src/modules/m_nick.c was accidental)
- Win32: Made UnrealIRCd run as a service under non-privileged accounts
(ones that do not belong to the Administrator group). Reported by
skyflash, Bock, zer, etc... Thanks to BuHHunyx for some hints on how to
fix this.
server.
Should never happen except when using faulty services or when something
else
got horrible wrong (like a date which is 40 years ahead). Reported by
Darth Android (#0003738).
don't support this and will fail to compile UnrealIRCd. This fixes#3680,
reported by therock247uk.
- Upgraded c-ares to 1.6.0 (also now using pkg-config).
If you get a "undefined reference to `clock_gettime'" error, then you
might consider installing 'pkg-config' on your system, and then simply
re-run
./Config and make, should fix things.
__TODO__: win32 c-ares upgrade to 1.6.0 (and copy & fix header files).
__TODO__: testing! testing! i'd like to be sure this c-ares is stable!
'uname -a' at compile time. This fixes bug #1438 and #3320 reported by
Mouse and Monk, where because of previous behavior the IRCd sometimes
would not compile in certain environments.
'error setting max fd's to 9223372036854775807' which prevents the ircd
from booting up. Reported by btcentral and Bock. This hack might not be
totally correct though ;).
each time it executes, how LONG it takes to execute. When a certain
threshold
is reached the IRCd will warn or even remove the spamfilter. This will
prevent
a spamfilter (regex) from slowing down the IRCd too much, though it's
still not
a guarantee that it will never go to a halt (eg: in case it takes several
minutes to execute a regex or loops forever).
Warning can be configured via set::spamfilter::slowdetect-warn (default:
250 milliseconds) and automatic deletion of spamfilters if it takes too
long is set through set::spamfilter::slowdetect-fatal (default: 500 ms).
NOTE: slow spamfilter detection is currently not available on Windows.
NOTE 2: to disable slow detection you can set the warn and fatal settings
to 0 (zero). OR to really disable all code, remove SPAMFILTER_DETECTSLOW
from include/config.h and recompile.
This new feature (away notify) is announced in 005 (ISUPPORT) as: WATCHOPTS=A
Format is: WATCH A +UserOne +UserTwo
New numerics to cope with away notification in WATCH are:
RPL_NOWISAWAY: to indicate the user is away _when adding_ it to WATCH list
RPL_GONEAWAY: user was not away, but is now
RPL_NOTAWAY: user was away, but is no longer away
RPL_NOWISAWAY: user was away, and still is, but the reason changed
Example:
WATCH A +Target
Request to add user 'Target' to the watch list with away notification
:maintest.test.net 609 MySelf Target ~blih test.testnet 1204309588 :not here atm
Reply to watch add: user is online and away, reason is provided
:maintest.test.net 599 MySelf Target ~blih test.testnet 1204309588 :is no longer away
User is back (no longer away)
:maintest.test.net 598 MySelf Target ~blih test.testnet 1204309722 :lunch
State change: user is now away, reason is provided
:maintest.test.net 597 MySelf Target ~blih test.testnet 1204309738 :shopping, bbl
User is still away, but reason changed.
The syntax for each numeric is:
<nickname> <username> <hostname> <awaysince> :<away reason>
In case of 599 (RPL_NOTAWAY) it is:
<nickname> <username> <hostname> <awaysince> :is no longer away
For the record, this is all based on a draft from codemastr from 2004, which was
implemented in Unreal3.3 (devel branch) in 2006. Today, in 2008 it was updated
with away reason support and backported to Unreal3.2. Because away notification
hasn't been used until now (due to it only being in Unreal3.3) we felt it was
safe to break some numerics.
now set a ban on *!*@*h.com and then later add one on *!*@*blah.com
without
any trouble. Previously the second one was rejected due to the former
already matching it. To change it back edit the include/config.h setting
SOCALLEDSMARTBANNING.
reported by Monk (#0003453). It should be large enough now. Also changed the
way we deal with this when it happens (if it ever happens again..): we now
close the server connection, instead of trying to continue, because continueing
is too dangerous.
trying to read unrealircd.conf. All due to strange chmod() behavior. We now no
longer try to set permissions on Mac OS X. Patch provided by Tibby (#3489).
properly (..again..), this was previously reported by pv2b.
- CGI:IRC + IPv6: Fixed issue where all cgiirc ipv4 clients were rejected with
the message 'Invalid IP address', reported by stskeeps (#0003311), nate
(#0003533) and others.
'::ffff:1.2.3.4' ips in the conf, they are now auto-converted to that).
Based on patch from tabrisnet.
- Fixed issue where the cgiirc block did not work with IPv6, reported by
djGrrr, fixed by previous change.
defines IRC_USER, IRC_GROUP which is a string specifiying what user name/
group name that should be changed into, instead of a hardcoded gid/uid.
This should make it easier for packaged binary releases to work (even
though this probably means Debian will take us in, ick .. Can't we pull
a new fight with debian-legal again?)
- #0003363 patched by adrianp, changing IRC_UID and IRC_GID into
defines IRC_USER, IRC_GROUP which is a string specifiying what user name/
group name that should be changed into, instead of a hardcoded gid/uid.
This should make it easier for packaged binary releases to work (even
though this probably means Debian will take us in, ick .. Can't we pull
a new fight with debian-legal again?)
- Retranslated the whole CDIR section (3.15)
- According to http://forditas.fsf.hu/html/node3.html the Hungarian expression for 'Internet Service Provider' should be written with a hypen (all occurrences fixed).
will be backwards compatible as well, SJOIN doesn't care (TM) and mode
doesn't either in case of a server sending it. So this will be just a
client protocol modification.
when trying to /connect to a server with wildcards (* and ?) in the link
block. We also raise an error if link::options::autoconnect is used
together with wildcards in hostname.
will now attempt to accept() up to LISTEN_SIZE (possibly saving CPU
through this under load, and speeding up connection).
- IRCd now also sets the &me fd as being non blocking (wasn't before, that
was odd..)
file descriptors being leaked upon every /REHASH.
So if you, for example, had 3 modules loaded and rehashed 30 times, it would cause
the ircd to consume 60 useless file descriptors (which often means 60 less file
descriptors being available to clients).
new commands SVSNOLAG/SVS2NOLAG (syntax: SVSNOLAG [+|-] NickName). Obviously, care
should be taken when giving such access to a user since he/she will be able to flood
at full speed and could possibly take down the entire IRCd (well, everyone on it).
Suggested by avb, coded by djGrrr.
- Made SAPART work for mulitple channels, just like SAJOIN. Reported by Snake and
SeigHart, patch provided by Bock (#0003064). This also fixes SAPART now being
announced to all opers globally, just like SAJOIN.
- Improved description of link::hub/leaf/leafdepth in unreal32docs.html reported by Bugz (#2623),
also fixed typo (leafdepth, not leaf-depth), reported by monas (#3083).
- Fixed bug where omitting class::connfreq would result in a huge connection attempt
flood when autoconnect was enabled. We now set class::connfreq to 60 if it's not
specified. Reported by Milliways (#0003018).
error, reported by Bock (#0003114).
- Added information about extbans to help.conf (/HELPOP ?EXTBANS). Patch from Bock
(#0003113).
- Made SAPART work for mulitple channels, just like SAJOIN. Patch provided by Bock
(#0003064). This also fixes SAPART now being announced to all opers globally, just
like SAJOIN.
- Finally fixed /RESTART issue on windows for good, should now always restart correctly.
Patch provided by BuHHunyx and Bock (#0002734).
- Fixed set::dns::bind-ip directive seen as duplicate, reported by aegis (#0003074).
- set::dns::* block is now no longer mandatory. All info has always been read from
/etc/resolv.conf (*NIX) or the registry (Win32), and the set::dns block is ignored
(except for set::dns::bind-ip, but that's a special case). Suggested by many including
djGrrr to make things slightly more logical (#0003019).
- As a consequence of the above, set::dns blocks were removed from doc/example*conf.
- Added two more characters to Catalan charset, reported by rmh (#0002995).
- Added set::pingpong-warning [yes|no] which decides whether to send the "** If you are
having problems connecting due to ping timeouts, please type /quote pong .." message
to each client when NOSPOOF is enabled (usually on Win32). The default is NO.
Previously this message was always sent if NOSPOOF was on, which often caused
confusion among users. The message was intended for non-confirming clients, but these
should be fixed by now, and those that were not fixed (self-made bots/etc) did often
not understand the message anyway. Anyway, you can still turn it on ;). (#2680).
user target string (nick!user@host:info), insteaf of doing it at like 5 places.
- Spamfilter target 'u' (user): the host field (nick!user@HOST:realname) is now escaped
with brackets if it's an IPv6 address, eg: blah!blah@[1:2:3:4:5:6:7:8]:hello, reported
by aquanight and others (#0003010).
instead of letting it magically reappear whenever +x is set. This means services can
now properly "unvhost" a user by sending a "SVSMODE User -x+x" (then any existing vhost
will be removed and user will have a cloaked host). Reported by avenger and others
(#0002933).
- Made Unreal use the original name in case of a CNAME, instead of the forwarded name,
reported by jerrcsnet (#0003054).
- The "looking up your hostname" message was always sent, regardless of show-connect-info.
though it always acted like it did in the MODE line sent to the channel. This bug caused
desynchs in some cases. Bug reported by Korfio (#0003048).
- Fixes to SVSNICK: case-change no longer causes a collision, don't return the value from
exit_client (which would be FLUSH_BUFFER), fix QUIT not being sent back on collision.
- Fix for above so it doesn't -r the client.
- Renamed unreal32docs.tk.html to unreal32docs.tr.html
- Module coders: Added HOOKTYPE_POST_SERVER_CONNECT (1 param: cptr) which is called when
a server connects, just like HOOTYPE_SERVER_CONNECT but this is actually called *after*
all clients and channels are synched. Obviously needed for some modules which must synch
data that refers to clients/channels that would otherwise not exist yet on the other side.
reported by Bock (as part of #2889).
- Fixed desynch problem with +Q, reported by tabrisnet (#0002992).
- Updated doc/coding-guidelines
- Added bugs.* url to /info, was still showing some email address.
including one reported by frigola on an old Sun Cobalt RAQ3.
It will probably also fix an issue with the just released curl 7.15.4, if compiling
with remote includes.
TODO: Update win32 (not urgent)
you do 'cd ..' and then 'cd -' again, make works just fine. This is going to be the most
stupid workaround in history... Reported by vonitsanet and others (#0002926).
- Fixed crash problem on win32 if TKL times were <0. Obviously it's hard to protect from such
invalid server traffic, but figured in this case it might be a good idea since *NIX does
not crash.
- Made a note about possessive quantifiers, they are scary :P.
+- Moved another 2K lines from core to modules, this means 31K lines are now in modules
+ and can be upgraded on the fly.
+- Real Command Aliases: This makes it possible to, for example, alias '/GLINEBOT' to
+ 'GLINE <param> 2d Bots are not permitted on this network, etcetc'. For more information,
+ see the docs on the alias block and/or search for "glinebot" in doc/example.conf.
added glinebot example @ real command aliases / updated description...
- Added 'real' aliases, this are aliases that map to real commands, so you can for example
map the command '/GLINEBOT <x>' to 'GLINE <x> 2d Bots are not allowed on this server, blabla'.
See the documentation on the alias block for more information. doc/example.conf contains an
example as well (search for "glinebot").
map the command '/BLAH 5' to 'NICK idiot5'. More info in docs on alias block.
- Modulized: badwords system (src/badwords.c is now gone) and StripColors/StripControlCodes
to m_message, multiple netsynch routines to m_server, send_list to m_list, a certain mode
routine to m_svsmode, all /MSG IRC.. webtv stuff to src/modules/webtv.c which is compiled
with m_message.
This means another ~1500 lines of code are now in modules (and thus can be upgraded on
the fly), which brings the total of modulized lines at 32K.
synchronize the IRCd clock (TSOffset) with a few good time servers. It currently only does
this on-boot, but it will hopefully help a lot of people with most of their time differences.
I still keep recommending anyone who can to run proper time-synchronization software such as
ntpd/ntpdate on their servers.
To disable time synchronization (eg: because you are already running ntp), you can simply
set set::timesynch::enabled to no.
The boot timeout for the timeserver response (=causes boot delay) can be configured via
set::timesynch::timeout and is set to 3 seconds by default (range is 1s-5s), there should
be no reason to change this.
The time server can be configured by setting set::timesynch::server, the default is to
use 3 time servers on 3 continents (US, EU, AU) which should be sufficient for anyone but
if you got a good one near you you can use that one instead.
The time protocol we use is (S)NTP v4.
this case ;p). Reported by KnAseN and many others (#0002581).
There might still be other operator count bugs, but these are triggered by a different bug
and may or may not be caused by services.
which basically means if it allows .*. If you want to require a parameter, use .+ (or
anything other in regex that requires at least one character). Suggested and patch provided
by Nazzy (#0002722).
far as we want to go with regards to relaxing "too broad" checking... Just continue to use
services AKILL for (other) "too broad cases", as many people (correctly) do. Change
suggested by salama (#0002911).
CALLBACKTYPE_CLOAK). This passes 'aClient *sptr, char *host' instead of only 'char *host'
to the cloaking module, which can be useful if you need to cloak on something other than
IP/host. Suggested by fez (#0002275).
Module may still provide only CALLBACKTYPE_CLOAK though, in fact this is what the official
cloaking module does. So no updating of cloaking modules needed.
A side-effect of this "extra cloaking" callback is that we needed to change make_virthost()
which now has an extra parameter in front, and another side-effect is that calling the
CALLBACKTYPE_CLOAK may not work since only *_EX might be available. To my knowledge there
are very few modules (only 1 I know) that will have a problem due to this, so sounds like
an affordable tradeoff.
some more odd problems from people (eg: people switching from GCC 3.x to 4.x and wondering
why they are crashing or getting other errors).
** actually, this was already comitted, but forgot to commit Changes :p **
a lot of crashes. Both are now fixed. Reported by Zell, Yamake, and others (#2875, #2704).
Fix provided by Xuefer. This also gets rid of some annoying and useless compile warnings
as well.
- When checking if a user is banned, we always check the cloakhost too. Previously we could
not do this if the user had a /VHOST (=a minority of the cases, but still...). In short,
this is some extra protection to combat ban evasion.
- Performance of is_banned() *slightly* improved (just 1-2 usec, but 7 usec if no bans).
- [Module coders] For extban routines, we now offer a routine extban_is_banned_helper(buf)
which can be used instead of the ban_realhost/etc static chars stuff, see
extban_modeq_is_banned for a (real-life) example of how this is used.
- [Services coders!] Added PROTOCTL CLK (requires NICKv2) which adds an extra field in the
NICK command (when a user connects) right before the infofield (gecos).
The added field contains the cloaked host, that is: the masked host if +x would have been
set. This field is ALWAYS sent, regardless of whether the user is actually +x or not.
Services can then store this field in memory, to know the host of the user if the user
is set +x (+x-t). This is a (better) alternative to PROTOCTL VHP, with no race conditions,
and avoids some other VHP problems.
VHP will stay supported though... so it's not mandatory to switch over.
- c-ares (currently, a forked off version) enhancements:
- '/quote dns i' now shows the nameserver settings (which is taken from /etc/resolv.conf
on *NIX, and from the registry on Windows)
- We no longer depend on a C++ compiler (was useless c-ares dependency caused by libtool)
- '/REHASH -dns' now rereads the resolver data from resolv.conf/registry, no IRCd restart
needed anymore. It's currently kinda experimental however, but I *think* it will work ok.
Unfortunately the above features required some ugly hacks if curl was enabled, so if you
use curl (Remote includes), feel free to test on your OS (Linux, but especially FreeBSD
and the other *NIXes) to see if things still compile (make clean; ./Config && make).
- '/quote dns i' now shows the nameserver settings (which is taken from /etc/resolv.conf
on *NIX, and from the registry on Windows)
- We no longer depend on a C++ compiler (was useless c-ares dependency caused by libtool)
- '/REHASH -dns' now rereads the resolver data from resolv.conf/registry, no IRCd restart
needed anymore. It's currently kinda experimental however, but I *think* it will work ok.
Unfortunately the above features required some ugly hacks if curl was enabled, so if you
use curl (Remote includes), feel free to test on your OS (Linux, but especially FreeBSD
and the other *NIXes) to see if things still compile (make clean; ./Config && make).
clients support it now (mIRC, xchat, epic, eggdrop, Klient, PJIRC, irssi, CGI:IRC, etc).
It has always been weird that win32 had it ON by default and *NIX OFF, anyway.
Naturally this change will be mentioned clearly in next release notes.
clients connecting trough a CGI:IRC gateway that is in cgiirc { }. This might also fix a bug
where (g)zlines were not applied to CGI:IRC clients, reported by devil (#0002850).
- Rephrased/editted part of example.conf and unreal32docs to make it a littttttle bit easier
for beginners / try to mention the FAQ a bit more explicitly.
- Modulized NAMES command (can now be upgraded on the fly, if ever needed).
- Added NAMESX support, seeing both mIRC (5.17) and XChat support this. What this does is
send all rights of all users on the channel in the NAMES reply (eg: @+Syzop if the user is +ov)
instead of only the highest one (@Syzop in previous example). We only do so if the client
explicitly requested this via a NAMESX in a PROTOCTL message (eg: 'PROTOCTL NAMESX').
Note that there is a glitch: since most clients only send the PROTOCTL NAMESX after they
see NAMESX listed in the 005 announce message this has the effect that if there are
set::auto-join channels present (where users are automatically joined to by the server) the
extended NAMES reply will not be sent for those channels, because from the IRC server' point
of view the join happened before the PROTOCTL and hence it does not know the client wanted
NAMESX at that point (the result is not catastrophic: the old-style NAMES is sent for those
channels). Anyway, for all non-autojoin channels this works great. So still worth adding IMO.
Originally suggested in #0000606.
Side note: this does not mean we dropped the idea of (also) having a challenge-response
system for good ;).
We now support the webirc ('webirc_password' in CGI:IRC) method, which is kinda superior
to the older method ('realhost_as_password').
See the Unreal documentation (section '4.36 - Cgiirc Block') for details on how to configure.
- Changed quoting color in unreal32docs.. looks better now IMO (only English docs updated).
"trusted" and the IRCd will show the users' _real_ host/ip everywhere on IRC, instead of the
_CGI:IRC-gateway_ host/ip.
To do so you must set 'realhost_as_password' to 1 in your cgiirc.conf. And add the
CGI:IRC gateway(s) you fully trust to set::cgiirc::hosts.
means no longer weird issues with +b *\* etc not banning nicks with \ in it.
ExtBan ~c/~r get special treatment and will use our match_esc [match with escaping]
routine, that way you can ban channels such as "#f*ck" via "+b ~c:#f\*ck".
Fix triggered by bugreport of vonitsanet (#0002782).
the switchover we were accidently using different ones which caused funny kill messages
like "You were killed by a.b.c (a!a.b.c (SOMENICK[N\A](?) <- d.e.f))." This also broke
some bans in pre2/rc1. Bug reported by HERZ (#0002772).
contains the (root) certificates of most major Certificate Authorities. It is basically
the default curl ca-bundle.crt plus cacert's certificates.
The 'curl-ca-bundle.crt' will be copied to the installation dir if needed.
It will from now on be used by Unreal for all remote includes (curl) related certificates.
If you want to use https but don't want to buy a certificate, we suggest you to apply for
a free certificate at CACert (www.CACert.org). Or, alternatively, add your own certificate
(PEM encoded) to curl-ca-bundle.crt, see 'SSLCERTS' in the curl package for more info.
but is actually understandable and has less bugs. This fixes +b ~c:#c\*t not properly
matching #c*t, reported by Jason (#0002752). Initial results look good, but this needs
some good testing ;).
- Updated unrealinst.iss: made it easier for me to have 2 curl versions, this is so we can
ship the SSL version of unreal with a curl that supports SSL (https, etc).
- Preperations for pre-1 (version change, etc)
- Changed the default maxbanlength from 1K to 2K, which means people can set more bans because
in pracitce the 60 (maxbans) limit was never met because the maxbanlimit was set so low.
set::maxbans in the configfile, note that you probably also want to enlarge set::maxbanlength
as well (see docs) or else you will hit that limit first.
- Changed the default maxbanlength from 1K to 2K, which in practice will mean people can set
a lot more bans since in practice the 60 (maxbans) limit was never met because the
maxbanlimit was set so low.
an error, since specifying usermask should not be done and is useless, since a (G)ZLINE
takes place BEFORE ident lookups.
- Did the same for /(G)ZLINE *@hostmask (should be *@ipmask), this already was a warning
in 3.2.3, and is an error now in 3.2.4.
- Redid some net synching code to make it more efficient (#2716).
- Fixed spamfilter crash problem: the action 'viruschan' is now no longer incompatible
with target 'user'. Reported by Monk (#0002570).
oper privileges on quarantined servers will be instantly killed. Bit ugly perhaps, but
then it actually does what it should (prevent opers on quarantine from getting GLOBAL
oper privileges). This "fixes" #2510, #2163 and #1968.
[forgot docs commit]
oper privileges on quarantined servers will be instantly killed. Bit ugly perhaps, but
then it actually does what it should (prevent opers on quarantine from getting GLOBAL
oper privileges). This "fixes" #2510, #2163 and #1968.
- Made ./Config better react to errors (no longer print a "everything is a big success"
kind of message when in fact everything went wrong).
- Made ./Config (configure) exit on openssl or zlib not found errors, instead of
silently continueing and then causing trouble later on. Also now printing _a bit_
more helpful error message.
you have to put 'spamfilter yes;' in every alias block you want to get filtered.
This is so you can have for example /MS filtered (due to heavy spam), while keeping
/NS and /CS unfiltered. Reported by Homer (#0002496).
- The memoserv aliases (/MS and /MEMOSERV) now have spamfiltering enabled by default.
in the function, reported by Robby22 (#0002696).
- Fixed set::static-part set to 'no' not working properly. Reported by Robby22 (#0002698).
- Fixed crash in new resolver, reported by firstof9.
unreal version that the user is using. I presume this can be helpful (although nobody ever
suggested it ;p). The macros (#define's) are:
UNREAL_VERSION_GENERATION The generation version number eg: 3 for 3.2.4
UNREAL_VERSION_MAJOR The major version number eg: 2 for 3.2.4
UNREAL_VERSION_MINOR The minor version number eg: 4 for 3.2.4
This can be negative for unstable,
alpha and beta versions.
UNREAL_VERSION_TIME Year + week of the day (starting eg: 200541
on Monday), this is updated on
the CVS server every week.
The first 3 are for nicely identifiying the version, the 4th can be useful in case
you want to support CVS and/or want some more control.
Reported by Trocotronic (#0002659).
- Fixed a problem with entries in the hosts file (such as, usually, localhost), this would
cause an unresolved host and a 30s delay for the user, even though resolving succeeded.
This should get rid of some annoying untracable (and usually rare) crashbugs in the
old resolver. Besides that, it makes things look more clean and understandable.
This should be the fix for the following bugids (all the same issue): #2499, #2551, #2558,
#2559, #2603, #2642, #2502, #2501, #2618, #2616.
Feedback and testing is very much welcomed (syzop@unrealircd.com).
generated (for linkage by commands.so), are now used to generate the .so files of the
individual modules as well (eg: m_setname.o -link-> m_setname.so). This reduces compile
time ('make') on my machine by 33%, so it's quite noticable ;).
It also sends a numeric to the user saying the command has been processed, but a copy
has been sent to ircops. I feel this is a good idea for privacy reasons (anti-spy),
though I don't know how users will react to this. If you are using this on your network
and get users bothering you about it (or before that ;p), it's probably a good idea
to explain it somewhere on your site or FAQ :).
Example usage:
/spamfilter add p warn - Testing_mirc_decode_filter \$decode\(.*\)
[WARNING] The numeric text is likely to change in the next few weeks (early-cvs-commit).
- If a class block was removed and any other blocks would be referencing the class block
(such as: allow::class, oper::class, link::class), then this would cause a crash.
Reported by Mike_ (#0002646).
cd src;${MAKE}${MAKEARGS}MODULEFILE=${MODULEFILE}'EXLIBS=${EXLIBS}' custommodule
@if test -z "${MODULEFILE}";thenecho"Please set MODULEFILE when calling \`\`make custommodule''. For example, \`\`make custommodule MODULEFILE=callerid''." >&2;exit 1;fi
AC_ARG_WITH(hostname, [AC_HELP_STRING([--with-hostname=host],[Specify the local hostname of the server])], AC_DEFINE_UNQUOTED(DOMAINNAME,"$withval"),AC_DEFINE_UNQUOTED(DOMAINNAME,"`hostname`"))
AC_DEFINE_UNQUOTED(MYOSNAME,"`uname -a`")
AC_ARG_WITH(permissions, [AC_HELP_STRING([--with-permissions=permissions],[Specify the default permissions for
AC_ARG_WITH(disableusermod, [AC_HELP_STRING([--with-disableusermod], [Disable /set* and /chg*])],
AC_DEFINE(DISABLE_USERMOD))
AC_ARG_WITH(operoverride-verify, [AC_HELP_STRING([--with-operoverride-verify], [Require opers to invite themselves to +s/+p channels])],
AC_DEFINE(OPEROVERRIDE_VERIFY))
CHECK_SSL
CHECK_ZLIB
CHECK_LIBCURL
AC_ARG_ENABLE(dynamic-linking, [AC_HELP_STRING([--enable-dynamic-linking],[Make the IRCd dynamically link shared objects rather than statically])], AC_ENABLE_DYN, AC_DEFINE(STATIC_LINKING))
AC_ARG_ENABLE(inet6, [AC_HELP_STRING([--enable-inet6],[Make the IRCd support IPv6])], AC_ENABLE_INET6)
AC_SUBST(IRCDDIR)
AC_SUBST(BINDIR)
AC_MSG_CHECKING(if FD_SETSIZE is large enough to allow $ac_fd file descriptors)
AC_TRY_RUN([
#include <sys/types.h>
#include <sys/time.h>
int main() {
if (FD_SETSIZE >= $ac_fd)
exit(0);
exit(1);
}
], AC_MSG_RESULT(yes), [
FD_SETSIZE="-DFD_SETSIZE=$ac_fd"
AC_MSG_RESULT(no)
])
AC_SUBST(FD_SETSIZE)
case `uname -s` in
*SunOS*)
CFLAGS="$CFLAGS -D_SOLARIS"
IRCDLIBS="$IRCDLIBS -lresolv "
;;
*solaris*)
CFLAGS="$CFLAGS -D_SOLARIS"
IRCDLIBS="$IRCDLIBS -lresolv "
;;
esac
dnl REMEMBER TO CHANGE WITH A NEW RELEASE!
tre_version="0.7.2"
AC_MSG_RESULT(extracting TRE regex library)
cur_dir=`pwd`
cd extras
dnl remove old tre directory to force a recompile...
dnl Save build directory early on (used in our m4 macros too)
BUILDDIR_NOW="`pwd`"
dnl Calculate the versions. Perhaps the use of expr is a little too extravagant
# Generation version number (e.g.: X in X.Y.Z)
UNREAL_VERSION_GENERATION=["6"]
AC_DEFINE_UNQUOTED([UNREAL_VERSION_GENERATION], [$UNREAL_VERSION_GENERATION], [Generation version number (e.g.: X for X.Y.Z)])
# Major version number (e.g.: Y in X.Y.Z)
UNREAL_VERSION_MAJOR=["2"]
AC_DEFINE_UNQUOTED([UNREAL_VERSION_MAJOR], [$UNREAL_VERSION_MAJOR], [Major version number (e.g.: Y for X.Y.Z)])
# Minor version number (e.g.: Z in X.Y.Z)
UNREAL_VERSION_MINOR=["6"]
AC_DEFINE_UNQUOTED([UNREAL_VERSION_MINOR], [$UNREAL_VERSION_MINOR], [Minor version number (e.g.: Z for X.Y.Z)])
# The version suffix such as a beta marker or release candidate
# marker. (e.g.: -rcX for unrealircd-3.2.9-rcX). This macro is a
# string instead of an integer because it contains arbitrary data.
UNREAL_VERSION_SUFFIX=["-git"]
AC_DEFINE_UNQUOTED([UNREAL_VERSION_SUFFIX], ["$UNREAL_VERSION_SUFFIX"], [Version suffix such as a beta marker or release candidate marker. (e.g.: -rcX for unrealircd-3.2.9-rcX)])
AC_PATH_PROG(RM,rm)
AC_PATH_PROG(CP,cp)
AC_PATH_PROG(TOUCH,touch)
AC_PATH_PROG(OPENSSLPATH,openssl)
AS_IF([test x"$OPENSSLPATH" = "x"],
[
echo ""
echo "Apparently you do not have both the openssl binary and openssl development libraries installed."
echo "The following packages are required:"
echo "1) The library package is often called 'openssl-dev', 'openssl-devel' or 'libssl-dev'"
echo "2) The binary package is usually called 'openssl'."
echo "NOTE: you or your system administrator needs to install the library AND the binary package."
echo "After doing so, simply re-run ./Config"
exit 1
])
AC_PATH_PROG(INSTALL,install)
AC_PATH_PROG(GUNZIP, gunzip)
AC_PATH_PROG(PKGCONFIG, pkg-config)
dnl Check for compiler
AC_PROG_CC_C99
AS_IF([test "$ac_cv_prog_cc_c99" = "no"],
[AC_MSG_ERROR([No C99 compiler was found. Please install gcc or clang and other build tools. Eg, on Debian/Ubuntu you probably want to run the following as root: apt-get install build-essential ])])
dnl Save CFLAGS, use this when building the libraries like c-ares
orig_cflags="$CFLAGS"
dnl Check for make moved down, so the above compiler check takes precedence.
AC_CHECK_PROG(MAKER, gmake, gmake, make)
AC_PATH_PROG(GMAKE,gmake)
AS_IF([$MAKER --version | grep -q "GNU Make"],
[GNUMAKE="0"],
[AC_MSG_ERROR([It seems your system does not have make/gmake installed. If you are on Linux then install make, otherwise install gmake.])])
dnl Checks for libraries.
AC_CHECK_LIB(descrypt, crypt,
[AC_DEFINE([HAVE_CRYPT], [], [Define if you have crypt])
IRCDLIBS="$IRCDLIBS-ldescrypt "],
[AC_CHECK_LIB(crypt, crypt,
[AC_DEFINE([HAVE_CRYPT], [], [Define if you have crypt])
IRCDLIBS="$IRCDLIBS-lcrypt "])])
dnl Check for big-endian system, even though these hardly exist anymore...
AS_CASE([$host_cpu],
[i?86|amd64|x86_64],
[ac_cv_c_bigendian=no]
)
AC_C_BIGENDIAN(
AC_DEFINE(NATIVE_BIG_ENDIAN, 1, [machine is bigendian]),
AC_DEFINE(NATIVE_LITTLE_ENDIAN, 1, [machine is littleendian]),
AC_MSG_ERROR([unknown endianness]),
AC_MSG_ERROR([universal endianness is not supported - compile separately and use lipo(1)])
)
dnl HARDENING START
dnl This is taken from https://github.com/kmcallister/autoharden
dnl With some very small modifications (to remove C++ checking for instance)
# We want to check for compiler flag support, but there is no way to make
# clang's "argument unused" warning fatal. So we invoke the compiler through a
[AC_DEFINE([HAVE_PSSTRINGS],[], [Define if you have PS_STRINGS])],
[AC_CHECK_FUNCS([pstat],
[AC_DEFINE([HAVE_PSTAT], [], [Define if you have pstat])])])
])
]
)
AC_CHECK_FUNCS(explicit_bzero,AC_DEFINE([HAVE_EXPLICIT_BZERO], [], [Define if you have explicit_bzero]))
AC_CHECK_FUNCS(syslog,AC_DEFINE([HAVE_SYSLOG], [], [Define if you have syslog]))
AC_CHECK_FUNCS(strnlen,AC_DEFINE([HAVE_STRNLEN], [], [Define if you have strnlen]))
AC_SUBST(CRYPTOLIB)
AC_SUBST(MODULEFLAGS)
AC_SUBST(DYNAMIC_LDFLAGS)
AC_ARG_WITH(nick-history, [AS_HELP_STRING([--with-nick-history=length],[Specify the length of the nickname history])],
[AC_DEFINE_UNQUOTED([NICKNAMEHISTORYLENGTH], [$withval], [Set to the nickname history length you want])],
[AC_DEFINE([NICKNAMEHISTORYLENGTH], [2000], [Set to the nickname history length you want])])
AC_ARG_WITH(permissions, [AS_HELP_STRING([--with-permissions=permissions], [Specify the default permissions for
configuration files])],
dnl We have an apparently out-of-place 0 here because of a MacOSX bug and because
dnl we assume that a user thinks that `chmod 0600 blah' is the same as `chmod 600 blah'
dnl (#3189)
[AC_DEFINE_UNQUOTED([DEFAULT_PERMISSIONS], [0$withval], [The default permissions for configuration files. Set to 0 to prevent unrealircd from calling chmod() on the files.])],
[AC_DEFINE([DEFAULT_PERMISSIONS], [0600], [The default permissions for configuration files. Set to 0 to prevent unrealircd from calling chmod() on the files.])])
AC_ARG_WITH(bindir, [AS_HELP_STRING([--with-bindir=path],[Specify the directory for the unrealircd binary])],
[AC_DEFINE_UNQUOTED([BINDIR], ["$withval"], [Define the directory where the unrealircd binary is located])
BINDIR="$withval"],
[AC_DEFINE_UNQUOTED([BINDIR], ["$HOME/unrealircd/bin"], [Define the directory where the unrealircd binary is located])
BINDIR="$HOME/unrealircd/bin"])
AC_ARG_WITH(scriptdir, [AS_HELP_STRING([--with-scriptdir=path],[Specify the directory for the unrealircd start-stop script])],
[AC_DEFINE_UNQUOTED([SCRIPTDIR], ["$withval"], [Define the directory where the unrealircd start stop scripts is located])
SCRIPTDIR="$withval"],
[AC_DEFINE_UNQUOTED([SCRIPTDIR], ["$HOME/unrealircd"], [Define the directory where the unrealircd start stop scripts is located])
SCRIPTDIR="$HOME/unrealircd"])
AC_ARG_WITH(confdir, [AS_HELP_STRING([--with-confdir=path],[Specify the directory where configuration files are stored])],
[AC_DEFINE_UNQUOTED([CONFDIR], ["$withval"], [Define the location of the configuration files])
CONFDIR="$withval"],
[AC_DEFINE_UNQUOTED([CONFDIR], ["$HOME/unrealircd/conf"], [Define the location of the configuration files])
CONFDIR="$HOME/unrealircd/conf"])
dnl We have to pass the builddir as well, for the module manager
AC_ARG_WITH(builddir, [AS_HELP_STRING([--with-builddir=path],[Specify the build directory])],
[AC_DEFINE_UNQUOTED([BUILDDIR], ["$withval"], [Define the build directory])
BUILDDIR="$withval"],
[AC_DEFINE_UNQUOTED([BUILDDIR], ["$BUILDDIR_NOW"], [Specify the build directory])
BUILDDIR="$BUILDDIR_NOW"])
AC_ARG_WITH(modulesdir, [AS_HELP_STRING([--with-modulesdir=path],[Specify the directory for loadable modules])],
[AC_DEFINE_UNQUOTED([MODULESDIR], ["$withval"], [Define the location of the modules])
MODULESDIR="$withval"],
[AC_DEFINE_UNQUOTED([MODULESDIR], ["$HOME/unrealircd/modules"], [Define the location of the modules])
MODULESDIR="$HOME/unrealircd/modules"])
AC_ARG_WITH(logdir, [AS_HELP_STRING([--with-logdir=path],[Specify the directory where log files are stored])],
[AC_DEFINE_UNQUOTED([LOGDIR], ["$withval"], [Define the location of the log files])
LOGDIR="$withval"],
[AC_DEFINE_UNQUOTED([LOGDIR], ["$HOME/unrealircd/logs"], [Define the location of the log files])
LOGDIR="$HOME/unrealircd/logs"])
AC_ARG_WITH(cachedir, [AS_HELP_STRING([--with-cachedir=path],[Specify the directory where cached files are stored])],
[AC_DEFINE_UNQUOTED([CACHEDIR], ["$withval"], [Define the location of the cached remote include files])
CACHEDIR="$withval"],
[AC_DEFINE_UNQUOTED([CACHEDIR], ["$HOME/unrealircd/cache"], [Define the location of the cached remote include files])
CACHEDIR="$HOME/unrealircd/cache"])
AC_ARG_WITH(tmpdir, [AS_HELP_STRING([--with-tmpdir=path],[Specify the directory where private temporary files are stored. Should not be readable or writable by others, so not /tmp!!])],
[AC_DEFINE_UNQUOTED([TMPDIR], ["$withval"], [Define the location of private temporary files])
TMPDIR="$withval"],
[AC_DEFINE_UNQUOTED([TMPDIR], ["$HOME/unrealircd/tmp"], [Define the location of private temporary files])
TMPDIR="$HOME/unrealircd/tmp"])
AC_ARG_WITH(datadir, [AS_HELP_STRING([--with-datadir=path],[Specify the directory where permanent data is stored])],
[AC_DEFINE_UNQUOTED([PERMDATADIR], ["$withval"], [Define the location of permanent data files])
PERMDATADIR="$withval"],
[AC_DEFINE_UNQUOTED([DATADIR], ["$HOME/unrealircd/data"], [Define the location of permanent data files])
PERMDATADIR="$HOME/unrealircd/data"])
AC_ARG_WITH(docdir, [AS_HELP_STRING([--with-docdir=path],[Specify the directory where documentation is stored])],
[AC_DEFINE_UNQUOTED([DOCDIR], ["$withval"], [Define the location of the documentation])
DOCDIR="$withval"],
[AC_DEFINE_UNQUOTED([DOCDIR], ["$HOME/unrealircd/doc"], [Define the location of the documentation])
DOCDIR="$HOME/unrealircd/doc"])
AC_ARG_WITH(pidfile, [AS_HELP_STRING([--with-pidfile=path],[Specify the path of the pid file])],
[AC_DEFINE_UNQUOTED([PIDFILE], ["$withval"], [Define the path of the pid file])
PIDFILE="$withval"],
[AC_DEFINE_UNQUOTED([PIDFILE], ["$HOME/unrealircd/data/unrealircd.pid"], [Define the path of the pid file])
PIDFILE="$HOME/unrealircd/data/unrealircd.pid"])
AC_ARG_WITH(controlfile, [AS_HELP_STRING([--with-controlfile=path],[Specify the path of the control socket])],
[AC_DEFINE_UNQUOTED([CONTROLFILE], ["$withval"], [Define the path of the control socket])
CONTROLFILE="$withval"],
[AC_DEFINE_UNQUOTED([CONTROLFILE], ["$HOME/unrealircd/data/unrealircd.ctl"], [Define the path of the control socket])
dnl Ensure that this “feature” can be disabled as it makes it harder to package unrealircd.
dnl Users have always been able to specify “./configure LDFLAGS=-Wl,-rpath,/path/to/blah”—binki
AC_ARG_WITH(privatelibdir, [AS_HELP_STRING([--with-privatelibdir=path],[Specify the directory where private libraries are stored. Disable when building a package for a distro])],
[],
[with_privatelibdir="yes"])
AS_IF([test "x$with_privatelibdir" = "xno"],
[PRIVATELIBDIR=],
[test "x$with_privatelibdir" = "xyes"],
[PRIVATELIBDIR="$HOME/unrealircd/lib"],
[PRIVATELIBDIR="$with_privatelibdir"])
AS_IF([test "x$PRIVATELIBDIR" = "x"],
[LDFLAGS_PRIVATELIBS=""],
[AC_DEFINE_UNQUOTED([PRIVATELIBDIR], ["$PRIVATELIBDIR"], [Define the location of private libraries])
# Create the private library directory now with restrictive permissions.
# This must happen here rather than in the Makefile because the bundled
# libraries are installed into it during configure. It must also work when
# configure is run directly without ./Config having created it first.
[AC_DEFINE([NO_OPEROVERRIDE], [], [Define if you want OperOverride disabled])])])
AC_ARG_WITH(operoverride-verify, [AS_HELP_STRING([--with-operoverride-verify], [Require opers to invite themselves to +s/+p channels])],
[AS_IF([test $withval = "yes"],
[AC_DEFINE([OPEROVERRIDE_VERIFY], [], [Define if you want opers to have to use /invite to join +s/+p channels])])])
AC_ARG_WITH(system-pcre2, [AS_HELP_STRING([--without-system-pcre2], [Use the system pcre2 package instead of bundled, discovered using pkg-config])], [], [with_system_pcre2=yes])
AC_ARG_WITH(system-argon2, [AS_HELP_STRING([--with-system-argon2], [Use system argon2 instead of bundled version. Normally we prefer the one shipped with unrealircd because it is much faster])], [], [with_system_argon2=no])
AC_ARG_WITH(system-sodium, [AS_HELP_STRING([--without-system-sodium], [Use bundled version instead of system sodium library. Normally autodetected via pkg-config])], [], [with_system_sodium=yes])
AC_ARG_WITH(system-cares, [AS_HELP_STRING([--without-system-cares], [Use bundled version instead of system c-ares. Normally autodetected via pkg-config.])], [], [with_system_cares=yes])
AC_ARG_WITH(system-jansson, [AS_HELP_STRING([--without-system-jansson], [Use bundled version instead of system jansson. Normally autodetected via pkg-config.])], [], [with_system_jansson=yes])
CHECK_SSL
CHECK_SSL_CTX_SET1_SIGALGS_LIST
CHECK_SSL_CTX_SET1_CURVES_LIST
CHECK_SSL_CTX_SET1_GROUPS_LIST
CHECK_SSL_GET_NEGOTIATED_GROUP
CHECK_SSL_CTX_SET_MIN_PROTO_VERSION
CHECK_SSL_CTX_SET_SECURITY_LEVEL
CHECK_ASN1_TIME_diff
CHECK_X509_get0_notAfter
CHECK_X509_check_host
AC_ARG_ENABLE(dynamic-linking, [AS_HELP_STRING([--disable-dynamic-linking], [Make the IRCd statically link with shared objects rather than dynamically (noone knows if disabling dynamic linking actually does anything or not)])],
The ts parameter is the time at which the channel, chname, was created. The
modes parameter is only included if modes are set, if not modes and mode para
are excluded. If modes exists and modes requiring parameters (+klLf) are set,
one mode para parameter is included for each value. The last parameter
specifies a list of channel members and the channel ban and except list. The
members are listed with the prefixes they have. * = +q, ~ = +a, @ = +o, % =
+h, + = +v. If no prefix is specified for the member then the user is a
normal user. The & prefix is used to denote a +b, and the " prefix denotes a
+e. It is important that if a & or " is encountered that you do not continue
to check that entry for other prefixes as a ban/except may contain *~@
characters which will intefere with prefixes.
When synching, if ts lower than the local value, the information supplied by
the remote server replaces the local (ie remove local +ohv that are not
recorded on the remote server). The opposite is true when the ts is
higher. Bans/excepts do not apply to the previous rule. If the ts is the
same, information is merged therefore the modes from both servers are added
together. If +l is set and both servers have different values, the highest is
choosen, for +f the highest of each param, N:M is chosen, and if one server
has * set, then it is included. For +k and +L the "highest" in a string
comparison is used.
NS When specified informs the server that numeric server names are
supported. Numeric server names are a base64 number that is associated with
each server. This number is used as a shorthand name for the server. It is
used in the server parameter of the NICK command and can also be used in the
prefix for a message. In the event that the prefix is an NS, rather than
using :<sender>, the format is @<ns> the ns should be translated into the
server name so that the message can be processed. The format for a SERVER
message (at sync time) that supports NS is:
SERVER <servername> <hops> :U<protocol>-<versionflags>-<numeric> <info>
The VL protocol must also be supported. The numeric is passed to all servers
on the network through the SERVER command using the syntax:
:<sender> SERVER <servername> <hops> <numeric> :<info>
Note: anywhere a :<sender> is expected an @<ns> may be received if the source
is a server. See doc/technical/base64.txt for information on the base64
system used.
SJB64 This token allows timestamps to be specified in base64 notation to conserve
bandwidth. When SJB64 is supported, anywhere a timestamp can appear may be in
base64 notation. A base64 timestamp is preceeded by a ! to identify that it
is an sjb64 rather than a regular timestamp, if this is the case the
characters following the ! represent the timestamp in base64. See
doc/technical/base64.txt for information on the base64 system used.
ZIP If both servers have this set then the link will be (zlib) compressed after
the SERVER message. If one of the servers does not have ZIP in his PROTOCTL
message then the link stays uncompressed.
TKLEXT This allows 10 instead of 8 parameters in TKL's for spamfilter, see s_kline.c
function m_tkl for more info on this (added in 3.2RC2).
NICKIP This token indicates that a (standard) base64 encoded IP address is included
in the NICK command. The IP is in binary network byte order formated and
encoded using the standard base64 algorithm. '*' is used if no IP is available.
NICKCHARS This specifies a list of language characters that are allowed in nicks.
USMARC codes are used, with a suffix if needed. See src/charsys.c for the full
list (ctrl+f, static LangList) of possible languages (2nd column).
The items in the list sent as NICKCHARS=.. must always be sorted.
If a server sends NICKCHARS= and if the remote parameters do not match the
charsets in use locally, then the server link is rejected.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.