Annotation of embedaddon/sudo/plugins/sudoers/match_addr.c, revision 1.1.1.3
1.1 misho 1: /*
1.1.1.3 ! misho 2: * Copyright (c) 1996, 1998-2005, 2007-2013
1.1 misho 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:
49: #include "sudoers.h"
50: #include "interfaces.h"
51:
1.1.1.2 misho 52: static bool
1.1 misho 53: addr_matches_if(char *n)
54: {
55: union sudo_in_addr_un addr;
56: struct interface *ifp;
1.1.1.2 misho 57: #ifdef HAVE_STRUCT_IN6_ADDR
1.1 misho 58: int j;
59: #endif
60: int family;
1.1.1.2 misho 61: debug_decl(addr_matches_if, SUDO_DEBUG_MATCH)
1.1 misho 62:
1.1.1.2 misho 63: #ifdef HAVE_STRUCT_IN6_ADDR
1.1 misho 64: if (inet_pton(AF_INET6, n, &addr.ip6) > 0) {
65: family = AF_INET6;
66: } else
1.1.1.2 misho 67: #endif /* HAVE_STRUCT_IN6_ADDR */
1.1 misho 68: {
69: family = AF_INET;
70: addr.ip4.s_addr = inet_addr(n);
71: }
72:
1.1.1.3 ! misho 73: for (ifp = get_interfaces(); ifp != NULL; ifp = ifp->next) {
1.1 misho 74: if (ifp->family != family)
75: continue;
1.1.1.2 misho 76: switch (family) {
1.1 misho 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)
1.1.1.2 misho 81: debug_return_bool(true);
1.1 misho 82: break;
1.1.1.2 misho 83: #ifdef HAVE_STRUCT_IN6_ADDR
1.1 misho 84: case AF_INET6:
85: if (memcmp(ifp->addr.ip6.s6_addr, addr.ip6.s6_addr,
86: sizeof(addr.ip6.s6_addr)) == 0)
1.1.1.2 misho 87: debug_return_bool(true);
1.1 misho 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))
1.1.1.2 misho 93: debug_return_bool(true);
94: break;
95: #endif /* HAVE_STRUCT_IN6_ADDR */
1.1 misho 96: }
97: }
98:
1.1.1.2 misho 99: debug_return_bool(false);
1.1 misho 100: }
101:
1.1.1.2 misho 102: static bool
1.1 misho 103: addr_matches_if_netmask(char *n, char *m)
104: {
105: int i;
106: union sudo_in_addr_un addr, mask;
107: struct interface *ifp;
1.1.1.2 misho 108: #ifdef HAVE_STRUCT_IN6_ADDR
1.1 misho 109: int j;
110: #endif
111: int family;
1.1.1.2 misho 112: debug_decl(addr_matches_if, SUDO_DEBUG_MATCH)
1.1 misho 113:
1.1.1.2 misho 114: #ifdef HAVE_STRUCT_IN6_ADDR
1.1 misho 115: if (inet_pton(AF_INET6, n, &addr.ip6) > 0)
116: family = AF_INET6;
117: else
1.1.1.2 misho 118: #endif /* HAVE_STRUCT_IN6_ADDR */
1.1 misho 119: {
120: family = AF_INET;
121: addr.ip4.s_addr = inet_addr(n);
122: }
123:
124: if (family == AF_INET) {
125: if (strchr(m, '.')) {
126: mask.ip4.s_addr = inet_addr(m);
127: } else {
128: i = atoi(m);
129: if (i == 0)
130: mask.ip4.s_addr = 0;
131: else if (i == 32)
132: mask.ip4.s_addr = 0xffffffff;
133: else
134: mask.ip4.s_addr = 0xffffffff - (1 << (32 - i)) + 1;
135: mask.ip4.s_addr = htonl(mask.ip4.s_addr);
136: }
137: addr.ip4.s_addr &= mask.ip4.s_addr;
138: }
1.1.1.2 misho 139: #ifdef HAVE_STRUCT_IN6_ADDR
1.1 misho 140: else {
141: if (inet_pton(AF_INET6, m, &mask.ip6) <= 0) {
142: j = atoi(m);
143: for (i = 0; i < sizeof(addr.ip6.s6_addr); i++) {
144: if (j < i * 8)
145: mask.ip6.s6_addr[i] = 0;
146: else if (i * 8 + 8 <= j)
147: mask.ip6.s6_addr[i] = 0xff;
148: else
149: mask.ip6.s6_addr[i] = 0xff00 >> (j - i * 8);
150: addr.ip6.s6_addr[i] &= mask.ip6.s6_addr[i];
151: }
152: }
153: }
1.1.1.2 misho 154: #endif /* HAVE_STRUCT_IN6_ADDR */
1.1 misho 155:
1.1.1.3 ! misho 156: for (ifp = get_interfaces(); ifp != NULL; ifp = ifp->next) {
1.1 misho 157: if (ifp->family != family)
158: continue;
1.1.1.2 misho 159: switch (family) {
1.1 misho 160: case AF_INET:
161: if ((ifp->addr.ip4.s_addr & mask.ip4.s_addr) == addr.ip4.s_addr)
1.1.1.2 misho 162: debug_return_bool(true);
163: break;
164: #ifdef HAVE_STRUCT_IN6_ADDR
1.1 misho 165: case AF_INET6:
166: for (j = 0; j < sizeof(addr.ip6.s6_addr); j++) {
167: if ((ifp->addr.ip6.s6_addr[j] & mask.ip6.s6_addr[j]) != addr.ip6.s6_addr[j])
168: break;
169: }
170: if (j == sizeof(addr.ip6.s6_addr))
1.1.1.2 misho 171: debug_return_bool(true);
172: break;
173: #endif /* HAVE_STRUCT_IN6_ADDR */
1.1 misho 174: }
175: }
176:
1.1.1.2 misho 177: debug_return_bool(false);
1.1 misho 178: }
179:
180: /*
1.1.1.2 misho 181: * Returns true if "n" is one of our ip addresses or if
182: * "n" is a network that we are on, else returns false.
1.1 misho 183: */
1.1.1.2 misho 184: bool
1.1 misho 185: addr_matches(char *n)
186: {
187: char *m;
1.1.1.2 misho 188: bool retval;
189: debug_decl(addr_matches, SUDO_DEBUG_MATCH)
1.1 misho 190:
191: /* If there's an explicit netmask, use it. */
192: if ((m = strchr(n, '/'))) {
193: *m++ = '\0';
194: retval = addr_matches_if_netmask(n, m);
195: *(m - 1) = '/';
196: } else
197: retval = addr_matches_if(n);
198:
1.1.1.2 misho 199: debug_return_bool(retval);
1.1 misho 200: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>