| 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 |