If looking up a string which looks like a gTLD, doesn't match a known set of
authorsthen <sthen@openbsd.org>
Thu, 9 Apr 2015 19:29:53 +0000 (19:29 +0000)
committersthen <sthen@openbsd.org>
Thu, 9 Apr 2015 19:29:53 +0000 (19:29 +0000)
existing ones not using the new standard hostnames, and whois.nic.TLD exists,
head straight there for lookups rather than using whois-servers.net (who have
been a bit variable in their speed of picking up new zones). Bug spotted by
giovanni@ and jasper@, ok giovanni@

usr.bin/whois/whois.1
usr.bin/whois/whois.c

index 4ecd0b4..ba3ba41 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: whois.1,v 1.32 2013/03/05 16:09:10 sthen Exp $
+.\"    $OpenBSD: whois.1,v 1.33 2015/04/09 19:29:53 sthen Exp $
 .\"    $NetBSD: whois.1,v 1.5 1995/08/31 21:51:32 jtc Exp $
 .\"
 .\" Copyright (c) 1985, 1990, 1993
@@ -30,7 +30,7 @@
 .\"
 .\"     @(#)whois.1    8.2 (Berkeley) 6/20/94
 .\"
-.Dd $Mdocdate: March 5 2013 $
+.Dd $Mdocdate: April 9 2015 $
 .Dt WHOIS 1
 .Os
 .Sh NAME
@@ -97,8 +97,11 @@ By default
 .Nm
 constructs the name of a whois server to use from the top-level domain
 .Pq Tn TLD
-of the supplied (single) argument, and appending
-.Qq Li .whois-servers.net .
+of the supplied (single) argument.
+For newer generic domains (gTLDs), a lookup for whois.nic.tld is attempted.
+For other TLDs, or if this lookup fails,
+.Qq Li .whois-servers.net
+is appended to the TLD.
 This effectively allows a suitable whois server to be selected
 automatically for a large number of
 .Tn TLDs .
index b361333..f085f56 100644 (file)
@@ -1,4 +1,4 @@
-/*      $OpenBSD: whois.c,v 1.46 2014/01/03 15:25:18 millert Exp $   */
+/*      $OpenBSD: whois.c,v 1.47 2015/04/09 19:29:53 sthen Exp $   */
 
 /*
  * Copyright (c) 1980, 1993
@@ -278,6 +278,12 @@ choose_server(const char *name, const char *country)
        char *nserver;
        char *ep;
        size_t len;
+       struct addrinfo hints, *res;
+
+       memset(&hints, 0, sizeof(hints));
+       hints.ai_flags = 0;
+       hints.ai_family = AF_UNSPEC;
+       hints.ai_socktype = SOCK_STREAM;
 
        if (country != NULL)
                qhead = country;
@@ -299,8 +305,33 @@ choose_server(const char *name, const char *country)
        if ((nserver = realloc(server, len)) == NULL)
                err(1, "realloc");
        server = nserver;
-       strlcpy(server, qhead, len);
-       strlcat(server, QNICHOST_TAIL, len);
+
+       /*
+        * Post-2003 ("new") gTLDs are all supposed to have "whois.nic.domain"
+        * (per registry agreement), some older gTLDs also support this...
+        */
+       strlcpy(server, "whois.nic.", len);
+       strlcat(server, qhead, len);
+
+       /* most ccTLDs don't do this, but QNICHOST/whois-servers mostly works */
+       if ((strlen(qhead) == 2 ||
+           /* and is required for most of the <=2003 TLDs/gTLDs */
+           strncasecmp(qhead, "org", 3) == 0 ||
+           strncasecmp(qhead, "com", 3) == 0 ||
+           strncasecmp(qhead, "net", 3) == 0 ||
+           strncasecmp(qhead, "cat", 3) == 0 ||
+           strncasecmp(qhead, "pro", 3) == 0 ||
+           strncasecmp(qhead, "info", 4) == 0 ||
+           strncasecmp(qhead, "aero", 4) == 0 ||
+           strncasecmp(qhead, "jobs", 4) == 0 ||
+           strncasecmp(qhead, "mobi", 4) == 0 ||
+           strncasecmp(qhead, "museum", 6) == 0 ||
+            /* for others, if whois.nic.TLD doesn't exist, try whois-servers */
+           getaddrinfo(server, NULL, &hints, &res) != 0)) {
+               strlcpy(server, qhead, len);
+               strlcat(server, QNICHOST_TAIL, len);
+       }
+
        return (server);
 }