Example #1
0
	virtual void OnBuildExemptList(MessageType message_type, Channel* chan, User* sender, char status, CUList &exempt_list, const std::string &text)
	{
		int public_silence = (message_type == MSG_PRIVMSG ? SILENCE_CHANNEL : SILENCE_CNOTICE);
		CUList *ulist;
		switch (status)
		{
			case '@':
				ulist = chan->GetOppedUsers();
				break;
			case '%':
				ulist = chan->GetHalfoppedUsers();
				break;
			case '+':
				ulist = chan->GetVoicedUsers();
				break;
			default:
				ulist = chan->GetUsers();
				break;
		}

		for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++)
		{
			if (IS_LOCAL(i->first))
			{
				if (MatchPattern(i->first, sender, public_silence) == 1)
				{
					exempt_list[i->first] = i->first->nick;
				}
			}
		}
	}
Example #2
0
void UserManager::RemoveCloneCounts(User *user)
{
	if (IS_LOCAL(user))
	{
		clonemap::iterator x = local_clones.find(user->GetCIDRMask());
		if (x != local_clones.end())
		{
			x->second--;
			if (!x->second)
			{
				local_clones.erase(x);
			}
		}
	}

	clonemap::iterator y = global_clones.find(user->GetCIDRMask());
	if (y != global_clones.end())
	{
		y->second--;
		if (!y->second)
		{
			global_clones.erase(y);
		}
	}
}
Example #3
0
static bool checkHoplimit(MacInfo_t *info)
{
    if (IS_LOCAL(info)) return true; // only for forwarding
    if (!info->hoplimit) return true; // hoplimit is optional
    if (--info->hoplimit) return true; // shold be larger than zero after decrement
    return false;
}
Example #4
0
void ModuleSpanningTree::OnUserJoin(userrec* user, chanrec* channel, bool &silent)
{
	// Only do this for local users
	if (IS_LOCAL(user))
	{
		if (channel->GetUserCounter() == 1)
		{
			std::deque<std::string> params;
			// set up their permissions and the channel TS with FJOIN.
			// All users are FJOINed now, because a module may specify
			// new joining permissions for the user.
			params.push_back(channel->name);
			params.push_back(ConvToStr(channel->age));
			params.push_back(std::string(channel->GetAllPrefixChars(user))+","+std::string(user->nick));
			Utils->DoOneToMany(ServerInstance->Config->ServerName,"FJOIN",params);
			/* First user in, sync the modes for the channel */
			params.pop_back();
			params.push_back(channel->ChanModes(true));
			Utils->DoOneToMany(ServerInstance->Config->ServerName,"FMODE",params);
		}
		else
		{
			std::deque<std::string> params;
			params.push_back(channel->name);
			params.push_back(ConvToStr(channel->age));
			Utils->DoOneToMany(user->nick,"JOIN",params);
		}
	}
}
Example #5
0
/** Because Andy insists that services-compatible servers must
 * implement SVSNICK and SVSJOIN, that's exactly what we do :p
 */
