ircd mode handling ------------------ ircd, channels, modes, TSes, netsplits, netjoins, etc. assumption: each client has a unique identifier (no hacking due to reuse or change of identifiers) not all protocols apply TS to bans, this is ignored here many protocols have special cases for TS 0, this is ignored here some protocols have special cases for opless channels (allowing hacked ops on them), this is ignored here halfops can lead to complications, particularly with protocols involving a deopped flag, this is ignored here protocols can be categorized by their handling of bursted channel descriptions (joining nicks, statuses, simple modes and bans) and their handling of mode changes by remote users protocol burst handling mode handling TS6 clear/ignore ignore (TS) bahamut clear/ignore ignore (TS) inspircd 1.1 clear/ignore ignore (TS) TS5 clear/ignore ignore (deopped flag) unreal clear/ignore bounce (no ops) P10 clear/ignore bounce (no ops, zombies) 2.8.21.mu3.2 bounce bounce (deopped flag, zombies) dreamforge bounce bounce (no ops) oldinspircd 1.1 clear/bounce (statuses) accept all bounce (simple modes and lists) a version of P10 without zannels (zombie channels for channel registration in ircd, you do not want to know) is assumed references for these protocols: TS6 - doc/technical/ts6.txt in ratbox or charybdis source tree, http://docs.ircd-ratbox.org/ircd_ts6.shtml, http://www.ircd-ratbox.org/, http://www.ircd-charybdis.org/, see also TS5 bahamut - http://bahamut.dal.net/ TS5 - doc/technical/ts5.txt and doc/technical/README.TSora in hybrid, ratbox or charybdis source tree unreal - http://www.unrealircd.com/ P10 - http://coder-com.undernet.org/ 2.8.21.mu3.2 - the original Undernet ircd, also known as TS8 dreamforge - the old dalnet ircd, ftp://ftp.dal.net/dalnet/server/dreamforge, many forks exist inspircd 1.1 - http://www.inspircd.org/wiki/InspIRCd_Spanning_Tree_%281.1%29 as of 2007-04-11 burst handling treatment of the "old" (existing) and "new" (incoming) modes, depending on the old and new TS "deopped" is an additional channel user flag used by some protocols, set according to the below rules and cleared when a valid +o change is received for the user clear/ignore nothing is ever sent back existing TS < incoming TS: ignore incoming modes, mark users that would be opped "deopped", propagate only joining nicks with existing TS existing TS = incoming TS: merge incoming modes existing TS > incoming TS: clear existing modes, accept incoming modes, update TS bounce existing TS < incoming TS: bounce incoming modes, ignore incoming modes, mark users that would be opped "deopped", propagate only joining nicks with existing TS existing TS = incoming TS: merge incoming modes existing TS > incoming TS: merge incoming modes, update TS clear/bounce existing TS < incoming TS: bounce incoming modes existing TS = incoming TS: merge incoming modes existing TS > incoming TS: clear existing modes, accept incoming modes, update TS mode handling ignore (TS): all user mode changes are sent with the current TS, mode changes with existing TS < incoming TS are ignored (deopped flag): mode changes from "deopped" users are ignored variation on (deopped flag): if a deopped user tries to op a user without valid ops, mark that user deopped also. implemented in hybrid6 and csircd, but not in hybrid7 and ratbox. bounce (deopped flag): mode changes from "deopped" users are bounced if a deopped user tries to op a user without valid ops, mark that user deopped also. (no ops): mode changes from users without ops are bounced (zombies) means kicked users remain in the channel as a zombie (retaining opped and deopped flags) until an (implicit or explicit) confirmation of the kick from their server happens. more precisely, kicks for remote clients that come from a different direction than that client convert the membership into a zombie instead of removing it entirely, and kicks for local clients from remote clients cause a PART to be sent back. Are these protocols correct for simple net rides (no cases with more than two TSes, etc)? assumption: users recreating a channel get a TS greater than the original users scenario: splitrider recreated channel, network rejoins, splitrider is on server S, legitimate channel is on server L the splitrider can use additional clients on S and L for all treated protocols except P10, the protocol for a channel creation is the same as the protocol for bursting a channel with one opped user in it, hence no special case is needed for P10, a CREATE is bounced if the channel already existed and had a lower TS, this is stronger than BURST which just ignores the hacked op. hence no special case is needed. (however, a CREATE with a lower TS will not clear existing modes (relying on CREATE and MODE bounces), so a CREATE winning against a BURST will lead to desync) theorem: in this scenario, mode hacking in TS6 or bahamut is impossible proof hacked modes set before the netjoin: cleared on S (clear/ignore >), ignored on L (clear/ignore <) hacked modes set after S sends burst: cleared on S (clear/ignore >), ignored on L (ignore (TS)) hacked modes set after S has received burst from L: denied by S (local client without ops) in this scenario, mode hacking in TS5 is possible, examples: - splitrider sends a mode after S sends burst and is kicked by a user on L before that mode change arrives on L, deopped flag is lost, L accepts the mode, S still clears it - splitrider ops another user on S after S sends burst, that user sends a mode, L accepts the mode, S still clears it (only works in hybrid7 and ratbox) -> this could be fixed by adding zombies to hybrid6/csircd's variation theorem: in this scenario, mode hacking in P10 is impossible proof hacked modes set before the netjoin: cleared on S (clear/ignore >), ignored on L (clear/ignore <) hacked modes set after S sends burst, by users already opped before the netjoin: cleared on S (clear/ignore >), bounced on L (bounce (no ops, zombies)) hacked modes set after S sends burst, by users opped after the netjoin: cleared on S (clear/ignore >), bounced on L (bounce (no ops, zombies)) hacked modes set after S has received burst from L: denied by S (local client without ops) the above also hold if the network connection suddenly vanishes during the netjoin for the following an extra assumption is needed: all bounces are received properly this assumption consists of two parts: - the network connection does not break, the servers do not shut down while the bounce is sent (a bad assumption on a large network with packetkiddies) - the bounce is accepted by the destination server (2.8.21.mu3.2 and dreamforge use almost the same protocol for bursting and bouncing) this latter part is wrong for dreamforge, S will not accept a +o (bounce) if a splitrider kicked an opped user on L, and S received a KICK, MODE, PRIVMSG or NOTICE from that user. for 2.8.21.mu3.2 this is harder to determine; the code is very hard to read and understand. it seems safer than dreamforge though. theorem: in this scenario, mode hacking in dreamforge is impossible proof hacked modes set before the netjoin: removed later on S (bounce < from L), bounced on L (bounce <) hacked modes set after S sends burst, by users already opped before the netjoin: removed later on S (bounce (no ops) from L), bounced on L (bounce (no ops)) hacked modes set after S sends burst, by users opped after the netjoin: removed later on S (bounce (no ops) from L), bounced on L (bounce (no ops)) hacked modes set after S has received burst from L: removed later on S (bounce (no ops) from L), bounced on L (bounce (no ops)) theorem: in this scenario, mode hacking in 2.8.21.mu3.2 is impossible proof hacked modes set before the netjoin: removed later on S (bounce < from L), bounced on L (bounce <) hacked modes set after S sends burst, by users already opped before the netjoin: removed later on S (bounce (deopped flag, zombies) from L), bounced on L (bounce (deopped flag, zombies)) hacked modes set after S sends burst, by users opped after the netjoin: removed later on S (bounce (deopped flag, zombies) from L), bounced on L (bounce (deopped flag, zombies)) hacked modes set after S has received burst from L: removed later on S (bounce (deopped flag, zombies) from L), bounced on L (bounce (deopped flag, zombies)) mode hacking in old inspircd 1.1 is possible as it accepts all modes from remote clients. to hack, the splitrider should send his mode changes after S has sent the burst. behaviour outside of netbursts the treatment of mode changes by remote users also affects what happens when a user is deopped or kicked while setting a mode. protocols with (TS), (deopped flag) or (deopped flag, zombies) will always let them through, while other protocols may revert them. bounce (no ops) and bounce (no ops, zombies) may lead to disaster if there are special privileges which allow mode hacking and servers assume they have them but actually do not any protocol using bouncing is likely harder to implement and more prone to desyncs (e.g. consider two mode changes from the same direction, the first of which is bounced and the second accepted) Copyright (C) 2006-2007 Jilles Tjoelker