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 &param) { }
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 &param) { }
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> &params) = 0;
281 	virtual void Run(MessageSource &, const std::vector<Anope::string> &params, 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