bool TreeSocket::ForceNick(const std::string &prefix, std::deque<std::string> &params)
{
	if (params.size() < 3)
		return true;

	User* u = this->ServerInstance->FindNick(params[0]);

	if (u)
	{
		Utils->DoOneToAllButSender(prefix,"SVSNICK",params,prefix);

		if (IS_LOCAL(u))
		{
			std::deque<std::string> par;
			par.push_back(params[1]);

			if (!u->ForceNickChange(params[1].c_str()))
			{
				/* buh. UID them */
				if (!u->ForceNickChange(u->uuid.c_str()))
				{
					this->ServerInstance->Users->QuitUser(u, "Nickname collision");
					return true;
				}
			}

			u->age = atoi(params[2].c_str());
		}
	}

	return true;
}
Example #6
0
int ModuleSpanningTree::HandleSquit(const char** parameters, int pcnt, userrec* user)
{
	TreeServer* s = Utils->FindServerMask(parameters[0]);
	if (s)
	{
		if (s == Utils->TreeRoot)
		{
			user->WriteServ("NOTICE %s :*** SQUIT: Foolish mortal, you cannot make a server SQUIT itself! (%s matches local server name)",user->nick,parameters[0]);
			return 1;
		}
		TreeSocket* sock = s->GetSocket();
		if (sock)
		{
			ServerInstance->SNO->WriteToSnoMask('l',"SQUIT: Server \002%s\002 removed from network by %s",parameters[0],user->nick);
			sock->Squit(s,std::string("Server quit by ") + user->GetFullRealHost());
			ServerInstance->SE->DelFd(sock);
			sock->Close();
		}
		else
		{
			if (IS_LOCAL(user))
				user->WriteServ("NOTICE %s :*** WARNING: Using SQUIT to split remote servers is deprecated. Please use RSQUIT instead.",user->nick);
		}
	}
	else
	{
		 user->WriteServ("NOTICE %s :*** SQUIT: The server \002%s\002 does not exist on the network.",user->nick,parameters[0]);
	}
	return 1;
}
Example #7
0
void Snomask::SendMessage(const std::string &message)
{
	if (message != LastMessage)
	{
		this->Flush();
		LastMessage = message;

		std::string desc = this->Description;
		int MOD_RESULT = 0;
		char mysnomask = MySnomask;
		ServerInstance->Logs->Log("snomask", DEFAULT, "%s: %s", desc.c_str(), message.c_str());

		FOREACH_RESULT(I_OnSendSnotice, OnSendSnotice(mysnomask, desc, message));

		LastBlocked = (MOD_RESULT == 1); // 1 blocks the message

		if (!LastBlocked)
		{
			/* Only opers can receive snotices, so we iterate the oper list */
			std::list<User*>::iterator i = ServerInstance->Users->all_opers.begin();

			while (i != ServerInstance->Users->all_opers.end())
			{
				User* a = *i;
				if (IS_LOCAL(a) && a->IsModeSet('s') && a->IsNoticeMaskSet(mysnomask) && !a->quitting)
				{
					a->WriteServ("NOTICE %s :*** %s: %s", a->nick.c_str(), desc.c_str(), message.c_str());
				}

				i++;
			}
		}
	}
	Count++;
}
Example #8
0
void ModuleSpanningTree::OnMode(userrec* user, void* dest, int target_type, const std::string &text)
{
	if ((IS_LOCAL(user)) && (user->registered == REG_ALL))
	{
		std::deque<std::string> params;
		std::string command;

		if (target_type == TYPE_USER)
		{
			userrec* u = (userrec*)dest;
			params.push_back(u->nick);
			params.push_back(text);
			command = "MODE";
		}
		else
		{
			chanrec* c = (chanrec*)dest;
			params.push_back(c->name);
			params.push_back(ConvToStr(c->age));
			params.push_back(text);
			command = "FMODE";
		}
		Utils->DoOneToMany(user->nick, command, params);
	}
}
Example #9
0
	CmdResult Handle (const std::vector<std::string>& parameters, User *user)
	{
		User* dest = ServerInstance->FindNick(parameters[0]);
		if ((dest) && (dest->registered == REG_ALL))
		{
			if (dest->server->IsULine())
			{
				user->WriteNumeric(ERR_NOPRIVILEGES, ":Cannot use an SA command on a u-lined client");
				return CMD_FAILURE;
			}
			if (IS_LOCAL(user) && !ServerInstance->IsChannel(parameters[1]))
			{
				/* we didn't need to check this for each character ;) */
				user->WriteNotice("*** Invalid characters in channel name or name too long");
				return CMD_FAILURE;
			}

			/* For local users, we call Channel::JoinUser which may create a channel and set its TS.
			 * For non-local users, we just return CMD_SUCCESS, knowing this will propagate it where it needs to be
			 * and then that server will handle the command.
			 */
			LocalUser* localuser = IS_LOCAL(dest);
			if (localuser)
			{
				Channel* n = Channel::JoinUser(localuser, parameters[1], true);
				if (n && n->HasUser(dest))
				{
					ServerInstance->SNO->WriteGlobalSno('a', user->nick+" used SAJOIN to make "+dest->nick+" join "+parameters[1]);
					return CMD_SUCCESS;
				}
				else
				{
					user->WriteNotice("*** Could not join "+dest->nick+" to "+parameters[1]);
					return CMD_FAILURE;
				}
			}
			else
			{
				return CMD_SUCCESS;
			}
		}
		else
		{
			user->WriteNotice("*** No such nickname "+parameters[0]);
			return CMD_FAILURE;
		}
	}
