--- ircd-hybrid-8/src/hostmask.c 2012/02/26 15:28:14 1297 +++ ircd-hybrid-8/src/hostmask.c 2012/02/28 18:51:13 1298 @@ -46,7 +46,7 @@ static unsigned long hash_ipv4(struct ir ch = ch - 'A' + 10; \ else if (ch >= 'a' && ch <= 'f') \ ch = ch - 'a' + 10; \ - } while(0); + } while (0); /* The mask parser/type determination code... */ @@ -74,7 +74,7 @@ try_parse_v6_netmask(const char *text, s int bits = 128; int deficit = 0; short dc[8]; - struct sockaddr_in6 *v6 = (struct sockaddr_in6*) addr; + struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr; for (p = text; (c = *p); p++) if (IsXDigit(c)) @@ -116,6 +116,7 @@ try_parse_v6_netmask(const char *text, s d[dp] = d[dp] >> 4 * nyble; dp++; bits = strtoul(p + 1, &after, 10); + if (bits < 0 || *after) return HM_HOST; if (bits > dp * 4 && !(finsert >= 0 && bits <= 128)) @@ -126,12 +127,15 @@ try_parse_v6_netmask(const char *text, s return HM_HOST; d[dp] = d[dp] >> 4 * nyble; + if (c == 0) dp++; if (finsert < 0 && bits == 0) bits = dp * 16; + /* How many words are missing? -A1kmm */ deficit = bits / 16 + ((bits % 16) ? 1 : 0) - dp; + /* Now fill in the gaps(from ::) in the copied table... -A1kmm */ for (dp = 0, nyble = 0; dp < 8; dp++) { @@ -143,16 +147,19 @@ try_parse_v6_netmask(const char *text, s else dc[dp] = d[nyble++]; } + /* Set unused bits to 0... -A1kmm */ if (bits < 128 && (bits % 16 != 0)) dc[bits / 16] &= ~((1 << (15 - bits % 16)) - 1); for (dp = bits / 16 + (bits % 16 ? 1 : 0); dp < 8; dp++) dc[dp] = 0; + /* And assign... -A1kmm */ if (addr) for (dp = 0; dp < 8; dp++) /* The cast is a kludge to make netbsd work. */ ((unsigned short *)&v6->sin6_addr)[dp] = htons(dc[dp]); + if (b != NULL) *b = bits; return HM_IPV6; @@ -174,7 +181,7 @@ try_parse_v4_netmask(const char *text, s unsigned char addb[4]; int n = 0, bits = 0; char c; - struct sockaddr_in *v4 = (struct sockaddr_in*) addr; + struct sockaddr_in *v4 = (struct sockaddr_in *)addr; digits[n++] = text; @@ -185,12 +192,14 @@ try_parse_v4_netmask(const char *text, s { if (n >= 4) return HM_HOST; + digits[n++] = p + 1; } else if (c == '*') { if (*(p + 1) || n == 0 || *(p - 1) != '.') return HM_HOST; + bits = (n - 1) * 8; break; } @@ -198,10 +207,12 @@ try_parse_v4_netmask(const char *text, s { char *after; bits = strtoul(p + 1, &after, 10); + if (!bits || *after) return HM_HOST; if (bits > n * 8) return HM_HOST; + break; } else @@ -212,10 +223,13 @@ try_parse_v4_netmask(const char *text, s if (bits) while (n < 4) digits[n++] = "0"; + for (n = 0; n < 4; n++) addb[n] = strtoul(digits[n], NULL, 10); + if (bits == 0) bits = 32; + /* Set unused bits to 0... -A1kmm */ if (bits < 32 && bits % 8) addb[bits / 8] &= ~((1 << (8 - bits % 8)) - 1); @@ -240,7 +254,7 @@ int parse_netmask(const char *text, struct irc_ssaddr *addr, int *b) { #ifdef IPV6 - if (strchr(text, ':')) + if (strchr(text, ':')) return try_parse_v6_netmask(text, addr, b); #endif if (strchr(text, '.')) @@ -259,8 +273,8 @@ int match_ipv6(struct irc_ssaddr *addr, struct irc_ssaddr *mask, int bits) { int i, m, n = bits / 8; - struct sockaddr_in6 *v6 = (struct sockaddr_in6*)addr; - struct sockaddr_in6 *v6mask = (struct sockaddr_in6*)mask; + struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr; + struct sockaddr_in6 *v6mask = (struct sockaddr_in6 *)mask; for (i = 0; i < n; i++) if (v6->sin6_addr.s6_addr[i] != v6mask->sin6_addr.s6_addr[i]) @@ -281,8 +295,9 @@ match_ipv6(struct irc_ssaddr *addr, stru int match_ipv4(struct irc_ssaddr *addr, struct irc_ssaddr *mask, int bits) { - struct sockaddr_in *v4 = (struct sockaddr_in*) addr; - struct sockaddr_in *v4mask = (struct sockaddr_in*) mask; + struct sockaddr_in *v4 = (struct sockaddr_in *)addr; + struct sockaddr_in *v4mask = (struct sockaddr_in *)mask; + if ((ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1)) != ntohl(v4mask->sin_addr.s_addr)) return 0; @@ -311,20 +326,21 @@ mask_addr(struct irc_ssaddr *ip, int bit if (ip->ss.ss_family != AF_INET6) #endif { - v4_base_ip = (struct sockaddr_in*)ip; + v4_base_ip = (struct sockaddr_in *)ip; + mask = ~((1 << (32 - bits)) - 1); - v4_base_ip->sin_addr.s_addr = - htonl(ntohl(v4_base_ip->sin_addr.s_addr) & mask); + v4_base_ip->sin_addr.s_addr = htonl(ntohl(v4_base_ip->sin_addr.s_addr) & mask); } #ifdef IPV6 else { n = bits / 8; m = bits % 8; - v6_base_ip = (struct sockaddr_in6*)ip; + v6_base_ip = (struct sockaddr_in6 *)ip; mask = ~((1 << (8 - m)) -1 ); v6_base_ip->sin6_addr.s6_addr[n] = v6_base_ip->sin6_addr.s6_addr[n] & mask; + for (i = n + 1; i < 16; i++) v6_base_ip->sin6_addr.s6_addr[i] = 0; } @@ -352,10 +368,11 @@ hash_ipv4(struct irc_ssaddr *addr, int b { struct sockaddr_in *v4 = (struct sockaddr_in *)addr; unsigned long av = ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1); - return((av ^ (av >> 12) ^ (av >> 24)) & (ATABLE_SIZE - 1)); + + return (av ^ (av >> 12) ^ (av >> 24)) & (ATABLE_SIZE - 1); } - return(0); + return 0; } /* unsigned long hash_ipv6(struct irc_ssaddr*) @@ -368,8 +385,8 @@ static unsigned long hash_ipv6(struct irc_ssaddr *addr, int bits) { unsigned long v = 0, n; - struct sockaddr_in6 *v6 = (struct sockaddr_in6*) addr; - + struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr; + for (n = 0; n < 16; n++) { if (bits >= 8) @@ -401,10 +418,9 @@ hash_text(const char *start) unsigned long h = 0; while (*p) - { h = (h << 4) - (h + (unsigned char)ToLower(*p++)); - } - return (h & (ATABLE_SIZE - 1)); + + return h & (ATABLE_SIZE - 1); } /* unsigned long get_hash_mask(const char *) @@ -551,11 +567,11 @@ find_address_conf(const char *host, cons /* Find the best I-line... If none, return NULL -A1kmm */ if ((iconf = find_conf_by_address(host, ip, CONF_CLIENT, aftype, user, password)) == NULL) - return(NULL); + return NULL; /* If they are exempt from K-lines, return the best I-line. -A1kmm */ if (IsConfExemptKline(iconf)) - return(iconf); + return iconf; /* Find the best K-line... -A1kmm */ kconf = find_conf_by_address(host, ip, CONF_KILL, aftype, user, NULL); @@ -563,13 +579,13 @@ find_address_conf(const char *host, cons /* If they are K-lined, return the K-line. Otherwise, return the * I-line. -A1kmm */ if (kconf != NULL) - return(kconf); + return kconf; kconf = find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL); if (kconf != NULL && !IsConfExemptGline(iconf)) - return(kconf); + return kconf; - return(iconf); + return iconf; } struct AccessItem * @@ -581,9 +597,9 @@ find_gline_conf(const char *host, const eline = find_conf_by_address(host, ip, CONF_EXEMPTKLINE, aftype, user, NULL); if (eline != NULL) - return(eline); + return eline; - return(find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL)); + return find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL); } /* find_kline_conf @@ -596,16 +612,16 @@ find_gline_conf(const char *host, const */ struct AccessItem * find_kline_conf(const char *host, const char *user, - struct irc_ssaddr *ip, int aftype) + struct irc_ssaddr *ip, int aftype) { struct AccessItem *eline; eline = find_conf_by_address(host, ip, CONF_EXEMPTKLINE, aftype, user, NULL); if (eline != NULL) - return(eline); + return eline; - return(find_conf_by_address(host, ip, CONF_KILL, aftype, user, NULL)); + return find_conf_by_address(host, ip, CONF_KILL, aftype, user, NULL); } /* struct AccessItem* find_dline_conf(struct irc_ssaddr*, int) @@ -622,8 +638,9 @@ find_dline_conf(struct irc_ssaddr *addr, eline = find_conf_by_address(NULL, addr, CONF_EXEMPTDLINE | 1, aftype, NULL, NULL); if (eline != NULL) - return(eline); - return(find_conf_by_address(NULL, addr, CONF_DLINE | 1, aftype, NULL, NULL)); + return eline; + + return find_conf_by_address(NULL, addr, CONF_DLINE | 1, aftype, NULL, NULL); } /* void add_conf_by_address(int, struct AccessItem *aconf) @@ -654,6 +671,7 @@ add_conf_by_address(int type, struct Acc masktype = parse_netmask(address, &arec->Mask.ipa.addr, &bits); arec->Mask.ipa.bits = bits; arec->masktype = masktype; + #ifdef IPV6 if (masktype == HM_IPV6) { @@ -677,6 +695,7 @@ add_conf_by_address(int type, struct Acc arec->next = atable[(hv = get_mask_hash(address))]; atable[hv] = arec; } + arec->username = username; arec->aconf = aconf; arec->precedence = prec_value--; @@ -696,6 +715,7 @@ delete_one_address_conf(const char *addr unsigned long hv; struct AddressRec *arec, *arecl = NULL; struct irc_ssaddr addr; + masktype = parse_netmask(address, &addr, &bits); #ifdef IPV6 @@ -715,6 +735,7 @@ delete_one_address_conf(const char *addr } else hv = get_mask_hash(address); + for (arec = atable[hv]; arec; arec = arec->next) { if (arec->aconf == aconf) @@ -723,9 +744,12 @@ delete_one_address_conf(const char *addr arecl->next = arec->next; else atable[hv] = arec->next; + aconf->status |= CONF_ILLEGAL; + if (aconf->clients == 0) free_access_item(aconf); + MyFree(arec); return; } @@ -751,6 +775,7 @@ clear_out_address_conf(void) for (i = 0; i < ATABLE_SIZE; i++) { last_arec = NULL; + for (arec = atable[i]; arec; arec = next_arec) { /* We keep the temporary K-lines and destroy the @@ -776,6 +801,7 @@ clear_out_address_conf(void) } arec->aconf->status |= CONF_ILLEGAL; + if (arec->aconf->clients == 0) free_access_item(arec->aconf); MyFree(arec); @@ -797,9 +823,8 @@ char * show_iline_prefix(struct Client *sptr, struct AccessItem *aconf, const char *name) { static char prefix_of_host[USERLEN + 14]; - char *prefix_ptr; + char *prefix_ptr = prefix_of_host; - prefix_ptr = prefix_of_host; if (IsNoTilde(aconf)) *prefix_ptr++ = '-'; if (IsLimitIp(aconf)) @@ -822,9 +847,10 @@ show_iline_prefix(struct Client *sptr, s *prefix_ptr++ = '>'; if (IsConfCanFlood(aconf)) *prefix_ptr++ = '|'; + strlcpy(prefix_ptr, name, USERLEN+1); - return(prefix_of_host); + return prefix_of_host; } /* report_auth() @@ -908,14 +934,14 @@ report_Klines(struct Client *client_p, i (!tkline && ((aconf = arec->aconf)->flags & CONF_FLAGS_TEMPORARY))) continue; - if (HasUMode(client_p, UMODE_OPER)) - sendto_one(client_p, form_str(RPL_STATSKLINE), me.name, + if (HasUMode(client_p, UMODE_OPER)) + sendto_one(client_p, form_str(RPL_STATSKLINE), me.name, client_p->name, p, aconf->host, aconf->user, - aconf->reason, aconf->oper_reason ? aconf->oper_reason : ""); - else + aconf->reason, aconf->oper_reason ? aconf->oper_reason : ""); + else sendto_one(client_p, form_str(RPL_STATSKLINE), me.name, client_p->name, p, aconf->host, aconf->user, - aconf->reason, ""); + aconf->reason, ""); } } }