The existing approach to invite-notify is deeply flawed--it currently
notifies only the target user's server, and that can't be fixed without
sending notifies for invites that end up not happening.
I'm resolving this by broadcasting a second message, INVITED, from the
target user's server. I'm also pulling it out into an extension while
I'm at it--invite notifies reveal new information, so I don't think
they should be mandatory.
/modrestart used to be implemented as a normal command and could crash
when used remotely because it would reload m_encap, which was on the
call stack at the time. This was fixed in 41390bfe5f. However,
/modreload has exactly the same problem, so I'm giving it the
same treatment.
Incidentally: This bug was first discovered in ircd-seven, where the
`/mod*` commands themselves live in the core, so m_encap was the only way
the crash could happen (and it didn't most of the time, because m_encap
would only be moved if you got unlucky). But `/mod*` are in modules in
charybdis, so /modrestart would have unloaded the code it was in the
middle of executing. With that in mind, I'm not sure how it ever
appeared to work.
Charybdis' rewritten m_grant introduces at least one serious bug without
providing any apparent benefit. I think the best solution here is the
easiest one.
The bug in question is that an empty mode change is triggered after
seven's grant has done its work, and this is necessary in order to
give umodes granted by oper privileges a chance to update. The rewrite
removes this, generating a mode change only if it wants to change the
state of +o, which means the grant victim can keep privileged modes they
no longer have access to, or fail to gain new ones.
Move opername and privset storage to struct User, so it can exist for
remote opers.
On /oper and when bursting opers, send:
:foo OPER opername privset
which sets foo's opername and privset. The contents of the privset on
remote servers come from the remote server's config, so the potential
for confusion exists if these do not match.
If an oper's privset does not exist on a server that sees it, it will
complain, but create a placeholder privset. If the privset is created by
a rehash, this will be reflected properly.
/privs is udpated to take an optional argument, the server to query, and
is now local by default:
/privs [[nick_or_server] nick]
As it stands, oper hiding is rather messy and inconsistent. Add
SeesOper(target, source), which is true iff target should appear as an
oper to source. If I haven't missed something, all commands that reveal
oper status now use the same logic.
general::hide_opers_in_whois is a special case, and affects /whois only.
general::hide_opers is introduced, and has the same effect as giving
everyone oper:hidden. All commands that reveal oper status respect both.
Reloading modules sends CAP DEL followed by an immediate CAP NEW:
:staberinde.local CAP * DEL :account-tag
:staberinde.local CAP * NEW :account-tag
This isn't very nice. /modrestart is particularly bad. In order to avoid
doing this, we remember the capability set at the beginning of module
operations, compare that with the set afterwards, and report only the
differences with CAP {DEL,NEW}.
When a server disconnects the client_exit hook will only be called once
but there could be multiple servers and clients behind that server.
After any client exits, check if the agent is still present.
Otherwise we'd send the * on to services as actual data, which is likely
to fail to decode it (it's not valid Base-64) and reply with an SASL ...
D F which will result in us sending a 904 numeric instead of a 906.
cf. https://github.com/ircv3/ircv3-specifications/pull/298#issuecomment-271336287
Reported-By: James Wheare
ENCAP module. The ms_encap function is responsible for dispatching the
command handler and then the modules will eventually be reloaded.
However, if the ENCAP module is reloaded to a different address, the
stack now contains the address of a function that no longer exists.
Also, in this version of the IRCd, the module restarting functionality
was located in a function that is itself located in a module, so things
will also go badly if that module is reloaded to a different address,
too.
Return immediately from the command handler and have the event loop
call the function responsible for reloading the modules instead.
c.f. release/3.5 commit db05a36210
Reported-by: mniip (Freenode)
When certificate validation fails, the certificate fingerprint won't be
calculated, resulting in an attempt to format NULL into a log line
showing the fingerprint. Instead, add a different error message for
missing fingerprint (i.e. validation failed).
Build the same message but send it to the local client first,
so that the echo-message capability works. But don't do it when
sending a message to yourself.