Skip to content

Commit

Permalink
Implement -I to use referrals from whois.iana.org
Browse files Browse the repository at this point in the history
Closes: #774603
  • Loading branch information
rfc1036 committed Jun 27, 2019
1 parent a0c0bf7 commit b49ba5e
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 2 deletions.
8 changes: 7 additions & 1 deletion whois.1
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ whois \- client for the whois directory service
.B whois
[\~{\~\fB\-h\fP | \fB\-\-host\fP\~}\~\fIHOST\fP\~]
[\~{\~\fB\-p\fP | \fB\-\-port\fP\~}\~\fIPORT\fP\~]
[\~\fB\-abBcdGHKlLmMrRx\fP\~]
[\~\fB\-abBcdGHIKlLmMrRx\fP\~]
[\~\fB\-g\fP\~\fISOURCE:FIRST\-LAST\fP\~]
[\~\fB\-i\fP\~\fIATTR\fP[\fI,ATTR\fP]...\~]
[\~\fB\-s\fP\~\fISOURCE\fP[\fI,SOURCE\fP]...\~]
Expand Down Expand Up @@ -51,6 +51,12 @@ Do not display the legal disclaimers some registries like to show you.
.B \-p, \-\-port PORT
Connect to PORT.
.TP 8
.B -I
First query \fIwhois.iana.org\fP and then follow its referral to the
whois server authoritative for that request. This works for IP addresses,
AS numbers and domains. \fBBEWARE\fP: this means that the IANA server
will see your complete query.
.TP 8
.B \-\-verbose
Be verbose.
.TP 8
Expand Down
54 changes: 53 additions & 1 deletion whois.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ int main(int argc, char *argv[])
argv = merge_args(getenv("WHOIS_OPTIONS"), argv, &argc);

while ((ch = GETOPT_LONGISH(argc, argv,
"abBcdFg:Gh:Hi:KlLmMp:q:rRs:t:T:v:V:x",
"abBcdFg:Gh:Hi:IKlLmMp:q:rRs:t:T:v:V:x",
longopts, &longindex)) > 0) {
/* RIPE flags */
if (strchr(ripeflags, ch)) {
Expand Down Expand Up @@ -221,6 +221,9 @@ int main(int argc, char *argv[])
case 'H':
hide_discl = HIDE_NOT_STARTED; /* enable disclaimers hiding */
break;
case 'I':
server = strdup("\x0E");
break;
case 'p':
port = strdup(optarg);
break;
Expand Down Expand Up @@ -372,6 +375,13 @@ int handle_query(const char *hserver, const char *hport,
server = guess_server(p);
free(p);
goto retry;
case 0x0E:
if (verb)
printf(_("Using server %s.\n"), "whois.iana.org");
sockfd = openconn("whois.iana.org", NULL);
free(server);
server = query_iana(sockfd, query);
break;
default:
break;
}
Expand Down Expand Up @@ -921,6 +931,47 @@ char *query_afilias(const int sock, const char *query)
return referral_server;
}

char *query_iana(const int sock, const char *query)
{
char *temp, *p, buf[2000];
FILE *fi;
char *referral_server = NULL;
int state = 0;

temp = malloc(strlen(query) + 2 + 1);
strcpy(temp, query);
strcat(temp, "\r\n");

fi = fdopen(sock, "r");
if (write(sock, temp, strlen(temp)) < 0)
err_sys("write");
free(temp);

while (fgets(buf, sizeof(buf), fi)) {
/* If multiple attributes are returned then use the first result.
This is not supposed to happen. */
if (state == 0 && strneq(buf, "refer:", 6)) {
for (p = buf; *p != ':'; p++); /* skip until colon */
for (p++; *p == ' '; p++); /* skip colon and spaces */
referral_server = strdup(p);
if ((p = strpbrk(referral_server, "\r\n ")))
*p = '\0';
state = 2;
}

if ((p = strpbrk(buf, "\r\n")))
*p = '\0';
recode_fputs(buf, stdout);
fputc('\n', stdout);
}

if (ferror(fi))
err_sys("fgets");
fclose(fi);

return referral_server;
}

int openconn(const char *server, const char *port)
{
int fd = -1;
Expand Down Expand Up @@ -1437,6 +1488,7 @@ void NORETURN usage(int error)
"Usage: whois [OPTION]... OBJECT...\n\n"
"-h HOST, --host HOST connect to server HOST\n"
"-p PORT, --port PORT connect to PORT\n"
"-I query whois.iana.org and follow its referral\n"
"-H hide legal disclaimers\n"
));
fprintf((EXIT_SUCCESS == error) ? stdout : stderr, _(
Expand Down
1 change: 1 addition & 0 deletions whois.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ int hide_line(int *hiding, const char *const line);
char *do_query(const int, const char *);
char *query_crsnic(const int, const char *);
char *query_afilias(const int, const char *);
char *query_iana(const int, const char *);
int openconn(const char *, const char *);
int connect_with_timeout(int, const struct sockaddr *, socklen_t, int);
void NORETURN usage(int error);
Expand Down

0 comments on commit b49ba5e

Please sign in to comment.