Date: Sat, 16 Mar 2002 10:12:32 +0000 From: Anatole Shaw <Anatole@mindspring.com> To: freebsd-audit@freebsd.org Subject: regex for tcpwrappers Message-ID: <20020316101232.C65694@ouch.Oof.NET>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
This is my patch that adds extended regular expressions to tcpwrappers.
I wrote it so that I could permit selected cities from DialSprint.net,
which lumps the city, state and other information all into the third
level of DNS. For example, with this patch, the tcpwrappers token
~^sdn-ar-...cthart....\.dialsprint\.net$
will only match the DialSprint pool in Hartford, Connecticut. Pretty
useful I think. Any committers care to review?
--Anatole Shaw
[-- Attachment #2 --]
--- 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 <errno.h>
#include <setjmp.h>
#include <string.h>
+#include <regex.h>
#ifdef INET6
#include <netdb.h>
#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);
}
/* masked_match - match address against netnumber/netmask */
--- contrib/tcp_wrappers/hosts_access.5.orig Thu Feb 3 10:26:57 2000
+++ contrib/tcp_wrappers/hosts_access.5 Thu Mar 14 06:13:06 2002
@@ -103,6 +103,15 @@
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
+A string that begins with a `~\' character.
+The address (and hostname, if available) are matched
+against the extended regular expression (see \fIre_format(7)\fR)
+which follows the `~\' character.
+For example, the pattern `~^nyc[0-9]+\\.example\\.com$\' matches the host name
+`nyc23.example.com\' but neither `nyc.example.com\' nor `nyc42.example.com.au\'.
+The comparison is not case-sensitive, and it is both impossible and useless
+for spaces to appear in the expression.
.SH WILDCARDS
The access control language supports explicit wildcards:
.IP ALL
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020316101232.C65694>