Example #10
0
void ModuleSpanningTree::OnUserNotice(userrec* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list)
{
	if (target_type == TYPE_USER)
	{
		userrec* d = (userrec*)dest;
		if ((d->GetFd() < 0) && (IS_LOCAL(user)))
		{
			std::deque<std::string> params;
			params.clear();
			params.push_back(d->nick);
			params.push_back(":"+text);
			Utils->DoOneToOne(user->nick,"NOTICE",params,d->server);
		}
	}
	else if (target_type == TYPE_CHANNEL)
	{
		if (IS_LOCAL(user))
		{
			chanrec *c = (chanrec*)dest;
			if (c)
			{
				std::string cname = c->name;
				if (status)
					cname = status + cname;
				TreeServerList list;
				Utils->GetListOfServersForChannel(c,list,status,exempt_list);
				for (TreeServerList::iterator i = list.begin(); i != list.end(); i++)
				{
					TreeSocket* Sock = i->second->GetSocket();
					if (Sock)
						Sock->WriteLine(":"+std::string(user->nick)+" NOTICE "+cname+" :"+text);
				}
			}
		}
	}
	else if (target_type == TYPE_SERVER)
	{
		if (IS_LOCAL(user))
		{
			char* target = (char*)dest;
			std::deque<std::string> par;
			par.push_back(target);
			par.push_back(":"+text);
			Utils->DoOneToMany(user->nick,"NOTICE",par);
		}
	}
}
Example #11
0
	ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
	{
		if (adding)
		{
			if (IS_LOCAL(source))
			{
				if (!ServerInstance->IsChannel(parameter))
				{
					source->WriteNumeric(ERR_NOSUCHCHANNEL, "%s :Invalid channel name", parameter.c_str());
					return MODEACTION_DENY;
				}
			}

			if (IS_LOCAL(source) && !source->IsOper())
			{
				Channel* c = ServerInstance->FindChan(parameter);
				if (!c)
				{
					source->WriteNumeric(690, ":Target channel %s must exist to be set as a redirect.",parameter.c_str());
					return MODEACTION_DENY;
				}
				else if (c->GetPrefixValue(source) < OP_VALUE)
				{
					source->WriteNumeric(690, ":You must be opped on %s to set it as a redirect.",parameter.c_str());
					return MODEACTION_DENY;
				}
			}

			if (channel->GetModeParameter(this) == parameter)
				return MODEACTION_DENY;
			/*
			 * We used to do some checking for circular +L here, but there is no real need for this any more especially as we
			 * now catch +L looping in PreJoin. Remove it, since O(n) logic makes me sad, and we catch it anyway. :) -- w00t
			 */
			return MODEACTION_ALLOW;
		}
		else
		{
			if (channel->IsModeSet(this))
			{
				return MODEACTION_ALLOW;
			}
		}

		return MODEACTION_DENY;

	}
Example #12
0
	RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
	{
		if (IS_LOCAL(user))
			// This is handled by the OnUserMessage hook to split the LoopCall pieces
			return ROUTE_LOCALONLY;
		else
			return ROUTE_MESSAGE(parameters[0]);
	}
Example #13
0
	virtual void OnUserPart(Membership* memb, std::string &partmessage, CUList& excepts)
	{
		if (!IS_LOCAL(memb->user))
			return;

		if (memb->chan->GetExtBanStatus(memb->user, 'p') == MOD_RES_DENY)
			partmessage.clear();
	}
Example #14
0
	// :kenny.chatspike.net 320 Om Epy|AFK :is a Secure Connection
	virtual void OnWhois(userrec* source, userrec* dest)
	{
		// Bugfix, only send this numeric for *our* SSL users
		if(dest->GetExt("ssl", dummy) || (IS_LOCAL(dest) &&  isin(dest->GetPort(), listenports)))
		{
			source->WriteServ("320 %s %s :is using a secure connection", source->nick, dest->nick);
		}
	}
