Skip to content

Fix services, SASL order, and labeled list replies - #43

Merged
iconidentify merged 1 commit into
mainfrom
fix/issues-37-42
Sep 29, 2026
Merged

iconidentify merged 1 commit into
mainfrom
fix/issues-37-42

Conversation

@iconidentify

Copy link
Copy Markdown
Owner

Summary

  • NickServ SET PASSWORD <current> <new> rotates an identified account. The current password is required, the new hash uses a fresh salt, and the password is not logged. HELP lists the command. Account DROP is intentionally not added: founder rights are still compared by name, so a dropped name must not be re-registered into someone else's channels.
  • NickServ and ChanServ are refused with 432 (Reserved nickname) and cannot be registered as accounts. Comparison uses the rfc1459 fold. PRIVMSG to those names was already intercepted, so this closes impersonation rather than credential theft.
  • A founder who identifies after joining is opped by the same ChanServ MODE +o path JOIN already uses. /msg ChanServ OP #channel restores ops after a deop for an identified founder who is on the channel and is not already op. Logout does not deop. HELP lists OP.
  • SASL 907 is sent when registration has finished (NICK/USER paired and capability negotiation closed) or when this connection already holds an account. AUTHENTICATE during CAP negotiation works in the usual order: CAP LS, NICK, USER, CAP REQ sasl, AUTHENTICATE, CAP END.
  • Replies to the connection that sent the command are buffered and queued as one write. A full queue waits outside the server lock instead of dropping lines, so LIST/WHO/NAMES/mode lists cannot lose their closing numeric. SAFELIST and ELIST=M are on the existing 005 (the line stays under 510 bytes). U/C/T/N are not advertised. 321 is Channel :Users Name.
  • batch and labeled-response are advertised and acknowledged independently. Labeling runs only when both are enabled. A valid label is opaque, required, and at most 64 bytes; an invalid label is ignored and the command still runs. Zero replies become one labeled ACK (not for a client's own PRIVMSG/NOTICE). One reply carries @label. Several are one labeled-response batch: the label is on the open, @batch is merged onto the inner lines, and the close is unlabeled. Client tags are not relayed.

Fixes #37
Fixes #38
Fixes #39
Fixes #40
Fixes #41
Fixes #42

Test plan

  • cargo test --release --locked -- --test-threads=1 (lib 114, e2e 13, ircv3 28, services 6, and the rest of the suite, 0 failed)
  • New end-to-end coverage in tests/services.rs: reserved nicks, password rotation, SASL after NICK/USER, founder op on identify, ChanServ OP, LIST mask and 321 header, labeled PING/PONG/LIST/PRIVMSG
  • CI on this PR

NickServ SET PASSWORD rotates an identified account after checking the
current password, using a fresh salt. NickServ and ChanServ cannot be
taken as nicks or account names. A founder is opped when they identify
on a channel they already joined, and ChanServ OP restores that status
after a deop. Logout does not remove it.

SASL PLAIN is accepted while capability negotiation is still open, which
is the order clients send. Registration is finished only once the welcome
burst is released.

LIST, WHO, NAMES, and the mode-list replies are queued as one write, so a
full reply queue waits instead of dropping the tail. SAFELIST and ELIST=M
are advertised. batch and labeled-response are negotiated independently;
a label is applied only when both are on, and a client's own PRIVMSG is
not labeled.

Fixes #37
Fixes #38
Fixes #39
Fixes #40
Fixes #41
Fixes #42
@iconidentify
iconidentify merged commit a1a8838 into main Sep 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment