anope- supernets anope source code & configuration |
git clone git://git.acid.vegas/anope.git |
Log | Files | Refs | Archive | README |
plexus.cpp (16614B)
1 /* Plexus 3+ IRCD functions 2 * 3 * (C) 2003-2022 Anope Team 4 * Contact us at team@anope.org 5 * 6 * Please read COPYING and README for further details. 7 * 8 * Based on the original code of Epona by Lara. 9 * Based on the original code of Services by Andy Church. 10 */ 11 12 #include "module.h" 13 #include "modules/sasl.h" 14 15 static Anope::string UplinkSID; 16 17 static ServiceReference<IRCDProto> hybrid("IRCDProto", "hybrid"); 18 19 class PlexusProto : public IRCDProto 20 { 21 public: 22 PlexusProto(Module *creator) : IRCDProto(creator, "hybrid-7.2.3+plexus-3.0.1") 23 { 24 DefaultPseudoclientModes = "+iU"; 25 CanSVSNick = true; 26 CanSVSJoin = true; 27 CanSetVHost = true; 28 CanSetVIdent = true; 29 CanSNLine = true; 30 CanSQLine = true; 31 CanSQLineChannel = true; 32 CanSVSHold = true; 33 CanCertFP = true; 34 RequiresID = true; 35 MaxModes = 4; 36 } 37 38 void SendSVSKillInternal(const MessageSource &source, User *targ, const Anope::string &reason) anope_override { hybrid->SendSVSKillInternal(source, targ, reason); } 39 void SendGlobalNotice(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override { hybrid->SendGlobalNotice(bi, dest, msg); } 40 void SendGlobalPrivmsg(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override { hybrid->SendGlobalPrivmsg(bi, dest, msg); } 41 void SendSQLine(User *u, const XLine *x) anope_override { hybrid->SendSQLine(u, x); } 42 void SendSQLineDel(const XLine *x) anope_override { hybrid->SendSQLineDel(x); } 43 void SendSGLineDel(const XLine *x) anope_override { hybrid->SendSGLineDel(x); } 44 void SendSGLine(User *u, const XLine *x) anope_override { hybrid->SendSGLine(u, x); } 45 void SendAkillDel(const XLine *x) anope_override { hybrid->SendAkillDel(x); } 46 void SendAkill(User *u, XLine *x) anope_override { hybrid->SendAkill(u, x); } 47 void SendServer(const Server *server) anope_override { hybrid->SendServer(server); } 48 void SendChannel(Channel *c) anope_override { hybrid->SendChannel(c); } 49 void SendSVSHold(const Anope::string &nick, time_t t) anope_override { hybrid->SendSVSHold(nick, t); } 50 void SendSVSHoldDel(const Anope::string &nick) anope_override { hybrid->SendSVSHoldDel(nick); } 51 52 void SendGlobopsInternal(const MessageSource &source, const Anope::string &buf) anope_override 53 { 54 UplinkSocket::Message(source) << "OPERWALL :" << buf; 55 } 56 57 void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override 58 { 59 UplinkSocket::Message(Me) << "SJOIN " << c->creation_time << " " << c->name << " +" << c->GetModes(true, true) << " :" << user->GetUID(); 60 if (status) 61 { 62 /* First save the channel status incase uc->Status == status */ 63 ChannelStatus cs = *status; 64 /* If the user is internally on the channel with flags, kill them so that 65 * the stacker will allow this. 66 */ 67 ChanUserContainer *uc = c->FindUser(user); 68 if (uc != NULL) 69 uc->status.Clear(); 70 71 BotInfo *setter = BotInfo::Find(user->GetUID()); 72 for (size_t i = 0; i < cs.Modes().length(); ++i) 73 c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false); 74 75 if (uc != NULL) 76 uc->status = cs; 77 } 78 } 79 80 void SendForceNickChange(User *u, const Anope::string &newnick, time_t when) anope_override 81 { 82 UplinkSocket::Message(Me) << "ENCAP " << u->server->GetName() << " SVSNICK " << u->GetUID() << " " << u->timestamp << " " << newnick << " " << when; 83 } 84 85 void SendVhost(User *u, const Anope::string &ident, const Anope::string &host) anope_override 86 { 87 if (!ident.empty()) 88 UplinkSocket::Message(Me) << "ENCAP * CHGIDENT " << u->GetUID() << " " << ident; 89 UplinkSocket::Message(Me) << "ENCAP * CHGHOST " << u->GetUID() << " " << host; 90 u->SetMode(Config->GetClient("HostServ"), "CLOAK"); 91 } 92 93 void SendVhostDel(User *u) anope_override 94 { 95 u->RemoveMode(Config->GetClient("HostServ"), "CLOAK"); 96 } 97 98 void SendConnect() anope_override 99 { 100 UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " TS 6 :" << Me->GetSID(); 101 /* CAPAB 102 * QS - Can handle quit storm removal 103 * EX - Can do channel +e exemptions 104 * CHW - Can do channel wall @# 105 * LL - Can do lazy links 106 * IE - Can do invite exceptions 107 * EOB - Can do EOB message 108 * KLN - Can do KLINE message 109 * GLN - Can do GLINE message 110 * HUB - This server is a HUB 111 * AOPS - Can do anon ops (+a) 112 * UID - Can do UIDs 113 * ZIP - Can do ZIPlinks 114 * ENC - Can do ENCrypted links 115 * KNOCK - Supports KNOCK 116 * TBURST - Supports TBURST 117 * PARA - Supports invite broadcasting for +p 118 * ENCAP - Supports encapsulation of protocol messages 119 * SVS - Supports services protocol extensions 120 */ 121 UplinkSocket::Message() << "CAPAB :QS EX CHW IE EOB KLN UNKLN GLN HUB KNOCK TBURST PARA ENCAP SVS"; 122 /* Make myself known to myself in the serverlist */ 123 SendServer(Me); 124 /* 125 * SVINFO 126 * parv[0] = sender prefix 127 * parv[1] = TS_CURRENT for the server 128 * parv[2] = TS_MIN for the server 129 * parv[3] = server is standalone or connected to non-TS only 130 * parv[4] = server's idea of UTC time 131 */ 132 UplinkSocket::Message() << "SVINFO 6 5 0 :" << Anope::CurTime; 133 } 134 135 void SendClientIntroduction(User *u) anope_override 136 { 137 Anope::string modes = "+" + u->GetModes(); 138 UplinkSocket::Message(Me) << "UID " << u->nick << " 1 " << u->timestamp << " " << modes << " " << u->GetIdent() << " " << u->host << " 255.255.255.255 " << u->GetUID() << " 0 " << u->host << " :" << u->realname; 139 } 140 141 void SendModeInternal(const MessageSource &source, User *u, const Anope::string &buf) anope_override 142 { 143 UplinkSocket::Message(source) << "ENCAP * SVSMODE " << u->GetUID() << " " << u->timestamp << " " << buf; 144 } 145 146 void SendLogin(User *u, NickAlias *na) anope_override 147 { 148 UplinkSocket::Message(Me) << "ENCAP * SU " << u->GetUID() << " " << na->nc->display; 149 } 150 151 void SendLogout(User *u) anope_override 152 { 153 UplinkSocket::Message(Me) << "ENCAP * SU " << u->GetUID(); 154 } 155 156 void SendTopic(const MessageSource &source, Channel *c) anope_override 157 { 158 UplinkSocket::Message(source) << "ENCAP * TOPIC " << c->name << " " << c->topic_setter << " " << c->topic_ts << " :" << c->topic; 159 } 160 161 void SendSVSJoin(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string ¶m) anope_override 162 { 163 UplinkSocket::Message(source) << "ENCAP " << user->server->GetName() << " SVSJOIN " << user->GetUID() << " " << chan; 164 } 165 166 void SendSVSPart(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string ¶m) anope_override 167 { 168 UplinkSocket::Message(source) << "ENCAP " << user->server->GetName() << " SVSPART " << user->GetUID() << " " << chan; 169 } 170 171 void SendSASLMessage(const SASL::Message &message) anope_override 172 { 173 Server *s = Server::Find(message.target.substr(0, 3)); 174 UplinkSocket::Message(Me) << "ENCAP " << (s ? s->GetName() : message.target.substr(0, 3)) << " SASL " << message.source << " " << message.target << " " << message.type << " " << message.data << (message.ext.empty() ? "" : (" " + message.ext)); 175 } 176 177 void SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) anope_override 178 { 179 Server *s = Server::Find(uid.substr(0, 3)); 180 UplinkSocket::Message(Me) << "ENCAP " << (s ? s->GetName() : uid.substr(0, 3)) << " SVSLOGIN " << uid << " * * " 181 << (vhost.empty() ? "*" : vhost) << " " << acc; 182 } 183 184 void SendSVSNOOP(const Server *server, bool set) anope_override 185 { 186 UplinkSocket::Message() << "ENCAP " << server->GetName() << " SVSNOOP " << (set ? "+" : "-"); 187 } 188 }; 189 190 struct IRCDMessageEncap : IRCDMessage 191 { 192 IRCDMessageEncap(Module *creator) : IRCDMessage(creator, "ENCAP", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); } 193 194 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override 195 { 196 /* 197 * Received: :dev.anope.de ENCAP * SU DukePyrolator DukePyrolator 198 * params[0] = * 199 * params[1] = SU 200 * params[2] = nickname 201 * params[3] = account 202 */ 203 if (params[1].equals_cs("SU")) 204 { 205 User *u = User::Find(params[2]); 206 NickCore *nc = NickCore::Find(params[3]); 207 if (u && nc) 208 { 209 u->Login(nc); 210 } 211 } 212 213 /* 214 * Received: :dev.anope.de ENCAP * CERTFP DukePyrolator :3F122A9CC7811DBAD3566BF2CEC3009007C0868F 215 * params[0] = * 216 * params[1] = CERTFP 217 * params[2] = nickname 218 * params[3] = fingerprint 219 */ 220 else if (params[1].equals_cs("CERTFP")) 221 { 222 User *u = User::Find(params[2]); 223 if (u) 224 { 225 u->fingerprint = params[3]; 226 FOREACH_MOD(OnFingerprint, (u)); 227 } 228 } 229 230 else if (params[1] == "SASL" && SASL::sasl && params.size() >= 6) 231 { 232 SASL::Message m; 233 m.source = params[2]; 234 m.target = params[3]; 235 m.type = params[4]; 236 m.data = params[5]; 237 m.ext = params.size() > 6 ? params[6] : ""; 238 239 SASL::sasl->ProcessMessage(m); 240 } 241 242 return; 243 } 244 }; 245 246 struct IRCDMessagePass : IRCDMessage 247 { 248 IRCDMessagePass(Module *creator) : IRCDMessage(creator, "PASS", 4) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } 249 250 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override 251 { 252 UplinkSID = params[3]; 253 } 254 }; 255 256 struct IRCDMessageServer : IRCDMessage 257 { 258 IRCDMessageServer(Module *creator) : IRCDMessage(creator, "SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } 259 260 /* 0 1 2 */ 261 /* SERVER hades.arpa 1 :ircd-hybrid test server */ 262 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override 263 { 264 /* Servers other than our immediate uplink are introduced via SID */ 265 if (params[1] != "1") 266 return; 267 268 new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID); 269 } 270 }; 271 272 struct IRCDMessageUID : IRCDMessage 273 { 274 IRCDMessageUID(Module *creator) : IRCDMessage(creator, "UID", 11) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } 275 276 /* 277 params[0] = nick 278 params[1] = hop 279 params[2] = ts 280 params[3] = modes 281 params[4] = user 282 params[5] = host 283 params[6] = IP 284 params[7] = UID 285 params[8] = services stamp 286 params[9] = realhost 287 params[10] = info 288 */ 289 // :42X UID Adam 1 1348535644 +aow Adam 192.168.0.5 192.168.0.5 42XAAAAAB 0 192.168.0.5 :Adam 290 void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override 291 { 292 /* An IP of 0 means the user is spoofed */ 293 Anope::string ip = params[6]; 294 if (ip == "0") 295 ip.clear(); 296 297 time_t ts; 298 try 299 { 300 ts = convertTo<time_t>(params[2]); 301 } 302 catch (const ConvertException &) 303 { 304 ts = Anope::CurTime; 305 } 306 307 NickAlias *na = NULL; 308 try 309 { 310 if (params[8].is_pos_number_only() && convertTo<time_t>(params[8]) == ts) 311 na = NickAlias::Find(params[0]); 312 } 313 catch (const ConvertException &) { } 314 if (params[8] != "0" && !na) 315 na = NickAlias::Find(params[8]); 316 317 User::OnIntroduce(params[0], params[4], params[9], params[5], ip, source.GetServer(), params[10], ts, params[3], params[7], na ? *na->nc : NULL); 318 } 319 }; 320 321 class ProtoPlexus : public Module 322 { 323 Module *m_hybrid; 324 325 PlexusProto ircd_proto; 326 327 /* Core message handlers */ 328 Message::Away message_away; 329 Message::Capab message_capab; 330 Message::Error message_error; 331 Message::Invite message_invite; 332 Message::Kick message_kick; 333 Message::Kill message_kill; 334 Message::Mode message_mode; 335 Message::MOTD message_motd; 336 Message::Notice message_notice; 337 Message::Part message_part; 338 Message::Ping message_ping; 339 Message::Privmsg message_privmsg; 340 Message::Quit message_quit; 341 Message::SQuit message_squit; 342 Message::Stats message_stats; 343 Message::Time message_time; 344 Message::Topic message_topic; 345 Message::Version message_version; 346 Message::Whois message_whois; 347 348 /* Hybrid message handlers */ 349 ServiceAlias message_bmask, message_eob, message_join, message_nick, message_sid, message_sjoin, 350 message_tburst, message_tmode; 351 352 /* Our message handlers */ 353 IRCDMessageEncap message_encap; 354 IRCDMessagePass message_pass; 355 IRCDMessageServer message_server; 356 IRCDMessageUID message_uid; 357 358 void AddModes() 359 { 360 /* Add user modes */ 361 ModeManager::AddUserMode(new UserModeOperOnly("ADMIN", 'a')); 362 ModeManager::AddUserMode(new UserMode("NOCTCP", 'C')); 363 ModeManager::AddUserMode(new UserMode("DEAF", 'D')); 364 ModeManager::AddUserMode(new UserMode("SOFTCALLERID", 'G')); 365 ModeManager::AddUserMode(new UserMode("CALLERID", 'g')); 366 ModeManager::AddUserMode(new UserMode("INVIS", 'i')); 367 ModeManager::AddUserMode(new UserModeOperOnly("LOCOPS", 'l')); 368 ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o')); 369 ModeManager::AddUserMode(new UserModeOperOnly("NETADMIN", 'N')); 370 ModeManager::AddUserMode(new UserMode("PRIV", 'p')); 371 ModeManager::AddUserMode(new UserModeOperOnly("ROUTING", 'q')); 372 ModeManager::AddUserMode(new UserModeNoone("REGISTERED", 'r')); 373 ModeManager::AddUserMode(new UserMode("REGPRIV", 'R')); 374 ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's')); 375 ModeManager::AddUserMode(new UserModeNoone("SSL", 'S')); 376 ModeManager::AddUserMode(new UserModeNoone("PROTECTED", 'U')); 377 ModeManager::AddUserMode(new UserMode("WALLOPS", 'w')); 378 ModeManager::AddUserMode(new UserModeNoone("WEBIRC", 'W')); 379 ModeManager::AddUserMode(new UserMode("CLOAK", 'x')); 380 ModeManager::AddUserMode(new UserModeOperOnly("OPERWALLS", 'z')); 381 382 /* b/e/I */ 383 ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b')); 384 ModeManager::AddChannelMode(new ChannelModeList("EXCEPT", 'e')); 385 ModeManager::AddChannelMode(new ChannelModeList("INVITEOVERRIDE", 'I')); 386 387 /* v/h/o/a/q */ 388 ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0)); 389 ModeManager::AddChannelMode(new ChannelModeStatus("HALFOP", 'h', '%', 1)); 390 ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 2)); 391 ModeManager::AddChannelMode(new ChannelModeStatus("PROTECT", 'a', '&', 3)); 392 ModeManager::AddChannelMode(new ChannelModeStatus("OWNER", 'q', '~', 4)); 393 394 /* l/k */ 395 ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true)); 396 ModeManager::AddChannelMode(new ChannelModeKey('k')); 397 398 /* Add channel modes */ 399 ModeManager::AddChannelMode(new ChannelMode("BANDWIDTH", 'B')); 400 ModeManager::AddChannelMode(new ChannelMode("NOCTCP", 'C')); 401 ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c')); 402 ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i')); 403 ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm')); 404 ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M')); 405 ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n')); 406 ModeManager::AddChannelMode(new ChannelMode("NONOTICE", 'N')); 407 ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p')); 408 ModeManager::AddChannelMode(new ChannelMode("SECRET", 's')); 409 ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't')); 410 ModeManager::AddChannelMode(new ChannelModeOperOnly("OPERONLY", 'O')); 411 ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R')); 412 ModeManager::AddChannelMode(new ChannelMode("SSL", 'S')); 413 ModeManager::AddChannelMode(new ChannelMode("PERM", 'z')); 414 } 415 416 public: 417 ProtoPlexus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR), 418 ircd_proto(this), 419 message_away(this), message_capab(this), message_error(this), message_invite(this), message_kick(this), message_kill(this), 420 message_mode(this), message_motd(this), message_notice(this), message_part(this), message_ping(this), message_privmsg(this), 421 message_quit(this), message_squit(this), message_stats(this), message_time(this), message_topic(this), message_version(this), 422 message_whois(this), 423 424 message_bmask("IRCDMessage", "plexus/bmask", "hybrid/bmask"), message_eob("IRCDMessage", "plexus/eob", "hybrid/eob"), 425 message_join("IRCDMessage", "plexus/join", "hybrid/join"), message_nick("IRCDMessage", "plexus/nick", "hybrid/nick"), 426 message_sid("IRCDMessage", "plexus/sid", "hybrid/sid"), 427 message_sjoin("IRCDMessage", "plexus/sjoin", "hybrid/sjoin"), message_tburst("IRCDMessage", "plexus/tburst", "hybrid/tburst"), 428 message_tmode("IRCDMessage", "plexus/tmode", "hybrid/tmode"), 429 430 message_encap(this), message_pass(this), message_server(this), message_uid(this) 431 { 432 433 if (ModuleManager::LoadModule("hybrid", User::Find(creator)) != MOD_ERR_OK) 434 throw ModuleException("Unable to load hybrid"); 435 m_hybrid = ModuleManager::FindModule("hybrid"); 436 if (!m_hybrid) 437 throw ModuleException("Unable to find hybrid"); 438 if (!hybrid) 439 throw ModuleException("No protocol interface for hybrid"); 440 441 this->AddModes(); 442 } 443 444 ~ProtoPlexus() 445 { 446 m_hybrid = ModuleManager::FindModule("hybrid"); 447 ModuleManager::UnloadModule(m_hybrid, NULL); 448 } 449 }; 450 451 MODULE_INIT(ProtoPlexus)