InspIRCd  4.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-2020 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 = 0;
76 
77  public:
79  ModResult() = default;
80 
82  explicit ModResult(char res)
83  : result(res)
84  {
85  }
86 
88  inline bool operator==(const ModResult& res) const
89  {
90  return result == res.result;
91  }
92 
94  inline bool operator!=(const ModResult& res) const
95  {
96  return result != res.result;
97  }
98 
100  inline bool operator!() const
101  {
102  return !result;
103  }
104 
106  inline bool check(bool def) const
107  {
108  return (result == 1 || (result == 0 && def));
109  }
110 
111  /* Merges two results preferring MOD_RES_ALLOW to MOD_RES_DENY. */
112  inline ModResult operator+(const ModResult& res) const
113  {
114  // If the results are identical or the other result is MOD_RES_PASSTHRU
115  // then return this result.
116  if (result == res.result || res.result == 0)
117  return *this;
118 
119  // If this result is MOD_RES_PASSTHRU then return the other result.
120  if (result == 0)
121  return res;
122 
123  // Otherwise, they are different, and neither is MOD_RES_PASSTHRU.
124  return MOD_RES_ALLOW;
125  }
126 };
127 
133 #define FOREACH_MOD(y,x) do { \
134  const Module::List& _handlers = ServerInstance->Modules.EventHandlers[I_ ## y]; \
135  for (Module::List::const_reverse_iterator _i = _handlers.rbegin(), _next; _i != _handlers.rend(); _i = _next) \
136  { \
137  _next = _i+1; \
138  try \
139  { \
140  if (!(*_i)->dying) \
141  (*_i)->y x ; \
142  } \
143  catch (CoreException& modexcept) \
144  { \
145  ServerInstance->Logs.Log("MODULE", LOG_DEFAULT, "Exception caught: " + modexcept.GetReason()); \
146  } \
147  } \
148 } while (0)
149 
156 #define DO_EACH_HOOK(n,v,args) \
157 do { \
158  const Module::List& _handlers = ServerInstance->Modules.EventHandlers[I_ ## n]; \
159  for (Module::List::const_reverse_iterator _i = _handlers.rbegin(), _next; _i != _handlers.rend(); _i = _next) \
160  { \
161  _next = _i+1; \
162  try \
163  { \
164  if (!(*_i)->dying) \
165  v = (*_i)->n args;
166 
167 #define WHILE_EACH_HOOK(n) \
168  } \
169  catch (CoreException& except_ ## n) \
170  { \
171  ServerInstance->Logs.Log("MODULE", LOG_DEFAULT, "Exception caught: " + (except_ ## n).GetReason()); \
172  } \
173  } \
174 } while(0)
175 
183 #define FIRST_MOD_RESULT(n,v,args) do { \
184  v = MOD_RES_PASSTHRU; \
185  DO_EACH_HOOK(n,v,args) \
186  { \
187  if (v != MOD_RES_PASSTHRU) \
188  break; \
189  } \
190  WHILE_EACH_HOOK(n); \
191 } while (0)
192 
193 class CoreExport DataProvider : public ServiceProvider
194 {
195  public:
196  DataProvider(Module* Creator, const std::string& Name)
197  : ServiceProvider(Creator, Name, SERVICE_DATA) {}
198 };
199 
202 enum Priority { PRIORITY_FIRST, PRIORITY_LAST, PRIORITY_BEFORE, PRIORITY_AFTER };
203 
206 enum Implementation
207 {
208  I_OnAcceptConnection,
209  I_OnAddLine,
210  I_OnBackgroundTimer,
211  I_OnBuildNeighborList,
212  I_OnChangeHost,
213  I_OnChangeIdent,
214  I_OnChangeRealHost,
215  I_OnChangeRealName,
216  I_OnChannelDelete,
217  I_OnChannelPreDelete,
218  I_OnCheckBan,
219  I_OnCheckChannelBan,
220  I_OnCheckInvite,
221  I_OnCheckKey,
222  I_OnCheckLimit,
223  I_OnCheckReady,
224  I_OnCommandBlocked,
225  I_OnDecodeMetaData,
226  I_OnDelLine,
227  I_OnExpireLine,
228  I_OnGarbageCollect,
229  I_OnKill,
230  I_OnLoadModule,
231  I_OnMode,
232  I_OnModuleRehash,
233  I_OnNumeric,
234  I_OnOper,
235  I_OnPassCompare,
236  I_OnPostCommand,
237  I_OnPostConnect,
238  I_OnPostDeoper,
239  I_OnPostJoin,
240  I_OnPostOper,
241  I_OnPostTopicChange,
242  I_OnPreChangeHost,
243  I_OnPreChangeRealName,
244  I_OnPreCommand,
245  I_OnPreMode,
246  I_OnPreRehash,
247  I_OnPreTopicChange,
248  I_OnRawMode,
249  I_OnSendSnotice,
250  I_OnServiceAdd,
251  I_OnServiceDel,
252  I_OnSetConnectClass,
253  I_OnSetUserIP,
254  I_OnShutdown,
255  I_OnUnloadModule,
256  I_OnUserConnect,
257  I_OnUserDisconnect,
258  I_OnUserInit,
259  I_OnUserInvite,
260  I_OnUserJoin,
261  I_OnUserKick,
262  I_OnUserMessage,
263  I_OnUserMessageBlocked,
264  I_OnUserPart,
265  I_OnUserPostInit,
266  I_OnUserPostMessage,
267  I_OnUserPostNick,
268  I_OnUserPreInvite,
269  I_OnUserPreJoin,
270  I_OnUserPreKick,
271  I_OnUserPreMessage,
272  I_OnUserPreNick,
273  I_OnUserPreQuit,
274  I_OnUserQuit,
275  I_OnUserRegister,
276  I_OnUserWrite,
277  I_END
278 };
279 
285 class CoreExport Module : public Cullable, public usecountbase
286 {
287  protected:
292  Module(int mprops, const std::string& mdesc);
293 
297  void DetachEvent(Implementation i);
298 
299  public:
301  typedef std::map<std::string, std::string, irc::insensitive_swo> LinkData;
302 
304  typedef std::map<std::string, std::pair<std::optional<std::string>, std::optional<std::string>>, irc::insensitive_swo> LinkDataDiff;
305 
307  typedef std::vector<Module*> List;
308 
311  std::string ModuleSourceFile;
312 
315  DLLManager* ModuleDLLManager = nullptr;
316 
320  bool dying = false;
321 
323  const std::string description;
324 
326  const int properties;
327 
331  virtual void init() { }
332 
336  Cullable::Result Cull() override;
337 
342  virtual void CompareLinkData(const LinkData& otherdata, LinkDataDiff& diffs);
343 
348  virtual void GetLinkData(LinkData& data, std::string& compatdata);
349 
351  std::string GetPropertyString() const;
352 
357  virtual void ReadConfig(ConfigStatus& status);
358 
360  virtual void Prioritize();
361 
366  virtual void OnUserConnect(LocalUser* user);
367 
376  virtual ModResult OnUserPreQuit(LocalUser* user, std::string& message, std::string& oper_message);
377 
386  virtual void OnUserQuit(User* user, const std::string &message, const std::string &oper_message);
387 
394  virtual void OnUserDisconnect(LocalUser* user);
395 
400  virtual ModResult OnChannelPreDelete(Channel *chan);
401 
405  virtual void OnChannelDelete(Channel* chan);
406 
416  virtual void OnUserJoin(Membership* memb, bool sync, bool created, CUList& except_list);
417 
423  virtual void OnPostJoin(Membership* memb);
424 
432  virtual void OnUserPart(Membership* memb, std::string &partmessage, CUList& except_list);
433 
444  virtual void OnPreRehash(User* user, const std::string &parameter);
445 
454  virtual void OnModuleRehash(User* user, const std::string &parameter);
455 
463  virtual ModResult OnSendSnotice(char &snomask, std::string &type, const std::string &message);
464 
486  virtual ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven, bool override);
487 
497  virtual ModResult OnUserPreKick(User* source, Membership* memb, const std::string &reason);
498 
507  virtual void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& except_list);
508 
515  virtual void OnOper(User* user, const std::string &opertype);
516 
525  virtual void OnPostOper(User* user, const std::string &opername, const std::string &opertype);
526 
530  virtual void OnPostDeoper(User* user);
531 
542  virtual ModResult OnUserPreInvite(User* source,User* dest,Channel* channel, time_t timeout);
543 
554  virtual void OnUserInvite(User* source, User* dest, Channel* channel, time_t timeout, unsigned int notifyrank, CUList& notifyexcepts);
555 
565  virtual ModResult OnUserPreMessage(User* user, const MessageTarget& target, MessageDetails& details);
566 
576  virtual void OnBuildNeighborList(User* source, IncludeChanList& include_c, std::map<User*, bool>& exceptions);
577 
585  virtual ModResult OnUserPreNick(LocalUser* user, const std::string& newnick);
586 
594  virtual void OnUserPostMessage(User* user, const MessageTarget& target, const MessageDetails& details);
595 
603  virtual void OnUserMessage(User* user, const MessageTarget& target, const MessageDetails& details);
604 
612  virtual void OnUserMessageBlocked(User* user, const MessageTarget& target, const MessageDetails& details);
613 
625  virtual void OnMode(User* user, User* usertarget, Channel* chantarget, const Modes::ChangeList& changelist, ModeParser::ModeProcessFlag processflags);
626 
633  virtual void OnDecodeMetaData(Extensible* target, const std::string &extname, const std::string &extdata);
634 
640  virtual void OnChangeHost(User* user, const std::string &newhost);
641 
647  virtual void OnChangeRealHost(User* user, const std::string& newhost);
648 
654  virtual void OnChangeRealName(User* user, const std::string& real);
655 
661  virtual void OnChangeIdent(User* user, const std::string &ident);
662 
668  virtual void OnAddLine(User* source, XLine* line);
669 
675  virtual void OnDelLine(User* source, XLine* line);
676 
681  virtual void OnExpireLine(XLine *line);
682 
691  virtual void OnCleanup(ExtensionItem::ExtensibleType type, Extensible* item);
692 
702  virtual void OnUserPostNick(User* user, const std::string &oldnick);
703 
715  virtual ModResult OnPreMode(User* source, User* dest, Channel* channel, Modes::ChangeList& modes);
716 
730  virtual ModResult OnKill(User* source, User* dest, const std::string &reason);
731 
743  virtual void OnLoadModule(Module* mod);
744 
756  virtual void OnUnloadModule(Module* mod);
757 
764  virtual void OnBackgroundTimer(time_t curtime);
765 
782  virtual ModResult OnPreCommand(std::string& command, CommandBase::Params& parameters, LocalUser* user, bool validated);
783 
795  virtual void OnPostCommand(Command* command, const CommandBase::Params& parameters, LocalUser* user, CmdResult result, bool loop);
796 
802  virtual void OnCommandBlocked(const std::string& command, const CommandBase::Params& parameters, LocalUser* user);
803 
810  virtual void OnUserInit(LocalUser* user);
811 
816  virtual void OnUserPostInit(LocalUser* user);
817 
828  virtual ModResult OnCheckReady(LocalUser* user);
829 
839  virtual ModResult OnUserRegister(LocalUser* user);
840 
849  virtual ModResult OnCheckInvite(User* user, Channel* chan);
850 
860  virtual ModResult OnRawMode(User* user, Channel* chan, const Modes::Change& change);
861 
872  virtual ModResult OnCheckKey(User* user, Channel* chan, const std::string &keygiven);
873 
882  virtual ModResult OnCheckLimit(User* user, Channel* chan);
883 
891  virtual ModResult OnCheckChannelBan(User* user, Channel* chan);
892 
901  virtual ModResult OnCheckBan(User* user, Channel* chan, const std::string& mask);
902 
909  virtual ModResult OnPreChangeHost(LocalUser* user, const std::string &newhost);
910 
917  virtual ModResult OnPreChangeRealName(LocalUser* user, const std::string &newhost);
918 
927  virtual ModResult OnPreTopicChange(User* user, Channel* chan, const std::string &topic);
928 
935  virtual void OnPostTopicChange(User* user, Channel* chan, const std::string &topic);
936 
947  virtual ModResult OnPassCompare(Extensible* ex, const std::string &password, const std::string &input, const std::string& hashtype);
948 
955  virtual void OnPostConnect(User* user);
956 
964  virtual ModResult OnAcceptConnection(int fd, ListenSocket* sock, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server);
965 
971  virtual void OnGarbageCollect();
972 
977  virtual ModResult OnSetConnectClass(LocalUser* user, std::shared_ptr<ConnectClass> myclass);
978 
979  virtual ModResult OnNumeric(User* user, const Numeric::Numeric& numeric);
980 
984  virtual void OnSetUserIP(LocalUser* user);
985 
989  virtual void OnServiceAdd(ServiceProvider& service);
990 
994  virtual void OnServiceDel(ServiceProvider& service);
995 
1002  virtual ModResult OnUserWrite(LocalUser* user, ClientProtocol::Message& msg);
1003 
1007  virtual void OnShutdown(const std::string& reason);
1008 };
1009 
1013 class CoreExport ModuleManager
1014 {
1015  public:
1016  typedef std::multimap<std::string, ServiceProvider*, irc::insensitive_swo> DataProviderMap;
1017  typedef std::vector<ServiceProvider*> ServiceList;
1018 
1019  private:
1022  std::string LastModuleError;
1023 
1027  std::map<std::string, Module*> Modules;
1028 
1029  enum {
1030  PRIO_STATE_FIRST,
1031  PRIO_STATE_AGAIN,
1032  PRIO_STATE_LAST
1033  } prioritizationState;
1034 
1037  void LoadCoreModules(std::map<std::string, ServiceList>& servicemap);
1038 
1042  bool PrioritizeHooks();
1043 
1048  void UnregisterModes(Module* mod, ModeType modetype);
1049 
1050  public:
1051  typedef std::map<std::string, Module*> ModuleMap;
1052 
1056  Module::List EventHandlers[I_END];
1057 
1059  DataProviderMap DataProviders;
1060 
1069  ServiceList* NewServices;
1070 
1076  static std::string ExpandModName(const std::string& modname);
1077 
1083  static std::string ShrinkModName(const std::string& modname);
1084 
1101  bool SetPriority(Module* mod, Implementation i, Priority s, Module* which = NULL);
1102 
1111  void SetPriority(Module* mod, Priority s);
1112 
1120  bool Attach(Implementation i, Module* mod);
1121 
1129  bool Detach(Implementation i, Module* mod);
1130 
1136  void Attach(Implementation* i, Module* mod, size_t sz);
1137 
1141  void DetachAll(Module* mod);
1142 
1146  void AttachAll(Module* mod);
1147 
1151  std::string& LastError();
1152 
1158  bool Load(const std::string& filename, bool defer = false);
1159 
1165  bool Unload(Module* module);
1166 
1169  void LoadAll();
1170  void UnloadAll();
1171  void DoSafeUnload(Module*);
1172 
1178  bool CanUnload(Module* mod);
1179 
1185  Module* Find(const std::string &name);
1186 
1188  void AddService(ServiceProvider&);
1189 
1191  void DelService(ServiceProvider&);
1192 
1196  void AddServices(const ServiceList& list);
1197 
1198  inline void AddServices(ServiceProvider** list, int count)
1199  {
1200  for(int i=0; i < count; i++)
1201  AddService(*list[i]);
1202  }
1203 
1207  ServiceProvider* FindService(ServiceType Type, const std::string& name);
1208 
1209  template<typename T> inline T* FindDataService(const std::string& name)
1210  {
1211  return static_cast<T*>(FindService(SERVICE_DATA, name));
1212  }
1213 
1217  const ModuleMap& GetModules() const { return Modules; }
1218 
1223  void AddReferent(const std::string& name, ServiceProvider* service);
1224 
1228  void DelReferent(ServiceProvider* service);
1229 };
Definition: channels.h:41
Definition: clientprotocol.h:182
Definition: ctables.h:128
Definition: ctables.h:208
Definition: configreader.h:537
Definition: cull.h:38
Definition: cull.h:30
virtual Result Cull()
Definition: cull.cpp:54
Definition: dynamic.h:42
Definition: modules.h:194
Definition: extensible.h:132
ExtensibleType
Definition: extensible.h:32
Definition: socket.h:173
Definition: users.h:658
Definition: membership.h:36
Definition: message.h:34
Definition: message.h:92
Definition: modules.h:72
bool check(bool def) const
Definition: modules.h:106
bool operator==(const ModResult &res) const
Definition: modules.h:88
bool operator!() const
Definition: modules.h:100
ModResult()=default
bool operator!=(const ModResult &res) const
Definition: modules.h:94
ModResult(char res)
Definition: modules.h:82
Definition: modechange.h:71
Definition: modules.h:286
const int properties
Definition: modules.h:326
std::map< std::string, std::pair< std::optional< std::string >, std::optional< std::string > >, irc::insensitive_swo > LinkDataDiff
Definition: modules.h:304
std::map< std::string, std::string, irc::insensitive_swo > LinkData
Definition: modules.h:301
std::string ModuleSourceFile
Definition: modules.h:311
const std::string description
Definition: modules.h:323
std::vector< Module * > List
Definition: modules.h:307
virtual void init()
Definition: modules.h:331
Definition: modules.h:1014
const ModuleMap & GetModules() const
Definition: modules.h:1217
DataProviderMap DataProviders
Definition: modules.h:1059
ServiceList * NewServices
Definition: modules.h:1069
Definition: numeric.h:31
Definition: base.h:204
Definition: users.h:238
Definition: xline.h:36
Definition: base.h:72
Definition: modechange.h:32
Definition: hashcomp.h:101
Definition: socket.h:63