00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "module.h"
00015
00016 class CommandCSEnforce : public Command
00017 {
00018 private:
00019 void DoSecureOps(CommandSource &source, ChannelInfo *ci)
00020 {
00021 bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
00022 Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce secureops";
00023
00024
00025
00026
00027
00028
00029 bool hadsecureops = ci->HasExt("SECUREOPS");
00030 ci->ExtendMetadata("SECUREOPS");
00031
00032 for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
00033 {
00034 ChanUserContainer *uc = *it;
00035
00036 ci->c->SetCorrectModes(uc->user, false, false);
00037 }
00038
00039 if (!hadsecureops)
00040 ci->Shrink("SECUREOPS");
00041
00042 source.Reply(_("Secureops enforced on %s."), ci->name.c_str());
00043 }
00044
00045 void DoRestricted(CommandSource &source, ChannelInfo *ci)
00046 {
00047 bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
00048 Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce restricted";
00049
00050 std::vector<User *> users;
00051 for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
00052 {
00053 ChanUserContainer *uc = *it;
00054 User *user = uc->user;
00055
00056 if (user->IsProtected())
00057 continue;
00058
00059 if (ci->AccessFor(user).empty())
00060 users.push_back(user);
00061 }
00062
00063 for (unsigned i = 0; i < users.size(); ++i)
00064 {
00065 User *user = users[i];
00066
00067 Anope::string mask = ci->GetIdealBan(user);
00068 Anope::string reason = Language::Translate(user, _("RESTRICTED enforced by ")) + source.GetNick();
00069 ci->c->SetMode(NULL, "BAN", mask);
00070 ci->c->Kick(NULL, user, "%s", reason.c_str());
00071 }
00072
00073 source.Reply(_("Restricted enforced on %s."), ci->name.c_str());
00074 }
00075
00076 void DoRegOnly(CommandSource &source, ChannelInfo *ci)
00077 {
00078 bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
00079 Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce registered only";
00080
00081 std::vector<User *> users;
00082 for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
00083 {
00084 ChanUserContainer *uc = *it;
00085 User *user = uc->user;
00086
00087 if (user->IsProtected())
00088 continue;
00089
00090 if (!user->IsIdentified())
00091 users.push_back(user);
00092 }
00093
00094 for (unsigned i = 0; i < users.size(); ++i)
00095 {
00096 User *user = users[i];
00097
00098 Anope::string mask = ci->GetIdealBan(user);
00099 Anope::string reason = Language::Translate(user, _("REGONLY enforced by ")) + source.GetNick();
00100 if (!ci->c->HasMode("REGISTEREDONLY"))
00101 ci->c->SetMode(NULL, "BAN", mask);
00102 ci->c->Kick(NULL, user, "%s", reason.c_str());
00103 }
00104
00105 source.Reply(_("Registered only enforced on %s."), ci->name.c_str());
00106 }
00107
00108 void DoSSLOnly(CommandSource &source, ChannelInfo *ci)
00109 {
00110 bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
00111 Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce SSL only";
00112
00113 std::vector<User *> users;
00114 for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
00115 {
00116 ChanUserContainer *uc = *it;
00117 User *user = uc->user;
00118
00119 if (user->IsProtected())
00120 continue;
00121
00122 if (!user->HasMode("SSL"))
00123 users.push_back(user);
00124 }
00125
00126 for (unsigned i = 0; i < users.size(); ++i)
00127 {
00128 User *user = users[i];
00129
00130 Anope::string mask = ci->GetIdealBan(user);
00131 Anope::string reason = Language::Translate(user, _("SSLONLY enforced by ")) + source.GetNick();
00132 if (!ci->c->HasMode("SSL"))
00133 ci->c->SetMode(NULL, "BAN", mask);
00134 ci->c->Kick(NULL, user, "%s", reason.c_str());
00135 }
00136
00137 source.Reply(_("SSL only enforced on %s."), ci->name.c_str());
00138 }
00139
00140 void DoBans(CommandSource &source, ChannelInfo *ci)
00141 {
00142 bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
00143 Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce bans";
00144
00145 std::vector<User *> users;
00146 for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
00147 {
00148 ChanUserContainer *uc = *it;
00149 User *user = uc->user;
00150
00151 if (user->IsProtected())
00152 continue;
00153
00154 if (ci->c->MatchesList(user, "BAN") && !ci->c->MatchesList(user, "EXCEPT"))
00155 users.push_back(user);
00156 }
00157
00158 for (unsigned i = 0; i < users.size(); ++i)
00159 {
00160 User *user = users[i];
00161
00162 Anope::string reason = Language::Translate(user, _("BANS enforced by ")) + source.GetNick();
00163 ci->c->Kick(NULL, user, "%s", reason.c_str());
00164 }
00165
00166 source.Reply(_("Bans enforced on %s."), ci->name.c_str());
00167 }
00168
00169 void DoLimit(CommandSource &source, ChannelInfo *ci)
00170 {
00171 bool override = !source.AccessFor(ci).HasPriv("AKICK") && source.HasPriv("chanserv/access/modify");
00172 Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enforce limit";
00173
00174 Anope::string l_str;
00175 if (!ci->c->GetParam("LIMIT", l_str))
00176 {
00177 source.Reply(_("No limit is set on %s."), ci->name.c_str());
00178 return;
00179 }
00180
00181 int l;
00182 try
00183 {
00184 l = convertTo<int>(l_str);
00185 if (l < 0)
00186 throw ConvertException();
00187 }
00188 catch (const ConvertException &)
00189 {
00190 source.Reply(_("The limit on %s is not valid."), ci->name.c_str());
00191 return;
00192 }
00193
00194 std::vector<User *> users;
00195
00196 for (Channel::ChanUserList::reverse_iterator it = ci->c->users.rbegin(), it_end = ci->c->users.rend(); it != it_end; ++it)
00197 {
00198 ChanUserContainer *uc = *it;
00199 User *user = uc->user;
00200
00201 if (user->IsProtected())
00202 continue;
00203
00204 if (!ci->AccessFor(user).empty())
00205 continue;
00206
00207 if (ci->c->users.size() - users.size() <= static_cast<unsigned>(l))
00208 continue;
00209
00210 users.push_back(user);
00211 }
00212
00213 for (unsigned i = 0; i < users.size(); ++i)
00214 {
00215 User *user = users[i];
00216
00217 Anope::string reason = Language::Translate(user, _("LIMIT enforced by ")) + source.GetNick();
00218 ci->c->Kick(NULL, user, "%s", reason.c_str());
00219 }
00220
00221 source.Reply(_("LIMIT enforced on %s, %d users removed."), ci->name.c_str(), users.size());
00222 }
00223
00224 public:
00225 CommandCSEnforce(Module *creator) : Command(creator, "chanserv/enforce", 2, 2)
00226 {
00227 this->SetDesc(_("Enforce various channel modes and set options"));
00228 this->SetSyntax(_("\037channel\037 \037what\037"));
00229 }
00230
00231 void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
00232 {
00233 const Anope::string &what = params.size() > 1 ? params[1] : "";
00234
00235 ChannelInfo *ci = ChannelInfo::Find(params[0]);
00236
00237 if (!ci)
00238 source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
00239 else if (!ci->c)
00240 source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
00241 else if (!source.AccessFor(ci).HasPriv("AKICK") && !source.HasPriv("chanserv/access/modify"))
00242 source.Reply(ACCESS_DENIED);
00243 else if (what.equals_ci("SECUREOPS"))
00244 this->DoSecureOps(source, ci);
00245 else if (what.equals_ci("RESTRICTED"))
00246 this->DoRestricted(source, ci);
00247 else if (what.equals_ci("REGONLY"))
00248 this->DoRegOnly(source, ci);
00249 else if (what.equals_ci("SSLONLY"))
00250 this->DoSSLOnly(source, ci);
00251 else if (what.equals_ci("BANS"))
00252 this->DoBans(source, ci);
00253 else if (what.equals_ci("LIMIT"))
00254 this->DoLimit(source, ci);
00255 else
00256 this->OnSyntaxError(source, "");
00257 }
00258
00259 bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
00260 {
00261 this->SendSyntax(source);
00262 source.Reply(" ");
00263 source.Reply(_("Enforce various channel modes and set options. The \037channel\037\n"
00264 "option indicates what channel to enforce the modes and options\n"
00265 "on. The \037what\037 option indicates what modes and options to\n"
00266 "enforce, and can be any of \002SECUREOPS\002, \002RESTRICTED\002, \002REGONLY\002, \002SSLONLY\002,\n"
00267 "\002BANS\002, or \002LIMIT\002.\n"
00268 " \n"
00269 "Use \002SECUREOPS\002 to enforce the SECUREOPS option, even if it is not\n"
00270 "enabled. Use \002RESTRICTED\002 to enfore the RESTRICTED option, also\n"
00271 "if it's not enabled. Use \002REGONLY\002 to kick all unregistered users\n"
00272 "from the channel. Use \002SSLONLY\002 to kick all users not using a secure\n"
00273 "connection from the channel. \002BANS\002 will enforce bans on the channel by\n"
00274 "kicking users affected by them, and \002LIMIT\002 will kick users until the\n"
00275 "user count drops below the channel limit, if one is set."));
00276 return true;
00277 }
00278 };
00279
00280 class CSEnforce : public Module
00281 {
00282 CommandCSEnforce commandcsenforce;
00283
00284 public:
00285 CSEnforce(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
00286 commandcsenforce(this)
00287 {
00288 this->SetAuthor("Anope");
00289
00290 }
00291 };
00292
00293 MODULE_INIT(CSEnforce)