]>
jfr.im git - irc/quakenet/newserv.git/blob - glines/glines.c
4 #include "../lib/irc_string.h"
5 #include "../lib/version.h"
6 #include "../core/schedule.h"
7 #include "../irc/irc.h"
8 #include "../trusts/trusts.h"
9 #include "../control/control.h"
14 static void glines_sched_save(void *arg
);
17 /* If we're connected to IRC, force a disconnect. */
19 irc_send("%s SQ %s 0 :Resync [adding gline support]", mynumeric
->content
, myserver
->content
);
23 registerserverhandler("GL", handleglinemsg
, 6);
24 registerhook(HOOK_CORE_STATSREQUEST
, handleglinestats
);
26 schedulerecurring(time(NULL
), 0, GLSTORE_SAVE_INTERVAL
, &glines_sched_save
, NULL
);
32 deregisterserverhandler("GL", handleglinemsg
);
33 deregisterhook(HOOK_CORE_STATSREQUEST
, handleglinestats
);
35 deleteschedule(NULL
, glines_sched_save
, NULL
);
38 static void glines_sched_save(void *arg
) {
42 int gline_match_nick(gline
*gl
, nick
*np
) {
43 if (gl
->flags
& GLINE_BADCHAN
)
46 if (gl
->flags
& GLINE_REALNAME
) {
47 if (gl
->user
&& match(gl
->user
->content
, np
->realname
->name
->content
) != 0)
53 if (gl
->nick
&& match(gl
->nick
->content
, np
->nick
) != 0)
56 if (gl
->user
&& match(gl
->user
->content
, np
->ident
) != 0)
59 if (gl
->flags
& GLINE_IPMASK
) {
60 if (!ipmask_check(&gl
->ip
, &np
->p_ipaddr
, gl
->bits
))
63 if (gl
->host
&& match(gl
->host
->content
, np
->host
->name
->content
) != 0)
70 int gline_match_channel(gline
*gl
, channel
*cp
) {
71 if (!(gl
->flags
& GLINE_BADCHAN
))
74 if (match(gl
->user
->content
, cp
->index
->name
->content
) != 0)
80 gline
*findgline(const char *mask
) {
83 time_t curtime
= time(0);
85 globalgline
= makegline(mask
);
88 return NULL
; /* gline mask couldn't be processed */
90 for (gl
= glinelist
; gl
; gl
= next
) {
93 if (gl
->lifetime
<= curtime
) {
96 } else if (gl
->expire
<= curtime
) {
97 gl
->flags
&= ~GLINE_ACTIVE
;
100 if (glineequal(globalgline
, gl
)) {
101 freegline(globalgline
);
106 freegline(globalgline
);
110 gline
*gline_activate(gline
*agline
, time_t lastmod
, int propagate
) {
111 time_t now
= getnettime();
112 agline
->flags
|= GLINE_ACTIVE
;
115 agline
->lastmod
= lastmod
;
117 if (now
<= agline
->lastmod
)
120 agline
->lastmod
= now
;
124 gline_propagate(agline
);
129 gline
*gline_deactivate(gline
*agline
, time_t lastmod
, int propagate
) {
130 time_t now
= getnettime();
131 agline
->flags
&= ~GLINE_ACTIVE
;
134 agline
->lastmod
= lastmod
;
136 if (now
<= agline
->lastmod
)
139 agline
->lastmod
= now
;
143 gline_propagate(agline
);
148 void gline_propagate(gline
*agline
) {
149 if (agline
->flags
& GLINE_ACTIVE
) {
150 controlwall(NO_OPER
, NL_GLINES
, "Activating G-Line on '%s' lasting %s with reason '%s', created by: %s",
151 glinetostring(agline
), longtoduration(agline
->expire
-getnettime(), 0),
152 agline
->reason
->content
, agline
->creator
->content
);
155 irc_send("%s GL * +%s %lu %lu :%s\r\n", mynumeric
->content
,
156 glinetostring(agline
), agline
->expire
- getnettime(),
157 agline
->lastmod
, agline
->reason
->content
);
159 controlwall(NO_OPER
, NL_GLINES
, "%s GL * +%s %lu %lu :%s\r\n", mynumeric
->content
,
160 glinetostring(agline
), agline
->expire
- getnettime(),
161 agline
->lastmod
, agline
->reason
->content
);
164 controlwall(NO_OPER
, NL_GLINES
, "Deactivating G-Line on '%s'",
165 glinetostring(agline
));
168 irc_send("%s GL * -%s %lu %lu :%s\r\n", mynumeric
->content
,
169 glinetostring(agline
), agline
->expire
- getnettime(),
170 agline
->lastmod
, agline
->reason
->content
);
172 controlwall(NO_OPER
, NL_GLINES
, "%s GL * -%s %lu %lu :%s\r\n", mynumeric
->content
,
173 glinetostring(agline
), agline
->expire
- getnettime(),
174 agline
->lastmod
, agline
->reason
->content
);
179 /* returns non-zero if the glines are exactly the same */
180 int glineequal(gline
*gla
, gline
*glb
) {
181 if ((gla
->flags
& GLINE_BADCHAN
) != (glb
->flags
& GLINE_BADCHAN
))
184 if ((gla
->flags
& GLINE_REALNAME
) != (glb
->flags
& GLINE_REALNAME
))
187 if ((gla
->flags
& GLINE_IPMASK
) != (glb
->flags
& GLINE_IPMASK
))
190 if ((!gla
->nick
&& glb
->nick
) || (gla
->nick
&& !glb
->nick
))
193 if (gla
->nick
&& ircd_strcmp(gla
->nick
->content
, glb
->nick
->content
) != 0)
196 if ((!gla
->user
&& glb
->user
) || (gla
->user
&& !glb
->user
))
199 if (gla
->user
&& ircd_strcmp(gla
->user
->content
, glb
->user
->content
) != 0)
202 if (gla
->flags
& GLINE_IPMASK
) {
203 if (gla
->bits
!= glb
->bits
)
206 if (!ipmask_check(&gla
->ip
, &glb
->ip
, gla
->bits
))
209 if ((!gla
->host
&& glb
->host
) || (gla
->host
&& !glb
->host
))
212 if (gla
->host
&& ircd_strcmp(gla
->host
->content
, glb
->host
->content
) != 0)
219 /* returns non-zero on match */
220 int gline_match_mask(gline
*gla
, gline
*glb
) {
221 if ((gla
->flags
& GLINE_BADCHAN
) != (glb
->flags
& GLINE_BADCHAN
))
224 if ((gla
->flags
& GLINE_REALNAME
) != (glb
->flags
& GLINE_REALNAME
))
227 if ((gla
->flags
& GLINE_IPMASK
) != (glb
->flags
& GLINE_IPMASK
))
230 if (gla
->nick
&& !glb
->nick
)
233 if (gla
->nick
&& glb
->nick
&& match(gla
->nick
->content
, glb
->nick
->content
) != 0)
236 if (gla
->user
&& !glb
->user
)
239 if (gla
->user
&& glb
->user
&& match(gla
->user
->content
, glb
->user
->content
) != 0)
242 if (gla
->flags
& GLINE_IPMASK
) {
243 if (gla
->bits
> glb
->bits
)
246 if (!ipmask_check(&gla
->ip
, &glb
->ip
, gla
->bits
))
249 if (gla
->host
&& !glb
->host
)
252 if (gla
->host
&& glb
->host
&& match(gla
->host
->content
, glb
->host
->content
) != 0)
259 int isglinesane(gline
*gl
, const char **hint
) {
260 int wildcard
, nowildcardcount
;
264 /* Hits all realnames. */
265 if ((gl
->flags
& GLINE_REALNAME
) && !gl
->user
) {
266 *hint
= "Matches all realnames.";
270 /* Hits all local/non-local channels. */
271 if ((gl
->flags
& GLINE_BADCHAN
) && (strcmp(gl
->user
->content
, "&*") == 0 || strcmp(gl
->user
->content
, "#*") == 0)) {
272 *hint
= "Matches all local/non-local channels.";
276 /* Skip the other checks for nickname glines. */
280 /* Mask wider than /16 for IPv4 or /32 for IPv6. */
281 if ((gl
->flags
& GLINE_IPMASK
) && gl
->bits
< (irc_in_addr_is_ipv4(&gl
->ip
) ? (96 + 16) : 32)) {
282 *hint
= "CIDR mask too wide.";
286 /* Doesn't have at least two non-wildcarded host components. */
287 if (gl
->flags
& GLINE_HOSTMASK
) {
291 pos
= gl
->host
->content
;
309 pos
= NULL
; /* Leave the loop. */
320 if (nowildcardcount
< 2) {
321 *hint
= "Needs at least 2 non-wildcarded host components.";
326 /* Wildcard username match for trusted host with reliable usernames. */
327 if (gl
->flags
& GLINE_IPMASK
&& (!gl
->user
|| strchr(gl
->user
->content
, '*') || strchr(gl
->user
->content
, '?'))) {
328 th
= th_getbyhost(&gl
->ip
);
330 if (th
&& (th
->group
->flags
& TRUST_RELIABLE_USERNAME
)) {
331 *hint
= "Wildcard username match for a trusted host that has reliable usernames.";