Пример #1
0
/**
 * SAVE command - force nick change to UID on timestamp match
 */
CmdResult CommandSave::Handle(User* user, std::vector<std::string>& params)
{
	User* u = ServerInstance->FindUUID(params[0]);
	if ((!u) || (IS_SERVER(u)))
		return CMD_FAILURE;

	time_t ts = atol(params[1].c_str());

	if (u->age == ts)
		u->ChangeNick(u->uuid, SavedTimestamp);

	return CMD_SUCCESS;
}
Пример #2
0
	CmdResult Handle (const std::vector<std::string>& parameters, User *user)
	{
		User* target = ServerInstance->FindNick(parameters[0]);

		/* Do local sanity checks and bails */
		if (IS_LOCAL(user))
		{
			if (target && ServerInstance->ULine(target->server))
			{
				user->WriteNumeric(ERR_NOPRIVILEGES, "%s :Cannot use an SA command on a u-lined client",user->nick.c_str());
				return CMD_FAILURE;
			}

			if ((!target) || (target->registered != REG_ALL))
			{
				user->WriteServ("NOTICE %s :*** No such nickname: '%s'", user->nick.c_str(), parameters[0].c_str());
				return CMD_FAILURE;
			}

			if (!ServerInstance->IsNick(parameters[1], ServerInstance->Config->Limits.NickMax))
			{
				user->WriteServ("NOTICE %s :*** Invalid nickname '%s'", user->nick.c_str(), parameters[1].c_str());
				return CMD_FAILURE;
			}
		}

		/* Have we hit target's server yet? */
		if (target && IS_LOCAL(target))
		{
			std::string oldnick = user->nick;
			std::string newnick = target->nick;
			if (target->ChangeNick(parameters[1], true))
			{
				ServerInstance->SNO->WriteGlobalSno('a', oldnick+" used SANICK to change "+newnick+" to "+parameters[1]);
			}
			else
			{
				ServerInstance->SNO->WriteGlobalSno('a', oldnick+" failed SANICK (from "+newnick+" to "+parameters[1]+")");
			}
		}

		return CMD_SUCCESS;
	}
Пример #3
0
/*
 ** NICK - new
 **	  source  = NULL
 **	  parv[0] = nickname
 **	  parv[1] = hopcount
 **	  parv[2] = timestamp
 **	  parv[3] = modes
 **	  parv[4] = username
 **	  parv[5] = hostname
 **	  parv[6] = server
 **	  parv[7] = servicestamp
 **	  parv[8] = IP
 **	  parv[9] = info
 ** NICK - change
 **	  source  = oldnick
 **	  parv[0] = new nickname
 **	  parv[1] = hopcount
 */
void bahamut::Nick::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
	if (params.size() == 10)
	{
		Server *s = Server::Find(params[6]);
		if (s == nullptr)
		{
			Log(LOG_DEBUG) << "User " << params[0] << " introduced from non-existent server " << params[6] << "?";
			return;
		}

		NickServ::Nick *na = nullptr;
		time_t signon = 0, stamp = 0;

		try
		{
			signon = convertTo<time_t>(params[2]);
			stamp = convertTo<time_t>(params[7]);
		}
		catch (const ConvertException &)
		{
		}

		if (signon && signon == stamp && NickServ::service)
			na = NickServ::service->FindNick(params[0]);

		User::OnIntroduce(params[0], params[4], params[5], "", params[8], s, params[9], signon, params[3], "", na ? na->GetAccount() : nullptr);
	}
	else
	{
		User *u = source.GetUser();

		if (u)
			u->ChangeNick(params[0]);
	}
}
Пример #4
0
CmdResult CommandUID::HandleServer(TreeServer* remoteserver, std::vector<std::string>& params)
{
	/**
	 *      0    1    2    3    4    5        6        7     8        9       (n-1)
	 * UID uuid age nick host dhost ident ip.string signon +modes (modepara) :gecos
	 */
	time_t age_t = ServerCommand::ExtractTS(params[1]);
	time_t signon = ServerCommand::ExtractTS(params[7]);
	std::string empty;
	const std::string& modestr = params[8];

	// Check if the length of the uuid is correct and confirm the sid portion of the uuid matches the sid of the server introducing the user
	if (params[0].length() != UIDGenerator::UUID_LENGTH || params[0].compare(0, 3, remoteserver->GetID()))
		throw ProtocolException("Bogus UUID");
	// Sanity check on mode string: must begin with '+'
	if (modestr[0] != '+')
		throw ProtocolException("Invalid mode string");

	// See if there is a nick collision
	User* collideswith = ServerInstance->FindNickOnly(params[2]);
	if ((collideswith) && (collideswith->registered != REG_ALL))
	{
		// 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, collideswith->nick, "Nickname overruled.");

		// 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
		bool they_change = Utils->DoCollision(collideswith, remoteserver, age_t, params[5], params[6], params[0], "UID");
		if (they_change)
		{
			// The client being introduced needs to change nick to uuid, change the nick in the message before
			// processing/forwarding it. Also change the nick TS to CommandSave::SavedTimestamp.
			age_t = CommandSave::SavedTimestamp;
			params[1] = ConvToStr(CommandSave::SavedTimestamp);
			params[2] = params[0];
		}
	}

	/* For remote users, we pass the UUID they sent to the constructor.
	 * If the UUID already exists User::User() throws an exception which causes this connection to be closed.
	 */
	RemoteUser* _new = new SpanningTree::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.back();
	_new->registered = REG_ALL;
	_new->signon = signon;
	_new->age = age_t;

	unsigned int paramptr = 9;

	for (std::string::const_iterator v = modestr.begin(); v != modestr.end(); ++v)
	{
		// Accept more '+' chars, for now
		if (*v == '+')
			continue;

		/* For each mode thats set, find the mode handler and set it on the new user */
		ModeHandler* mh = ServerInstance->Modes->FindMode(*v, MODETYPE_USER);
		if (!mh)
			throw ProtocolException("Unrecognised mode '" + std::string(1, *v) + "'");

		if (mh->NeedsParam(true))
		{
			if (paramptr >= params.size() - 1)
				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.
			 * Modes CANNOT FAIL here. If they DO fail, then the failure is ignored. This is important
			 * to note as all but one modules currently cannot ever fail in this situation, except for
			 * m_servprotect which specifically works this way to prevent the mode being set ANYWHERE
			 * but here, at client introduction. You may safely assume this behaviour is standard and
			 * will not change in future versions if you want to make use of this protective behaviour
			 * yourself.
			 */
			mh->OnModeChange(_new, _new, NULL, mp, true);
		}
		else
			mh->OnModeChange(_new, _new, NULL, empty, true);
		_new->SetMode(mh, true);
	}

	_new->SetClientIP(params[6].c_str());

	ServerInstance->Users->AddClone(_new);
	remoteserver->UserCount++;

	bool dosend = true;

	if ((Utils->quiet_bursts && remoteserver->IsBehindBursting()) || _new->server->IsSilentULine())
		dosend = false;

	if (dosend)
		ServerInstance->SNO->WriteToSnoMask('C',"Client connecting at %s: %s (%s) [%s]", remoteserver->GetName().c_str(), _new->GetFullRealHost().c_str(), _new->GetIPString().c_str(), _new->fullname.c_str());

	FOREACH_MOD(OnPostConnect, (_new));

	return CMD_SUCCESS;
}