Example #15
0
void ModuleSpanningTree::OnPostTopicChange(User* user, Channel* chan, const std::string &topic)
{
	// Drop remote events on the floor.
	if (!IS_LOCAL(user))
		return;

	CommandFTopic::Builder(user, chan).Broadcast();
}
Example #16
0
bool User::ChangeName(const std::string& gecos)
{
	if (!this->fullname.compare(gecos))
		return true;

	if (IS_LOCAL(this))
	{
		ModResult MOD_RESULT;
		FIRST_MOD_RESULT(OnChangeLocalUserGECOS, MOD_RESULT, (IS_LOCAL(this),gecos));
		if (MOD_RESULT == MOD_RES_DENY)
			return false;
		FOREACH_MOD(OnChangeName, (this,gecos));
	}
	this->fullname.assign(gecos, 0, ServerInstance->Config->Limits.MaxGecos);

	return true;
}
Example #17
0
	ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
	{
		if (adding)
		{
			std::string::size_type colon = parameter.find(':');
			if (colon == std::string::npos)
				return MODEACTION_DENY;

			std::string duration = parameter.substr(colon+1);
			if ((IS_LOCAL(source)) && ((duration.length() > 10) || (!IsValidDuration(duration))))
				return MODEACTION_DENY;

			unsigned int len = ConvToInt(parameter.substr(0, colon));
			int time = InspIRCd::Duration(duration);
			if (len == 0 || time < 0)
				return MODEACTION_DENY;
			if (len > maxlines && IS_LOCAL(source))
				return MODEACTION_DENY;
			if (len > maxlines)
				len = maxlines;
			if (parameter == channel->GetModeParameter(this))
				return MODEACTION_DENY;

			HistoryList* history = ext.get(channel);
			if (history)
			{
				// Shrink the list if the new line number limit is lower than the old one
				if (len < history->lines.size())
					history->lines.erase(history->lines.begin(), history->lines.begin() + (history->lines.size() - len));

				history->maxlen = len;
				history->maxtime = time;
			}
			else
			{
				ext.set(channel, new HistoryList(len, time));
			}
		}
		else
		{
			if (!channel->IsModeSet(this))
				return MODEACTION_DENY;
			ext.unset(channel);
		}
		return MODEACTION_ALLOW;
	}
Example #18
0
/** Handle /MODULES
 */
CmdResult CommandModules::Handle(User* user, const Params& parameters)
{
	// Don't ask remote servers about their modules unless the local user asking is an oper
	// 2.0 asks anyway, so let's handle that the same way
	bool for_us = (parameters.empty() || irc::equals(parameters[0], ServerInstance->Config->ServerName));
	if ((!for_us) || (!IS_LOCAL(user)))
	{
		if (!user->IsOper())
		{
			user->WriteNotice("*** You cannot check what modules other servers have loaded.");
			return CMD_FAILURE;
		}

		// From an oper and not for us, forward
		if (!for_us)
			return CMD_SUCCESS;
	}

	const ModuleManager::ModuleMap& mods = ServerInstance->Modules.GetModules();

  	for (ModuleManager::ModuleMap::const_iterator i = mods.begin(); i != mods.end(); ++i)
	{
		Module* m = i->second;
		Version V = m->GetVersion();

		if (IS_LOCAL(user) && user->HasPrivPermission("servers/auspex"))
		{
			std::string flags("VCO");
			size_t pos = 0;
			for (int mult = 2; mult <= VF_OPTCOMMON; mult *= 2, ++pos)
				if (!(V.Flags & mult))
					flags[pos] = '-';

			std::string srcrev = m->ModuleDLLManager->GetVersion();
			user->WriteRemoteNumeric(RPL_MODLIST, m->ModuleSourceFile, srcrev.empty() ? "*" : srcrev, flags, V.description);
		}
		else
		{
			user->WriteRemoteNumeric(RPL_MODLIST, m->ModuleSourceFile, '*', '*', V.description);
		}
	}
	user->WriteRemoteNumeric(RPL_ENDOFMODLIST, "End of MODULES list");

	return CMD_SUCCESS;
}
Example #19
0
	bool Matches(User *u)
	{
		LocalUser* lu = IS_LOCAL(u);
		if (lu && lu->exempt)
			return false;

		std::string compare = u->nick + "!" + u->ident + "@" + u->host + " " + u->fullname;
		return regex->Matches(compare);
	}
