diff -up tcp_wrappers_7.6/hosts_access.5.patch6 tcp_wrappers_7.6/hosts_access.5 --- tcp_wrappers_7.6/hosts_access.5.patch6 2008-08-29 09:45:12.000000000 +0200 +++ tcp_wrappers_7.6/hosts_access.5 2008-08-29 09:45:12.000000000 +0200 @@ -96,6 +96,10 @@ or address pattern listed in the named f zero or more lines with zero or more host name or address patterns separated by whitespace. A file name pattern can be used anywhere a host name or address pattern can be used. +.IP \(bu +Wildcards `*\' and `?\' can be used to match hostnames or IP addresses. This +method of matching cannot be used in conjunction with `net/mask\' matching, +hostname matching beginning with `.\' or IP address matching ending with `.\'. .SH WILDCARDS The access control language supports explicit wildcards: .IP ALL diff -up tcp_wrappers_7.6/hosts_access.c.patch6 tcp_wrappers_7.6/hosts_access.c --- tcp_wrappers_7.6/hosts_access.c.patch6 2008-08-29 09:45:12.000000000 +0200 +++ tcp_wrappers_7.6/hosts_access.c 2008-08-29 09:45:12.000000000 +0200 @@ -311,6 +311,11 @@ char *string; { int n; +#ifndef DISABLE_WILDCARD_MATCHING + if (strchr(tok, '*') || strchr(tok,'?')) { /* contains '*' or '?' */ + return (match_pattern_ylo(string,tok)); + } else +#endif if (tok[0] == '.') { /* suffix */ n = strlen(string) - strlen(tok); return (n > 0 && STR_EQ(tok, string + n)); @@ -351,3 +356,71 @@ char *string; } return ((addr & mask) == net); } + +#ifndef DISABLE_WILDCARD_MATCHING +/* Note: this feature has been adapted in a pretty straightforward way + from Tatu Ylonen's last SSH version under free license by + Pekka Savola . + + Copyright (c) 1995 Tatu Ylonen , Espoo, Finland +*/ + +/* Returns true if the given string matches the pattern (which may contain + ? and * as wildcards), and zero if it does not match. */ + +int match_pattern_ylo(const char *s, const char *pattern) +{ + while (1) + { + /* If at end of pattern, accept if also at end of string. */ + if (!*pattern) + return !*s; + + /* Process '*'. */ + if (*pattern == '*') + { + /* Skip the asterisk. */ + pattern++; + + /* If at end of pattern, accept immediately. */ + if (!*pattern) + return 1; + + /* If next character in pattern is known, optimize. */ + if (*pattern != '?' && *pattern != '*') + { + /* Look instances of the next character in pattern, and try + to match starting from those. */ + for (; *s; s++) + if (*s == *pattern && + match_pattern_ylo(s + 1, pattern + 1)) + return 1; + /* Failed. */ + return 0; + } + + /* Move ahead one character at a time and try to match at each + position. */ + for (; *s; s++) + if (match_pattern_ylo(s, pattern)) + return 1; + /* Failed. */ + return 0; + } + + /* There must be at least one more character in the string. If we are + at the end, fail. */ + if (!*s) + return 0; + + /* Check if the next character of the string is acceptable. */ + if (*pattern != '?' && *pattern != *s) + return 0; + + /* Move to the next character, both in string and in pattern. */ + s++; + pattern++; + } + /*NOTREACHED*/ +} +#endif /* DISABLE_WILDCARD_MATCHING */