]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_spanningtree/treesocket2.cpp
Fix potential for duplicate SID if the SID is auto generated.
[user/henk/code/inspircd.git] / src / modules / m_spanningtree / treesocket2.cpp
index 74e1dd0844e9b5fd3ea696e37ac21b46a40770a9..34cf318e30d9ec7488d445ca500d89db9b73f53a 100644 (file)
@@ -779,12 +779,13 @@ bool TreeSocket::RemoveStatus(const std::string &prefix, std::deque<std::string>
 
 bool TreeSocket::RemoteServer(const std::string &prefix, std::deque<std::string> &params)
 {
-       if (params.size() < 4)
+       if (params.size() < 5)
                return false;
        std::string servername = params[0];
        std::string password = params[1];
        // hopcount is not used for a remote server, we calculate this ourselves
-       std::string description = params[3];
+       std::string sid = params[3];
+       std::string description = params[4];
        TreeServer* ParentOfThis = Utils->FindServer(prefix);
        if (!ParentOfThis)
        {
@@ -798,10 +799,20 @@ bool TreeSocket::RemoteServer(const std::string &prefix, std::deque<std::string>
                this->Instance->SNO->WriteToSnoMask('l',"Server \2"+servername+"\2 being introduced from \2" + prefix + "\2 denied, already exists. Closing link with " + prefix);
                return false;
        }
+
        Link* lnk = Utils->FindLink(servername);
-       TreeServer* Node = new TreeServer(this->Utils,this->Instance,servername,description,ParentOfThis,NULL, lnk ? lnk->Hidden : false);
+
+       TreeServer *Node = new TreeServer(this->Utils, this->Instance, servername, description, sid, ParentOfThis,NULL, lnk ? lnk->Hidden : false);
+
+       if (Node->DuplicateID())
+       {
+               this->SendError("Server ID "+sid+" already exists on the network!");
+               this->Instance->SNO->WriteToSnoMask('l',"Server \2"+servername+"\2 being introduced from \2" + prefix + "\2 denied, server ID already exists on the network. Closing link with " + prefix);
+               return false;
+       }
+
        ParentOfThis->AddChild(Node);
-       params[3] = ":" + params[3];
+       params[4] = ":" + params[4];
        Utils->SetRemoteBursting(Node, true);
        Utils->DoOneToAllButSender(prefix,"SERVER",params,prefix);
        this->Instance->SNO->WriteToSnoMask('l',"Server \002"+prefix+"\002 introduced server \002"+servername+"\002 ("+description+")");
@@ -828,17 +839,19 @@ bool TreeSocket::ComparePass(const std::string &ours, const std::string &theirs)
 
 bool TreeSocket::Outbound_Reply_Server(std::deque<std::string> &params)
 {
-       if (params.size() < 4)
+       if (params.size() < 5)
                return false;
 
        irc::string servername = params[0].c_str();
        std::string sname = params[0];
        std::string password = params[1];
-       std::string description = params[3];
+       std::string sid = params[3];
+       std::string description = params[4];
        int hops = atoi(params[2].c_str());
 
        this->InboundServerName = sname;
        this->InboundDescription = description;
+       this->InboundSID = sid;
 
        if (!sentcapab)
                this->SendCapabilities();
@@ -869,9 +882,18 @@ bool TreeSocket::Outbound_Reply_Server(std::deque<std::string> &params)
                        // we should add the details of this server now
                        // to the servers tree, as a child of the root
                        // node.
-                       TreeServer* Node = new TreeServer(this->Utils,this->Instance,sname,description,Utils->TreeRoot,this,x->Hidden);
+
+                       TreeServer *Node = new TreeServer(this->Utils, this->Instance, sname, description, sid, Utils->TreeRoot, this, x->Hidden);
+
+                       if (Node->DuplicateID())
+                       {
+                               this->SendError("Server ID "+sid+" already exists on the network!");
+                               this->Instance->SNO->WriteToSnoMask('l',"Server \2"+assign(servername)+"\2 being introduced denied, server ID already exists on the network. Closing link.");
+                               return false;
+                       }
+
                        Utils->TreeRoot->AddChild(Node);
-                       params[3] = ":" + params[3];
+                       params[4] = ":" + params[4];
                        Utils->DoOneToAllButSender(Utils->TreeRoot->GetName(),"SERVER",params,sname);
                        this->bursting = true;
                        this->DoBurst(Node);
@@ -885,16 +907,23 @@ bool TreeSocket::Outbound_Reply_Server(std::deque<std::string> &params)
 
 bool TreeSocket::Inbound_Server(std::deque<std::string> &params)
 {
-       if (params.size() < 4)
+       if (params.size() < 5)
                return false;
        irc::string servername = params[0].c_str();
        std::string sname = params[0];
        std::string password = params[1];
-       std::string description = params[3];
+       std::string sid = params[3];
+       std::string description = params[4];
+       std::string OurSID;
        int hops = atoi(params[2].c_str());
 
        this->InboundServerName = sname;
        this->InboundDescription = description;
+       this->InboundSID = sid;
+
+       OurSID += (char)((Instance->Config->sid / 100) + 48);
+       OurSID += (char)((Instance->Config->sid / 10) % 10 + 48);
+       OurSID += (char)(Instance->Config->sid % 10 + 48);
 
        if (!sentcapab)
                this->SendCapabilities();
@@ -922,7 +951,17 @@ bool TreeSocket::Inbound_Server(std::deque<std::string> &params)
                                CheckDupeSocket->Close();
                                return false;
                        }
-                       /* Now check for fully initialized instances of the server */
+                       /* Check for fully initialized instances of the server by id */
+                       Instance->Log(DEBUG,"Looking for dupe SID %s", sid.c_str());
+                       TreeServer* CheckDupeSID = Utils->FindServerID(sid);
+                       if (CheckDupeSID)
+                       {
+                               this->SendError("Server ID "+CheckDupeSID->GetID()+" already exists on server "+CheckDupeSID->GetName()+"!");
+                               this->Instance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, server ID '"+CheckDupeSID->GetID()+
+                                               "' already exists on server "+CheckDupeSID->GetName());
+                               return false;
+                       }
+                       /* Now check for fully initialized instances of the server by name */
                        TreeServer* CheckDupe = Utils->FindServer(sname);
                        if (CheckDupe)
                        {
@@ -941,7 +980,7 @@ bool TreeSocket::Inbound_Server(std::deque<std::string> &params)
 
                        // this is good. Send our details: Our server name and description and hopcount of 0,
                        // along with the sendpass from this block.
-                       this->WriteLine(std::string("SERVER ")+this->Instance->Config->ServerName+" "+this->MakePass(x->SendPass, this->GetTheirChallenge())+" 0 :"+this->Instance->Config->ServerDesc);
+                       this->WriteLine(std::string("SERVER ")+this->Instance->Config->ServerName+" "+this->MakePass(x->SendPass, this->GetTheirChallenge())+" 0 "+OurSID+" :"+this->Instance->Config->ServerDesc);
                        // move to the next state, we are now waiting for THEM.
                        this->LinkState = WAIT_AUTH_2;
                        return true;
@@ -1064,13 +1103,22 @@ bool TreeSocket::ProcessLine(std::string &line)
                                }
                                this->LinkState = CONNECTED;
                                Link* lnk = Utils->FindLink(InboundServerName);
-                               Node = new TreeServer(this->Utils,this->Instance, InboundServerName, InboundDescription, Utils->TreeRoot, this, lnk ? lnk->Hidden : false);
+
+                               Node = new TreeServer(this->Utils,this->Instance, InboundServerName, InboundDescription, InboundSID, Utils->TreeRoot, this, lnk ? lnk->Hidden : false);
+
+                               if (Node->DuplicateID())
+                               {
+                                       this->SendError("Server ID "+InboundSID+" already exists on the network!");
+                                       this->Instance->SNO->WriteToSnoMask('l',"Server \2"+InboundServerName+"\2 being introduced from \2" + prefix + "\2 denied, server ID already exists on the network. Closing link.");
+                                       return false;
+                               }
                                Utils->DelBurstingServer(this);
                                Utils->TreeRoot->AddChild(Node);
                                params.clear();
                                params.push_back(InboundServerName);
                                params.push_back("*");
                                params.push_back("1");
+                               params.push_back(InboundSID);
                                params.push_back(":"+InboundDescription);
                                Utils->DoOneToAllButSender(Utils->TreeRoot->GetName(),"SERVER",params,InboundServerName);
                                this->bursting = true;
@@ -1117,16 +1165,8 @@ bool TreeSocket::ProcessLine(std::string &line)
                        if (!prefix.empty())
                        {
                                std::string direction = prefix;
-                               // XXX
+
                                userrec *t = this->Instance->FindUUID(prefix);
-                               if (!t)
-                               {
-                                       userrec* t = this->Instance->FindNick(prefix);
-                                       if (t)
-                                       {
-                                               Instance->Log(DEBUG,"Ack, legacy command!");
-                                       }
-                               }
                                if (t)
                                {
                                        direction = t->server;
@@ -1426,26 +1466,8 @@ bool TreeSocket::ProcessLine(std::string &line)
                                 * Not a special s2s command. Emulate the user doing it.
                                 * This saves us having a huge ugly command parser again.
                                 */
-
-
-                               /*
-                                *
-                                * First, let's find them by UID. If we don't find, try again
-                                * by nick (to catch legacy commands temporarily).
-                                * If we still don't .. carry on and pray. -- w00t
-                                */
                                userrec *who = this->Instance->FindUUID(prefix);
 
-                               if (!who)
-                               {
-                                       userrec* who = this->Instance->FindNick(prefix);
-
-                                       if (who)
-                                       {
-                                               Instance->Log(DEBUG, "Glark! I got a legacy command!");
-                                       }
-                               }
-
                                std::string sourceserv = this->myhost;
                                if (!this->InboundServerName.empty())
                                {