Example #20
0
    virtual void OnPostOper(userrec* user, const std::string &opertype)
    {
        if (!IS_LOCAL(user))
            return;

        for(std::vector<std::string>::iterator it = operChans.begin(); it != operChans.end(); it++)
            if (ServerInstance->IsChannel(it->c_str()))
                chanrec::JoinUser(ServerInstance, user, it->c_str(), false, "", ServerInstance->Time(true));
    }
Example #21
0
void ModuleSpanningTree::OnOper(User* user, const std::string &opertype)
{
	if (user->registered != REG_ALL || !IS_LOCAL(user))
		return;

	// Note: The protocol does not allow direct umode +o;
	// sending OPERTYPE infers +o modechange locally.
	CommandOpertype::Builder(user).Broadcast();
}
Example #22
0
void ModuleSpanningTree::OnCancelAway(userrec* user)
{
	if (IS_LOCAL(user))
	{
		std::deque<std::string> params;
		params.clear();
		Utils->DoOneToMany(user->nick,"AWAY",params);
	}
}
Example #23
0
	CmdResult Handle (const char** parameters, int pcnt, userrec *user)
	{
		userrec* dest = ServerInstance->FindNick(parameters[0]);
		if (dest)
		{
			if (ServerInstance->ULine(dest->server))
			{
				user->WriteServ("990 %s :Cannot use an SA command on a u-lined client",user->nick);
				return CMD_FAILURE;
			}
			if (!ServerInstance->IsChannel(parameters[1]))
			{
				/* we didn't need to check this for each character ;) */
				user->WriteServ("NOTICE "+std::string(user->nick)+" :*** Invalid characters in channel name");
				return CMD_FAILURE;
			}

			/* For local users, we send the JoinUser which may create a channel and set its TS.
			 * For non-local users, we just return CMD_SUCCESS, knowing this will propogate it where it needs to be
			 * and then that server will generate the users JOIN or FJOIN instead.
			 */
			if (IS_LOCAL(dest))
			{
				chanrec::JoinUser(ServerInstance, dest, parameters[1], true, "", ServerInstance->Time(true));
				/* Fix for dotslasher and w00t - if the join didnt succeed, return CMD_FAILURE so that it doesnt propogate */
				chanrec* n = ServerInstance->FindChan(parameters[1]);
				if (n)
				{
					if (n->HasUser(dest))
					{
						ServerInstance->WriteOpers("*** "+std::string(user->nick)+" used SAJOIN to make "+std::string(dest->nick)+" join "+parameters[1]);
						return CMD_SUCCESS;
					}
					else
					{
						user->WriteServ("NOTICE "+std::string(user->nick)+" :*** Could not join "+std::string(dest->nick)+" to "+parameters[1]+" (User is probably banned, or blocking modes)");
						return CMD_FAILURE;
					}
				}
				else
				{
					user->WriteServ("NOTICE "+std::string(user->nick)+" :*** Could not join "+std::string(dest->nick)+" to "+parameters[1]);
					return CMD_FAILURE;
				}
			}
			else
			{
				ServerInstance->WriteOpers("*** "+std::string(user->nick)+" sent remote SAJOIN to make "+std::string(dest->nick)+" join "+parameters[1]);
				return CMD_SUCCESS;
			}
		}
		else
		{
			user->WriteServ("NOTICE "+std::string(user->nick)+" :*** No such nickname "+parameters[0]);
			return CMD_FAILURE;
		}
	}
Example #24
0
void ModuleSpanningTree::OnWallops(User* user, const std::string &text)
{
	if (IS_LOCAL(user))
	{
		std::deque<std::string> params;
		params.push_back(":"+text);
		Utils->DoOneToMany(user->uuid,"WALLOPS",params);
	}
}
Example #25
0
	void OnChangeIdent(User* user, const std::string& ident)
	{
		if (IS_LOCAL(user) && ext.get(user) == NULL)
		{
			ServerInstance->Logs->Log("m_identmeta", DEBUG, "Setting ident metadata of %s to %s.",
				user->nick.c_str(), ident.c_str());
			ext.set(user, ident);
		}
	}
