Example #1
0
Extban *ExtbanAdd(Module *module, ExtbanInfo req)
{
int slot;
char tmpbuf[512];

	if (findmod_by_bantype(req.flag))
	{
		if (module)
			module->errorcode = MODERR_EXISTS;
		return NULL; 
	}

	/* TODO: perhaps some sanity checking on a-zA-Z0-9? */
	for (slot = 0; slot < EXTBANTABLESZ; slot++)
		if (ExtBan_Table[slot].flag == '\0')
			break;
	if (slot == EXTBANTABLESZ - 1)
	{
		if (module)
			module->errorcode = MODERR_NOSPACE;
		return NULL;
	}
	ExtBan_Table[slot].flag = req.flag;
	ExtBan_Table[slot].is_ok = req.is_ok;
	ExtBan_Table[slot].conv_param = req.conv_param;
	ExtBan_Table[slot].is_banned = req.is_banned;
	ExtBan_Table[slot].owner = module;
	ExtBan_Table[slot].options = req.options;
	if (module)
	{
		ModuleObject *banobj = MyMallocEx(sizeof(ModuleObject));
		banobj->object.extban = &ExtBan_Table[slot];
		banobj->type = MOBJ_EXTBAN;
		AddListItem(banobj, module->objects);
		module->errorcode = MODERR_NOERROR;
	}
	ExtBan_highest = slot;
	if (loop.ircd_booted)
	{
		make_extbanstr();
		ircsprintf(tmpbuf, "~,%s", extbanstr);
		IsupportSetValue(IsupportFind("EXTBAN"), tmpbuf);
	}
	return &ExtBan_Table[slot];
}
Example #2
0
/** General is_ok for n!u@h stuff that also deals with recursive extbans.
 */
int extban_is_ok_nuh_extban(aClient* sptr, aChannel* chptr, char* para, int checkt, int what, int what2)
{
	char *mask = (para + 3);
	Extban *p = NULL;
	int isok;
	static int extban_is_ok_recursion = 0;

	/* Mostly copied from clean_ban_mask - but note MyClient checks aren't needed here: extban->is_ok() according to m_mode isn't called for nonlocal. */
	if ((*mask == '~') && mask[1] && (mask[2] == ':'))
	{
		if (extban_is_ok_recursion)
			return 0; /* Fail: more than one stacked extban */

		/* We can be sure RESTRICT_EXTENDEDBANS is not *. Else this extended ban wouldn't be happening at all. */
		if (what == EXBCHK_PARAM && RESTRICT_EXTENDEDBANS && !IsAnOper(sptr))
		{
			if (strchr(RESTRICT_EXTENDEDBANS, mask[1]))
			{
				sendnotice(sptr, "Setting/removing of extended bantypes '%s' has been disabled.", RESTRICT_EXTENDEDBANS);
				return 0; /* Fail */
			}
		}
		p = findmod_by_bantype(mask[1]);
		if (!p)
		{
			if (what == MODE_DEL)
			{
				return 1; /* Always allow killing unknowns. */
			}
			return 0; /* Don't add unknown extbans. */
		}
		/* Now we have to ask the stacked extban if it's ok. */
		if (p->is_ok)
		{
			extban_is_ok_recursion++;
			isok = p->is_ok(sptr, chptr, mask, checkt, what, what2);
			extban_is_ok_recursion--;
			return isok;
		}
	}
	return 1; /* Either not an extban, or extban has NULL is_ok. Good to go. */
}
Example #3
0
/** ban_check_mask - Checks if the current user in ban checking (ban_ip, etc) matches the specified n!u@h mask -or- run an extended ban.
 * @param sptr         Client to check (can be remote client)
 * @param chptr        Channel to check
 * @param banstr       Mask string to check user
 * @param type         Type of ban to check for (BANCHK_*)
 * @param no_extbans   0 to check extbans, nonzero to disable extban checking.
 * @returns            Nonzero if the mask/extban succeeds. Zero if it doesn't.
 * @comments           This is basically extracting the mask and extban check from is_banned_with_nick, but with being a bit more strict in what an extban is.
 *                     Strange things could happen if this is called outside standard ban checking.
 */
inline int ban_check_mask(aClient *sptr, aChannel *chptr, char *banstr, int type, int no_extbans)
{
	Extban *extban = NULL;
	if (!no_extbans && banstr[0] == '~' && banstr[1] != '\0' && banstr[2] == ':')
	{
		/* Is an extended ban. */
		extban = findmod_by_bantype(banstr[1]);
		if (!extban)
		{
			return 0;
		}
		else
		{
			return extban->is_banned(sptr, chptr, banstr, type);
		}
	}
	else
	{
		/* Is a n!u@h mask. */
		return extban_is_banned_helper(banstr);
	}
}
Example #4
0
/** is_banned_with_nick - Check if a user is banned on a channel.
 * @param sptr   Client to check (can be remote client)
 * @param chptr  Channel to check
 * @param type   Type of ban to check for (BANCHK_*)
 * @param nick   Nick of the user
 * @returns      A pointer to the ban struct if banned, otherwise NULL.
 */
