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

845 Commits

Author SHA1 Message Date
Val Lorentz d5ceb664bc Add 'history_delete' method to HistoryBackend (#253)
This will allow modules to implement deletion of specific messages
(unlike history_destroy, which removes the entire history of a channel)
2023-06-17 16:10:10 +00:00
Bram Matthys 995d28cacb Add duplicate_security_group() function, and also:
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.
2023-05-26 16:15:09 +02:00
Bram Matthys fa4b39d4aa Fix "function returns an aggregate" to make GCC happy.
Actually I don't think this was really wrong as this is an
enum, which is probably why clang does not complain...
but still... whatever....
2023-05-26 14:40:24 +02:00
Bram Matthys 9aafdb7f9c Move handling of webirc { } block into new proxy { } block (allow the old name)
This is untested, as I'm first working on the rest...
2023-05-26 12:23:51 +02:00
Bram Matthys c2d465c5dd Move chunk of code from start_of_normal_client_handshake() to
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...).
2023-05-26 11:24:01 +02:00
Bram Matthys 52472a9a88 Add support for set unknown-users { } and the like:
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.
2023-05-22 12:07:43 +02:00
Bram Matthys 6bbb5dee37 Add str_starts_with* and str_ends_with* functions:
int str_starts_with_case_sensitive(const char *haystack, const char *needle);
int str_ends_with_case_sensitive(const char *haystack, const char *needle);
int str_starts_with_case_insensitive(const char *haystack, const char *needle);
int str_ends_with_case_insensitive(const char *haystack, const char *needle);
[skip ci]
2023-05-22 07:42:26 +02:00
Bram Matthys 3652940c2c Add set::anti-flood::<secgroup>::max-channels-per-user setting to override
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!
2023-05-19 21:47:23 +02:00
Bram Matthys f2015ad865 Fix crash when removing a listen { } block with websocket or rpc
(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!)
2023-05-19 19:29:46 +02:00
Bram Matthys f804c5ed65 Add detection and set the high connect rate to 1000 per seconds.
https://www.unrealircd.org/docs/FAQ#hi-conn-rate
This finishes https://bugs.unrealircd.org/view.php?id=5532
2023-05-18 13:15:17 +02:00
Bram Matthys 89075e532a Send throttling and some other error messages to SSL/TLS users (encrypted).
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.
2023-05-18 11:17:37 +02:00
Bram Matthys 40bdef6cd9 Make exceeds_maxperip() use a hash table (performance improvement) 2023-05-17 19:44:10 +02:00
Bram Matthys b19b70e876 Speed up invisibility checks for delayjoin mode (and when not used too).
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.
2023-05-15 16:58:51 +02:00
Bram Matthys d48ccb1ec8 When rpc.modules.default.conf is loaded, remember last 1000 lines of log
entries for a maximum of 7 days, in memory.
[skip ci]
2023-05-05 12:16:54 +02:00
Bram Matthys 1dcef57970 Add safe_json_decref() which sets pointer to NULL after decref. 2023-05-05 09:51:09 +02:00
Bram Matthys 2922a8ae5a Fix crash if there is a parse error in an included file and there are
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).
2023-04-22 14:08:29 +02:00
Val Lorentz ebcfe6a6bc Add sendtaggednumeric/sendtaggednumericfmt (#250)
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.
2023-04-15 14:34:38 +00:00
Bram Matthys 2184f38e7e Expose more WHOWAS fields in JSON-RPC and change add_history() to take a reason
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.
2023-04-15 09:00:06 +02:00
Bram Matthys e7e2a5a275 whowasdb: write currently online users as well, as if they already
left. This so, if we die, there is still a history of them.
2023-04-15 08:17:54 +02:00
Bram Matthys 45201fffe7 New module 'whowasdb': persistent WHOWAS history (preserved between reboots) 2023-04-14 19:29:45 +02:00
Bram Matthys 66b8259234 JSON-RPC: don't do filtering on low ASCII like we do for JSON logging.
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)
2023-04-13 18:53:49 +02:00
Bram Matthys 7c22f37a9f JSON-RPC: add log.subscribe and log.unsubscribe
https://www.unrealircd.org/docs/JSON-RPC:Log
2023-04-08 17:56:59 +02:00
Bram Matthys 254afbb9c6 Make set::hide-ban-reason not affect opers (eg. show full gline reason).
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.
2023-04-05 07:26:12 +02:00
Bram Matthys 1e315bb953 Add and use command_issued_by_rpc() helper function for internal logging
of commands issued by JSON-RPC.
2023-04-02 16:04:17 +02:00
Bram Matthys 50c3ed2c24 Add unrealircd.org/issued-by if using RPC call channel.set_mode
This also changes the set_channel_mode() function to have
an extra arguments MessageTag *mtags (2nd parameter).
2023-04-02 12:06:52 +02:00
Bram Matthys a3c151a16a RPC: add rpc.set_issuer, eg set to logged in user on the admin panel.
This so UnrealIRCd knows who is issuing the commands.
This information is then passed on to unrealircd.org/issued-by and
is planned to be used by the logging system too.

