00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "module.h"
00015
00016 class ChannelModeFlood : public ChannelModeParam
00017 {
00018 public:
00019 ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam("FLOOD", modeChar, minusNoArg) { }
00020
00021 bool IsValid(const Anope::string &value) const anope_override
00022 {
00023 try
00024 {
00025 Anope::string rest;
00026 if (!value.empty() && value[0] != ':' && convertTo<int>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<int>(rest.substr(1), rest, false) > 0 && rest.empty())
00027 return true;
00028 }
00029 catch (const ConvertException &) { }
00030
00031 return false;
00032 }
00033 };
00034
00035 class BahamutIRCdProto : public IRCDProto
00036 {
00037 public:
00038 BahamutIRCdProto(Module *creator) : IRCDProto(creator, "Bahamut 1.8.x")
00039 {
00040 DefaultPseudoclientModes = "+";
00041 CanSVSNick = true;
00042 CanSNLine = true;
00043 CanSQLine = true;
00044 CanSQLineChannel = true;
00045 CanSZLine = true;
00046 CanSVSHold = true;
00047 MaxModes = 60;
00048 }
00049
00050 void SendModeInternal(const BotInfo *source, const Channel *dest, const Anope::string &buf) anope_override
00051 {
00052 if (Servers::Capab.count("TSMODE") > 0)
00053 {
00054 if (source)
00055 UplinkSocket::Message(source) << "MODE " << dest->name << " " << dest->creation_time << " " << buf;
00056 else
00057 UplinkSocket::Message(Me) << "MODE " << dest->name << " " << dest->creation_time << " " << buf;
00058 }
00059 else
00060 IRCDProto::SendModeInternal(source, dest, buf);
00061 }
00062
00063 void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf) anope_override
00064 {
00065 if (bi)
00066 UplinkSocket::Message(bi) << "SVSMODE " << u->nick << " " << u->timestamp << " " << buf;
00067 else
00068 UplinkSocket::Message(Me) << "SVSMODE " << u->nick << " " << u->timestamp << " " << buf;
00069 }
00070
00071 void SendGlobalNotice(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
00072 {
00073 UplinkSocket::Message(bi) << "NOTICE $" << dest->GetName() << " :" << msg;
00074 }
00075
00076 void SendGlobalPrivmsg(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
00077 {
00078 UplinkSocket::Message(bi) << "PRIVMSG $" << dest->GetName() << " :" << msg;
00079 }
00080
00081
00082 void SendSVSHold(const Anope::string &nick) anope_override
00083 {
00084 UplinkSocket::Message(Me) << "SVSHOLD " << nick << " " << Config->NSReleaseTimeout << " :Being held for registered user";
00085 }
00086
00087
00088 void SendSVSHoldDel(const Anope::string &nick) anope_override
00089 {
00090 UplinkSocket::Message(Me) << "SVSHOLD " << nick << " 0";
00091 }
00092
00093
00094 void SendSQLine(User *, const XLine *x) anope_override
00095 {
00096 UplinkSocket::Message() << "SQLINE " << x->mask << " :" << x->GetReason();
00097 }
00098
00099
00100 void SendSGLineDel(const XLine *x) anope_override
00101 {
00102 UplinkSocket::Message() << "UNSGLINE 0 :" << x->mask;
00103 }
00104
00105
00106 void SendSZLineDel(const XLine *x) anope_override
00107 {
00108
00109 UplinkSocket::Message() << "UNSZLINE 0 " << x->GetHost();
00110
00111 UplinkSocket::Message() << "RAKILL " << x->GetHost() << " *";
00112 }
00113
00114
00115 void SendSZLine(User *, const XLine *x) anope_override
00116 {
00117
00118 time_t timeleft = x->expires - Anope::CurTime;
00119 if (timeleft > 172800 || !x->expires)
00120 timeleft = 172800;
00121
00122 UplinkSocket::Message() << "SZLINE " << x->GetHost() << " :" << x->GetReason();
00123
00124 UplinkSocket::Message() << "AKILL " << x->GetHost() << " * " << timeleft << " " << x->by << " " << Anope::CurTime << " :" << x->GetReason();
00125 }
00126
00127
00128 void SendSVSNOOP(const Server *server, bool set) anope_override
00129 {
00130 UplinkSocket::Message() << "SVSNOOP " << server->GetName() << " " << (set ? "+" : "-");
00131 }
00132
00133
00134 void SendSGLine(User *, const XLine *x) anope_override
00135 {
00136 UplinkSocket::Message() << "SGLINE " << x->mask.length() << " :" << x->mask << ":" << x->GetReason();
00137 }
00138
00139
00140 void SendAkillDel(const XLine *x) anope_override
00141 {
00142 if (x->IsRegex() || x->HasNickOrReal())
00143 return;
00144
00145
00146 try
00147 {
00148 if (x->GetUser() == "*")
00149 {
00150 sockaddrs(x->GetHost());
00151 IRCD->SendSZLineDel(x);
00152 return;
00153 }
00154 }
00155 catch (const SocketException &) { }
00156
00157 UplinkSocket::Message() << "RAKILL " << x->GetHost() << " " << x->GetUser();
00158 }
00159
00160
00161 void SendTopic(BotInfo *whosets, Channel *c) anope_override
00162 {
00163 UplinkSocket::Message(whosets) << "TOPIC " << c->name << " " << c->topic_setter << " " << c->topic_ts << " :" << c->topic;
00164 }
00165
00166
00167 void SendSQLineDel(const XLine *x) anope_override
00168 {
00169 UplinkSocket::Message() << "UNSQLINE " << x->mask;
00170 }
00171
00172
00173 void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override
00174 {
00175 UplinkSocket::Message(user) << "SJOIN " << c->creation_time << " " << c->name;
00176 if (status)
00177 {
00178
00179 ChannelStatus cs = *status;
00180
00181
00182
00183 ChanUserContainer *uc = c->FindUser(user);
00184 if (uc != NULL)
00185 uc->status.modes.clear();
00186
00187 BotInfo *setter = BotInfo::Find(user->nick);
00188 for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
00189 if (cs.modes.count(ModeManager::ChannelModes[i]->name))
00190 c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false);
00191 }
00192 }
00193
00194 void SendAkill(User *u, XLine *x) anope_override
00195 {
00196 if (x->IsRegex() || x->HasNickOrReal())
00197 {
00198 if (!u)
00199 {
00200
00201 for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
00202 if (x->manager->Check(it->second, x))
00203 this->SendAkill(it->second, x);
00204 return;
00205 }
00206
00207 const XLine *old = x;
00208
00209 if (old->manager->HasEntry("*@" + u->host))
00210 return;
00211
00212
00213 x = new XLine("*@" + u->host, old->by, old->expires, old->reason, old->id);
00214 old->manager->AddXLine(x);
00215
00216 Log(OperServ, "akill") << "AKILL: Added an akill for " << x->mask << " because " << u->GetMask() << "#" << u->realname << " matches " << old->mask;
00217 }
00218
00219
00220 try
00221 {
00222 if (x->GetUser() == "*")
00223 {
00224 sockaddrs(x->GetHost());
00225 IRCD->SendSZLine(u, x);
00226 return;
00227 }
00228 }
00229 catch (const SocketException &) { }
00230
00231
00232 time_t timeleft = x->expires - Anope::CurTime;
00233 if (timeleft > 172800)
00234 timeleft = 172800;
00235 UplinkSocket::Message() << "AKILL " << x->GetHost() << " " << x->GetUser() << " " << timeleft << " " << x->by << " " << Anope::CurTime << " :" << x->GetReason();
00236 }
00237
00238
00239
00240
00241 void SendSVSKillInternal(const BotInfo *source, User *user, const Anope::string &buf) anope_override
00242 {
00243 if (source)
00244 UplinkSocket::Message(source) << "SVSKILL " << user->nick << " :" << buf;
00245 else
00246 UplinkSocket::Message() << "SVSKILL " << user->nick << " :" << buf;
00247 }
00248
00249 void SendBOB() anope_override
00250 {
00251 UplinkSocket::Message() << "BURST";
00252 }
00253
00254 void SendEOB() anope_override
00255 {
00256 UplinkSocket::Message() << "BURST 0";
00257 }
00258
00259 void SendClientIntroduction(const User *u) anope_override
00260 {
00261 Anope::string modes = "+" + u->GetModes();
00262 UplinkSocket::Message() << "NICK " << u->nick << " 1 " << u->timestamp << " " << modes << " " << u->GetIdent() << " " << u->host << " " << u->server->GetName() << " 0 0 :" << u->realname;
00263 }
00264
00265
00266 void SendServer(const Server *server) anope_override
00267 {
00268 UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :" << server->GetDescription();
00269 }
00270
00271 void SendConnect() anope_override
00272 {
00273 UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink]->password << " :TS";
00274 UplinkSocket::Message() << "CAPAB SSJOIN NOQUIT BURST UNCONNECT NICKIP TSMODE TS3";
00275 SendServer(Me);
00276
00277
00278
00279
00280
00281
00282
00283
00284 UplinkSocket::Message() << "SVINFO 3 1 0 :" << Anope::CurTime;
00285 this->SendBOB();
00286 }
00287
00288 void SendChannel(Channel *c) anope_override
00289 {
00290 Anope::string modes = c->GetModes(true, true);
00291 if (modes.empty())
00292 modes = "+";
00293 UplinkSocket::Message() << "SJOIN " << c->creation_time << " " << c->name << " " << modes << " :";
00294 }
00295
00296 void SendLogin(User *u) anope_override
00297 {
00298 IRCD->SendMode(NickServ, u, "+d %d", u->signon);
00299 }
00300
00301 void SendLogout(User *u) anope_override
00302 {
00303 IRCD->SendMode(NickServ, u, "+d 1");
00304 }
00305 };
00306
00307 struct IRCDMessageBurst : IRCDMessage
00308 {
00309 IRCDMessageBurst(Module *creator) : IRCDMessage(creator, "BURST", 0) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
00310
00311 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00312 {
00313
00314
00315
00316
00317 Server *s = source.GetServer();
00318 if (!s)
00319 s = Me->GetLinks().front();
00320 if (s)
00321 s->Sync(true);
00322 }
00323 };
00324
00325 struct IRCDMessageMode : IRCDMessage
00326 {
00327 IRCDMessageMode(Module *creator, const Anope::string &sname) : IRCDMessage(creator, sname, 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
00328
00329 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00330 {
00331 if (params.size() > 2 && IRCD->IsChannelValid(params[0]))
00332 {
00333 Channel *c = Channel::Find(params[0]);
00334 time_t ts = 0;
00335
00336 try
00337 {
00338 ts = convertTo<time_t>(params[1]);
00339 }
00340 catch (const ConvertException &) { }
00341
00342 if (c)
00343 c->SetModesInternal(source, params[2], ts);
00344 }
00345 else
00346 {
00347 User *u = User::Find(params[0]);
00348 if (u)
00349 u->SetModesInternal("%s", params[1].c_str());
00350 }
00351 }
00352 };
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 struct IRCDMessageNick : IRCDMessage
00373 {
00374 ServiceReference<NickServService> NSService;
00375
00376 IRCDMessageNick(Module *creator) : IRCDMessage(creator, "NICK", 2), NSService("NickServService", "NickServ") { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
00377
00378 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00379 {
00380 if (params.size() == 10)
00381 {
00382 Server *s = Server::Find(params[6]);
00383 if (s == NULL)
00384 {
00385 Log(LOG_DEBUG) << "User " << params[0] << " introduced from nonexistant server " << params[6] << "?";
00386 return;
00387 }
00388
00389 User *user = new User(params[0], params[4], params[5], "", params[8], s, params[9], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[3]);
00390 try
00391 {
00392 NickAlias *na;
00393 if (NSService && user->signon == convertTo<time_t>(params[7]) && (na = NickAlias::Find(user->nick)))
00394 NSService->Login(user, na);
00395 }
00396 catch (const ConvertException &) { }
00397 }
00398 else
00399 source.GetUser()->ChangeNick(params[0]);
00400 }
00401 };
00402
00403 struct IRCDMessageServer : IRCDMessage
00404 {
00405 IRCDMessageServer(Module *creator) : IRCDMessage(creator, "SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
00406
00407 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00408 {
00409 unsigned int hops = Anope::string(params[1]).is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0;
00410 new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, params[2]);
00411 }
00412 };
00413
00414 struct IRCDMessageSJoin : IRCDMessage
00415 {
00416 IRCDMessageSJoin(Module *creator) : IRCDMessage(creator, "SJOIN", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
00417
00418 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00419 {
00420 Anope::string modes;
00421 if (params.size() >= 4)
00422 for (unsigned i = 2; i < params.size(); ++i)
00423 modes += " " + params[i];
00424 if (!modes.empty())
00425 modes.erase(modes.begin());
00426
00427 std::list<Message::Join::SJoinUser> users;
00428
00429
00430
00431
00432 if (source.GetUser())
00433 {
00434 Message::Join::SJoinUser sju;
00435 sju.second = source.GetUser();
00436 users.push_back(sju);
00437 }
00438 else
00439 {
00440 spacesepstream sep(params[params.size() - 1]);
00441 Anope::string buf;
00442
00443 while (sep.GetToken(buf))
00444 {
00445 Message::Join::SJoinUser sju;
00446
00447
00448 for (char ch; (ch = ModeManager::GetStatusChar(buf[0]));)
00449 {
00450 buf.erase(buf.begin());
00451 ChannelMode *cm = ModeManager::FindChannelModeByChar(ch);
00452 if (!cm)
00453 {
00454 Log() << "Received unknown mode prefix " << cm << " in SJOIN string";
00455 continue;
00456 }
00457
00458 sju.first.modes.insert(cm->name);
00459 }
00460
00461 sju.second = User::Find(buf);
00462 if (!sju.second)
00463 {
00464 Log(LOG_DEBUG) << "SJOIN for nonexistant user " << buf << " on " << params[1];
00465 continue;
00466 }
00467
00468 users.push_back(sju);
00469 }
00470 }
00471
00472 time_t ts = Anope::string(params[0]).is_pos_number_only() ? convertTo<time_t>(params[0]) : Anope::CurTime;
00473 Message::Join::SJoin(source, params[1], ts, modes, users);
00474 }
00475 };
00476
00477 struct IRCDMessageTopic : IRCDMessage
00478 {
00479 IRCDMessageTopic(Module *creator) : IRCDMessage(creator, "TOPIC", 4) { }
00480
00481 void Run(MessageSource &, const std::vector<Anope::string> ¶ms) anope_override
00482 {
00483 Channel *c = Channel::Find(params[0]);
00484 if (c)
00485 c->ChangeTopicInternal(params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime);
00486 }
00487 };
00488
00489 class ProtoBahamut : public Module
00490 {
00491 BahamutIRCdProto ircd_proto;
00492
00493
00494 Message::Away message_away;
00495 Message::Capab message_capab;
00496 Message::Error message_error;
00497 Message::Join message_join;
00498 Message::Kick message_kick;
00499 Message::Kill message_kill;
00500 Message::MOTD message_motd;
00501 Message::Part message_part;
00502 Message::Ping message_ping;
00503 Message::Privmsg message_privmsg;
00504 Message::Quit message_quit;
00505 Message::SQuit message_squit;
00506 Message::Stats message_stats;
00507 Message::Time message_time;
00508 Message::Version message_version;
00509 Message::Whois message_whois;
00510
00511
00512 IRCDMessageBurst message_burst;
00513 IRCDMessageMode message_mode, message_svsmode;
00514 IRCDMessageNick message_nick;
00515 IRCDMessageServer message_server;
00516 IRCDMessageSJoin message_sjoin;
00517 IRCDMessageTopic message_topic;
00518
00519 void AddModes()
00520 {
00521
00522 ModeManager::AddUserMode(new UserMode("SERV_ADMIN", 'A'));
00523 ModeManager::AddUserMode(new UserMode("REGPRIV", 'R'));
00524 ModeManager::AddUserMode(new UserMode("ADMIN", 'a'));
00525 ModeManager::AddUserMode(new UserMode("INVIS", 'i'));
00526 ModeManager::AddUserMode(new UserMode("OPER", 'o'));
00527 ModeManager::AddUserMode(new UserMode("REGISTERED", 'r'));
00528 ModeManager::AddUserMode(new UserMode("SNOMASK", 's'));
00529 ModeManager::AddUserMode(new UserMode("WALLOPS", 'w'));
00530 ModeManager::AddUserMode(new UserMode("DEAF", 'd'));
00531
00532
00533 ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b'));
00534
00535
00536 ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0));
00537 ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 1));
00538
00539
00540 ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c'));
00541 ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i'));
00542 ModeManager::AddChannelMode(new ChannelModeFlood('f', false));
00543 ModeManager::AddChannelMode(new ChannelModeKey('k'));
00544 ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l'));
00545 ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm'));
00546 ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n'));
00547 ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p'));
00548 ModeManager::AddChannelMode(new ChannelModeRegistered('r'));
00549 ModeManager::AddChannelMode(new ChannelMode("SECRET", 's'));
00550 ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't'));
00551 ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M'));
00552 ModeManager::AddChannelMode(new ChannelModeOper('O'));
00553 ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R'));
00554 }
00555
00556 public:
00557 ProtoBahamut(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL),
00558 ircd_proto(this),
00559 message_away(this), message_capab(this), message_error(this), message_join(this),
00560 message_kick(this), message_kill(this), message_motd(this), message_part(this),
00561 message_ping(this), message_privmsg(this), message_quit(this), message_squit(this),
00562 message_stats(this), message_time(this), message_version(this), message_whois(this),
00563
00564 message_burst(this), message_mode(this, "MODE"), message_svsmode(this, "SVSMODE"),
00565 message_nick(this), message_server(this), message_sjoin(this), message_topic(this)
00566 {
00567 this->SetAuthor("Anope");
00568
00569 this->AddModes();
00570
00571 ModuleManager::Attach(I_OnUserNickChange, this);
00572 }
00573
00574 void OnUserNickChange(User *u, const Anope::string &) anope_override
00575 {
00576 u->RemoveModeInternal(ModeManager::FindUserModeByName("REGISTERED"));
00577 IRCD->SendLogout(u);
00578 }
00579 };
00580
00581 MODULE_INIT(ProtoBahamut)