From 70fd7fc9fbd1e12a2f65fd29da84a0f19e9fabe7 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sat, 6 Mar 2010 01:45:41 +0100 Subject: [PATCH] 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. --- include/s_conf.h | 1 + modules/core/m_ban.c | 27 ++++++++++++++- modules/m_kline.c | 82 +++++++++++--------------------------------- src/s_conf.c | 56 ++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 63 deletions(-) diff --git a/include/s_conf.h b/include/s_conf.h index 6573e7b..a535d93 100644 --- a/include/s_conf.h +++ b/include/s_conf.h @@ -370,6 +370,7 @@ extern void yyerror(const char *); extern int conf_yy_fatal_error(const char *); 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_dline(struct ConfItem *); extern void report_temp_klines(struct Client *); diff --git a/modules/core/m_ban.c b/modules/core/m_ban.c index 8d4f269..f61ba07 100644 --- a/modules/core/m_ban.c +++ b/modules/core/m_ban.c @@ -35,6 +35,7 @@ #include "ircd.h" #include "match.h" #include "s_conf.h" +#include "s_newconf.h" #include "msg.h" #include "modules.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->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. */ sendto_realops_snomask(SNO_GENERAL, L_ALL, diff --git a/modules/m_kline.c b/modules/m_kline.c index c532c0a..46ff730 100644 --- a/modules/m_kline.c +++ b/modules/m_kline.c @@ -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 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_wild_card(struct Client *source_p, const char *user, const char *host); static void handle_remote_kline(struct Client *source_p, int tkline_time, 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); 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; + 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) { 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; 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; + 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)) return; @@ -695,65 +712,6 @@ valid_user_host(struct Client *source_p, const char *luser, const char *lhost) 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 * inputs - pointer to client diff --git a/src/s_conf.c b/src/s_conf.c index 55a9728..5775387 100644 --- a/src/s_conf.c +++ b/src/s_conf.c @@ -1007,6 +1007,62 @@ add_temp_dline(struct ConfItem *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 * find_prop_ban(unsigned int status, const char *user, const char *host) {