00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "inspircd.h"
00017 #include "xline.h"
00018 #include "bancache.h"
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 bool XLine::Matches(User *u)
00053 {
00054 return false;
00055 }
00056
00057
00058
00059
00060 void XLineManager::CheckELines()
00061 {
00062 ContainerIter n = lookup_lines.find("E");
00063
00064 if (n == lookup_lines.end())
00065 return;
00066
00067 XLineLookup& ELines = n->second;
00068
00069 if (ELines.empty())
00070 return;
00071
00072 for (std::vector<User*>::const_iterator u2 = ServerInstance->Users->local_users.begin(); u2 != ServerInstance->Users->local_users.end(); u2++)
00073 {
00074 User* u = (User*)(*u2);
00075
00076
00077 LookupIter safei;
00078
00079 for (LookupIter i = ELines.begin(); i != ELines.end(); )
00080 {
00081 safei = i;
00082 safei++;
00083
00084 XLine *e = i->second;
00085 u->exempt = e->Matches(u);
00086
00087 i = safei;
00088 }
00089 }
00090 }
00091
00092
00093 XLineLookup* XLineManager::GetAll(const std::string &type)
00094 {
00095 ContainerIter n = lookup_lines.find(type);
00096
00097 if (n == lookup_lines.end())
00098 return NULL;
00099
00100 LookupIter safei;
00101 const time_t current = ServerInstance->Time();
00102
00103
00104 for (LookupIter x = n->second.begin(); x != n->second.end(); )
00105 {
00106 safei = x;
00107 safei++;
00108 if (x->second->duration && current > x->second->expiry)
00109 {
00110 ExpireLine(n, x);
00111 }
00112 x = safei;
00113 }
00114
00115 return &(n->second);
00116 }
00117
00118 void XLineManager::DelAll(const std::string &type)
00119 {
00120 ContainerIter n = lookup_lines.find(type);
00121
00122 if (n == lookup_lines.end())
00123 return;
00124
00125 LookupIter x;
00126
00127
00128 while ((x = n->second.begin()) != n->second.end())
00129 {
00130 ExpireLine(n, x);
00131 }
00132 }
00133
00134 std::vector<std::string> XLineManager::GetAllTypes()
00135 {
00136 std::vector<std::string> items;
00137 for (ContainerIter x = lookup_lines.begin(); x != lookup_lines.end(); ++x)
00138 items.push_back(x->first);
00139 return items;
00140 }
00141
00142 IdentHostPair XLineManager::IdentSplit(const std::string &ident_and_host)
00143 {
00144 IdentHostPair n = std::make_pair<std::string,std::string>("*","*");
00145 std::string::size_type x = ident_and_host.find('@');
00146 if (x != std::string::npos)
00147 {
00148 n.second = ident_and_host.substr(x + 1,ident_and_host.length());
00149 n.first = ident_and_host.substr(0, x);
00150 if (!n.first.length())
00151 n.first.assign("*");
00152 if (!n.second.length())
00153 n.second.assign("*");
00154 }
00155 else
00156 {
00157 n.first = "";
00158 n.second = ident_and_host;
00159 }
00160
00161 return n;
00162 }
00163
00164
00165
00166 bool XLineManager::AddLine(XLine* line, User* user)
00167 {
00168
00169
00170 ServerInstance->BanCache->RemoveEntries(line->type, false);
00171
00172 if (DelLine(line->Displayable(), line->type, user, true))
00173 return false;
00174
00175
00176 XLineFactory* xlf = GetFactory(line->type);
00177 if (!xlf)
00178 return false;
00179
00180 if (xlf->AutoApplyToUserList(line))
00181 pending_lines.push_back(line);
00182
00183 lookup_lines[line->type][line->Displayable()] = line;
00184 line->OnAdd();
00185
00186 FOREACH_MOD(I_OnAddLine,OnAddLine(user, line));
00187
00188 return true;
00189 }
00190
00191
00192
00193 bool XLineManager::DelLine(const char* hostmask, const std::string &type, User* user, bool simulate)
00194 {
00195 ContainerIter x = lookup_lines.find(type);
00196
00197 if (x == lookup_lines.end())
00198 return false;
00199
00200 LookupIter y = x->second.find(hostmask);
00201
00202 if (y == x->second.end())
00203 return false;
00204
00205 if (simulate)
00206 return true;
00207
00208 ServerInstance->BanCache->RemoveEntries(y->second->type, true);
00209
00210 FOREACH_MOD(I_OnDelLine,OnDelLine(user, y->second));
00211
00212 y->second->Unset();
00213
00214 std::vector<XLine*>::iterator pptr = std::find(pending_lines.begin(), pending_lines.end(), y->second);
00215 if (pptr != pending_lines.end())
00216 pending_lines.erase(pptr);
00217
00218 delete y->second;
00219 x->second.erase(y);
00220
00221 return true;
00222 }
00223
00224
00225 void ELine::Unset()
00226 {
00227
00228 for (std::vector<User*>::const_iterator u2 = ServerInstance->Users->local_users.begin(); u2 != ServerInstance->Users->local_users.end(); u2++)
00229 {
00230 User* u = (User*)(*u2);
00231 u->exempt = false;
00232 }
00233
00234 ServerInstance->XLines->CheckELines();
00235 }
00236
00237
00238
00239 XLine* XLineManager::MatchesLine(const std::string &type, User* user)
00240 {
00241 ContainerIter x = lookup_lines.find(type);
00242
00243 if (x == lookup_lines.end())
00244 return NULL;
00245
00246 const time_t current = ServerInstance->Time();
00247
00248 LookupIter safei;
00249
00250 for (LookupIter i = x->second.begin(); i != x->second.end(); )
00251 {
00252 safei = i;
00253 safei++;
00254
00255 if (i->second->Matches(user))
00256 {
00257 if (i->second->duration && current > i->second->expiry)
00258 {
00259
00260 ExpireLine(x, i);
00261
00262
00263
00264 i = safei;
00265 continue;
00266 }
00267 else
00268 return i->second;
00269 }
00270
00271 i = safei;
00272 }
00273 return NULL;
00274 }
00275
00276 XLine* XLineManager::MatchesLine(const std::string &type, const std::string &pattern)
00277 {
00278 ContainerIter x = lookup_lines.find(type);
00279
00280 if (x == lookup_lines.end())
00281 return NULL;
00282
00283 const time_t current = ServerInstance->Time();
00284
00285 LookupIter safei;
00286
00287 for (LookupIter i = x->second.begin(); i != x->second.end(); )
00288 {
00289 safei = i;
00290 safei++;
00291
00292 if (i->second->Matches(pattern))
00293 {
00294 if (i->second->duration && current > i->second->expiry)
00295 {
00296
00297 ExpireLine(x, i);
00298
00299 i = safei;
00300 continue;
00301 }
00302 else
00303 return i->second;
00304 }
00305
00306 i = safei;
00307 }
00308 return NULL;
00309 }
00310
00311
00312 void XLineManager::ExpireLine(ContainerIter container, LookupIter item)
00313 {
00314 FOREACH_MOD(I_OnExpireLine, OnExpireLine(item->second));
00315
00316 item->second->DisplayExpiry();
00317 item->second->Unset();
00318
00319
00320
00321
00322
00323 std::vector<XLine*>::iterator pptr = std::find(pending_lines.begin(), pending_lines.end(), item->second);
00324 if (pptr != pending_lines.end())
00325 pending_lines.erase(pptr);
00326
00327 delete item->second;
00328 container->second.erase(item);
00329 }
00330
00331
00332
00333 void XLineManager::ApplyLines()
00334 {
00335 for (std::vector<User*>::const_iterator u2 = ServerInstance->Users->local_users.begin(); u2 != ServerInstance->Users->local_users.end(); u2++)
00336 {
00337 User* u = (User*)(*u2);
00338
00339 for (std::vector<XLine *>::iterator i = pending_lines.begin(); i != pending_lines.end(); i++)
00340 {
00341 XLine *x = *i;
00342 if (x->Matches(u))
00343 x->Apply(u);
00344 }
00345 }
00346
00347 pending_lines.clear();
00348 }
00349
00350 void XLineManager::InvokeStats(const std::string &type, int numeric, User* user, string_list &results)
00351 {
00352 std::string sn = ServerInstance->Config->ServerName;
00353
00354 ContainerIter n = lookup_lines.find(type);
00355
00356 time_t current = ServerInstance->Time();
00357
00358 LookupIter safei;
00359
00360 if (n != lookup_lines.end())
00361 {
00362 XLineLookup& list = n->second;
00363 for (LookupIter i = list.begin(); i != list.end(); )
00364 {
00365 safei = i;
00366 safei++;
00367
00368 if (i->second->duration && current > i->second->expiry)
00369 {
00370 ExpireLine(n, i);
00371 }
00372 else
00373 results.push_back(sn+" "+ConvToStr(numeric)+" "+user->nick+" :"+i->second->Displayable()+" "+
00374 ConvToStr(i->second->set_time)+" "+ConvToStr(i->second->duration)+" "+std::string(i->second->source)+" :"+(i->second->reason));
00375 i = safei;
00376 }
00377 }
00378 }
00379
00380
00381 XLineManager::XLineManager(InspIRCd* Instance) : ServerInstance(Instance)
00382 {
00383 GFact = new GLineFactory(Instance);
00384 EFact = new ELineFactory(Instance);
00385 KFact = new KLineFactory(Instance);
00386 QFact = new QLineFactory(Instance);
00387 ZFact = new ZLineFactory(Instance);
00388
00389 RegisterFactory(GFact);
00390 RegisterFactory(EFact);
00391 RegisterFactory(KFact);
00392 RegisterFactory(QFact);
00393 RegisterFactory(ZFact);
00394 }
00395
00396 XLineManager::~XLineManager()
00397 {
00398 UnregisterFactory(GFact);
00399 UnregisterFactory(EFact);
00400 UnregisterFactory(KFact);
00401 UnregisterFactory(QFact);
00402 UnregisterFactory(ZFact);
00403
00404 delete GFact;
00405 delete EFact;
00406 delete KFact;
00407 delete QFact;
00408 delete ZFact;
00409
00410
00411 for (XLineContainer::iterator i = lookup_lines.begin(); i != lookup_lines.end(); i++)
00412 {
00413 for (XLineLookup::iterator j = i->second.begin(); j != i->second.end(); j++)
00414 {
00415 delete j->second;
00416 }
00417 i->second.clear();
00418 }
00419 lookup_lines.clear();
00420
00421 }
00422
00423 void XLine::Apply(User* u)
00424 {
00425 }
00426
00427 bool XLine::IsBurstable()
00428 {
00429 return true;
00430 }
00431
00432 void XLine::DefaultApply(User* u, const std::string &line, bool bancache)
00433 {
00434 char sreason[MAXBUF];
00435 snprintf(sreason, MAXBUF, "%s-Lined: %s", line.c_str(), this->reason);
00436 if (*ServerInstance->Config->MoronBanner)
00437 u->WriteServ("NOTICE %s :*** %s", u->nick.c_str(), ServerInstance->Config->MoronBanner);
00438
00439 if (ServerInstance->Config->HideBans)
00440 ServerInstance->Users->QuitUser(u, line + "-Lined", sreason);
00441 else
00442 ServerInstance->Users->QuitUser(u, sreason);
00443
00444
00445 if (bancache)
00446 {
00447 ServerInstance->Logs->Log("BANCACHE", DEBUG, std::string("BanCache: Adding positive hit (") + line + ") for " + u->GetIPString());
00448 if (this->duration > 0)
00449 ServerInstance->BanCache->AddHit(u->GetIPString(), this->type, line + "-Lined: " + this->reason, this->duration);
00450 else
00451 ServerInstance->BanCache->AddHit(u->GetIPString(), this->type, line + "-Lined: " + this->reason);
00452 }
00453 }
00454
00455 bool KLine::Matches(User *u)
00456 {
00457 if (u->exempt)
00458 return false;
00459
00460 if (InspIRCd::Match(u->ident, this->identmask))
00461 {
00462 if (InspIRCd::MatchCIDR(u->host, this->hostmask) ||
00463 InspIRCd::MatchCIDR(u->GetIPString(), this->hostmask))
00464 {
00465 return true;
00466 }
00467 }
00468
00469 return false;
00470 }
00471
00472 void KLine::Apply(User* u)
00473 {
00474 DefaultApply(u, "K", (strcmp(this->identmask, "*") == 0) ? true : false);
00475 }
00476
00477 bool GLine::Matches(User *u)
00478 {
00479 if (u->exempt)
00480 return false;
00481
00482 if (InspIRCd::Match(u->ident, this->identmask))
00483 {
00484 if (InspIRCd::MatchCIDR(u->host, this->hostmask) ||
00485 InspIRCd::MatchCIDR(u->GetIPString(), this->hostmask))
00486 {
00487 return true;
00488 }
00489 }
00490
00491 return false;
00492 }
00493
00494 void GLine::Apply(User* u)
00495 {
00496 DefaultApply(u, "G", (strcmp(this->identmask, "*") == 0) ? true : false);
00497 }
00498
00499 bool ELine::Matches(User *u)
00500 {
00501 if (u->exempt)
00502 return false;
00503
00504 if (InspIRCd::Match(u->ident, this->identmask))
00505 {
00506 if (InspIRCd::MatchCIDR(u->host, this->hostmask) ||
00507 InspIRCd::MatchCIDR(u->GetIPString(), this->hostmask))
00508 {
00509 return true;
00510 }
00511 }
00512
00513 return false;
00514 }
00515
00516 bool ZLine::Matches(User *u)
00517 {
00518 if (u->exempt)
00519 return false;
00520
00521 if (InspIRCd::MatchCIDR(u->GetIPString(), this->ipaddr))
00522 return true;
00523 else
00524 return false;
00525 }
00526
00527 void ZLine::Apply(User* u)
00528 {
00529 DefaultApply(u, "Z", true);
00530 }
00531
00532
00533 bool QLine::Matches(User *u)
00534 {
00535 if (u->exempt)
00536 return false;
00537
00538 if (InspIRCd::Match(u->nick, this->nick))
00539 return true;
00540
00541 return false;
00542 }
00543
00544 void QLine::Apply(User* u)
00545 {
00546
00547 u->ForceNickChange(u->uuid.c_str());
00548 }
00549
00550
00551 bool ZLine::Matches(const std::string &str)
00552 {
00553 if (InspIRCd::MatchCIDR(str, this->ipaddr))
00554 return true;
00555 else
00556 return false;
00557 }
00558
00559 bool QLine::Matches(const std::string &str)
00560 {
00561 if (InspIRCd::Match(str, this->nick))
00562 return true;
00563
00564 return false;
00565 }
00566
00567 bool ELine::Matches(const std::string &str)
00568 {
00569 return (InspIRCd::MatchCIDR(str, matchtext));
00570 }
00571
00572 bool KLine::Matches(const std::string &str)
00573 {
00574 return (InspIRCd::MatchCIDR(str.c_str(), matchtext));
00575 }
00576
00577 bool GLine::Matches(const std::string &str)
00578 {
00579 return (InspIRCd::MatchCIDR(str, matchtext));
00580 }
00581
00582 void ELine::OnAdd()
00583 {
00584
00585 for (std::vector<User*>::const_iterator u2 = ServerInstance->Users->local_users.begin(); u2 != ServerInstance->Users->local_users.end(); u2++)
00586 {
00587 User* u = (User*)(*u2);
00588 if (this->Matches(u))
00589 u->exempt = true;
00590 }
00591 }
00592
00593 void ELine::DisplayExpiry()
00594 {
00595 ServerInstance->SNO->WriteToSnoMask('x',"Expiring timed E-Line %s@%s (set by %s %ld seconds ago)",this->identmask,this->hostmask,this->source,this->duration);
00596 }
00597
00598 void QLine::DisplayExpiry()
00599 {
00600 ServerInstance->SNO->WriteToSnoMask('x',"Expiring timed Q-Line %s (set by %s %ld seconds ago)",this->nick,this->source,this->duration);
00601 }
00602
00603 void ZLine::DisplayExpiry()
00604 {
00605 ServerInstance->SNO->WriteToSnoMask('x',"Expiring timed Z-Line %s (set by %s %ld seconds ago)",this->ipaddr,this->source,this->duration);
00606 }
00607
00608 void KLine::DisplayExpiry()
00609 {
00610 ServerInstance->SNO->WriteToSnoMask('x',"Expiring timed K-Line %s@%s (set by %s %ld seconds ago)",this->identmask,this->hostmask,this->source,this->duration);
00611 }
00612
00613 void GLine::DisplayExpiry()
00614 {
00615 ServerInstance->SNO->WriteToSnoMask('x',"Expiring timed G-Line %s@%s (set by %s %ld seconds ago)",this->identmask,this->hostmask,this->source,this->duration);
00616 }
00617
00618 const char* ELine::Displayable()
00619 {
00620 return matchtext.c_str();
00621 }
00622
00623 const char* KLine::Displayable()
00624 {
00625 return matchtext.c_str();
00626 }
00627
00628 const char* GLine::Displayable()
00629 {
00630 return matchtext.c_str();
00631 }
00632
00633 const char* ZLine::Displayable()
00634 {
00635 return ipaddr;
00636 }
00637
00638 const char* QLine::Displayable()
00639 {
00640 return nick;
00641 }
00642
00643 bool KLine::IsBurstable()
00644 {
00645 return false;
00646 }
00647
00648 bool XLineManager::RegisterFactory(XLineFactory* xlf)
00649 {
00650 XLineFactMap::iterator n = line_factory.find(xlf->GetType());
00651
00652 if (n != line_factory.end())
00653 return false;
00654
00655 line_factory[xlf->GetType()] = xlf;
00656
00657 return true;
00658 }
00659
00660 bool XLineManager::UnregisterFactory(XLineFactory* xlf)
00661 {
00662 XLineFactMap::iterator n = line_factory.find(xlf->GetType());
00663
00664 if (n == line_factory.end())
00665 return false;
00666
00667 line_factory.erase(n);
00668
00669 return true;
00670 }
00671
00672 XLineFactory* XLineManager::GetFactory(const std::string &type)
00673 {
00674 XLineFactMap::iterator n = line_factory.find(type);
00675
00676 if (n == line_factory.end())
00677 return NULL;
00678
00679 return n->second;
00680 }
00681