Example #26
0
void cmd_kill::Handle (const char** parameters, int pcnt, userrec *user)
{
	userrec *u = ServerInstance->FindNick(parameters[0]);
	char killreason[MAXBUF];
	int MOD_RESULT = 0;

	ServerInstance->Log(DEBUG,"kill: %s %s", parameters[0], parameters[1]);

	if (u)
	{
		ServerInstance->Log(DEBUG, "into kill mechanism");
		FOREACH_RESULT(I_OnKill, OnKill(user, u, parameters[1]));

		if (MOD_RESULT)
		{
			ServerInstance->Log(DEBUG, "A module prevented the kill with result %d", MOD_RESULT);
			return;
		}

		if (!IS_LOCAL(u))
		{
			// remote kill
			ServerInstance->WriteOpers("*** Remote kill by %s: %s!%s@%s (%s)", user->nick, u->nick, u->ident, u->host, parameters[1]);
			snprintf(killreason, MAXQUIT,"[%s] Killed (%s (%s))", ServerInstance->Config->ServerName, user->nick, parameters[1]);
			u->WriteCommonExcept("QUIT :%s", killreason);
			FOREACH_MOD(I_OnRemoteKill, OnRemoteKill(user, u, killreason));
			
			user_hash::iterator iter = ServerInstance->clientlist.find(u->nick);

			if (iter != ServerInstance->clientlist.end())
			{
				ServerInstance->Log(DEBUG,"deleting user hash value %d", iter->second);
				ServerInstance->clientlist.erase(iter);
			}

			if (u->registered == REG_ALL)
			{
				u->PurgeEmptyChannels();
			}

			DELETE(u);
		}
		else
		{
			// local kill
			ServerInstance->Log(DEFAULT,"LOCAL KILL: %s :%s!%s!%s (%s)", u->nick, ServerInstance->Config->ServerName, user->dhost, user->nick, parameters[1]);
			user->WriteTo(u, "KILL %s :%s!%s!%s (%s)", u->nick, ServerInstance->Config->ServerName, user->dhost, user->nick, parameters[1]);
			ServerInstance->WriteOpers("*** Local Kill by %s: %s!%s@%s (%s)", user->nick, u->nick, u->ident, u->host, parameters[1]);
			snprintf(killreason,MAXQUIT,"Killed (%s (%s))", user->nick, parameters[1]);
			userrec::QuitUser(ServerInstance, u, killreason);
		}
	}
	else
	{
		user->WriteServ( "401 %s %s :No such nick/channel", user->nick, parameters[0]);
	}
}
Example #27
0
		virtual void OnPostConnect(User* user)
		{
			if (!IS_LOCAL(user))
				return;

			for(std::vector<std::string>::iterator it = Joinchans.begin(); it != Joinchans.end(); it++)
				if (ServerInstance->IsChannel(it->c_str(), ServerInstance->Config->Limits.ChanMax))
					Channel::JoinUser(ServerInstance, user, it->c_str(), false, "", false, ServerInstance->Time());
		}
Example #28
0
static void BuildExcept(Membership* memb, CUList& excepts)
{
	const UserMembList* users = memb->chan->GetUsers();
	for(UserMembCIter i = users->begin(); i != users->end(); i++)
	{
		if (IS_LOCAL(i->first) && i->first->HasPrivPermission("invisible/see"))
			excepts.insert(i->first);
	}
}
Example #29
0
void ModuleSpanningTree::OnSetAway(userrec* user)
{
	if (IS_LOCAL(user))
	{
		std::deque<std::string> params;
		params.push_back(":"+std::string(user->awaymsg));
		Utils->DoOneToMany(user->nick,"AWAY",params);
	}
}
Example #30
0
// note: the protocol does not allow direct umode +o except
// via NICK with 8 params. sending OPERTYPE infers +o modechange
// locally.
void ModuleSpanningTree::OnOper(User* user, const std::string &opertype)
{
	if (IS_LOCAL(user))
	{
		std::deque<std::string> params;
		params.push_back(opertype);
		Utils->DoOneToMany(user->uuid,"OPERTYPE",params);
	}
}