Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/openssh/src/addrmatch.c |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /* $OpenBSD: addrmatch.c,v 1.14 2018/07/31 03:07:24 djm Exp $ */ | - | ||||||||||||||||||||||||||||||
2 | - | |||||||||||||||||||||||||||||||
3 | /* | - | ||||||||||||||||||||||||||||||
4 | * Copyright (c) 2004-2008 Damien Miller <djm@mindrot.org> | - | ||||||||||||||||||||||||||||||
5 | * | - | ||||||||||||||||||||||||||||||
6 | * Permission to use, copy, modify, and distribute this software for any | - | ||||||||||||||||||||||||||||||
7 | * purpose with or without fee is hereby granted, provided that the above | - | ||||||||||||||||||||||||||||||
8 | * copyright notice and this permission notice appear in all copies. | - | ||||||||||||||||||||||||||||||
9 | * | - | ||||||||||||||||||||||||||||||
10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | - | ||||||||||||||||||||||||||||||
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | - | ||||||||||||||||||||||||||||||
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | - | ||||||||||||||||||||||||||||||
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | - | ||||||||||||||||||||||||||||||
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | - | ||||||||||||||||||||||||||||||
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | - | ||||||||||||||||||||||||||||||
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | - | ||||||||||||||||||||||||||||||
17 | */ | - | ||||||||||||||||||||||||||||||
18 | - | |||||||||||||||||||||||||||||||
19 | #include "includes.h" | - | ||||||||||||||||||||||||||||||
20 | - | |||||||||||||||||||||||||||||||
21 | #include <sys/types.h> | - | ||||||||||||||||||||||||||||||
22 | #include <sys/socket.h> | - | ||||||||||||||||||||||||||||||
23 | #include <netinet/in.h> | - | ||||||||||||||||||||||||||||||
24 | #include <arpa/inet.h> | - | ||||||||||||||||||||||||||||||
25 | - | |||||||||||||||||||||||||||||||
26 | #include <netdb.h> | - | ||||||||||||||||||||||||||||||
27 | #include <string.h> | - | ||||||||||||||||||||||||||||||
28 | #include <stdlib.h> | - | ||||||||||||||||||||||||||||||
29 | #include <stdio.h> | - | ||||||||||||||||||||||||||||||
30 | #include <stdarg.h> | - | ||||||||||||||||||||||||||||||
31 | - | |||||||||||||||||||||||||||||||
32 | #include "match.h" | - | ||||||||||||||||||||||||||||||
33 | #include "log.h" | - | ||||||||||||||||||||||||||||||
34 | - | |||||||||||||||||||||||||||||||
35 | struct xaddr { | - | ||||||||||||||||||||||||||||||
36 | sa_family_t af; | - | ||||||||||||||||||||||||||||||
37 | union { | - | ||||||||||||||||||||||||||||||
38 | struct in_addr v4; | - | ||||||||||||||||||||||||||||||
39 | struct in6_addr v6; | - | ||||||||||||||||||||||||||||||
40 | u_int8_t addr8[16]; | - | ||||||||||||||||||||||||||||||
41 | u_int32_t addr32[4]; | - | ||||||||||||||||||||||||||||||
42 | } xa; /* 128-bit address */ | - | ||||||||||||||||||||||||||||||
43 | u_int32_t scope_id; /* iface scope id for v6 */ | - | ||||||||||||||||||||||||||||||
44 | #define v4 xa.v4 | - | ||||||||||||||||||||||||||||||
45 | #define v6 xa.v6 | - | ||||||||||||||||||||||||||||||
46 | #define addr8 xa.addr8 | - | ||||||||||||||||||||||||||||||
47 | #define addr32 xa.addr32 | - | ||||||||||||||||||||||||||||||
48 | }; | - | ||||||||||||||||||||||||||||||
49 | - | |||||||||||||||||||||||||||||||
50 | static int | - | ||||||||||||||||||||||||||||||
51 | addr_unicast_masklen(int af) | - | ||||||||||||||||||||||||||||||
52 | { | - | ||||||||||||||||||||||||||||||
53 | switch (af) { | - | ||||||||||||||||||||||||||||||
54 | case AF_INET: executed 10 times by 1 test: case 2 : Executed by:
| 10 | ||||||||||||||||||||||||||||||
55 | return 32; executed 10 times by 1 test: return 32; Executed by:
| 10 | ||||||||||||||||||||||||||||||
56 | case AF_INET6: never executed: case 10 : | 0 | ||||||||||||||||||||||||||||||
57 | return 128; never executed: return 128; | 0 | ||||||||||||||||||||||||||||||
58 | default: never executed: default: | 0 | ||||||||||||||||||||||||||||||
59 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||||||||
60 | } | - | ||||||||||||||||||||||||||||||
61 | } | - | ||||||||||||||||||||||||||||||
62 | - | |||||||||||||||||||||||||||||||
63 | static inline int | - | ||||||||||||||||||||||||||||||
64 | masklen_valid(int af, u_int masklen) | - | ||||||||||||||||||||||||||||||
65 | { | - | ||||||||||||||||||||||||||||||
66 | switch (af) { | - | ||||||||||||||||||||||||||||||
67 | case AF_INET: executed 47 times by 1 test: case 2 : Executed by:
| 47 | ||||||||||||||||||||||||||||||
68 | return masklen <= 32 ? 0 : -1; executed 47 times by 1 test: return masklen <= 32 ? 0 : -1; Executed by:
| 2-47 | ||||||||||||||||||||||||||||||
69 | case AF_INET6: never executed: case 10 : | 0 | ||||||||||||||||||||||||||||||
70 | return masklen <= 128 ? 0 : -1; never executed: return masklen <= 128 ? 0 : -1;
| 0 | ||||||||||||||||||||||||||||||
71 | default: never executed: default: | 0 | ||||||||||||||||||||||||||||||
72 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||||||||
73 | } | - | ||||||||||||||||||||||||||||||
74 | } | - | ||||||||||||||||||||||||||||||
75 | - | |||||||||||||||||||||||||||||||
76 | /* | - | ||||||||||||||||||||||||||||||
77 | * Convert struct sockaddr to struct xaddr | - | ||||||||||||||||||||||||||||||
78 | * Returns 0 on success, -1 on failure. | - | ||||||||||||||||||||||||||||||
79 | */ | - | ||||||||||||||||||||||||||||||
80 | static int | - | ||||||||||||||||||||||||||||||
81 | addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa) | - | ||||||||||||||||||||||||||||||
82 | { | - | ||||||||||||||||||||||||||||||
83 | struct sockaddr_in *in4 = (struct sockaddr_in *)sa; | - | ||||||||||||||||||||||||||||||
84 | struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa; | - | ||||||||||||||||||||||||||||||
85 | - | |||||||||||||||||||||||||||||||
86 | memset(xa, '\0', sizeof(*xa)); | - | ||||||||||||||||||||||||||||||
87 | - | |||||||||||||||||||||||||||||||
88 | switch (sa->sa_family) { | - | ||||||||||||||||||||||||||||||
89 | case AF_INET: executed 31 times by 1 test: case 2 : Executed by:
| 31 | ||||||||||||||||||||||||||||||
90 | if (slen < (socklen_t)sizeof(*in4))
| 0-31 | ||||||||||||||||||||||||||||||
91 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||||||||
92 | xa->af = AF_INET; | - | ||||||||||||||||||||||||||||||
93 | memcpy(&xa->v4, &in4->sin_addr, sizeof(xa->v4)); | - | ||||||||||||||||||||||||||||||
94 | break; executed 31 times by 1 test: break; Executed by:
| 31 | ||||||||||||||||||||||||||||||
95 | case AF_INET6: never executed: case 10 : | 0 | ||||||||||||||||||||||||||||||
96 | if (slen < (socklen_t)sizeof(*in6))
| 0 | ||||||||||||||||||||||||||||||
97 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||||||||
98 | xa->af = AF_INET6; | - | ||||||||||||||||||||||||||||||
99 | memcpy(&xa->v6, &in6->sin6_addr, sizeof(xa->v6)); | - | ||||||||||||||||||||||||||||||
100 | #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID | - | ||||||||||||||||||||||||||||||
101 | xa->scope_id = in6->sin6_scope_id; | - | ||||||||||||||||||||||||||||||
102 | #endif | - | ||||||||||||||||||||||||||||||
103 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
104 | default: never executed: default: | 0 | ||||||||||||||||||||||||||||||
105 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||||||||
106 | } | - | ||||||||||||||||||||||||||||||
107 | - | |||||||||||||||||||||||||||||||
108 | return 0; executed 31 times by 1 test: return 0; Executed by:
| 31 | ||||||||||||||||||||||||||||||
109 | } | - | ||||||||||||||||||||||||||||||
110 | - | |||||||||||||||||||||||||||||||
111 | /* | - | ||||||||||||||||||||||||||||||
112 | * Calculate a netmask of length 'l' for address family 'af' and | - | ||||||||||||||||||||||||||||||
113 | * store it in 'n'. | - | ||||||||||||||||||||||||||||||
114 | * Returns 0 on success, -1 on failure. | - | ||||||||||||||||||||||||||||||
115 | */ | - | ||||||||||||||||||||||||||||||
116 | static int | - | ||||||||||||||||||||||||||||||
117 | addr_netmask(int af, u_int l, struct xaddr *n) | - | ||||||||||||||||||||||||||||||
118 | { | - | ||||||||||||||||||||||||||||||
119 | int i; | - | ||||||||||||||||||||||||||||||
120 | - | |||||||||||||||||||||||||||||||
121 | if (masklen_valid(af, l) != 0 || n == NULL)
| 0-30 | ||||||||||||||||||||||||||||||
122 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||||||||
123 | - | |||||||||||||||||||||||||||||||
124 | memset(n, '\0', sizeof(*n)); | - | ||||||||||||||||||||||||||||||
125 | switch (af) { | - | ||||||||||||||||||||||||||||||
126 | case AF_INET: executed 30 times by 1 test: case 2 : Executed by:
| 30 | ||||||||||||||||||||||||||||||
127 | n->af = AF_INET; | - | ||||||||||||||||||||||||||||||
128 | if (l == 0)
| 0-30 | ||||||||||||||||||||||||||||||
129 | return 0; never executed: return 0; | 0 | ||||||||||||||||||||||||||||||
130 | n->v4.s_addr = htonl((0xffffffff << (32 - l)) & 0xffffffff); | - | ||||||||||||||||||||||||||||||
131 | return 0; executed 30 times by 1 test: return 0; Executed by:
| 30 | ||||||||||||||||||||||||||||||
132 | case AF_INET6: never executed: case 10 : | 0 | ||||||||||||||||||||||||||||||
133 | n->af = AF_INET6; | - | ||||||||||||||||||||||||||||||
134 | for (i = 0; i < 4 && l >= 32; i++, l -= 32)
| 0 | ||||||||||||||||||||||||||||||
135 | n->addr32[i] = 0xffffffffU; never executed: n->xa.addr32[i] = 0xffffffffU; | 0 | ||||||||||||||||||||||||||||||
136 | if (i < 4 && l != 0)
| 0 | ||||||||||||||||||||||||||||||
137 | n->addr32[i] = htonl((0xffffffff << (32 - l)) & never executed: n->xa.addr32[i] = __bswap_32 ( (0xffffffff << (32 - l)) & 0xffffffff ) ; | 0 | ||||||||||||||||||||||||||||||
138 | 0xffffffff); never executed: n->xa.addr32[i] = __bswap_32 ( (0xffffffff << (32 - l)) & 0xffffffff ) ; | 0 | ||||||||||||||||||||||||||||||
139 | return 0; never executed: return 0; | 0 | ||||||||||||||||||||||||||||||
140 | default: never executed: default: | 0 | ||||||||||||||||||||||||||||||
141 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||||||||
142 | } | - | ||||||||||||||||||||||||||||||
143 | } | - | ||||||||||||||||||||||||||||||
144 | - | |||||||||||||||||||||||||||||||
145 | /* | - | ||||||||||||||||||||||||||||||
146 | * Perform logical AND of addresses 'a' and 'b', storing result in 'dst'. | - | ||||||||||||||||||||||||||||||
147 | * Returns 0 on success, -1 on failure. | - | ||||||||||||||||||||||||||||||
148 | */ | - | ||||||||||||||||||||||||||||||
149 | static int | - | ||||||||||||||||||||||||||||||
150 | addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b) | - | ||||||||||||||||||||||||||||||
151 | { | - | ||||||||||||||||||||||||||||||
152 | int i; | - | ||||||||||||||||||||||||||||||
153 | - | |||||||||||||||||||||||||||||||
154 | if (dst == NULL || a == NULL || b == NULL || a->af != b->af)
| 0-30 | ||||||||||||||||||||||||||||||
155 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||||||||
156 | - | |||||||||||||||||||||||||||||||
157 | memcpy(dst, a, sizeof(*dst)); | - | ||||||||||||||||||||||||||||||
158 | switch (a->af) { | - | ||||||||||||||||||||||||||||||
159 | case AF_INET: executed 30 times by 1 test: case 2 : Executed by:
| 30 | ||||||||||||||||||||||||||||||
160 | dst->v4.s_addr &= b->v4.s_addr; | - | ||||||||||||||||||||||||||||||
161 | return 0; executed 30 times by 1 test: return 0; Executed by:
| 30 | ||||||||||||||||||||||||||||||
162 | case AF_INET6: never executed: case 10 : | 0 | ||||||||||||||||||||||||||||||
163 | dst->scope_id = a->scope_id; | - | ||||||||||||||||||||||||||||||
164 | for (i = 0; i < 4; i++)
| 0 | ||||||||||||||||||||||||||||||
165 | dst->addr32[i] &= b->addr32[i]; never executed: dst->xa.addr32[i] &= b->xa.addr32[i]; | 0 | ||||||||||||||||||||||||||||||
166 | return 0; never executed: return 0; | 0 | ||||||||||||||||||||||||||||||
167 | default: never executed: default: | 0 | ||||||||||||||||||||||||||||||
168 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||||||||
169 | } | - | ||||||||||||||||||||||||||||||
170 | } | - | ||||||||||||||||||||||||||||||
171 | - | |||||||||||||||||||||||||||||||
172 | /* | - | ||||||||||||||||||||||||||||||
173 | * Compare addresses 'a' and 'b' | - | ||||||||||||||||||||||||||||||
174 | * Return 0 if addresses are identical, -1 if (a < b) or 1 if (a > b) | - | ||||||||||||||||||||||||||||||
175 | */ | - | ||||||||||||||||||||||||||||||
176 | static int | - | ||||||||||||||||||||||||||||||
177 | addr_cmp(const struct xaddr *a, const struct xaddr *b) | - | ||||||||||||||||||||||||||||||
178 | { | - | ||||||||||||||||||||||||||||||
179 | int i; | - | ||||||||||||||||||||||||||||||
180 | - | |||||||||||||||||||||||||||||||
181 | if (a->af != b->af)
| 0-15 | ||||||||||||||||||||||||||||||
182 | return a->af == AF_INET6 ? 1 : -1; never executed: return a->af == 10 ? 1 : -1;
| 0 | ||||||||||||||||||||||||||||||
183 | - | |||||||||||||||||||||||||||||||
184 | switch (a->af) { | - | ||||||||||||||||||||||||||||||
185 | case AF_INET: executed 15 times by 1 test: case 2 : Executed by:
| 15 | ||||||||||||||||||||||||||||||
186 | if (a->v4.s_addr == b->v4.s_addr)
| 7-8 | ||||||||||||||||||||||||||||||
187 | return 0; executed 7 times by 1 test: return 0; Executed by:
| 7 | ||||||||||||||||||||||||||||||
188 | return ntohl(a->v4.s_addr) > ntohl(b->v4.s_addr) ? 1 : -1; executed 8 times by 1 test: return __bswap_32 ( a->xa.v4.s_addr ) > __bswap_32 ( b->xa.v4.s_addr ) ? 1 : -1; Executed by:
| 4-8 | ||||||||||||||||||||||||||||||
189 | case AF_INET6: never executed: case 10 : | 0 | ||||||||||||||||||||||||||||||
190 | for (i = 0; i < 16; i++)
| 0 | ||||||||||||||||||||||||||||||
191 | if (a->addr8[i] - b->addr8[i] != 0)
| 0 | ||||||||||||||||||||||||||||||
192 | return a->addr8[i] > b->addr8[i] ? 1 : -1; never executed: return a->xa.addr8[i] > b->xa.addr8[i] ? 1 : -1;
| 0 | ||||||||||||||||||||||||||||||
193 | if (a->scope_id == b->scope_id)
| 0 | ||||||||||||||||||||||||||||||
194 | return 0; never executed: return 0; | 0 | ||||||||||||||||||||||||||||||
195 | return a->scope_id > b->scope_id ? 1 : -1; never executed: return a->scope_id > b->scope_id ? 1 : -1;
| 0 | ||||||||||||||||||||||||||||||
196 | default: never executed: default: | 0 | ||||||||||||||||||||||||||||||
197 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||||||||
198 | } | - | ||||||||||||||||||||||||||||||
199 | } | - | ||||||||||||||||||||||||||||||
200 | - | |||||||||||||||||||||||||||||||
201 | /* | - | ||||||||||||||||||||||||||||||
202 | * Parse string address 'p' into 'n' | - | ||||||||||||||||||||||||||||||
203 | * Returns 0 on success, -1 on failure. | - | ||||||||||||||||||||||||||||||
204 | */ | - | ||||||||||||||||||||||||||||||
205 | static int | - | ||||||||||||||||||||||||||||||
206 | addr_pton(const char *p, struct xaddr *n) | - | ||||||||||||||||||||||||||||||
207 | { | - | ||||||||||||||||||||||||||||||
208 | struct addrinfo hints, *ai = NULL; | - | ||||||||||||||||||||||||||||||
209 | int ret = -1; | - | ||||||||||||||||||||||||||||||
210 | - | |||||||||||||||||||||||||||||||
211 | memset(&hints, '\0', sizeof(hints)); | - | ||||||||||||||||||||||||||||||
212 | hints.ai_flags = AI_NUMERICHOST; | - | ||||||||||||||||||||||||||||||
213 | - | |||||||||||||||||||||||||||||||
214 | if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0)
| 0-34 | ||||||||||||||||||||||||||||||
215 | goto out; executed 3 times by 1 test: goto out; Executed by:
| 3 | ||||||||||||||||||||||||||||||
216 | if (ai == NULL || ai->ai_addr == NULL)
| 0-31 | ||||||||||||||||||||||||||||||
217 | goto out; never executed: goto out; | 0 | ||||||||||||||||||||||||||||||
218 | if (n != NULL && addr_sa_to_xaddr(ai->ai_addr, ai->ai_addrlen, n) == -1)
| 0-31 | ||||||||||||||||||||||||||||||
219 | goto out; never executed: goto out; | 0 | ||||||||||||||||||||||||||||||
220 | /* success */ | - | ||||||||||||||||||||||||||||||
221 | ret = 0; | - | ||||||||||||||||||||||||||||||
222 | out: code before this statement executed 31 times by 1 test: out: Executed by:
| 31 | ||||||||||||||||||||||||||||||
223 | if (ai != NULL)
| 3-31 | ||||||||||||||||||||||||||||||
224 | freeaddrinfo(ai); executed 31 times by 1 test: freeaddrinfo(ai); Executed by:
| 31 | ||||||||||||||||||||||||||||||
225 | return ret; executed 34 times by 1 test: return ret; Executed by:
| 34 | ||||||||||||||||||||||||||||||
226 | } | - | ||||||||||||||||||||||||||||||
227 | - | |||||||||||||||||||||||||||||||
228 | /* | - | ||||||||||||||||||||||||||||||
229 | * Perform bitwise negation of address | - | ||||||||||||||||||||||||||||||
230 | * Returns 0 on success, -1 on failure. | - | ||||||||||||||||||||||||||||||
231 | */ | - | ||||||||||||||||||||||||||||||
232 | static int | - | ||||||||||||||||||||||||||||||
233 | addr_invert(struct xaddr *n) | - | ||||||||||||||||||||||||||||||
234 | { | - | ||||||||||||||||||||||||||||||
235 | int i; | - | ||||||||||||||||||||||||||||||
236 | - | |||||||||||||||||||||||||||||||
237 | if (n == NULL)
| 0-15 | ||||||||||||||||||||||||||||||
238 | return (-1); never executed: return (-1); | 0 | ||||||||||||||||||||||||||||||
239 | - | |||||||||||||||||||||||||||||||
240 | switch (n->af) { | - | ||||||||||||||||||||||||||||||
241 | case AF_INET: executed 15 times by 1 test: case 2 : Executed by:
| 15 | ||||||||||||||||||||||||||||||
242 | n->v4.s_addr = ~n->v4.s_addr; | - | ||||||||||||||||||||||||||||||
243 | return (0); executed 15 times by 1 test: return (0); Executed by:
| 15 | ||||||||||||||||||||||||||||||
244 | case AF_INET6: never executed: case 10 : | 0 | ||||||||||||||||||||||||||||||
245 | for (i = 0; i < 4; i++)
| 0 | ||||||||||||||||||||||||||||||
246 | n->addr32[i] = ~n->addr32[i]; never executed: n->xa.addr32[i] = ~n->xa.addr32[i]; | 0 | ||||||||||||||||||||||||||||||
247 | return (0); never executed: return (0); | 0 | ||||||||||||||||||||||||||||||
248 | default: never executed: default: | 0 | ||||||||||||||||||||||||||||||
249 | return (-1); never executed: return (-1); | 0 | ||||||||||||||||||||||||||||||
250 | } | - | ||||||||||||||||||||||||||||||
251 | } | - | ||||||||||||||||||||||||||||||
252 | - | |||||||||||||||||||||||||||||||
253 | /* | - | ||||||||||||||||||||||||||||||
254 | * Calculate a netmask of length 'l' for address family 'af' and | - | ||||||||||||||||||||||||||||||
255 | * store it in 'n'. | - | ||||||||||||||||||||||||||||||
256 | * Returns 0 on success, -1 on failure. | - | ||||||||||||||||||||||||||||||
257 | */ | - | ||||||||||||||||||||||||||||||
258 | static int | - | ||||||||||||||||||||||||||||||
259 | addr_hostmask(int af, u_int l, struct xaddr *n) | - | ||||||||||||||||||||||||||||||
260 | { | - | ||||||||||||||||||||||||||||||
261 | if (addr_netmask(af, l, n) == -1 || addr_invert(n) == -1)
| 0-15 | ||||||||||||||||||||||||||||||
262 | return (-1); never executed: return (-1); | 0 | ||||||||||||||||||||||||||||||
263 | return (0); executed 15 times by 1 test: return (0); Executed by:
| 15 | ||||||||||||||||||||||||||||||
264 | } | - | ||||||||||||||||||||||||||||||
265 | - | |||||||||||||||||||||||||||||||
266 | /* | - | ||||||||||||||||||||||||||||||
267 | * Test whether address 'a' is all zeros (i.e. 0.0.0.0 or ::) | - | ||||||||||||||||||||||||||||||
268 | * Returns 0 on if address is all-zeros, -1 if not all zeros or on failure. | - | ||||||||||||||||||||||||||||||
269 | */ | - | ||||||||||||||||||||||||||||||
270 | static int | - | ||||||||||||||||||||||||||||||
271 | addr_is_all0s(const struct xaddr *a) | - | ||||||||||||||||||||||||||||||
272 | { | - | ||||||||||||||||||||||||||||||
273 | int i; | - | ||||||||||||||||||||||||||||||
274 | - | |||||||||||||||||||||||||||||||
275 | switch (a->af) { | - | ||||||||||||||||||||||||||||||
276 | case AF_INET: executed 15 times by 1 test: case 2 : Executed by:
| 15 | ||||||||||||||||||||||||||||||
277 | return (a->v4.s_addr == 0 ? 0 : -1); executed 15 times by 1 test: return (a->xa.v4.s_addr == 0 ? 0 : -1); Executed by:
| 0-15 | ||||||||||||||||||||||||||||||
278 | case AF_INET6:; never executed: case 10 : | 0 | ||||||||||||||||||||||||||||||
279 | for (i = 0; i < 4; i++)
| 0 | ||||||||||||||||||||||||||||||
280 | if (a->addr32[i] != 0)
| 0 | ||||||||||||||||||||||||||||||
281 | return (-1); never executed: return (-1); | 0 | ||||||||||||||||||||||||||||||
282 | return (0); never executed: return (0); | 0 | ||||||||||||||||||||||||||||||
283 | default: never executed: default: | 0 | ||||||||||||||||||||||||||||||
284 | return (-1); never executed: return (-1); | 0 | ||||||||||||||||||||||||||||||
285 | } | - | ||||||||||||||||||||||||||||||
286 | } | - | ||||||||||||||||||||||||||||||
287 | - | |||||||||||||||||||||||||||||||
288 | /* | - | ||||||||||||||||||||||||||||||
289 | * Test whether host portion of address 'a', as determined by 'masklen' | - | ||||||||||||||||||||||||||||||
290 | * is all zeros. | - | ||||||||||||||||||||||||||||||
291 | * Returns 0 on if host portion of address is all-zeros, | - | ||||||||||||||||||||||||||||||
292 | * -1 if not all zeros or on failure. | - | ||||||||||||||||||||||||||||||
293 | */ | - | ||||||||||||||||||||||||||||||
294 | static int | - | ||||||||||||||||||||||||||||||
295 | addr_host_is_all0s(const struct xaddr *a, u_int masklen) | - | ||||||||||||||||||||||||||||||
296 | { | - | ||||||||||||||||||||||||||||||
297 | struct xaddr tmp_addr, tmp_mask, tmp_result; | - | ||||||||||||||||||||||||||||||
298 | - | |||||||||||||||||||||||||||||||
299 | memcpy(&tmp_addr, a, sizeof(tmp_addr)); | - | ||||||||||||||||||||||||||||||
300 | if (addr_hostmask(a->af, masklen, &tmp_mask) == -1)
| 0-15 | ||||||||||||||||||||||||||||||
301 | return (-1); never executed: return (-1); | 0 | ||||||||||||||||||||||||||||||
302 | if (addr_and(&tmp_result, &tmp_addr, &tmp_mask) == -1)
| 0-15 | ||||||||||||||||||||||||||||||
303 | return (-1); never executed: return (-1); | 0 | ||||||||||||||||||||||||||||||
304 | return (addr_is_all0s(&tmp_result)); executed 15 times by 1 test: return (addr_is_all0s(&tmp_result)); Executed by:
| 15 | ||||||||||||||||||||||||||||||
305 | } | - | ||||||||||||||||||||||||||||||
306 | - | |||||||||||||||||||||||||||||||
307 | /* | - | ||||||||||||||||||||||||||||||
308 | * Parse a CIDR address (x.x.x.x/y or xxxx:yyyy::/z). | - | ||||||||||||||||||||||||||||||
309 | * Return -1 on parse error, -2 on inconsistency or 0 on success. | - | ||||||||||||||||||||||||||||||
310 | */ | - | ||||||||||||||||||||||||||||||
311 | static int | - | ||||||||||||||||||||||||||||||
312 | addr_pton_cidr(const char *p, struct xaddr *n, u_int *l) | - | ||||||||||||||||||||||||||||||
313 | { | - | ||||||||||||||||||||||||||||||
314 | struct xaddr tmp; | - | ||||||||||||||||||||||||||||||
315 | long unsigned int masklen = 999; | - | ||||||||||||||||||||||||||||||
316 | char addrbuf[64], *mp, *cp; | - | ||||||||||||||||||||||||||||||
317 | - | |||||||||||||||||||||||||||||||
318 | /* Don't modify argument */ | - | ||||||||||||||||||||||||||||||
319 | if (p == NULL || strlcpy(addrbuf, p, sizeof(addrbuf)) >= sizeof(addrbuf))
| 0-19 | ||||||||||||||||||||||||||||||
320 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||||||||
321 | - | |||||||||||||||||||||||||||||||
322 | if ((mp = strchr(addrbuf, '/')) != NULL) {
| 0-19 | ||||||||||||||||||||||||||||||
323 | *mp = '\0'; | - | ||||||||||||||||||||||||||||||
324 | mp++; | - | ||||||||||||||||||||||||||||||
325 | masklen = strtoul(mp, &cp, 10); | - | ||||||||||||||||||||||||||||||
326 | if (*mp == '\0' || *cp != '\0' || masklen > 128)
| 0-7 | ||||||||||||||||||||||||||||||
327 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||||||||
328 | } executed 7 times by 1 test: end of block Executed by:
| 7 | ||||||||||||||||||||||||||||||
329 | - | |||||||||||||||||||||||||||||||
330 | if (addr_pton(addrbuf, &tmp) == -1)
| 2-17 | ||||||||||||||||||||||||||||||
331 | return -1; executed 2 times by 1 test: return -1; Executed by:
| 2 | ||||||||||||||||||||||||||||||
332 | - | |||||||||||||||||||||||||||||||
333 | if (mp == NULL)
| 7-10 | ||||||||||||||||||||||||||||||
334 | masklen = addr_unicast_masklen(tmp.af); executed 10 times by 1 test: masklen = addr_unicast_masklen(tmp.af); Executed by:
| 10 | ||||||||||||||||||||||||||||||
335 | if (masklen_valid(tmp.af, masklen) == -1)
| 2-15 | ||||||||||||||||||||||||||||||
336 | return -2; executed 2 times by 1 test: return -2; Executed by:
| 2 | ||||||||||||||||||||||||||||||
337 | if (addr_host_is_all0s(&tmp, masklen) != 0)
| 0-15 | ||||||||||||||||||||||||||||||
338 | return -2; never executed: return -2; | 0 | ||||||||||||||||||||||||||||||
339 | - | |||||||||||||||||||||||||||||||
340 | if (n != NULL)
| 0-15 | ||||||||||||||||||||||||||||||
341 | memcpy(n, &tmp, sizeof(*n)); executed 15 times by 1 test: memcpy(n, &tmp, sizeof(*n)); Executed by:
| 15 | ||||||||||||||||||||||||||||||
342 | if (l != NULL)
| 0-15 | ||||||||||||||||||||||||||||||
343 | *l = masklen; executed 15 times by 1 test: *l = masklen; Executed by:
| 15 | ||||||||||||||||||||||||||||||
344 | - | |||||||||||||||||||||||||||||||
345 | return 0; executed 15 times by 1 test: return 0; Executed by:
| 15 | ||||||||||||||||||||||||||||||
346 | } | - | ||||||||||||||||||||||||||||||
347 | - | |||||||||||||||||||||||||||||||
348 | static int | - | ||||||||||||||||||||||||||||||
349 | addr_netmatch(const struct xaddr *host, const struct xaddr *net, u_int masklen) | - | ||||||||||||||||||||||||||||||
350 | { | - | ||||||||||||||||||||||||||||||
351 | struct xaddr tmp_mask, tmp_result; | - | ||||||||||||||||||||||||||||||
352 | - | |||||||||||||||||||||||||||||||
353 | if (host->af != net->af)
| 0-15 | ||||||||||||||||||||||||||||||
354 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||||||||
355 | - | |||||||||||||||||||||||||||||||
356 | if (addr_netmask(host->af, masklen, &tmp_mask) == -1)
| 0-15 | ||||||||||||||||||||||||||||||
357 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||||||||
358 | if (addr_and(&tmp_result, host, &tmp_mask) == -1)
| 0-15 | ||||||||||||||||||||||||||||||
359 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||||||||
360 | return addr_cmp(&tmp_result, net); executed 15 times by 1 test: return addr_cmp(&tmp_result, net); Executed by:
| 15 | ||||||||||||||||||||||||||||||
361 | } | - | ||||||||||||||||||||||||||||||
362 | - | |||||||||||||||||||||||||||||||
363 | /* | - | ||||||||||||||||||||||||||||||
364 | * Match "addr" against list pattern list "_list", which may contain a | - | ||||||||||||||||||||||||||||||
365 | * mix of CIDR addresses and old-school wildcards. | - | ||||||||||||||||||||||||||||||
366 | * | - | ||||||||||||||||||||||||||||||
367 | * If addr is NULL, then no matching is performed, but _list is parsed | - | ||||||||||||||||||||||||||||||
368 | * and checked for well-formedness. | - | ||||||||||||||||||||||||||||||
369 | * | - | ||||||||||||||||||||||||||||||
370 | * Returns 1 on match found (never returned when addr == NULL). | - | ||||||||||||||||||||||||||||||
371 | * Returns 0 on if no match found, or no errors found when addr == NULL. | - | ||||||||||||||||||||||||||||||
372 | * Returns -1 on negated match found (never returned when addr == NULL). | - | ||||||||||||||||||||||||||||||
373 | * Returns -2 on invalid list entry. | - | ||||||||||||||||||||||||||||||
374 | */ | - | ||||||||||||||||||||||||||||||
375 | int | - | ||||||||||||||||||||||||||||||
376 | addr_match_list(const char *addr, const char *_list) | - | ||||||||||||||||||||||||||||||
377 | { | - | ||||||||||||||||||||||||||||||
378 | char *list, *cp, *o; | - | ||||||||||||||||||||||||||||||
379 | struct xaddr try_addr, match_addr; | - | ||||||||||||||||||||||||||||||
380 | u_int masklen, neg; | - | ||||||||||||||||||||||||||||||
381 | int ret = 0, r; | - | ||||||||||||||||||||||||||||||
382 | - | |||||||||||||||||||||||||||||||
383 | if (addr != NULL && addr_pton(addr, &try_addr) != 0) {
| 1-15 | ||||||||||||||||||||||||||||||
384 | debug2("%s: couldn't parse address %.100s", __func__, addr); | - | ||||||||||||||||||||||||||||||
385 | return 0; executed 1 time by 1 test: return 0; Executed by:
| 1 | ||||||||||||||||||||||||||||||
386 | } | - | ||||||||||||||||||||||||||||||
387 | if ((o = list = strdup(_list)) == NULL) never executed: __retval = (char *) memcpy (__retval, _list , __len);
| 0-16 | ||||||||||||||||||||||||||||||
388 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||||||||
389 | while ((cp = strsep(&list, ",")) != NULL) {
| 10-19 | ||||||||||||||||||||||||||||||
390 | neg = *cp == '!'; | - | ||||||||||||||||||||||||||||||
391 | if (neg)
| 4-15 | ||||||||||||||||||||||||||||||
392 | cp++; executed 4 times by 1 test: cp++; Executed by:
| 4 | ||||||||||||||||||||||||||||||
393 | if (*cp == '\0') {
| 0-19 | ||||||||||||||||||||||||||||||
394 | ret = -2; | - | ||||||||||||||||||||||||||||||
395 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
396 | } | - | ||||||||||||||||||||||||||||||
397 | /* Prefer CIDR address matching */ | - | ||||||||||||||||||||||||||||||
398 | r = addr_pton_cidr(cp, &match_addr, &masklen); | - | ||||||||||||||||||||||||||||||
399 | if (r == -2) {
| 2-17 | ||||||||||||||||||||||||||||||
400 | debug2("%s: inconsistent mask length for " | - | ||||||||||||||||||||||||||||||
401 | "match network \"%.100s\"", __func__, cp); | - | ||||||||||||||||||||||||||||||
402 | ret = -2; | - | ||||||||||||||||||||||||||||||
403 | break; executed 2 times by 1 test: break; Executed by:
| 2 | ||||||||||||||||||||||||||||||
404 | } else if (r == 0) {
| 2-15 | ||||||||||||||||||||||||||||||
405 | if (addr != NULL && addr_netmatch(&try_addr,
| 0-15 | ||||||||||||||||||||||||||||||
406 | &match_addr, masklen) == 0) {
| 7-8 | ||||||||||||||||||||||||||||||
407 | foundit: | - | ||||||||||||||||||||||||||||||
408 | if (neg) {
| 4 | ||||||||||||||||||||||||||||||
409 | ret = -1; | - | ||||||||||||||||||||||||||||||
410 | break; executed 4 times by 1 test: break; Executed by:
| 4 | ||||||||||||||||||||||||||||||
411 | } | - | ||||||||||||||||||||||||||||||
412 | ret = 1; | - | ||||||||||||||||||||||||||||||
413 | } executed 4 times by 1 test: end of block Executed by:
| 4 | ||||||||||||||||||||||||||||||
414 | continue; executed 12 times by 1 test: continue; Executed by:
| 12 | ||||||||||||||||||||||||||||||
415 | } else { | - | ||||||||||||||||||||||||||||||
416 | /* If CIDR parse failed, try wildcard string match */ | - | ||||||||||||||||||||||||||||||
417 | if (addr != NULL && match_pattern(addr, cp) == 1)
| 0-1 | ||||||||||||||||||||||||||||||
418 | goto foundit; executed 1 time by 1 test: goto foundit; Executed by:
| 1 | ||||||||||||||||||||||||||||||
419 | } executed 1 time by 1 test: end of block Executed by:
| 1 | ||||||||||||||||||||||||||||||
420 | } | - | ||||||||||||||||||||||||||||||
421 | free(o); | - | ||||||||||||||||||||||||||||||
422 | - | |||||||||||||||||||||||||||||||
423 | return ret; executed 16 times by 1 test: return ret; Executed by:
| 16 | ||||||||||||||||||||||||||||||
424 | } | - | ||||||||||||||||||||||||||||||
425 | - | |||||||||||||||||||||||||||||||
426 | /* | - | ||||||||||||||||||||||||||||||
427 | * Match "addr" against list CIDR list "_list". Lexical wildcards and | - | ||||||||||||||||||||||||||||||
428 | * negation are not supported. If "addr" == NULL, will verify structure | - | ||||||||||||||||||||||||||||||
429 | * of "_list". | - | ||||||||||||||||||||||||||||||
430 | * | - | ||||||||||||||||||||||||||||||
431 | * Returns 1 on match found (never returned when addr == NULL). | - | ||||||||||||||||||||||||||||||
432 | * Returns 0 on if no match found, or no errors found when addr == NULL. | - | ||||||||||||||||||||||||||||||
433 | * Returns -1 on error | - | ||||||||||||||||||||||||||||||
434 | */ | - | ||||||||||||||||||||||||||||||
435 | int | - | ||||||||||||||||||||||||||||||
436 | addr_match_cidr_list(const char *addr, const char *_list) | - | ||||||||||||||||||||||||||||||
437 | { | - | ||||||||||||||||||||||||||||||
438 | char *list, *cp, *o; | - | ||||||||||||||||||||||||||||||
439 | struct xaddr try_addr, match_addr; | - | ||||||||||||||||||||||||||||||
440 | u_int masklen; | - | ||||||||||||||||||||||||||||||
441 | int ret = 0, r; | - | ||||||||||||||||||||||||||||||
442 | - | |||||||||||||||||||||||||||||||
443 | if (addr != NULL && addr_pton(addr, &try_addr) != 0) {
| 0 | ||||||||||||||||||||||||||||||
444 | debug2("%s: couldn't parse address %.100s", __func__, addr); | - | ||||||||||||||||||||||||||||||
445 | return 0; never executed: return 0; | 0 | ||||||||||||||||||||||||||||||
446 | } | - | ||||||||||||||||||||||||||||||
447 | if ((o = list = strdup(_list)) == NULL) never executed: __retval = (char *) memcpy (__retval, _list , __len);
| 0 | ||||||||||||||||||||||||||||||
448 | return -1; never executed: return -1; | 0 | ||||||||||||||||||||||||||||||
449 | while ((cp = strsep(&list, ",")) != NULL) {
| 0 | ||||||||||||||||||||||||||||||
450 | if (*cp == '\0') {
| 0 | ||||||||||||||||||||||||||||||
451 | error("%s: empty entry in list \"%.100s\"", | - | ||||||||||||||||||||||||||||||
452 | __func__, o); | - | ||||||||||||||||||||||||||||||
453 | ret = -1; | - | ||||||||||||||||||||||||||||||
454 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
455 | } | - | ||||||||||||||||||||||||||||||
456 | - | |||||||||||||||||||||||||||||||
457 | /* | - | ||||||||||||||||||||||||||||||
458 | * NB. This function is called in pre-auth with untrusted data, | - | ||||||||||||||||||||||||||||||
459 | * so be extra paranoid about junk reaching getaddrino (via | - | ||||||||||||||||||||||||||||||
460 | * addr_pton_cidr). | - | ||||||||||||||||||||||||||||||
461 | */ | - | ||||||||||||||||||||||||||||||
462 | - | |||||||||||||||||||||||||||||||
463 | /* Stop junk from reaching getaddrinfo. +3 is for masklen */ | - | ||||||||||||||||||||||||||||||
464 | if (strlen(cp) > INET6_ADDRSTRLEN + 3) {
| 0 | ||||||||||||||||||||||||||||||
465 | error("%s: list entry \"%.100s\" too long", | - | ||||||||||||||||||||||||||||||
466 | __func__, cp); | - | ||||||||||||||||||||||||||||||
467 | ret = -1; | - | ||||||||||||||||||||||||||||||
468 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
469 | } | - | ||||||||||||||||||||||||||||||
470 | #define VALID_CIDR_CHARS "0123456789abcdefABCDEF.:/" | - | ||||||||||||||||||||||||||||||
471 | if (strspn(cp, VALID_CIDR_CHARS) != strlen(cp)) {
| 0 | ||||||||||||||||||||||||||||||
472 | error("%s: list entry \"%.100s\" contains invalid " | - | ||||||||||||||||||||||||||||||
473 | "characters", __func__, cp); | - | ||||||||||||||||||||||||||||||
474 | ret = -1; | - | ||||||||||||||||||||||||||||||
475 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
476 | - | |||||||||||||||||||||||||||||||
477 | /* Prefer CIDR address matching */ | - | ||||||||||||||||||||||||||||||
478 | r = addr_pton_cidr(cp, &match_addr, &masklen); | - | ||||||||||||||||||||||||||||||
479 | if (r == -1) {
| 0 | ||||||||||||||||||||||||||||||
480 | error("Invalid network entry \"%.100s\"", cp); | - | ||||||||||||||||||||||||||||||
481 | ret = -1; | - | ||||||||||||||||||||||||||||||
482 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
483 | } else if (r == -2) {
| 0 | ||||||||||||||||||||||||||||||
484 | error("Inconsistent mask length for " | - | ||||||||||||||||||||||||||||||
485 | "network \"%.100s\"", cp); | - | ||||||||||||||||||||||||||||||
486 | ret = -1; | - | ||||||||||||||||||||||||||||||
487 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
488 | } else if (r == 0 && addr != NULL) {
| 0 | ||||||||||||||||||||||||||||||
489 | if (addr_netmatch(&try_addr, &match_addr,
| 0 | ||||||||||||||||||||||||||||||
490 | masklen) == 0)
| 0 | ||||||||||||||||||||||||||||||
491 | ret = 1; never executed: ret = 1; | 0 | ||||||||||||||||||||||||||||||
492 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||||||||
493 | } | - | ||||||||||||||||||||||||||||||
494 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
495 | free(o); | - | ||||||||||||||||||||||||||||||
496 | - | |||||||||||||||||||||||||||||||
497 | return ret; never executed: return ret; | 0 | ||||||||||||||||||||||||||||||
498 | } | - | ||||||||||||||||||||||||||||||
Source code | Switch to Preprocessed file |