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.
Eg: vhost "$operlogin@$operclass.example.net";
Also add potentially_valid_vhost() function which can be used in
config code to ignore invalid $vars. Then at runtime you use the
real valid_vhost() function after variable expansion by
unreal_expand_string().
and use it not only from vhost { } block code but also for like
blacklist::reason.
This so the same variables with the same names are available at
those places.
Supported are:
$nick, $username, $realname, $ip, $hostname, $server, $account,
$operlogin, $operclass, $country_code (xx for unknown),
$asn (0 for unknown).
* Convert to use module-based config handling
* Split part of VHOST command into do_vhost() for later
* Use AppendListItem instead of AddListItem so they are in config-order.
This is not really important atm but will matter later if we go auto.
* No other code changes at this point
This so if there is ever an issue, we can hot-patch it. This affects
exit_client(), exit_client_fmt(), exit_client_ex(), banned_client(),
and various (internal) help functions.
This also means you cannot call these functions during TEST/INIT (eg
during REHASH) since the 'quit' module which provides these modules
may not be loaded yet. I don't think that's a situation/problem but
this needs some more testing.
This was in src/hash.c, src/list.c and src/modules/stats.c.
Now all in src/modules/nick.c... or should this go into a new module?
Again, this needs some more testing, like previous commit.
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 ;)
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().
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.
*/
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
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.
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
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
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..
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.
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.
* 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).
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
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.
... 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)
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....
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.
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
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.
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.
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 ;)