InspIRCd  3.0
modules.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  * Copyright (C) 2020 Matt Schatz <[email protected]>
5  * Copyright (C) 2019 iwalkalone <[email protected]>
6  * Copyright (C) 2013 Adam <[email protected]>
7  * Copyright (C) 2012-2016, 2018 Attila Molnar <[email protected]>
8  * Copyright (C) 2012-2013, 2017-2021 Sadie Powell <[email protected]>
9  * Copyright (C) 2012 Robby <[email protected]>
10  * Copyright (C) 2009-2010 Daniel De Graaf <[email protected]>
11  * Copyright (C) 2009 Uli Schlachter <[email protected]>
12  * Copyright (C) 2008 Thomas Stagner <[email protected]>
13  * Copyright (C) 2007-2009 Robin Burchell <[email protected]>
14  * Copyright (C) 2007 Oliver Lupton <[email protected]>
15  * Copyright (C) 2006-2007 Dennis Friis <[email protected]>
16  * Copyright (C) 2006 John Brooks <[email protected]>
17  * Copyright (C) 2003-2008, 2010 Craig Edwards <[email protected]>
18  *
19  * This file is part of InspIRCd. InspIRCd is free software: you can
20  * redistribute it and/or modify it under the terms of the GNU General Public
21  * License as published by the Free Software Foundation, version 2.
22  *
23  * This program is distributed in the hope that it will be useful, but WITHOUT
24  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
25  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
26  * details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program. If not, see <http://www.gnu.org/licenses/>.
30  */
31 
32 
33 #pragma once
34 
35 #include "moduledefs.h"
36 #include "dynamic.h"
37 #include "base.h"
38 #include "ctables.h"
39 #include "inspsocket.h"
40 #include "mode.h"
41 
43 enum ModuleFlags
44 {
46  VF_NONE = 0,
47 
49  VF_CORE = 1,
50 
51  /* The module is included with InspIRCd. */
52  VF_VENDOR = 2,
53 
55  VF_COMMON = 4,
56 
58  VF_OPTCOMMON = 8
59 };
60 
62 #define MOD_RES_ALLOW (ModResult(1))
63 
65 #define MOD_RES_PASSTHRU (ModResult(0))
66 
68 #define MOD_RES_DENY (ModResult(-1))
69 
71 class ModResult
72 {
73  private:
75  char result;
76 
77  public:
80  : result(0)
81  {
82  }
83 
85  explicit ModResult(char res)
86  : result(res)
87  {
88  }
89 
91  inline bool operator==(const ModResult& res) const
92  {
93  return result == res.result;
94  }
95 
97  inline bool operator!=(const ModResult& res) const
98  {
99  return result != res.result;
100  }
101 
103  inline bool operator!() const
104  {
105  return !result;
106  }
107 
109  inline bool check(bool def) const
110  {
111  return (result == 1 || (result == 0 && def));
112  }
113 
114  /* Merges two results preferring MOD_RES_ALLOW to MOD_RES_DENY. */
115  inline ModResult operator+(const ModResult& res) const
116  {
117  // If the results are identical or the other result is MOD_RES_PASSTHRU
118  // then return this result.
119  if (result == res.result || res.result == 0)
120  return *this;
121 
122  // If this result is MOD_RES_PASSTHRU then return the other result.
123  if (result == 0)
124  return res;
125 
126  // Otherwise, they are different, and neither is MOD_RES_PASSTHRU.
127  return MOD_RES_ALLOW;
128  }
129 };
130 
136 #define FOREACH_MOD(y,x) do { \
137  const Module::List& _handlers = ServerInstance->Modules->EventHandlers[I_ ## y]; \
138  for (Module::List::const_reverse_iterator _i = _handlers.rbegin(), _next; _i != _handlers.rend(); _i = _next) \
139  { \
140  _next = _i+1; \
141  try \
142  { \
143  if (!(*_i)->dying) \
144  (*_i)->y x ; \
145  } \
146  catch (CoreException& modexcept) \
147  { \
148  ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Exception caught: " + modexcept.GetReason()); \
149  } \
150  } \
151 } while (0);
152 
159 #define DO_EACH_HOOK(n,v,args) \
160 do { \
161  const Module::List& _handlers = ServerInstance->Modules->EventHandlers[I_ ## n]; \
162  for (Module::List::const_reverse_iterator _i = _handlers.rbegin(), _next; _i != _handlers.rend(); _i = _next) \
163  { \
164  _next = _i+1; \
165  try \
166  { \
167  if (!(*_i)->dying) \
168  v = (*_i)->n args;
169 
170 #define WHILE_EACH_HOOK(n) \
171  } \
172  catch (CoreException& except_ ## n) \
173  { \
174  ServerInstance->Logs->Log("MODULE", LOG_DEFAULT, "Exception caught: " + (except_ ## n).GetReason()); \
175  } \
176  } \
177 } while(0)
178 
186 #define FIRST_MOD_RESULT(n,v,args) do { \
187  v = MOD_RES_PASSTHRU; \
188  DO_EACH_HOOK(n,v,args) \
189  { \
190  if (v != MOD_RES_PASSTHRU) \
191  break; \
192  } \
193  WHILE_EACH_HOOK(n); \
194 } while (0)
195 
200 class CoreExport Version
201 {
202  public:
205  const std::string description;
206 
209  const int Flags;
210 
212  const std::string link_data;
213 
215  Version(const std::string &desc, int flags = VF_NONE);
216 
218  Version(const std::string &desc, int flags, const std::string& linkdata);
219 };
220 
221 class CoreExport DataProvider : public ServiceProvider
222 {
223  public:
224  DataProvider(Module* Creator, const std::string& Name)
225  : ServiceProvider(Creator, Name, SERVICE_DATA) {}
226 };
227 
230 enum Priority { PRIORITY_FIRST, PRIORITY_LAST, PRIORITY_BEFORE, PRIORITY_AFTER };
231 
234 enum Implementation
235 {
236  I_On005Numeric,
237  I_OnAcceptConnection,
238  I_OnAddLine,
239  I_OnBackgroundTimer,
240  I_OnBuildNeighborList,
241  I_OnChangeHost,
242  I_OnChangeIdent,
243  I_OnChangeRealHost,
244  I_OnChangeRealName,
245  I_OnChannelDelete,
246  I_OnChannelPreDelete,
247  I_OnCheckBan,
248  I_OnCheckChannelBan,
249  I_OnCheckInvite,
250  I_OnCheckKey,
251  I_OnCheckLimit,
252  I_OnCheckReady,
253  I_OnCommandBlocked,
254  I_OnConnectionFail,
255  I_OnDecodeMetaData,
256  I_OnDelLine,
257  I_OnExpireLine,
258  I_OnExtBanCheck,
259  I_OnGarbageCollect,
260  I_OnKill,
261  I_OnLoadModule,
262  I_OnMode,
263  I_OnModuleRehash,
264  I_OnNumeric,
265  I_OnOper,
266  I_OnPassCompare,
267  I_OnPostChangeRealHost,
268  I_OnPostCommand,
269  I_OnPostConnect,
270  I_OnPostDeoper,
271  I_OnPostJoin,
272  I_OnPostOper,
273  I_OnPostTopicChange,
274  I_OnPreChangeHost,
275  I_OnPreChangeRealName,
276  I_OnPreCommand,
277  I_OnPreMode,
278  I_OnPreRehash,
279  I_OnPreTopicChange,
280  I_OnRawMode,
281  I_OnSendSnotice,
282  I_OnServiceAdd,
283  I_OnServiceDel,
284  I_OnSetConnectClass,
285  I_OnSetUserIP,
286  I_OnShutdown,
287  I_OnUnloadModule,
288  I_OnUserConnect,
289  I_OnUserDisconnect,
290  I_OnUserInit,
291  I_OnUserInvite,
292  I_OnUserJoin,
293  I_OnUserKick,
294  I_OnUserMessage,
295  I_OnUserMessageBlocked,
296  I_OnUserPart,
297  I_OnUserPostInit,
298  I_OnUserPostMessage,
299  I_OnUserPostNick,
300  I_OnUserPreInvite,
301  I_OnUserPreJoin,
302  I_OnUserPreKick,
303  I_OnUserPreMessage,
304  I_OnUserPreNick,
305  I_OnUserPreQuit,
306  I_OnUserQuit,
307  I_OnUserRegister,
308  I_OnUserWrite,
309  I_END
310 };
311 
317 class CoreExport Module : public classbase, public usecountbase
318 {
322  void DetachEvent(Implementation i);
323 
324  public:
326  typedef std::vector<Module*> List;
327 
330  std::string ModuleSourceFile;
331 
335 
339  bool dying;
340 
345  Module();
346 
350  virtual void init() { }
351 
355  CullResult cull() CXX11_OVERRIDE;
356 
360  virtual ~Module();
361 
363  virtual void Prioritize() { }
364 
370  virtual void ReadConfig(ConfigStatus& status);
371 
376  virtual Version GetVersion() = 0;
377 
382  virtual void OnUserConnect(LocalUser* user);
383 
392  virtual ModResult OnUserPreQuit(LocalUser* user, std::string& message, std::string& oper_message);
393 
402  virtual void OnUserQuit(User* user, const std::string &message, const std::string &oper_message);
403 
410  virtual void OnUserDisconnect(LocalUser* user);
411 
416  virtual ModResult OnChannelPreDelete(Channel *chan);
417 
421  virtual void OnChannelDelete(Channel* chan);
422 
432  virtual void OnUserJoin(Membership* memb, bool sync, bool created, CUList& except_list);
433 
439  virtual void OnPostJoin(Membership* memb);
440 
448  virtual void OnUserPart(Membership* memb, std::string &partmessage, CUList& except_list);
449 
460  virtual void OnPreRehash(User* user, const std::string &parameter);
461 
470  virtual void OnModuleRehash(User* user, const std::string &parameter);
471 
479  virtual ModResult OnSendSnotice(char &snomask, std::string &type, const std::string &message);
480 
501  virtual ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven);
502 
512  virtual ModResult OnUserPreKick(User* source, Membership* memb, const std::string &reason);
513 
522  virtual void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& except_list);
523 
530  virtual void OnOper(User* user, const std::string &opertype);
531 
540  virtual void OnPostOper(User* user, const std::string &opername, const std::string &opertype);
541 
545  virtual void OnPostDeoper(User* user);
546 
557  virtual ModResult OnUserPreInvite(User* source,User* dest,Channel* channel, time_t timeout);
558 
569  virtual void OnUserInvite(User* source, User* dest, Channel* channel, time_t timeout, unsigned int notifyrank, CUList& notifyexcepts);
570 
580  virtual ModResult OnUserPreMessage(User* user, const MessageTarget& target, MessageDetails& details);
581 
591  virtual void OnBuildNeighborList(User* source, IncludeChanList& include_c, std::map<User*, bool>& exceptions);
592 
600  virtual ModResult OnUserPreNick(LocalUser* user, const std::string& newnick);
601 
609  virtual void OnUserPostMessage(User* user, const MessageTarget& target, const MessageDetails& details);
610 
618  virtual void OnUserMessage(User* user, const MessageTarget& target, const MessageDetails& details);
619 
627  virtual void OnUserMessageBlocked(User* user, const MessageTarget& target, const MessageDetails& details);
628 
640  virtual void OnMode(User* user, User* usertarget, Channel* chantarget, const Modes::ChangeList& changelist, ModeParser::ModeProcessFlag processflags);
641 
648  virtual void OnDecodeMetaData(Extensible* target, const std::string &extname, const std::string &extdata);
649 
655  virtual void OnChangeHost(User* user, const std::string &newhost);
656 
662  virtual void OnChangeRealHost(User* user, const std::string& newhost);
663 
668  virtual void OnPostChangeRealHost(User* user);
669 
675  virtual void OnChangeRealName(User* user, const std::string& real);
676 
682  virtual void OnChangeIdent(User* user, const std::string &ident);
683 
689  virtual void OnAddLine(User* source, XLine* line);
690 
696  virtual void OnDelLine(User* source, XLine* line);
697 
702  virtual void OnExpireLine(XLine *line);
703 
712  virtual void OnCleanup(ExtensionItem::ExtensibleType type, Extensible* item);
713 
723  virtual void OnUserPostNick(User* user, const std::string &oldnick);
724 
736  virtual ModResult OnPreMode(User* source, User* dest, Channel* channel, Modes::ChangeList& modes);
737 
742  virtual void On005Numeric(std::map<std::string, std::string>& tokens);
743 
757  virtual ModResult OnKill(User* source, User* dest, const std::string &reason);
758 
770  virtual void OnLoadModule(Module* mod);
771 
783  virtual void OnUnloadModule(Module* mod);
784 
791  virtual void OnBackgroundTimer(time_t curtime);
792 
809  virtual ModResult OnPreCommand(std::string& command, CommandBase::Params& parameters, LocalUser* user, bool validated);
810 
822  virtual void OnPostCommand(Command* command, const CommandBase::Params& parameters, LocalUser* user, CmdResult result, bool loop);
823 
829  virtual void OnCommandBlocked(const std::string& command, const CommandBase::Params& parameters, LocalUser* user);
830 
837  virtual void OnUserInit(LocalUser* user);
838 
843  virtual void OnUserPostInit(LocalUser* user);
844 
855  virtual ModResult OnCheckReady(LocalUser* user);
856 
866  virtual ModResult OnUserRegister(LocalUser* user);
867 
876  virtual ModResult OnCheckInvite(User* user, Channel* chan);
877 
889  virtual ModResult OnRawMode(User* user, Channel* chan, ModeHandler* mh, const std::string& param, bool adding);
890 
901  virtual ModResult OnCheckKey(User* user, Channel* chan, const std::string &keygiven);
902 
911  virtual ModResult OnCheckLimit(User* user, Channel* chan);
912 
920  virtual ModResult OnCheckChannelBan(User* user, Channel* chan);
921 
930  virtual ModResult OnCheckBan(User* user, Channel* chan, const std::string& mask);
931 
936  virtual ModResult OnExtBanCheck(User* user, Channel* chan, char type);
937 
944  virtual ModResult OnPreChangeHost(LocalUser* user, const std::string &newhost);
945 
952  virtual ModResult OnPreChangeRealName(LocalUser* user, const std::string &newhost);
953 
962  virtual ModResult OnPreTopicChange(User* user, Channel* chan, const std::string &topic);
963 
970  virtual void OnPostTopicChange(User* user, Channel* chan, const std::string &topic);
971 
982  virtual ModResult OnPassCompare(Extensible* ex, const std::string &password, const std::string &input, const std::string& hashtype);
983 
990  virtual void OnPostConnect(User* user);
991 
999  virtual ModResult OnAcceptConnection(int fd, ListenSocket* sock, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server);
1000 
1006  virtual void OnGarbageCollect();
1007 
1012  virtual ModResult OnSetConnectClass(LocalUser* user, ConnectClass* myclass);
1013 
1014  virtual ModResult OnNumeric(User* user, const Numeric::Numeric& numeric);
1015 
1020  virtual void OnSetUserIP(LocalUser* user);
1021 
1025  virtual void OnServiceAdd(ServiceProvider& service);
1026 
1030  virtual void OnServiceDel(ServiceProvider& service);
1031 
1038  virtual ModResult OnUserWrite(LocalUser* user, ClientProtocol::Message& msg);
1039 
1046  virtual ModResult OnConnectionFail(LocalUser* user, BufferedSocketError error);
1047 
1051  virtual void OnShutdown(const std::string& reason);
1052 };
1053 
1057 class CoreExport ModuleManager : public fakederef<ModuleManager>
1058 {
1059  public:
1060  typedef std::multimap<std::string, ServiceProvider*, irc::insensitive_swo> DataProviderMap;
1061  typedef std::vector<ServiceProvider*> ServiceList;
1062 
1063  private:
1066  std::string LastModuleError;
1067 
1071  std::map<std::string, Module*> Modules;
1072 
1073  enum {
1074  PRIO_STATE_FIRST,
1075  PRIO_STATE_AGAIN,
1076  PRIO_STATE_LAST
1077  } prioritizationState;
1078 
1081  void LoadCoreModules(std::map<std::string, ServiceList>& servicemap);
1082 
1086  bool PrioritizeHooks();
1087 
1092  void UnregisterModes(Module* mod, ModeType modetype);
1093 
1094  public:
1095  typedef std::map<std::string, Module*> ModuleMap;
1096 
1100  Module::List EventHandlers[I_END];
1101 
1103  DataProviderMap DataProviders;
1104 
1113  ServiceList* NewServices;
1114 
1120  static std::string ExpandModName(const std::string& modname);
1121 
1124  ModuleManager();
1125 
1128  ~ModuleManager();
1129 
1146  bool SetPriority(Module* mod, Implementation i, Priority s, Module* which = NULL);
1147 
1156  void SetPriority(Module* mod, Priority s);
1157 
1165  bool Attach(Implementation i, Module* mod);
1166 
1174  bool Detach(Implementation i, Module* mod);
1175 
1181  void Attach(Implementation* i, Module* mod, size_t sz);
1182 
1186  void DetachAll(Module* mod);
1187 
1191  void AttachAll(Module* mod);
1192 
1196  std::string& LastError();
1197 
1203  bool Load(const std::string& filename, bool defer = false);
1204 
1210  bool Unload(Module* module);
1211 
1214  void LoadAll();
1215  void UnloadAll();
1216  void DoSafeUnload(Module*);
1217 
1223  bool CanUnload(Module* mod);
1224 
1230  Module* Find(const std::string &name);
1231 
1233  void AddService(ServiceProvider&);
1234 
1236  void DelService(ServiceProvider&);
1237 
1241  void AddServices(const ServiceList& list);
1242 
1243  inline void AddServices(ServiceProvider** list, int count)
1244  {
1245  for(int i=0; i < count; i++)
1246  AddService(*list[i]);
1247  }
1248 
1252  ServiceProvider* FindService(ServiceType Type, const std::string& name);
1253 
1254  template<typename T> inline T* FindDataService(const std::string& name)
1255  {
1256  return static_cast<T*>(FindService(SERVICE_DATA, name));
1257  }
1258 
1262  const ModuleMap& GetModules() const { return Modules; }
1263 
1268  void AddReferent(const std::string& name, ServiceProvider* service);
1269 
1273  void DelReferent(ServiceProvider* service);
1274 };
Definition: channels.h:41
Definition: clientprotocol.h:182
Definition: ctables.h:118
Definition: ctables.h:198
Definition: configreader.h:509
Definition: base.h:36
Definition: dynamic.h:32
Definition: modules.h:222
Definition: extensible.h:142
ExtensibleType
Definition: extensible.h:40
Definition: socket.h:173
Definition: users.h:745
Definition: membership.h:36
Definition: message.h:34
Definition: message.h:95
Definition: modules.h:72
bool check(bool def) const
Definition: modules.h:109
bool operator==(const ModResult &res) const
Definition: modules.h:91
bool operator!() const
Definition: modules.h:103
ModResult()
Definition: modules.h:79
bool operator!=(const ModResult &res) const
Definition: modules.h:97
ModResult(char res)
Definition: modules.h:85
Definition: mode.h:100
Definition: modechange.h:53
Definition: modules.h:318
std::string ModuleSourceFile
Definition: modules.h:330
DLLManager * ModuleDLLManager
Definition: modules.h:334
std::vector< Module * > List
Definition: modules.h:326
bool dying
Definition: modules.h:339
virtual void init()
Definition: modules.h:350
virtual Version GetVersion()=0
Definition: modules.h:1058
const ModuleMap & GetModules() const
Definition: modules.h:1262
DataProviderMap DataProviders
Definition: modules.h:1103
ServiceList * NewServices
Definition: modules.h:1113
Definition: numeric.h:31
Definition: base.h:249
Definition: users.h:247
Definition: modules.h:201
const std::string link_data
Definition: modules.h:212
const std::string description
Definition: modules.h:205
const int Flags
Definition: modules.h:209
Definition: xline.h:36
Definition: base.h:46
Definition: base.h:113
Definition: users.h:77
Definition: inspircd.h:72
Definition: socket.h:63