mirror of
https://github.com/unrealircd/unrealircd.git
synced 2026-07-06 23:43:13 +02:00
Chained extbans support.
This commit is contained in:
@@ -1669,3 +1669,22 @@ MOTDs
|
||||
- Removed class.h and minor references to aClass. Patched by WolfSage
|
||||
- Changed all references to 'class' to 'cclass' (connection class) - to
|
||||
avoid some keyword confusion and other wacky ideas
|
||||
- Added support for "chained" extbans. Put simply this allows extban combinations
|
||||
such as ~q:~c:#test to only silence users on #test, for example. This feature
|
||||
is enabled by default, but can be disabled during ./Config -advanced. Module
|
||||
support for this feature must note the following:
|
||||
- For is_ok function, the extban can either assign extban_is_ok_nuh_extban, which
|
||||
will deal checking a chained extban (including checking for restricted extbans),
|
||||
or it can call that function from its own is_ok routine. For the latter case,
|
||||
remember to pass only the mask part of your ban format (ie, don't just pass para as
|
||||
otherwise it'll just call your is_ok again).
|
||||
- For conv_param function, the extban can either assign extban_conv_param_nuh_or_extban,
|
||||
which will automatically call conv_param for a chained extban, or pretty up a n!u@h mask.
|
||||
- For is_banned, the extban should call ban_check_mask with the mask part of the parameter.
|
||||
This will automatically call is_banned for a stacked extban, or match against a n!u@h. n!u@h
|
||||
is checked against the current user (ie, with the info in the globals ban_ip, etc), so things
|
||||
can get weird if you call this outside a normal ban check.
|
||||
Modules must keep in mind that chained extban support is not available (and neither are the three
|
||||
functions above) if DISABLE_STACKED_EXTBANS is #defined (this is controled by Config). Modules will
|
||||
not compile/load if they try to use them anyway.
|
||||
This change should not break extban modules, and should need some more extensive testing.
|
||||
|
||||
@@ -41,6 +41,9 @@ fi
|
||||
if [ "$OPEROVERRIDEVERIFY" = "1" ] ; then
|
||||
ARG="$ARG--with-operoverride-verify "
|
||||
fi
|
||||
if [ "$DISABLEEXTBANSTACKING" = "1" ]; then
|
||||
ARG="$ARG--with-disable-extendedban-stacking ";
|
||||
fi
|
||||
fi
|
||||
if [ "$NOSPOOF" = "1" ] ; then
|
||||
ARG="$ARG--enable-nospoof "
|
||||
@@ -274,6 +277,35 @@ while [ -z "$TEST" ] ; do
|
||||
esac
|
||||
done
|
||||
|
||||
TEST=""
|
||||
while [ -z "$TEST" ] ; do
|
||||
if [ "$DISABLEEXTBANSTACKING" = "1" ] ; then
|
||||
TEST="Yes"
|
||||
else
|
||||
TEST="No"
|
||||
fi
|
||||
echo ""
|
||||
echo "Do you want to disable extended ban stacking (~q:~c:#test, etc) support?"
|
||||
echo $n "[$TEST] -> $c"
|
||||
read cc
|
||||
if [ -z "$cc" ] ; then
|
||||
cc=$TEST
|
||||
fi
|
||||
case "$cc" in
|
||||
[Yy]*)
|
||||
DISABLEEXTBANSTACKING="1"
|
||||
;;
|
||||
[Nn]*)
|
||||
DISABLEEXTBANSTACKING="0"
|
||||
;;
|
||||
*)
|
||||
echo ""
|
||||
echo "You must enter either Yes or No"
|
||||
TEST=""
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
}
|
||||
c=""
|
||||
n=""
|
||||
@@ -302,6 +334,7 @@ SHUNNOTICES=""
|
||||
NOOPEROVERRIDE=""
|
||||
DISABLEUSERMOD=""
|
||||
OPEROVERRIDEVERIFY=""
|
||||
DISABLEEXTBANSTACKING=""
|
||||
EXTRAPARA=""
|
||||
if [ "`eval echo -n 'a'`" = "-n a" ] ; then
|
||||
c="\c"
|
||||
@@ -838,6 +871,7 @@ SHUNNOTICES="$SHUNNOTICES"
|
||||
NOOPEROVERRIDE="$NOOPEROVERRIDE"
|
||||
DISABLEUSERMOD="$DISABLEUSERMOD"
|
||||
OPEROVERRIDEVERIFY="$OPEROVERRIDEVERIFY"
|
||||
DISABLEEXTBANSTACKING="$DISABLEEXTBANSTACKING"
|
||||
EXTRAPARA="$EXTRAPARA"
|
||||
ADVANCED="$ADVANCED"
|
||||
__EOF__
|
||||
|
||||
@@ -874,6 +874,8 @@ Optional Packages:
|
||||
--with-disableusermod Disable /set* and /chg*
|
||||
--with-operoverride-verify
|
||||
Require opers to invite themselves to +s/+p channels
|
||||
--with-disable-extendedban-stacking
|
||||
Disable extended ban stacking (~q:~c:#chan) support
|
||||
|
||||
Some influential environment variables:
|
||||
CC C compiler command
|
||||
@@ -12025,6 +12027,15 @@ _ACEOF
|
||||
|
||||
fi;
|
||||
|
||||
# Check whether --with-disable-extendedban-stacking or --without-disable-extendedban-stacking was given.
|
||||
if test "${with_disable_extendedban_stacking+set}" = set; then
|
||||
withval="$with_disable_extendedban_stacking"
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define DISABLE_STACKED_EXTBANS 1
|
||||
_ACEOF
|
||||
|
||||
fi;
|
||||
|
||||
# Check whether --enable-ssl or --disable-ssl was given.
|
||||
if test "${enable_ssl+set}" = set; then
|
||||
enableval="$enable_ssl"
|
||||
|
||||
@@ -186,6 +186,11 @@ extern long get_access(aClient *, aChannel *);
|
||||
extern int is_chan_op(aClient *, aChannel *);
|
||||
extern int has_voice(aClient *, aChannel *);
|
||||
extern int is_chanowner(aClient *, aChannel *);
|
||||
#ifndef DISABLE_EXTBAN_STACKING
|
||||
extern int ban_check_mask(aClient *, aChannel *, char *, int, int);
|
||||
extern int extban_is_ok_nuh_extban(aClient *, aChannel *, char *, int, int, int);
|
||||
extern char* extban_conv_param_nuh_extban(char *);
|
||||
#endif
|
||||
extern Ban *is_banned(aClient *, aChannel *, int);
|
||||
extern Ban *is_banned_with_nick(aClient *, aChannel *, int, char *);
|
||||
extern int parse_help(aClient *, char *, char *);
|
||||
|
||||
@@ -240,6 +240,9 @@
|
||||
/* Define if you want to disable /set* and /chg* */
|
||||
#undef DISABLE_USERMOD
|
||||
|
||||
/* Define to disable extended ban stacking (~q:~c:#chan, etc) */
|
||||
#undef DISABLE_STACKED_EXTBANS
|
||||
|
||||
/* Define if your system prepends an underscore to symbols */
|
||||
#undef UNDERSCORE
|
||||
|
||||
|
||||
+52
-1
@@ -447,6 +447,46 @@ inline Ban *is_banned(aClient *sptr, aChannel *chptr, int type)
|
||||
return is_banned_with_nick(sptr, chptr, type, sptr->name);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_STACKED_EXTBANS
|
||||
/** 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 (
|
||||
(match(banstr, ban_realhost) == 0) || /* nick!user@realhost */
|
||||
(!BadPtr(ban_virthost) && (match(banstr, ban_virthost) == 0)) || /* nick!user@virthost - if he's been sethost/chghost/vhost */
|
||||
(!BadPtr(ban_ip) && (match(banstr, ban_ip) == 0)) || /* nick!user@IP (1.2.3.4, 1234:5678::90AB:CDEF, ::ffff:1.2.3.4, etc) */
|
||||
(!BadPtr(ban_cloakhost) && (match(banstr, ban_cloakhost) == 0)) /* nick!user@cloakhost - if +x */
|
||||
);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/** 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
|
||||
@@ -470,7 +510,8 @@ Ban *is_banned_with_nick(aClient *sptr, aChannel *chptr, int type, char *nick)
|
||||
|
||||
ban_realhost = realhost;
|
||||
ban_ip = ban_virthost = ban_cloakhost = NULL;
|
||||
|
||||
|
||||
/* Might it be possible in the future to include the possiblity for SupportNICKIP(sptr->from), SupportCLK(sptr->from)? -- aquanight */
|
||||
if (MyConnect(sptr))
|
||||
{
|
||||
mine = 1;
|
||||
@@ -495,6 +536,7 @@ Ban *is_banned_with_nick(aClient *sptr, aChannel *chptr, int type, char *nick)
|
||||
*/
|
||||
for (tmp = chptr->banlist; tmp; tmp = tmp->next)
|
||||
{
|
||||
#ifdef DISABLE_STACKED_EXTBANS
|
||||
if (*tmp->banstr == '~')
|
||||
{
|
||||
extban = findmod_by_bantype(tmp->banstr[1]);
|
||||
@@ -512,10 +554,15 @@ Ban *is_banned_with_nick(aClient *sptr, aChannel *chptr, int type, char *nick)
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
if (!ban_check_mask(sptr, chptr, tmp->banstr, type, 0))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
/* Ban found, now check for +e */
|
||||
for (tmp2 = chptr->exlist; tmp2; tmp2 = tmp2->next)
|
||||
{
|
||||
#ifdef DISABLE_STACKED_EXTBANS
|
||||
if (*tmp2->banstr == '~')
|
||||
{
|
||||
extban = findmod_by_bantype(tmp2->banstr[1]);
|
||||
@@ -530,6 +577,10 @@ Ban *is_banned_with_nick(aClient *sptr, aChannel *chptr, int type, char *nick)
|
||||
(mine && (match(tmp2->banstr, cloakhost) == 0)) )
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
if (!ban_check_mask(sptr, chptr, tmp2->banstr, type, 0))
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
break; /* ban found and not on except */
|
||||
}
|
||||
|
||||
+112
-1
@@ -251,7 +251,11 @@ char *ban = banin + 3;
|
||||
if (type != BANCHK_MSG)
|
||||
return 0;
|
||||
|
||||
#ifdef DISABLE_STACKED_EXTBANS
|
||||
return extban_is_banned_helper(ban);
|
||||
#else
|
||||
return ban_check_mask(sptr, chptr, ban, type, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
int extban_moden_is_banned(aClient *sptr, aChannel *chptr, char *banin, int type)
|
||||
@@ -263,8 +267,12 @@ char *ban = banin + 3;
|
||||
|
||||
if (has_voice(sptr, chptr))
|
||||
return 0;
|
||||
|
||||
|
||||
#ifdef DISABLE_STACKED_EXTBANS
|
||||
return extban_is_banned_helper(ban);
|
||||
#else
|
||||
return ban_check_mask(sptr, chptr, ban, type, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
int extban_modej_is_banned(aClient* sptr, aChannel* chptr, char* banin, int type)
|
||||
@@ -274,9 +282,52 @@ char* ban = banin + 3;
|
||||
if (type != BANCHK_JOIN)
|
||||
return 0;
|
||||
|
||||
#ifdef DISABLE_STACKED_EXTBANS
|
||||
return extban_is_banned_helper(ban);
|
||||
#else
|
||||
return ban_check_mask(sptr, chptr, ban, type, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef DISABLE_STACKED_EXTBANS
|
||||
/** 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;
|
||||
|
||||
/* 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] == ':'))
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
return p->is_ok(sptr, chptr, mask, checkt, what, what2);
|
||||
}
|
||||
}
|
||||
return 1; /* Either not an extban, or extban has NULL is_ok. Good to go. */
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Some kind of general conv_param routine,
|
||||
* to ensure the parameter is nick!user@host.
|
||||
* most of the code is just copied from clean_ban_mask.
|
||||
@@ -311,6 +362,51 @@ char pfix[8];
|
||||
return retbuf;
|
||||
}
|
||||
|
||||
#ifndef DISABLE_STACKED_EXTBANS
|
||||
/** conv_param to deal with stacked extbans.
|
||||
*/
|
||||
char* extban_conv_param_nuh_or_extban(char* para)
|
||||
{
|
||||
static char retbuf[USERLEN + NICKLEN + HOSTLEN + 32];
|
||||
char* mask;
|
||||
char tmpbuf[USERLEN + NICKLEN + HOSTLEN + 32];
|
||||
char bantype = para[1];
|
||||
char* ret = NULL;
|
||||
Extban* p = NULL;
|
||||
|
||||
if (para[3] == '~' && para[4] && para[5] == ':')
|
||||
{
|
||||
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->conv_param)
|
||||
{
|
||||
if (ret = p->conv_param(mask))
|
||||
{
|
||||
ircsprintf(retbuf, "~%c:%s", bantype, ret); /* Make sure our extban prefix sticks. */
|
||||
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. */
|
||||
return para;
|
||||
}
|
||||
else
|
||||
{
|
||||
return extban_conv_param_nuh(para);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Realname bans - conv_param */
|
||||
char *extban_moder_conv_param(char *para)
|
||||
{
|
||||
@@ -345,19 +441,34 @@ void extban_init(void)
|
||||
|
||||
memset(&req, 0, sizeof(ExtbanInfo));
|
||||
req.flag = 'q';
|
||||
#ifdef DISABLE_STACKED_EXTBANS
|
||||
req.conv_param = extban_conv_param_nuh;
|
||||
#else
|
||||
req.is_ok = extban_is_ok_nuh_extban;
|
||||
req.conv_param = extban_conv_param_nuh_or_extban;
|
||||
#endif
|
||||
req.is_banned = extban_modeq_is_banned;
|
||||
ExtbanAdd(NULL, req);
|
||||
|
||||
memset(&req, 0, sizeof(ExtbanInfo));
|
||||
req.flag = 'n';
|
||||
#ifdef DISABLE_STACKED_EXTBANS
|
||||
req.conv_param = extban_conv_param_nuh;
|
||||
#else
|
||||
req.is_ok = extban_is_ok_nuh_extban;
|
||||
req.conv_param = extban_conv_param_nuh_or_extban;
|
||||
#endif
|
||||
req.is_banned = extban_moden_is_banned;
|
||||
ExtbanAdd(NULL, req);
|
||||
|
||||
memset(&req, 0, sizeof(ExtbanInfo));
|
||||
req.flag = 'j';
|
||||
#ifdef DISABLE_STACKED_EXTBANS
|
||||
req.conv_param = extban_conv_param_nuh;
|
||||
#else
|
||||
req.is_ok = extban_is_ok_nuh_extban;
|
||||
req.conv_param = extban_conv_param_nuh_or_extban;
|
||||
#endif
|
||||
req.is_banned = extban_modej_is_banned;
|
||||
ExtbanAdd(NULL, req);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user