X-Git-Url: https://jfr.im/git/irc/evilnet/x3.git/blobdiff_plain/d914d1cbfd541d1c1302ac989a8c5b7d57d25f55..0f3e9cfc4b5d0f13085c975e10c0e6c4c8e5fbc3:/src/opserv.c diff --git a/src/opserv.c b/src/opserv.c index 88fb61d..71fa774 100644 --- a/src/opserv.c +++ b/src/opserv.c @@ -369,6 +369,7 @@ typedef struct opservDiscrim { unsigned int match_opers : 1, option_log : 1; unsigned int chan_req_modes : 2, chan_no_modes : 2; int authed : 2, info_space : 2; + unsigned int intra_scmp : 2, intra_dcmp : 2; time_t min_ts, max_ts; unsigned int use_regex : 1; } *discrim_t; @@ -389,6 +390,7 @@ static int ungag_helper_func(struct userNode *match, void *extra); typedef enum { REACT_NOTICE, REACT_KILL, + REACT_SILENT, REACT_GLINE, REACT_SHUN } opserv_alert_reaction; @@ -864,7 +866,7 @@ static MODCMD_FUNC(cmd_restart) } static struct gline * -opserv_block(struct userNode *target, char *src_handle, char *reason, unsigned long duration) +opserv_block(struct userNode *target, char *src_handle, char *reason, unsigned long duration, int silent) { char *mask; mask = alloca(MAXLEN); @@ -874,7 +876,7 @@ opserv_block(struct userNode *target, char *src_handle, char *reason, unsigned l snprintf(reason, MAXLEN, "G-line requested by %s.", src_handle); } if (!duration) duration = opserv_conf.block_gline_duration; - return gline_add(src_handle, mask, duration, reason, now, 1); + return gline_add(src_handle, mask, duration, reason, now, 1, silent ? 1 : 0); } static MODCMD_FUNC(cmd_block) @@ -893,7 +895,7 @@ static MODCMD_FUNC(cmd_block) return 0; } reason = (argc > 2) ? unsplit_string(argv+2, argc-2, NULL) : NULL; - gline = opserv_block(target, user->handle_info->handle, reason, 0); + gline = opserv_block(target, user->handle_info->handle, reason, 0, 0); reply("OSMSG_GLINE_ISSUED", gline->target); return 1; } @@ -918,7 +920,7 @@ static MODCMD_FUNC(cmd_gline) reply("MSG_INVALID_DURATION", argv[2]); return 0; } - gline = gline_add(user->handle_info->handle, argv[1], duration, reason, now, 1); + gline = gline_add(user->handle_info->handle, argv[1], duration, reason, now, 1, 0); reply("OSMSG_GLINE_ISSUED", gline->target); return 1; } @@ -1801,6 +1803,7 @@ static MODCMD_FUNC(cmd_stats_alerts) { switch (alert->reaction) { case REACT_NOTICE: reaction = "notice"; break; case REACT_KILL: reaction = "kill"; break; + case REACT_SILENT: reaction = "silent"; break; case REACT_GLINE: reaction = "gline"; break; case REACT_SHUN: reaction = "shun"; break; default: reaction = ""; break; @@ -2062,7 +2065,7 @@ opserv_new_user_check(struct userNode *user) } else if (ohi->clients.used > limit) { char target[18]; sprintf(target, "*@%s", inet_ntoa(user->ip)); - gline_add(opserv->nick, target, opserv_conf.clone_gline_duration, "AUTO Excessive connections from a single host.", now, 1); + gline_add(opserv->nick, target, opserv_conf.clone_gline_duration, "Excessive connections from a single host.", now, 1, 1); } } @@ -2755,6 +2758,8 @@ foreach_matching_user(const char *hostmask, discrim_search_func func, void *extr discrim->max_channels = INT_MAX; discrim->authed = -1; discrim->info_space = -1; + discrim->intra_scmp = 0; + discrim->intra_dcmp = 0; discrim->use_regex = 0; dupmask = strdup(hostmask); if (split_ircmask(dupmask, &discrim->mask_nick, &discrim->mask_ident, &discrim->mask_host)) { @@ -2920,6 +2925,8 @@ add_user_alert(const char *key, void *data, UNUSED_ARG(void *extra)) reaction = REACT_NOTICE; else if (!irccasecmp(react, "kill")) reaction = REACT_KILL; + else if (!irccasecmp(react, "silent")) + reaction = REACT_SILENT; else if (!irccasecmp(react, "gline")) reaction = REACT_GLINE; else if (!irccasecmp(react, "shun")) @@ -3110,6 +3117,7 @@ opserv_saxdb_write(struct saxdb_context *ctx) switch (alert->reaction) { case REACT_NOTICE: reaction = "notice"; break; case REACT_KILL: reaction = "kill"; break; + case REACT_SILENT: reaction = "silent"; break; case REACT_GLINE: reaction = "gline"; break; case REACT_SHUN: reaction = "shun"; break; default: @@ -3226,6 +3234,8 @@ opserv_discrim_create(struct userNode *user, struct userNode *bot, unsigned int discrim->max_channels = INT_MAX; discrim->authed = -1; discrim->info_space = -1; + discrim->intra_dcmp = 0; + discrim->intra_scmp = 0; for (i=0; iintra_dcmp = 1; + else if (!strcasecmp(tmp, "ident")) + discrim->intra_dcmp = 2; + else if (!strcasecmp(tmp, "info")) + discrim->intra_dcmp = 3; + } + } if (irccasecmp(argv[i], "mask") == 0) { if (!is_ircmask(argv[++i])) { send_message(user, bot, "OSMSG_INVALID_IRCMASK", argv[i]); @@ -3250,13 +3272,25 @@ opserv_discrim_create(struct userNode *user, struct userNode *bot, unsigned int goto fail; } } else if (irccasecmp(argv[i], "nick") == 0) { - discrim->mask_nick = argv[++i]; + i++; + if (discrim->intra_dcmp > 0) + discrim->intra_scmp = 1; + else + discrim->mask_nick = argv[i]; } else if (irccasecmp(argv[i], "ident") == 0) { - discrim->mask_ident = argv[++i]; + i++; + if (discrim->intra_dcmp > 0) + discrim->intra_scmp = 2; + else + discrim->mask_ident = argv[i]; } else if (irccasecmp(argv[i], "host") == 0) { discrim->mask_host = argv[++i]; } else if (irccasecmp(argv[i], "info") == 0) { - discrim->mask_info = argv[++i]; + i++; + if (discrim->intra_dcmp > 0) + discrim->intra_scmp = 3; + else + discrim->mask_info = argv[i]; } else if (irccasecmp(argv[i], "server") == 0) { discrim->server = argv[++i]; } else if (irccasecmp(argv[i], "ip") == 0) { @@ -3502,6 +3536,7 @@ static int discrim_match(discrim_t discrim, struct userNode *user) { unsigned int access; + char *scmp=NULL, *dcmp=NULL; if ((user->timestamp < discrim->min_ts) || (user->timestamp > discrim->max_ts) @@ -3536,6 +3571,31 @@ discrim_match(discrim_t discrim, struct userNode *user) } } + if ((discrim->intra_scmp > 0 && discrim->intra_dcmp > 0)) { + switch(discrim->intra_scmp) { + case 1: scmp=user->nick; break; + case 2: scmp=user->ident; break; + case 3: + scmp=user->info; + if (discrim->info_space == 1) scmp++; + break; + } + switch(discrim->intra_dcmp) { + case 1: dcmp=user->nick; break; + case 2: dcmp=user->ident; break; + case 3: /* When checking INFO, and info_space is enabled + * ignore the first character in a search + * XXX: Should we ignore ALL leading whitespace? + * Also, what about ignoring ~ in ident? + */ + dcmp=user->info; + if (discrim->info_space == 1) dcmp++; + break; + } + if (irccasecmp(scmp,dcmp)) + return 0; + } + if (discrim->channel && !GetUserMode(discrim->channel, user)) return 0; access = user->handle_info ? user->handle_info->opserv_level : 0; if ((access < discrim->min_level) @@ -3654,7 +3714,7 @@ trace_gline_func(struct userNode *match, void *extra) struct discrim_and_source *das = extra; if (is_oper_victim(das->source, match, das->discrim->match_opers)) { - opserv_block(match, das->source->handle_info->handle, das->discrim->reason, das->discrim->duration); + opserv_block(match, das->source->handle_info->handle, das->discrim->reason, das->discrim->duration, 0); } return 0; @@ -4283,8 +4343,11 @@ alert_check_user(const char *key, void *data, void *extra) case REACT_KILL: DelUser(user, opserv, 1, alert->discrim->reason); return 1; + case REACT_SILENT: + opserv_block(user, alert->owner, alert->discrim->reason, alert->discrim->duration, 1); + return 1; case REACT_GLINE: - opserv_block(user, alert->owner, alert->discrim->reason, alert->discrim->duration); + opserv_block(user, alert->owner, alert->discrim->reason, alert->discrim->duration, 0); return 1; case REACT_SHUN: opserv_shun(user, alert->owner, alert->discrim->reason, alert->discrim->duration); @@ -4452,6 +4515,8 @@ static MODCMD_FUNC(cmd_addalert) reaction = REACT_NOTICE; else if (!irccasecmp(argv[2], "kill")) reaction = REACT_KILL; + else if (!irccasecmp(argv[2], "silent")) + reaction = REACT_SILENT; else if (!irccasecmp(argv[2], "gline")) reaction = REACT_GLINE; else if (!irccasecmp(argv[2], "shun")) @@ -4649,6 +4714,7 @@ init_opserv(const char *nick) opserv_define_func("ACCESS", cmd_access, 0, 0, 0); opserv_define_func("ADDALERT", cmd_addalert, 800, 0, 4); opserv_define_func("ADDALERT NOTICE", NULL, 0, 0, 0); + opserv_define_func("ADDALERT SILENT", NULL, 900, 0, 0); opserv_define_func("ADDALERT GLINE", NULL, 900, 0, 0); opserv_define_func("ADDALERT SHUN", NULL, 900, 0, 0); opserv_define_func("ADDALERT KILL", NULL, 900, 0, 0);