Ban *is_banned_with_nick(aClient *sptr, aChannel *chptr, int type, char *nick)
{
	Ban *tmp, *tmp2;
	char *s;
	static char realhost[NICKLEN + USERLEN + HOSTLEN + 24];
	static char cloakhost[NICKLEN + USERLEN + HOSTLEN + 24];
	static char virthost[NICKLEN + USERLEN + HOSTLEN + 24];
	static char     nuip[NICKLEN + USERLEN + HOSTLEN + 24];
	int dovirt = 0, mine = 0;
	Extban *extban;

	if (!IsPerson(sptr) || !chptr->banlist)
		return NULL;

	ban_realhost = realhost;
	ban_ip = ban_virthost = ban_cloakhost = NULL;
	
	if (MyConnect(sptr))
	{
		mine = 1;
		make_nick_user_host_r(nuip, nick, sptr->user->username, GetIP(sptr));
		ban_ip = nuip;
		make_nick_user_host_r(cloakhost, nick, sptr->user->username, sptr->user->cloakedhost);
		ban_cloakhost = cloakhost;
	}

	if (IsSetHost(sptr) && strcmp(sptr->user->realhost, sptr->user->virthost))
	{
		dovirt = 1;
		make_nick_user_host_r(virthost, nick, sptr->user->username, sptr->user->virthost);
		ban_virthost = virthost;
	}


	make_nick_user_host_r(realhost, nick, sptr->user->username, sptr->user->realhost);

/* We now check +b first, if a +b is found we then see if there is a +e.
 * If a +e was found we return NULL, if not, we return the ban.
 */
	for (tmp = chptr->banlist; tmp; tmp = tmp->next)
	{
		if (*tmp->banstr == '~')
		{
			extban = findmod_by_bantype(tmp->banstr[1]);
			if (!extban)
				continue;
			if (!extban->is_banned(sptr, chptr, tmp->banstr, type))
				continue;
		} else {
			if ((match(tmp->banstr, realhost) == 0) ||
			    (dovirt && (match(tmp->banstr, virthost) == 0)) ||
			    (mine && (match(tmp->banstr, nuip) == 0)) ||
			    (mine && (match(tmp->banstr, cloakhost) == 0)) )
			{
				/* matches.. do nothing */
			} else
				continue;
		}

		/* Ban found, now check for +e */
		for (tmp2 = chptr->exlist; tmp2; tmp2 = tmp2->next)
		{
			if (*tmp2->banstr == '~')
			{
				extban = findmod_by_bantype(tmp2->banstr[1]);
				if (!extban)
					continue;
				if (extban->is_banned(sptr, chptr, tmp2->banstr, type))
					return NULL;
			} else {
				if ((match(tmp2->banstr, realhost) == 0) ||
					(dovirt && (match(tmp2->banstr, virthost) == 0)) ||
					(mine && (match(tmp2->banstr, nuip) == 0)) ||
					(mine && (match(tmp2->banstr, cloakhost) == 0)) )
					return NULL;
			}
		}
		break; /* ban found and not on except */
	}

	return (tmp);
}
Example #5
0
/* clean_ban_mask:	makes a proper banmask
 * RETURNS: pointer to correct banmask or NULL in case of error
 * NOTES:
 * - A pointer is returned to a static buffer, which is overwritten
 *   on next clean_ban_mask or make_nick_user_host call.
 * - mask is fragged in some cases, this could be bad.
 */
