]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 1683] Non-localhost on loopback exempted from nic rules.
authorDave Hart <hart@ntp.org>
Thu, 11 Nov 2010 19:20:40 +0000 (19:20 +0000)
committerDave Hart <hart@ntp.org>
Thu, 11 Nov 2010 19:20:40 +0000 (19:20 +0000)
bk: 4cdc42081Lx7FRbNxl5ht0MVQzLkEQ

ChangeLog
include/ntp.h
include/ntp_io.h
ntpd/ntp_config.c
ntpd/ntp_io.c
ntpd/ntpd.c

index c0c245e6a709518aeec24e5ce767a1312bf08ac4..7bdf9004a307e3787def2bb56636958d84bd8c50 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+---
+
+* [Bug 1683] Non-localhost on loopback exempted from nic rules.
+
 ---
 (4.2.6p3-RC9) 2010/11/10 Released by Harlan Stenn <stenn@ntp.org>
 
index 11285f47bd6686189e015f7dd3663f88f2cd6cf6..898ce07c90e3033d5f4fe8ab7e1deaf21a84623b 100644 (file)
@@ -185,7 +185,7 @@ struct interface {
        char name[32];          /* name of interface */
        u_short family;         /* Address family */
        u_short phase;          /* phase in update cycle */
-       int flags;              /* interface flags */
+       u_int32 flags;          /* interface flags */
        int last_ttl;           /* last TTL specified */
        u_int32 addr_refid;     /* IPv4 addr or IPv6 hash */
        int num_mcast;          /* No. of IP addresses in multicast socket */
index 692d4440fc04e74634ac5eece7efa58f0c679b22..7d88314ea86dc6b4e5a1b8787fa28b4cc359550d 100644 (file)
@@ -81,7 +81,7 @@ typedef enum {
 
 
 isc_boolean_t  get_broadcastclient_flag(void);
-isc_boolean_t  is_ip_address(const char *, isc_netaddr_t *);
+extern int     is_ip_address(const char *, sockaddr_u *);
 extern void    sau_from_netaddr(sockaddr_u *, const isc_netaddr_t *);
 extern void add_nic_rule(nic_rule_match match_type, const char *if_name,
                         int prefixlen, nic_rule_action action);
index e6fb56c24a890bd9c6c1e87d2cd95fc9b67561dd..2bbc0b5c4affc628e520e43fc9a84aa08abf7dc2 100644 (file)
@@ -2160,8 +2160,8 @@ config_access(
        int *                   curr_flag;
        sockaddr_u              addr_sock;
        sockaddr_u              addr_mask;
-       int                     flags;
-       int                     mflags;
+       u_short                 flags;
+       u_short                 mflags;
        int                     restrict_default;
        const char *            signd_warning =
 #ifdef HAVE_NTP_SIGND
@@ -2430,12 +2430,13 @@ config_nic_rules(
        )
 {
        nic_rule_node * curr_node;
-       isc_netaddr_t   netaddr;
+       sockaddr_u      addr;
        nic_rule_match  match_type;
        nic_rule_action action;
        char *          if_name;
        char *          pchSlash;
        int             prefixlen;
+       int             addrbits;
 
        curr_node = queue_head(ptree->nic_rules);
 
@@ -2482,16 +2483,16 @@ config_nic_rules(
                        pchSlash = strchr(if_name, '/');
                        if (pchSlash != NULL)
                                *pchSlash = '\0';
-                       if (is_ip_address(if_name, &netaddr)) {
+                       if (is_ip_address(if_name, &addr)) {
                                match_type = MATCH_IFADDR;
                                if (pchSlash != NULL) {
                                        sscanf(pchSlash + 1, "%d",
                                            &prefixlen);
+                                       addrbits = 8 *
+                                           SIZEOF_INADDR(AF(&addr));
                                        prefixlen = max(-1, prefixlen);
-                                       prefixlen = min(prefixlen, 
-                                           (AF_INET6 == netaddr.family)
-                                               ? 128
-                                               : 32);
+                                       prefixlen = min(prefixlen,
+                                                       addrbits);
                                }
                        } else {
                                match_type = MATCH_IFNAME;
@@ -4317,7 +4318,7 @@ get_multiple_netnums(
        struct addrinfo hints;
        struct addrinfo *ptr;
        int retval;
-       isc_netaddr_t ipaddr;
+       sockaddr_u ipaddr;
 
        memset(&hints, 0, sizeof(hints));
 
@@ -4329,7 +4330,7 @@ get_multiple_netnums(
        lookup = nameornum;
        if (is_ip_address(nameornum, &ipaddr)) {
                hints.ai_flags = AI_NUMERICHOST;
-               hints.ai_family = ipaddr.family;
+               hints.ai_family = AF(&ipaddr);
                if ('[' == nameornum[0]) {
                        lookup = lookbuf;
                        strncpy(lookbuf, &nameornum[1],
@@ -4387,8 +4388,9 @@ get_multiple_netnums(
                if (!retval) {
                        freeaddrinfo(ptr);
                        return -1;
-               } else 
+               } else {
                        return 0;
+               }
        }
        *res = ptr;
 
index b8674fc51f31b31bbc2063a5453ef800dafa55b0..84cecbc909a0c115e31d97cf9c825a8275ce9f92 100644 (file)
@@ -76,7 +76,7 @@ struct nic_rule_tag {
        nic_rule_action action;
        nic_rule_match  match_type;
        char *          if_name;
-       isc_netaddr_t   netaddr;
+       sockaddr_u      addr;
        int             prefixlen;
 };
 
@@ -186,8 +186,7 @@ static void         remove_interface(struct interface *);
 static struct interface *create_interface(u_short, struct interface *);
 
 static int     move_fd                 (SOCKET);
-static int     is_wildcard_addr        (sockaddr_u *);
-static int     is_wildcard_netaddr     (const isc_netaddr_t *);
+static int     is_wildcard_addr        (const sockaddr_u *);
 
 /*
  * Multicast functions
@@ -250,7 +249,9 @@ static void remove_asyncio_reader (struct asyncio_reader *);
 
 static void init_async_notifications (void);
 
-static int create_sockets      (u_short);
+static int     addr_eqprefix   (const sockaddr_u *, const sockaddr_u *,
+                                int);
+static int     create_sockets  (u_short);
 static SOCKET  open_socket     (sockaddr_u *, int, int, struct interface *);
 static char *  fdbits          (int, fd_set *);
 static void    set_reuseaddr   (int);
@@ -285,8 +286,7 @@ static void         create_wildcards        (u_short);
 #ifdef DEBUG
 static const char *    action_text             (nic_rule_action);
 #endif
-static nic_rule_action interface_action(char *, isc_netaddr_t *,
-                                        isc_uint32_t);
+static nic_rule_action interface_action(char *, sockaddr_u *, u_int32);
 static void            convert_isc_if  (isc_interface_t *,
                                         struct interface *, u_short);
 static void            calc_addr_distance(sockaddr_u *,
@@ -706,16 +706,44 @@ remove_asyncio_reader(
 }
 #endif /* !defined(HAVE_IO_COMPLETION_PORT) && defined(HAS_ROUTING_SOCKET) */
 
+
+/* compare two sockaddr prefixes */
+static int
+addr_eqprefix(
+       const sockaddr_u *      a,
+       const sockaddr_u *      b,
+       int                     prefixlen
+       )
+{
+       isc_netaddr_t           isc_a;
+       isc_netaddr_t           isc_b;
+       isc_sockaddr_t          isc_sa;
+
+       memset(&isc_sa, 0, sizeof(isc_sa));
+       memcpy(&isc_sa.type.sa, &a->sa, 
+              min(sizeof(isc_sa.type), sizeof(a)));
+       isc_netaddr_fromsockaddr(&isc_a, &isc_sa);
+
+       memset(&isc_sa, 0, sizeof(isc_sa));
+       memcpy(&isc_sa.type.sa, &b->sa, 
+              min(sizeof(isc_sa.type), sizeof(b)));
+       isc_netaddr_fromsockaddr(&isc_b, &isc_sa);
+
+       return (int)isc_netaddr_eqprefix(&isc_a, &isc_b,
+                                        (u_int)prefixlen);
+}
+
+
 /*
  * Code to tell if we have an IP address
  * If we have then return the sockaddr structure
  * and set the return value
  * see the bind9/getaddresses.c for details
  */
-isc_boolean_t
+int
 is_ip_address(
        const char *    host,
-       isc_netaddr_t * addr
+       sockaddr_u *    addr
        )
 {
        struct in_addr in4;
@@ -726,6 +754,8 @@ is_ip_address(
        NTP_REQUIRE(host != NULL);
        NTP_REQUIRE(addr != NULL);
 
+       memset(addr, 0, sizeof(*addr));
+
        /*
         * Try IPv4, then IPv6.  In order to handle the extended format
         * for IPv6 scoped addresses (address%scope_ID), we'll use a local
@@ -736,8 +766,10 @@ is_ip_address(
         * terminating NULL character.
         */
        if (inet_pton(AF_INET, host, &in4) == 1) {
-               isc_netaddr_fromin(addr, &in4);
-               return (ISC_TRUE);
+               AF(addr) = AF_INET;
+               SET_ADDR4N(addr, in4.s_addr);
+
+               return TRUE;
        } else if (sizeof(tmpbuf) > strlen(host)) {
                if ('[' == host[0]) {
                        strncpy(tmpbuf, &host[1], sizeof(tmpbuf));
@@ -751,14 +783,16 @@ is_ip_address(
                        *pch = '\0';
 
                if (inet_pton(AF_INET6, tmpbuf, &in6) == 1) {
-                       isc_netaddr_fromin6(addr, &in6);
-                       return (ISC_TRUE);
+                       AF(addr) = AF_INET6;
+                       SET_ADDR6N(addr, in6);
+
+                       return TRUE;
                }
        }
        /*
         * If we got here it was not an IP address
         */
-       return (ISC_FALSE);
+       return FALSE;
 }
 
 
@@ -930,7 +964,6 @@ create_wildcards(
 {
        int                     v4wild, v6wild;
        sockaddr_u              wildaddr;
-       isc_netaddr_t           wnaddr;
        nic_rule_action         action;
        struct interface *      wildif;
 
@@ -953,11 +986,8 @@ create_wildcards(
                SET_ADDR4(&wildaddr, INADDR_ANY);
                SET_PORT(&wildaddr, port);
 
-               /* make an libisc-friendly copy */
-               isc_netaddr_fromin(&wnaddr, &wildaddr.sa4.sin_addr);
-
                /* check for interface/nic rules affecting the wildcard */
-               action = interface_action(NULL, &wnaddr, 0);
+               action = interface_action(NULL, &wildaddr, 0);
                v4wild = (ACTION_IGNORE != action);
        }
        if (v4wild) {
@@ -1010,11 +1040,8 @@ create_wildcards(
                SET_PORT(&wildaddr, port);
                SET_SCOPE(&wildaddr, 0);
 
-               /* make an libisc-friendly copy */
-               isc_netaddr_fromin(&wnaddr, &wildaddr.sa4.sin_addr);
-
                /* check for interface/nic rules affecting the wildcard */
-               action = interface_action(NULL, &wnaddr, 0);
+               action = interface_action(NULL, &wildaddr, 0);
                v6wild = (ACTION_IGNORE != action);
        }
        if (v6wild) {
@@ -1074,8 +1101,8 @@ add_nic_rule(
                rule->if_name = estrdup(if_name);
        } else if (MATCH_IFADDR == match_type) {
                NTP_REQUIRE(NULL != if_name);
-               /* set rule->netaddr */
-               is_ip = is_ip_address(if_name, &rule->netaddr);
+               /* set rule->addr */
+               is_ip = is_ip_address(if_name, &rule->addr);
                NTP_REQUIRE(is_ip);
        } else
                NTP_REQUIRE(NULL == if_name);
@@ -1122,30 +1149,31 @@ action_text(
 static nic_rule_action
 interface_action(
        char *          if_name,
-       isc_netaddr_t * if_netaddr,
-       isc_uint32_t    if_flags
+       sockaddr_u *    if_addr,
+       u_int32         if_flags
        )
 {
-       nic_rule *rule;
-       int isloopback;
-       int iswildcard;
+       nic_rule *      rule;
+       int             isloopback;
+       int             iswildcard;
 
        DPRINTF(4, ("interface_action: interface %s ",
                    (if_name != NULL) ? if_name : "wildcard"));
 
-       iswildcard = is_wildcard_netaddr(if_netaddr);
+       iswildcard = is_wildcard_addr(if_addr);
 
        /*
         * Always listen on 127.0.0.1 - required by ntp_intres
         */
-       if (if_flags & INTERFACE_F_LOOPBACK) {
-               isloopback = 1;
-               if (AF_INET == if_netaddr->family) {
+       if (INT_LOOPBACK & if_flags) {
+               isloopback = TRUE;
+               if (IS_IPV4(if_addr)) {
                        DPRINTF(4, ("IPv4 loopback - listen\n"));
                        return ACTION_LISTEN;
                }
-       } else
-               isloopback = 0;
+       } else {
+               isloopback = FALSE;
+       }
 
        /*
         * Find any matching NIC rule from --interface / -I or ntp.conf
@@ -1164,7 +1192,7 @@ interface_action(
                        return rule->action;
 
                case MATCH_IPV4:
-                       if (AF_INET == if_netaddr->family) {
+                       if (IS_IPV4(if_addr)) {
                                DPRINTF(4, ("nic ipv4 %s\n",
                                    action_text(rule->action)));
                                return rule->action;
@@ -1172,7 +1200,7 @@ interface_action(
                        break;
 
                case MATCH_IPV6:
-                       if (AF_INET6 == if_netaddr->family) {
+                       if (IS_IPV6(if_addr)) {
                                DPRINTF(4, ("nic ipv6 %s\n",
                                    action_text(rule->action)));
                                return rule->action;
@@ -1189,16 +1217,15 @@ interface_action(
 
                case MATCH_IFADDR:
                        if (rule->prefixlen != -1) {
-                               if (isc_netaddr_eqprefix(if_netaddr,
-                                   &rule->netaddr, rule->prefixlen)) {
+                               if (addr_eqprefix(if_addr, &rule->addr,
+                                                 rule->prefixlen)) {
 
                                        DPRINTF(4, ("subnet address match - %s\n",
                                            action_text(rule->action)));
                                        return rule->action;
                                }
                        } else
-                               if (isc_netaddr_equal(if_netaddr,
-                                   &rule->netaddr)) {
+                               if (SOCK_EQ(if_addr, &rule->addr)) {
 
                                        DPRINTF(4, ("address match - %s\n",
                                            action_text(rule->action)));
@@ -1326,7 +1353,7 @@ convert_isc_if(
 
        /*
         * Clear the loopback flag if the address is not localhost.
-        * http://bugs.ntp.org/1691
+        * http://bugs.ntp.org/1683
         */
        if (INT_LOOPBACK & itf->flags) {
                if (AF_INET == itf->family) {
@@ -1436,7 +1463,7 @@ sau_from_netaddr(
 
 static int
 is_wildcard_addr(
-       sockaddr_u *psau
+       const sockaddr_u *psau
        )
 {
        if (IS_IPV4(psau) && !NSRCADR(psau))
@@ -1451,19 +1478,6 @@ is_wildcard_addr(
 }
 
 
-static int
-is_wildcard_netaddr(
-       const isc_netaddr_t *pna
-       )
-{
-       sockaddr_u sau;
-
-       sau_from_netaddr(&sau, pna);
-
-       return is_wildcard_addr(&sau);
-}
-
-
 #ifdef OS_NEEDS_REUSEADDR_FOR_IFADDRBIND
 /*
  * enable/disable re-use of wildcard address socket
@@ -1618,8 +1632,8 @@ update_interfaces(
                /* 
                 * Check if and how we are going to use the interface.
                 */
-               switch (interface_action(isc_if.name, &isc_if.address,
-                                        isc_if.flags)) {
+               switch (interface_action(interface.name, &interface.sin,
+                                        interface.flags)) {
 
                case ACTION_IGNORE:
                        continue;
index 62e4f98052e511372b1caff85cb6f11abfe39d65..e6135615bed2cec8a00d1479e5a3e676d1608831 100644 (file)
@@ -556,13 +556,13 @@ ntpdmain(
         * --interface, listen on specified interfaces
         */
        if (HAVE_OPT( INTERFACE )) {
-               int     ifacect = STACKCT_OPT( INTERFACE );
+               int             ifacect = STACKCT_OPT( INTERFACE );
                const char**    ifaces  = STACKLST_OPT( INTERFACE );
-               isc_netaddr_t   netaddr;
+               sockaddr_u      addr;
 
                while (ifacect-- > 0) {
                        add_nic_rule(
-                               is_ip_address(*ifaces, &netaddr)
+                               is_ip_address(*ifaces, &addr)
                                        ? MATCH_IFADDR
                                        : MATCH_IFNAME,
                                *ifaces, -1, ACTION_LISTEN);