1 /* 2 * 3 * (C) 2003-2020 Anope Team 4 * Contact us at team@anope.org 5 * 6 * Please read COPYING and README for further details. 7 * 8 * Based on the original code of Epona by Lara. 9 * Based on the original code of Services by Andy Church. 10 */ 11 12 #ifndef PROTOCOL_H 13 #define PROTOCOL_H 14 15 #include "services.h" 16 #include "anope.h" 17 #include "service.h" 18 19 /* Encapsultes the IRCd protocol we are speaking. */ 20 class CoreExport IRCDProto : public Service 21 { 22 Anope::string proto_name; 23 24 protected: 25 IRCDProto(Module *creator, const Anope::string &proto_name); 26 public: 27 virtual ~IRCDProto(); 28 29 virtual void SendSVSKillInternal(const MessageSource &, User *, const Anope::string &); 30 virtual void SendModeInternal(const MessageSource &, const Channel *, const Anope::string &); 31 virtual void SendModeInternal(const MessageSource &, User *, const Anope::string &); 32 virtual void SendKickInternal(const MessageSource &, const Channel *, User *, const Anope::string &); 33 virtual void SendNoticeInternal(const MessageSource &, const Anope::string &dest, const Anope::string &msg); 34 virtual void SendPrivmsgInternal(const MessageSource &, const Anope::string &dest, const Anope::string &buf); 35 virtual void SendQuitInternal(User *, const Anope::string &buf); 36 virtual void SendPartInternal(User *, const Channel *chan, const Anope::string &buf); 37 virtual void SendGlobopsInternal(const MessageSource &, const Anope::string &buf); 38 virtual void SendCTCPInternal(const MessageSource &, const Anope::string &dest, const Anope::string &buf); 39 virtual void SendNumericInternal(int numeric, const Anope::string &dest, const Anope::string &buf); 40 41 const Anope::string &GetProtocolName(); 42 virtual bool Parse(const Anope::string &, Anope::map<Anope::string> &, Anope::string &, Anope::string &, std::vector<Anope::string> &); 43 virtual Anope::string Format(const Anope::string &source, const Anope::string &message); 44 45 /* Modes used by default by our clients */ 46 Anope::string DefaultPseudoclientModes; 47 /* Can we force change a users's nick? */ 48 bool CanSVSNick; 49 /* Can we force join or part users? */ 50 bool CanSVSJoin; 51 /* Can we set vhosts/vidents on users? */ 52 bool CanSetVHost, CanSetVIdent; 53 /* Can we ban specific gecos from being used? */ 54 bool CanSNLine; 55 /* Can we ban specific nicknames from being used? */ 56 bool CanSQLine; 57 /* Can we ban sepcific channel names from being used? */ 58 bool CanSQLineChannel; 59 /* Can we ban by IP? */ 60 bool CanSZLine; 61 /* Can we place temporary holds on specific nicknames? */ 62 bool CanSVSHold; 63 /* See os_oline */ 64 bool CanSVSO; 65 /* See ns_cert */ 66 bool CanCertFP; 67 /* Whether this IRCd requires unique IDs for each user or server. See TS6/P10. */ 68 bool RequiresID; 69 /* If this IRCd has unique ids, whether the IDs and nicknames are ambiguous */ 70 bool AmbiguousID; 71 /* The maximum number of modes we are allowed to set with one MODE command */ 72 unsigned MaxModes; 73 /* The maximum number of bytes a line may have */ 74 unsigned MaxLine; 75 76 /* Retrieves the next free UID or SID */ 77 virtual Anope::string UID_Retrieve(); 78 virtual Anope::string SID_Retrieve(); 79 80 /** Sets the server in NOOP mode. If NOOP mode is enabled, no users 81 * will be able to oper on the server. 82 * @param s The server 83 * @param mode Whether to turn NOOP on or off 84 */ SendSVSNOOP(const Server * s,bool mode)85 virtual void SendSVSNOOP(const Server *s, bool mode) { } 86 87 /** Sets the topic on a channel 88 * @param bi The bot to set the topic from 89 * @param c The channel to set the topic on. The topic being set is Channel::topic 90 */ 91 virtual void SendTopic(const MessageSource &, Channel *); 92 93 /** Sets a vhost on a user. 94 * @param u The user 95 * @param vident The ident to set 96 * @param vhost The vhost to set 97 */ SendVhost(User * u,const Anope::string & vident,const Anope::string & vhost)98 virtual void SendVhost(User *u, const Anope::string &vident, const Anope::string &vhost) { } SendVhostDel(User *)99 virtual void SendVhostDel(User *) { } 100 101 /** Sets an akill. This is a recursive function that can be called multiple times 102 * for the same xline, but for different users, if the xline is not one that can be 103 * enforced by the IRCd, such as a nick/user/host/realname combination ban. 104 * @param u The user affected by the akill, if known 105 * @param x The akill 106 */ 107 virtual void SendAkill(User *, XLine *) = 0; 108 virtual void SendAkillDel(const XLine *) = 0; 109 110 /* Realname ban */ SendSGLine(User *,const XLine *)111 virtual void SendSGLine(User *, const XLine *) { } SendSGLineDel(const XLine *)112 virtual void SendSGLineDel(const XLine *) { } 113 114 /* IP ban */ SendSZLine(User * u,const XLine *)115 virtual void SendSZLine(User *u, const XLine *) { } SendSZLineDel(const XLine *)116 virtual void SendSZLineDel(const XLine *) { } 117 118 /* Nick ban (and sometimes channel) */ SendSQLine(User *,const XLine * x)119 virtual void SendSQLine(User *, const XLine *x) { } SendSQLineDel(const XLine * x)120 virtual void SendSQLineDel(const XLine *x) { } 121 122 virtual void SendKill(const MessageSource &source, const Anope::string &target, const Anope::string &reason); 123 124 /** Kills a user 125 * @param source Who is doing the kill 126 * @param user The user to be killed 127 * @param fmt Kill reason 128 */ 129 virtual void SendSVSKill(const MessageSource &source, User *user, const char *fmt, ...); 130 131 virtual void SendMode(const MessageSource &source, const Channel *dest, const char *fmt, ...); 132 virtual void SendMode(const MessageSource &source, User *u, const char *fmt, ...); 133 134 /** Introduces a client to the rest of the network 135 * @param u The client to introduce 136 */ 137 virtual void SendClientIntroduction(User *u) = 0; 138 139 virtual void SendKick(const MessageSource &source, const Channel *chan, User *user, const char *fmt, ...); 140 141 virtual void SendNotice(const MessageSource &source, const Anope::string &dest, const char *fmt, ...); 142 virtual void SendPrivmsg(const MessageSource &source, const Anope::string &dest, const char *fmt, ...); 143 virtual void SendAction(const MessageSource &source, const Anope::string &dest, const char *fmt, ...); 144 virtual void SendCTCP(const MessageSource &source, const Anope::string &dest, const char *fmt, ...); 145 146 virtual void SendGlobalNotice(BotInfo *bi, const Server *dest, const Anope::string &msg) = 0; 147 virtual void SendGlobalPrivmsg(BotInfo *bi, const Server *desc, const Anope::string &msg) = 0; 148 149 virtual void SendQuit(User *u, const char *fmt, ...); 150 virtual void SendPing(const Anope::string &servname, const Anope::string &who); 151 virtual void SendPong(const Anope::string &servname, const Anope::string &who); 152 153 /** Joins one of our users to a channel. 154 * @param u The user to join 155 * @param c The channel to join the user to 156 * @param status The status to set on the user after joining. This may or may not already internally 157 * be set on the user. This may include the modes in the join, but will usually place them on the mode 158 * stacker to be set "soon". 159 */ 160 virtual void SendJoin(User *u, Channel *c, const ChannelStatus *status) = 0; 161 virtual void SendPart(User *u, const Channel *chan, const char *fmt, ...); 162 163 /** Force joins a user that isn't ours to a channel. 164 * @param bi The source of the message 165 * @param u The user to join 166 * @param chan The channel to join the user to 167 * @param param Channel key? 168 */ SendSVSJoin(const MessageSource & source,User * u,const Anope::string & chan,const Anope::string & param)169 virtual void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string ¶m) { } 170 171 /** Force parts a user that isn't ours from a channel. 172 * @param source The source of the message 173 * @param u The user to part 174 * @param chan The channel to part the user from 175 * @param param part reason, some IRCds don't support this 176 */ SendSVSPart(const MessageSource & source,User * u,const Anope::string & chan,const Anope::string & param)177 virtual void SendSVSPart(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string ¶m) { } 178 179 virtual void SendInvite(const MessageSource &source, const Channel *c, User *u); 180 virtual void SendGlobops(const MessageSource &source, const char *fmt, ...); 181 182 /** Sets oper flags on a user, currently only supported by Unreal 183 */ SendSVSO(BotInfo *,const Anope::string &,const Anope::string &)184 virtual void SendSVSO(BotInfo *, const Anope::string &, const Anope::string &) { } 185 186 /** Sends a nick change of one of our clients. 187 */ 188 virtual void SendNickChange(User *u, const Anope::string &newnick); 189 190 /** Forces a nick change of a user that isn't ours (SVSNICK) 191 */ 192 virtual void SendForceNickChange(User *u, const Anope::string &newnick, time_t when); 193 194 /** Used to introduce ourselves to our uplink. Usually will SendServer(Me) and any other 195 * initial handshake requirements. 196 */ 197 virtual void SendConnect() = 0; 198 199 /** Called right before we begin our burst, after we have handshaked successfully with the uplink. 200 * At this point none of our servers, users, or channels exist on the uplink 201 */ SendBOB()202 virtual void SendBOB() { } SendEOB()203 virtual void SendEOB() { } 204 SendSVSHold(const Anope::string &,time_t)205 virtual void SendSVSHold(const Anope::string &, time_t) { } SendSVSHoldDel(const Anope::string &)206 virtual void SendSVSHoldDel(const Anope::string &) { } 207 SendSWhois(const MessageSource &,const Anope::string &,const Anope::string &)208 virtual void SendSWhois(const MessageSource &, const Anope::string &, const Anope::string &) { } 209 210 /** Introduces a server to the uplink 211 */ 212 virtual void SendServer(const Server *) = 0; 213 virtual void SendSquit(Server *, const Anope::string &message); 214 215 virtual void SendNumeric(int numeric, const Anope::string &dest, const char *fmt, ...); 216 217 virtual void SendLogin(User *u, NickAlias *na) = 0; 218 virtual void SendLogout(User *u) = 0; 219 220 /** Send a channel creation message to the uplink. 221 * On most TS6 IRCds this is a SJOIN with no nick 222 */ SendChannel(Channel * c)223 virtual void SendChannel(Channel *c) { } 224 225 /** Make the user an IRC operator 226 * Normally this is a simple +o, though some IRCds require us to send the oper type 227 */ 228 virtual void SendOper(User *u); 229 SendSASLMechanisms(std::vector<Anope::string> &)230 virtual void SendSASLMechanisms(std::vector<Anope::string> &) { } SendSASLMessage(const SASL::Message &)231 virtual void SendSASLMessage(const SASL::Message &) { } SendSVSLogin(const Anope::string & uid,const Anope::string & acc,const Anope::string & vident,const Anope::string & vhost)232 virtual void SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) { } 233 234 virtual bool IsNickValid(const Anope::string &); 235 virtual bool IsChannelValid(const Anope::string &); 236 virtual bool IsIdentValid(const Anope::string &); 237 virtual bool IsHostValid(const Anope::string &); IsExtbanValid(const Anope::string &)238 virtual bool IsExtbanValid(const Anope::string &) { return false; } 239 240 /** Retrieve the maximum number of list modes settable on this channel 241 * Defaults to Config->ListSize 242 */ 243 virtual unsigned GetMaxListFor(Channel *c); 244 245 virtual Anope::string NormalizeMask(const Anope::string &mask); 246 }; 247 248 class CoreExport MessageSource 249 { 250 Anope::string source; 251 User *u; 252 Server *s; 253 254 public: 255 MessageSource(const Anope::string &); 256 MessageSource(User *u); 257 MessageSource(Server *s); 258 const Anope::string &GetName() const; 259 const Anope::string &GetSource() const; 260 User *GetUser() const; 261 BotInfo *GetBot() const; 262 Server *GetServer() const; 263 }; 264 265 enum IRCDMessageFlag 266 { 267 IRCDMESSAGE_SOFT_LIMIT, 268 IRCDMESSAGE_REQUIRE_SERVER, 269 IRCDMESSAGE_REQUIRE_USER 270 }; 271 272 class CoreExport IRCDMessage : public Service 273 { 274 Anope::string name; 275 unsigned param_count; 276 std::set<IRCDMessageFlag> flags; 277 public: 278 IRCDMessage(Module *owner, const Anope::string &n, unsigned p = 0); 279 unsigned GetParamCount() const; 280 virtual void Run(MessageSource &, const std::vector<Anope::string> ¶ms) = 0; 281 virtual void Run(MessageSource &, const std::vector<Anope::string> ¶ms, const Anope::map<Anope::string> &tags); 282 SetFlag(IRCDMessageFlag f)283 void SetFlag(IRCDMessageFlag f) { flags.insert(f); } HasFlag(IRCDMessageFlag f)284 bool HasFlag(IRCDMessageFlag f) const { return flags.count(f); } 285 }; 286 287 /** MessageTokenizer allows tokens in the IRC wire format to be read from a string */ 288 class CoreExport MessageTokenizer 289 { 290 private: 291 /** The message we are parsing tokens from. */ 292 Anope::string message; 293 294 /** The current position within the message. */ 295 Anope::string::size_type position; 296 297 public: 298 /** Create a tokenstream and fill it with the provided data. */ 299 MessageTokenizer(const Anope::string &msg); 300 301 /** Retrieve the next \<middle> token in the message. 302 * @param token The next token available, or an empty string if none remain. 303 * @return True if a token was retrieved; otherwise, false. 304 */ 305 bool GetMiddle(Anope::string &token); 306 307 /** Retrieve the next \<trailing> token in the message. 308 * @param token The next token available, or an empty string if none remain. 309 * @return True if a token was retrieved; otherwise, false. 310 */ 311 bool GetTrailing(Anope::string &token); 312 }; 313 314 extern CoreExport IRCDProto *IRCD; 315 316 #endif // PROTOCOL_H 317