1 /* $OpenBSD: pfkeyv2_parsemessage.c,v 1.60 2021/07/14 22:39:26 tobhe Exp $ */ 2 3 /* 4 * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995 5 * 6 * NRL grants permission for redistribution and use in source and binary 7 * forms, with or without modification, of the software and documentation 8 * created at NRL provided that the following conditions are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgements: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * This product includes software developed at the Information 20 * Technology Division, US Naval Research Laboratory. 21 * 4. Neither the name of the NRL nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS 26 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 28 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR 29 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 30 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 31 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * The views and conclusions contained in the software and documentation 38 * are those of the authors and should not be interpreted as representing 39 * official policies, either expressed or implied, of the US Naval 40 * Research Laboratory (NRL). 41 */ 42 43 /* 44 * Copyright (c) 1995, 1996, 1997, 1998, 1999 Craig Metz. All rights reserved. 45 * 46 * Redistribution and use in source and binary forms, with or without 47 * modification, are permitted provided that the following conditions 48 * are met: 49 * 1. Redistributions of source code must retain the above copyright 50 * notice, this list of conditions and the following disclaimer. 51 * 2. Redistributions in binary form must reproduce the above copyright 52 * notice, this list of conditions and the following disclaimer in the 53 * documentation and/or other materials provided with the distribution. 54 * 3. Neither the name of the author nor the names of any contributors 55 * may be used to endorse or promote products derived from this software 56 * without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * SUCH DAMAGE. 69 */ 70 71 #include "pf.h" 72 73 #include <sys/param.h> 74 #include <sys/systm.h> 75 #include <sys/socket.h> 76 #include <sys/mbuf.h> 77 #include <sys/proc.h> 78 #include <netinet/ip_ipsp.h> 79 #include <net/pfkeyv2.h> 80 81 #if NPF > 0 82 #include <net/if.h> 83 #include <net/pfvar.h> 84 #endif 85 86 #ifdef ENCDEBUG 87 #define DPRINTF(fmt, args...) \ 88 do { \ 89 if (encdebug) \ 90 printf("%s: " fmt "\n", __func__, ## args); \ 91 } while (0) 92 #else 93 #define DPRINTF(fmt, args...) \ 94 do { } while (0) 95 #endif 96 97 #define BITMAP_SA (1LL << SADB_EXT_SA) 98 #define BITMAP_LIFETIME_CURRENT (1LL << SADB_EXT_LIFETIME_CURRENT) 99 #define BITMAP_LIFETIME_HARD (1LL << SADB_EXT_LIFETIME_HARD) 100 #define BITMAP_LIFETIME_SOFT (1LL << SADB_EXT_LIFETIME_SOFT) 101 #define BITMAP_ADDRESS_SRC (1LL << SADB_EXT_ADDRESS_SRC) 102 #define BITMAP_ADDRESS_DST (1LL << SADB_EXT_ADDRESS_DST) 103 #define BITMAP_ADDRESS_PROXY (1LL << SADB_EXT_ADDRESS_PROXY) 104 #define BITMAP_KEY_AUTH (1LL << SADB_EXT_KEY_AUTH) 105 #define BITMAP_KEY_ENCRYPT (1LL << SADB_EXT_KEY_ENCRYPT) 106 #define BITMAP_IDENTITY_SRC (1LL << SADB_EXT_IDENTITY_SRC) 107 #define BITMAP_IDENTITY_DST (1LL << SADB_EXT_IDENTITY_DST) 108 #define BITMAP_SENSITIVITY (1LL << SADB_EXT_SENSITIVITY) 109 #define BITMAP_PROPOSAL (1LL << SADB_EXT_PROPOSAL) 110 #define BITMAP_SUPPORTED_AUTH (1LL << SADB_EXT_SUPPORTED_AUTH) 111 #define BITMAP_SUPPORTED_ENCRYPT (1LL << SADB_EXT_SUPPORTED_ENCRYPT) 112 #define BITMAP_SPIRANGE (1LL << SADB_EXT_SPIRANGE) 113 #define BITMAP_LIFETIME (BITMAP_LIFETIME_CURRENT | BITMAP_LIFETIME_HARD | BITMAP_LIFETIME_SOFT) 114 #define BITMAP_ADDRESS (BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST) 115 #define BITMAP_KEY (BITMAP_KEY_AUTH | BITMAP_KEY_ENCRYPT) 116 #define BITMAP_IDENTITY (BITMAP_IDENTITY_SRC | BITMAP_IDENTITY_DST) 117 #define BITMAP_MSG 1 118 #define BITMAP_X_SRC_MASK (1LL << SADB_X_EXT_SRC_MASK) 119 #define BITMAP_X_DST_MASK (1LL << SADB_X_EXT_DST_MASK) 120 #define BITMAP_X_PROTOCOL (1LL << SADB_X_EXT_PROTOCOL) 121 #define BITMAP_X_SRC_FLOW (1LL << SADB_X_EXT_SRC_FLOW) 122 #define BITMAP_X_DST_FLOW (1LL << SADB_X_EXT_DST_FLOW) 123 #define BITMAP_X_FLOW_TYPE (1LL << SADB_X_EXT_FLOW_TYPE) 124 #define BITMAP_X_SA2 (1LL << SADB_X_EXT_SA2) 125 #define BITMAP_X_DST2 (1LL << SADB_X_EXT_DST2) 126 #define BITMAP_X_POLICY (1LL << SADB_X_EXT_POLICY) 127 #define BITMAP_X_FLOW (BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE) 128 #define BITMAP_X_SUPPORTED_COMP (1LL << SADB_X_EXT_SUPPORTED_COMP) 129 #define BITMAP_X_UDPENCAP (1LL << SADB_X_EXT_UDPENCAP) 130 #define BITMAP_X_LIFETIME_LASTUSE (1LL << SADB_X_EXT_LIFETIME_LASTUSE) 131 #define BITMAP_X_TAG (1LL << SADB_X_EXT_TAG) 132 #define BITMAP_X_TAP (1LL << SADB_X_EXT_TAP) 133 #define BITMAP_X_SATYPE2 (1LL << SADB_X_EXT_SATYPE2) 134 #define BITMAP_X_RDOMAIN (1LL << SADB_X_EXT_RDOMAIN) 135 #define BITMAP_X_COUNTER (1LL << SADB_X_EXT_COUNTER) 136 #define BITMAP_X_MTU (1LL << SADB_X_EXT_MTU) 137 #define BITMAP_X_REPLAY (1LL << SADB_X_EXT_REPLAY) 138 139 uint64_t sadb_exts_allowed_in[SADB_MAX+1] = 140 { 141 /* RESERVED */ 142 ~0, 143 /* GETSPI */ 144 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_SPIRANGE, 145 /* UPDATE */ 146 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_ADDRESS_PROXY | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN, 147 /* ADD */ 148 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN, 149 /* DELETE */ 150 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_X_RDOMAIN, 151 /* GET */ 152 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_X_RDOMAIN, 153 /* ACQUIRE */ 154 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_IDENTITY | BITMAP_PROPOSAL, 155 /* REGISTER */ 156 0, 157 /* EXPIRE */ 158 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST, 159 /* FLUSH */ 160 0, 161 /* DUMP */ 162 0, 163 /* X_PROMISC */ 164 0, 165 /* X_ADDFLOW */ 166 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_IDENTITY_SRC | BITMAP_IDENTITY_DST | BITMAP_X_FLOW | BITMAP_X_RDOMAIN, 167 /* X_DELFLOW */ 168 BITMAP_X_FLOW | BITMAP_X_RDOMAIN, 169 /* X_GRPSPIS */ 170 BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_SATYPE2 | BITMAP_X_RDOMAIN, 171 /* X_ASKPOLICY */ 172 BITMAP_X_POLICY, 173 }; 174 175 uint64_t sadb_exts_required_in[SADB_MAX+1] = 176 { 177 /* RESERVED */ 178 0, 179 /* GETSPI */ 180 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_SPIRANGE, 181 /* UPDATE */ 182 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST, 183 /* ADD */ 184 BITMAP_SA | BITMAP_ADDRESS_DST, 185 /* DELETE */ 186 BITMAP_SA | BITMAP_ADDRESS_DST, 187 /* GET */ 188 BITMAP_SA | BITMAP_ADDRESS_DST, 189 /* ACQUIRE */ 190 0, 191 /* REGISTER */ 192 0, 193 /* EXPIRE */ 194 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST, 195 /* FLUSH */ 196 0, 197 /* DUMP */ 198 0, 199 /* X_PROMISC */ 200 0, 201 /* X_ADDFLOW */ 202 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE, 203 /* X_DELFLOW */ 204 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE, 205 /* X_GRPSPIS */ 206 BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_SATYPE2, 207 /* X_ASKPOLICY */ 208 BITMAP_X_POLICY, 209 }; 210 211 const uint64_t sadb_exts_allowed_out[SADB_MAX+1] = 212 { 213 /* RESERVED */ 214 ~0, 215 /* GETSPI */ 216 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST, 217 /* UPDATE */ 218 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_ADDRESS_PROXY | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN, 219 /* ADD */ 220 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_RDOMAIN, 221 /* DELETE */ 222 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_X_RDOMAIN, 223 /* GET */ 224 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_FLOW_TYPE | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_TAG | BITMAP_X_TAP | BITMAP_X_COUNTER | BITMAP_X_RDOMAIN | BITMAP_X_MTU | BITMAP_X_REPLAY, 225 /* ACQUIRE */ 226 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_IDENTITY | BITMAP_PROPOSAL, 227 /* REGISTER */ 228 BITMAP_SUPPORTED_AUTH | BITMAP_SUPPORTED_ENCRYPT | BITMAP_X_SUPPORTED_COMP, 229 /* EXPIRE */ 230 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS, 231 /* FLUSH */ 232 0, 233 /* DUMP */ 234 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY, 235 /* X_PROMISC */ 236 0, 237 /* X_ADDFLOW */ 238 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE | BITMAP_IDENTITY_SRC | BITMAP_IDENTITY_DST | BITMAP_X_RDOMAIN, 239 /* X_DELFLOW */ 240 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE | BITMAP_X_RDOMAIN, 241 /* X_GRPSPIS */ 242 BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_SATYPE2 | BITMAP_X_RDOMAIN, 243 /* X_ASKPOLICY */ 244 BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_FLOW_TYPE | BITMAP_X_POLICY, 245 }; 246 247 const uint64_t sadb_exts_required_out[SADB_MAX+1] = 248 { 249 /* RESERVED */ 250 0, 251 /* GETSPI */ 252 BITMAP_SA | BITMAP_ADDRESS_DST, 253 /* UPDATE */ 254 BITMAP_SA | BITMAP_ADDRESS_DST, 255 /* ADD */ 256 BITMAP_SA | BITMAP_ADDRESS_DST, 257 /* DELETE */ 258 BITMAP_SA | BITMAP_ADDRESS_DST, 259 /* GET */ 260 BITMAP_SA | BITMAP_LIFETIME_CURRENT | BITMAP_ADDRESS_DST, 261 /* ACQUIRE */ 262 0, 263 /* REGISTER */ 264 BITMAP_SUPPORTED_AUTH | BITMAP_SUPPORTED_ENCRYPT | BITMAP_X_SUPPORTED_COMP, 265 /* EXPIRE */ 266 BITMAP_SA | BITMAP_ADDRESS_DST, 267 /* FLUSH */ 268 0, 269 /* DUMP */ 270 0, 271 /* X_PROMISC */ 272 0, 273 /* X_ADDFLOW */ 274 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE, 275 /* X_DELFLOW */ 276 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE, 277 /* X_GRPSPIS */ 278 BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_SATYPE2, 279 /* X_REPPOLICY */ 280 BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_FLOW_TYPE, 281 }; 282 283 int 284 pfkeyv2_parsemessage(void *p, int len, void **headers) 285 { 286 struct sadb_ext *sadb_ext; 287 int i, left = len; 288 uint64_t allow, seen = 1; 289 struct sadb_msg *sadb_msg = (struct sadb_msg *) p; 290 291 bzero(headers, (SADB_EXT_MAX + 1) * sizeof(void *)); 292 293 if (left < sizeof(struct sadb_msg)) { 294 DPRINTF("message too short"); 295 return (EINVAL); 296 } 297 298 headers[0] = p; 299 300 if (sadb_msg->sadb_msg_len * sizeof(uint64_t) != left) { 301 DPRINTF("length not a multiple of 64"); 302 return (EINVAL); 303 } 304 305 p += sizeof(struct sadb_msg); 306 left -= sizeof(struct sadb_msg); 307 308 if (sadb_msg->sadb_msg_reserved) { 309 DPRINTF("message header reserved field set"); 310 return (EINVAL); 311 } 312 313 if (sadb_msg->sadb_msg_type > SADB_MAX) { 314 DPRINTF("message type > %d", SADB_MAX); 315 return (EINVAL); 316 } 317 318 if (!sadb_msg->sadb_msg_type) { 319 DPRINTF("message type unset"); 320 return (EINVAL); 321 } 322 323 if (sadb_msg->sadb_msg_pid != curproc->p_p->ps_pid) { 324 DPRINTF("bad PID value"); 325 return (EINVAL); 326 } 327 328 if (sadb_msg->sadb_msg_errno) { 329 if (left) { 330 DPRINTF("too-large error message"); 331 return (EINVAL); 332 } 333 return (0); 334 } 335 336 if (sadb_msg->sadb_msg_type == SADB_X_PROMISC) { 337 DPRINTF("message type promiscuous"); 338 return (0); 339 } 340 341 allow = sadb_exts_allowed_in[sadb_msg->sadb_msg_type]; 342 343 while (left > 0) { 344 sadb_ext = (struct sadb_ext *)p; 345 if (left < sizeof(struct sadb_ext)) { 346 DPRINTF("extension header too short"); 347 return (EINVAL); 348 } 349 350 i = sadb_ext->sadb_ext_len * sizeof(uint64_t); 351 if (left < i) { 352 DPRINTF("extension header exceeds message length"); 353 return (EINVAL); 354 } 355 356 if (sadb_ext->sadb_ext_type > SADB_EXT_MAX) { 357 DPRINTF("unknown extension header %d", 358 sadb_ext->sadb_ext_type); 359 return (EINVAL); 360 } 361 362 if (!sadb_ext->sadb_ext_type) { 363 DPRINTF("unset extension header"); 364 return (EINVAL); 365 } 366 367 if (!(allow & (1LL << sadb_ext->sadb_ext_type))) { 368 DPRINTF("extension header %d not permitted on message " 369 "type %d", 370 sadb_ext->sadb_ext_type, sadb_msg->sadb_msg_type); 371 return (EINVAL); 372 } 373 374 if (headers[sadb_ext->sadb_ext_type]) { 375 DPRINTF("duplicate extension header %d", 376 sadb_ext->sadb_ext_type); 377 return (EINVAL); 378 } 379 380 seen |= (1LL << sadb_ext->sadb_ext_type); 381 382 switch (sadb_ext->sadb_ext_type) { 383 case SADB_EXT_SA: 384 case SADB_X_EXT_SA2: 385 { 386 struct sadb_sa *sadb_sa = (struct sadb_sa *)p; 387 388 if (i != sizeof(struct sadb_sa)) { 389 DPRINTF("bad header length for SA extension " 390 "header %d", 391 sadb_ext->sadb_ext_type); 392 return (EINVAL); 393 } 394 395 if (sadb_sa->sadb_sa_state > SADB_SASTATE_MAX) { 396 DPRINTF("unknown SA state %d in SA extension " 397 "header %d", 398 sadb_sa->sadb_sa_state, 399 sadb_ext->sadb_ext_type); 400 return (EINVAL); 401 } 402 403 if (sadb_sa->sadb_sa_state == SADB_SASTATE_DEAD) { 404 DPRINTF("cannot set SA state to dead, " 405 "SA extension header %d", 406 sadb_ext->sadb_ext_type); 407 return (EINVAL); 408 } 409 410 if (sadb_sa->sadb_sa_encrypt > SADB_EALG_MAX) { 411 DPRINTF("unknown encryption algorithm %d " 412 "in SA extension header %d", 413 sadb_sa->sadb_sa_encrypt, 414 sadb_ext->sadb_ext_type); 415 return (EINVAL); 416 } 417 418 if (sadb_sa->sadb_sa_auth > SADB_AALG_MAX) { 419 DPRINTF("unknown authentication algorithm %d " 420 "in SA extension header %d", 421 sadb_sa->sadb_sa_auth, 422 sadb_ext->sadb_ext_type); 423 return (EINVAL); 424 } 425 426 if (sadb_sa->sadb_sa_replay > 64) { 427 DPRINTF("unsupported replay window size %d " 428 "in SA extension header %d", 429 sadb_sa->sadb_sa_replay, 430 sadb_ext->sadb_ext_type); 431 return (EINVAL); 432 } 433 } 434 break; 435 case SADB_X_EXT_PROTOCOL: 436 case SADB_X_EXT_FLOW_TYPE: 437 case SADB_X_EXT_SATYPE2: 438 if (i != sizeof(struct sadb_protocol)) { 439 DPRINTF("bad PROTOCOL/FLOW/SATYPE2 header " 440 "length in extension header %d", 441 sadb_ext->sadb_ext_type); 442 return (EINVAL); 443 } 444 break; 445 case SADB_X_EXT_POLICY: 446 if (i != sizeof(struct sadb_x_policy)) { 447 DPRINTF("bad POLICY header length"); 448 return (EINVAL); 449 } 450 break; 451 case SADB_EXT_LIFETIME_CURRENT: 452 case SADB_EXT_LIFETIME_HARD: 453 case SADB_EXT_LIFETIME_SOFT: 454 case SADB_X_EXT_LIFETIME_LASTUSE: 455 if (i != sizeof(struct sadb_lifetime)) { 456 DPRINTF("bad header length for LIFETIME " 457 "extension header %d", 458 sadb_ext->sadb_ext_type); 459 return (EINVAL); 460 } 461 break; 462 case SADB_EXT_ADDRESS_SRC: 463 case SADB_EXT_ADDRESS_DST: 464 case SADB_EXT_ADDRESS_PROXY: 465 case SADB_X_EXT_SRC_MASK: 466 case SADB_X_EXT_DST_MASK: 467 case SADB_X_EXT_SRC_FLOW: 468 case SADB_X_EXT_DST_FLOW: 469 case SADB_X_EXT_DST2: 470 { 471 struct sadb_address *sadb_address = 472 (struct sadb_address *)p; 473 struct sockaddr *sa = (struct sockaddr *)(p + 474 sizeof(struct sadb_address)); 475 476 if (i < sizeof(struct sadb_address) + 477 sizeof(struct sockaddr)) { 478 DPRINTF("bad ADDRESS extension header %d " 479 "length", 480 sadb_ext->sadb_ext_type); 481 return (EINVAL); 482 } 483 484 if (sadb_address->sadb_address_reserved) { 485 DPRINTF("ADDRESS extension header %d reserved " 486 "field set", 487 sadb_ext->sadb_ext_type); 488 return (EINVAL); 489 } 490 if (sa->sa_len && 491 (i != sizeof(struct sadb_address) + 492 PADUP(sa->sa_len))) { 493 DPRINTF("bad sockaddr length field in ADDRESS " 494 "extension header %d", 495 sadb_ext->sadb_ext_type); 496 return (EINVAL); 497 } 498 499 switch (sa->sa_family) { 500 case AF_INET: 501 if (sizeof(struct sadb_address) + 502 PADUP(sizeof(struct sockaddr_in)) != i) { 503 DPRINTF("invalid ADDRESS extension " 504 "header %d length", 505 sadb_ext->sadb_ext_type); 506 return (EINVAL); 507 } 508 509 if (sa->sa_len != sizeof(struct sockaddr_in)) { 510 DPRINTF("bad sockaddr_in length in " 511 "ADDRESS extension header %d", 512 sadb_ext->sadb_ext_type); 513 return (EINVAL); 514 } 515 516 /* Only check the right pieces */ 517 switch (sadb_ext->sadb_ext_type) 518 { 519 case SADB_X_EXT_SRC_MASK: 520 case SADB_X_EXT_DST_MASK: 521 case SADB_X_EXT_SRC_FLOW: 522 case SADB_X_EXT_DST_FLOW: 523 break; 524 525 default: 526 if (((struct sockaddr_in *)sa)->sin_port) { 527 DPRINTF("port field set in " 528 "sockaddr_in of ADDRESS " 529 "extension header %d", 530 sadb_ext->sadb_ext_type); 531 return (EINVAL); 532 } 533 break; 534 } 535 536 { 537 char zero[sizeof(((struct sockaddr_in *)sa)->sin_zero)]; 538 bzero(zero, sizeof(zero)); 539 540 if (bcmp(&((struct sockaddr_in *)sa)->sin_zero, zero, sizeof(zero))) { 541 DPRINTF("reserved sockaddr_in " 542 "field non-zero'ed in " 543 "ADDRESS extension header " 544 "%d", 545 sadb_ext->sadb_ext_type); 546 return (EINVAL); 547 } 548 } 549 break; 550 #ifdef INET6 551 case AF_INET6: 552 if (i != sizeof(struct sadb_address) + 553 PADUP(sizeof(struct sockaddr_in6))) { 554 DPRINTF("invalid sockaddr_in6 length " 555 "in ADDRESS extension header %d", 556 sadb_ext->sadb_ext_type); 557 return (EINVAL); 558 } 559 560 if (sa->sa_len != 561 sizeof(struct sockaddr_in6)) { 562 DPRINTF("bad sockaddr_in6 length in " 563 "ADDRESS extension header %d", 564 sadb_ext->sadb_ext_type); 565 return (EINVAL); 566 } 567 568 if (((struct sockaddr_in6 *)sa)->sin6_flowinfo) { 569 DPRINTF("flowinfo field set in " 570 "sockaddr_in6 of ADDRESS " 571 "extension header %d", 572 sadb_ext->sadb_ext_type); 573 return (EINVAL); 574 } 575 576 /* Only check the right pieces */ 577 switch (sadb_ext->sadb_ext_type) 578 { 579 case SADB_X_EXT_SRC_MASK: 580 case SADB_X_EXT_DST_MASK: 581 case SADB_X_EXT_SRC_FLOW: 582 case SADB_X_EXT_DST_FLOW: 583 break; 584 585 default: 586 if (((struct sockaddr_in6 *)sa)->sin6_port) { 587 DPRINTF("port field set in " 588 "sockaddr_in6 of ADDRESS " 589 "extension header %d", 590 sadb_ext->sadb_ext_type); 591 return (EINVAL); 592 } 593 break; 594 } 595 break; 596 #endif /* INET6 */ 597 default: 598 if (sadb_msg->sadb_msg_satype == 599 SADB_X_SATYPE_TCPSIGNATURE && 600 sa->sa_family == 0) 601 break; 602 DPRINTF("unknown address family %d in ADDRESS " 603 "extension header %d", 604 sa->sa_family, sadb_ext->sadb_ext_type); 605 return (EINVAL); 606 } 607 } 608 break; 609 case SADB_EXT_KEY_AUTH: 610 case SADB_EXT_KEY_ENCRYPT: 611 { 612 struct sadb_key *sadb_key = (struct sadb_key *)p; 613 614 if (i < sizeof(struct sadb_key)) { 615 DPRINTF("bad header length in KEY extension " 616 "header %d", 617 sadb_ext->sadb_ext_type); 618 return (EINVAL); 619 } 620 621 if (!sadb_key->sadb_key_bits) { 622 DPRINTF("key length unset in KEY extension " 623 "header %d", 624 sadb_ext->sadb_ext_type); 625 return (EINVAL); 626 } 627 628 if (((sadb_key->sadb_key_bits + 63) / 64) * sizeof(uint64_t) != i - sizeof(struct sadb_key)) { 629 DPRINTF("invalid key length in KEY extension " 630 "header %d", 631 sadb_ext->sadb_ext_type); 632 return (EINVAL); 633 } 634 635 if (sadb_key->sadb_key_reserved) { 636 DPRINTF("reserved field set in KEY extension " 637 "header %d", 638 sadb_ext->sadb_ext_type); 639 return (EINVAL); 640 } 641 } 642 break; 643 case SADB_EXT_IDENTITY_SRC: 644 case SADB_EXT_IDENTITY_DST: 645 { 646 struct sadb_ident *sadb_ident = (struct sadb_ident *)p; 647 648 if (i < sizeof(struct sadb_ident)) { 649 DPRINTF("bad header length of IDENTITY " 650 "extension header %d", 651 sadb_ext->sadb_ext_type); 652 return (EINVAL); 653 } 654 655 if (sadb_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) { 656 DPRINTF("unknown identity type %d in IDENTITY " 657 "extension header %d", 658 sadb_ident->sadb_ident_type, 659 sadb_ext->sadb_ext_type); 660 return (EINVAL); 661 } 662 663 if (sadb_ident->sadb_ident_reserved) { 664 DPRINTF("reserved field set in IDENTITY " 665 "extension header %d", 666 sadb_ext->sadb_ext_type); 667 return (EINVAL); 668 } 669 670 if (i > sizeof(struct sadb_ident)) { 671 char *c = 672 (char *)(p + sizeof(struct sadb_ident)); 673 int j; 674 675 if (*(char *)(p + i - 1)) { 676 DPRINTF("non NUL-terminated identity " 677 "in IDENTITY extension header %d", 678 sadb_ext->sadb_ext_type); 679 return (EINVAL); 680 } 681 682 j = PADUP(strlen(c) + 1) + 683 sizeof(struct sadb_ident); 684 685 if (i != j) { 686 DPRINTF("actual identity length does " 687 "not match expected length in " 688 "identity extension header %d", 689 sadb_ext->sadb_ext_type); 690 return (EINVAL); 691 } 692 } 693 } 694 break; 695 case SADB_EXT_SENSITIVITY: 696 { 697 struct sadb_sens *sadb_sens = (struct sadb_sens *)p; 698 699 if (i < sizeof(struct sadb_sens)) { 700 DPRINTF("bad header length for SENSITIVITY " 701 "extension header"); 702 return (EINVAL); 703 } 704 705 if (i != (sadb_sens->sadb_sens_sens_len + 706 sadb_sens->sadb_sens_integ_len) * 707 sizeof(uint64_t) + 708 sizeof(struct sadb_sens)) { 709 DPRINTF("bad payload length for SENSITIVITY " 710 "extension header"); 711 return (EINVAL); 712 } 713 } 714 break; 715 case SADB_EXT_PROPOSAL: 716 { 717 struct sadb_prop *sadb_prop = (struct sadb_prop *)p; 718 719 if (i < sizeof(struct sadb_prop)) { 720 DPRINTF("bad PROPOSAL header length"); 721 return (EINVAL); 722 } 723 724 if (sadb_prop->sadb_prop_reserved) { 725 DPRINTF("reserved fieldset in PROPOSAL " 726 "extension header"); 727 return (EINVAL); 728 } 729 730 if ((i - sizeof(struct sadb_prop)) % 731 sizeof(struct sadb_comb)) { 732 DPRINTF("bad proposal length"); 733 return (EINVAL); 734 } 735 736 { 737 struct sadb_comb *sadb_comb = 738 (struct sadb_comb *)(p + 739 sizeof(struct sadb_prop)); 740 int j; 741 742 for (j = 0; 743 j < (i - sizeof(struct sadb_prop))/ 744 sizeof(struct sadb_comb); 745 j++) { 746 if (sadb_comb->sadb_comb_auth > 747 SADB_AALG_MAX) { 748 DPRINTF("unknown " 749 "authentication algorithm " 750 "%d in PROPOSAL", 751 sadb_comb->sadb_comb_auth); 752 return (EINVAL); 753 } 754 755 if (sadb_comb->sadb_comb_encrypt > 756 SADB_EALG_MAX) { 757 DPRINTF("unknown encryption " 758 "algorithm %d in PROPOSAL", 759 sadb_comb-> 760 sadb_comb_encrypt); 761 return (EINVAL); 762 } 763 764 if (sadb_comb->sadb_comb_reserved) { 765 DPRINTF("reserved field set " 766 "in COMB header"); 767 return (EINVAL); 768 } 769 } 770 } 771 } 772 break; 773 case SADB_EXT_SUPPORTED_AUTH: 774 case SADB_EXT_SUPPORTED_ENCRYPT: 775 case SADB_X_EXT_SUPPORTED_COMP: 776 { 777 struct sadb_supported *sadb_supported = 778 (struct sadb_supported *)p; 779 int j; 780 781 if (i < sizeof(struct sadb_supported)) { 782 DPRINTF("bad header length for SUPPORTED " "extension header %d", 783 sadb_ext->sadb_ext_type); 784 return (EINVAL); 785 } 786 787 if (sadb_supported->sadb_supported_reserved) { 788 DPRINTF("reserved field set in SUPPORTED " 789 "extension header %d", 790 sadb_ext->sadb_ext_type); 791 return (EINVAL); 792 } 793 794 { 795 struct sadb_alg *sadb_alg = 796 (struct sadb_alg *)(p + 797 sizeof(struct sadb_supported)); 798 int max_alg; 799 800 max_alg = sadb_ext->sadb_ext_type == 801 SADB_EXT_SUPPORTED_AUTH ? 802 SADB_AALG_MAX : SADB_EXT_SUPPORTED_ENCRYPT ? 803 SADB_EALG_MAX : SADB_X_CALG_MAX; 804 805 for (j = 0; 806 j < sadb_supported->sadb_supported_len - 1; 807 j++) { 808 if (sadb_alg->sadb_alg_id > max_alg) { 809 DPRINTF("unknown algorithm %d " 810 "in SUPPORTED extension " 811 "header %d", 812 sadb_alg->sadb_alg_id, 813 sadb_ext->sadb_ext_type); 814 return (EINVAL); 815 } 816 817 if (sadb_alg->sadb_alg_reserved) { 818 DPRINTF("reserved field set " 819 "in supported algorithms " 820 "header inside SUPPORTED " 821 "extension header %d", 822 sadb_ext->sadb_ext_type); 823 return (EINVAL); 824 } 825 826 sadb_alg++; 827 } 828 } 829 } 830 break; 831 case SADB_EXT_SPIRANGE: 832 { 833 struct sadb_spirange *sadb_spirange = 834 (struct sadb_spirange *)p; 835 836 if (i != sizeof(struct sadb_spirange)) { 837 DPRINTF("bad header length of SPIRANGE " 838 "extension header"); 839 return (EINVAL); 840 } 841 842 if (sadb_spirange->sadb_spirange_min > 843 sadb_spirange->sadb_spirange_max) { 844 DPRINTF("bad SPI range"); 845 return (EINVAL); 846 } 847 } 848 break; 849 case SADB_X_EXT_UDPENCAP: 850 if (i != sizeof(struct sadb_x_udpencap)) { 851 DPRINTF("bad UDPENCAP header length"); 852 return (EINVAL); 853 } 854 break; 855 case SADB_X_EXT_RDOMAIN: 856 if (i != sizeof(struct sadb_x_rdomain)) { 857 DPRINTF("bad RDOMAIN header length"); 858 return (EINVAL); 859 } 860 break; 861 #if NPF > 0 862 case SADB_X_EXT_TAG: 863 if (i < sizeof(struct sadb_x_tag)) { 864 DPRINTF("TAG extension header too small"); 865 return (EINVAL); 866 } 867 if (i > (sizeof(struct sadb_x_tag) + 868 PF_TAG_NAME_SIZE)) { 869 DPRINTF("TAG extension header too long"); 870 return (EINVAL); 871 } 872 break; 873 case SADB_X_EXT_TAP: 874 if (i < sizeof(struct sadb_x_tap)) { 875 DPRINTF("TAP extension header too small"); 876 return (EINVAL); 877 } 878 if (i > sizeof(struct sadb_x_tap)) { 879 DPRINTF("TAP extension header too long"); 880 return (EINVAL); 881 } 882 break; 883 #endif 884 default: 885 DPRINTF("unknown extension header type %d", 886 sadb_ext->sadb_ext_type); 887 return (EINVAL); 888 } 889 890 headers[sadb_ext->sadb_ext_type] = p; 891 p += i; 892 left -= i; 893 } 894 895 if (left) { 896 DPRINTF("message too long"); 897 return (EINVAL); 898 } 899 900 { 901 uint64_t required; 902 903 required = sadb_exts_required_in[sadb_msg->sadb_msg_type]; 904 905 if ((seen & required) != required) { 906 DPRINTF("required fields missing"); 907 return (EINVAL); 908 } 909 } 910 911 switch (((struct sadb_msg *)headers[0])->sadb_msg_type) { 912 case SADB_UPDATE: 913 if (((struct sadb_sa *)headers[SADB_EXT_SA])->sadb_sa_state != 914 SADB_SASTATE_MATURE) { 915 DPRINTF("updating non-mature SA prohibited"); 916 return (EINVAL); 917 } 918 break; 919 case SADB_ADD: 920 if (((struct sadb_sa *)headers[SADB_EXT_SA])->sadb_sa_state != 921 SADB_SASTATE_MATURE) { 922 DPRINTF("adding non-mature SA prohibited"); 923 return (EINVAL); 924 } 925 break; 926 } 927 928 return (0); 929 } 930