Annotation of embedaddon/sudo/plugins/sudoers/match_addr.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (c) 1996, 1998-2005, 2007-2011
! 3: * Todd C. Miller <Todd.Miller@courtesan.com>
! 4: *
! 5: * Permission to use, copy, modify, and distribute this software for any
! 6: * purpose with or without fee is hereby granted, provided that the above
! 7: * copyright notice and this permission notice appear in all copies.
! 8: *
! 9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
! 10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
! 12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
! 14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
! 15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 16: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
! 17: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 18: *
! 19: * Sponsored in part by the Defense Advanced Research Projects
! 20: * Agency (DARPA) and Air Force Research Laboratory, Air Force
! 21: * Materiel Command, USAF, under agreement number F39502-99-1-0512.
! 22: */
! 23:
! 24: #include <config.h>
! 25:
! 26: #include <sys/types.h>
! 27: #include <sys/socket.h>
! 28: #include <stdio.h>
! 29: #ifdef STDC_HEADERS
! 30: # include <stdlib.h>
! 31: # include <stddef.h>
! 32: #else
! 33: # ifdef HAVE_STDLIB_H
! 34: # include <stdlib.h>
! 35: # endif
! 36: #endif /* STDC_HEADERS */
! 37: #ifdef HAVE_STRING_H
! 38: # include <string.h>
! 39: #endif /* HAVE_STRING_H */
! 40: #ifdef HAVE_STRINGS_H
! 41: # include <strings.h>
! 42: #endif /* HAVE_STRINGS_H */
! 43: #ifdef HAVE_UNISTD_H
! 44: # include <unistd.h>
! 45: #endif /* HAVE_UNISTD_H */
! 46: #include <netinet/in.h>
! 47: #include <arpa/inet.h>
! 48: #include <netdb.h>
! 49:
! 50: #include "sudoers.h"
! 51: #include "interfaces.h"
! 52:
! 53: static int
! 54: addr_matches_if(char *n)
! 55: {
! 56: union sudo_in_addr_un addr;
! 57: struct interface *ifp;
! 58: #ifdef HAVE_IN6_ADDR
! 59: int j;
! 60: #endif
! 61: int family;
! 62:
! 63: #ifdef HAVE_IN6_ADDR
! 64: if (inet_pton(AF_INET6, n, &addr.ip6) > 0) {
! 65: family = AF_INET6;
! 66: } else
! 67: #endif
! 68: {
! 69: family = AF_INET;
! 70: addr.ip4.s_addr = inet_addr(n);
! 71: }
! 72:
! 73: for (ifp = interfaces; ifp != NULL; ifp = ifp->next) {
! 74: if (ifp->family != family)
! 75: continue;
! 76: switch(family) {
! 77: case AF_INET:
! 78: if (ifp->addr.ip4.s_addr == addr.ip4.s_addr ||
! 79: (ifp->addr.ip4.s_addr & ifp->netmask.ip4.s_addr)
! 80: == addr.ip4.s_addr)
! 81: return TRUE;
! 82: break;
! 83: #ifdef HAVE_IN6_ADDR
! 84: case AF_INET6:
! 85: if (memcmp(ifp->addr.ip6.s6_addr, addr.ip6.s6_addr,
! 86: sizeof(addr.ip6.s6_addr)) == 0)
! 87: return TRUE;
! 88: for (j = 0; j < sizeof(addr.ip6.s6_addr); j++) {
! 89: if ((ifp->addr.ip6.s6_addr[j] & ifp->netmask.ip6.s6_addr[j]) != addr.ip6.s6_addr[j])
! 90: break;
! 91: }
! 92: if (j == sizeof(addr.ip6.s6_addr))
! 93: return TRUE;
! 94: #endif
! 95: }
! 96: }
! 97:
! 98: return FALSE;
! 99: }
! 100:
! 101: static int
! 102: addr_matches_if_netmask(char *n, char *m)
! 103: {
! 104: int i;
! 105: union sudo_in_addr_un addr, mask;
! 106: struct interface *ifp;
! 107: #ifdef HAVE_IN6_ADDR
! 108: int j;
! 109: #endif
! 110: int family;
! 111:
! 112: #ifdef HAVE_IN6_ADDR
! 113: if (inet_pton(AF_INET6, n, &addr.ip6) > 0)
! 114: family = AF_INET6;
! 115: else
! 116: #endif
! 117: {
! 118: family = AF_INET;
! 119: addr.ip4.s_addr = inet_addr(n);
! 120: }
! 121:
! 122: if (family == AF_INET) {
! 123: if (strchr(m, '.')) {
! 124: mask.ip4.s_addr = inet_addr(m);
! 125: } else {
! 126: i = atoi(m);
! 127: if (i == 0)
! 128: mask.ip4.s_addr = 0;
! 129: else if (i == 32)
! 130: mask.ip4.s_addr = 0xffffffff;
! 131: else
! 132: mask.ip4.s_addr = 0xffffffff - (1 << (32 - i)) + 1;
! 133: mask.ip4.s_addr = htonl(mask.ip4.s_addr);
! 134: }
! 135: addr.ip4.s_addr &= mask.ip4.s_addr;
! 136: }
! 137: #ifdef HAVE_IN6_ADDR
! 138: else {
! 139: if (inet_pton(AF_INET6, m, &mask.ip6) <= 0) {
! 140: j = atoi(m);
! 141: for (i = 0; i < sizeof(addr.ip6.s6_addr); i++) {
! 142: if (j < i * 8)
! 143: mask.ip6.s6_addr[i] = 0;
! 144: else if (i * 8 + 8 <= j)
! 145: mask.ip6.s6_addr[i] = 0xff;
! 146: else
! 147: mask.ip6.s6_addr[i] = 0xff00 >> (j - i * 8);
! 148: addr.ip6.s6_addr[i] &= mask.ip6.s6_addr[i];
! 149: }
! 150: }
! 151: }
! 152: #endif /* HAVE_IN6_ADDR */
! 153:
! 154: for (ifp = interfaces; ifp != NULL; ifp = ifp->next) {
! 155: if (ifp->family != family)
! 156: continue;
! 157: switch(family) {
! 158: case AF_INET:
! 159: if ((ifp->addr.ip4.s_addr & mask.ip4.s_addr) == addr.ip4.s_addr)
! 160: return TRUE;
! 161: #ifdef HAVE_IN6_ADDR
! 162: case AF_INET6:
! 163: for (j = 0; j < sizeof(addr.ip6.s6_addr); j++) {
! 164: if ((ifp->addr.ip6.s6_addr[j] & mask.ip6.s6_addr[j]) != addr.ip6.s6_addr[j])
! 165: break;
! 166: }
! 167: if (j == sizeof(addr.ip6.s6_addr))
! 168: return TRUE;
! 169: #endif /* HAVE_IN6_ADDR */
! 170: }
! 171: }
! 172:
! 173: return FALSE;
! 174: }
! 175:
! 176: /*
! 177: * Returns TRUE if "n" is one of our ip addresses or if
! 178: * "n" is a network that we are on, else returns FALSE.
! 179: */
! 180: int
! 181: addr_matches(char *n)
! 182: {
! 183: char *m;
! 184: int retval;
! 185:
! 186: /* If there's an explicit netmask, use it. */
! 187: if ((m = strchr(n, '/'))) {
! 188: *m++ = '\0';
! 189: retval = addr_matches_if_netmask(n, m);
! 190: *(m - 1) = '/';
! 191: } else
! 192: retval = addr_matches_if(n);
! 193:
! 194: return retval;
! 195: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>