X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_spanningtree%2Fserver.cpp;h=07004a1e8069468cc8031470d56080eb2ddc72a9;hb=ba23c2b115ad3bf2632179d283165c1579332fd8;hp=f232d57d65ebbdfd7e442b0d7f272fb44162f441;hpb=f62654a6859998f9d63eb22702c572d5ebcff15c;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_spanningtree/server.cpp b/src/modules/m_spanningtree/server.cpp index f232d57d6..07004a1e8 100644 --- a/src/modules/m_spanningtree/server.cpp +++ b/src/modules/m_spanningtree/server.cpp @@ -19,6 +19,7 @@ #include "inspircd.h" +#include "modules/ssl.h" #include "main.h" #include "utils.h" @@ -31,13 +32,11 @@ * Some server somewhere in the network introducing another server. * -- w */ -CmdResult CommandServer::HandleServer(TreeServer* ParentOfThis, std::vector& params) +CmdResult CommandServer::HandleServer(TreeServer* ParentOfThis, Params& params) { - std::string servername = params[0]; - // password is not used for a remote server - // hopcount is not used (ever) - std::string sid = params[3]; - std::string description = params[4]; + const std::string& servername = params[0]; + const std::string& sid = params[1]; + const std::string& description = params.back(); TreeSocket* socket = ParentOfThis->GetSocket(); if (!InspIRCd::IsSID(sid)) @@ -65,42 +64,57 @@ CmdResult CommandServer::HandleServer(TreeServer* ParentOfThis, std::vectorGetSocket(), lnk ? lnk->Hidden : false); - ParentOfThis->AddChild(Node); + HandleExtra(Node, params); + ServerInstance->SNO->WriteToSnoMask('L', "Server \002"+ParentOfThis->GetName()+"\002 introduced server \002"+servername+"\002 ("+description+")"); return CMD_SUCCESS; } +void CommandServer::HandleExtra(TreeServer* newserver, Params& params) +{ + for (CommandBase::Params::const_iterator i = params.begin() + 2; i != params.end() - 1; ++i) + { + const std::string& prop = *i; + std::string::size_type p = prop.find('='); -/* - * 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) + std::string key = prop; + std::string val; + if (p != std::string::npos) + { + key.erase(p); + val.assign(prop, p+1, std::string::npos); + } + + if (key == "burst") + newserver->BeginBurst(ConvToNum(val)); + } +} + +Link* TreeSocket::AuthRemote(const CommandBase::Params& params) { if (params.size() < 5) { SendError("Protocol error - Not enough parameters for SERVER command"); - return false; + return NULL; } - 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]; + const std::string& sname = params[0]; + const std::string& password = params[1]; + const std::string& sid = params[3]; + const std::string& description = params.back(); this->SendCapabilities(2); if (!ServerInstance->IsSID(sid)) { this->SendError("Invalid format server ID: "+sid+"!"); - return false; + return NULL; } for (std::vector >::iterator i = Utils->LinkBlocks.begin(); i < Utils->LinkBlocks.end(); i++) { Link* x = *i; - if (x->Name != servername && x->Name != "*") // open link allowance + if ((!stdalgo::string::equalsci(x->Name, sname)) && (x->Name != "*")) // open link allowance continue; if (!ComparePass(*x, password)) @@ -109,22 +123,36 @@ bool TreeSocket::Outbound_Reply_Server(parameterlist ¶ms) continue; } - TreeServer* CheckDupe = Utils->FindServer(sname); - if (CheckDupe) - { - std::string pname = CheckDupe->GetParent() ? CheckDupe->GetParent()->GetName() : ""; - 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) + if (!CheckDuplicate(sname, sid)) + return NULL; + + ServerInstance->SNO->WriteToSnoMask('l',"Verified server connection " + linkID + " ("+description+")"); + + const SSLIOHook* const ssliohook = SSLIOHook::IsSSL(this); + if (ssliohook) { - this->SendError("Server ID "+sid+" already exists on the network! You may want to specify the server ID for the server manually with 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; + std::string ciphersuite; + ssliohook->GetCiphersuite(ciphersuite); + ServerInstance->SNO->WriteToSnoMask('l', "Negotiated ciphersuite %s on link %s", ciphersuite.c_str(), x->Name.c_str()); } + return x; + } + + this->SendError("Mismatched server name or password (check the other server's snomask output for details - e.g. umode +s +Ll)"); + ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, invalid link credentials"); + return NULL; +} + +/* + * 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(CommandBase::Params& params) +{ + const Link* x = AuthRemote(params); + if (x) + { /* * They're in WAIT_AUTH_2 (having accepted our credentials). * Set our state to CONNECTED (since everything's peachy so far) and send our @@ -133,29 +161,17 @@ bool TreeSocket::Outbound_Reply_Server(parameterlist ¶ms) * 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(sname, description, sid, Utils->TreeRoot, this, x->Hidden); - Utils->TreeRoot->AddChild(MyRoot); - this->DoBurst(MyRoot); - - // This will send a * in place of the password/hmac - CommandServer::Builder(MyRoot).Forward(MyRoot); + FinishAuth(params[0], params[3], params.back(), x->Hidden); return true; } - this->SendError("Mismatched server name or password (check the other server's snomask output for details - e.g. umode +s +Ll)"); - ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, invalid link credentials"); return false; } bool TreeSocket::CheckDuplicate(const std::string& sname, const std::string& sid) { - /* Check for fully initialized instances of the server by name */ + // Check if the server name is not in use by a server that's already fully connected TreeServer* CheckDupe = Utils->FindServer(sname); if (CheckDupe) { @@ -165,7 +181,7 @@ bool TreeSocket::CheckDuplicate(const std::string& sname, const std::string& sid return false; } - /* Check for fully initialized instances of the server by id */ + // 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); @@ -184,52 +200,16 @@ bool TreeSocket::CheckDuplicate(const std::string& sname, const std::string& sid * Someone else is attempting to connect to us if this is called. Validate their credentials etc. * -- w */ -bool TreeSocket::Inbound_Server(parameterlist ¶ms) +bool TreeSocket::Inbound_Server(CommandBase::Params& params) { - if (params.size() < 5) + const Link* x = AuthRemote(params); + if (x) { - SendError("Protocol error - Missing SID"); - 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]; - - this->SendCapabilities(2); - - if (!ServerInstance->IsSID(sid)) - { - this->SendError("Invalid format server ID: "+sid+"!"); - return false; - } - - for (std::vector >::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; - } - - if (!CheckDuplicate(sname, sid)) - return false; - - ServerInstance->SNO->WriteToSnoMask('l',"Verified incoming server connection " + linkID + " ("+description+")"); - - this->SendCapabilities(2); - // Save these for later, so when they accept our credentials (indicated by BURST) we remember them this->capab->hidden = x->Hidden; - this->capab->sid = sid; - this->capab->description = description; - this->capab->name = sname; + this->capab->sid = params[3]; + this->capab->description = params.back(); + this->capab->name = params[0]; // Send our details: Our server name and description and hopcount of 0, // along with the sendpass from this block. @@ -240,8 +220,6 @@ bool TreeSocket::Inbound_Server(parameterlist ¶ms) return true; } - this->SendError("Mismatched server name or password (check the other server's snomask output for details - e.g. umode +s +Ll)"); - ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, invalid link credentials"); return false; } @@ -249,7 +227,8 @@ CommandServer::Builder::Builder(TreeServer* server) : CmdBuilder(server->GetParent()->GetID(), "SERVER") { push(server->GetName()); - push_raw(" * 0 "); - push_raw(server->GetID()); + push(server->GetID()); + if (server->IsBursting()) + push_property("burst", ConvToStr(server->StartBurst)); push_last(server->GetDesc()); }