X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/4d23dfbcb5731bf38ff062b2c73219f001d7c291..6dec141a911f930cc9115a896484e3eb0f9ae2a8:/src/hostmask.c diff --git a/src/hostmask.c b/src/hostmask.c index 90208e0..7792993 100644 --- a/src/hostmask.c +++ b/src/hostmask.c @@ -5,7 +5,7 @@ * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center * Copyright (C) 1996-2002 Hybrid Development Team * Copyright (C) 2002-2005 ircd-ratbox development team - * Copyright (C) 2005-2006 charybdis development team + * Copyright (C) 2005-2008 charybdis development team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,25 +22,23 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: hostmask.c 2757 2006-11-10 22:58:15Z jilles $ */ #include "stdinc.h" -#include "memory.h" #include "ircd_defs.h" #include "s_conf.h" #include "hostmask.h" #include "numeric.h" #include "send.h" -#include "irc_string.h" +#include "match.h" -#ifdef IPV6 +#ifdef RB_IPV6 static unsigned long hash_ipv6(struct sockaddr *, int); #endif static unsigned long hash_ipv4(struct sockaddr *, int); -/* int parse_netmask(const char *, struct irc_sockaddr_storage *, 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), @@ -52,7 +50,7 @@ parse_netmask(const char *text, struct sockaddr *naddr, int *nb) { char *ip = LOCAL_COPY(text); char *ptr; - struct irc_sockaddr_storage *addr, xaddr; + struct rb_sockaddr_storage *addr, xaddr; int *b, xb; if(nb == NULL) b = &xb; @@ -60,11 +58,15 @@ parse_netmask(const char *text, struct sockaddr *naddr, int *nb) b = nb; if(naddr == NULL) - addr = (struct irc_sockaddr_storage *)&xaddr; + addr = (struct rb_sockaddr_storage *)&xaddr; else - addr = (struct irc_sockaddr_storage *)naddr; - -#ifdef IPV6 + addr = (struct rb_sockaddr_storage *)naddr; + + if(strpbrk(ip, "*?") != NULL) + { + return HM_HOST; + } +#ifdef RB_IPV6 if(strchr(ip, ':')) { if((ptr = strchr(ip, '/'))) @@ -76,7 +78,7 @@ parse_netmask(const char *text, struct sockaddr *naddr, int *nb) *b = 128; } else *b = 128; - if(inetpton_sock(ip, (struct sockaddr *)addr) > 0) + if(rb_inet_pton_sock(ip, (struct sockaddr *)addr) > 0) return HM_IPV6; else return HM_HOST; @@ -93,7 +95,7 @@ parse_netmask(const char *text, struct sockaddr *naddr, int *nb) *b = 32; } else *b = 32; - if(inetpton_sock(ip, (struct sockaddr *)addr) > 0) + if(rb_inet_pton_sock(ip, (struct sockaddr *)addr) > 0) return HM_IPV4; else return HM_HOST; @@ -110,7 +112,7 @@ init_host_hash(void) memset(&atable, 0, sizeof(atable)); } -/* unsigned long hash_ipv4(struct irc_sockaddr_storage*) +/* unsigned long hash_ipv4(struct rb_sockaddr_storage*) * Input: An IP address. * Output: A hash value of the IP address. * Side effects: None @@ -129,12 +131,12 @@ hash_ipv4(struct sockaddr *saddr, int bits) return 0; } -/* unsigned long hash_ipv6(struct irc_sockaddr_storage*) +/* unsigned long hash_ipv6(struct rb_sockaddr_storage*) * Input: An IP address. * Output: A hash value of the IP address. * Side effects: None */ -#ifdef IPV6 +#ifdef RB_IPV6 static unsigned long hash_ipv6(struct sockaddr *saddr, int bits) { @@ -197,7 +199,7 @@ get_mask_hash(const char *text) return hash_text(text); } -/* struct ConfItem* find_conf_by_address(const char*, struct irc_sockaddr_storage*, +/* struct ConfItem* find_conf_by_address(const char*, struct rb_sockaddr_storage*, * int type, int fam, const char *username) * Input: The hostname, the address, the type of mask to find, the address * family, the username. @@ -209,7 +211,7 @@ struct ConfItem * find_conf_by_address(const char *name, const char *sockhost, const char *orighost, struct sockaddr *addr, int type, int fam, - const char *username) + const char *username, const char *auth_user) { unsigned long hprecv = 0; struct ConfItem *hprec = NULL; @@ -222,7 +224,7 @@ find_conf_by_address(const char *name, const char *sockhost, if(addr) { /* Check for IPV6 matches... */ -#ifdef IPV6 +#ifdef RB_IPV6 if(fam == AF_INET6) { @@ -232,12 +234,11 @@ find_conf_by_address(const char *name, const char *sockhost, if(arec->type == (type & ~0x1) && arec->masktype == HM_IPV6 && comp_with_mask_sock(addr, (struct sockaddr *)&arec->Mask.ipa.addr, - arec->Mask.ipa.bits) && (type & 0x1 - || - match(arec-> - username, - username)) - && arec->precedence > hprecv) + arec->Mask.ipa.bits) && + (type & 0x1 || match(arec-> username, username)) && + (type != CONF_CLIENT || !arec->auth_user || + (auth_user && match(arec->auth_user, auth_user))) && + arec->precedence > hprecv) { hprecv = arec->precedence; hprec = arec->aconf; @@ -253,10 +254,12 @@ find_conf_by_address(const char *name, const char *sockhost, for (arec = atable[hash_ipv4(addr, b)]; arec; arec = arec->next) if(arec->type == (type & ~0x1) && arec->masktype == HM_IPV4 && - arec->precedence > hprecv && comp_with_mask_sock(addr, (struct sockaddr *)&arec->Mask.ipa.addr, arec->Mask.ipa.bits) && - (type & 0x1 || match(arec->username, username))) + (type & 0x1 || match(arec->username, username)) && + (type != CONF_CLIENT || !arec->auth_user || + (auth_user && match(arec->auth_user, auth_user))) && + arec->precedence > hprecv) { hprecv = arec->precedence; hprec = arec->aconf; @@ -277,6 +280,8 @@ find_conf_by_address(const char *name, const char *sockhost, (arec->masktype == HM_HOST) && arec->precedence > hprecv && match(arec->Mask.hostname, orighost) && + (type != CONF_CLIENT || !arec->auth_user || + (auth_user && match(arec->auth_user, auth_user))) && (type & 0x1 || match(arec->username, username))) { hprecv = arec->precedence; @@ -295,6 +300,8 @@ find_conf_by_address(const char *name, const char *sockhost, arec->precedence > hprecv && (match(arec->Mask.hostname, orighost) || (sockhost && match(arec->Mask.hostname, sockhost))) && + (type != CONF_CLIENT || !arec->auth_user || + (auth_user && match(arec->auth_user, auth_user))) && (type & 0x1 || match(arec->username, username))) { hprecv = arec->precedence; @@ -315,6 +322,8 @@ find_conf_by_address(const char *name, const char *sockhost, (arec->masktype == HM_HOST) && arec->precedence > hprecv && match(arec->Mask.hostname, name) && + (type != CONF_CLIENT || !arec->auth_user || + (auth_user && match(arec->auth_user, auth_user))) && (type & 0x1 || match(arec->username, username))) { hprecv = arec->precedence; @@ -333,6 +342,8 @@ find_conf_by_address(const char *name, const char *sockhost, arec->precedence > hprecv && (match(arec->Mask.hostname, name) || (sockhost && match(arec->Mask.hostname, sockhost))) && + (type != CONF_CLIENT || !arec->auth_user || + (auth_user && match(arec->auth_user, auth_user))) && (type & 0x1 || match(arec->username, username))) { hprecv = arec->precedence; @@ -344,20 +355,20 @@ find_conf_by_address(const char *name, const char *sockhost, } /* struct ConfItem* find_address_conf(const char*, const char*, - * struct irc_sockaddr_storage*, int); + * struct rb_sockaddr_storage*, int); * Input: The hostname, username, address, address family. * Output: The applicable ConfItem. * Side-effects: None */ struct ConfItem * find_address_conf(const char *host, const char *sockhost, const char *user, - const char *notildeuser, struct sockaddr *ip, int aftype) + const char *notildeuser, struct sockaddr *ip, int aftype, char *auth_user) { struct ConfItem *iconf, *kconf; const char *vuser; /* Find the best I-line... If none, return NULL -A1kmm */ - if(!(iconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_CLIENT, aftype, user))) + if(!(iconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_CLIENT, aftype, user, auth_user))) return NULL; /* Find what their visible username will be. * Note that the username without tilde may contain one char more. @@ -369,7 +380,7 @@ find_address_conf(const char *host, const char *sockhost, const char *user, return iconf; /* Find the best K-line... -A1kmm */ - kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_KILL, aftype, user); + 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) @@ -378,7 +389,7 @@ find_address_conf(const char *host, const char *sockhost, const char *user, /* if theres a spoof, check it against klines.. */ if(IsConfDoSpoofIp(iconf)) { - char *p = strchr(iconf->name, '@'); + char *p = strchr(iconf->info.name, '@'); /* note, we dont need to pass sockhost here, as its * guaranteed to not match by whats above.. --anfl @@ -386,11 +397,11 @@ find_address_conf(const char *host, const char *sockhost, const char *user, if(p) { *p = '\0'; - kconf = find_conf_by_address(p+1, NULL, NULL, ip, CONF_KILL, aftype, iconf->name); + kconf = find_conf_by_address(p+1, NULL, NULL, ip, CONF_KILL, aftype, iconf->info.name, NULL); *p = '@'; } else - kconf = find_conf_by_address(iconf->name, NULL, NULL, ip, CONF_KILL, aftype, vuser); + kconf = find_conf_by_address(iconf->info.name, NULL, NULL, ip, CONF_KILL, aftype, vuser, NULL); if(kconf) return kconf; @@ -400,24 +411,15 @@ find_address_conf(const char *host, const char *sockhost, const char *user, * -- jilles */ if(user != vuser) { - kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_KILL, aftype, vuser); + kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_KILL, aftype, vuser, NULL); if(kconf) return kconf; } - /* hunt for a gline */ - if(ConfigFileEntry.glines) - { - kconf = find_conf_by_address(host, sockhost, NULL, ip, CONF_GLINE, aftype, user); - - if((kconf != NULL) && !IsConfExemptGline(iconf)) - return kconf; - } - return iconf; } -/* struct ConfItem* find_dline(struct irc_sockaddr_storage*, int) +/* struct ConfItem* find_dline(struct rb_sockaddr_storage*, int) * Input: An address, an address family. * Output: The best matching D-line or exempt line. * Side effects: None. @@ -426,10 +428,10 @@ struct ConfItem * find_dline(struct sockaddr *addr, int aftype) { struct ConfItem *eline; - eline = find_conf_by_address(NULL, NULL, NULL, addr, CONF_EXEMPTDLINE | 1, aftype, NULL); + eline = find_conf_by_address(NULL, NULL, NULL, addr, CONF_EXEMPTDLINE | 1, aftype, NULL, NULL); if(eline) return eline; - return find_conf_by_address(NULL, NULL, NULL, addr, CONF_DLINE | 1, aftype, NULL); + return find_conf_by_address(NULL, NULL, NULL, addr, CONF_DLINE | 1, aftype, NULL, NULL); } /* void find_exact_conf_by_address(const char*, int, const char *) @@ -443,13 +445,12 @@ find_exact_conf_by_address(const char *address, int type, const char *username) int masktype, bits; unsigned long hv; struct AddressRec *arec; - struct irc_sockaddr_storage addr; + struct rb_sockaddr_storage addr; if(address == NULL) address = "/NOMATCH!/"; - arec = MyMalloc(sizeof(struct AddressRec)); masktype = parse_netmask(address, (struct sockaddr *)&addr, &bits); -#ifdef IPV6 +#ifdef RB_IPV6 if(masktype == HM_IPV6) { /* We have to do this, since we do not re-hash for every bit -A1kmm. */ @@ -495,7 +496,7 @@ find_exact_conf_by_address(const char *address, int type, const char *username) * Side-effects: Adds this entry to the hash table. */ void -add_conf_by_address(const char *address, int type, const char *username, struct ConfItem *aconf) +add_conf_by_address(const char *address, int type, const char *username, const char *auth_user, struct ConfItem *aconf) { static unsigned long prec_value = 0xFFFFFFFF; int masktype, bits; @@ -504,11 +505,11 @@ add_conf_by_address(const char *address, int type, const char *username, struct if(address == NULL) address = "/NOMATCH!/"; - arec = MyMalloc(sizeof(struct AddressRec)); + arec = rb_malloc(sizeof(struct AddressRec)); masktype = parse_netmask(address, (struct sockaddr *)&arec->Mask.ipa.addr, &bits); arec->Mask.ipa.bits = bits; arec->masktype = masktype; -#ifdef IPV6 +#ifdef RB_IPV6 if(masktype == HM_IPV6) { /* We have to do this, since we do not re-hash for every bit -A1kmm. */ @@ -532,6 +533,7 @@ add_conf_by_address(const char *address, int type, const char *username, struct atable[hv] = arec; } arec->username = username; + arec->auth_user = auth_user; arec->aconf = aconf; arec->precedence = prec_value--; arec->type = type; @@ -549,9 +551,9 @@ delete_one_address_conf(const char *address, struct ConfItem *aconf) int masktype, bits; unsigned long hv; struct AddressRec *arec, *arecl = NULL; - struct irc_sockaddr_storage addr; + struct rb_sockaddr_storage addr; masktype = parse_netmask(address, (struct sockaddr *)&addr, &bits); -#ifdef IPV6 +#ifdef RB_IPV6 if(masktype == HM_IPV6) { /* We have to do this, since we do not re-hash for every bit -A1kmm. */ @@ -579,7 +581,7 @@ delete_one_address_conf(const char *address, struct ConfItem *aconf) aconf->status |= CONF_ILLEGAL; if(!aconf->clients) free_conf(aconf); - MyFree(arec); + rb_free(arec); return; } arecl = arec; @@ -619,7 +621,7 @@ clear_out_address_conf(void) arec->aconf->status |= CONF_ILLEGAL; if(!arec->aconf->clients) free_conf(arec->aconf); - MyFree(arec); + rb_free(arec); } } *store_next = NULL; @@ -652,7 +654,7 @@ clear_out_address_conf_bans(void) arec->aconf->status |= CONF_ILLEGAL; if(!arec->aconf->clients) free_conf(arec->aconf); - MyFree(arec); + rb_free(arec); } } *store_next = NULL; @@ -682,12 +684,14 @@ show_iline_prefix(struct Client *sptr, struct ConfItem *aconf, char *name) *prefix_ptr++ = '+'; if(IsConfDoSpoofIp(aconf)) *prefix_ptr++ = '='; - if(MyOper(sptr) && IsConfExemptKline(aconf)) + if(IsOper(sptr) && IsConfExemptFlood(aconf)) + *prefix_ptr++ = '|'; + if(IsOper(sptr) && IsConfExemptDNSBL(aconf) && !IsConfExemptKline(aconf)) + *prefix_ptr++ = '$'; + if(IsOper(sptr) && IsConfExemptKline(aconf)) *prefix_ptr++ = '^'; - if(MyOper(sptr) && IsConfExemptLimits(aconf)) + if(IsOper(sptr) && IsConfExemptLimits(aconf)) *prefix_ptr++ = '>'; - if(MyOper(sptr) && IsConfIdlelined(aconf)) - *prefix_ptr++ = '<'; *prefix_ptr = '\0'; strncpy(prefix_ptr, name, USERLEN); return (prefix_of_host); @@ -713,15 +717,18 @@ report_auth(struct Client *client_p) { aconf = arec->aconf; - if(!MyOper(client_p) && IsConfDoSpoofIp(aconf)) + if(!IsOper(client_p) && IsConfDoSpoofIp(aconf)) continue; get_printable_conf(aconf, &name, &host, &pass, &user, &port, &classname); + + if(!EmptyString(aconf->spasswd)) + pass = aconf->spasswd; sendto_one_numeric(client_p, RPL_STATSILINE, form_str(RPL_STATSILINE), - name, show_iline_prefix(client_p, aconf, user), + name, pass, show_iline_prefix(client_p, aconf, user), show_ip_conf(aconf, client_p) ? host : "255.255.255.255", port, classname); }