00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "module.h"
00015
00016 class UnrealIRCdProto : public IRCDProto
00017 {
00018 public:
00019 UnrealIRCdProto(Module *creator) : IRCDProto(creator, "UnrealIRCd 3.2.x")
00020 {
00021 DefaultPseudoclientModes = "+Soiq";
00022 CanSVSNick = true;
00023 CanSVSJoin = true;
00024 CanSetVHost = true;
00025 CanSetVIdent = true;
00026 CanSNLine = true;
00027 CanSQLine = true;
00028 CanSZLine = true;
00029 CanSVSHold = true;
00030 CanSVSO = true;
00031 MaxModes = 12;
00032 }
00033
00034 private:
00035
00036 void SendSVSNOOP(const Server *server, bool set) anope_override
00037 {
00038 UplinkSocket::Message() << "SVSNOOP " << server->GetName() << " " << (set ? "+" : "-");
00039 }
00040
00041 void SendAkillDel(const XLine *x) anope_override
00042 {
00043 if (x->IsRegex() || x->HasNickOrReal())
00044 return;
00045
00046
00047 try
00048 {
00049 if (x->GetUser() == "*")
00050 {
00051 sockaddrs(x->GetHost());
00052 IRCD->SendSZLineDel(x);
00053 return;
00054 }
00055 }
00056 catch (const SocketException &) { }
00057
00058 UplinkSocket::Message() << "TKL - G " << x->GetUser() << " " << x->GetHost() << " " << Config->OperServ;
00059 }
00060
00061 void SendTopic(BotInfo *whosets, Channel *c) anope_override
00062 {
00063 UplinkSocket::Message(whosets) << "TOPIC " << c->name << " " << c->topic_setter << " " << c->topic_ts << " :" << c->topic;
00064 }
00065
00066 void SendGlobalNotice(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
00067 {
00068 UplinkSocket::Message(bi) << "NOTICE $" << dest->GetName() << " :" << msg;
00069 }
00070
00071 void SendGlobalPrivmsg(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override
00072 {
00073 UplinkSocket::Message(bi) << "PRIVMSG $" << dest->GetName() << " :" << msg;
00074 }
00075
00076 void SendVhostDel(User *u) anope_override
00077 {
00078 u->RemoveMode(HostServ, "CLOAK");
00079 u->RemoveMode(HostServ, "VHOST");
00080 ModeManager::ProcessModes();
00081 u->SetMode(HostServ, "CLOAK");
00082 }
00083
00084 void SendAkill(User *u, XLine *x) anope_override
00085 {
00086 if (x->IsRegex() || x->HasNickOrReal())
00087 {
00088 if (!u)
00089 {
00090
00091 for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
00092 if (x->manager->Check(it->second, x))
00093 this->SendAkill(it->second, x);
00094 return;
00095 }
00096
00097 const XLine *old = x;
00098
00099 if (old->manager->HasEntry("*@" + u->host))
00100 return;
00101
00102
00103 XLine *xline = new XLine("*@" + u->host, old->by, old->expires, old->reason, old->id);
00104 old->manager->AddXLine(xline);
00105 x = xline;
00106
00107 Log(OperServ, "akill") << "AKILL: Added an akill for " << x->mask << " because " << u->GetMask() << "#" << u->realname << " matches " << old->mask;
00108 }
00109
00110
00111 try
00112 {
00113 if (x->GetUser() == "*")
00114 {
00115 sockaddrs(x->GetHost());
00116 IRCD->SendSZLine(u, x);
00117 return;
00118 }
00119 }
00120 catch (const SocketException &) { }
00121
00122
00123 time_t timeleft = x->expires - Anope::CurTime;
00124 if (timeleft > 172800 || !x->expires)
00125 timeleft = 172800;
00126 UplinkSocket::Message() << "TKL + G " << x->GetUser() << " " << x->GetHost() << " " << x->by << " " << Anope::CurTime + timeleft << " " << x->created << " :" << x->GetReason();
00127 }
00128
00129 void SendSVSKillInternal(const BotInfo *source, User *user, const Anope::string &buf) anope_override
00130 {
00131 UplinkSocket::Message(source) << "SVSKILL " << user->nick << " :" << buf;
00132 user->KillInternal(source ? source->nick : Me->GetName(), buf);
00133 }
00134
00135 void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf) anope_override
00136 {
00137 UplinkSocket::Message(bi) << "SVS2MODE " << u->nick <<" " << buf;
00138 }
00139
00140 void SendClientIntroduction(const User *u) anope_override
00141 {
00142 Anope::string modes = "+" + u->GetModes();
00143 UplinkSocket::Message() << "NICK " << u->nick << " 1 " << u->timestamp << " " << u->GetIdent() << " " << u->host << " " << u->server->GetName() << " 0 " << modes << " " << u->host << " * :" << u->realname;
00144 }
00145
00146
00147
00148 void SendServer(const Server *server) anope_override
00149 {
00150 if (!Config->Numeric.empty())
00151 UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :U0-*-" << Config->Numeric << " " << server->GetDescription();
00152 else
00153 UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :" << server->GetDescription();
00154 }
00155
00156
00157 void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override
00158 {
00159 UplinkSocket::Message(Me) << "SJOIN " << c->creation_time << " " << c->name << " :" << user->nick;
00160 if (status)
00161 {
00162
00163 ChannelStatus cs = *status;
00164
00165
00166
00167 ChanUserContainer *uc = c->FindUser(user);
00168 if (uc != NULL)
00169 uc->status.modes.clear();
00170
00171 BotInfo *setter = BotInfo::Find(user->nick);
00172 for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
00173 if (cs.modes.count(ModeManager::ChannelModes[i]->name))
00174 c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false);
00175 }
00176 }
00177
00178
00179
00180 void SendSQLineDel(const XLine *x) anope_override
00181 {
00182 UplinkSocket::Message() << "UNSQLINE " << x->mask;
00183 }
00184
00185
00186
00187
00188
00189
00190 void SendSQLine(User *, const XLine *x) anope_override
00191 {
00192 UplinkSocket::Message() << "SQLINE " << x->mask << " :" << x->GetReason();
00193 }
00194
00195
00196
00197
00198
00199
00200
00201 void SendSVSO(const BotInfo *source, const Anope::string &nick, const Anope::string &flag) anope_override
00202 {
00203 UplinkSocket::Message(source) << "SVSO " << nick << " " << flag;
00204 }
00205
00206
00207
00208 void SendVhost(User *u, const Anope::string &vIdent, const Anope::string &vhost) anope_override
00209 {
00210 if (!vIdent.empty())
00211 UplinkSocket::Message(Me) << "CHGIDENT " << u->nick << " " << vIdent;
00212 if (!vhost.empty())
00213 UplinkSocket::Message(Me) << "CHGHOST " << u->nick << " " << vhost;
00214 }
00215
00216 void SendConnect() anope_override
00217 {
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 if (!Config->Numeric.empty())
00234 UplinkSocket::Message() << "PROTOCTL NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT ESVID MLOCK VL";
00235 else
00236 UplinkSocket::Message() << "PROTOCTL NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT ESVID MLOCK";
00237 UplinkSocket::Message() << "PASS :" << Config->Uplinks[Anope::CurrentUplink]->password;
00238 SendServer(Me);
00239 }
00240
00241
00242 void SendSVSHold(const Anope::string &nick) anope_override
00243 {
00244 UplinkSocket::Message() << "TKL + Q H " << nick << " " << Config->ServerName << " " << Anope::CurTime + Config->NSReleaseTimeout << " " << Anope::CurTime << " :Being held for registered user";
00245 }
00246
00247
00248 void SendSVSHoldDel(const Anope::string &nick) anope_override
00249 {
00250 UplinkSocket::Message() << "TKL - Q * " << nick << " " << Config->ServerName;
00251 }
00252
00253
00254
00255
00256
00257 void SendSGLineDel(const XLine *x) anope_override
00258 {
00259 UplinkSocket::Message() << "SVSNLINE - :" << x->mask;
00260 }
00261
00262
00263 void SendSZLineDel(const XLine *x) anope_override
00264 {
00265 UplinkSocket::Message() << "TKL - Z * " << x->GetHost() << " " << Config->OperServ;
00266 }
00267
00268
00269 void SendSZLine(User *, const XLine *x) anope_override
00270 {
00271
00272 time_t timeleft = x->expires - Anope::CurTime;
00273 if (timeleft > 172800 || !x->expires)
00274 timeleft = 172800;
00275 UplinkSocket::Message() << "TKL + Z * " << x->GetHost() << " " << x->by << " " << Anope::CurTime + timeleft << " " << x->created << " :" << x->GetReason();
00276 }
00277
00278
00279
00280
00281
00282 void SendSGLine(User *, const XLine *x) anope_override
00283 {
00284 Anope::string edited_reason = x->GetReason();
00285 edited_reason = edited_reason.replace_all_cs(" ", "_");
00286 UplinkSocket::Message() << "SVSNLINE + " << edited_reason << " :" << x->mask;
00287 }
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 void SendSVSJoin(const BotInfo *source, const User *user, const Anope::string &chan, const Anope::string ¶m) anope_override
00299 {
00300 if (!param.empty())
00301 UplinkSocket::Message(source) << "SVSJOIN " << user->GetUID() << " " << chan << " :" << param;
00302 else
00303 UplinkSocket::Message(source) << "SVSJOIN " << user->GetUID() << " " << chan;
00304 }
00305
00306 void SendSVSPart(const BotInfo *source, const User *user, const Anope::string &chan, const Anope::string ¶m) anope_override
00307 {
00308 if (!param.empty())
00309 UplinkSocket::Message(source) << "SVSPART " << user->GetUID() << " " << chan << " :" << param;
00310 else
00311 UplinkSocket::Message(source) << "SVSPART " << user->GetUID() << " " << chan;
00312 }
00313
00314 void SendSWhois(const BotInfo *source, const Anope::string &who, const Anope::string &mask) anope_override
00315 {
00316 UplinkSocket::Message(source) << "SWHOIS " << who << " :" << mask;
00317 }
00318
00319 void SendEOB() anope_override
00320 {
00321 UplinkSocket::Message(Me) << "EOS";
00322 }
00323
00324 bool IsNickValid(const Anope::string &nick) anope_override
00325 {
00326 if (nick.equals_ci("ircd") || nick.equals_ci("irc"))
00327 return false;
00328
00329 return IRCDProto::IsNickValid(nick);
00330 }
00331
00332 bool IsChannelValid(const Anope::string &chan) anope_override
00333 {
00334 if (chan.find(':') != Anope::string::npos)
00335 return false;
00336
00337 return IRCDProto::IsChannelValid(chan);
00338 }
00339
00340 bool IsExtbanValid(const Anope::string &mask) anope_override
00341 {
00342 return mask.length() >= 4 && mask[0] == '~' && mask[2] == ':';
00343 }
00344
00345 void SendLogin(User *u) anope_override
00346 {
00347 if (!u->Account())
00348 return;
00349
00350 if (Servers::Capab.count("ESVID") > 0)
00351 IRCD->SendMode(NickServ, u, "+d %s", u->Account()->display.c_str());
00352 else
00353 IRCD->SendMode(NickServ, u, "+d %d", u->signon);
00354 }
00355
00356 void SendLogout(User *u) anope_override
00357 {
00358 IRCD->SendMode(NickServ, u, "+d 0");
00359 }
00360
00361 void SendChannel(Channel *c) anope_override
00362 {
00363
00364
00365
00366 BotInfo *bi = c->ci->WhoSends();
00367 if (!bi)
00368 ;
00369 else if (c->FindUser(bi) == NULL)
00370 {
00371 bi->Join(c);
00372 bi->Part(c);
00373 }
00374 else
00375 {
00376 bi->Part(c);
00377 bi->Join(c);
00378 }
00379 }
00380 };
00381
00382 class UnrealExtBan : public ChannelModeList
00383 {
00384 public:
00385 UnrealExtBan(const Anope::string &mname, char modeChar) : ChannelModeList(mname, modeChar) { }
00386
00387 bool Matches(const User *u, const Entry *e) anope_override
00388 {
00389 const Anope::string &mask = e->GetMask();
00390
00391 if (mask.find("~c:") == 0)
00392 {
00393 Anope::string channel = mask.substr(3);
00394
00395 ChannelMode *cm = NULL;
00396 if (channel[0] != '#')
00397 {
00398 char modeChar = ModeManager::GetStatusChar(channel[0]);
00399 channel.erase(channel.begin());
00400 cm = ModeManager::FindChannelModeByChar(modeChar);
00401 if (cm != NULL && cm->type != MODE_STATUS)
00402 cm = NULL;
00403 }
00404
00405 Channel *c = Channel::Find(channel);
00406 if (c != NULL)
00407 {
00408 ChanUserContainer *uc = c->FindUser(u);
00409 if (uc != NULL)
00410 if (cm == NULL || uc->status.modes.count(cm->name))
00411 return true;
00412 }
00413 }
00414 else if (mask.find("~j:") == 0 || mask.find("~n:") == 0 || mask.find("~q:") == 0)
00415 {
00416 Anope::string real_mask = mask.substr(3);
00417
00418 Entry en(this->name, real_mask);
00419 if (en.Matches(u))
00420 return true;
00421 }
00422 else if (mask.find("~r:") == 0)
00423 {
00424 Anope::string real_mask = mask.substr(3);
00425
00426 if (Anope::Match(u->realname, real_mask))
00427 return true;
00428 }
00429 else if (mask.find("~R:") == 0)
00430 {
00431 if (u->HasMode("REGISTERED") && mask.equals_ci(u->nick))
00432 return true;
00433 }
00434 else if (mask.find("~a:") == 0)
00435 {
00436 Anope::string real_mask = mask.substr(3);
00437
00438 if (u->Account() && Anope::Match(u->Account()->display, real_mask))
00439 return true;
00440 }
00441
00442 return false;
00443 }
00444 };
00445
00446 class ChannelModeFlood : public ChannelModeParam
00447 {
00448 public:
00449 ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam("FLOOD", modeChar, minusNoArg) { }
00450
00451
00452 bool IsValid(const Anope::string &value) const anope_override
00453 {
00454 if (value.empty())
00455 return false;
00456 try
00457 {
00458 Anope::string rest;
00459 if (value[0] != ':' && convertTo<unsigned>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<unsigned>(rest.substr(1), rest, false) > 0 && rest.empty())
00460 return true;
00461 }
00462 catch (const ConvertException &) { }
00463
00464
00465 size_t end_bracket = value.find(']', 1);
00466 if (end_bracket == Anope::string::npos)
00467 return false;
00468 Anope::string xbuf = value.substr(0, end_bracket);
00469 if (value[end_bracket + 1] != ':')
00470 return false;
00471 commasepstream args(xbuf.substr(1));
00472 Anope::string arg;
00473 while (args.GetToken(arg))
00474 {
00475
00476 size_t p = 0;
00477 while (p < arg.length() && isdigit(arg[p]))
00478 ++p;
00479 if (p == arg.length() || !(arg[p] == 'c' || arg[p] == 'j' || arg[p] == 'k' || arg[p] == 'm' || arg[p] == 'n' || arg[p] == 't'))
00480 continue;
00481 try
00482 {
00483 int v = arg.substr(0, p).is_number_only() ? convertTo<int>(arg.substr(0, p)) : 0;
00484 if (v < 1 || v > 999)
00485 return false;
00486 }
00487 catch (const ConvertException &)
00488 {
00489 return false;
00490 }
00491 }
00492
00493 return true;
00494 }
00495 };
00496
00497 class ChannelModeUnrealSSL : public ChannelMode
00498 {
00499 public:
00500 ChannelModeUnrealSSL(const Anope::string &n, char c) : ChannelMode(n, c)
00501 {
00502 }
00503
00504 bool CanSet(User *u) const anope_override
00505 {
00506 return false;
00507 }
00508 };
00509
00510 struct IRCDMessageCapab : Message::Capab
00511 {
00512 IRCDMessageCapab(Module *creator) : Message::Capab(creator, "PROTOCTL") { }
00513
00514 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00515 {
00516 for (unsigned i = 0; i < params.size(); ++i)
00517 {
00518 Anope::string capab = params[i];
00519
00520 if (capab.find("CHANMODES") != Anope::string::npos)
00521 {
00522 Anope::string modes(capab.begin() + 10, capab.end());
00523 commasepstream sep(modes);
00524 Anope::string modebuf;
00525
00526 sep.GetToken(modebuf);
00527 for (size_t t = 0, end = modebuf.length(); t < end; ++t)
00528 {
00529 switch (modebuf[t])
00530 {
00531 case 'b':
00532 ModeManager::AddChannelMode(new UnrealExtBan("BAN", 'b'));
00533 continue;
00534 case 'e':
00535 ModeManager::AddChannelMode(new UnrealExtBan("EXCEPT", 'e'));
00536 continue;
00537 case 'I':
00538 ModeManager::AddChannelMode(new UnrealExtBan("INVITEOVERRIDE", 'I'));
00539 continue;
00540 default:
00541 ModeManager::AddChannelMode(new ChannelModeList("END", modebuf[t]));
00542 }
00543 }
00544
00545 sep.GetToken(modebuf);
00546 for (size_t t = 0, end = modebuf.length(); t < end; ++t)
00547 {
00548 switch (modebuf[t])
00549 {
00550 case 'k':
00551 ModeManager::AddChannelMode(new ChannelModeKey('k'));
00552 continue;
00553 case 'f':
00554 ModeManager::AddChannelMode(new ChannelModeFlood('f', false));
00555 continue;
00556 case 'L':
00557 ModeManager::AddChannelMode(new ChannelModeParam("REDIRECT", 'L'));
00558 continue;
00559 default:
00560 ModeManager::AddChannelMode(new ChannelModeParam("END", modebuf[t]));
00561 }
00562 }
00563
00564 sep.GetToken(modebuf);
00565 for (size_t t = 0, end = modebuf.length(); t < end; ++t)
00566 {
00567 switch (modebuf[t])
00568 {
00569 case 'l':
00570 ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true));
00571 continue;
00572 case 'j':
00573 ModeManager::AddChannelMode(new ChannelModeParam("JOINFLOOD", 'j', true));
00574 continue;
00575 default:
00576 ModeManager::AddChannelMode(new ChannelModeParam("END", modebuf[t], true));
00577 }
00578 }
00579
00580 sep.GetToken(modebuf);
00581 for (size_t t = 0, end = modebuf.length(); t < end; ++t)
00582 {
00583 switch (modebuf[t])
00584 {
00585 case 'p':
00586 ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p'));
00587 continue;
00588 case 's':
00589 ModeManager::AddChannelMode(new ChannelMode("SECRET", 's'));
00590 continue;
00591 case 'm':
00592 ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm'));
00593 continue;
00594 case 'n':
00595 ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n'));
00596 continue;
00597 case 't':
00598 ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't'));
00599 continue;
00600 case 'i':
00601 ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i'));
00602 continue;
00603 case 'r':
00604 ModeManager::AddChannelMode(new ChannelModeRegistered('r'));
00605 continue;
00606 case 'R':
00607 ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R'));
00608 continue;
00609 case 'c':
00610 ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c'));
00611 continue;
00612 case 'O':
00613 ModeManager::AddChannelMode(new ChannelModeOper('O'));
00614 continue;
00615 case 'A':
00616 ModeManager::AddChannelMode(new ChannelModeAdmin('A'));
00617 continue;
00618 case 'Q':
00619 ModeManager::AddChannelMode(new ChannelMode("NOKICK", 'Q'));
00620 continue;
00621 case 'K':
00622 ModeManager::AddChannelMode(new ChannelMode("NOKNOCK", 'K'));
00623 continue;
00624 case 'V':
00625 ModeManager::AddChannelMode(new ChannelMode("NOINVITE", 'V'));
00626 continue;
00627 case 'C':
00628 ModeManager::AddChannelMode(new ChannelMode("NOCTCP", 'C'));
00629 continue;
00630 case 'u':
00631 ModeManager::AddChannelMode(new ChannelMode("AUDITORIUM", 'u'));
00632 continue;
00633 case 'z':
00634 ModeManager::AddChannelMode(new ChannelMode("SSL", 'z'));
00635 continue;
00636 case 'N':
00637 ModeManager::AddChannelMode(new ChannelMode("NONICK", 'N'));
00638 continue;
00639 case 'S':
00640 ModeManager::AddChannelMode(new ChannelMode("STRIPCOLOR", 'S'));
00641 continue;
00642 case 'M':
00643 ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M'));
00644 continue;
00645 case 'T':
00646 ModeManager::AddChannelMode(new ChannelMode("NONOTICE", 'T'));
00647 continue;
00648 case 'G':
00649 ModeManager::AddChannelMode(new ChannelMode("FILTER", 'G'));
00650 continue;
00651 case 'Z':
00652 ModeManager::AddChannelMode(new ChannelModeUnrealSSL("END", 'Z'));
00653 continue;
00654 default:
00655 ModeManager::AddChannelMode(new ChannelMode("END", modebuf[t]));
00656 }
00657 }
00658 }
00659 }
00660
00661 Message::Capab::Run(source, params);
00662 }
00663 };
00664
00665 struct IRCDMessageChgHost : IRCDMessage
00666 {
00667 IRCDMessageChgHost(Module *creator) : IRCDMessage(creator, "CHGHOST", 2) { }
00668
00669 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00670 {
00671 User *u = User::Find(params[0]);
00672 if (u)
00673 u->SetDisplayedHost(params[1]);
00674 }
00675 };
00676
00677 struct IRCDMessageChgIdent : IRCDMessage
00678 {
00679 IRCDMessageChgIdent(Module *creator) : IRCDMessage(creator, "CHGIDENT", 2) { }
00680
00681 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00682 {
00683 User *u = User::Find(params[0]);
00684 if (u)
00685 u->SetVIdent(params[1]);
00686 }
00687 };
00688
00689 struct IRCDMessageChgName : IRCDMessage
00690 {
00691 IRCDMessageChgName(Module *creator) : IRCDMessage(creator, "CHGNAME", 2) { }
00692
00693 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00694 {
00695 User *u = User::Find(params[0]);
00696 if (u)
00697 u->SetRealname(params[1]);
00698 }
00699 };
00700
00701 struct IRCDMessageMode : IRCDMessage
00702 {
00703 IRCDMessageMode(Module *creator, const Anope::string &mname) : IRCDMessage(creator, mname, 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
00704
00705 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00706 {
00707 bool server_source = source.GetServer() != NULL;
00708 Anope::string modes = params[1];
00709 for (unsigned i = 2; i < params.size() - (server_source ? 1 : 0); ++i)
00710 modes += " " + params[i];
00711
00712 if (IRCD->IsChannelValid(params[0]))
00713 {
00714 Channel *c = Channel::Find(params[0]);
00715 time_t ts = 0;
00716
00717 try
00718 {
00719 if (server_source)
00720 ts = convertTo<time_t>(params[params.size() - 1]);
00721 }
00722 catch (const ConvertException &) { }
00723
00724 if (c)
00725 c->SetModesInternal(source, modes, ts);
00726 }
00727 else
00728 {
00729 User *u = User::Find(params[0]);
00730 if (u)
00731 u->SetModesInternal("%s", params[1].c_str());
00732 }
00733 }
00734 };
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746 struct IRCDMessageNetInfo : IRCDMessage
00747 {
00748 IRCDMessageNetInfo(Module *creator) : IRCDMessage(creator, "NETINFO", 8) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
00749
00750 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00751 {
00752 UplinkSocket::Message() << "NETINFO " << MaxUserCount << " " << Anope::CurTime << " " << convertTo<int>(params[2]) << " " << params[3] << " 0 0 0 :" << params[7];
00753 }
00754 };
00755
00756 struct IRCDMessageNick : IRCDMessage
00757 {
00758 ServiceReference<NickServService> NSService;
00759
00760 IRCDMessageNick(Module *creator) : IRCDMessage(creator, "NICK", 2), NSService("NickServService", "NickServ") { SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00783 {
00784 if (params.size() == 11)
00785 {
00786 Anope::string ip;
00787 if (params[9] != "*")
00788 {
00789 Anope::string decoded_ip;
00790 Anope::B64Decode(params[9], decoded_ip);
00791
00792 try
00793 {
00794 sockaddrs ip_addr;
00795 ip_addr.ntop(params[9].length() == 8 ? AF_INET : AF_INET6, decoded_ip.c_str());
00796 ip = ip_addr.addr();
00797 }
00798 catch (const SocketException &ex) { }
00799 }
00800
00801 Anope::string vhost = params[8];
00802 if (vhost.equals_cs("*"))
00803 vhost.clear();
00804
00805 time_t user_ts = params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime;
00806
00807 Server *s = Server::Find(params[5]);
00808 if (s == NULL)
00809 {
00810 Log(LOG_DEBUG) << "User " << params[0] << " introduced from nonexistant server " << params[5] << "?";
00811 return;
00812 }
00813
00814 User *user = new User(params[0], params[3], params[4], vhost, ip, s, params[10], user_ts, params[7]);
00815
00816 NickAlias *na = NULL;
00817
00818 if (params[6] == "0")
00819 ;
00820 else if (params[6].is_pos_number_only())
00821 {
00822 if (convertTo<time_t>(params[6]) == user->signon)
00823 na = NickAlias::Find(user->nick);
00824 }
00825 else
00826 {
00827 na = NickAlias::Find(params[6]);
00828 }
00829
00830 if (na && NSService)
00831 NSService->Login(user, na);
00832 }
00833 else
00834 source.GetUser()->ChangeNick(params[0]);
00835 }
00836 };
00837
00847 struct IRCDMessagePong : IRCDMessage
00848 {
00849 IRCDMessagePong(Module *creator) : IRCDMessage(creator, "PONG", 0) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
00850
00851 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00852 {
00853 if (!source.GetServer()->IsSynced())
00854 source.GetServer()->Sync(false);
00855 }
00856 };
00857
00858 struct IRCDMessageSASL : IRCDMessage
00859 {
00860 class UnrealSASLIdentifyRequest : public IdentifyRequest
00861 {
00862 Anope::string uid;
00863
00864 public:
00865 UnrealSASLIdentifyRequest(Module *m, const Anope::string &id, const Anope::string &acc, const Anope::string &pass) : IdentifyRequest(m, acc, pass), uid(id) { }
00866
00867 void OnSuccess() anope_override
00868 {
00869 size_t p = this->uid.find('!');
00870 if (p == Anope::string::npos)
00871 return;
00872
00873 UplinkSocket::Message(Me) << "SVSLOGIN " << this->uid.substr(0, p) << " " << this->uid << " " << this->GetAccount();
00874 UplinkSocket::Message() << "SASL " << this->uid.substr(0, p) << " " << this->uid << " D S";
00875 }
00876
00877 void OnFail() anope_override
00878 {
00879 size_t p = this->uid.find('!');
00880 if (p == Anope::string::npos)
00881 return;
00882
00883 UplinkSocket::Message() << "SASL " << this->uid.substr(0, p) << " " << this->uid << " D F";
00884
00885 Log(NickServ) << "A user failed to identify for account " << this->GetAccount() << " using SASL";
00886 }
00887 };
00888
00889 IRCDMessageSASL(Module *creator) : IRCDMessage(creator, "SASL", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
00890
00891
00892
00893
00894
00895
00896
00897 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00898 {
00899 size_t p = params[1].find('!');
00900 if (!Config->NSSASL || p == Anope::string::npos)
00901 return;
00902
00903 if (params[2] == "S")
00904 {
00905 if (params[3] == "PLAIN")
00906 UplinkSocket::Message() << "SASL " << params[1].substr(0, p) << " " << params[1] << " C +";
00907 else
00908 UplinkSocket::Message() << "SASL " << params[1].substr(0, p) << " " << params[1] << " D F";
00909 }
00910 else if (params[2] == "C")
00911 {
00912 Anope::string decoded;
00913 Anope::B64Decode(params[3], decoded);
00914
00915 p = decoded.find('\0');
00916 if (p == Anope::string::npos)
00917 return;
00918 decoded = decoded.substr(p + 1);
00919
00920 p = decoded.find('\0');
00921 if (p == Anope::string::npos)
00922 return;
00923
00924 Anope::string acc = decoded.substr(0, p),
00925 pass = decoded.substr(p + 1);
00926
00927 if (acc.empty() || pass.empty())
00928 return;
00929
00930 IdentifyRequest *req = new UnrealSASLIdentifyRequest(this->owner, params[1], acc, pass);
00931 FOREACH_MOD(I_OnCheckAuthentication, OnCheckAuthentication(NULL, req));
00932 req->Dispatch();
00933 }
00934 }
00935 };
00936
00937 struct IRCDMessageSDesc : IRCDMessage
00938 {
00939 IRCDMessageSDesc(Module *creator) : IRCDMessage(creator, "SDESC", 1) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
00940
00941 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00942 {
00943 source.GetServer()->SetDescription(params[0]);
00944 }
00945 };
00946
00947 struct IRCDMessageSetHost : IRCDMessage
00948 {
00949 IRCDMessageSetHost(Module *creator) : IRCDMessage(creator, "SETHOST", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
00950
00951 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00952 {
00953 User *u = source.GetUser();
00954
00955
00956 if (u->HasMode("CLOAK"))
00957 u->SetDisplayedHost(params[0]);
00958 else
00959 u->SetCloakedHost(params[0]);
00960 }
00961 };
00962
00963 struct IRCDMessageSetIdent : IRCDMessage
00964 {
00965 IRCDMessageSetIdent(Module *creator) : IRCDMessage(creator, "SETIDENT", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
00966
00967 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00968 {
00969 User *u = source.GetUser();
00970 u->SetVIdent(params[0]);
00971 }
00972 };
00973
00974 struct IRCDMessageSetName : IRCDMessage
00975 {
00976 IRCDMessageSetName(Module *creator) : IRCDMessage(creator, "SETNAME", 1) { }
00977
00978 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00979 {
00980 User *u = User::Find(params[0]);
00981 if (u)
00982 u->SetRealname(params[1]);
00983 }
00984 };
00985
00986 struct IRCDMessageServer : IRCDMessage
00987 {
00988 IRCDMessageServer(Module *creator) : IRCDMessage(creator, "SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); }
00989
00990 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
00991 {
00992 unsigned int hops = Anope::string(params[1]).is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0;
00993
00994 if (params[1].equals_cs("1"))
00995 {
00996 Anope::string desc;
00997 spacesepstream(params[2]).GetTokenRemainder(desc, 1);
00998
00999 new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, desc);
01000 }
01001 else
01002 new Server(source.GetServer(), params[0], hops, params[2]);
01003
01004 IRCD->SendPing(Config->ServerName, params[0]);
01005 }
01006 };
01007
01008 struct IRCDMessageSJoin : IRCDMessage
01009 {
01010 IRCDMessageSJoin(Module *creator) : IRCDMessage(creator, "SJOIN", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); }
01011
01012 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
01013 {
01014 Anope::string modes;
01015 if (params.size() >= 4)
01016 for (unsigned i = 2; i < params.size() - 1; ++i)
01017 modes += " " + params[i];
01018 if (!modes.empty())
01019 modes.erase(modes.begin());
01020
01021 std::list<Anope::string> bans, excepts, invites;
01022 std::list<Message::Join::SJoinUser> users;
01023
01024 spacesepstream sep(params[params.size() - 1]);
01025 Anope::string buf;
01026 while (sep.GetToken(buf))
01027 {
01028
01029 if (buf[0] == '&')
01030 {
01031 buf.erase(buf.begin());
01032 bans.push_back(buf);
01033 }
01034
01035 else if (buf[0] == '"')
01036 {
01037 buf.erase(buf.begin());
01038 excepts.push_back(buf);
01039 }
01040
01041 else if (buf[0] == '\'')
01042 {
01043 buf.erase(buf.begin());
01044 invites.push_back(buf);
01045 }
01046 else
01047 {
01048 Message::Join::SJoinUser sju;
01049
01050
01051 for (char ch; (ch = ModeManager::GetStatusChar(buf[0]));)
01052 {
01053 buf.erase(buf.begin());
01054 ChannelMode *cm = ModeManager::FindChannelModeByChar(ch);
01055 if (!cm)
01056 {
01057 Log(LOG_DEBUG) << "Received unknown mode prefix " << ch << " in SJOIN string";
01058 continue;
01059 }
01060
01061 sju.first.modes.insert(cm->name);
01062 }
01063
01064 sju.second = User::Find(buf);
01065 if (!sju.second)
01066 {
01067 Log(LOG_DEBUG) << "SJOIN for nonexistant user " << buf << " on " << params[1];
01068 continue;
01069 }
01070
01071 users.push_back(sju);
01072 }
01073 }
01074
01075 time_t ts = Anope::string(params[0]).is_pos_number_only() ? convertTo<time_t>(params[0]) : Anope::CurTime;
01076 Message::Join::SJoin(source, params[1], ts, modes, users);
01077
01078 if (!bans.empty() || !excepts.empty() || !invites.empty())
01079 {
01080 Channel *c = Channel::Find(params[1]);
01081
01082 if (!c || c->creation_time != ts)
01083 return;
01084
01085 ChannelMode *ban = ModeManager::FindChannelModeByName("BAN"),
01086 *except = ModeManager::FindChannelModeByName("EXCEPT"),
01087 *invex = ModeManager::FindChannelModeByName("INVITEOVERRIDE");
01088
01089 if (ban)
01090 for (std::list<Anope::string>::iterator it = bans.begin(), it_end = bans.end(); it != it_end; ++it)
01091 c->SetModeInternal(source, ban, *it);
01092 if (except)
01093 for (std::list<Anope::string>::iterator it = excepts.begin(), it_end = excepts.end(); it != it_end; ++it)
01094 c->SetModeInternal(source, except, *it);
01095 if (invex)
01096 for (std::list<Anope::string>::iterator it = invites.begin(), it_end = invites.end(); it != it_end; ++it)
01097 c->SetModeInternal(source, invex, *it);
01098 }
01099 }
01100 };
01101
01102 struct IRCDMessageTopic : IRCDMessage
01103 {
01104 IRCDMessageTopic(Module *creator) : IRCDMessage(creator, "TOPIC", 4) { }
01105
01106
01107
01108
01109
01110
01111
01112
01113 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
01114 {
01115 Channel *c = Channel::Find(params[0]);
01116 if (c)
01117 c->ChangeTopicInternal(params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime);
01118 }
01119 };
01120
01121
01122 struct IRCDMessageUmode2 : IRCDMessage
01123 {
01124 IRCDMessageUmode2(Module *creator) : IRCDMessage(creator, "UMODE2", 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); }
01125
01126 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override
01127 {
01128 source.GetUser()->SetModesInternal("%s", params[0].c_str());
01129 }
01130 };
01131
01132 class ProtoUnreal : public Module
01133 {
01134 UnrealIRCdProto ircd_proto;
01135
01136
01137 Message::Away message_away;
01138 Message::Error message_error;
01139 Message::Join message_join;
01140 Message::Kick message_kick;
01141 Message::Kill message_kill;
01142 Message::MOTD message_motd;
01143 Message::Part message_part;
01144 Message::Ping message_ping;
01145 Message::Privmsg message_privmsg;
01146 Message::Quit message_quit;
01147 Message::SQuit message_squit;
01148 Message::Stats message_stats;
01149 Message::Time message_time;
01150 Message::Version message_version;
01151 Message::Whois message_whois;
01152
01153
01154 IRCDMessageCapab message_capab;
01155 IRCDMessageChgHost message_chghost;
01156 IRCDMessageChgIdent message_chgident;
01157 IRCDMessageChgName message_chgname;
01158 IRCDMessageMode message_mode, message_svsmode, message_svs2mode;
01159 IRCDMessageNetInfo message_netinfo;
01160 IRCDMessageNick message_nick;
01161 IRCDMessagePong message_pong;
01162 IRCDMessageSASL message_sasl;
01163 IRCDMessageSDesc message_sdesc;
01164 IRCDMessageSetHost message_sethost;
01165 IRCDMessageSetIdent message_setident;
01166 IRCDMessageSetName message_setname;
01167 IRCDMessageServer message_server;
01168 IRCDMessageSJoin message_sjoin;
01169 IRCDMessageTopic message_topic;
01170 IRCDMessageUmode2 message_umode2;
01171
01172 void AddModes()
01173 {
01174 ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0));
01175 ModeManager::AddChannelMode(new ChannelModeStatus("HALFOP", 'h', '%', 1));
01176 ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 2));
01177
01178 ModeManager::AddChannelMode(new ChannelModeStatus("PROTECT", 'a', '~', 3));
01179 ModeManager::AddChannelMode(new ChannelModeStatus("OWNER", 'q', '*', 4));
01180
01181
01182 ModeManager::AddUserMode(new UserMode("SERV_ADMIN", 'A'));
01183 ModeManager::AddUserMode(new UserMode("BOT", 'B'));
01184 ModeManager::AddUserMode(new UserMode("CO_ADMIN", 'C'));
01185 ModeManager::AddUserMode(new UserMode("FILTER", 'G'));
01186 ModeManager::AddUserMode(new UserMode("HIDEOPER", 'H'));
01187 ModeManager::AddUserMode(new UserMode("HIDEIDLE", 'I'));
01188 ModeManager::AddUserMode(new UserMode("NETADMIN", 'N'));
01189 ModeManager::AddUserMode(new UserMode("REGPRIV", 'R'));
01190 ModeManager::AddUserMode(new UserMode("PROTECTED", 'S'));
01191 ModeManager::AddUserMode(new UserMode("NOCTCP", 'T'));
01192 ModeManager::AddUserMode(new UserMode("WEBTV", 'V'));
01193 ModeManager::AddUserMode(new UserMode("WHOIS", 'W'));
01194 ModeManager::AddUserMode(new UserMode("ADMIN", 'a'));
01195 ModeManager::AddUserMode(new UserMode("DEAF", 'd'));
01196 ModeManager::AddUserMode(new UserMode("GLOBOPS", 'g'));
01197 ModeManager::AddUserMode(new UserMode("HELPOP", 'h'));
01198 ModeManager::AddUserMode(new UserMode("INVIS", 'i'));
01199 ModeManager::AddUserMode(new UserMode("OPER", 'o'));
01200 ModeManager::AddUserMode(new UserMode("PRIV", 'p'));
01201 ModeManager::AddUserMode(new UserMode("GOD", 'q'));
01202 ModeManager::AddUserMode(new UserMode("REGISTERED", 'r'));
01203 ModeManager::AddUserMode(new UserMode("SNOMASK", 's'));
01204 ModeManager::AddUserMode(new UserMode("VHOST", 't'));
01205 ModeManager::AddUserMode(new UserMode("WALLOPS", 'w'));
01206 ModeManager::AddUserMode(new UserMode("CLOAK", 'x'));
01207 ModeManager::AddUserMode(new UserMode("SSL", 'z'));
01208 }
01209
01210 public:
01211 ProtoUnreal(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL),
01212 ircd_proto(this),
01213 message_away(this), message_error(this), message_join(this), message_kick(this), message_kill(this),
01214 message_motd(this), message_part(this), message_ping(this), message_privmsg(this), message_quit(this),
01215 message_squit(this), message_stats(this), message_time(this), message_version(this),
01216 message_whois(this),
01217
01218 message_capab(this), message_chghost(this), message_chgident(this), message_chgname(this), message_mode(this, "MODE"),
01219 message_svsmode(this, "SVSMODE"), message_svs2mode(this, "SVS2MODE"), message_netinfo(this), message_nick(this), message_pong(this),
01220 message_sasl(this), message_sdesc(this), message_sethost(this), message_setident(this), message_setname(this), message_server(this),
01221 message_sjoin(this), message_topic(this), message_umode2(this)
01222 {
01223 this->SetAuthor("Anope");
01224
01225 this->AddModes();
01226
01227 Implementation i[] = { I_OnUserNickChange, I_OnChannelCreate, I_OnChanRegistered, I_OnDelChan, I_OnMLock, I_OnUnMLock };
01228 ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
01229 ModuleManager::SetPriority(this, PRIORITY_FIRST);
01230 }
01231
01232 void OnUserNickChange(User *u, const Anope::string &) anope_override
01233 {
01234 u->RemoveModeInternal(ModeManager::FindUserModeByName("REGISTERED"));
01235 if (Servers::Capab.count("ESVID") == 0)
01236 IRCD->SendLogout(u);
01237 }
01238
01239 void OnChannelCreate(Channel *c) anope_override
01240 {
01241 if (Config->UseServerSideMLock && Servers::Capab.count("MLOCK") > 0 && c->ci)
01242 {
01243 Anope::string modes = c->ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
01244 UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(c->creation_time) << " " << c->ci->name << " " << modes;
01245 }
01246 }
01247
01248 void OnChanRegistered(ChannelInfo *ci) anope_override
01249 {
01250 if (!ci->c || !Config->UseServerSideMLock)
01251 return;
01252 Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "");
01253 UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
01254 }
01255
01256 void OnDelChan(ChannelInfo *ci) anope_override
01257 {
01258 if (!ci->c || !Config->UseServerSideMLock)
01259 return;
01260 UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " :";
01261 }
01262
01263 EventReturn OnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
01264 {
01265 ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
01266 if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0 && Config->UseServerSideMLock)
01267 {
01268 Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "") + cm->mchar;
01269 UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
01270 }
01271
01272 return EVENT_CONTINUE;
01273 }
01274
01275 EventReturn OnUnMLock(ChannelInfo *ci, ModeLock *lock) anope_override
01276 {
01277 ChannelMode *cm = ModeManager::FindChannelModeByName(lock->name);
01278 if (cm && ci->c && (cm->type == MODE_REGULAR || cm->type == MODE_PARAM) && Servers::Capab.count("MLOCK") > 0 && Config->UseServerSideMLock)
01279 {
01280 Anope::string modes = ci->GetMLockAsString(false).replace_all_cs("+", "").replace_all_cs("-", "").replace_all_cs(cm->mchar, "");
01281 UplinkSocket::Message(Me) << "MLOCK " << static_cast<long>(ci->c->creation_time) << " " << ci->name << " " << modes;
01282 }
01283
01284 return EVENT_CONTINUE;
01285 }
01286 };
01287
01288 MODULE_INIT(ProtoUnreal)