X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_spanningtree%2Ftreesocket1.cpp;h=2ead91c8ed3fc8e285a54423d9bea03e5ccb8376;hb=d129d452d391e56284672afee74ca90dee0e6580;hp=d5aeb223c1b37e6e105d71bf5d55c7d0a58a81f2;hpb=8b8a479207923702a93b28829f400444d3bcc624;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_spanningtree/treesocket1.cpp b/src/modules/m_spanningtree/treesocket1.cpp index d5aeb223c..2ead91c8e 100644 --- a/src/modules/m_spanningtree/treesocket1.cpp +++ b/src/modules/m_spanningtree/treesocket1.cpp @@ -628,6 +628,7 @@ bool TreeSocket::ForceJoin(const std::string &source, std::deque &p userrec* who = NULL; /* User we are currently checking */ std::string channel = params[0]; /* Channel name, as a string */ time_t TS = atoi(params[1].c_str()); /* Timestamp given to us for remote side */ + std::string nicklist = params[2]; bool created = false; /* Try and find the channel */ @@ -645,6 +646,13 @@ bool TreeSocket::ForceJoin(const std::string &source, std::deque &p ourTS = chan->age; else created = true; /* don't perform deops, and set TS to correct time after processing. */ + + /* do this first, so our mode reversals are correctly received by other servers + * if there is a TS collision. + */ + params[2] = ":" + params[2]; + Utils->DoOneToAllButSender(source,"FJOIN",params,source); + /* In 1.1, if they have the newer channel, we immediately clear * all status modes from our users. We then accept their modes. * If WE have the newer channel its the other side's job to do this. @@ -669,13 +677,9 @@ bool TreeSocket::ForceJoin(const std::string &source, std::deque &p } } /* Put the final parameter of the FJOIN into a tokenstream ready to split it */ - irc::tokenstream users(params[2]); + irc::tokenstream users(nicklist); std::string item = "*"; - /* do this first, so our mode reversals are correctly received by other servers - * if there is a TS collision. - */ - params[2] = ":" + params[2]; - Utils->DoOneToAllButSender(source,"FJOIN",params,source); + /* Now, process every 'prefixes,nick' pair */ while (item != "") { @@ -752,7 +756,10 @@ bool TreeSocket::ForceJoin(const std::string &source, std::deque &p /* Finally, we can actually place the user into the channel. * We're sure its right. Final answer, phone a friend. */ - chanrec::JoinUser(this->Instance, who, channel.c_str(), true, ""); + if (created) + chanrec::JoinUser(this->Instance, who, channel.c_str(), true, "", TS); + else + chanrec::JoinUser(this->Instance, who, channel.c_str(), true, ""); /* Have we already queued up MAXMODES modes with parameters * (+qaohv) ready to be sent to the server? */ @@ -834,19 +841,6 @@ bool TreeSocket::ForceJoin(const std::string &source, std::deque &p for (unsigned int f = 2; f < modectr; f++) free(mode_users[f]); } - /* if we newly created the channel, set it's TS properly. */ - if (created) - { - /* find created channel .. */ - chan = this->Instance->FindChan(channel); - if (chan) - /* w00t said this shouldnt be needed but it is. - * This isnt strictly true, as chan can be NULL - * if a nick collision has occured and therefore - * the channel was never created. - */ - chan->age = TS; - } /* All done. That wasnt so bad was it, you can wipe * the sweat from your forehead now. :-) */ @@ -856,25 +850,60 @@ bool TreeSocket::ForceJoin(const std::string &source, std::deque &p /** NICK command */ bool TreeSocket::IntroduceClient(const std::string &source, std::deque ¶ms) { - if (params.size() < 8) - return true; - if (params.size() > 8) + /** Do we have enough parameters: + * NICK age nick host dhost ident +modes ip :gecos + */ + if (params.size() != 8) { this->WriteLine(std::string(":")+this->Instance->Config->ServerName+" KILL "+params[1]+" :Invalid client introduction ("+params[1]+"?)"); return true; } - // NICK age nick host dhost ident +modes ip :gecos - // 0 1 2 3 4 5 6 7 - time_t age = atoi(params[0].c_str()); + time_t age = atoi(params[0].c_str()); const char* tempnick = params[1].c_str(); - Instance->Log(DEBUG,"New remote client %s",tempnick); + /** Check parameters for validity before introducing the client, discovered by dmb. + * XXX: Can we make this neater? + */ + if (!age) + { + this->WriteLine(std::string(":")+this->Instance->Config->ServerName+" KILL "+params[1]+" :Invalid client introduction (Invalid TS?)"); + return true; + } + else if (params[1].length() > NICKMAX) + { + this->WriteLine(std::string(":")+this->Instance->Config->ServerName+" KILL "+params[1]+" :Invalid client introduction ("+params[1]+" > NICKMAX?)"); + return true; + } + else if (params[2].length() > 64) + { + this->WriteLine(std::string(":")+this->Instance->Config->ServerName+" KILL "+params[1]+" :Invalid client introduction ("+params[2]+" > 64?)"); + return true; + } + else if (params[3].length() > 64) + { + this->WriteLine(std::string(":")+this->Instance->Config->ServerName+" KILL "+params[1]+" :Invalid client introduction ("+params[3]+" > 64?)"); + return true; + } + else if (params[4].length() > IDENTMAX) + { + this->WriteLine(std::string(":")+this->Instance->Config->ServerName+" KILL "+params[1]+" :Invalid client introduction ("+params[4]+" > IDENTMAX?)"); + return true; + } + else if (params[7].length() > MAXGECOS) + { + this->WriteLine(std::string(":")+this->Instance->Config->ServerName+" KILL "+params[1]+" :Invalid client introduction ("+params[7]+" > MAXGECOS?)"); + return true; + } + + /** Our client looks ok, lets introduce it now + */ + Instance->Log(DEBUG,"New remote client %s",tempnick); user_hash::iterator iter = this->Instance->clientlist->find(tempnick); if (iter != this->Instance->clientlist->end()) { - // nick collision + /* nick collision */ this->WriteLine(std::string(":")+this->Instance->Config->ServerName+" KILL "+tempnick+" :Nickname collision"); userrec::QuitUser(this->Instance, iter->second, "Nickname collision"); return true; @@ -892,9 +921,7 @@ bool TreeSocket::IntroduceClient(const std::string &source, std::dequeregistered = REG_ALL; _new->signon = age; - /* - * we need to remove the + from the modestring, so we can do our stuff - */ + /* we need to remove the + from the modestring, so we can do our stuff */ std::string::size_type pos_after_plus = params[5].find_first_not_of('+'); if (pos_after_plus != std::string::npos) params[5] = params[5].substr(pos_after_plus);