Anope IRC Services  Version 2.0
cs_enforce.cpp
Go to the documentation of this file.
1 /* ChanServ core functions
2  *
3  * (C) 2003-2014 Anope Team
4  * Contact us at team@anope.org
5  *
6  * Original Coder: GeniusDex <geniusdex@anope.org>
7  *
8  * Please read COPYING and README for further details.
9  *
10  * Send any bug reports to the Anope Coder, as he will be able
11  * to deal with it best.
12  */
13 
14 #include "module.h"
15 
16 class CommandCSEnforce : public Command
17 {
18  private:
20  {
21  bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
22  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce secureops";
23 
24  /* Dirty hack to allow Channel::SetCorrectModes to work ok.
25  * We pretend like SECUREOPS is on so it doesn't ignore that
26  * part of the code. This way we can enforce SECUREOPS even
27  * if it's off.
28  */
29  bool hadsecureops = ci->HasExt("SECUREOPS");
30  ci->Extend<bool>("SECUREOPS");
31 
32  for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
33  {
34  ChanUserContainer *uc = it->second;
35 
36  ci->c->SetCorrectModes(uc->user, false);
37  }
38 
39  if (!hadsecureops)
40  ci->Shrink<bool>("SECUREOPS");
41 
42  source.Reply(_("Secureops enforced on %s."), ci->name.c_str());
43  }
44 
46  {
47  bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
48  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce restricted";
49 
50  std::vector<User *> users;
51  for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
52  {
53  ChanUserContainer *uc = it->second;
54  User *user = uc->user;
55 
56  if (user->IsProtected())
57  continue;
58 
59  if (ci->AccessFor(user).empty())
60  users.push_back(user);
61  }
62 
63  for (unsigned i = 0; i < users.size(); ++i)
64  {
65  User *user = users[i];
66 
67  Anope::string mask = ci->GetIdealBan(user);
68  Anope::string reason = Language::Translate(user, _("RESTRICTED enforced by ")) + source.GetNick();
69  ci->c->SetMode(NULL, "BAN", mask);
70  ci->c->Kick(NULL, user, "%s", reason.c_str());
71  }
72 
73  source.Reply(_("Restricted enforced on %s."), ci->name.c_str());
74  }
75 
77  {
78  bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
79  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce registered only";
80 
81  std::vector<User *> users;
82  for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
83  {
84  ChanUserContainer *uc = it->second;
85  User *user = uc->user;
86 
87  if (user->IsProtected())
88  continue;
89 
90  if (!user->IsIdentified())
91  users.push_back(user);
92  }
93 
94  for (unsigned i = 0; i < users.size(); ++i)
95  {
96  User *user = users[i];
97 
98  Anope::string mask = ci->GetIdealBan(user);
99  Anope::string reason = Language::Translate(user, _("REGONLY enforced by ")) + source.GetNick();
100  if (!ci->c->HasMode("REGISTEREDONLY"))
101  ci->c->SetMode(NULL, "BAN", mask);
102  ci->c->Kick(NULL, user, "%s", reason.c_str());
103  }
104 
105  source.Reply(_("Registered only enforced on %s."), ci->name.c_str());
106  }
107 
109  {
110  bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
111  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce SSL only";
112 
113  std::vector<User *> users;
114  for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
115  {
116  ChanUserContainer *uc = it->second;
117  User *user = uc->user;
118 
119  if (user->IsProtected())
120  continue;
121 
122  if (!user->HasMode("SSL") && !user->HasExt("ssl"))
123  users.push_back(user);
124  }
125 
126  for (unsigned i = 0; i < users.size(); ++i)
127  {
128  User *user = users[i];
129 
130  Anope::string mask = ci->GetIdealBan(user);
131  Anope::string reason = Language::Translate(user, _("SSLONLY enforced by ")) + source.GetNick();
132  if (!ci->c->HasMode("SSL"))
133  ci->c->SetMode(NULL, "BAN", mask);
134  ci->c->Kick(NULL, user, "%s", reason.c_str());
135  }
136 
137  source.Reply(_("SSL only enforced on %s."), ci->name.c_str());
138  }
139 
141  {
142  bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
143  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce bans";
144 
145  std::vector<User *> users;
146  for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
147  {
148  ChanUserContainer *uc = it->second;
149  User *user = uc->user;
150 
151  if (user->IsProtected())
152  continue;
153 
154  if (ci->c->MatchesList(user, "BAN") && !ci->c->MatchesList(user, "EXCEPT"))
155  users.push_back(user);
156  }
157 
158  for (unsigned i = 0; i < users.size(); ++i)
159  {
160  User *user = users[i];
161 
162  Anope::string reason = Language::Translate(user, _("BANS enforced by ")) + source.GetNick();
163  ci->c->Kick(NULL, user, "%s", reason.c_str());
164  }
165 
166  source.Reply(_("Bans enforced on %s."), ci->name.c_str());
167  }
168 
170  {
171  bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
172  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce limit";
173 
174  Anope::string l_str;
175  if (!ci->c->GetParam("LIMIT", l_str))
176  {
177  source.Reply(_("No limit is set on %s."), ci->name.c_str());
178  return;
179  }
180 
181  int l;
182  try
183  {
184  l = convertTo<int>(l_str);
185  if (l < 0)
186  throw ConvertException();
187  }
188  catch (const ConvertException &)
189  {
190  source.Reply(_("The limit on %s is not valid."), ci->name.c_str());
191  return;
192  }
193 
194  std::vector<User *> users;
195  /* The newer users are at the end of the list, so kick users starting from the end */
196  for (Channel::ChanUserList::reverse_iterator it = ci->c->users.rbegin(), it_end = ci->c->users.rend(); it != it_end; ++it)
197  {
198  ChanUserContainer *uc = it->second;
199  User *user = uc->user;
200 
201  if (user->IsProtected())
202  continue;
203 
204  if (!ci->AccessFor(user).empty())
205  continue;
206 
207  if (ci->c->users.size() - users.size() <= static_cast<unsigned>(l))
208  continue;
209 
210  users.push_back(user);
211  }
212 
213  for (unsigned i = 0; i < users.size(); ++i)
214  {
215  User *user = users[i];
216 
217  Anope::string reason = Language::Translate(user, _("LIMIT enforced by ")) + source.GetNick();
218  ci->c->Kick(NULL, user, "%s", reason.c_str());
219  }
220 
221  source.Reply(_("LIMIT enforced on %s, %d users removed."), ci->name.c_str(), users.size());
222  }
223 
224  public:
225  CommandCSEnforce(Module *creator) : Command(creator, "chanserv/enforce", 2, 2)
226  {
227  this->SetDesc(_("Enforce various channel modes and set options"));
228  this->SetSyntax(_("\037channel\037 \037what\037"));
229  }
230 
231  void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
232  {
233  const Anope::string &what = params.size() > 1 ? params[1] : "";
234 
235  ChannelInfo *ci = ChannelInfo::Find(params[0]);
236 
237  if (!ci)
238  source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
239  else if (!ci->c)
240  source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
241  else if (!source.AccessFor(ci).HasPriv("AKICK") && !source.HasPriv("chanserv/access/modify"))
242  source.Reply(ACCESS_DENIED);
243  else if (what.equals_ci("SECUREOPS"))
244  this->DoSecureOps(source, ci);
245  else if (what.equals_ci("RESTRICTED"))
246  this->DoRestricted(source, ci);
247  else if (what.equals_ci("REGONLY"))
248  this->DoRegOnly(source, ci);
249  else if (what.equals_ci("SSLONLY"))
250  this->DoSSLOnly(source, ci);
251  else if (what.equals_ci("BANS"))
252  this->DoBans(source, ci);
253  else if (what.equals_ci("LIMIT"))
254  this->DoLimit(source, ci);
255  else
256  this->OnSyntaxError(source, "");
257  }
258 
259  bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
260  {
261  this->SendSyntax(source);
262  source.Reply(" ");
263  source.Reply(_("Enforce various channel modes and set options. The \037channel\037\n"
264  "option indicates what channel to enforce the modes and options\n"
265  "on. The \037what\037 option indicates what modes and options to\n"
266  "enforce, and can be any of \002SECUREOPS\002, \002RESTRICTED\002, \002REGONLY\002, \002SSLONLY\002,\n"
267  "\002BANS\002, or \002LIMIT\002.\n"
268  " \n"
269  "Use \002SECUREOPS\002 to enforce the SECUREOPS option, even if it is not\n"
270  "enabled. Use \002RESTRICTED\002 to enfore the RESTRICTED option, also\n"
271  "if it's not enabled. Use \002REGONLY\002 to kick all unregistered users\n"
272  "from the channel. Use \002SSLONLY\002 to kick all users not using a secure\n"
273  "connection from the channel. \002BANS\002 will enforce bans on the channel by\n"
274  "kicking users affected by them, and \002LIMIT\002 will kick users until the\n"
275  "user count drops below the channel limit, if one is set."));
276  return true;
277  }
278 };
279 
280 class CSEnforce : public Module
281 {
283 
284  public:
285  CSEnforce(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
286  commandcsenforce(this)
287  {
288 
289  }
290 };
291 
bool HasMode(const Anope::string &name) const
Definition: users.cpp:513
void DoRestricted(CommandSource &source, ChannelInfo *ci)
Definition: cs_enforce.cpp:45
void DoBans(CommandSource &source, ChannelInfo *ci)
Definition: cs_enforce.cpp:140
Definition: hashcomp.h:84
Anope::string name
Definition: regchannel.h:63
#define CHAN_X_NOT_IN_USE
Definition: language.h:85
Anope::string GetIdealBan(User *u) const
Definition: regchannel.cpp:610
void DoSecureOps(CommandSource &source, ChannelInfo *ci)
Definition: cs_enforce.cpp:19
#define ACCESS_DENIED
Definition: language.h:73
Definition: users.h:34
T * Extend(const Anope::string &name, const T &what)
Definition: extensible.h:224
void DoSSLOnly(CommandSource &source, ChannelInfo *ci)
Definition: cs_enforce.cpp:108
void SetDesc(const Anope::string &d)
Definition: command.cpp:130
bool equals_ci(const char *_str) const
Definition: anope.h:78
void Execute(CommandSource &source, const std::vector< Anope::string > &params) anope_override
Definition: cs_enforce.cpp:231
bool HasPriv(const Anope::string &priv) const
Definition: access.cpp:384
const Anope::string & GetNick() const
Definition: command.cpp:26
bool GetParam(const Anope::string &name, Anope::string &target) const
Definition: channels.cpp:513
static ChannelInfo * Find(const Anope::string &name)
Definition: regchannel.cpp:630
void DoRegOnly(CommandSource &source, ChannelInfo *ci)
Definition: cs_enforce.cpp:76
bool IsProtected()
Definition: users.cpp:724
Channel * c
Definition: regchannel.h:79
void Shrink(const Anope::string &name)
Definition: extensible.h:253
virtual void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
Definition: command.cpp:191
void Reply(const char *message,...)
Definition: command.cpp:96
bool HasPriv(const Anope::string &cmd)
Definition: command.cpp:69
bool IsIdentified(bool check_nick=false) const
Definition: users.cpp:427
CommandCSEnforce(Module *creator)
Definition: cs_enforce.cpp:225
#define anope_override
Definition: services.h:56
void SetCorrectModes(User *u, bool give_modes)
Definition: channels.cpp:816
CommandCSEnforce commandcsenforce
Definition: cs_enforce.cpp:282
#define MODULE_INIT(x)
Definition: modules.h:45
CoreExport const char * Translate(const char *string)
Definition: language.cpp:59
ChanUserList users
Definition: channels.h:56
void SetSyntax(const Anope::string &s)
Definition: command.cpp:140
AccessGroup AccessFor(const User *u)
Definition: regchannel.cpp:413
size_t HasMode(const Anope::string &name, const Anope::string &param="")
Definition: channels.cpp:201
CSEnforce(const Anope::string &modname, const Anope::string &creator)
Definition: cs_enforce.cpp:285
bool MatchesList(User *u, const Anope::string &list)
Definition: channels.cpp:713
#define CHAN_X_NOT_REGISTERED
Definition: language.h:84
AccessGroup AccessFor(ChannelInfo *ci)
Definition: command.cpp:41
bool Kick(BotInfo *bi, User *u, const char *reason=NULL,...)
Definition: channels.cpp:762
void DoLimit(CommandSource &source, ChannelInfo *ci)
Definition: cs_enforce.cpp:169
void SetMode(BotInfo *bi, ChannelMode *cm, const Anope::string &param="", bool enforce_mlock=true)
Definition: channels.cpp:401
void SendSyntax(CommandSource &)
Definition: command.cpp:145
const char * c_str() const
Definition: anope.h:117
Definition: logger.h:53
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
Definition: cs_enforce.cpp:259
#define _(x)
Definition: services.h:50
bool HasExt(const Anope::string &name) const
Definition: extensible.cpp:31