1 |
|
/* |
2 |
|
* ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd) |
3 |
|
* |
4 |
< |
* Copyright (c) 2001-2015 ircd-hybrid development team |
4 |
> |
* Copyright (c) 2001-2019 ircd-hybrid development team |
5 |
|
* |
6 |
|
* This program is free software; you can redistribute it and/or modify |
7 |
|
* it under the terms of the GNU General Public License as published by |
42 |
|
ch = ch - 'A' + 10; \ |
43 |
|
else if (ch >= 'a' && ch <= 'f') \ |
44 |
|
ch = ch - 'a' + 10; \ |
45 |
< |
} while (0); |
45 |
> |
} while (false); |
46 |
|
|
47 |
|
/* Hashtable stuff...now external as it's used in m_stats.c */ |
48 |
|
dlink_list atable[ATABLE_SIZE]; |
154 |
|
|
155 |
|
/* And assign... -A1kmm */ |
156 |
|
if (addr) |
157 |
+ |
{ |
158 |
+ |
v6->sin6_family = AF_INET6; |
159 |
+ |
|
160 |
|
for (dp = 0; dp < 8; ++dp) |
161 |
|
/* The cast is a kludge to make netbsd work. */ |
162 |
|
((unsigned short *)&v6->sin6_addr)[dp] = htons(dc[dp]); |
163 |
+ |
} |
164 |
|
|
165 |
|
if (b) |
166 |
|
*b = bits; |
238 |
|
for (n = bits / 8 + (bits % 8 ? 1 : 0); n < 4; ++n) |
239 |
|
addb[n] = 0; |
240 |
|
if (addr) |
241 |
+ |
{ |
242 |
+ |
v4->sin_family = AF_INET; |
243 |
|
v4->sin_addr.s_addr = |
244 |
|
htonl(addb[0] << 24 | addb[1] << 16 | addb[2] << 8 | addb[3]); |
245 |
+ |
} |
246 |
+ |
|
247 |
|
if (b) |
248 |
|
*b = bits; |
249 |
|
return HM_IPV4; |
259 |
|
int |
260 |
|
parse_netmask(const char *text, struct irc_ssaddr *addr, int *b) |
261 |
|
{ |
262 |
+ |
if (addr) |
263 |
+ |
memset(addr, 0, sizeof(*addr)); |
264 |
+ |
|
265 |
|
if (strchr(text, '.')) |
266 |
|
return try_parse_v4_netmask(text, addr, b); |
267 |
|
if (strchr(text, ':')) |
276 |
|
* Output: if match, -1 else 0 |
277 |
|
* Side effects: None |
278 |
|
*/ |
279 |
< |
int |
279 |
> |
bool |
280 |
|
match_ipv6(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits) |
281 |
|
{ |
282 |
|
int i, m, n = bits / 8; |
285 |
|
|
286 |
|
for (i = 0; i < n; ++i) |
287 |
|
if (v6->sin6_addr.s6_addr[i] != v6mask->sin6_addr.s6_addr[i]) |
288 |
< |
return 0; |
288 |
> |
return false; |
289 |
|
|
290 |
|
if ((m = bits % 8) == 0) |
291 |
< |
return -1; |
291 |
> |
return true; |
292 |
|
if ((v6->sin6_addr.s6_addr[n] & ~((1 << (8 - m)) - 1)) == |
293 |
|
v6mask->sin6_addr.s6_addr[n]) |
294 |
< |
return -1; |
295 |
< |
return 0; |
294 |
> |
return true; |
295 |
> |
return false; |
296 |
|
} |
297 |
|
|
298 |
|
/* int match_ipv4(struct irc_ssaddr *, struct irc_ssaddr *, int) |
300 |
|
* Output: if match, -1 else 0 |
301 |
|
* Side Effects: None |
302 |
|
*/ |
303 |
< |
int |
303 |
> |
bool |
304 |
|
match_ipv4(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits) |
305 |
|
{ |
306 |
|
const struct sockaddr_in *const v4 = (const struct sockaddr_in *)addr; |
307 |
|
const struct sockaddr_in *const v4mask = (const struct sockaddr_in *)mask; |
308 |
|
|
309 |
< |
if ((ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1)) != |
309 |
> |
if ((ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1)) == |
310 |
|
ntohl(v4mask->sin_addr.s_addr)) |
311 |
< |
return 0; |
312 |
< |
return -1; |
302 |
< |
} |
303 |
< |
|
304 |
< |
/* |
305 |
< |
* mask_addr |
306 |
< |
* |
307 |
< |
* inputs - pointer to the ip to mask |
308 |
< |
* - bitlen |
309 |
< |
* output - NONE |
310 |
< |
* side effects - |
311 |
< |
*/ |
312 |
< |
void |
313 |
< |
mask_addr(struct irc_ssaddr *ip, int bits) |
314 |
< |
{ |
315 |
< |
int mask; |
316 |
< |
struct sockaddr_in6 *v6_base_ip; |
317 |
< |
int i, m, n; |
318 |
< |
struct sockaddr_in *v4_base_ip; |
319 |
< |
|
320 |
< |
if (ip->ss.ss_family == AF_INET) |
321 |
< |
{ |
322 |
< |
uint32_t tmp = 0; |
323 |
< |
v4_base_ip = (struct sockaddr_in *)ip; |
324 |
< |
|
325 |
< |
mask = ~((1 << (32 - bits)) - 1); |
326 |
< |
tmp = ntohl(v4_base_ip->sin_addr.s_addr); |
327 |
< |
v4_base_ip->sin_addr.s_addr = htonl(tmp & mask); |
328 |
< |
} |
329 |
< |
else |
330 |
< |
{ |
331 |
< |
n = bits / 8; |
332 |
< |
m = bits % 8; |
333 |
< |
v6_base_ip = (struct sockaddr_in6 *)ip; |
334 |
< |
|
335 |
< |
mask = ~((1 << (8 - m)) - 1); |
336 |
< |
v6_base_ip->sin6_addr.s6_addr[n] = v6_base_ip->sin6_addr.s6_addr[n] & mask; |
337 |
< |
|
338 |
< |
for (i = n + 1; i < 16; i++) |
339 |
< |
v6_base_ip->sin6_addr.s6_addr[i] = 0; |
340 |
< |
} |
311 |
> |
return true; |
312 |
> |
return false; |
313 |
|
} |
314 |
|
|
315 |
|
/* unsigned long hash_ipv4(struct irc_ssaddr*) |
320 |
|
static uint32_t |
321 |
|
hash_ipv4(const struct irc_ssaddr *addr, int bits) |
322 |
|
{ |
323 |
< |
if (bits != 0) |
323 |
> |
if (bits) |
324 |
|
{ |
325 |
|
const struct sockaddr_in *const v4 = (const struct sockaddr_in *)addr; |
326 |
|
uint32_t av = ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1); |
408 |
|
*/ |
409 |
|
struct MaskItem * |
410 |
|
find_conf_by_address(const char *name, const struct irc_ssaddr *addr, unsigned int type, |
411 |
< |
int fam, const char *username, const char *password, int do_match) |
411 |
> |
const char *username, const char *password, int do_match) |
412 |
|
{ |
413 |
|
unsigned int hprecv = 0; |
414 |
< |
dlink_node *node = NULL; |
414 |
> |
dlink_node *node; |
415 |
|
struct MaskItem *hprec = NULL; |
416 |
|
struct AddressRec *arec = NULL; |
445 |
– |
int b; |
417 |
|
int (*cmpfunc)(const char *, const char *) = do_match ? match : irccmp; |
418 |
|
|
419 |
|
if (addr) |
420 |
|
{ |
421 |
|
/* Check for IPV6 matches... */ |
422 |
< |
if (fam == AF_INET6) |
422 |
> |
if (addr->ss.ss_family == AF_INET6) |
423 |
|
{ |
424 |
< |
for (b = 128; b >= 0; b -= 16) |
424 |
> |
for (int b = 128; b >= 0; b -= 16) |
425 |
|
{ |
426 |
|
DLINK_FOREACH(node, atable[hash_ipv6(addr, b)].head) |
427 |
|
{ |
442 |
|
} |
443 |
|
} |
444 |
|
} |
445 |
< |
else if (fam == AF_INET) |
445 |
> |
else if (addr->ss.ss_family == AF_INET) |
446 |
|
{ |
447 |
< |
for (b = 32; b >= 0; b -= 8) |
447 |
> |
for (int b = 32; b >= 0; b -= 8) |
448 |
|
{ |
449 |
|
DLINK_FOREACH(node, atable[hash_ipv4(addr, b)].head) |
450 |
|
{ |
471 |
|
{ |
472 |
|
const char *p = name; |
473 |
|
|
474 |
< |
while (1) |
474 |
> |
while (true) |
475 |
|
{ |
476 |
|
DLINK_FOREACH(node, atable[hash_text(p)].head) |
477 |
|
{ |
522 |
|
* Side-effects: None |
523 |
|
*/ |
524 |
|
struct MaskItem * |
525 |
< |
find_address_conf(const char *host, const char *user, const struct irc_ssaddr *ip, |
555 |
< |
int aftype, const char *password) |
525 |
> |
find_address_conf(const char *host, const char *user, const struct irc_ssaddr *addr, const char *password) |
526 |
|
{ |
527 |
|
struct MaskItem *authcnf = NULL, *killcnf = NULL; |
528 |
|
|
529 |
|
/* Find the best auth{} block... If none, return NULL -A1kmm */ |
530 |
< |
if ((authcnf = find_conf_by_address(host, ip, CONF_CLIENT, aftype, user, |
561 |
< |
password, 1)) == NULL) |
530 |
> |
if ((authcnf = find_conf_by_address(host, addr, CONF_CLIENT, user, password, 1)) == NULL) |
531 |
|
return NULL; |
532 |
|
|
533 |
|
/* If they are exempt from K-lines, return the best auth{} block. -A1kmm */ |
535 |
|
return authcnf; |
536 |
|
|
537 |
|
/* Find the best K-line... -A1kmm */ |
538 |
< |
killcnf = find_conf_by_address(host, ip, CONF_KLINE, aftype, user, NULL, 1); |
538 |
> |
killcnf = find_conf_by_address(host, addr, CONF_KLINE, user, NULL, 1); |
539 |
|
|
540 |
|
/* |
541 |
|
* If they are K-lined, return the K-line. Otherwise, return the |
554 |
|
* Side effects: None. |
555 |
|
*/ |
556 |
|
struct MaskItem * |
557 |
< |
find_dline_conf(const struct irc_ssaddr *addr, int aftype) |
557 |
> |
find_dline_conf(const struct irc_ssaddr *addr) |
558 |
|
{ |
559 |
|
struct MaskItem *eline; |
560 |
|
|
561 |
< |
eline = find_conf_by_address(NULL, addr, CONF_EXEMPT, aftype, NULL, NULL, 1); |
561 |
> |
eline = find_conf_by_address(NULL, addr, CONF_EXEMPT, NULL, NULL, 1); |
562 |
|
if (eline) |
563 |
|
return eline; |
564 |
|
|
565 |
< |
return find_conf_by_address(NULL, addr, CONF_DLINE, aftype, NULL, NULL, 1); |
565 |
> |
return find_conf_by_address(NULL, addr, CONF_DLINE, NULL, NULL, 1); |
566 |
|
} |
567 |
|
|
568 |
|
/* void add_conf_by_address(int, struct MaskItem *aconf) |
573 |
|
struct AddressRec * |
574 |
|
add_conf_by_address(const unsigned int type, struct MaskItem *conf) |
575 |
|
{ |
607 |
– |
struct AddressRec *arec = NULL; |
576 |
|
const char *const hostname = conf->host; |
577 |
|
const char *const username = conf->user; |
578 |
|
static unsigned int prec_value = UINT_MAX; |
580 |
|
|
581 |
|
assert(type && !EmptyString(hostname)); |
582 |
|
|
583 |
< |
arec = MyCalloc(sizeof(struct AddressRec)); |
583 |
> |
struct AddressRec *arec = xcalloc(sizeof(*arec)); |
584 |
|
arec->masktype = parse_netmask(hostname, &arec->Mask.ipa.addr, &bits); |
585 |
|
arec->Mask.ipa.bits = bits; |
586 |
|
arec->username = username; |
620 |
|
{ |
621 |
|
int bits = 0; |
622 |
|
uint32_t hv = 0; |
623 |
< |
dlink_node *node = NULL; |
623 |
> |
dlink_node *node; |
624 |
|
struct irc_ssaddr addr; |
625 |
|
|
626 |
|
switch (parse_netmask(address, &addr, &bits)) |
648 |
|
{ |
649 |
|
dlinkDelete(&arec->node, &atable[hv]); |
650 |
|
|
651 |
< |
if (!conf->ref_count) |
651 |
> |
if (conf->ref_count == 0) |
652 |
|
conf_free(conf); |
653 |
|
|
654 |
< |
MyFree(arec); |
654 |
> |
xfree(arec); |
655 |
|
return; |
656 |
|
} |
657 |
|
} |
667 |
|
void |
668 |
|
clear_out_address_conf(void) |
669 |
|
{ |
670 |
< |
dlink_node *node = NULL, *node_next = NULL; |
670 |
> |
dlink_node *node, *node_next; |
671 |
|
|
672 |
|
for (unsigned int i = 0; i < ATABLE_SIZE; ++i) |
673 |
|
{ |
682 |
|
continue; |
683 |
|
|
684 |
|
dlinkDelete(&arec->node, &atable[i]); |
685 |
< |
arec->conf->active = 0; |
685 |
> |
arec->conf->active = false; |
686 |
|
|
687 |
< |
if (!arec->conf->ref_count) |
687 |
> |
if (arec->conf->ref_count == 0) |
688 |
|
conf_free(arec->conf); |
689 |
< |
MyFree(arec); |
689 |
> |
xfree(arec); |
690 |
|
} |
691 |
|
} |
692 |
|
} |
694 |
|
static void |
695 |
|
hostmask_send_expiration(const struct AddressRec *const arec) |
696 |
|
{ |
697 |
< |
char ban_type = '\0'; |
730 |
< |
|
731 |
< |
if (!ConfigGeneral.tkline_expire_notices) |
732 |
< |
return; |
697 |
> |
char ban_type = '?'; |
698 |
|
|
699 |
|
switch (arec->type) |
700 |
|
{ |
707 |
|
default: break; |
708 |
|
} |
709 |
|
|
710 |
< |
sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE, |
710 |
> |
sendto_realops_flags(UMODE_EXPIRATION, L_ALL, SEND_NOTICE, |
711 |
|
"Temporary %c-line for [%s@%s] expired", ban_type, |
712 |
|
(arec->conf->user) ? arec->conf->user : "*", |
713 |
|
(arec->conf->host) ? arec->conf->host : "*"); |
716 |
|
void |
717 |
|
hostmask_expire_temporary(void) |
718 |
|
{ |
719 |
< |
dlink_node *node = NULL, *node_next = NULL; |
719 |
> |
dlink_node *node, *node_next; |
720 |
|
|
721 |
|
for (unsigned int i = 0; i < ATABLE_SIZE; ++i) |
722 |
|
{ |
724 |
|
{ |
725 |
|
struct AddressRec *arec = node->data; |
726 |
|
|
727 |
< |
if (!arec->conf->until || arec->conf->until > CurrentTime) |
727 |
> |
if (arec->conf->until == 0 || arec->conf->until > event_base->time.sec_real) |
728 |
|
continue; |
729 |
|
|
730 |
|
switch (arec->type) |
735 |
|
|
736 |
|
dlinkDelete(&arec->node, &atable[i]); |
737 |
|
conf_free(arec->conf); |
738 |
< |
MyFree(arec); |
738 |
> |
xfree(arec); |
739 |
|
break; |
740 |
|
default: break; |
741 |
|
} |