--- embedaddon/sudo/plugins/sudoers/match_addr.c 2012/02/21 16:23:02 1.1.1.1 +++ embedaddon/sudo/plugins/sudoers/match_addr.c 2014/06/15 16:12:54 1.1.1.4 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 1998-2005, 2007-2011 + * Copyright (c) 1996, 1998-2005, 2007-2013 * Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any @@ -45,85 +45,99 @@ #endif /* HAVE_UNISTD_H */ #include #include -#include #include "sudoers.h" #include "interfaces.h" -static int -addr_matches_if(char *n) +static bool +addr_matches_if(const char *n) { union sudo_in_addr_un addr; struct interface *ifp; -#ifdef HAVE_IN6_ADDR - int j; +#ifdef HAVE_STRUCT_IN6_ADDR + unsigned int j; #endif - int family; + unsigned int family; + debug_decl(addr_matches_if, SUDO_DEBUG_MATCH) -#ifdef HAVE_IN6_ADDR - if (inet_pton(AF_INET6, n, &addr.ip6) > 0) { +#ifdef HAVE_STRUCT_IN6_ADDR + if (inet_pton(AF_INET6, n, &addr.ip6) == 1) { family = AF_INET6; } else -#endif - { +#endif /* HAVE_STRUCT_IN6_ADDR */ + if (inet_pton(AF_INET, n, &addr.ip4) == 1) { family = AF_INET; - addr.ip4.s_addr = inet_addr(n); + } else { + debug_return_bool(false); } - for (ifp = interfaces; ifp != NULL; ifp = ifp->next) { + SLIST_FOREACH(ifp, get_interfaces(), entries) { if (ifp->family != family) continue; - switch(family) { + switch (family) { case AF_INET: if (ifp->addr.ip4.s_addr == addr.ip4.s_addr || (ifp->addr.ip4.s_addr & ifp->netmask.ip4.s_addr) == addr.ip4.s_addr) - return TRUE; + debug_return_bool(true); break; -#ifdef HAVE_IN6_ADDR +#ifdef HAVE_STRUCT_IN6_ADDR case AF_INET6: if (memcmp(ifp->addr.ip6.s6_addr, addr.ip6.s6_addr, sizeof(addr.ip6.s6_addr)) == 0) - return TRUE; + debug_return_bool(true); for (j = 0; j < sizeof(addr.ip6.s6_addr); j++) { if ((ifp->addr.ip6.s6_addr[j] & ifp->netmask.ip6.s6_addr[j]) != addr.ip6.s6_addr[j]) break; } if (j == sizeof(addr.ip6.s6_addr)) - return TRUE; -#endif + debug_return_bool(true); + break; +#endif /* HAVE_STRUCT_IN6_ADDR */ } } - return FALSE; + debug_return_bool(false); } -static int -addr_matches_if_netmask(char *n, char *m) +static bool +addr_matches_if_netmask(const char *n, const char *m) { - int i; + unsigned int i; union sudo_in_addr_un addr, mask; struct interface *ifp; -#ifdef HAVE_IN6_ADDR - int j; +#ifdef HAVE_STRUCT_IN6_ADDR + unsigned int j; #endif - int family; + unsigned int family; + const char *errstr; + debug_decl(addr_matches_if, SUDO_DEBUG_MATCH) -#ifdef HAVE_IN6_ADDR - if (inet_pton(AF_INET6, n, &addr.ip6) > 0) +#ifdef HAVE_STRUCT_IN6_ADDR + if (inet_pton(AF_INET6, n, &addr.ip6) == 1) family = AF_INET6; else -#endif - { +#endif /* HAVE_STRUCT_IN6_ADDR */ + if (inet_pton(AF_INET, n, &addr.ip4) == 1) { family = AF_INET; - addr.ip4.s_addr = inet_addr(n); + } else { + debug_return_bool(false); } if (family == AF_INET) { if (strchr(m, '.')) { - mask.ip4.s_addr = inet_addr(m); + if (inet_pton(AF_INET, m, &mask.ip4) != 1) { + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, + "IPv4 netmask %s: %s", m, "invalid value"); + debug_return_bool(false); + } } else { - i = atoi(m); + i = strtonum(m, 0, 32, &errstr); + if (errstr != NULL) { + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, + "IPv4 netmask %s: %s", m, errstr); + debug_return_bool(false); + } if (i == 0) mask.ip4.s_addr = 0; else if (i == 32) @@ -134,10 +148,15 @@ addr_matches_if_netmask(char *n, char *m) } addr.ip4.s_addr &= mask.ip4.s_addr; } -#ifdef HAVE_IN6_ADDR +#ifdef HAVE_STRUCT_IN6_ADDR else { - if (inet_pton(AF_INET6, m, &mask.ip6) <= 0) { - j = atoi(m); + if (inet_pton(AF_INET6, m, &mask.ip6) != 1) { + j = strtonum(m, 0, 128, &errstr); + if (errstr != NULL) { + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, + "IPv6 netmask %s: %s", m, errstr); + debug_return_bool(false); + } for (i = 0; i < sizeof(addr.ip6.s6_addr); i++) { if (j < i * 8) mask.ip6.s6_addr[i] = 0; @@ -149,47 +168,52 @@ addr_matches_if_netmask(char *n, char *m) } } } -#endif /* HAVE_IN6_ADDR */ +#endif /* HAVE_STRUCT_IN6_ADDR */ - for (ifp = interfaces; ifp != NULL; ifp = ifp->next) { + SLIST_FOREACH(ifp, get_interfaces(), entries) { if (ifp->family != family) continue; - switch(family) { + switch (family) { case AF_INET: if ((ifp->addr.ip4.s_addr & mask.ip4.s_addr) == addr.ip4.s_addr) - return TRUE; -#ifdef HAVE_IN6_ADDR + debug_return_bool(true); + break; +#ifdef HAVE_STRUCT_IN6_ADDR case AF_INET6: for (j = 0; j < sizeof(addr.ip6.s6_addr); j++) { if ((ifp->addr.ip6.s6_addr[j] & mask.ip6.s6_addr[j]) != addr.ip6.s6_addr[j]) break; } if (j == sizeof(addr.ip6.s6_addr)) - return TRUE; -#endif /* HAVE_IN6_ADDR */ + debug_return_bool(true); + break; +#endif /* HAVE_STRUCT_IN6_ADDR */ } } - return FALSE; + debug_return_bool(false); } /* - * Returns TRUE if "n" is one of our ip addresses or if - * "n" is a network that we are on, else returns FALSE. + * Returns true if "n" is one of our ip addresses or if + * "n" is a network that we are on, else returns false. */ -int +bool addr_matches(char *n) { char *m; - int retval; + bool rc; + debug_decl(addr_matches, SUDO_DEBUG_MATCH) /* If there's an explicit netmask, use it. */ if ((m = strchr(n, '/'))) { *m++ = '\0'; - retval = addr_matches_if_netmask(n, m); + rc = addr_matches_if_netmask(n, m); *(m - 1) = '/'; } else - retval = addr_matches_if(n); + rc = addr_matches_if(n); - return retval; + sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO, + "IP address %s matches local host: %s", n, rc ? "true" : "false"); + debug_return_bool(rc); }