X-Git-Url: https://jfr.im/git/irc/quakenet/newserv.git/blobdiff_plain/331ecd4116cf678bbf4f44692001d0f9195a8535..9172b03e94b4a23862c5ffeab84d2bcec001cb64:/glines/glines.c?ds=sidebyside diff --git a/glines/glines.c b/glines/glines.c index 8d036c14..e19559d8 100644 --- a/glines/glines.c +++ b/glines/glines.c @@ -11,32 +11,20 @@ MODULE_VERSION(""); -static void glines_sched_save(void *arg); - void _init() { /* If we're connected to IRC, force a disconnect. */ if (connected) { irc_send("%s SQ %s 0 :Resync [adding gline support]", mynumeric->content, myserver->content); - irc_disconnected(); + irc_disconnected(0); } registerserverhandler("GL", handleglinemsg, 6); registerhook(HOOK_CORE_STATSREQUEST, handleglinestats); - - schedulerecurring(time(NULL), 0, GLSTORE_SAVE_INTERVAL, &glines_sched_save, NULL); - - glstore_load(); } void _fini() { deregisterserverhandler("GL", handleglinemsg); deregisterhook(HOOK_CORE_STATSREQUEST, handleglinestats); - - deleteschedule(NULL, glines_sched_save, NULL); -} - -static void glines_sched_save(void *arg) { - glstore_save(); } int gline_match_nick(gline *gl, nick *np) { @@ -57,7 +45,7 @@ int gline_match_nick(gline *gl, nick *np) { return 0; if (gl->flags & GLINE_IPMASK) { - if (!ipmask_check(&gl->ip, &np->p_ipaddr, gl->bits)) + if (!ipmask_check(&gl->ip, &np->ipaddress, gl->bits)) return 0; } else { if (gl->host && match(gl->host->content, np->host->name->content) != 0) @@ -109,6 +97,7 @@ gline *findgline(const char *mask) { void gline_activate(gline *agline, time_t lastmod, int propagate) { time_t now = getnettime(); + agline->flags |= GLINE_ACTIVE; if (lastmod) @@ -124,6 +113,12 @@ void gline_activate(gline *agline, time_t lastmod, int propagate) { void gline_deactivate(gline *agline, time_t lastmod, int propagate) { time_t now = getnettime(); + + if (agline->lastmod == 0) { + Error("gline", ERR_WARNING, "Tried to deactivate gline with lastmod == 0: %s", glinetostring(agline)); + return; + } + agline->flags &= ~GLINE_ACTIVE; if (lastmod) @@ -137,34 +132,69 @@ void gline_deactivate(gline *agline, time_t lastmod, int propagate) { gline_propagate(agline); } +void gline_destroy(gline *agline, time_t lastmod, int propagate) { + time_t now = getnettime(); + + agline->flags &= ~GLINE_ACTIVE; + agline->flags |= GLINE_DESTROYED; + + if (agline->lastmod == 0) { + Error("gline", ERR_WARNING, "Tried to destroy gline with lastmod == 0: %s", glinetostring(agline)); + return; + } + + if (lastmod) + agline->lastmod = lastmod; + else if (now <= agline->lastmod) + agline->lastmod++; + else + agline->lastmod = now; + + if (propagate) + gline_propagate(agline); + + removegline(agline); +} + void gline_propagate(gline *agline) { - if (agline->flags & GLINE_ACTIVE) { - controlwall(NO_OPER, NL_GLINES, "Activating G-Line on '%s' lasting %s with reason '%s', created by: %s", + /* Don't propagate Ulined glines. */ + if (agline->lastmod == 0) { + Error("gline", ERR_WARNING, "Tried to propagate gline with lastmod == 0: %s", glinetostring(agline)); + return; + } + +#if SNIRCD_VERSION >= 140 +#error TODO: implement 6 parameter glines for snircd >=1.4.0 +#endif /* SNIRCD_VERSION */ + + if (agline->flags & GLINE_DESTROYED) { +#if SNIRCD_VERSION < 135 + controlwall(NO_OPER, NL_GLINES_AUTO, "Tried to destroy G-Line on '%s' however SNIRCD_VERSION is too old.", glinetostring(agline)); +#else + controlwall(NO_OPER, NL_GLINES_AUTO, "Destroying G-Line on '%s' lasting %s with reason '%s', created by: %s", glinetostring(agline), longtoduration(agline->expire-getnettime(), 0), - agline->reason->content, agline->creator->content); + agline->reason ? agline->reason->content : "", agline->creator->content); -#if 1 - irc_send("%s GL * +%s %lu %lu :%s\r\n", mynumeric->content, + irc_send("%s GL * %%-%s %lu %lu :%s\r\n", mynumeric->content, glinetostring(agline), agline->expire - getnettime(), - agline->lastmod, agline->reason->content); -#else - controlwall(NO_OPER, NL_GLINES, "%s GL * +%s %lu %lu :%s\r\n", mynumeric->content, + agline->lastmod, agline->reason ? agline->reason->content : ""); +#endif /* SNIRCD_VERSION */ + } else if (agline->flags & GLINE_ACTIVE) { + controlwall(NO_OPER, NL_GLINES_AUTO, "Activating G-Line on '%s' lasting %s created by %s with reason '%s'", + glinetostring(agline), longtoduration(agline->expire-getnettime(), 0), + agline->creator->content, agline->reason ? agline->reason->content : ""); + + irc_send("%s GL * +%s %lu %lu :%s\r\n", mynumeric->content, glinetostring(agline), agline->expire - getnettime(), - agline->lastmod, agline->reason->content); -#endif + agline->lastmod, agline->reason ? agline->reason->content : ""); } else { - controlwall(NO_OPER, NL_GLINES, "Deactivating G-Line on '%s'", - glinetostring(agline)); + controlwall(NO_OPER, NL_GLINES_AUTO, "Deactivating G-Line on '%s' lasting %s created by %s with reason '%s'", + glinetostring(agline), longtoduration(agline->expire-getnettime(), 0), + agline->creator->content, agline->reason ? agline->reason->content : ""); -#if 1 irc_send("%s GL * -%s %lu %lu :%s\r\n", mynumeric->content, glinetostring(agline), agline->expire - getnettime(), - agline->lastmod, agline->reason->content); -#else - controlwall(NO_OPER, NL_GLINES, "%s GL * -%s %lu %lu :%s\r\n", mynumeric->content, - glinetostring(agline), agline->expire - getnettime(), - agline->lastmod, agline->reason->content); -#endif + agline->lastmod, agline->reason ? agline->reason->content : ""); } } @@ -216,9 +246,6 @@ int gline_match_mask(gline *gla, gline *glb) { if ((gla->flags & GLINE_REALNAME) != (glb->flags & GLINE_REALNAME)) return 0; - if ((gla->flags & GLINE_IPMASK) != (glb->flags & GLINE_IPMASK)) - return 0; - if (gla->nick && !glb->nick) return 0; @@ -231,7 +258,7 @@ int gline_match_mask(gline *gla, gline *glb) { if (gla->user && glb->user && match(gla->user->content, glb->user->content) != 0) return 0; - if (gla->flags & GLINE_IPMASK) { + if (gla->flags & GLINE_IPMASK && glb->flags & GLINE_IPMASK) { if (gla->bits > glb->bits) return 0; @@ -253,6 +280,18 @@ int isglinesane(gline *gl, const char **hint) { char *pos; trusthost *th; + /* Reason is too short */ + if (!gl->reason || strlen(gl->reason->content) < MINGLINEREASONLEN) { + *hint = "G-Line reason is too short."; + return 0; + } + + /* Duration is too long */ + if (gl->expire - getnettime() > MAXGLINEDURATION) { + *hint = "G-Line duration is too long."; + return 0; + } + /* Hits all realnames. */ if ((gl->flags & GLINE_REALNAME) && !gl->user) { *hint = "Matches all realnames."; @@ -265,6 +304,15 @@ int isglinesane(gline *gl, const char **hint) { return 0; } + /* Hostmask is too long. */ + if (!(gl->flags & (GLINE_BADCHAN | GLINE_REALNAME)) && + ((gl->nick && strlen(gl->nick->content) > NICKLEN) || + (gl->user && strlen(gl->user->content) > USERLEN) || + (gl->host && strlen(gl->host->content) > HOSTLEN))) { + *hint = "Hostmask components are too long."; + return 0; + } + /* Skip the other checks for nickname glines. */ if (gl->nick) return 1; @@ -316,7 +364,7 @@ int isglinesane(gline *gl, const char **hint) { } /* Wildcard username match for trusted host with reliable usernames. */ - if (gl->flags & GLINE_IPMASK && (!gl->user || strchr(gl->user->content, '*') || strchr(gl->user->content, '?'))) { + if ((gl->flags & GLINE_IPMASK) && (!gl->user || strchr(gl->user->content, '*') || strchr(gl->user->content, '?'))) { th = th_getbyhost(&gl->ip); if (th && (th->group->flags & TRUST_RELIABLE_USERNAME)) { @@ -327,3 +375,35 @@ int isglinesane(gline *gl, const char **hint) { return 1; } + +gline *glinedup(gline *gl) { + gline *sgl; + + sgl = newgline(); + + if (!sgl) + return NULL; + + if (gl->nick) + sgl->nick = getsstring(gl->nick->content, 512); + + if (gl->user) + sgl->user = getsstring(gl->user->content, 512); + + if (gl->host) + sgl->host = getsstring(gl->host->content, 512); + + sgl->reason = gl->reason ? getsstring(gl->reason->content, 512) : NULL; + sgl->creator = getsstring(gl->creator->content, 512); + + memcpy(&sgl->ip, &gl->ip, sizeof(gl->ip)); + sgl->bits = gl->bits; + + sgl->expire = gl->expire; + sgl->lastmod = gl->lastmod; + sgl->lifetime = gl->lifetime; + + sgl->flags = gl->flags; + + return sgl; +}