X-Git-Url: https://jfr.im/git/solanum.git/blobdiff_plain/60445f51d0a83379e7a77b04cec9f6dc46652b87..8efff56fdf9f4ce4a3968c74162fed9d8d45c51a:/ircd/hostmask.c diff --git a/ircd/hostmask.c b/ircd/hostmask.c index 580a3509..1a154130 100644 --- a/ircd/hostmask.c +++ b/ircd/hostmask.c @@ -1,5 +1,5 @@ /* - * charybdis: an advanced internet relay chat daemon (ircd). + * Solanum: a slightly advanced ircd * hostmask.c: Code to efficiently find IP & hostmask based configs. * * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center @@ -26,6 +26,7 @@ #include "stdinc.h" #include "ircd_defs.h" #include "s_conf.h" +#include "s_newconf.h" #include "hostmask.h" #include "numeric.h" #include "send.h" @@ -35,18 +36,12 @@ static unsigned long hash_ipv6(struct sockaddr *, int); static unsigned long hash_ipv4(struct sockaddr *, int); -/* int parse_netmask(const char *, struct rb_sockaddr_storage *, int *); - * Input: A hostmask, or an IPV4/6 address. - * Output: An integer describing whether it is an IPV4, IPV6 address or a - * hostmask, an address(if it is an IP mask), - * a bitlength(if it is IP mask). - * Side effects: None - */ -int -parse_netmask(const char *text, struct rb_sockaddr_storage *naddr, int *nb) +static int +_parse_netmask(const char *text, struct rb_sockaddr_storage *naddr, int *nb, bool strict) { char *ip = LOCAL_COPY(text); char *ptr; + char *endp; struct rb_sockaddr_storage *addr, xaddr; int *b, xb; if(nb == NULL) @@ -69,11 +64,17 @@ parse_netmask(const char *text, struct rb_sockaddr_storage *naddr, int *nb) { *ptr = '\0'; ptr++; - *b = atoi(ptr); - if(*b > 128) - *b = 128; - else if(*b < 0) + long n = strtol(ptr, &endp, 10); + if (endp == ptr || n < 0) return HM_HOST; + if (n > 128 || *endp != '\0') + { + if (strict) + return HM_ERROR; + else + n = 128; + } + *b = n; } else *b = 128; if(rb_inet_pton_sock(ip, addr) > 0) @@ -87,11 +88,17 @@ parse_netmask(const char *text, struct rb_sockaddr_storage *naddr, int *nb) { *ptr = '\0'; ptr++; - *b = atoi(ptr); - if(*b > 32) - *b = 32; - else if(*b < 0) + long n = strtol(ptr, &endp, 10); + if (endp == ptr || n < 0) return HM_HOST; + if (n > 32 || *endp != '\0') + { + if (strict) + return HM_ERROR; + else + n = 32; + } + *b = n; } else *b = 32; if(rb_inet_pton_sock(ip, addr) > 0) @@ -102,6 +109,23 @@ parse_netmask(const char *text, struct rb_sockaddr_storage *naddr, int *nb) return HM_HOST; } +/* int parse_netmask(const char *, struct rb_sockaddr_storage *, int *); + * Input: A hostmask, or an IPV4/6 address. + * Output: An integer describing whether it is an IPV4, IPV6 address or a + * hostmask, an address(if it is an IP mask), + * a bitlength(if it is IP mask). + * Side effects: None + */ +int parse_netmask(const char *mask, struct rb_sockaddr_storage *addr, int *blen) +{ + return _parse_netmask(mask, addr, blen, false); +} + +int parse_netmask_strict(const char *mask, struct rb_sockaddr_storage *addr, int *blen) +{ + return _parse_netmask(mask, addr, blen, true); +} + /* Hashtable stuff...now external as its used in m_stats.c */ struct AddressRec *atable[ATABLE_SIZE]; @@ -383,34 +407,38 @@ find_address_conf(const char *host, const char *sockhost, const char *user, if(IsConfExemptKline(iconf)) return iconf; - /* Find the best K-line... -A1kmm */ - kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_KILL, aftype, user, NULL); - - /* If they are K-lined, return the K-line */ - if(kconf) - return kconf; - /* if theres a spoof, check it against klines.. */ if(IsConfDoSpoofIp(iconf)) { char *p = strchr(iconf->info.name, '@'); /* note, we dont need to pass sockhost here, as its - * guaranteed to not match by whats above.. --anfl + * guaranteed to not match by whats below.. --anfl */ if(p) { *p = '\0'; - kconf = find_conf_by_address(p+1, NULL, NULL, ip, CONF_KILL, aftype, iconf->info.name, NULL); + kconf = find_conf_by_address(p+1, NULL, NULL, NULL, CONF_KILL, aftype, iconf->info.name, NULL); *p = '@'; } else - kconf = find_conf_by_address(iconf->info.name, NULL, NULL, ip, CONF_KILL, aftype, vuser, NULL); + kconf = find_conf_by_address(iconf->info.name, NULL, NULL, NULL, CONF_KILL, aftype, vuser, NULL); if(kconf) return kconf; + + /* everything else checks real hosts, if they're kline_spoof_ip we're done */ + if(IsConfKlineSpoof(iconf)) + return iconf; } + /* Find the best K-line... -A1kmm */ + kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_KILL, aftype, user, NULL); + + /* If they are K-lined, return the K-line */ + if(kconf) + return kconf; + /* if no_tilde, check the username without tilde against klines too * -- jilles */ if(user != vuser) @@ -603,7 +631,7 @@ delete_one_address_conf(const char *address, struct ConfItem *aconf) * them, otherwise sets them as illegal. */ void -clear_out_address_conf(void) +clear_out_address_conf(enum aconf_category clear_type) { int i; struct AddressRec **store_next; @@ -614,44 +642,17 @@ clear_out_address_conf(void) store_next = &atable[i]; for (arec = atable[i]; arec; arec = arecn) { + enum aconf_category cur_type; arecn = arec->next; - /* We keep the temporary K-lines and destroy the - * permanent ones, just to be confusing :) -A1kmm */ - if(arec->aconf->flags & CONF_FLAGS_TEMPORARY || - (arec->type != CONF_CLIENT && arec->type != CONF_EXEMPTDLINE)) - { - *store_next = arec; - store_next = &arec->next; - } - else - { - arec->aconf->status |= CONF_ILLEGAL; - if(!arec->aconf->clients) - free_conf(arec->aconf); - rb_free(arec); - } - } - *store_next = NULL; - } -} -void -clear_out_address_conf_bans(void) -{ - int i; - struct AddressRec **store_next; - struct AddressRec *arec, *arecn; + if (arec->type == CONF_CLIENT || arec->type == CONF_EXEMPTDLINE || arec->type == CONF_SECURE) + cur_type = AC_CONFIG; + else + cur_type = AC_BANDB; - for (i = 0; i < ATABLE_SIZE; i++) - { - store_next = &atable[i]; - for (arec = atable[i]; arec; arec = arecn) - { - arecn = arec->next; /* We keep the temporary K-lines and destroy the * permanent ones, just to be confusing :) -A1kmm */ - if(arec->aconf->flags & CONF_FLAGS_TEMPORARY || - (arec->type == CONF_CLIENT || arec->type == CONF_EXEMPTDLINE)) + if (arec->aconf->flags & CONF_FLAGS_TEMPORARY || cur_type != clear_type) { *store_next = arec; store_next = &arec->next; @@ -668,7 +669,6 @@ clear_out_address_conf_bans(void) } } - /* * show_iline_prefix() * @@ -725,7 +725,7 @@ report_auth(struct Client *client_p) { aconf = arec->aconf; - if(!IsOper(client_p) && IsConfDoSpoofIp(aconf)) + if(!IsOperGeneral(client_p) && IsConfDoSpoofIp(aconf)) continue; get_printable_conf(aconf, &name, &host, &pass, &user, &port,