--- contrib/tcp_wrappers/hosts_access.c.orig Tue Jul 18 08:34:54 2000 +++ contrib/tcp_wrappers/hosts_access.c Thu Mar 14 06:45:02 2002 @@ -41,6 +41,7 @@ #include #include #include +#include #ifdef INET6 #include #endif @@ -93,6 +94,7 @@ static int host_match(); static int string_match(); static int masked_match(); +static int regex_match(); #ifdef INET6 static int masked_match4(); static int masked_match6(); @@ -336,6 +338,8 @@ if (tok[0] == '.') { /* suffix */ n = strlen(string) - strlen(tok); return (n > 0 && STR_EQ(tok, string + n)); + } else if (tok[0] == '~') { /* regex */ + return (regex_match(tok+1, string)); } else if (STR_EQ(tok, "ALL")) { /* all: match any */ return (YES); } else if (STR_EQ(tok, "KNOWN")) { /* not unknown */ @@ -378,6 +382,45 @@ #endif return (STR_EQ(tok, string)); } +} + +/* regex_match - match string against regular expression */ + +static int regex_match(exp, string) +char *exp; +char *string; +{ + regex_t preg; + int errn; + char errstr[256]; + + if ( *exp == '\0' ) { + tcpd_warn("null regular expression"); + return (NO); + } + errn = regcomp(&preg, exp, REG_EXTENDED | REG_ICASE | REG_NOSUB); + if ( errn != 0 ) { + regerror(errn, &preg, errstr, 256); + regfree(&preg); + tcpd_warn("error in regex: %s", errstr); + return (NO); + } + errn = regexec(&preg, string, 0, NULL, 0); + if ( errn == 0 ) { + regfree(&preg); + return (YES); + } else if ( errn == REG_NOMATCH ) { + regfree(&preg); + return (NO); + } else { + regerror(errn, &preg, errstr, 256); + regfree(&preg); + tcpd_warn("could not execute regex: %s", errstr); + return (NO); + } + /* unreached */ + regfree(&preg); + return (NO); }