char *clean_ban_mask(char *mask, int what, aClient *cptr)
{
	char *cp;
	char *user;
	char *host;
	Extban *p;

	cp = index(mask, ' ');
	if (cp)
		*cp = '\0';

	/* Strip any ':' at beginning coz that desynchs clients/banlists */
	for (; (*mask && (*mask == ':')); mask++);
	if (!*mask)
		return NULL;

	/* Extended ban? */
	if ((*mask == '~') && mask[1] && (mask[2] == ':'))
	{
		if (RESTRICT_EXTENDEDBANS && MyClient(cptr) && !IsAnOper(cptr))
		{
			if (!strcmp(RESTRICT_EXTENDEDBANS, "*"))
			{
				sendnotice(cptr, "Setting/removing of extended bans has been disabled");
				return NULL;
			}
			if (strchr(RESTRICT_EXTENDEDBANS, mask[1]))
			{
				sendnotice(cptr, "Setting/removing of extended bantypes '%s' has been disabled",
					RESTRICT_EXTENDEDBANS);
				return NULL;
			}
		}
		p = findmod_by_bantype(mask[1]);
		if (!p)
		{
			/* extended bantype not supported, what to do?
			 * Here are the rules:
			 * - if from a remote client/server: allow it (easy upgrading,
			 *   no desynch)
			 * - if from a local client trying to REMOVE the extban,
			 *   allow it too (so you don't get "unremovable" extbans).
			 */
			if (!MyClient(cptr) || (what == MODE_DEL))
				return mask; /* allow it */
			return NULL; /* reject */
		}
		if (p->conv_param)
			return p->conv_param(mask);
		/* else, do some basic sanity checks and cut it off at 80 bytes */
		if ((cp[1] != ':') || (cp[2] == '\0'))
		    return NULL; /* require a ":<char>" after extban type */
		if (strlen(mask) > 80)
			mask[80] = '\0';
		return mask;
	}

	if ((*mask == '~') && !strchr(mask, '@'))
		return NULL; /* not an extended ban and not a ~user@host ban either. */

	if ((user = index((cp = mask), '!')))
		*user++ = '\0';
	if ((host = rindex(user ? user : cp, '@')))
	{
		*host++ = '\0';

		if (!user)
			return make_nick_user_host(NULL, trim_str(cp,USERLEN), 
				trim_str(host,HOSTLEN));
	}
	else if (!user && index(cp, '.'))
		return make_nick_user_host(NULL, NULL, trim_str(cp,HOSTLEN));
	return make_nick_user_host(trim_str(cp,NICKLEN), trim_str(user,USERLEN), 
		trim_str(host,HOSTLEN));
}
Example #6
0
/** conv_param to deal with stacked extbans.
 */
char* extban_conv_param_nuh_or_extban(char* para)
{
#if (USERLEN + NICKLEN + HOSTLEN + 32) > 256
 #error "wtf?"
#endif
	static char retbuf[256];
	static char printbuf[256];
	char *mask;
	char tmpbuf[USERLEN + NICKLEN + HOSTLEN + 32];
	char bantype = para[1];
	char *ret = NULL;
	Extban *p = NULL;
	static int extban_recursion = 0;

	if (para[3] == '~' && para[4] && para[5] == ':')
	{
		/* We're dealing with a stacked extended ban.
		 * Rules:
		 * 1) You can only stack once, so: ~x:~y:something and not ~x:~y:~z...
		 * 2) The first item must be an action modifier, such as ~q/~n/~j
		 * 3) The second item may never be an action modifier, nor have the
		 *    EXTBOPT_NOSTACKCHILD flag set (for things like a textban).
		 */
		 
		/* Rule #1. Yes the recursion check is also in extban_is_ok_nuh_extban,
		 * but it's possible to get here without the is_ok() function ever
		 * being called (think: non-local client). And no, don't delete it
		 * there either. It needs to be in BOTH places. -- Syzop
		 */
		if (extban_recursion)
			return NULL;

		/* Rule #2 */
		p = findmod_by_bantype(para[1]);
		if (p && !(p->options & EXTBOPT_ACTMODIFIER))
		{
			/* Rule #2 violation */
			return NULL;
		}
		
		strncpyzt(tmpbuf, para, sizeof(tmpbuf));
		mask = tmpbuf + 3;
		/* Already did restrict-extended bans check. */
		p = findmod_by_bantype(mask[1]);
		if (!p)
		{
			/* Handling unknown bantypes in is_ok. Assume that it's ok here. */
			return para;
		}
		if ((p->options & EXTBOPT_ACTMODIFIER) || (p->options & EXTBOPT_NOSTACKCHILD))
		{
			/* Rule #3 violation */
			return NULL;
		}
		
		if (p->conv_param)
		{
			extban_recursion++;
			ret = p->conv_param(mask);
			extban_recursion--;
			if (ret)
			{
				/*
				 * If bans are stacked, then we have to use two buffers
				 * to prevent ircsprintf() from going into a loop.
				 */
				ircsprintf(printbuf, "~%c:%s", bantype, ret); /* Make sure our extban prefix sticks. */
				memcpy(retbuf, printbuf, sizeof(retbuf));
				return retbuf;
			}
			else
			{
				return NULL; /* Fail. */
			}
		}
		/* I honestly don't know what the deal is with the 80 char cap in clean_ban_mask is about. So I'm leaving it out here. -- aquanight */
		/* I don't know why it's 80, but I like a limit anyway. A ban of 500 characters can never be good... -- Syzop */
		if (strlen(para) > 80)
		{
			strlcpy(retbuf, para, 128);
			return retbuf;
		}
		return para;
	}
	else
	{
		return extban_conv_param_nuh(para);
	}
}