diff --git a/common/match.c b/common/match.c index 2f154f06..706cbfe6 100644 --- a/common/match.c +++ b/common/match.c @@ -363,3 +363,63 @@ int isvalidusername(char *username) return 1; } +/* + * Match an IP against a subnet (10.11.12.128/27, fdf0:584f:e66b::/48). + */ +int match_ipmask(char *mask, char *ip) +{ + int m, j; + u_long lmask; + char *p, dummy[128]; + struct IN_ADDR mask_addr, ip_addr; + + if (inetpton(AF_INET6, ip, (void *) ip_addr.s6_addr) != 1) + return -1; + + strncpyzt(dummy, mask, sizeof(dummy)); + mask = dummy; + + if (!(p = index(mask, '/'))) + return -1; + + *p = '\0'; + + if (sscanf(p + 1, "%d", &m) != 1) + return -1; + + if (!m) + return 0; /* x.x.x.x/0 always matches */ + + if (m < 0 || m > 128) + return -1; + + if (inetpton(AF_INET6, mask, (void *) mask_addr.s6_addr) != 1) + return -1; + + /* Make sure that the ipv4 notation still works. */ + if (IN6_IS_ADDR_V4MAPPED(&mask_addr)) + { + if (m <= 32) + m += 96; + if (m <= 96) + return -1; + } + + j = m & 0x1F; /* number not multiple of 32 bits */ + m >>= 5; /* number of 32 bits */ + + if (m && memcmp((void *) (mask_addr.s6_addr), + (void *) (ip_addr.s6_addr), m << 2)) + return 1; + + if (j) + { + lmask = htonl((u_long) 0xffffffffL << (32 - j)); + if ((((u_int32_t *) (mask_addr.s6_addr))[m] ^ + ((u_int32_t *) (ip_addr.s6_addr))[m]) & + lmask) + return 1; + } + + return 0; +} \ No newline at end of file diff --git a/common/match_ext.h b/common/match_ext.h index 749ef87c..9b7ffeb7 100644 --- a/common/match_ext.h +++ b/common/match_ext.h @@ -41,4 +41,5 @@ EXTERN char *collapse (char *pattern); EXTERN int mycmp (char *s1, char *s2); EXTERN int myncmp (char *str1, char *str2, int n); EXTERN int isvalidusername (char *username); +EXTERN int match_ipmask(char *mask, char *ip); #undef EXTERN diff --git a/iauth/a_conf.c b/iauth/a_conf.c index b916b34e..6290f2c3 100644 --- a/iauth/a_conf.c +++ b/iauth/a_conf.c @@ -45,67 +45,6 @@ static void conf_err(u_int nb, char *msg, char *chk) exit(1); } -/* - * Match address by #IP bitmask (10.11.12.128/27) - */ -static int match_ipmask(char *mask, char *ip) -{ - int m, j; - u_long lmask; - char *p, dummy[128]; - struct IN_ADDR mask_addr, ip_addr; - - if (inetpton(AF_INET6, ip, (void *) ip_addr.s6_addr) != 1) - return -1; - - strncpyzt(dummy, mask, sizeof(dummy)); - mask = dummy; - - if (!(p = index(mask, '/'))) - return -1; - - *p = '\0'; - - if (sscanf(p + 1, "%d", &m) != 1) - return -1; - - if (!m) - return 0; /* x.x.x.x/0 always matches */ - - if (m < 0 || m > 128) - return -1; - - if (inetpton(AF_INET6, mask, (void *) mask_addr.s6_addr) != 1) - return -1; - - /* Make sure that the ipv4 notation still works. */ - if (IN6_IS_ADDR_V4MAPPED(&mask_addr)) - { - if (m <= 32) - m += 96; - if (m <= 96) - return -1; - } - - j = m & 0x1F; /* number not multiple of 32 bits */ - m >>= 5; /* number of 32 bits */ - - if (m && memcmp((void *) (mask_addr.s6_addr), - (void *) (ip_addr.s6_addr), m << 2)) - return 1; - - if (j) - { - lmask = htonl((u_long) 0xffffffffL << (32 - j)); - if ((((u_int32_t *) (mask_addr.s6_addr))[m] ^ - ((u_int32_t *) (ip_addr.s6_addr))[m]) & - lmask) - return 1; - } - - return 0; -} - /* conf_read: read the configuration file, instanciate modules */ char *conf_read(char *cfile) { diff --git a/ircd/channel.c b/ircd/channel.c index 2f2ab9c4..cbc96dde 100644 --- a/ircd/channel.c +++ b/ircd/channel.c @@ -389,7 +389,7 @@ static Link *match_modeid(int type, aClient *cptr, aChannel *chptr) } /* so now we check CIDR */ if (strchr(tmp->value.alist->host, '/') && - match_ipmask(tmp->value.alist->host, cptr, 0) == 0) + match_ipmask_client(tmp->value.alist->host, cptr, 0) == 0) { break; } diff --git a/ircd/s_conf.c b/ircd/s_conf.c index 22258a91..b037ec7b 100644 --- a/ircd/s_conf.c +++ b/ircd/s_conf.c @@ -450,7 +450,7 @@ void det_confs_butmask(aClient *cptr, int mask) * Now should work for IPv6 too. * returns -1 on error, 0 on match, 1 when NO match. */ -int match_ipmask(char *mask, aClient *cptr, int maskwithusername) +int match_ipmask_client(char *mask, aClient *cptr, int maskwithusername) { int m; char *p; @@ -623,9 +623,9 @@ int attach_Iline(aClient *cptr, struct hostent *hp, char *sockhost) if (strchr(aconf->host, '/')) /* 1.2.3.0/24 */ { - /* match_ipmask takes care of checking + /* match_ipmask_client takes care of checking ** possible username if aconf->host has '@' */ - if (match_ipmask(aconf->host, cptr, 1)) + if (match_ipmask_client(aconf->host, cptr, 1)) { /* Try another I:line. */ continue; @@ -1137,7 +1137,7 @@ aConfItem *find_Oline(char *name, aClient *cptr) */ if (match(tmp->host, userhost) && match(tmp->host, userip) && (!strchr(tmp->host, '/') - || match_ipmask(tmp->host, cptr, 1))) + || match_ipmask_client(tmp->host, cptr, 1))) continue; if (tmp->clients < MaxLinks(Class(tmp))) return tmp; @@ -2318,7 +2318,7 @@ int find_kill(aClient *cptr, int timedklines, char **comment) { if (strchr(tmp->host, '/')) { - if (match_ipmask((*tmp->host == '=') ? + if (match_ipmask_client((*tmp->host == '=') ? tmp->host+1: tmp->host, cptr, 1)) continue; } @@ -2332,7 +2332,7 @@ int find_kill(aClient *cptr, int timedklines, char **comment) else /* resolved */ if (strchr(tmp->host, '/')) { - if (match_ipmask(tmp->host, cptr, 1)) + if (match_ipmask_client(tmp->host, cptr, 1)) continue; } else @@ -2555,7 +2555,7 @@ void find_bounce(aClient *cptr, int class, int fd) { if (strchr(aconf->host, '/')) { - if (match_ipmask(aconf->host, cptr, 1)) + if (match_ipmask_client(aconf->host, cptr, 1)) continue; } else if (match(aconf->host, cptr->sockhost)) @@ -2771,7 +2771,7 @@ void do_kline(int tkline, char *who, time_t time, char *user, char *host, char * /* unresolved */ if (strchr(aconf->host, '/')) { - if (match_ipmask(*aconf->host == '=' ? + if (match_ipmask_client(*aconf->host == '=' ? aconf->host + 1 : aconf->host, acptr, 1)) { @@ -2798,7 +2798,7 @@ void do_kline(int tkline, char *who, time_t time, char *user, char *host, char * } if (strchr(aconf->host, '/')) { - if (match_ipmask(aconf->host, acptr, 1)) + if (match_ipmask_client(aconf->host, acptr, 1)) { continue; } @@ -2903,7 +2903,7 @@ int prep_kline(int tkline, aClient *cptr, aClient *sptr, int parc, char **parv) /* disallow all forms of bad u@h format and block *@* without flags too */ err = 1; } - if (!err && host && strchr(host, '/') && match_ipmask(host, sptr, 0) == -1) + if (!err && host && strchr(host, '/') && match_ipmask_client(host, sptr, 0) == -1) { /* check validity of 1.2.3.0/24 or it will be spewing errors ** for every connecting client. */ diff --git a/ircd/s_conf_ext.h b/ircd/s_conf_ext.h index 0b8c3c6f..d96f5714 100644 --- a/ircd/s_conf_ext.h +++ b/ircd/s_conf_ext.h @@ -39,8 +39,7 @@ extern char *networkname; #define EXTERN #endif /* S_CONF_C */ EXTERN void det_confs_butmask (aClient *cptr, int mask); -EXTERN int match_ipmask (char *mask, aClient *cptr, - int maskwithusername); +EXTERN int match_ipmask_client (char *mask, aClient *cptr, int maskwithusername); EXTERN int attach_Iline (aClient *cptr, Reg struct hostent *hp, char *sockhost); EXTERN aConfItem *count_cnlines (Reg Link *lp); diff --git a/ircd/s_user.c b/ircd/s_user.c index 5d7975d7..6e68955d 100644 --- a/ircd/s_user.c +++ b/ircd/s_user.c @@ -392,7 +392,7 @@ int register_user(aClient *cptr, aClient *sptr, char *nick, char *username) sptr->hostp->h_name : sptr->sockhost)) && match(xtmp->source_ip, sptr->user->sip) && strchr(xtmp->source_ip, '/') && - match_ipmask(xtmp->source_ip, sptr, 0))) + match_ipmask_client(xtmp->source_ip, sptr, 0))) continue; SetXlined(sptr); break; diff --git a/support/Makefile.in b/support/Makefile.in index 7c62849d..af976d12 100644 --- a/support/Makefile.in +++ b/support/Makefile.in @@ -154,7 +154,7 @@ IAUTH_OBJS = iauth.o a_conf.o a_io.o a_log.o \ mod_pipe.o mod_rfc931.o mod_socks.o \ mod_webproxy.o mod_dnsbl.o -CHKCONF_COMMON_OBJS = match.o +CHKCONF_COMMON_OBJS = match.o clsupport.o CHKCONF_OBJS = chkconf.o CHKCONF = chkconf