mirror of
https://github.com/unrealircd/unrealircd.git
synced 2026-07-09 22:23:13 +02:00
First go at multi actions...
This commit is contained in:
+1
-1
@@ -104,7 +104,7 @@ struct Configuration {
|
||||
char *channel_command_prefix;
|
||||
long handshake_data_flood_amount;
|
||||
long handshake_data_flood_ban_time;
|
||||
int handshake_data_flood_ban_action;
|
||||
BanAction *handshake_data_flood_ban_action;
|
||||
struct ChMode modes_on_join;
|
||||
int modes_on_join_set;
|
||||
char *level_on_join;
|
||||
|
||||
+18
-6
@@ -732,10 +732,22 @@ extern void ExtbanDel(Extban *);
|
||||
extern void extban_init(void);
|
||||
extern char *trim_str(char *str, int len);
|
||||
extern MODVAR char *ban_realhost, *ban_virthost, *ban_ip;
|
||||
extern BanAction banact_stringtoval(const char *s);
|
||||
extern const char *banact_valtostring(BanAction val);
|
||||
extern BanAction banact_chartoval(char c);
|
||||
extern char banact_valtochar(BanAction val);
|
||||
extern BanAction *parse_ban_action_config(ConfigEntry *ce);
|
||||
extern int test_ban_action_config(ConfigEntry *ce);
|
||||
extern void free_single_ban_action(BanAction *action);
|
||||
extern void free_all_ban_actions(BanAction *actions);
|
||||
#define safe_free_all_ban_actions(x) do { free_all_ban_actions(x); x = NULL; } while(0)
|
||||
#define safe_free_single_ban_action(x) do { free_single_ban_action(x); x = NULL; } while(0)
|
||||
BanAction *duplicate_ban_actions(BanAction *actions);
|
||||
extern BanActionValue banact_stringtoval(const char *s);
|
||||
extern const char *banact_valtostring(BanActionValue val);
|
||||
extern BanActionValue banact_chartoval(char c);
|
||||
extern char banact_valtochar(BanActionValue val);
|
||||
extern BanAction *banact_value_to_struct(BanActionValue val);
|
||||
extern int only_actions_of_type(BanAction *actions, BanActionValue what);
|
||||
extern int has_actions_of_type(BanAction *actions, BanActionValue what);
|
||||
extern int only_soft_actions(BanAction *actions);
|
||||
extern const char *ban_actions_to_string(BanAction *actions);
|
||||
extern int spamfilter_gettargets(const char *s, Client *client);
|
||||
extern char *spamfilter_target_inttostring(int v);
|
||||
extern char *our_strcasestr(const char *haystack, const char *needle);
|
||||
@@ -806,7 +818,7 @@ extern MODVAR TKL *(*tkl_add_banexception)(int type, const char *usermask, const
|
||||
time_t expire_at, time_t set_at, int soft, const char *bantypes, int flags);
|
||||
extern MODVAR TKL *(*tkl_add_nameban)(int type, const char *name, int hold, const char *reason, const char *setby,
|
||||
time_t expire_at, time_t set_at, int flags);
|
||||
extern MODVAR TKL *(*tkl_add_spamfilter)(int type, unsigned short target, unsigned short action, Match *match, const char *setby,
|
||||
extern MODVAR TKL *(*tkl_add_spamfilter)(int type, unsigned short target, BanAction *action, Match *match, const char *setby,
|
||||
time_t expire_at, time_t set_at,
|
||||
time_t spamf_tkl_duration, const char *spamf_tkl_reason,
|
||||
int flags);
|
||||
@@ -827,7 +839,7 @@ extern MODVAR TKL *(*find_tkline_match_zap)(Client *cptr);
|
||||
extern MODVAR void (*tkl_stats)(Client *cptr, int type, const char *para, int *cnt);
|
||||
extern MODVAR void (*tkl_sync)(Client *client);
|
||||
extern MODVAR void (*cmd_tkl)(Client *client, MessageTag *recv_mtags, int parc, const char *parv[]);
|
||||
extern MODVAR int (*place_host_ban)(Client *client, BanAction action, const char *reason, long duration);
|
||||
extern MODVAR int (*place_host_ban)(Client *client, BanAction *actions, const char *reason, long duration);
|
||||
extern MODVAR int (*match_spamfilter)(Client *client, const char *str_in, int type, const char *cmd, const char *target, int flags, TKL **rettk);
|
||||
extern MODVAR int (*match_spamfilter_mtags)(Client *client, MessageTag *mtags, const char *cmd);
|
||||
extern MODVAR int (*join_viruschan)(Client *client, TKL *tk, int type);
|
||||
|
||||
+2
-2
@@ -2099,12 +2099,12 @@ int hooktype_sasl_result(Client *client, int success);
|
||||
* This is called for automated bans such as spamfilter hits, flooding, etc.
|
||||
* This hook can be used to prevent the ban, or as used by the authprompt to delay it.
|
||||
* @param client The client that should be banned
|
||||
* @param action The TKL type, such as BAN_ACT_GLINE
|
||||
* @param action The actions to take, one of BAN_ACT_*
|
||||
* @param reason The ban reason
|
||||
* @param duration The duration of the ban, 0 for permanent ban
|
||||
* @return The magic value 99 is used to exempt the user (=do not ban!), otherwise the ban is added.
|
||||
*/
|
||||
int hooktype_place_host_ban(Client *client, int action, const char *reason, long duration);
|
||||
int hooktype_place_host_ban(Client *client, BanActionValue action, const char *reason, long duration);
|
||||
|
||||
/** Called when a TKL ban is hit by this user (function prototype for HOOKTYPE_FIND_TKLINE_MATCH).
|
||||
* This is called when an existing TKL entry is hit by the user.
|
||||
|
||||
+20
-5
@@ -1111,7 +1111,7 @@ struct Secret {
|
||||
#define SPAMFLAG_NOWARN 0x0001
|
||||
|
||||
/* Ban actions. These must be ordered by severity (!) */
|
||||
typedef enum BanAction {
|
||||
typedef enum BanActionValue {
|
||||
BAN_ACT_GZLINE =1100,
|
||||
BAN_ACT_GLINE =1000,
|
||||
BAN_ACT_SOFT_GLINE = 950,
|
||||
@@ -1132,7 +1132,22 @@ typedef enum BanAction {
|
||||
BAN_ACT_SOFT_BLOCK = 150,
|
||||
BAN_ACT_WARN = 100,
|
||||
BAN_ACT_SOFT_WARN = 50,
|
||||
} BanAction;
|
||||
BAN_ACT_SET = 40,
|
||||
} BanActionValue;
|
||||
|
||||
typedef enum VarActionValue {
|
||||
VAR_ACT_SET = 1,
|
||||
VAR_ACT_INCREASE = 2,
|
||||
} VarActionValue;
|
||||
|
||||
typedef struct BanAction BanAction;
|
||||
struct BanAction {
|
||||
BanAction *prev, *next;
|
||||
BanActionValue action;
|
||||
char *var;
|
||||
int value;
|
||||
VarActionValue var_action;
|
||||
};
|
||||
|
||||
#define IsSoftBanAction(x) ((x == BAN_ACT_SOFT_GLINE) || (x == BAN_ACT_SOFT_KLINE) || \
|
||||
(x == BAN_ACT_SOFT_SHUN) || (x == BAN_ACT_SOFT_KILL) || \
|
||||
@@ -1159,7 +1174,7 @@ struct NameBan {
|
||||
/** Spamfilter sub-struct of TKL entry (Spamfilter) */
|
||||
struct Spamfilter {
|
||||
unsigned short target;
|
||||
BanAction action; /**< Ban action, see BAN_ACT* */
|
||||
BanAction *action; /**< Ban action */
|
||||
Match *match; /**< Spamfilter matcher */
|
||||
char *tkl_reason; /**< Reason to use for bans placed by this spamfilter, escaped by unreal_encodespace(). */
|
||||
time_t tkl_duration; /**< Duration of bans placed by this spamfilter */
|
||||
@@ -1940,8 +1955,8 @@ struct ConfigItem_link {
|
||||
struct ConfigItem_ban {
|
||||
ConfigItem_ban *prev, *next;
|
||||
ConfigFlag_ban flag;
|
||||
char *mask, *reason;
|
||||
unsigned short action;
|
||||
char *mask, *reason;
|
||||
BanAction *action;
|
||||
};
|
||||
|
||||
struct ConfigItem_deny_dcc {
|
||||
|
||||
@@ -55,7 +55,7 @@ TKL *(*tkl_add_serverban)(int type, const char *usermask, const char *hostmask,
|
||||
time_t expire_at, time_t set_at, int soft, int flags);
|
||||
TKL *(*tkl_add_nameban)(int type, const char *name, int hold, const char *reason, const char *setby,
|
||||
time_t expire_at, time_t set_at, int flags);
|
||||
TKL *(*tkl_add_spamfilter)(int type, unsigned short target, unsigned short action, Match *match, const char *setby,
|
||||
TKL *(*tkl_add_spamfilter)(int type, unsigned short target, BanAction *action, Match *match, const char *setby,
|
||||
time_t expire_at, time_t set_at,
|
||||
time_t spamf_tkl_duration, const char *spamf_tkl_reason,
|
||||
int flags);
|
||||
@@ -72,7 +72,7 @@ TKL *(*find_tkline_match_zap)(Client *client);
|
||||
void (*tkl_stats)(Client *client, int type, const char *para, int *cnt);
|
||||
void (*tkl_sync)(Client *client);
|
||||
void (*cmd_tkl)(Client *client, MessageTag *mtags, int parc, const char *parv[]);
|
||||
int (*place_host_ban)(Client *client, BanAction action, const char *reason, long duration);
|
||||
int (*place_host_ban)(Client *client, BanAction *action, const char *reason, long duration);
|
||||
int (*match_spamfilter)(Client *client, const char *str_in, int type, const char *cmd, const char *target, int flags, TKL **rettk);
|
||||
int (*match_spamfilter_mtags)(Client *client, MessageTag *mtags, const char *cmd);
|
||||
int (*join_viruschan)(Client *client, TKL *tk, int type);
|
||||
|
||||
+10
-19
@@ -1648,6 +1648,7 @@ void free_iConf(Configuration *i)
|
||||
safe_free(i->helpchan);
|
||||
safe_free(i->stats_server);
|
||||
safe_free(i->sasl_server);
|
||||
safe_free_all_ban_actions(i->handshake_data_flood_ban_action);
|
||||
// anti-flood:
|
||||
for (f = i->floodsettings; f; f = f_next)
|
||||
{
|
||||
@@ -1710,7 +1711,8 @@ void config_setdefaultsettings(Configuration *i)
|
||||
/* - everyone */
|
||||
i->throttle_count = 3; i->throttle_period = 60; /* throttle protection: max 3 per 60s */
|
||||
i->handshake_data_flood_amount = 4096;
|
||||
i->handshake_data_flood_ban_action = BAN_ACT_ZLINE;
|
||||
i->handshake_data_flood_ban_action = safe_alloc(sizeof(BanAction));
|
||||
i->handshake_data_flood_ban_action->action = BAN_ACT_ZLINE;
|
||||
i->handshake_data_flood_ban_time = 600;
|
||||
// (targetflood is in the targetflood module)
|
||||
/* - known-users */
|
||||
@@ -2462,6 +2464,7 @@ void config_rehash()
|
||||
{
|
||||
safe_free(ban_ptr->mask);
|
||||
safe_free(ban_ptr->reason);
|
||||
free_all_ban_actions(ban_ptr->action);
|
||||
DelListItem(ban_ptr, conf_ban);
|
||||
safe_free(ban_ptr);
|
||||
}
|
||||
@@ -6901,7 +6904,7 @@ int _conf_ban(ConfigFile *conf, ConfigEntry *ce)
|
||||
else if (!strcmp(cep->name, "reason"))
|
||||
safe_strdup(ca->reason, cep->value);
|
||||
else if (!strcmp(cep->name, "action"))
|
||||
ca->action = banact_stringtoval(cep->value);
|
||||
ca->action = parse_ban_action_config(cep);
|
||||
}
|
||||
AddListItem(ca, conf_ban);
|
||||
return 0;
|
||||
@@ -7000,13 +7003,7 @@ int _test_ban(ConfigFile *conf, ConfigEntry *ce)
|
||||
cep->line_number, "ban::action");
|
||||
}
|
||||
has_action = 1;
|
||||
if (!banact_stringtoval(cep->value))
|
||||
{
|
||||
config_error("%s:%i: ban::action has unknown action type '%s'",
|
||||
cep->file->filename, cep->line_number,
|
||||
cep->value);
|
||||
errors++;
|
||||
}
|
||||
errors += test_ban_action_config(cep);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7800,8 +7797,8 @@ int _conf_set(ConfigFile *conf, ConfigEntry *ce)
|
||||
tempiConf.handshake_data_flood_amount = config_checkval(cep4->value, CFG_SIZE);
|
||||
else if (!strcmp(cep4->name, "ban-time"))
|
||||
tempiConf.handshake_data_flood_ban_time = config_checkval(cep4->value, CFG_TIME);
|
||||
else if (!strcmp(cep4->name, "ban-action"))
|
||||
tempiConf.handshake_data_flood_ban_action = banact_stringtoval(cep4->value);
|
||||
else if (!strcmp(cep4->name, "ban-action") || !strcmp(cep4->name, "action"))
|
||||
tempiConf.handshake_data_flood_ban_action = parse_ban_action_config(cep4);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(ceppp->name, "away-flood"))
|
||||
@@ -8718,16 +8715,10 @@ int _test_set(ConfigFile *conf, ConfigEntry *ce)
|
||||
errors++;
|
||||
}
|
||||
} else
|
||||
if (!strcmp(cep4->name, "ban-action"))
|
||||
if (!strcmp(cep4->name, "ban-action") || !strcmp(cep4->name, "action"))
|
||||
{
|
||||
CheckNull(cep4);
|
||||
if (!banact_stringtoval(cep4->value))
|
||||
{
|
||||
config_error("%s:%i: set::anti-flood::handshake-data-flood::ban-action has unknown action type '%s'",
|
||||
cep4->file->filename, cep4->line_number,
|
||||
cep4->value);
|
||||
errors++;
|
||||
}
|
||||
errors += test_ban_action_config(cep4);
|
||||
} else
|
||||
if (!strcmp(cep4->name, "ban-time"))
|
||||
{
|
||||
|
||||
+1
-1
@@ -571,7 +571,7 @@ void json_expand_tkl(json_t *root, const char *key, TKL *tkl, int detail)
|
||||
{
|
||||
json_object_set_new(j, "name", json_string_unreal(tkl->ptr.spamfilter->match->str));
|
||||
json_object_set_new(j, "match_type", json_string_unreal(unreal_match_method_valtostr(tkl->ptr.spamfilter->match->type)));
|
||||
json_object_set_new(j, "ban_action", json_string_unreal(banact_valtostring(tkl->ptr.spamfilter->action)));
|
||||
json_object_set_new(j, "ban_action", json_string_unreal(ban_actions_to_string(tkl->ptr.spamfilter->action)));
|
||||
json_object_set_new(j, "ban_duration", json_integer(tkl->ptr.spamfilter->tkl_duration));
|
||||
json_object_set_new(j, "ban_duration_string", json_string_unreal(pretty_time_val_r(buf, sizeof(buf), tkl->ptr.spamfilter->tkl_duration)));
|
||||
json_object_set_new(j, "spamfilter_targets", json_string_unreal(spamfilter_target_inttostring(tkl->ptr.spamfilter->target)));
|
||||
|
||||
+192
-4
@@ -79,6 +79,7 @@ static BanActTable banacttable[] = {
|
||||
{ BAN_ACT_SOFT_VIRUSCHAN,'V', "soft-viruschan" },
|
||||
{ BAN_ACT_WARN, 'w', "warn" },
|
||||
{ BAN_ACT_SOFT_WARN, 'W', "soft-warn" },
|
||||
{ BAN_ACT_SET, '1', "set" },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -781,8 +782,100 @@ int valid_vhost(const char *userhost)
|
||||
|
||||
/*|| BAN ACTION ROUTINES FOLLOW ||*/
|
||||
|
||||
int test_ban_action_config_helper(ConfigEntry *ce, const char *name, const char *value)
|
||||
{
|
||||
int errors = 0;
|
||||
BanActionValue action;
|
||||
|
||||
action = banact_stringtoval(name);
|
||||
if (!action)
|
||||
{
|
||||
config_error("%s:%d: unknown action: %s",
|
||||
ce->file->filename, ce->line_number, name);
|
||||
errors++;
|
||||
} else
|
||||
{
|
||||
// TODO: parse values
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
/** Test an action item in the config.
|
||||
* @param ce The config entry to parse
|
||||
* @returns Number of errors, so 0 means OK.
|
||||
*/
|
||||
int test_ban_action_config(ConfigEntry *ce)
|
||||
{
|
||||
ConfigEntry *cep;
|
||||
int errors = 0;
|
||||
|
||||
if (ce->items && !ce->value)
|
||||
{
|
||||
/* action { xxx; } */
|
||||
for (cep = ce->items; cep; cep = cep->next)
|
||||
errors += test_ban_action_config_helper(cep, cep->name, cep->value);
|
||||
} else
|
||||
if (!ce->value)
|
||||
{
|
||||
config_error("%s:%d: action has no value", ce->file->filename, ce->line_number);
|
||||
errors++;
|
||||
} else
|
||||
{
|
||||
/* action xxx; */
|
||||
errors += test_ban_action_config_helper(ce, ce->value, NULL);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
BanAction *parse_ban_action_config_helper(const char *name, const char *value)
|
||||
{
|
||||
int errors = 0;
|
||||
BanAction *action = safe_alloc(sizeof(BanAction));
|
||||
|
||||
action->action = banact_stringtoval(name);
|
||||
if (!action->action)
|
||||
abort(); /* impossible, is config tested earlier */
|
||||
|
||||
// TODO: parse values
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
/** Parse an action item in the config.
|
||||
* @param ce The config entry to parse
|
||||
* @returns BanAction item (can be more than one, in the linked list)
|
||||
*/
|
||||
BanAction *parse_ban_action_config(ConfigEntry *ce)
|
||||
{
|
||||
ConfigEntry *cep;
|
||||
BanAction *action_list = NULL;
|
||||
BanAction *action;
|
||||
|
||||
if (ce->items && !ce->value)
|
||||
{
|
||||
/* action { xxx; } */
|
||||
for (cep = ce->items; cep; cep = cep->next)
|
||||
{
|
||||
action = parse_ban_action_config_helper(cep->name, cep->value);
|
||||
if (action)
|
||||
AppendListItem(action, action_list);
|
||||
}
|
||||
} else
|
||||
if (ce->value)
|
||||
{
|
||||
/* action xxx; */
|
||||
action = parse_ban_action_config_helper(ce->value, NULL);
|
||||
if (action)
|
||||
AppendListItem(action, action_list);
|
||||
}
|
||||
|
||||
return action_list;
|
||||
}
|
||||
|
||||
/** Converts a banaction string (eg: "kill") to an integer value (eg: BAN_ACT_KILL) */
|
||||
BanAction banact_stringtoval(const char *s)
|
||||
BanActionValue banact_stringtoval(const char *s)
|
||||
{
|
||||
BanActTable *b;
|
||||
|
||||
@@ -793,7 +886,7 @@ BanAction banact_stringtoval(const char *s)
|
||||
}
|
||||
|
||||
/** Converts a banaction character (eg: 'K') to an integer value (eg: BAN_ACT_KILL) */
|
||||
BanAction banact_chartoval(char c)
|
||||
BanActionValue banact_chartoval(char c)
|
||||
{
|
||||
BanActTable *b;
|
||||
|
||||
@@ -804,7 +897,7 @@ BanAction banact_chartoval(char c)
|
||||
}
|
||||
|
||||
/** Converts a banaction value (eg: BAN_ACT_KILL) to a character value (eg: 'k') */
|
||||
char banact_valtochar(BanAction val)
|
||||
char banact_valtochar(BanActionValue val)
|
||||
{
|
||||
BanActTable *b;
|
||||
|
||||
@@ -815,7 +908,7 @@ char banact_valtochar(BanAction val)
|
||||
}
|
||||
|
||||
/** Converts a banaction value (eg: BAN_ACT_KLINE) to a string (eg: "kline") */
|
||||
const char *banact_valtostring(BanAction val)
|
||||
const char *banact_valtostring(BanActionValue val)
|
||||
{
|
||||
BanActTable *b;
|
||||
|
||||
@@ -825,6 +918,12 @@ const char *banact_valtostring(BanAction val)
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
BanAction *banact_value_to_struct(BanActionValue val)
|
||||
{
|
||||
BanAction *action = safe_alloc(sizeof(BanAction));
|
||||
action->action = val;
|
||||
return action;
|
||||
}
|
||||
/*|| BAN TARGET ROUTINES FOLLOW ||*/
|
||||
|
||||
/** Extract target flags from string 's'. */
|
||||
@@ -2729,3 +2828,92 @@ const char *command_issued_by_rpc(MessageTag *mtags)
|
||||
return m->value;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Check if action is only of type 'what', eg if they are all BAN_ACT_WARN */
|
||||
int only_actions_of_type(BanAction *actions, BanActionValue what)
|
||||
{
|
||||
for (; actions; actions = actions->next)
|
||||
if (actions->action != what)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Check if action 'what' is in any of 'actions' */
|
||||
int has_actions_of_type(BanAction *actions, BanActionValue what)
|
||||
{
|
||||
for (; actions; actions = actions->next)
|
||||
if (actions->action == what)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Check if only soft ban actions */
|
||||
int only_soft_actions(BanAction *actions)
|
||||
{
|
||||
for (; actions; actions = actions->next)
|
||||
if (!IsSoftBanAction(actions->action))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Turn a linked list BanAction * into a string of actions.
|
||||
* Returns something like "gline" or "set, gline"
|
||||
*/
|
||||
const char *ban_actions_to_string(BanAction *actions)
|
||||
{
|
||||
static char buf[512];
|
||||
const char *s;
|
||||
BanAction *action;
|
||||
*buf = '\0';
|
||||
|
||||
for (action = actions; action; action = action->next)
|
||||
{
|
||||
s = banact_valtostring(action->action);
|
||||
if (!s)
|
||||
s = "???";
|
||||
strlcat(buf, s, sizeof(buf));
|
||||
strlcat(buf, ", ", sizeof(buf));
|
||||
}
|
||||
|
||||
/* Cut off trailing ", " */
|
||||
if (*buf)
|
||||
buf[strlen(buf)-2] = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void free_single_ban_action(BanAction *action)
|
||||
{
|
||||
safe_free(action->var);
|
||||
safe_free(action);
|
||||
}
|
||||
|
||||
void free_all_ban_actions(BanAction *actions)
|
||||
{
|
||||
BanAction *next;
|
||||
for (; actions; actions = next)
|
||||
{
|
||||
next = actions->next;
|
||||
free_single_ban_action(actions);
|
||||
}
|
||||
}
|
||||
|
||||
/** Duplicate an entire BanAction linked list (deep copy) */
|
||||
BanAction *duplicate_ban_actions(BanAction *actions)
|
||||
{
|
||||
BanAction *newlist = NULL;
|
||||
BanAction *action, *n;
|
||||
|
||||
for (action = actions; action; action = action->next)
|
||||
{
|
||||
n = safe_alloc(sizeof(BanAction));
|
||||
// This matches the struct.h order:
|
||||
n->action = action->action;
|
||||
safe_strdup(n->var, action->var);
|
||||
n->value = action->value;
|
||||
n->var_action = action->var_action;
|
||||
/* And add to the list, maintain action ordering */
|
||||
AppendListItem(n, newlist);
|
||||
}
|
||||
return newlist;
|
||||
}
|
||||
|
||||
+16
-17
@@ -57,7 +57,7 @@ ModuleHeader MOD_HEADER
|
||||
|
||||
struct {
|
||||
int score;
|
||||
BanAction ban_action;
|
||||
BanAction *ban_action;
|
||||
char *ban_reason;
|
||||
long ban_time;
|
||||
SecurityGroup *except;
|
||||
@@ -685,24 +685,25 @@ CMD_OVERRIDE_FUNC(override_msg)
|
||||
score = lookalikespam_score(text, NULL, 0);
|
||||
if ((score >= cfg.score) && !find_tkl_exception(TKL_ANTIMIXEDUTF8, client))
|
||||
{
|
||||
/* Re-run with a log buffer... */
|
||||
char logbuf[512];
|
||||
int retval;
|
||||
|
||||
/* Re-run with a log buffer and log... */
|
||||
logbuf[0] = '\0';
|
||||
lookalikespam_score(text, logbuf, sizeof(logbuf));
|
||||
/* And log... */
|
||||
unreal_log(ULOG_INFO, "antimixedutf8", "ANTIMIXEDUTF8_HIT", client,
|
||||
"[antimixedutf8] Client $client.details hit score $score -- taking action. Mixed scripts detected: $scripts",
|
||||
log_data_integer("score", score),
|
||||
log_data_string("scripts", logbuf));
|
||||
if ((cfg.ban_action == BAN_ACT_BLOCK) ||
|
||||
((cfg.ban_action == BAN_ACT_SOFT_BLOCK) && !IsLoggedIn(client)))
|
||||
|
||||
/* Take the action */
|
||||
retval = place_host_ban(client, cfg.ban_action, cfg.ban_reason, cfg.ban_time);
|
||||
if (retval == 1)
|
||||
return;
|
||||
if (retval == BAN_ACT_BLOCK)
|
||||
{
|
||||
sendnotice(client, "%s", cfg.ban_reason);
|
||||
return;
|
||||
} else {
|
||||
if (place_host_ban(client, cfg.ban_action, cfg.ban_reason, cfg.ban_time))
|
||||
return;
|
||||
/* a return value of 0 means the user is exempted, so fallthrough.. */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -749,7 +750,7 @@ static void init_config(void)
|
||||
/* Default values */
|
||||
cfg.score = 10;
|
||||
safe_strdup(cfg.ban_reason, "Possible mixed character spam");
|
||||
cfg.ban_action = BAN_ACT_BLOCK;
|
||||
cfg.ban_action = banact_value_to_struct(BAN_ACT_BLOCK);
|
||||
cfg.ban_time = 60 * 60 * 4; /* irrelevant for block, but some default for others */
|
||||
}
|
||||
|
||||
@@ -757,6 +758,7 @@ static void free_config(void)
|
||||
{
|
||||
safe_free(cfg.ban_reason);
|
||||
free_security_group(cfg.except);
|
||||
safe_free_all_ban_actions(cfg.ban_action);
|
||||
memset(&cfg, 0, sizeof(cfg)); /* needed! */
|
||||
}
|
||||
|
||||
@@ -792,12 +794,7 @@ int antimixedutf8_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *er
|
||||
} else
|
||||
if (!strcmp(cep->name, "ban-action"))
|
||||
{
|
||||
if (!banact_stringtoval(cep->value))
|
||||
{
|
||||
config_error("%s:%i: set::antimixedutf8::ban-action: unknown action '%s'",
|
||||
cep->file->filename, cep->line_number, cep->value);
|
||||
errors++;
|
||||
}
|
||||
errors += test_ban_action_config(cep);
|
||||
} else
|
||||
if (!strcmp(cep->name, "ban-reason"))
|
||||
{
|
||||
@@ -838,7 +835,9 @@ int antimixedutf8_config_run(ConfigFile *cf, ConfigEntry *ce, int type)
|
||||
} else
|
||||
if (!strcmp(cep->name, "ban-action"))
|
||||
{
|
||||
cfg.ban_action = banact_stringtoval(cep->value);
|
||||
if (cfg.ban_action)
|
||||
safe_free_all_ban_actions(cfg.ban_action);
|
||||
cfg.ban_action = parse_ban_action_config(cep);
|
||||
} else
|
||||
if (!strcmp(cep->name, "ban-reason"))
|
||||
{
|
||||
|
||||
+11
-16
@@ -499,7 +499,7 @@ struct {
|
||||
|
||||
struct {
|
||||
int threshold;
|
||||
BanAction ban_action;
|
||||
BanAction *ban_action;
|
||||
char *ban_reason;
|
||||
long ban_time;
|
||||
int convert_to_lowercase;
|
||||
@@ -563,6 +563,7 @@ static void free_config(void)
|
||||
{
|
||||
safe_free(cfg.ban_reason);
|
||||
free_security_group(cfg.except);
|
||||
safe_free_all_ban_actions(cfg.ban_action);
|
||||
memset(&cfg, 0, sizeof(cfg)); /* needed! */
|
||||
}
|
||||
|
||||
@@ -612,13 +613,8 @@ int antirandom_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs)
|
||||
} else
|
||||
if (!strcmp(cep->name, "ban-action"))
|
||||
{
|
||||
if (!banact_stringtoval(cep->value))
|
||||
{
|
||||
config_error("%s:%i: set::antirandom::ban-action: unknown action '%s'",
|
||||
cep->file->filename, cep->line_number, cep->value);
|
||||
errors++;
|
||||
} else
|
||||
req.ban_action = 1;
|
||||
req.ban_action = 1;
|
||||
errors += test_ban_action_config(cep);
|
||||
} else
|
||||
if (!strcmp(cep->name, "ban-reason"))
|
||||
{
|
||||
@@ -678,7 +674,7 @@ int antirandom_config_run(ConfigFile *cf, ConfigEntry *ce, int type)
|
||||
} else
|
||||
if (!strcmp(cep->name, "ban-action"))
|
||||
{
|
||||
cfg.ban_action = banact_stringtoval(cep->value);
|
||||
cfg.ban_action = parse_ban_action_config(cep);
|
||||
} else
|
||||
if (!strcmp(cep->name, "ban-reason"))
|
||||
{
|
||||
@@ -870,21 +866,20 @@ int antirandom_preconnect(Client *client)
|
||||
score = get_spam_score(client);
|
||||
if (score > cfg.threshold)
|
||||
{
|
||||
if (cfg.ban_action == BAN_ACT_WARN)
|
||||
if (has_actions_of_type(cfg.ban_action, BAN_ACT_WARN))
|
||||
{
|
||||
unreal_log(ULOG_INFO, "antirandom", "ANTIRANDOM_DENIED_USER", client,
|
||||
"[antirandom] would have denied access to user with score $score: $client.details:$client.user.realname",
|
||||
log_data_integer("score", score));
|
||||
return HOOK_CONTINUE;
|
||||
}
|
||||
if (cfg.show_failedconnects)
|
||||
} else
|
||||
if (cfg.show_failedconnects) // FIXME: this is not entirely correct, with like soft actions or var setting, etc!
|
||||
{
|
||||
unreal_log(ULOG_INFO, "antirandom", "ANTIRANDOM_DENIED_USER", client,
|
||||
"[antirandom] denied access to user with score $score: $client.details:$client.user.realname",
|
||||
log_data_integer("score", score));
|
||||
}
|
||||
place_host_ban(client, cfg.ban_action, cfg.ban_reason, cfg.ban_time);
|
||||
return HOOK_DENY;
|
||||
if (place_host_ban(client, cfg.ban_action, cfg.ban_reason, cfg.ban_time))
|
||||
return HOOK_DENY;
|
||||
}
|
||||
return HOOK_CONTINUE;
|
||||
}
|
||||
@@ -911,7 +906,7 @@ static int is_exempt(Client *client)
|
||||
return 1;
|
||||
|
||||
/* Soft ban and logged in? */
|
||||
if (IsSoftBanAction(cfg.ban_action) && IsLoggedIn(client))
|
||||
if (only_soft_actions(cfg.ban_action) && IsLoggedIn(client))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
||||
+10
-17
@@ -64,7 +64,7 @@ struct Blacklist {
|
||||
char *name;
|
||||
BlacklistBackendType backend_type;
|
||||
BlacklistBackend *backend;
|
||||
int action;
|
||||
BanAction *action;
|
||||
long ban_time;
|
||||
char *reason;
|
||||
SecurityGroup *except;
|
||||
@@ -80,7 +80,7 @@ struct BLUser {
|
||||
int is_ipv6;
|
||||
int refcnt;
|
||||
/* The following save_* fields are used by softbans: */
|
||||
int save_action;
|
||||
BanAction *save_action;
|
||||
long save_tkltime;
|
||||
char *save_opernotice;
|
||||
char *save_reason;
|
||||
@@ -237,6 +237,7 @@ void delete_blacklist_block(Blacklist *e)
|
||||
|
||||
safe_free(e->name);
|
||||
safe_free(e->reason);
|
||||
safe_free_all_ban_actions(e->action);
|
||||
free_security_group(e->except);
|
||||
|
||||
safe_free(e);
|
||||
@@ -379,12 +380,7 @@ int blacklist_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs)
|
||||
continue;
|
||||
}
|
||||
has_action = 1;
|
||||
if (!banact_stringtoval(cep->value))
|
||||
{
|
||||
config_error("%s:%i: blacklist::action has unknown action type '%s'",
|
||||
cep->file->filename, cep->line_number, cep->value);
|
||||
errors++;
|
||||
}
|
||||
errors += test_ban_action_config(cep);
|
||||
}
|
||||
else if (!strcmp(cep->name, "ban-time"))
|
||||
{
|
||||
@@ -467,8 +463,6 @@ int blacklist_config_run(ConfigFile *cf, ConfigEntry *ce, int type)
|
||||
d = safe_alloc(sizeof(Blacklist));
|
||||
safe_strdup(d->name, ce->value);
|
||||
/* set some defaults */
|
||||
d->action = BAN_ACT_KILL;
|
||||
safe_strdup(d->reason, "Your IP is on a DNS Blacklist");
|
||||
d->ban_time = 3600;
|
||||
|
||||
/* assume dns for now ;) */
|
||||
@@ -529,7 +523,7 @@ int blacklist_config_run(ConfigFile *cf, ConfigEntry *ce, int type)
|
||||
}
|
||||
else if (!strcmp(cep->name, "action"))
|
||||
{
|
||||
d->action = banact_stringtoval(cep->value);
|
||||
d->action = parse_ban_action_config(cep);
|
||||
}
|
||||
else if (!strcmp(cep->name, "ban-time"))
|
||||
{
|
||||
@@ -692,6 +686,7 @@ void blacklist_free_bluser_if_able(BLUser *bl)
|
||||
|
||||
safe_free(bl->save_opernotice);
|
||||
safe_free(bl->save_reason);
|
||||
free_all_ban_actions(bl->save_action);
|
||||
safe_free(bl);
|
||||
}
|
||||
|
||||
@@ -747,7 +742,7 @@ int blacklist_parse_reply(struct hostent *he, int entry)
|
||||
* from blacklist_preconnect() for softbans that need to be delayed
|
||||
* as to give the user the opportunity to do SASL Authentication.
|
||||
*/
|
||||
int blacklist_action(Client *client, char *opernotice, BanAction ban_action, char *ban_reason, long ban_time,
|
||||
int blacklist_action(Client *client, char *opernotice, BanAction *ban_action, char *ban_reason, long ban_time,
|
||||
char *blacklist, char *blacklist_dns_name, int blacklist_dns_reply)
|
||||
{
|
||||
unreal_log_raw(ULOG_INFO, "blacklist", "BLACKLIST_HIT", client,
|
||||
@@ -755,11 +750,9 @@ int blacklist_action(Client *client, char *opernotice, BanAction ban_action, cha
|
||||
log_data_string("blacklist_name", blacklist),
|
||||
log_data_string("blacklist_dns_name", blacklist_dns_name),
|
||||
log_data_integer("blacklist_dns_reply", blacklist_dns_reply),
|
||||
log_data_string("ban_action", banact_valtostring(ban_action)),
|
||||
log_data_string("ban_action", ban_actions_to_string(ban_action)),
|
||||
log_data_string("ban_reason", ban_reason),
|
||||
log_data_integer("ban_time", ban_time));
|
||||
if (ban_action == BAN_ACT_WARN)
|
||||
return 0;
|
||||
return place_host_ban(client, ban_action, ban_reason, ban_time);
|
||||
}
|
||||
|
||||
@@ -797,10 +790,10 @@ void blacklist_hit(Client *client, Blacklist *bl, int reply)
|
||||
|
||||
buildvarstring(bl->reason, banbuf, sizeof(banbuf), name, value);
|
||||
|
||||
if (IsSoftBanAction(bl->action) && blu)
|
||||
if (only_soft_actions(bl->action) && blu)
|
||||
{
|
||||
/* For soft bans, delay the action until later (so user can do SASL auth) */
|
||||
blu->save_action = bl->action;
|
||||
blu->save_action = duplicate_ban_actions(bl->action);
|
||||
blu->save_tkltime = bl->ban_time;
|
||||
safe_strdup(blu->save_opernotice, opernotice);
|
||||
safe_strdup(blu->save_reason, banbuf);
|
||||
|
||||
@@ -616,14 +616,10 @@ int ban_version(Client *client, const char *text)
|
||||
|
||||
if ((ban = find_ban(NULL, ctcp_reply, CONF_BAN_VERSION)))
|
||||
{
|
||||
if (IsSoftBanAction(ban->action) && IsLoggedIn(client))
|
||||
return 0; /* soft ban does not apply to us, we are logged in */
|
||||
|
||||
if (find_tkl_exception(TKL_BAN_VERSION, client))
|
||||
return 0; /* we are exempt */
|
||||
|
||||
place_host_ban(client, ban->action, ban->reason, BAN_VERSION_TKL_TIME);
|
||||
return 1;
|
||||
return place_host_ban(client, ban->action, ban->reason, BAN_VERSION_TKL_TIME);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
+3
-2
@@ -1051,8 +1051,9 @@ int _register_user(Client *client)
|
||||
spamfilter_build_user_string(spamfilter_user, client->name, client);
|
||||
if (match_spamfilter(client, spamfilter_user, SPAMF_USER, NULL, NULL, 0, &savetkl))
|
||||
{
|
||||
if (savetkl && ((savetkl->ptr.spamfilter->action == BAN_ACT_VIRUSCHAN) ||
|
||||
(savetkl->ptr.spamfilter->action == BAN_ACT_SOFT_VIRUSCHAN)))
|
||||
if (savetkl &&
|
||||
(has_actions_of_type(savetkl->ptr.spamfilter->action, BAN_ACT_VIRUSCHAN) ||
|
||||
has_actions_of_type(savetkl->ptr.spamfilter->action, BAN_ACT_SOFT_VIRUSCHAN)))
|
||||
{
|
||||
/* 'viruschan' action:
|
||||
* Continue with registering the client, and at the end
|
||||
|
||||
@@ -100,9 +100,10 @@ RPC_CALL_FUNC(rpc_spamfilter_list)
|
||||
|
||||
/* Shared code for selecting a spamfilter, for .add/.del/get */
|
||||
int spamfilter_select_criteria(Client *client, json_t *request, json_t *params, const char **name, int *match_type,
|
||||
int *targets, char *targetbuf, size_t targetbuflen, BanAction *action, char *actionbuf)
|
||||
int *targets, char *targetbuf, size_t targetbuflen, BanActionValue *action, char *actionbuf)
|
||||
{
|
||||
const char *str;
|
||||
int actval;
|
||||
|
||||
*name = json_object_get_string(params, "name");
|
||||
if (!*name)
|
||||
@@ -161,7 +162,7 @@ RPC_CALL_FUNC(rpc_spamfilter_get)
|
||||
int type = TKL_SPAMF|TKL_GLOBAL;
|
||||
const char *name;
|
||||
TKL *tkl;
|
||||
BanAction action;
|
||||
BanActionValue action;
|
||||
int match_type = 0;
|
||||
int targets = 0;
|
||||
char targetbuf[64];
|
||||
@@ -193,7 +194,7 @@ RPC_CALL_FUNC(rpc_spamfilter_add)
|
||||
time_t ban_duration = 0;
|
||||
TKL *tkl;
|
||||
Match *m;
|
||||
BanAction action;
|
||||
BanActionValue action;
|
||||
int match_type = 0;
|
||||
int targets = 0;
|
||||
char targetbuf[64];
|
||||
@@ -246,7 +247,7 @@ RPC_CALL_FUNC(rpc_spamfilter_add)
|
||||
return;
|
||||
}
|
||||
|
||||
tkl = tkl_add_spamfilter(type, targets, action, m, set_by, 0, TStime(),
|
||||
tkl = tkl_add_spamfilter(type, targets, banact_value_to_struct(action), m, set_by, 0, TStime(),
|
||||
ban_duration, reason, 0);
|
||||
|
||||
if (!tkl)
|
||||
@@ -270,7 +271,7 @@ RPC_CALL_FUNC(rpc_spamfilter_del)
|
||||
const char *name;
|
||||
const char *set_by;
|
||||
TKL *tkl;
|
||||
BanAction action;
|
||||
BanActionValue action;
|
||||
int match_type = 0;
|
||||
int targets = 0;
|
||||
char targetbuf[64];
|
||||
|
||||
+1
-1
@@ -868,7 +868,7 @@ int stats_set(Client *client, const char *para)
|
||||
sendtxtnumeric(client, "link::bind-ip: %s", LINK_BINDIP);
|
||||
sendtxtnumeric(client, "anti-flood::connect-flood: %d per %s", THROTTLING_COUNT, pretty_time_val(THROTTLING_PERIOD));
|
||||
sendtxtnumeric(client, "anti-flood::handshake-data-flood::amount: %ld bytes", iConf.handshake_data_flood_amount);
|
||||
sendtxtnumeric(client, "anti-flood::handshake-data-flood::ban-action: %s", banact_valtostring(iConf.handshake_data_flood_ban_action));
|
||||
sendtxtnumeric(client, "anti-flood::handshake-data-flood::ban-action: %s", banact_valtostring(iConf.handshake_data_flood_ban_action->action));
|
||||
sendtxtnumeric(client, "anti-flood::handshake-data-flood::ban-time: %s", pretty_time_val(iConf.handshake_data_flood_ban_time));
|
||||
|
||||
/* set::anti-flood */
|
||||
|
||||
+149
-126
@@ -68,7 +68,7 @@ TKL *_tkl_add_banexception(int type, char *usermask, char *hostmask, SecurityGro
|
||||
time_t expire_at, time_t set_at, int soft, char *bantypes, int flags);
|
||||
TKL *_tkl_add_nameban(int type, char *name, int hold, char *reason, char *set_by,
|
||||
time_t expire_at, time_t set_at, int flags);
|
||||
TKL *_tkl_add_spamfilter(int type, unsigned short target, BanAction action, Match *match, char *set_by,
|
||||
TKL *_tkl_add_spamfilter(int type, unsigned short target, BanAction *action, Match *match, char *set_by,
|
||||
time_t expire_at, time_t set_at,
|
||||
time_t spamf_tkl_duration, char *spamf_tkl_reason,
|
||||
int flags);
|
||||
@@ -88,7 +88,7 @@ TKL *_find_tkline_match_zap(Client *client);
|
||||
void _tkl_stats(Client *client, int type, const char *para, int *cnt);
|
||||
void _tkl_sync(Client *client);
|
||||
CMD_FUNC(_cmd_tkl);
|
||||
int _place_host_ban(Client *client, BanAction action, char *reason, long duration);
|
||||
int _place_host_ban(Client *client, BanAction *action, char *reason, long duration);
|
||||
int _match_spamfilter(Client *client, const char *str_in, int type, const char *cmd, const char *target, int flags, TKL **rettk);
|
||||
int _match_spamfilter_mtags(Client *client, MessageTag *mtags, char *cmd);
|
||||
int check_mtag_spamfilters_present(void);
|
||||
@@ -97,13 +97,13 @@ void _spamfilter_build_user_string(char *buf, char *nick, Client *client);
|
||||
int _match_user(const char *rmask, Client *client, int options);
|
||||
int _unreal_match_iplist(Client *client, NameList *l);
|
||||
int _match_user_extended_server_ban(const char *banstr, Client *client);
|
||||
void ban_target_to_tkl_layer(BanTarget ban_target, BanAction action, Client *client, const char **tkl_username, const char **tkl_hostname);
|
||||
void ban_target_to_tkl_layer(BanTarget ban_target, BanActionValue action, Client *client, const char **tkl_username, const char **tkl_hostname);
|
||||
int _tkl_ip_hash(char *ip);
|
||||
int _tkl_ip_hash_type(int type);
|
||||
TKL *_find_tkl_serverban(int type, char *usermask, char *hostmask, int softban);
|
||||
TKL *_find_tkl_banexception(int type, char *usermask, char *hostmask, int softban);
|
||||
TKL *_find_tkl_nameban(int type, char *name, int hold);
|
||||
TKL *_find_tkl_spamfilter(int type, char *match_string, BanAction action, unsigned short target);
|
||||
TKL *_find_tkl_spamfilter(int type, char *match_string, BanActionValue action, unsigned short target);
|
||||
int _find_tkl_exception(int ban_type, Client *client);
|
||||
int _server_ban_parse_mask(Client *client, int add, char type, const char *str, char **usermask_out, char **hostmask_out, int *soft, const char **error);
|
||||
int _server_ban_exception_parse_mask(Client *client, int add, const char *bantypes, const char *str, char **usermask_out, char **hostmask_out, int *soft, const char **error);
|
||||
@@ -317,14 +317,25 @@ int tkl_config_test_spamfilter(ConfigFile *cf, ConfigEntry *ce, int type, int *e
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!cep->value)
|
||||
else if (!strcmp(cep->name, "action"))
|
||||
{
|
||||
if (has_action)
|
||||
{
|
||||
config_warn_duplicate(cep->file->filename,
|
||||
cep->line_number, "spamfilter::action");
|
||||
continue;
|
||||
}
|
||||
has_action = 1;
|
||||
errors += test_ban_action_config(cep);
|
||||
}
|
||||
else if (!cep->value)
|
||||
{
|
||||
config_error_empty(cep->file->filename, cep->line_number,
|
||||
"spamfilter", cep->name);
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(cep->name, "reason"))
|
||||
else if (!strcmp(cep->name, "reason"))
|
||||
{
|
||||
if (has_reason)
|
||||
{
|
||||
@@ -346,22 +357,6 @@ int tkl_config_test_spamfilter(ConfigFile *cf, ConfigEntry *ce, int type, int *e
|
||||
has_match = 1;
|
||||
match = cep->value;
|
||||
}
|
||||
else if (!strcmp(cep->name, "action"))
|
||||
{
|
||||
if (has_action)
|
||||
{
|
||||
config_warn_duplicate(cep->file->filename,
|
||||
cep->line_number, "spamfilter::action");
|
||||
continue;
|
||||
}
|
||||
has_action = 1;
|
||||
if (!banact_stringtoval(cep->value))
|
||||
{
|
||||
config_error("%s:%i: spamfilter::action has unknown action type '%s'",
|
||||
cep->file->filename, cep->line_number, cep->value);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(cep->name, "ban-time"))
|
||||
{
|
||||
if (has_bantime)
|
||||
@@ -482,7 +477,8 @@ int tkl_config_run_spamfilter(ConfigFile *cf, ConfigEntry *ce, int type)
|
||||
char *word = NULL;
|
||||
time_t bantime = tempiConf.spamfilter_ban_time;
|
||||
char *banreason = tempiConf.spamfilter_ban_reason;
|
||||
int action = 0, target = 0;
|
||||
BanAction *action;
|
||||
int target = 0;
|
||||
int match_type = 0;
|
||||
Match *m;
|
||||
|
||||
@@ -508,7 +504,7 @@ int tkl_config_run_spamfilter(ConfigFile *cf, ConfigEntry *ce, int type)
|
||||
}
|
||||
else if (!strcmp(cep->name, "action"))
|
||||
{
|
||||
action = banact_stringtoval(cep->value);
|
||||
action = parse_ban_action_config(cep);
|
||||
}
|
||||
else if (!strcmp(cep->name, "reason"))
|
||||
{
|
||||
@@ -1556,7 +1552,7 @@ int _server_ban_parse_mask(Client *client, int add, char type, const char *str,
|
||||
Client *acptr;
|
||||
if ((acptr = find_user(mask, NULL)))
|
||||
{
|
||||
BanAction action = BAN_ACT_KLINE; // just a dummy default
|
||||
BanActionValue action = BAN_ACT_KLINE; // just a dummy default
|
||||
if ((type == 'z') || (type == 'Z'))
|
||||
action = BAN_ACT_ZLINE; // to indicate zline (no hostname, no dns, etc)
|
||||
ban_target_to_tkl_layer(iConf.manual_ban_target, action, acptr, (const char **)&usermask, (const char **)&hostmask);
|
||||
@@ -1897,7 +1893,7 @@ int _server_ban_exception_parse_mask(Client *client, int add, const char *bantyp
|
||||
Client *acptr;
|
||||
if ((acptr = find_user(mask, NULL)))
|
||||
{
|
||||
BanAction action = BAN_ACT_KLINE; // just a dummy default
|
||||
BanActionValue action = BAN_ACT_KLINE; // just a dummy default
|
||||
if (add && eline_type_requires_ip(bantypes))
|
||||
action = BAN_ACT_ZLINE; // to indicate zline (no hostname, no dns, etc)
|
||||
ban_target_to_tkl_layer(iConf.manual_ban_target, action, acptr, (const char **)&usermask, (const char **)&hostmask);
|
||||
@@ -2115,7 +2111,7 @@ void spamfilter_del_by_id(Client *client, const char *id)
|
||||
/* Spamfilter found. Now fill the tkllayer */
|
||||
tkllayer[1] = "-";
|
||||
tkllayer[3] = spamfilter_target_inttostring(tk->ptr.spamfilter->target); /* target(s) */
|
||||
mo[0] = banact_valtochar(tk->ptr.spamfilter->action);
|
||||
mo[0] = banact_valtochar(tk->ptr.spamfilter->action->action);
|
||||
mo[1] = '\0';
|
||||
tkllayer[4] = mo; /* action */
|
||||
tkllayer[5] = make_nick_user_host(client->name, client->user->username, GetHost(client));
|
||||
@@ -2589,7 +2585,7 @@ TKL *tkl_find_head(char type, char *hostmask, TKL *def)
|
||||
* @returns The TKL entry, or NULL in case of a problem,
|
||||
* such as a regex failing to compile, memory problem, ..
|
||||
*/
|
||||
TKL *_tkl_add_spamfilter(int type, unsigned short target, BanAction action, Match *match, char *set_by,
|
||||
TKL *_tkl_add_spamfilter(int type, unsigned short target, BanAction *action, Match *match, char *set_by,
|
||||
time_t expire_at, time_t set_at,
|
||||
time_t tkl_duration, char *tkl_reason,
|
||||
int flags)
|
||||
@@ -3675,7 +3671,7 @@ int tkl_stats_matcher(Client *client, int type, const char *para, TKLFlag *tklfl
|
||||
(tkl->type & TKL_GLOBAL) ? 'F' : 'f',
|
||||
unreal_match_method_valtostr(tkl->ptr.spamfilter->match->type),
|
||||
spamfilter_target_inttostring(tkl->ptr.spamfilter->target),
|
||||
banact_valtostring(tkl->ptr.spamfilter->action),
|
||||
banact_valtostring(tkl->ptr.spamfilter->action->action),
|
||||
(tkl->expire_at != 0) ? (long long)(tkl->expire_at - TStime()) : 0,
|
||||
(long long)(TStime() - tkl->set_at),
|
||||
(long long)tkl->ptr.spamfilter->tkl_duration,
|
||||
@@ -3841,7 +3837,7 @@ void tkl_sync_send_entry(int add, Client *sender, Client *to, TKL *tkl)
|
||||
add ? '+' : '-',
|
||||
typ,
|
||||
spamfilter_target_inttostring(tkl->ptr.spamfilter->target),
|
||||
banact_valtochar(tkl->ptr.spamfilter->action),
|
||||
banact_valtochar(tkl->ptr.spamfilter->action->action),
|
||||
tkl->set_by,
|
||||
(long long)tkl->expire_at, (long long)tkl->set_at,
|
||||
(long long)tkl->ptr.spamfilter->tkl_duration, tkl->ptr.spamfilter->tkl_reason,
|
||||
@@ -3991,7 +3987,7 @@ TKL *_find_tkl_nameban(int type, char *name, int hold)
|
||||
}
|
||||
|
||||
/** Find a spamfilter TKL - only used to prevent duplicates and for deletion */
|
||||
TKL *_find_tkl_spamfilter(int type, char *match_string, BanAction action, unsigned short target)
|
||||
TKL *_find_tkl_spamfilter(int type, char *match_string, BanActionValue action, unsigned short target)
|
||||
{
|
||||
char tpe = tkl_typetochar(type);
|
||||
TKL *tkl;
|
||||
@@ -4003,7 +3999,7 @@ TKL *_find_tkl_spamfilter(int type, char *match_string, BanAction action, unsign
|
||||
{
|
||||
if ((type == tkl->type) &&
|
||||
!strcmp(match_string, tkl->ptr.spamfilter->match->str) &&
|
||||
(action == tkl->ptr.spamfilter->action) &&
|
||||
(action == tkl->ptr.spamfilter->action->action) &&
|
||||
(target == tkl->ptr.spamfilter->target))
|
||||
{
|
||||
return tkl;
|
||||
@@ -4102,7 +4098,7 @@ void _tkl_added(Client *client, TKL *tkl)
|
||||
sendnotice_tkl_add(tkl);
|
||||
|
||||
/* spamfilter 'warn' action is special */
|
||||
if ((tkl->type & TKL_SPAMF) && (tkl->ptr.spamfilter->action == BAN_ACT_WARN) && (tkl->ptr.spamfilter->target & SPAMF_USER))
|
||||
if ((tkl->type & TKL_SPAMF) && (tkl->ptr.spamfilter->action->action == BAN_ACT_WARN) && (tkl->ptr.spamfilter->target & SPAMF_USER))
|
||||
spamfilter_check_users(tkl);
|
||||
|
||||
/* Ban checking executes during run loop for efficiency */
|
||||
@@ -4283,7 +4279,7 @@ CMD_FUNC(cmd_tkl_add)
|
||||
Match *m; /* compiled match_string */
|
||||
time_t tkl_duration;
|
||||
const char *tkl_reason;
|
||||
BanAction action;
|
||||
BanActionValue action;
|
||||
unsigned short target;
|
||||
/* helper variables */
|
||||
char *err;
|
||||
@@ -4348,7 +4344,7 @@ CMD_FUNC(cmd_tkl_add)
|
||||
log_data_string("spamfilter_regex_error", err));
|
||||
return;
|
||||
}
|
||||
tkl = tkl_add_spamfilter(type, target, action, m, set_by, expire_at, set_at,
|
||||
tkl = tkl_add_spamfilter(type, target, banact_value_to_struct(action), m, set_by, expire_at, set_at,
|
||||
tkl_duration, tkl_reason, 0);
|
||||
}
|
||||
} else
|
||||
@@ -4458,7 +4454,7 @@ CMD_FUNC(cmd_tkl_del)
|
||||
{
|
||||
const char *match_string;
|
||||
unsigned short target;
|
||||
BanAction action;
|
||||
BanActionValue action;
|
||||
|
||||
if (parc < 9)
|
||||
{
|
||||
@@ -4588,7 +4584,7 @@ CMD_FUNC(_cmd_tkl)
|
||||
}
|
||||
|
||||
/** Configure the username/hostname TKL layer based on the BAN_TARGET_* configuration */
|
||||
void ban_target_to_tkl_layer(BanTarget ban_target, BanAction action, Client *client, const char **tkl_username, const char **tkl_hostname)
|
||||
void ban_target_to_tkl_layer(BanTarget ban_target, BanActionValue action, Client *client, const char **tkl_username, const char **tkl_hostname)
|
||||
{
|
||||
static char username[USERLEN+1];
|
||||
static char hostname[HOSTLEN+8];
|
||||
@@ -4649,100 +4645,125 @@ void ban_target_to_tkl_layer(BanTarget ban_target, BanAction action, Client *cli
|
||||
* @param reason The ban reason.
|
||||
* @param duration The ban duration in seconds.
|
||||
* @note This function assumes that client is a locally connected user.
|
||||
* @retval 1 if action is taken, 0 if user is exempted.
|
||||
* @retval 0 user is exempt or no action needs to be taken for other reasons (eg only var setting)
|
||||
* @retval 1 user is banned/shunned/killed/whatever, caller usually returns
|
||||
* @retval BAN_ACT_BLOCK the user was not banned/shunned/killed but should be "blocked"
|
||||
* @note Be sure to check IsDead(client) if return value is 1 and you are
|
||||
* considering to continue processing.
|
||||
*/
|
||||
int _place_host_ban(Client *client, BanAction action, char *reason, long duration)
|
||||
int _place_host_ban(Client *client, BanAction *actions, char *reason, long duration)
|
||||
{
|
||||
/* If this is a soft action and the user is logged in, then the ban does not apply.
|
||||
* NOTE: Actually in such a case it would be better if place_host_ban() would not
|
||||
* be called at all. Or at least, the caller should not take any action
|
||||
* (eg: the message should be delivered, the user may connect, etc..)
|
||||
* The following is more like secondary protection in case the caller forgets...
|
||||
*/
|
||||
if (IsSoftBanAction(action) && IsLoggedIn(client))
|
||||
return 0;
|
||||
BanAction *action;
|
||||
int retval = 0;
|
||||
|
||||
switch(action)
|
||||
for (action = actions; action; action = action->next)
|
||||
{
|
||||
case BAN_ACT_TEMPSHUN:
|
||||
/* We simply mark this connection as shunned and do not add a ban record */
|
||||
unreal_log(ULOG_INFO, "tkl", "TKL_ADD_TEMPSHUN", &me,
|
||||
"Temporary shun added on user $target.details [reason: $shun_reason] [by: $client]",
|
||||
log_data_string("shun_reason", reason),
|
||||
log_data_client("target", client));
|
||||
SetShunned(client);
|
||||
return 1;
|
||||
case BAN_ACT_GZLINE:
|
||||
case BAN_ACT_GLINE:
|
||||
case BAN_ACT_SOFT_GLINE:
|
||||
case BAN_ACT_ZLINE:
|
||||
case BAN_ACT_KLINE:
|
||||
case BAN_ACT_SOFT_KLINE:
|
||||
case BAN_ACT_SHUN:
|
||||
case BAN_ACT_SOFT_SHUN:
|
||||
/* If this is a soft action and the user is logged in, then the ban does not apply. */
|
||||
if (IsSoftBanAction(action->action) && IsLoggedIn(client))
|
||||
return 0;
|
||||
|
||||
switch(action->action)
|
||||
{
|
||||
char ip[128], user[USERLEN+3], mo[100], mo2[100];
|
||||
const char *tkllayer[9] = {
|
||||
me.name, /*0 server.name */
|
||||
"+", /*1 +|- */
|
||||
"?", /*2 type */
|
||||
"*", /*3 user */
|
||||
NULL, /*4 host */
|
||||
NULL,
|
||||
NULL, /*6 expire_at */
|
||||
NULL, /*7 set_at */
|
||||
NULL /*8 reason */
|
||||
};
|
||||
|
||||
ban_target_to_tkl_layer(iConf.automatic_ban_target, action, client, &tkllayer[3], &tkllayer[4]);
|
||||
|
||||
/* For soft bans we need to prefix the % in the username */
|
||||
if (IsSoftBanAction(action))
|
||||
case BAN_ACT_WARN:
|
||||
/* No action taken by us */
|
||||
break;
|
||||
case BAN_ACT_TEMPSHUN:
|
||||
/* We simply mark this connection as shunned and do not add a ban record */
|
||||
unreal_log(ULOG_INFO, "tkl", "TKL_ADD_TEMPSHUN", &me,
|
||||
"Temporary shun added on user $target.details [reason: $shun_reason] [by: $client]",
|
||||
log_data_string("shun_reason", reason),
|
||||
log_data_client("target", client));
|
||||
SetShunned(client);
|
||||
retval = 1;
|
||||
break;
|
||||
case BAN_ACT_GZLINE:
|
||||
case BAN_ACT_GLINE:
|
||||
case BAN_ACT_SOFT_GLINE:
|
||||
case BAN_ACT_ZLINE:
|
||||
case BAN_ACT_KLINE:
|
||||
case BAN_ACT_SOFT_KLINE:
|
||||
case BAN_ACT_SHUN:
|
||||
case BAN_ACT_SOFT_SHUN:
|
||||
{
|
||||
char tmp[USERLEN+3];
|
||||
snprintf(tmp, sizeof(tmp), "%%%s", tkllayer[3]);
|
||||
strlcpy(user, tmp, sizeof(user));
|
||||
tkllayer[3] = user;
|
||||
char ip[128], user[USERLEN+3], mo[100], mo2[100];
|
||||
const char *tkllayer[9] = {
|
||||
me.name, /*0 server.name */
|
||||
"+", /*1 +|- */
|
||||
"?", /*2 type */
|
||||
"*", /*3 user */
|
||||
NULL, /*4 host */
|
||||
NULL,
|
||||
NULL, /*6 expire_at */
|
||||
NULL, /*7 set_at */
|
||||
NULL /*8 reason */
|
||||
};
|
||||
|
||||
ban_target_to_tkl_layer(iConf.automatic_ban_target, action->action, client, &tkllayer[3], &tkllayer[4]);
|
||||
|
||||
/* For soft bans we need to prefix the % in the username */
|
||||
if (IsSoftBanAction(action->action))
|
||||
{
|
||||
char tmp[USERLEN+3];
|
||||
snprintf(tmp, sizeof(tmp), "%%%s", tkllayer[3]);
|
||||
strlcpy(user, tmp, sizeof(user));
|
||||
tkllayer[3] = user;
|
||||
}
|
||||
|
||||
if ((action->action == BAN_ACT_KLINE) || (action->action == BAN_ACT_SOFT_KLINE))
|
||||
tkllayer[2] = "k";
|
||||
else if (action->action == BAN_ACT_ZLINE)
|
||||
tkllayer[2] = "z";
|
||||
else if (action->action == BAN_ACT_GZLINE)
|
||||
tkllayer[2] = "Z";
|
||||
else if ((action->action == BAN_ACT_GLINE) || (action->action == BAN_ACT_SOFT_GLINE))
|
||||
tkllayer[2] = "G";
|
||||
else if ((action->action == BAN_ACT_SHUN) || (action->action == BAN_ACT_SOFT_SHUN))
|
||||
tkllayer[2] = "s";
|
||||
tkllayer[5] = me.name;
|
||||
if (!duration)
|
||||
strlcpy(mo, "0", sizeof(mo)); /* perm */
|
||||
else
|
||||
ircsnprintf(mo, sizeof(mo), "%lld", (long long)(duration + TStime()));
|
||||
ircsnprintf(mo2, sizeof(mo2), "%lld", (long long)TStime());
|
||||
tkllayer[6] = mo;
|
||||
tkllayer[7] = mo2;
|
||||
tkllayer[8] = reason;
|
||||
cmd_tkl(&me, NULL, 9, tkllayer);
|
||||
RunHookReturnInt(HOOKTYPE_PLACE_HOST_BAN, !=99, client, action->action, reason, duration);
|
||||
if ((action->action == BAN_ACT_SHUN) || (action->action == BAN_ACT_SOFT_SHUN))
|
||||
{
|
||||
find_shun(client);
|
||||
retval = 1;
|
||||
break;
|
||||
} /* else.. */
|
||||
retval = find_tkline_match(client, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((action == BAN_ACT_KLINE) || (action == BAN_ACT_SOFT_KLINE))
|
||||
tkllayer[2] = "k";
|
||||
else if (action == BAN_ACT_ZLINE)
|
||||
tkllayer[2] = "z";
|
||||
else if (action == BAN_ACT_GZLINE)
|
||||
tkllayer[2] = "Z";
|
||||
else if ((action == BAN_ACT_GLINE) || (action == BAN_ACT_SOFT_GLINE))
|
||||
tkllayer[2] = "G";
|
||||
else if ((action == BAN_ACT_SHUN) || (action == BAN_ACT_SOFT_SHUN))
|
||||
tkllayer[2] = "s";
|
||||
tkllayer[5] = me.name;
|
||||
if (!duration)
|
||||
strlcpy(mo, "0", sizeof(mo)); /* perm */
|
||||
else
|
||||
ircsnprintf(mo, sizeof(mo), "%lld", (long long)(duration + TStime()));
|
||||
ircsnprintf(mo2, sizeof(mo2), "%lld", (long long)TStime());
|
||||
tkllayer[6] = mo;
|
||||
tkllayer[7] = mo2;
|
||||
tkllayer[8] = reason;
|
||||
cmd_tkl(&me, NULL, 9, tkllayer);
|
||||
RunHookReturnInt(HOOKTYPE_PLACE_HOST_BAN, !=99, client, action, reason, duration);
|
||||
if ((action == BAN_ACT_SHUN) || (action == BAN_ACT_SOFT_SHUN))
|
||||
{
|
||||
find_shun(client);
|
||||
return 1;
|
||||
} /* else.. */
|
||||
return find_tkline_match(client, 0);
|
||||
case BAN_ACT_BLOCK:
|
||||
/* We don't actively do something, but we do indicate it is blocked */
|
||||
if (retval != 1)
|
||||
retval = BAN_ACT_BLOCK;
|
||||
break;
|
||||
case BAN_ACT_SOFT_BLOCK:
|
||||
if (!IsLoggedIn(client))
|
||||
{
|
||||
if (retval != 1)
|
||||
retval = BAN_ACT_BLOCK;
|
||||
}
|
||||
break;
|
||||
case BAN_ACT_SOFT_KILL:
|
||||
case BAN_ACT_KILL:
|
||||
default:
|
||||
RunHookReturnInt(HOOKTYPE_PLACE_HOST_BAN, !=99, client, action->action, reason, duration);
|
||||
exit_client(client, NULL, reason);
|
||||
retval = 1;
|
||||
break;
|
||||
}
|
||||
case BAN_ACT_SOFT_KILL:
|
||||
case BAN_ACT_KILL:
|
||||
default:
|
||||
RunHookReturnInt(HOOKTYPE_PLACE_HOST_BAN, !=99, client, action, reason, duration);
|
||||
exit_client(client, NULL, reason);
|
||||
return 1;
|
||||
|
||||
if (IsDead(client))
|
||||
break; /* stop processing actions */
|
||||
}
|
||||
return 0; /* no action taken (weird) */
|
||||
return retval;
|
||||
}
|
||||
|
||||
/** This function compares two spamfilters ('one' and 'two') and will return
|
||||
@@ -4901,13 +4922,13 @@ int _match_spamfilter(Client *client, const char *str_in, int target, const char
|
||||
if (!(tkl->ptr.spamfilter->target & target))
|
||||
continue;
|
||||
|
||||
if ((flags & SPAMFLAG_NOWARN) && (tkl->ptr.spamfilter->action == BAN_ACT_WARN))
|
||||
if ((flags & SPAMFLAG_NOWARN) && only_actions_of_type(tkl->ptr.spamfilter->action, BAN_ACT_WARN))
|
||||
continue;
|
||||
|
||||
/* If the action is 'soft' (for non-logged in users only) then
|
||||
* don't bother running the spamfilter if the user is logged in.
|
||||
*/
|
||||
if (IsSoftBanAction(tkl->ptr.spamfilter->action) && IsLoggedIn(client))
|
||||
if (IsLoggedIn(client) && only_soft_actions(tkl->ptr.spamfilter->action))
|
||||
continue;
|
||||
|
||||
#ifdef SPAMFILTER_DETECTSLOW
|
||||
@@ -4950,6 +4971,8 @@ int _match_spamfilter(Client *client, const char *str_in, int target, const char
|
||||
if (!winner_tkl && destination && target_is_spamexcept(destination))
|
||||
return 0; /* No problem! */
|
||||
|
||||
// TODO: if (only_actions_of_type(tkl->ptr.spamfilter->action, BAN_ACT_SET)) then don't show the warning unless debugging or something :)
|
||||
|
||||
unreal_log(ULOG_INFO, "tkl", "SPAMFILTER_MATCH", client,
|
||||
"[Spamfilter] $client.details matches filter '$tkl': [cmd: $command$_space$destination: '$str'] [reason: $tkl.reason] [action: $tkl.ban_action]",
|
||||
log_data_tkl("tkl", tkl),
|
||||
@@ -4985,7 +5008,7 @@ int _match_spamfilter(Client *client, const char *str_in, int target, const char
|
||||
/* Spamfilter matched, take action: */
|
||||
|
||||
reason = unreal_decodespace(tkl->ptr.spamfilter->tkl_reason);
|
||||
if ((tkl->ptr.spamfilter->action == BAN_ACT_BLOCK) || (tkl->ptr.spamfilter->action == BAN_ACT_SOFT_BLOCK))
|
||||
if ((tkl->ptr.spamfilter->action->action == BAN_ACT_BLOCK) || (tkl->ptr.spamfilter->action->action == BAN_ACT_SOFT_BLOCK))
|
||||
{
|
||||
switch(target)
|
||||
{
|
||||
@@ -5038,13 +5061,13 @@ int _match_spamfilter(Client *client, const char *str_in, int target, const char
|
||||
}
|
||||
return 1;
|
||||
} else
|
||||
if ((tkl->ptr.spamfilter->action == BAN_ACT_WARN) || (tkl->ptr.spamfilter->action == BAN_ACT_SOFT_WARN))
|
||||
if ((tkl->ptr.spamfilter->action->action == BAN_ACT_WARN) || (tkl->ptr.spamfilter->action->action == BAN_ACT_SOFT_WARN))
|
||||
{
|
||||
if ((target != SPAMF_USER) && (target != SPAMF_QUIT))
|
||||
sendnumeric(client, RPL_SPAMCMDFWD, cmd, reason);
|
||||
return 0;
|
||||
} else
|
||||
if ((tkl->ptr.spamfilter->action == BAN_ACT_DCCBLOCK) || (tkl->ptr.spamfilter->action == BAN_ACT_SOFT_DCCBLOCK))
|
||||
if ((tkl->ptr.spamfilter->action->action == BAN_ACT_DCCBLOCK) || (tkl->ptr.spamfilter->action->action == BAN_ACT_SOFT_DCCBLOCK))
|
||||
{
|
||||
if (target == SPAMF_DCC)
|
||||
{
|
||||
@@ -5054,7 +5077,7 @@ int _match_spamfilter(Client *client, const char *str_in, int target, const char
|
||||
}
|
||||
return 1;
|
||||
} else
|
||||
if ((tkl->ptr.spamfilter->action == BAN_ACT_VIRUSCHAN) || (tkl->ptr.spamfilter->action == BAN_ACT_SOFT_VIRUSCHAN))
|
||||
if ((tkl->ptr.spamfilter->action->action == BAN_ACT_VIRUSCHAN) || (tkl->ptr.spamfilter->action->action == BAN_ACT_SOFT_VIRUSCHAN))
|
||||
{
|
||||
if (IsVirus(client)) /* Already tagged */
|
||||
return 0;
|
||||
|
||||
+3
-3
@@ -430,7 +430,7 @@ int write_tkline(UnrealDB *db, const char *tmpfname, TKL *tkl)
|
||||
{
|
||||
char *match_type = unreal_match_method_valtostr(tkl->ptr.spamfilter->match->type);
|
||||
char *target = spamfilter_target_inttostring(tkl->ptr.spamfilter->target);
|
||||
char action = banact_valtochar(tkl->ptr.spamfilter->action);
|
||||
char action = banact_valtochar(tkl->ptr.spamfilter->action->action);
|
||||
|
||||
W_SAFE(unrealdb_write_str(db, match_type));
|
||||
W_SAFE(unrealdb_write_str(db, tkl->ptr.spamfilter->match->str));
|
||||
@@ -699,7 +699,7 @@ int read_tkldb(void)
|
||||
|
||||
/* Action */
|
||||
R_SAFE(unrealdb_read_char(db, &c));
|
||||
tkl->ptr.spamfilter->action = banact_chartoval(c);
|
||||
tkl->ptr.spamfilter->action = banact_value_to_struct(banact_chartoval(c));
|
||||
if (!tkl->ptr.spamfilter->action)
|
||||
{
|
||||
config_warn("[tkldb] Spamfilter '%s' without valid action (%c) -- spamfilter entry not added",
|
||||
@@ -712,7 +712,7 @@ int read_tkldb(void)
|
||||
tkl->ptr.spamfilter->tkl_duration = v;
|
||||
|
||||
if (find_tkl_spamfilter(tkl->type, tkl->ptr.spamfilter->match->str,
|
||||
tkl->ptr.spamfilter->action,
|
||||
tkl->ptr.spamfilter->action->action,
|
||||
tkl->ptr.spamfilter->target))
|
||||
{
|
||||
do_not_add = 1;
|
||||
|
||||
Reference in New Issue
Block a user