{ "OSMSG_NEED_CHANNEL", "You must specify a channel for $b%s$b." },
{ "OSMSG_INVALID_IRCMASK", "$b%s$b is an invalid IRC hostmask." },
{ "OSMSG_ADDED_BAN", "I have banned $b%s$b from $b%s$b." },
+ { "OSMSG_NO_GLINE_CMD", "The GLINE command is not bound so you can only block with the default duration." },
+ { "OSMSG_BLOCK_TRUSTED", "$b%s$b is on a trusted ip. If you really want to G-line him, use the GLINE command." },
{ "OSMSG_GLINE_ISSUED", "G-line issued for $b%s$b." },
{ "OSMSG_GLINE_REMOVED", "G-line removed for $b%s$b." },
{ "OSMSG_GLINE_FORCE_REMOVED", "Unknown/expired G-line removed for $b%s$b." },
static dict_t opserv_user_alerts; /* data is struct opserv_user_alert* */
static dict_t opserv_nick_based_alerts; /* data is struct opserv_user_alert* */
static dict_t opserv_channel_alerts; /* data is struct opserv_user_alert* */
+static dict_t opserv_account_alerts; /* data is struct opserv_user_alert* */
static struct module *opserv_module;
static struct log_type *OS_LOG;
static unsigned int new_user_flood;
time_t min_ts, max_ts;
unsigned int min_level, max_level, domain_depth, duration, min_clones, min_channels, max_channels;
unsigned char ip_mask_bits;
- unsigned int match_opers : 1, option_log : 1;
+ unsigned int match_opers : 1, match_trusted : 1, option_log : 1;
unsigned int chan_req_modes : 2, chan_no_modes : 2;
int authed : 2, info_space : 2;
} *discrim_t;
struct userNode *target;
struct gline *gline;
char *reason;
+ unsigned long duration = 0;
+ unsigned int offset = 2;
+ struct svccmd *gline_cmd;
target = GetUserH(argv[1]);
if (!target) {
- reply("MSG_NICK_UNKNOWN", argv[1]);
- return 0;
+ reply("MSG_NICK_UNKNOWN", argv[1]);
+ return 0;
}
if (IsService(target)) {
- reply("MSG_SERVICE_IMMUNE", target->nick);
- return 0;
+ reply("MSG_SERVICE_IMMUNE", target->nick);
+ return 0;
+ }
+ if (dict_find(opserv_trusted_hosts, irc_ntoa(&target->ip), NULL)) {
+ reply("OSMSG_BLOCK_TRUSTED", target->nick);
+ return 0;
+ }
+ if(argc > 2 && (duration = ParseInterval(argv[2]))) {
+ offset = 3;
}
- reason = (argc > 2) ? unsplit_string(argv+2, argc-2, NULL) : NULL;
- gline = opserv_block(target, user->handle_info->handle, reason, 0);
+ if(duration && duration != opserv_conf.block_gline_duration) {
+ // We require more access when the duration is not the default block duration.
+ gline_cmd = dict_find(cmd->parent->commands, "gline", NULL);
+ if(!gline_cmd)
+ {
+ reply("OSMSG_NO_GLINE_CMD");
+ return 0;
+ }
+ if(!svccmd_can_invoke(user, cmd->parent->bot, gline_cmd, channel, SVCCMD_NOISY))
+ return 0;
+ }
+ reason = (argc > offset) ? unsplit_string(argv+offset, argc-offset, NULL) : NULL;
+ gline = opserv_block(target, user->handle_info->handle, reason, duration);
reply("OSMSG_GLINE_ISSUED", gline->target);
return 1;
}
if (IsWallOp(target)) buffer[bpos++] = 'w';
if (IsOper(target)) buffer[bpos++] = 'o';
if (IsGlobal(target)) buffer[bpos++] = 'g';
- if (IsServNotice(target)) buffer[bpos++] = 's';
- if (IsHelperIrcu(target)) buffer[bpos++] = 'h';
if (IsService(target)) buffer[bpos++] = 'k';
if (IsDeaf(target)) buffer[bpos++] = 'd';
+ if (IsNoChan(target)) buffer[bpos++] = 'n';
if (IsHiddenHost(target)) buffer[bpos++] = 'x';
+ if (IsNoIdle(target)) buffer[bpos++] = 'I';
if (IsGagged(target)) buffer_cat(" (gagged)");
if (IsRegistering(target)) buffer_cat(" (registered account)");
buffer[bpos] = 0;
}
static MODCMD_FUNC(cmd_stats_uptime) {
+ extern int lines_processed;
+ extern time_t boot_time;
+ double kernel_time;
+ double user_time;
char uptime[INTERVALLEN];
+
+#if defined(HAVE_TIMES)
+ static double clocks_per_sec;
struct tms buf;
- extern time_t boot_time;
- extern int lines_processed;
- static long clocks_per_sec;
if (!clocks_per_sec) {
#if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
clocks_per_sec = CLOCKS_PER_SEC;
}
}
- intervalString(uptime, time(NULL)-boot_time, user->handle_info);
times(&buf);
- reply("OSMSG_UPTIME_STATS",
- uptime, lines_processed,
- buf.tms_utime/(double)clocks_per_sec,
- buf.tms_stime/(double)clocks_per_sec);
+ user_time = buf.tms_utime / clocks_per_sec;
+ kernel_time = buf.tms_stime / clocks_per_sec;
+#elif defined(HAVE_GETPROCESSTIMES)
+ FILETIME times[4];
+ LARGE_INTEGER li[2];
+
+ GetProcessTimes(GetCurrentProcess(), ×[0], ×[1], ×[2], ×[3]);
+ li[0].LowPart = times[2].dwLowDateTime;
+ li[0].HighPart = times[2].dwHighDateTime;
+ kernel_time = li[0].QuadPart * 1e-7;
+ li[1].LowPart = times[3].dwLowDateTime;
+ li[1].HighPart = times[3].dwHighDateTime;
+ user_time = li[1].QuadPart * 1e-7;
+#else
+ user_time = NAN;
+ system_time = NAN;
+#endif
+
+ intervalString(uptime, time(NULL)-boot_time, user->handle_info);
+ reply("OSMSG_UPTIME_STATS", uptime, lines_processed, user_time, kernel_time);
return 1;
}
dict_insert(opserv_channel_alerts, name_dup, alert);
if (alert->discrim->mask_nick)
dict_insert(opserv_nick_based_alerts, name_dup, alert);
+ if (alert->discrim->accountmask || alert->discrim->authed != -1)
+ dict_insert(opserv_account_alerts, name_dup, alert);
return alert;
}
discrim->max_ts = now - (ParseInterval(cmp+1) - 1);
}
} else {
- discrim->min_ts = now - ParseInterval(cmp+2);
+ discrim->min_ts = now - ParseInterval(cmp);
}
} else if (irccasecmp(argv[i], "access") == 0) {
const char *cmp = argv[++i];
discrim->min_level = strtoul(cmp+1, NULL, 0) + 1;
}
} else {
- discrim->min_level = strtoul(cmp+2, NULL, 0);
+ discrim->min_level = strtoul(cmp, NULL, 0);
+ }
+ } else if (irccasecmp(argv[i], "abuse") == 0) {
+ const char *abuse_what = argv[++i];
+ if (irccasecmp(abuse_what, "opers") == 0) {
+ discrim->match_opers = 1;
+ } else if (irccasecmp(abuse_what, "trusted") == 0) {
+ discrim->match_trusted = 1;
}
- } else if ((irccasecmp(argv[i], "abuse") == 0)
- && (irccasecmp(argv[++i], "opers") == 0)) {
- discrim->match_opers = 1;
} else if (irccasecmp(argv[i], "depth") == 0) {
discrim->domain_depth = strtoul(argv[++i], NULL, 0);
} else if (irccasecmp(argv[i], "clones") == 0) {
&& target->handle_info->opserv_level > user->handle_info->opserv_level));
}
+static int
+is_trust_victim(struct userNode *target, int match_trusted)
+{
+ return (match_trusted || !dict_find(opserv_trusted_hosts, irc_ntoa(&target->ip), NULL));
+}
+
static int
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)) {
+ if (is_oper_victim(das->source, match, das->discrim->match_opers) && is_trust_victim(match, das->discrim->match_trusted)) {
opserv_block(match, das->source->handle_info->handle, das->discrim->reason, das->discrim->duration);
}
{
struct discrim_and_source *das = extra;
- if (is_oper_victim(das->source, match, das->discrim->match_opers)) {
+ if (is_oper_victim(das->source, match, das->discrim->match_opers) && is_trust_victim(match, das->discrim->match_trusted)) {
char *reason;
if (das->discrim->reason) {
reason = das->discrim->reason;
{
struct discrim_and_source *das = extra;
- if (is_oper_victim(das->source, match, das->discrim->match_opers)) {
+ if (is_oper_victim(das->source, match, das->discrim->match_opers) && is_trust_victim(match, das->discrim->match_trusted)) {
char *reason, *mask;
int masksize;
if (das->discrim->reason) {
else
discrim->min_users = strtoul(cmp+1, NULL, 0) + 1;
} else {
- discrim->min_users = strtoul(cmp+2, NULL, 0);
+ discrim->min_users = strtoul(cmp, NULL, 0);
}
} else if (!irccasecmp(argv[i], "timestamp")) {
const char *cmp = argv[++i];
return 0;
}
+ if ((alert->reaction != REACT_NOTICE)
+ && !is_trust_victim(user, alert->discrim->match_trusted)) {
+ return 0;
+ }
+
/* The user matches the alert criteria, so trigger the reaction. */
if (alert->discrim->option_log)
log_module(OS_LOG, LOG_INFO, "Alert %s triggered by user %s!%s@%s (%s).", key, user->nick, user->ident, user->hostname, alert->discrim->reason);
send_channel_notice(opserv_conf.staff_auth_channel, opserv, IDENT_FORMAT" authed to %s account %s", IDENT_DATA(user), type, user->handle_info->handle);
else
send_channel_notice(opserv_conf.staff_auth_channel, opserv, "%s [%s@%s] authed to %s account %s", user->nick, user->ident, user->hostname, type, user->handle_info->handle);
+
+ dict_foreach(opserv_account_alerts, alert_check_user, user);
}
static MODCMD_FUNC(cmd_log)
for (i=1; i<argc; i++) {
dict_remove(opserv_nick_based_alerts, argv[i]);
dict_remove(opserv_channel_alerts, argv[i]);
- if (dict_remove(opserv_user_alerts, argv[i]))
- reply("OSMSG_REMOVED_ALERT", argv[i]);
+ dict_remove(opserv_account_alerts, argv[i]);
+ if (dict_remove(opserv_user_alerts, argv[i]))
+ reply("OSMSG_REMOVED_ALERT", argv[i]);
else
- reply("OSMSG_NO_SUCH_ALERT", argv[i]);
+ reply("OSMSG_NO_SUCH_ALERT", argv[i]);
}
return 1;
}
dict_set_free_keys(opserv_chan_warn, free);
dict_set_free_data(opserv_chan_warn, free);
/* set up opserv_user_alerts */
+ dict_delete(opserv_account_alerts);
+ opserv_account_alerts = dict_new();
dict_delete(opserv_channel_alerts);
opserv_channel_alerts = dict_new();
dict_delete(opserv_nick_based_alerts);
unreg_del_user_func(opserv_user_cleanup);
dict_delete(opserv_hostinfo_dict);
dict_delete(opserv_nick_based_alerts);
+ dict_delete(opserv_account_alerts);
dict_delete(opserv_channel_alerts);
dict_delete(opserv_user_alerts);
for (nn=0; nn<ArrayLength(level_strings); ++nn)