X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_spanningtree%2Fuid.cpp;h=cafaee4c077d015799419d6a2f0e5f8e97257157;hb=90abe2cd475c8ca2e81626f565d173e9f56d1251;hp=f248b3860743880d0e2720d8c9852e0faac5ba5d;hpb=ea590a5d80741c3bc030cb0a2fcb3c59da4fd078;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_spanningtree/uid.cpp b/src/modules/m_spanningtree/uid.cpp index f248b3860..cafaee4c0 100644 --- a/src/modules/m_spanningtree/uid.cpp +++ b/src/modules/m_spanningtree/uid.cpp @@ -31,58 +31,57 @@ CmdResult CommandUID::HandleServer(TreeServer* remoteserver, std::vectorGetID()) - return CMD_INVALID; + if (params[0].length() != UIDGenerator::UUID_LENGTH || params[0].compare(0, 3, remoteserver->GetID())) + throw ProtocolException("Bogus UUID"); /* Check parameters for validity before introducing the client, discovered by dmb */ - if (!age_t) - return CMD_INVALID; - if (!signon) - return CMD_INVALID; if (modestr[0] != '+') - return CMD_INVALID; + throw ProtocolException("Invalid mode string"); - /* check for collision */ + // See if there is a nick collision User* collideswith = ServerInstance->FindNickOnly(params[2]); - if (collideswith) + if ((collideswith) && (collideswith->registered != REG_ALL)) { - /* - * Nick collision. - */ + // User that the incoming user is colliding with is not fully registered, we force nick change the + // unregistered user to their uuid and tell them what happened + collideswith->WriteFrom(collideswith, "NICK %s", collideswith->uuid.c_str()); + collideswith->WriteNumeric(ERR_NICKNAMEINUSE, "%s :Nickname overruled.", collideswith->nick.c_str()); + + // Clear the bit before calling User::ChangeNick() to make it NOT run the OnUserPostNick() hook + collideswith->registered &= ~REG_NICK; + collideswith->ChangeNick(collideswith->uuid); + } + else if (collideswith) + { + // The user on this side is registered, handle the collision int collide = Utils->DoCollision(collideswith, remoteserver, age_t, params[5], params[6], params[0]); ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "*** Collision on %s, collide=%d", params[2].c_str(), collide); if (collide != 1) { - // Remote client lost, make sure we change their nick for the hash too + // The client being introduced needs to change nick to uuid, change the nick in the message before + // processing/forwarding it. params[2] = params[0]; } } /* IMPORTANT NOTE: For remote users, we pass the UUID in the constructor. This automatically * sets it up in the UUID hash for us. + * + * If the UUID already exists User::User() throws an exception which causes this connection to be closed. */ - User* _new = NULL; - try - { - _new = new RemoteUser(params[0], remoteserver); - } - catch (...) - { - ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Duplicate UUID %s in client introduction", params[0].c_str()); - return CMD_INVALID; - } + RemoteUser* _new = new RemoteUser(params[0], remoteserver); ServerInstance->Users->clientlist[params[2]] = _new; _new->nick = params[2]; _new->host = params[3]; _new->dhost = params[4]; _new->ident = params[5]; - _new->fullname = params[params.size() - 1]; + _new->fullname = params.back(); _new->registered = REG_ALL; _new->signon = signon; _new->age = age_t; @@ -98,15 +97,12 @@ CmdResult CommandUID::HandleServer(TreeServer* remoteserver, std::vectorModes->FindMode(*v, MODETYPE_USER); if (!mh) - { - ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Unrecognised mode '%c' for a user in UID, dropping link", *v); - return CMD_INVALID; - } + throw ProtocolException("Unrecognised mode '" + std::string(1, *v) + "'"); if (mh->GetNumParams(true)) { if (paramptr >= params.size() - 1) - return CMD_INVALID; + throw ProtocolException("Out of parameters while processing modes"); std::string mp = params[paramptr++]; /* IMPORTANT NOTE: * All modes are assumed to succeed here as they are being set by a remote server. @@ -126,7 +122,7 @@ CmdResult CommandUID::HandleServer(TreeServer* remoteserver, std::vectorSetClientIP(params[6].c_str()); - ServerInstance->Users->AddGlobalClone(_new); + ServerInstance->Users->AddClone(_new); remoteserver->UserCount++; bool dosend = true;