bool TreeSocket::CheckDuplicate(const std::string& sname, const std::string& sid) { // Check if the server name is not in use by a server that's already fully connected TreeServer* CheckDupe = Utils->FindServer(sname); if (CheckDupe) { std::string pname = CheckDupe->GetParent() ? CheckDupe->GetParent()->GetName() : "<ourself>"; SendError("Server "+sname+" already exists on server "+pname+"!"); ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, already exists on server "+pname); return false; } // Check if the id is not in use by a server that's already fully connected ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Looking for dupe SID %s", sid.c_str()); CheckDupe = Utils->FindServerID(sid); if (CheckDupe) { this->SendError("Server ID "+CheckDupe->GetID()+" already exists on server "+CheckDupe->GetName()+"! You may want to specify the server ID for the server manually with <server:id> so they do not conflict."); ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, server ID '"+CheckDupe->GetID()+ "' already exists on server "+CheckDupe->GetName()); return false; } return true; }
bool TreeSocket::CheckDuplicate(const std::string& sname, const std::string& sid) { /* Check for fully initialized instances of the server by name */ TreeServer* CheckDupe = Utils->FindServer(sname); if (CheckDupe) { std::string pname = CheckDupe->GetParent() ? CheckDupe->GetParent()->GetName() : "<ourself>"; SendError("Server "+sname+" already exists on server "+pname+"!"); ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, already exists on server "+pname); return false; } /* Check for fully initialized instances of the server by id */ ServerInstance->Logs->Log("m_spanningtree",DEBUG,"Looking for dupe SID %s", sid.c_str()); CheckDupe = Utils->FindServerID(sid); if (CheckDupe) { this->SendError("Server ID "+CheckDupe->GetID()+" already exists on server "+CheckDupe->GetName()+"! You may want to specify the server ID for the server manually with <server:id> so they do not conflict."); ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, server ID '"+CheckDupe->GetID()+ "' already exists on server "+CheckDupe->GetName()); return false; } return true; }
CmdResult CommandSQuit::HandleServer(TreeServer* server, std::vector<std::string>& params) { TreeServer* quitting = Utils->FindServer(params[0]); if (!quitting) { ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Squit from unknown server"); return CMD_FAILURE; } CmdResult ret = CMD_SUCCESS; if (quitting == server) { ret = CMD_FAILURE; server = server->GetParent(); } else if (quitting->GetParent() != server) throw ProtocolException("Attempted to SQUIT a non-directly connected server or the parent"); server->SQuitChild(quitting, params[1]); // XXX: Return CMD_FAILURE when servers SQUIT themselves (i.e. :00S SQUIT 00S :Shutting down) // to stop this message from being forwarded. // The squit logic generates a SQUIT message with our sid as the source and sends it to the // remaining servers. return ret; }
ModResult ModuleSpanningTree::HandleConnect(const CommandBase::Params& parameters, User* user) { for (std::vector<reference<Link> >::iterator i = Utils->LinkBlocks.begin(); i < Utils->LinkBlocks.end(); i++) { Link* x = *i; if (InspIRCd::Match(x->Name, parameters[0], ascii_case_insensitive_map)) { if (InspIRCd::Match(ServerInstance->Config->ServerName, x->Name, ascii_case_insensitive_map)) { user->WriteRemoteNotice(InspIRCd::Format("*** CONNECT: Server \002%s\002 is ME, not connecting.", x->Name.c_str())); return MOD_RES_DENY; } TreeServer* CheckDupe = Utils->FindServer(x->Name); if (!CheckDupe) { user->WriteRemoteNotice(InspIRCd::Format("*** CONNECT: Connecting to server: \002%s\002 (%s:%d)", x->Name.c_str(), (x->HiddenFromStats ? "<hidden>" : x->IPAddr.c_str()), x->Port)); ConnectServer(x); return MOD_RES_DENY; } else { user->WriteRemoteNotice(InspIRCd::Format("*** CONNECT: Server \002%s\002 already exists on the network and is connected via \002%s\002", x->Name.c_str(), CheckDupe->GetParent()->GetName().c_str())); return MOD_RES_DENY; } } } user->WriteRemoteNotice(InspIRCd::Format("*** CONNECT: No server matching \002%s\002 could be found in the config file.", parameters[0].c_str())); return MOD_RES_DENY; }
/* * This is used after the other side of a connection has accepted our credentials. * They are then introducing themselves to us, BEFORE either of us burst. -- w */ bool TreeSocket::Outbound_Reply_Server(parameterlist ¶ms) { if (params.size() < 5) { SendError("Protocol error - Not enough parameters for SERVER command"); return false; } irc::string servername = params[0].c_str(); std::string sname = params[0]; std::string password = params[1]; std::string sid = params[3]; std::string description = params[4]; int hops = atoi(params[2].c_str()); this->SendCapabilities(2); if (hops) { this->SendError("Server too far away for authentication"); ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, server is too far away for authentication"); return false; } if (!ServerInstance->IsSID(sid)) { this->SendError("Invalid format server ID: "+sid+"!"); return false; } for (std::vector<reference<Link> >::iterator i = Utils->LinkBlocks.begin(); i < Utils->LinkBlocks.end(); i++) { Link* x = *i; if (x->Name != servername && x->Name != "*") // open link allowance continue; if (!ComparePass(*x, password)) { ServerInstance->SNO->WriteToSnoMask('l',"Invalid password on link: %s", x->Name.c_str()); continue; } TreeServer* CheckDupe = Utils->FindServer(sname); if (CheckDupe) { std::string pname = CheckDupe->GetParent() ? CheckDupe->GetParent()->GetName() : "<ourself>"; SendError("Server "+sname+" already exists on server "+pname+"!"); ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, already exists on server "+pname); return false; } CheckDupe = Utils->FindServer(sid); if (CheckDupe) { this->SendError("Server ID "+sid+" already exists on the network! You may want to specify the server ID for the server manually with <server:id> so they do not conflict."); ServerInstance->SNO->WriteToSnoMask('l',"Server \2"+assign(servername)+"\2 being introduced denied, server ID already exists on the network. Closing link."); return false; } /* * They're in WAIT_AUTH_2 (having accepted our credentials). * Set our state to CONNECTED (since everything's peachy so far) and send our * netburst to them, which will trigger their CONNECTED state, and BURST in reply. * * While we're at it, create a treeserver object so we know about them. * -- w */ this->LinkState = CONNECTED; Utils->timeoutlist.erase(this); linkID = sname; MyRoot = new TreeServer(Utils, sname, description, sid, Utils->TreeRoot, this, x->Hidden); Utils->TreeRoot->AddChild(MyRoot); this->DoBurst(MyRoot); params[4] = ":" + params[4]; /* IMPORTANT: Take password/hmac hash OUT of here before we broadcast the introduction! */ params[1] = "*"; Utils->DoOneToAllButSender(ServerInstance->Config->GetSID(),"SERVER",params,sname); return true; } this->SendError("Invalid credentials (check the other server's linking snomask for more information)"); ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, invalid link credentials"); return false; }
int ModuleSpanningTree::HandleConnect(const std::vector<std::string>& parameters, User* user) { for (std::vector<Link>::iterator x = Utils->LinkBlocks.begin(); x < Utils->LinkBlocks.end(); x++) { if (InspIRCd::Match(x->Name.c_str(),parameters[0])) { if (InspIRCd::Match(ServerInstance->Config->ServerName, assign(x->Name))) { RemoteMessage(user, "*** CONNECT: Server \002%s\002 is ME, not connecting.",x->Name.c_str()); return 1; } TreeServer* CheckDupe = Utils->FindServer(x->Name.c_str()); if (!CheckDupe) { RemoteMessage(user, "*** CONNECT: Connecting to server: \002%s\002 (%s:%d)",x->Name.c_str(),(x->HiddenFromStats ? "<hidden>" : x->IPAddr.c_str()),x->Port); ConnectServer(&(*x)); return 1; } else { RemoteMessage(user, "*** CONNECT: Server \002%s\002 already exists on the network and is connected via \002%s\002",x->Name.c_str(),CheckDupe->GetParent()->GetName().c_str()); return 1; } } } RemoteMessage(user, "*** CONNECT: No server matching \002%s\002 could be found in the config file.",parameters[0].c_str()); return 1; }
int ModuleSpanningTree::HandleConnect(const char** parameters, int pcnt, userrec* user) { for (std::vector<Link>::iterator x = Utils->LinkBlocks.begin(); x < Utils->LinkBlocks.end(); x++) { if (ServerInstance->MatchText(x->Name.c_str(),parameters[0])) { TreeServer* CheckDupe = Utils->FindServer(x->Name.c_str()); if (!CheckDupe) { user->WriteServ("NOTICE %s :*** CONNECT: Connecting to server: \002%s\002 (%s:%d)",user->nick,x->Name.c_str(),(x->HiddenFromStats ? "<hidden>" : x->IPAddr.c_str()),x->Port); ConnectServer(&(*x)); return 1; } else { user->WriteServ("NOTICE %s :*** CONNECT: Server \002%s\002 already exists on the network and is connected via \002%s\002",user->nick,x->Name.c_str(),CheckDupe->GetParent()->GetName().c_str()); return 1; } } } user->WriteServ("NOTICE %s :*** CONNECT: No server matching \002%s\002 could be found in the config file.",user->nick,parameters[0]); return 1; }