]>
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
);
28 deregisterserverhandler("GL", handleglinemsg
);
29 deregisterhook(HOOK_CORE_STATSREQUEST
, handleglinestats
);
32 int gline_match_nick(gline
*gl
, nick
*np
) {
33 if (gl
->flags
& GLINE_BADCHAN
)
36 if (gl
->flags
& GLINE_REALNAME
) {
37 if (gl
->user
&& match(gl
->user
->content
, np
->realname
->name
->content
) != 0)
43 if (gl
->nick
&& match(gl
->nick
->content
, np
->nick
) != 0)
46 if (gl
->user
&& match(gl
->user
->content
, np
->ident
) != 0)
49 if (gl
->flags
& GLINE_IPMASK
) {
50 if (!ipmask_check(&gl
->ip
, &np
->p_ipaddr
, gl
->bits
))
53 if (gl
->host
&& match(gl
->host
->content
, np
->host
->name
->content
) != 0)
60 int gline_match_channel(gline
*gl
, channel
*cp
) {
61 if (!(gl
->flags
& GLINE_BADCHAN
))
64 if (match(gl
->user
->content
, cp
->index
->name
->content
) != 0)
70 gline
*findgline(const char *mask
) {
73 time_t curtime
= time(0);
75 globalgline
= makegline(mask
);
78 return NULL
; /* gline mask couldn't be processed */
80 for (gl
= glinelist
; gl
; gl
= next
) {
83 if (gl
->lifetime
<= curtime
) {
86 } else if (gl
->expire
<= curtime
) {
87 gl
->flags
&= ~GLINE_ACTIVE
;
90 if (glineequal(globalgline
, gl
)) {
91 freegline(globalgline
);
96 freegline(globalgline
);
100 void gline_activate(gline
*agline
, time_t lastmod
, int propagate
) {
101 time_t now
= getnettime();
103 agline
->flags
|= GLINE_ACTIVE
;
106 agline
->lastmod
= lastmod
;
107 else if (now
<= agline
->lastmod
)
110 agline
->lastmod
= now
;
113 gline_propagate(agline
);
116 void gline_deactivate(gline
*agline
, time_t lastmod
, int propagate
) {
117 time_t now
= getnettime();
119 if (agline
->lastmod
== 0) {
120 Error("gline", ERR_WARNING
, "Tried to deactivate gline with lastmod == 0: %s", glinetostring(agline
));
124 agline
->flags
&= ~GLINE_ACTIVE
;
127 agline
->lastmod
= lastmod
;
128 else if (now
<= agline
->lastmod
)
131 agline
->lastmod
= now
;
134 gline_propagate(agline
);
137 void gline_destroy(gline
*agline
, time_t lastmod
, int propagate
) {
138 time_t now
= getnettime();
140 agline
->flags
&= ~GLINE_ACTIVE
;
141 agline
->flags
|= GLINE_DESTROYED
;
143 if (agline
->lastmod
== 0) {
144 Error("gline", ERR_WARNING
, "Tried to destroy gline with lastmod == 0: %s", glinetostring(agline
));
149 agline
->lastmod
= lastmod
;
150 else if (now
<= agline
->lastmod
)
153 agline
->lastmod
= now
;
156 gline_propagate(agline
);
161 void gline_propagate(gline
*agline
) {
162 if (agline
->flags
& GLINE_DESTROYED
) {
163 controlwall(NO_OPER
, NL_GLINES
, "Destroying G-Line on '%s' lasting %s with reason '%s', created by: %s",
164 glinetostring(agline
), longtoduration(agline
->expire
-getnettime(), 0),
165 agline
->reason
->content
, agline
->creator
->content
);
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
);
176 } else if (agline
->flags
& GLINE_ACTIVE
) {
177 controlwall(NO_OPER
, NL_GLINES
, "Activating G-Line on '%s' lasting %s with reason '%s', created by: %s",
178 glinetostring(agline
), longtoduration(agline
->expire
-getnettime(), 0),
179 agline
->reason
->content
, agline
->creator
->content
);
182 irc_send("%s GL * +%s %lu %lu :%s\r\n", mynumeric
->content
,
183 glinetostring(agline
), agline
->expire
- getnettime(),
184 agline
->lastmod
, agline
->reason
->content
);
186 controlwall(NO_OPER
, NL_GLINES
, "%s GL * +%s %lu %lu :%s\r\n", mynumeric
->content
,
187 glinetostring(agline
), agline
->expire
- getnettime(),
188 agline
->lastmod
, agline
->reason
->content
);
191 controlwall(NO_OPER
, NL_GLINES
, "Deactivating G-Line on '%s'",
192 glinetostring(agline
));
195 irc_send("%s GL * -%s %lu %lu :%s\r\n", mynumeric
->content
,
196 glinetostring(agline
), agline
->expire
- getnettime(),
197 agline
->lastmod
, agline
->reason
->content
);
199 controlwall(NO_OPER
, NL_GLINES
, "%s GL * -%s %lu %lu :%s\r\n", mynumeric
->content
,
200 glinetostring(agline
), agline
->expire
- getnettime(),
201 agline
->lastmod
, agline
->reason
->content
);
206 /* returns non-zero if the glines are exactly the same */
207 int glineequal(gline
*gla
, gline
*glb
) {
208 if ((gla
->flags
& GLINE_BADCHAN
) != (glb
->flags
& GLINE_BADCHAN
))
211 if ((gla
->flags
& GLINE_REALNAME
) != (glb
->flags
& GLINE_REALNAME
))
214 if ((gla
->flags
& GLINE_IPMASK
) != (glb
->flags
& GLINE_IPMASK
))
217 if ((!gla
->nick
&& glb
->nick
) || (gla
->nick
&& !glb
->nick
))
220 if (gla
->nick
&& ircd_strcmp(gla
->nick
->content
, glb
->nick
->content
) != 0)
223 if ((!gla
->user
&& glb
->user
) || (gla
->user
&& !glb
->user
))
226 if (gla
->user
&& ircd_strcmp(gla
->user
->content
, glb
->user
->content
) != 0)
229 if (gla
->flags
& GLINE_IPMASK
) {
230 if (gla
->bits
!= glb
->bits
)
233 if (!ipmask_check(&gla
->ip
, &glb
->ip
, gla
->bits
))
236 if ((!gla
->host
&& glb
->host
) || (gla
->host
&& !glb
->host
))
239 if (gla
->host
&& ircd_strcmp(gla
->host
->content
, glb
->host
->content
) != 0)
246 /* returns non-zero on match */
247 int gline_match_mask(gline
*gla
, gline
*glb
) {
248 if ((gla
->flags
& GLINE_BADCHAN
) != (glb
->flags
& GLINE_BADCHAN
))
251 if ((gla
->flags
& GLINE_REALNAME
) != (glb
->flags
& GLINE_REALNAME
))
254 if ((gla
->flags
& GLINE_IPMASK
) != (glb
->flags
& GLINE_IPMASK
))
257 if (gla
->nick
&& !glb
->nick
)
260 if (gla
->nick
&& glb
->nick
&& match(gla
->nick
->content
, glb
->nick
->content
) != 0)
263 if (gla
->user
&& !glb
->user
)
266 if (gla
->user
&& glb
->user
&& match(gla
->user
->content
, glb
->user
->content
) != 0)
269 if (gla
->flags
& GLINE_IPMASK
) {
270 if (gla
->bits
> glb
->bits
)
273 if (!ipmask_check(&gla
->ip
, &glb
->ip
, gla
->bits
))
276 if (gla
->host
&& !glb
->host
)
279 if (gla
->host
&& glb
->host
&& match(gla
->host
->content
, glb
->host
->content
) != 0)
286 int isglinesane(gline
*gl
, const char **hint
) {
287 int wildcard
, nowildcardcount
;
291 /* Hits all realnames. */
292 if ((gl
->flags
& GLINE_REALNAME
) && !gl
->user
) {
293 *hint
= "Matches all realnames.";
297 /* Hits all local/non-local channels. */
298 if ((gl
->flags
& GLINE_BADCHAN
) && (strcmp(gl
->user
->content
, "&*") == 0 || strcmp(gl
->user
->content
, "#*") == 0)) {
299 *hint
= "Matches all local/non-local channels.";
303 /* Skip the other checks for nickname glines. */
307 /* Mask wider than /16 for IPv4 or /32 for IPv6. */
308 if ((gl
->flags
& GLINE_IPMASK
) && gl
->bits
< (irc_in_addr_is_ipv4(&gl
->ip
) ? (96 + 16) : 32)) {
309 *hint
= "CIDR mask too wide.";
313 /* Doesn't have at least two non-wildcarded host components. */
314 if (gl
->flags
& GLINE_HOSTMASK
) {
318 pos
= gl
->host
->content
;
336 pos
= NULL
; /* Leave the loop. */
347 if (nowildcardcount
< 2) {
348 *hint
= "Needs at least 2 non-wildcarded host components.";
353 /* Wildcard username match for trusted host with reliable usernames. */
354 if ((gl
->flags
& GLINE_IPMASK
) && (!gl
->user
|| strchr(gl
->user
->content
, '*') || strchr(gl
->user
->content
, '?'))) {
355 th
= th_getbyhost(&gl
->ip
);
357 if (th
&& (th
->group
->flags
& TRUST_RELIABLE_USERNAME
)) {
358 *hint
= "Wildcard username match for a trusted host that has reliable usernames.";