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.
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; }
}
}
* 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 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.
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.
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.
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];
| ^~~~~~
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.
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 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.
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().
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.