https://www.unrealircd.org/docs/JSON-RPC:Rpc#rpc.set_issuer
2023-03-31 12:55:31 +02:00
Bram Matthys 5871bd9463 Initial work on unrealircd.org/issued-by message tag.
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.
2023-03-31 12:17:54 +02:00
Bram Matthys 957af0909b RPC: channel.get and channel.list now have optional object_detail_level.
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).
2023-03-27 09:56:03 +02:00
Bram Matthys 04ce8f8ed7 Add helper functions 2023-03-25 12:19:44 +01:00
Bram Matthys 78ce692357 Move ban_exists() to the core (was a helper function in channeldb) 2023-03-25 10:38:05 +01:00
Bram Matthys e83c610b39 Add valid_vhost() and validate oper::vhost too just like vhost::vhost.
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
2023-03-22 10:26:05 +01:00
Bram Matthys 8a48cfb664 Fix not sending CAP DEL on module unload.
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().
2023-03-20 10:55:22 +01:00
Bram Matthys a1e7e9f882 Move deny link { } handling to server module. 2023-03-20 09:09:03 +01:00
Bram Matthys 5c108e0ec3 Don't fetch GeoIP.dat upon blacklist-module geoip_classic;
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.
2023-03-19 11:28:23 +01:00
Bram Matthys 951b913800 Update crule.c, re-porting it from ircu, to hopefully fix some bug(s).
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.
2023-03-19 08:38:54 +01:00
Bram Matthys c6c8bba311 Add find_server_by_uid() which hunts a server for the SID-portion of A UID.
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.
2023-02-08 10:10:27 +01:00
Bram Matthys dd830261db Reject a link for anope or atheme if there is no ulines { } for it.
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.
2023-02-08 09:02:44 +01:00
Bram Matthys 194a0b42f7 JSON-RPC: don't log the RPC calls if they are just for listing/getting,
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; }
	}
}
2023-01-14 16:40:48 +01:00
Bram Matthys a1800f01e9 JSON-RPC / RRPC: Announce all RPC modules and their versions over the wire via moddata.
Needed for rrpc_supported() at a later point, so one can require certain versions etc :p
2023-01-13 18:20:40 +01:00
Bram Matthys b9fcdcdb19 Make server.rehash for remote servers use two possible code paths:
* 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
2023-01-13 18:09:12 +01:00
Bram Matthys b8cbe63915 Support server.rehash for remote servers with full detailed response.
(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().
2023-01-13 16:51:47 +01:00
Bram Matthys 6a4ae9d9ec Support RPC calls to remote servers, where the RPC request/response is
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"
2023-01-13 12:45:51 +01:00
Bram Matthys d6833ae298 JSON-RPC: add server.connect API call
(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.
2023-01-11 16:54:22 +01:00
Bram Matthys a5bdf317fb JSON-RPC: begin with a server.* API, also fill client->local->rpc for
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
2023-01-11 15:43:50 +01:00
Bram Matthys 0244c31742 Split of some code from cmd_eline() into server_ban_exception_parse_mask(),
similar to how *LINE commands use server_ban_parse_mask().
Now used by ELINE and for JSON-RPC later...
2023-01-08 14:56:56 +01:00
Bram Matthys 619282397e Add json_object_get_boolean():
int json_object_get_boolean(json_t *j, const char *name, int default_value)
[skip ci]
2023-01-07 15:54:49 +01:00
Bram Matthys 4378979ad5 Add valid_username() so we can use it at multiple places.
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.
2023-01-07 15:11:52 +01:00
Bram Matthys 14107d88be Add set_channel_topic() and use it from cmd_topic (TOPIC) 2023-01-07 10:16:18 +01:00
Bram Matthys 141c4bc64d Use consts in set_channel_mode()
[skip ci]
2023-01-07 09:39:44 +01:00
Bram Matthys b33628b765 JSON-RPC over Websockets: Fix bug with >64Kb responses.
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()
2023-01-04 13:10:09 +01:00