00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "services.h"
00011 #include "modules.h"
00012 #include "config.h"
00013 #include "sockets.h"
00014 #include "protocol.h"
00015 #include "channels.h"
00016
00017
00018 std::map<User *, StackerInfo *> ModeManager::UserStackerObjects;
00019 std::map<Channel *, StackerInfo *> ModeManager::ChannelStackerObjects;
00020
00021
00022 std::vector<ChannelMode *> ModeManager::ChannelModes;
00023 std::vector<UserMode *> ModeManager::UserModes;
00024
00025
00026 unsigned ModeManager::GenericChannelModes = 0, ModeManager::GenericUserModes = 0;
00027
00028
00029 std::list<std::pair<Anope::string, Anope::string> > ModeManager::ModeLockOn;
00030 std::list<Anope::string> ModeManager::ModeLockOff;
00031
00032
00033 ChannelStatus ModeManager::DefaultBotModes;
00034
00035 Anope::string ChannelStatus::BuildCharPrefixList() const
00036 {
00037 Anope::string ret;
00038
00039 for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
00040 {
00041 ChannelMode *cm = ModeManager::ChannelModes[i];
00042
00043 if (this->modes.count(cm->name))
00044 ret += cm->mchar;
00045 }
00046
00047 return ret;
00048 }
00049
00050 Anope::string ChannelStatus::BuildModePrefixList() const
00051 {
00052 Anope::string ret;
00053
00054 for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
00055 {
00056 ChannelMode *cm = ModeManager::ChannelModes[i];
00057
00058 if (this->modes.count(cm->name))
00059 {
00060 ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm);
00061 ret += cms->Symbol;
00062 }
00063 }
00064
00065 return ret;
00066 }
00067
00068 Mode::Mode(const Anope::string &mname, ModeClass mcl, char mch, ModeType mt) : name(mname), mclass(mcl), mchar(mch), type(mt)
00069 {
00070 }
00071
00072 Mode::~Mode()
00073 {
00074 }
00075
00076 UserMode::UserMode(const Anope::string &un, char mch) : Mode(un, MC_USER, mch, MODE_REGULAR)
00077 {
00078 }
00079
00080 UserMode::~UserMode()
00081 {
00082 }
00083
00084 UserModeParam::UserModeParam(const Anope::string &un, char mch) : UserMode(un, mch)
00085 {
00086 this->type = MODE_PARAM;
00087 }
00088
00089 ChannelMode::ChannelMode(const Anope::string &cm, char mch) : Mode(cm, MC_CHANNEL, mch, MODE_REGULAR)
00090 {
00091 }
00092
00093 ChannelMode::~ChannelMode()
00094 {
00095 }
00096
00097 bool ChannelMode::CanSet(User *u) const
00098 {
00099 if (Config->NoMLock.find(this->mchar) != Anope::string::npos || Config->CSRequire.find(this->mchar) != Anope::string::npos)
00100 return false;
00101 return true;
00102 }
00103
00104 ChannelModeList::ChannelModeList(const Anope::string &cm, char mch) : ChannelMode(cm, mch)
00105 {
00106 this->type = MODE_LIST;
00107 }
00108
00109 ChannelModeList::~ChannelModeList()
00110 {
00111 }
00112
00113 ChannelModeParam::ChannelModeParam(const Anope::string &cm, char mch, bool ma) : ChannelMode(cm, mch), minus_no_arg(ma)
00114 {
00115 this->type = MODE_PARAM;
00116 }
00117
00118 ChannelModeParam::~ChannelModeParam()
00119 {
00120 }
00121
00122 ChannelModeStatus::ChannelModeStatus(const Anope::string &mname, char modeChar, char mSymbol, short mlevel) : ChannelMode(mname, modeChar), Symbol(mSymbol), level(mlevel)
00123 {
00124 this->type = MODE_STATUS;
00125 }
00126
00127 ChannelModeStatus::~ChannelModeStatus()
00128 {
00129 }
00130
00131 bool ChannelModeKey::IsValid(const Anope::string &value) const
00132 {
00133 if (!value.empty() && value.find(':') == Anope::string::npos && value.find(',') == Anope::string::npos)
00134 return true;
00135
00136 return false;
00137 }
00138
00139 bool ChannelModeAdmin::CanSet(User *u) const
00140 {
00141 if (u && u->HasMode("OPER"))
00142 return true;
00143
00144 return false;
00145 }
00146
00147 bool ChannelModeOper::CanSet(User *u) const
00148 {
00149 if (u && u->HasMode("OPER"))
00150 return true;
00151
00152 return false;
00153 }
00154
00155 bool ChannelModeRegistered::CanSet(User *u) const
00156 {
00157 return false;
00158 }
00159
00160 void StackerInfo::AddMode(Mode *mode, bool set, const Anope::string ¶m)
00161 {
00162 bool is_param = mode->type == MODE_PARAM;
00163
00164 std::list<std::pair<Mode *, Anope::string> > *list, *otherlist;
00165 if (set)
00166 {
00167 list = &AddModes;
00168 otherlist = &DelModes;
00169 }
00170 else
00171 {
00172 list = &DelModes;
00173 otherlist = &AddModes;
00174 }
00175
00176
00177 std::list<std::pair<Mode *, Anope::string > >::iterator it, it_end;
00178 for (it = list->begin(), it_end = list->end(); it != it_end; ++it)
00179 {
00180
00181
00182
00183 if (it->first == mode && (is_param || param.equals_cs(it->second)))
00184 {
00185 list->erase(it);
00186
00187 break;
00188 }
00189 }
00190
00191 for (it = otherlist->begin(), it_end = otherlist->end(); it != it_end; ++it)
00192 {
00193
00194
00195
00196 if (it->first == mode && (is_param || param.equals_cs(it->second)))
00197 {
00198 otherlist->erase(it);
00199 return;
00200
00201
00202
00203
00204 }
00205 }
00206
00207
00208 list->push_back(std::make_pair(mode, param));
00209 }
00210
00211 static class ModePipe : public Pipe
00212 {
00213 public:
00214 void OnNotify()
00215 {
00216 ModeManager::ProcessModes();
00217 }
00218 } *modePipe;
00219
00224 template<typename List, typename Object>
00225 static StackerInfo *GetInfo(List &l, Object *o)
00226 {
00227 typename List::const_iterator it = l.find(o);
00228 if (it != l.end())
00229 return it->second;
00230
00231 StackerInfo *s = new StackerInfo();
00232 l[o] = s;
00233 return s;
00234 }
00235
00236 std::list<Anope::string> ModeManager::BuildModeStrings(StackerInfo *info)
00237 {
00238 std::list<Anope::string> ret;
00239 std::list<std::pair<Mode *, Anope::string> >::iterator it, it_end;
00240 Anope::string buf = "+", parambuf;
00241 unsigned NModes = 0;
00242
00243 for (it = info->AddModes.begin(), it_end = info->AddModes.end(); it != it_end; ++it)
00244 {
00245 if (++NModes > IRCD->MaxModes)
00246 {
00247 ret.push_back(buf + parambuf);
00248 buf = "+";
00249 parambuf.clear();
00250 NModes = 1;
00251 }
00252
00253 buf += it->first->mchar;
00254
00255 if (!it->second.empty())
00256 parambuf += " " + it->second;
00257 }
00258
00259 if (buf[buf.length() - 1] == '+')
00260 buf.erase(buf.length() - 1);
00261
00262 buf += "-";
00263 for (it = info->DelModes.begin(), it_end = info->DelModes.end(); it != it_end; ++it)
00264 {
00265 if (++NModes > IRCD->MaxModes)
00266 {
00267 ret.push_back(buf + parambuf);
00268 buf = "-";
00269 parambuf.clear();
00270 NModes = 1;
00271 }
00272
00273 buf += it->first->mchar;
00274
00275 if (!it->second.empty())
00276 parambuf += " " + it->second;
00277 }
00278
00279 if (buf[buf.length() - 1] == '-')
00280 buf.erase(buf.length() - 1);
00281
00282 if (!buf.empty())
00283 ret.push_back(buf + parambuf);
00284
00285 return ret;
00286 }
00287
00288 bool ModeManager::AddUserMode(UserMode *um)
00289 {
00290 if (ModeManager::FindUserModeByChar(um->mchar) != NULL)
00291 return false;
00292
00293 if (um->name.empty())
00294 {
00295 um->name = stringify(++GenericUserModes);
00296 Log() << "ModeManager: Added generic support for user mode " << um->mchar;
00297 }
00298
00299 ModeManager::UserModes.push_back(um);
00300
00301 FOREACH_MOD(I_OnUserModeAdd, OnUserModeAdd(um));
00302
00303 return true;
00304 }
00305
00306 bool ModeManager::AddChannelMode(ChannelMode *cm)
00307 {
00308 if (ModeManager::FindChannelModeByChar(cm->mchar) != NULL)
00309 return false;
00310
00311 if (cm->name.empty())
00312 {
00313 cm->name = stringify(++GenericChannelModes);
00314 Log() << "ModeManager: Added generic support for channel mode " << cm->mchar;
00315 }
00316
00317 ModeManager::ChannelModes.push_back(cm);
00318
00319
00320 UpdateDefaultMLock(Config);
00321
00322 FOREACH_MOD(I_OnChannelModeAdd, OnChannelModeAdd(cm));
00323
00324 return true;
00325 }
00326
00327 void ModeManager::RemoveUserMode(UserMode *um)
00328 {
00329 for (unsigned i = 0; i < ModeManager::UserModes.size(); ++i)
00330 {
00331 UserMode *mode = ModeManager::UserModes[i];
00332 if (um == mode)
00333 {
00334 ModeManager::UserModes.erase(ModeManager::UserModes.begin() + i);
00335 break;
00336 }
00337 }
00338
00339 StackerDel(um);
00340 }
00341
00342 void ModeManager::RemoveChannelMode(ChannelMode *cm)
00343 {
00344 for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
00345 {
00346 ChannelMode *mode = ModeManager::ChannelModes[i];
00347 if (cm == mode)
00348 {
00349 ModeManager::ChannelModes.erase(ModeManager::ChannelModes.begin() + i);
00350 break;
00351 }
00352 }
00353
00354 StackerDel(cm);
00355 }
00356
00357 ChannelMode *ModeManager::FindChannelModeByChar(char Mode)
00358 {
00359 for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
00360 {
00361 ChannelMode *cm = ModeManager::ChannelModes[i];
00362 if (cm->mchar == Mode)
00363 return cm;
00364 }
00365
00366 return NULL;
00367 }
00368
00369 UserMode *ModeManager::FindUserModeByChar(char Mode)
00370 {
00371 for (unsigned i = 0; i < ModeManager::UserModes.size(); ++i)
00372 {
00373 UserMode *um = ModeManager::UserModes[i];
00374 if (um->mchar == Mode)
00375 return um;
00376 }
00377
00378 return NULL;
00379 }
00380
00381 ChannelMode *ModeManager::FindChannelModeByName(const Anope::string &name)
00382 {
00383 for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
00384 {
00385 ChannelMode *cm = ModeManager::ChannelModes[i];
00386 if (cm->name == name)
00387 return cm;
00388 }
00389
00390 return NULL;
00391 }
00392
00393 UserMode *ModeManager::FindUserModeByName(const Anope::string &name)
00394 {
00395 for (unsigned i = 0; i < ModeManager::UserModes.size(); ++i)
00396 {
00397 UserMode *um = ModeManager::UserModes[i];
00398 if (um->name == name)
00399 return um;
00400 }
00401
00402 return NULL;
00403 }
00404
00405 char ModeManager::GetStatusChar(char Value)
00406 {
00407 for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
00408 {
00409 ChannelMode *cm = ModeManager::ChannelModes[i];
00410 if (cm->type == MODE_STATUS)
00411 {
00412 ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm);
00413
00414 if (Value == cms->Symbol)
00415 return cms->mchar;
00416 }
00417 }
00418
00419 return 0;
00420 }
00421
00422 void ModeManager::StackerAdd(const BotInfo *bi, Channel *c, ChannelMode *cm, bool Set, const Anope::string &Param)
00423 {
00424 StackerInfo *s = GetInfo(ChannelStackerObjects, c);
00425 s->AddMode(cm, Set, Param);
00426 if (bi)
00427 s->bi = bi;
00428 else
00429 s->bi = c->ci->WhoSends();
00430
00431 if (!modePipe)
00432 modePipe = new ModePipe();
00433 modePipe->Notify();
00434 }
00435
00436 void ModeManager::StackerAdd(const BotInfo *bi, User *u, UserMode *um, bool Set, const Anope::string &Param)
00437 {
00438 StackerInfo *s = GetInfo(UserStackerObjects, u);
00439 s->AddMode(um, Set, Param);
00440 if (bi)
00441 s->bi = bi;
00442 else
00443 s->bi = NULL;
00444
00445 if (!modePipe)
00446 modePipe = new ModePipe();
00447 modePipe->Notify();
00448 }
00449
00450 void ModeManager::ProcessModes()
00451 {
00452 if (!UserStackerObjects.empty())
00453 {
00454 for (std::map<User *, StackerInfo *>::const_iterator it = UserStackerObjects.begin(), it_end = UserStackerObjects.end(); it != it_end; ++it)
00455 {
00456 User *u = it->first;
00457 StackerInfo *s = it->second;
00458
00459 std::list<Anope::string> ModeStrings = BuildModeStrings(s);
00460 for (std::list<Anope::string>::iterator lit = ModeStrings.begin(), lit_end = ModeStrings.end(); lit != lit_end; ++lit)
00461 IRCD->SendMode(s->bi, u, lit->c_str());
00462 delete it->second;
00463 }
00464 UserStackerObjects.clear();
00465 }
00466
00467 if (!ChannelStackerObjects.empty())
00468 {
00469 for (std::map<Channel *, StackerInfo *>::const_iterator it = ChannelStackerObjects.begin(), it_end = ChannelStackerObjects.end(); it != it_end; ++it)
00470 {
00471 Channel *c = it->first;
00472 StackerInfo *s = it->second;
00473
00474 std::list<Anope::string> ModeStrings = BuildModeStrings(s);
00475 for (std::list<Anope::string>::iterator lit = ModeStrings.begin(), lit_end = ModeStrings.end(); lit != lit_end; ++lit)
00476 IRCD->SendMode(s->bi, c, lit->c_str());
00477 delete it->second;
00478 }
00479 ChannelStackerObjects.clear();
00480 }
00481 }
00482
00483 void ModeManager::StackerDel(User *u)
00484 {
00485 UserStackerObjects.erase(u);
00486 }
00487
00488 void ModeManager::StackerDel(Channel *c)
00489 {
00490 ChannelStackerObjects.erase(c);
00491 }
00492
00493 void ModeManager::StackerDel(Mode *m)
00494 {
00495 for (std::map<User *, StackerInfo *>::const_iterator it = UserStackerObjects.begin(), it_end = UserStackerObjects.end(); it != it_end;)
00496 {
00497 StackerInfo *si = it->second;
00498 ++it;
00499
00500 for (std::list<std::pair<Mode *, Anope::string> >::iterator it2 = si->AddModes.begin(), it2_end = si->AddModes.end(); it2 != it2_end;)
00501 {
00502 if (it2->first == m)
00503 it2 = si->AddModes.erase(it2);
00504 else
00505 ++it2;
00506 }
00507
00508 for (std::list<std::pair<Mode *, Anope::string> >::iterator it2 = si->DelModes.begin(), it2_end = si->DelModes.end(); it2 != it2_end;)
00509 {
00510 if (it2->first == m)
00511 it2 = si->DelModes.erase(it2);
00512 else
00513 ++it2;
00514 }
00515 }
00516
00517 for (std::map<Channel *, StackerInfo *>::const_iterator it = ChannelStackerObjects.begin(), it_end = ChannelStackerObjects.end(); it != it_end;)
00518 {
00519 StackerInfo *si = it->second;
00520 ++it;
00521
00522 for (std::list<std::pair<Mode *, Anope::string> >::iterator it2 = si->AddModes.begin(), it2_end = si->AddModes.end(); it2 != it2_end;)
00523 {
00524 if (it2->first == m)
00525 it2 = si->AddModes.erase(it2);
00526 else
00527 ++it2;
00528 }
00529
00530 for (std::list<std::pair<Mode *, Anope::string> >::iterator it2 = si->DelModes.begin(), it2_end = si->DelModes.end(); it2 != it2_end;)
00531 {
00532 if (it2->first == m)
00533 it2 = si->DelModes.erase(it2);
00534 else
00535 ++it2;
00536 }
00537 }
00538 }
00539
00540 void ModeManager::UpdateDefaultMLock(ServerConfig *config)
00541 {
00542 ModeLockOn.clear();
00543 ModeLockOff.clear();
00544
00545 Anope::string modes;
00546 spacesepstream sep(config->MLock);
00547 sep.GetToken(modes);
00548
00549 int adding = -1;
00550 for (unsigned i = 0, end_mode = modes.length(); i < end_mode; ++i)
00551 {
00552 if (modes[i] == '+')
00553 adding = 1;
00554 else if (modes[i] == '-')
00555 adding = 0;
00556 else if (adding != -1)
00557 {
00558 ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
00559
00560 if (cm && cm->type != MODE_STATUS)
00561 {
00562 Anope::string param;
00563 if (adding == 1 && cm->type != MODE_REGULAR && !sep.GetToken(param))
00564 {
00565 Log() << "Warning: Got default mlock mode " << cm->mchar << " with no param?";
00566 continue;
00567 }
00568
00569 if (cm->type != MODE_LIST)
00570 {
00571 for (std::list<std::pair<Anope::string, Anope::string> >::iterator it = ModeLockOn.begin(), it_end = ModeLockOn.end(); it != it_end; ++it)
00572 if (it->first == cm->name)
00573 {
00574 ModeLockOn.erase(it);
00575 break;
00576 }
00577
00578 for (std::list<Anope::string>::iterator it = ModeLockOff.begin(), it_end = ModeLockOff.end(); it != it_end; ++it)
00579 if (*it == cm->name)
00580 {
00581 ModeLockOff.erase(it);
00582 break;
00583 }
00584 }
00585
00586 if (adding)
00587 ModeLockOn.push_back(std::make_pair(cm->name, param));
00588 else
00589 ModeLockOff.push_back(cm->name);
00590 }
00591 }
00592 }
00593
00594
00595 DefaultBotModes.modes.clear();
00596 for (unsigned i = 0; i < config->BotModes.length(); ++i)
00597 {
00598 ChannelMode *cm = ModeManager::FindChannelModeByChar(config->BotModes[i]);
00599
00600 if (cm && cm->type == MODE_STATUS)
00601 DefaultBotModes.modes.insert(cm->name);
00602 else
00603
00604 DefaultBotModes.modes.insert(config->BotModes[i]);
00605 }
00606 }
00607
00608 Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh), cidr_len(0)
00609 {
00610 Anope::string n, u, h;
00611
00612 size_t at = fh.find('@');
00613 if (at != Anope::string::npos)
00614 {
00615 this->host = fh.substr(at + 1);
00616
00617 const Anope::string &nu = fh.substr(0, at);
00618
00619 size_t ex = nu.find('!');
00620 if (ex != Anope::string::npos)
00621 {
00622 this->user = nu.substr(ex + 1);
00623 this->nick = nu.substr(0, ex);
00624 }
00625 else
00626 this->user = nu;
00627 }
00628 else
00629 {
00630 if (fh.find('.') != Anope::string::npos || fh.find(':') != Anope::string::npos)
00631 this->host = fh;
00632 else
00633 this->nick = fh;
00634 }
00635
00636 at = this->host.find('#');
00637 if (at != Anope::string::npos)
00638 {
00639 this->real = this->host.substr(at + 1);
00640 this->host = this->host.substr(0, at);
00641 }
00642
00643
00644 if (this->nick.find_first_not_of("*") == Anope::string::npos)
00645 this->nick.clear();
00646
00647 if (this->user.find_first_not_of("*") == Anope::string::npos)
00648 this->user.clear();
00649
00650 if (this->host.find_first_not_of("*") == Anope::string::npos)
00651 this->host.clear();
00652 else
00653 {
00654
00655 size_t sl = this->host.find_last_of('/');
00656 if (sl != Anope::string::npos)
00657 {
00658 const Anope::string &cidr_ip = this->host.substr(0, sl),
00659 &cidr_range = this->host.substr(sl + 1);
00660 try
00661 {
00662 sockaddrs addr(cidr_ip);
00663
00664
00665 if (cidr_range.is_pos_number_only())
00666 {
00667 this->cidr_len = convertTo<unsigned short>(cidr_range);
00668
00669
00670
00671
00672
00673 this->host = cidr_ip;
00674
00675 Log(LOG_DEBUG) << "Ban " << this->mask << " has cidr " << this->cidr_len;
00676 }
00677 }
00678 catch (const SocketException &) { }
00679 catch (const ConvertException &) { }
00680 }
00681 }
00682
00683 if (this->real.find_first_not_of("*") == Anope::string::npos)
00684 this->real.clear();
00685 }
00686
00687 const Anope::string Entry::GetMask() const
00688 {
00689 return this->mask;
00690 }
00691
00692 bool Entry::Matches(const User *u, bool full) const
00693 {
00694
00695 if (IRCD->IsExtbanValid(this->mask))
00696 {
00697 ChannelMode *cm = ModeManager::FindChannelModeByName(this->name);
00698 if (cm != NULL && cm->type == MODE_LIST)
00699 {
00700 ChannelModeList *cml = anope_dynamic_static_cast<ChannelModeList *>(cm);
00701 if (cml->Matches(u, this))
00702 return true;
00703 }
00704 }
00705
00706
00707
00708
00709 full |= u->GetDisplayedHost() == u->host;
00710
00711 bool ret = true;
00712
00713 if (!this->nick.empty() && !Anope::Match(u->nick, this->nick))
00714 ret = false;
00715
00716 if (!this->user.empty() && !Anope::Match(u->GetVIdent(), this->user) && (!full || !Anope::Match(u->GetIdent(), this->user)))
00717 ret = false;
00718
00719 if (this->cidr_len && full)
00720 {
00721 try
00722 {
00723 if (!cidr(this->host, this->cidr_len).match(u->ip))
00724 ret = false;
00725 }
00726 catch (const SocketException &)
00727 {
00728 ret = false;
00729 }
00730 }
00731 else if (!this->host.empty() && !Anope::Match(u->GetDisplayedHost(), this->host) && !Anope::Match(u->GetCloakedHost(), this->host) &&
00732 (!full || (!Anope::Match(u->host, this->host) && !Anope::Match(u->ip, this->host))))
00733 ret = false;
00734
00735 if (!this->real.empty() && !Anope::Match(u->realname, this->real))
00736 ret = false;
00737
00738 return ret;
00739 }
00740