BAN: Reject bans with insufficient non-wildcard characters.

Such bans are not applied locally, but are propagated normally.
They can only be removed on a server that applies them.

Note that normally KLINE will not accept such bans.
This is mainly for services, differing min_wildcard and
ircd changes.
This commit is contained in:
Jilles Tjoelker 2010-03-06 01:45:41 +01:00
parent 20eef93004
commit 70fd7fc9fb
4 changed files with 103 additions and 63 deletions

View File

@ -370,6 +370,7 @@ extern void yyerror(const char *);
extern int conf_yy_fatal_error(const char *); extern int conf_yy_fatal_error(const char *);
extern int conf_fgets(char *, int, FILE *); extern int conf_fgets(char *, int, FILE *);
extern int valid_wild_card(const char *, const char *);
extern void add_temp_kline(struct ConfItem *); extern void add_temp_kline(struct ConfItem *);
extern void add_temp_dline(struct ConfItem *); extern void add_temp_dline(struct ConfItem *);
extern void report_temp_klines(struct Client *); extern void report_temp_klines(struct Client *);

View File

@ -35,6 +35,7 @@
#include "ircd.h" #include "ircd.h"
#include "match.h" #include "match.h"
#include "s_conf.h" #include "s_conf.h"
#include "s_newconf.h"
#include "msg.h" #include "msg.h"
#include "modules.h" #include "modules.h"
#include "hash.h" #include "hash.h"
@ -160,7 +161,31 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p
aconf->passwd = rb_strndup(parv[parc - 1], p - parv[parc - 1] + 1); aconf->passwd = rb_strndup(parv[parc - 1], p - parv[parc - 1] + 1);
aconf->spasswd = rb_strdup(p + 1); aconf->spasswd = rb_strdup(p + 1);
} }
if (act && hold != created) if (act && hold != created &&
!(ntype == CONF_KILL ?
valid_wild_card(aconf->user, aconf->host) :
valid_wild_card_simple(aconf->host)))
{
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Ignoring global %d min. %s from %s%s%s for [%s%s%s]: too few non-wildcard characters",
(hold - rb_current_time()) / 60,
stype,
IsServer(source_p) ? source_p->name : get_oper_name(source_p),
strcmp(parv[7], "*") ? " on behalf of " : "",
strcmp(parv[7], "*") ? parv[7] : "",
aconf->user ? aconf->user : "",
aconf->user ? "@" : "",
aconf->host);
if(IsPerson(source_p))
sendto_one_notice(source_p,
":Your %s [%s%s%s] has too few non-wildcard characters",
stype,
aconf->user ? aconf->user : "",
aconf->user ? "@" : "",
aconf->host);
/* Propagate it, but do not apply it locally. */
}
else if (act && hold != created)
{ {
/* Keep the notices in sync with modules/m_kline.c etc. */ /* Keep the notices in sync with modules/m_kline.c etc. */
sendto_realops_snomask(SNO_GENERAL, L_ALL, sendto_realops_snomask(SNO_GENERAL, L_ALL,

View File

@ -71,7 +71,6 @@ DECLARE_MODULE_AV1(kline, NULL, NULL, kline_clist, NULL, NULL, "$Revision$");
static int find_user_host(struct Client *source_p, const char *userhost, char *user, char *host); static int find_user_host(struct Client *source_p, const char *userhost, char *user, char *host);
static int valid_comment(struct Client *source_p, char *comment); static int valid_comment(struct Client *source_p, char *comment);
static int valid_user_host(struct Client *source_p, const char *user, const char *host); static int valid_user_host(struct Client *source_p, const char *user, const char *host);
static int valid_wild_card(struct Client *source_p, const char *user, const char *host);
static void handle_remote_kline(struct Client *source_p, int tkline_time, static void handle_remote_kline(struct Client *source_p, int tkline_time,
const char *user, const char *host, const char *reason); const char *user, const char *host, const char *reason);
@ -168,9 +167,18 @@ mo_kline(struct Client *client_p, struct Client *source_p, int parc, const char
"%lu %s %s :%s", tkline_time, user, host, reason); "%lu %s %s :%s", tkline_time, user, host, reason);
if(!valid_user_host(source_p, user, host) || if(!valid_user_host(source_p, user, host) ||
!valid_wild_card(source_p, user, host) || !valid_comment(source_p, reason)) !valid_comment(source_p, reason))
return 0; return 0;
if(!valid_wild_card(user, host))
{
sendto_one_notice(source_p,
":Please include at least %d non-wildcard "
"characters with the user@host",
ConfigFileEntry.min_nonwildcard);
return 0;
}
if(propagated && tkline_time == 0) if(propagated && tkline_time == 0)
{ {
sendto_one_notice(source_p, ":Cannot set a permanent global ban"); sendto_one_notice(source_p, ":Cannot set a permanent global ban");
@ -280,9 +288,18 @@ handle_remote_kline(struct Client *source_p, int tkline_time,
return; return;
if(!valid_user_host(source_p, user, host) || if(!valid_user_host(source_p, user, host) ||
!valid_wild_card(source_p, user, host) || !valid_comment(source_p, reason)) !valid_comment(source_p, reason))
return; return;
if(!valid_wild_card(user, host))
{
sendto_one_notice(source_p,
":Please include at least %d non-wildcard "
"characters with the user@host",
ConfigFileEntry.min_nonwildcard);
return 0;
}
if(already_placed_kline(source_p, user, host, tkline_time)) if(already_placed_kline(source_p, user, host, tkline_time))
return; return;
@ -695,65 +712,6 @@ valid_user_host(struct Client *source_p, const char *luser, const char *lhost)
return 1; return 1;
} }
/* valid_wild_card()
*
* input - user buffer, host buffer
* output - 0 if invalid, 1 if valid
* side effects -
*/
static int
valid_wild_card(struct Client *source_p, const char *luser, const char *lhost)
{
const char *p;
char tmpch;
int nonwild = 0;
int bitlen;
/* user has no wildcards, always accept -- jilles */
if(!strchr(luser, '?') && !strchr(luser, '*'))
return 1;
/* check there are enough non wildcard chars */
p = luser;
while((tmpch = *p++))
{
if(!IsKWildChar(tmpch))
{
/* found enough chars, return */
if(++nonwild >= ConfigFileEntry.min_nonwildcard)
return 1;
}
}
/* try host, as user didnt contain enough */
/* special case for cidr masks -- jilles */
if((p = strrchr(lhost, '/')) != NULL && IsDigit(p[1]))
{
bitlen = atoi(p + 1);
/* much like non-cidr for ipv6, rather arbitrary for ipv4 */
if(bitlen > 0
&& bitlen >=
(strchr(lhost, ':') ? 4 * (ConfigFileEntry.min_nonwildcard - nonwild) : 6 -
2 * nonwild))
return 1;
}
else
{
p = lhost;
while((tmpch = *p++))
{
if(!IsKWildChar(tmpch))
if(++nonwild >= ConfigFileEntry.min_nonwildcard)
return 1;
}
}
sendto_one_notice(source_p,
":Please include at least %d non-wildcard "
"characters with the user@host", ConfigFileEntry.min_nonwildcard);
return 0;
}
/* /*
* valid_comment * valid_comment
* inputs - pointer to client * inputs - pointer to client

View File

@ -1007,6 +1007,62 @@ add_temp_dline(struct ConfItem *aconf)
add_conf_by_address(aconf->host, CONF_DLINE, aconf->user, NULL, aconf); add_conf_by_address(aconf->host, CONF_DLINE, aconf->user, NULL, aconf);
} }
/* valid_wild_card()
*
* input - user buffer, host buffer
* output - 0 if invalid, 1 if valid
* side effects -
*/
int
valid_wild_card(const char *luser, const char *lhost)
{
const char *p;
char tmpch;
int nonwild = 0;
int bitlen;
/* user has no wildcards, always accept -- jilles */
if(!strchr(luser, '?') && !strchr(luser, '*'))
return 1;
/* check there are enough non wildcard chars */
p = luser;
while((tmpch = *p++))
{
if(!IsKWildChar(tmpch))
{
/* found enough chars, return */
if(++nonwild >= ConfigFileEntry.min_nonwildcard)
return 1;
}
}
/* try host, as user didnt contain enough */
/* special case for cidr masks -- jilles */
if((p = strrchr(lhost, '/')) != NULL && IsDigit(p[1]))
{
bitlen = atoi(p + 1);
/* much like non-cidr for ipv6, rather arbitrary for ipv4 */
if(bitlen > 0
&& bitlen >=
(strchr(lhost, ':') ? 4 * (ConfigFileEntry.min_nonwildcard - nonwild) : 6 -
2 * nonwild))
return 1;
}
else
{
p = lhost;
while((tmpch = *p++))
{
if(!IsKWildChar(tmpch))
if(++nonwild >= ConfigFileEntry.min_nonwildcard)
return 1;
}
}
return 0;
}
rb_dlink_node * rb_dlink_node *
find_prop_ban(unsigned int status, const char *user, const char *host) find_prop_ban(unsigned int status, const char *user, const char *host)
{ {