Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 7 Oct 2001 20:38:52 -0400
From:      Mike Barcroft <mike@FreeBSD.ORG>
To:        "Todd C. Miller" <Todd.Miller@courtesan.com>
Cc:        Peter Pentchev <roam@ringlet.net>, freebsd-net@FreeBSD.ORG, freebsd-audit@FreeBSD.ORG
Subject:   Final Patch for Review (was Re: [CFR] whois(1) out-of-bound access patch)
Message-ID:  <20011007203852.G37270@coffee.q9media.com>
In-Reply-To: <200110041650.f94GoL10010161@xerxes.courtesan.com>; from Todd.Miller@courtesan.com on Thu, Oct 04, 2001 at 10:50:20AM -0600
References:  <20011004121640.C1959@ringworld.oblivion.bg> <20011004121933.B31795@coffee.q9media.com> <200110041650.f94GoL10010161@xerxes.courtesan.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Todd C. Miller <Todd.Miller@courtesan.com> writes:
> In message <20011004121933.B31795@coffee.q9media.com>
> 	so spake Mike Barcroft (mike):
> 
> > Would you please test the attached patch and confirm that it solves
> > the problem?  If it does, I'll commit it today.
> 
> I doubt that is sufficient as "buf" is treated as a NUL terminated
> string in the calls to strstr().  Also note that it is not necessary
> to copy the buffer each time as in the original patch.  You can
> only get a line w/o a newline as the last line before EOF.

After some discussion off the mailing list with Peter, I've come up
with a total solution that is fairly elegant, but requires the new
libc function strnstr(3) I posted earlier.  Most of the patch is a
cleanup of the current code.

I'd appreciate reviews of this.  I plan on committing it in a few
days.  The patch is at the end of this message and also at:
http://people.FreeBSD.org/~mike/patches/whois.20011007.diff

Best regards,
Mike Barcroft

----------------------------------------------------------------------
whois.20011007.diff

o Treat a buffer as a non-NUL terminated string, because the whois
  server may not return a new line character on the final line.
o Remove the whois.networksolutions.com fallback code, which is no
  longer needed.
o Instead of determining a hostname by terminating it when we see
  whitespace, only allow hostname characters and terminate the string
  when it's not such a character.
o Add a small optimization in a for loop.

PR:		30968
MFC after:	4 days

Index: whois.c
===================================================================
RCS file: /cvs/src/usr.bin/whois/whois.c,v
retrieving revision 1.24
diff -u -r1.24 whois.c
--- whois.c	5 Aug 2001 19:37:12 -0000	1.24
+++ whois.c	7 Oct 2001 21:38:04 -0000
@@ -71,11 +71,11 @@
 #define	SNICHOST	"whois.6bone.net"
 #define	DEFAULT_PORT	"whois"
 #define	WHOIS_SERVER_ID	"Whois Server: "
-#define	NO_MATCH_ID	"No match for \""
 
 #define WHOIS_RECURSE		0x01
-#define WHOIS_INIC_FALLBACK	0x02
-#define WHOIS_QUICK		0x04
+#define WHOIS_QUICK		0x02
+
+#define ishost(h) (isalnum((unsigned char)h) || h == '.' || h == '-')
 
 const char *ip_whois[] = { RNICHOST, PNICHOST, NULL };
 const char *port = DEFAULT_PORT;
@@ -164,7 +164,7 @@
 		use_qnichost = 1;
 		host = NICHOST;
 		if (!(flags & WHOIS_QUICK))
-			flags |= WHOIS_INIC_FALLBACK | WHOIS_RECURSE;
+			flags |= WHOIS_RECURSE;
 	}
 	while (argc--) {
 		if (country != NULL) {
@@ -251,8 +251,8 @@
 {
 	FILE *sfi, *sfo;
 	struct addrinfo *res2;
-	char *buf, *nhost, *p;
-	int i, nomatch, s;
+	char *buf, *host, *nhost, *p;
+	int i, s;
 	size_t len;
 
 	for (; res; res = res->ai_next) {
@@ -273,45 +273,34 @@
 	fprintf(sfo, "%s\r\n", name);
 	fflush(sfo);
 	nhost = NULL;
-	nomatch = 0;
 	while ((buf = fgetln(sfi, &len)) != NULL) {
-		while (len && isspace(buf[len - 1]))
+		while (len > 0 && isspace((unsigned char)buf[len - 1]))
 			buf[--len] = '\0';
+		printf("%.*s\n", (int)len, buf);
 
 		if ((flags & WHOIS_RECURSE) && nhost == NULL) {
-			p = strstr(buf, WHOIS_SERVER_ID);
-			if (p != NULL) {
-				p += sizeof(WHOIS_SERVER_ID) - 1;
-				if ((len = strcspn(p, " \t\n\r")) != 0) {
-					s_asprintf(&nhost, "%s", p);
+			host = strnstr(buf, WHOIS_SERVER_ID, len);
+			if (host != NULL) {
+				host += sizeof(WHOIS_SERVER_ID) - 1;
+				for (p = host; p < buf + len; p++) {
+					if (!ishost(*p)) {
+						*p = '\0';
+						break;
+					}
 				}
+				s_asprintf(&nhost, "%.*s",
+				     (int)(buf + len - host), host);
 			} else {
 				for (i = 0; ip_whois[i] != NULL; i++) {
-					if (strstr(buf, ip_whois[i]) == NULL)
+					if (strnstr(buf, ip_whois[i], len) ==
+					    NULL)
 						continue;
 					s_asprintf(&nhost, "%s", ip_whois[i]);
+					break;
 				}
 			}
 		}
-
-		if ((flags & WHOIS_INIC_FALLBACK) && nhost == NULL &&
-		    !nomatch && (p = strstr(buf, NO_MATCH_ID)) != NULL) {
-			p += sizeof(NO_MATCH_ID) - 1;
-			if ((len = strcspn(p, "\"")) &&
-			    strncasecmp(name, p, len) == 0 &&
-			    name[len] == '\0' &&
-			    strchr(name, '.') == NULL)
-				nomatch = 1;
-		}
-		printf("%s\n", buf);
 	}
-
-	/* Do second lookup as needed. */
-	if (nomatch && nhost == NULL) {
-		printf("Looking up %s at %s.\n\n", name, INICHOST);
-		s_asprintf(&nhost, "%s", INICHOST);
-	}
-
 	if (nhost != NULL) {
 		if ((res2 = gethostinfo(nhost, 0)) == NULL) {
 			free(nhost);

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-audit" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20011007203852.G37270>