From: Dave Hart Date: Sun, 4 Apr 2010 04:07:40 +0000 (+0000) Subject: [Bug 1516] unpeer by IP address fails, DNS name works. X-Git-Tag: NTP_4_2_7P23~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=582a8c3694002f9de7131dc5dcbc9231c43b934a;p=thirdparty%2Fntp.git [Bug 1516] unpeer by IP address fails, DNS name works. [Bug 1517] ntpq and ntpdc should verify reverse DNS before use. ntpq and ntpdc now use the following format for showing purported DNS names from IP address "reverse" DNS lookups when the DNS name does not exist or does not include the original IP address among the results: "192.168.1.2 (fake.dns.local)". bk: 4bb8108cauaG1mslKFv9Hy_H9hvGNg --- diff --git a/ChangeLog b/ChangeLog index 9ba0d5b9d..36927d904 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +* [Bug 1516] unpeer by IP address fails, DNS name works. +* [Bug 1517] ntpq and ntpdc should verify reverse DNS before use. + ntpq and ntpdc now use the following format for showing purported + DNS names from IP address "reverse" DNS lookups when the DNS name + does not exist or does not include the original IP address among + the results: "192.168.1.2 (fake.dns.local)". (4.2.7p22) 2010/04/02 Released by Harlan Stenn * [Bug 1432] Don't set inheritable flag for linux capabilities. * [Bug 1465] Make sure time from TS2100 is not invalid. diff --git a/libntp/socktohost.c b/libntp/socktohost.c index 8120b91fa..5a2080402 100644 --- a/libntp/socktohost.c +++ b/libntp/socktohost.c @@ -18,6 +18,7 @@ #include "lib_strbuf.h" #include "ntp_stdlib.h" #include "ntp.h" +#include "ntp_debug.h" char * @@ -25,12 +26,71 @@ socktohost( sockaddr_u *sock ) { - register char *buffer; + const char svc[] = "ntp"; + char * pbuf; + char * pliar; + int gni_flags; + struct addrinfo hints; + struct addrinfo * alist; + struct addrinfo * ai; + int a_info; - LIB_GETBUF(buffer); - if (getnameinfo(&sock->sa, SOCKLEN(sock), buffer, - LIB_BUFLENGTH, NULL, 0, 0)) - return stoa(sock); + /* reverse the address to purported DNS name */ + LIB_GETBUF(pbuf); + gni_flags = NI_DGRAM | NI_NAMEREQD; + if (getnameinfo(&sock->sa, SOCKLEN(sock), pbuf, LIB_BUFLENGTH, + NULL, 0, gni_flags)) + return stoa(sock); /* use address */ - return buffer; + DPRINTF(1, ("%s reversed to %s\n", stoa(sock), pbuf)); + + /* + * Resolve the reversed name and make sure the reversed address + * is among the results. + */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF(sock); + hints.ai_protocol = IPPROTO_UDP; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = 0; + alist = NULL; + + a_info = getaddrinfo(pbuf, svc, &hints, &alist); + if (a_info == EAI_NONAME +#ifdef EAI_NODATA + || a_info == EAI_NODATA +#endif + ) { + hints.ai_flags = AI_CANONNAME; +#ifdef AI_ADDRCONFIG + hints.ai_flags |= AI_ADDRCONFIG; +#endif + a_info = getaddrinfo(pbuf, svc, &hints, &alist); + } +#ifdef AI_ADDRCONFIG + /* Some older implementations don't like AI_ADDRCONFIG. */ + if (a_info == EAI_BADFLAGS) { + hints.ai_flags &= ~AI_ADDRCONFIG; + a_info = getaddrinfo(pbuf, svc, &hints, &alist); + } +#endif + if (a_info) + goto forward_fail; + + NTP_INSIST(alist != NULL); + + for (ai = alist; ai != NULL; ai = ai->ai_next) + if (SOCK_EQ(sock, (sockaddr_u *)ai->ai_addr)) + break; + freeaddrinfo(alist); + + if (ai != NULL) + return pbuf; /* forward check passed */ + + forward_fail: + DPRINTF(1, ("forward check lookup fail: %s\n", pbuf)); + LIB_GETBUF(pliar); + snprintf(pliar, LIB_BUFLENGTH, "%s (%s)", stoa(sock), pbuf); + + return pliar; } diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index 7a56ce1d1..80198694b 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -3790,11 +3790,10 @@ config_unpeers( { sockaddr_u peeraddr; struct addrinfo hints; - isc_netaddr_t i_netaddr; struct unpeer_node * curr_unpeer; struct peer * p; const char * name; - u_short af; + int rc; for (curr_unpeer = queue_head(ptree->unpeers); curr_unpeer != NULL; @@ -3816,18 +3815,12 @@ config_unpeers( continue; } + memset(&peeraddr, 0, sizeof(peeraddr)); + AF(&peeraddr) = curr_unpeer->addr->type; name = curr_unpeer->addr->address; - af = curr_unpeer->addr->type; + rc = getnetnum(name, &peeraddr, 0, t_UNK); /* Do we have a numeric address? */ - if (is_ip_address(name, af, &i_netaddr)) { - AF(&peeraddr) = (u_short)i_netaddr.family; - if (AF_INET6 == i_netaddr.family) - SET_ADDR6N(&peeraddr, - i_netaddr.type.in6); - else - SET_ADDR4N(&peeraddr, - i_netaddr.type.in.s_addr); - + if (rc > 0) { DPRINTF(1, ("unpeer: searching for %s\n", stoa(&peeraddr))); p = findexistingpeer(&peeraddr, NULL, NULL, -1); @@ -3856,7 +3849,7 @@ config_unpeers( /* Resolve the hostname to address(es). */ #ifdef WORKER memset(&hints, 0, sizeof(hints)); - hints.ai_family = af; + hints.ai_family = curr_unpeer->addr->type; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; getaddrinfo_sometime(name, "ntp", &hints, @@ -4600,7 +4593,7 @@ getnetnum( const char *num, sockaddr_u *addr, int complain, - enum gnn_type a_type + enum gnn_type a_type /* ignored */ ) { isc_netaddr_t ipaddr; diff --git a/ntpq/ntpq.c b/ntpq/ntpq.c index 6d20a0b73..1690aa22a 100644 --- a/ntpq/ntpq.c +++ b/ntpq/ntpq.c @@ -636,12 +636,12 @@ openhost( const char *hname ) { + const char svc[] = "ntp"; char temphost[LENHOSTNAME]; int a_info, i; - struct addrinfo hints, *ai = NULL; + struct addrinfo hints, *ai; register const char *cp; char name[LENHOSTNAME]; - char service[5]; /* * We need to get by the [] if they were entered @@ -668,14 +668,14 @@ openhost( * will return an "IPv4-mapped IPv6 address" address if you * give it an IPv4 address to lookup. */ - strcpy(service, "ntp"); - memset((char *)&hints, 0, sizeof(struct addrinfo)); + memset(&hints, 0, sizeof(hints)); hints.ai_family = ai_fam_templ; hints.ai_protocol = IPPROTO_UDP; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = Z_AI_NUMERICHOST; + ai = NULL; - a_info = getaddrinfo(hname, service, &hints, &ai); + a_info = getaddrinfo(hname, svc, &hints, &ai); if (a_info == EAI_NONAME #ifdef EAI_NODATA || a_info == EAI_NODATA @@ -685,13 +685,13 @@ openhost( #ifdef AI_ADDRCONFIG hints.ai_flags |= AI_ADDRCONFIG; #endif - a_info = getaddrinfo(hname, service, &hints, &ai); + a_info = getaddrinfo(hname, svc, &hints, &ai); } #ifdef AI_ADDRCONFIG /* Some older implementations don't like AI_ADDRCONFIG. */ if (a_info == EAI_BADFLAGS) { hints.ai_flags &= ~AI_ADDRCONFIG; - a_info = getaddrinfo(hname, service, &hints, &ai); + a_info = getaddrinfo(hname, svc, &hints, &ai); } #endif if (a_info != 0) {