1 /* $OpenBSD: pfkeyv2_parsemessage.c,v 1.47 2013/04/10 08:50:59 mpi 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 <netinet/ip_var.h> 80 #include <net/pfkeyv2.h> 81 82 #if NPF > 0 83 #include <net/if.h> 84 #include <net/pfvar.h> 85 #endif 86 87 #ifdef ENCDEBUG 88 #define DPRINTF(x) if (encdebug) printf x 89 #else 90 #define DPRINTF(x) 91 #endif 92 93 #define BITMAP_SA (1LL << SADB_EXT_SA) 94 #define BITMAP_LIFETIME_CURRENT (1LL << SADB_EXT_LIFETIME_CURRENT) 95 #define BITMAP_LIFETIME_HARD (1LL << SADB_EXT_LIFETIME_HARD) 96 #define BITMAP_LIFETIME_SOFT (1LL << SADB_EXT_LIFETIME_SOFT) 97 #define BITMAP_ADDRESS_SRC (1LL << SADB_EXT_ADDRESS_SRC) 98 #define BITMAP_ADDRESS_DST (1LL << SADB_EXT_ADDRESS_DST) 99 #define BITMAP_ADDRESS_PROXY (1LL << SADB_EXT_ADDRESS_PROXY) 100 #define BITMAP_KEY_AUTH (1LL << SADB_EXT_KEY_AUTH) 101 #define BITMAP_KEY_ENCRYPT (1LL << SADB_EXT_KEY_ENCRYPT) 102 #define BITMAP_IDENTITY_SRC (1LL << SADB_EXT_IDENTITY_SRC) 103 #define BITMAP_IDENTITY_DST (1LL << SADB_EXT_IDENTITY_DST) 104 #define BITMAP_SENSITIVITY (1LL << SADB_EXT_SENSITIVITY) 105 #define BITMAP_PROPOSAL (1LL << SADB_EXT_PROPOSAL) 106 #define BITMAP_SUPPORTED_AUTH (1LL << SADB_EXT_SUPPORTED_AUTH) 107 #define BITMAP_SUPPORTED_ENCRYPT (1LL << SADB_EXT_SUPPORTED_ENCRYPT) 108 #define BITMAP_SPIRANGE (1LL << SADB_EXT_SPIRANGE) 109 #define BITMAP_LIFETIME (BITMAP_LIFETIME_CURRENT | BITMAP_LIFETIME_HARD | BITMAP_LIFETIME_SOFT) 110 #define BITMAP_ADDRESS (BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_ADDRESS_PROXY) 111 #define BITMAP_KEY (BITMAP_KEY_AUTH | BITMAP_KEY_ENCRYPT) 112 #define BITMAP_IDENTITY (BITMAP_IDENTITY_SRC | BITMAP_IDENTITY_DST) 113 #define BITMAP_MSG 1 114 #define BITMAP_X_SRC_MASK (1LL << SADB_X_EXT_SRC_MASK) 115 #define BITMAP_X_DST_MASK (1LL << SADB_X_EXT_DST_MASK) 116 #define BITMAP_X_PROTOCOL (1LL << SADB_X_EXT_PROTOCOL) 117 #define BITMAP_X_SRC_FLOW (1LL << SADB_X_EXT_SRC_FLOW) 118 #define BITMAP_X_DST_FLOW (1LL << SADB_X_EXT_DST_FLOW) 119 #define BITMAP_X_FLOW_TYPE (1LL << SADB_X_EXT_FLOW_TYPE) 120 #define BITMAP_X_SA2 (1LL << SADB_X_EXT_SA2) 121 #define BITMAP_X_DST2 (1LL << SADB_X_EXT_DST2) 122 #define BITMAP_X_POLICY (1LL << SADB_X_EXT_POLICY) 123 #define BITMAP_X_LOCAL_CREDENTIALS (1LL << SADB_X_EXT_LOCAL_CREDENTIALS) 124 #define BITMAP_X_REMOTE_CREDENTIALS (1LL << SADB_X_EXT_REMOTE_CREDENTIALS) 125 #define BITMAP_X_LOCAL_AUTH (1LL << SADB_X_EXT_LOCAL_AUTH) 126 #define BITMAP_X_REMOTE_AUTH (1LL << SADB_X_EXT_REMOTE_AUTH) 127 #define BITMAP_X_CREDENTIALS (BITMAP_X_LOCAL_CREDENTIALS | BITMAP_X_REMOTE_CREDENTIALS | BITMAP_X_LOCAL_AUTH | BITMAP_X_REMOTE_AUTH) 128 #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) 129 #define BITMAP_X_SUPPORTED_COMP (1LL << SADB_X_EXT_SUPPORTED_COMP) 130 #define BITMAP_X_UDPENCAP (1LL << SADB_X_EXT_UDPENCAP) 131 #define BITMAP_X_LIFETIME_LASTUSE (1LL << SADB_X_EXT_LIFETIME_LASTUSE) 132 #define BITMAP_X_TAG (1LL << SADB_X_EXT_TAG) 133 #define BITMAP_X_TAP (1LL << SADB_X_EXT_TAP) 134 135 uint64_t sadb_exts_allowed_in[SADB_MAX+1] = 136 { 137 /* RESERVED */ 138 ~0, 139 /* GETSPI */ 140 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_SPIRANGE, 141 /* UPDATE */ 142 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP, 143 /* ADD */ 144 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_LIFETIME_LASTUSE | BITMAP_X_TAG | BITMAP_X_TAP, 145 /* DELETE */ 146 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST, 147 /* GET */ 148 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST, 149 /* ACQUIRE */ 150 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_IDENTITY | BITMAP_PROPOSAL | BITMAP_X_CREDENTIALS, 151 /* REGISTER */ 152 0, 153 /* EXPIRE */ 154 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST, 155 /* FLUSH */ 156 0, 157 /* DUMP */ 158 0, 159 /* X_PROMISC */ 160 0, 161 /* X_ADDFLOW */ 162 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_IDENTITY_SRC | BITMAP_IDENTITY_DST | BITMAP_X_FLOW, 163 /* X_DELFLOW */ 164 BITMAP_X_FLOW, 165 /* X_GRPSPIS */ 166 BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL, 167 /* X_ASKPOLICY */ 168 BITMAP_X_POLICY, 169 }; 170 171 uint64_t sadb_exts_required_in[SADB_MAX+1] = 172 { 173 /* RESERVED */ 174 0, 175 /* GETSPI */ 176 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_SPIRANGE, 177 /* UPDATE */ 178 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST, 179 /* ADD */ 180 BITMAP_SA | BITMAP_ADDRESS_DST, 181 /* DELETE */ 182 BITMAP_SA | BITMAP_ADDRESS_DST, 183 /* GET */ 184 BITMAP_SA | BITMAP_ADDRESS_DST, 185 /* ACQUIRE */ 186 0, 187 /* REGISTER */ 188 0, 189 /* EXPIRE */ 190 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST, 191 /* FLUSH */ 192 0, 193 /* DUMP */ 194 0, 195 /* X_PROMISC */ 196 0, 197 /* X_ADDFLOW */ 198 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE, 199 /* X_DELFLOW */ 200 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE, 201 /* X_GRPSPIS */ 202 BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL, 203 /* X_ASKPOLICY */ 204 BITMAP_X_POLICY, 205 }; 206 207 uint64_t sadb_exts_allowed_out[SADB_MAX+1] = 208 { 209 /* RESERVED */ 210 ~0, 211 /* GETSPI */ 212 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST, 213 /* UPDATE */ 214 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP, 215 /* ADD */ 216 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | BITMAP_X_FLOW | BITMAP_X_UDPENCAP | BITMAP_X_TAG | BITMAP_X_TAP, 217 /* DELETE */ 218 BITMAP_SA | BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST, 219 /* GET */ 220 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_KEY | BITMAP_IDENTITY | BITMAP_X_CREDENTIALS | 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, 221 /* ACQUIRE */ 222 BITMAP_ADDRESS_SRC | BITMAP_ADDRESS_DST | BITMAP_IDENTITY | BITMAP_PROPOSAL | BITMAP_X_CREDENTIALS, 223 /* REGISTER */ 224 BITMAP_SUPPORTED_AUTH | BITMAP_SUPPORTED_ENCRYPT | BITMAP_X_SUPPORTED_COMP, 225 /* EXPIRE */ 226 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS, 227 /* FLUSH */ 228 0, 229 /* DUMP */ 230 BITMAP_SA | BITMAP_LIFETIME | BITMAP_ADDRESS | BITMAP_IDENTITY, 231 /* X_PROMISC */ 232 0, 233 /* X_ADDFLOW */ 234 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, 235 /* X_DELFLOW */ 236 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE, 237 /* X_GRPSPIS */ 238 BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL, 239 /* X_ASKPOLICY */ 240 BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_FLOW_TYPE | BITMAP_X_POLICY, 241 }; 242 243 uint64_t sadb_exts_required_out[SADB_MAX+1] = 244 { 245 /* RESERVED */ 246 0, 247 /* GETSPI */ 248 BITMAP_SA | BITMAP_ADDRESS_DST, 249 /* UPDATE */ 250 BITMAP_SA | BITMAP_ADDRESS_DST, 251 /* ADD */ 252 BITMAP_SA | BITMAP_ADDRESS_DST, 253 /* DELETE */ 254 BITMAP_SA | BITMAP_ADDRESS_DST, 255 /* GET */ 256 BITMAP_SA | BITMAP_LIFETIME_CURRENT | BITMAP_ADDRESS_DST, 257 /* ACQUIRE */ 258 0, 259 /* REGISTER */ 260 BITMAP_SUPPORTED_AUTH | BITMAP_SUPPORTED_ENCRYPT | BITMAP_X_SUPPORTED_COMP, 261 /* EXPIRE */ 262 BITMAP_SA | BITMAP_ADDRESS_DST, 263 /* FLUSH */ 264 0, 265 /* DUMP */ 266 0, 267 /* X_PROMISC */ 268 0, 269 /* X_ADDFLOW */ 270 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE, 271 /* X_DELFLOW */ 272 BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE, 273 /* X_GRPSPIS */ 274 BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | BITMAP_X_PROTOCOL, 275 /* X_REPPOLICY */ 276 BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_FLOW_TYPE, 277 }; 278 279 int pfkeyv2_parsemessage(void *, int, void **); 280 281 #define RETURN_EINVAL(line) goto einval; 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(("pfkeyv2_parsemessage: message too short\n")); 295 return (EINVAL); 296 } 297 298 headers[0] = p; 299 300 if (sadb_msg->sadb_msg_len * sizeof(uint64_t) != left) { 301 DPRINTF(("pfkeyv2_parsemessage: length not a multiple of 64\n")); 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(("pfkeyv2_parsemessage: message header reserved " 310 "field set\n")); 311 return (EINVAL); 312 } 313 314 if (sadb_msg->sadb_msg_type > SADB_MAX) { 315 DPRINTF(("pfkeyv2_parsemessage: message type > %d\n", 316 SADB_MAX)); 317 return (EINVAL); 318 } 319 320 if (!sadb_msg->sadb_msg_type) { 321 DPRINTF(("pfkeyv2_parsemessage: message type unset\n")); 322 return (EINVAL); 323 } 324 325 if (sadb_msg->sadb_msg_pid != curproc->p_p->ps_pid) { 326 DPRINTF(("pfkeyv2_parsemessage: bad PID value\n")); 327 return (EINVAL); 328 } 329 330 if (sadb_msg->sadb_msg_errno) { 331 if (left) { 332 DPRINTF(("pfkeyv2_parsemessage: too-large error message\n")); 333 return (EINVAL); 334 } 335 return (0); 336 } 337 338 if (sadb_msg->sadb_msg_type == SADB_X_PROMISC) { 339 DPRINTF(("pfkeyv2_parsemessage: message type promiscuous\n")); 340 return (0); 341 } 342 343 allow = sadb_exts_allowed_in[sadb_msg->sadb_msg_type]; 344 345 while (left > 0) { 346 sadb_ext = (struct sadb_ext *)p; 347 if (left < sizeof(struct sadb_ext)) { 348 DPRINTF(("pfkeyv2_parsemessage: extension header too " 349 "short\n")); 350 return (EINVAL); 351 } 352 353 i = sadb_ext->sadb_ext_len * sizeof(uint64_t); 354 if (left < i) { 355 DPRINTF(("pfkeyv2_parsemessage: extension header " 356 "exceeds message length\n")); 357 return (EINVAL); 358 } 359 360 if (sadb_ext->sadb_ext_type > SADB_EXT_MAX) { 361 DPRINTF(("pfkeyv2_parsemessage: unknown extension " 362 "header %d\n", sadb_ext->sadb_ext_type)); 363 return (EINVAL); 364 } 365 366 if (!sadb_ext->sadb_ext_type) { 367 DPRINTF(("pfkeyv2_parsemessage: unset extension " 368 "header\n")); 369 return (EINVAL); 370 } 371 372 if (!(allow & (1LL << sadb_ext->sadb_ext_type))) { 373 DPRINTF(("pfkeyv2_parsemessage: extension header %d " 374 "not permitted on message type %d\n", 375 sadb_ext->sadb_ext_type, sadb_msg->sadb_msg_type)); 376 return (EINVAL); 377 } 378 379 if (headers[sadb_ext->sadb_ext_type]) { 380 DPRINTF(("pfkeyv2_parsemessage: duplicate extension " 381 "header %d\n", sadb_ext->sadb_ext_type)); 382 return (EINVAL); 383 } 384 385 seen |= (1LL << sadb_ext->sadb_ext_type); 386 387 switch (sadb_ext->sadb_ext_type) { 388 case SADB_EXT_SA: 389 case SADB_X_EXT_SA2: 390 { 391 struct sadb_sa *sadb_sa = (struct sadb_sa *)p; 392 393 if (i != sizeof(struct sadb_sa)) { 394 DPRINTF(("pfkeyv2_parsemessage: bad header " 395 "length for SA extension header %d\n", 396 sadb_ext->sadb_ext_type)); 397 return (EINVAL); 398 } 399 400 if (sadb_sa->sadb_sa_state > SADB_SASTATE_MAX) { 401 DPRINTF(("pfkeyv2_parsemessage: unknown SA " 402 "state %d in SA extension header %d\n", 403 sadb_sa->sadb_sa_state, 404 sadb_ext->sadb_ext_type)); 405 return (EINVAL); 406 } 407 408 if (sadb_sa->sadb_sa_state == SADB_SASTATE_DEAD) { 409 DPRINTF(("pfkeyv2_parsemessage: cannot set SA " 410 "state to dead, SA extension header %d\n", 411 sadb_ext->sadb_ext_type)); 412 return (EINVAL); 413 } 414 415 if (sadb_sa->sadb_sa_encrypt > SADB_EALG_MAX) { 416 DPRINTF(("pfkeyv2_parsemessage: unknown " 417 "encryption algorithm %d in SA extension " 418 "header %d\n", sadb_sa->sadb_sa_encrypt, 419 sadb_ext->sadb_ext_type)); 420 return (EINVAL); 421 } 422 423 if (sadb_sa->sadb_sa_auth > SADB_AALG_MAX) { 424 DPRINTF(("pfkeyv2_parsemessage: unknown " 425 "authentication algorithm %d in SA " 426 "extension header %d\n", 427 sadb_sa->sadb_sa_auth, 428 sadb_ext->sadb_ext_type)); 429 return (EINVAL); 430 } 431 432 if (sadb_sa->sadb_sa_replay > 64) { 433 DPRINTF(("pfkeyv2_parsemessage: unsupported " 434 "replay window size %d in SA extension " 435 "header %d\n", sadb_sa->sadb_sa_replay, 436 sadb_ext->sadb_ext_type)); 437 return (EINVAL); 438 } 439 } 440 break; 441 case SADB_X_EXT_PROTOCOL: 442 case SADB_X_EXT_FLOW_TYPE: 443 if (i != sizeof(struct sadb_protocol)) { 444 DPRINTF(("pfkeyv2_parsemessage: bad " 445 "PROTOCOL/FLOW header length in extension " 446 "header %d\n", sadb_ext->sadb_ext_type)); 447 return (EINVAL); 448 } 449 break; 450 case SADB_X_EXT_POLICY: 451 if (i != sizeof(struct sadb_x_policy)) { 452 DPRINTF(("pfkeyv2_parsemessage: bad POLICY " 453 "header length\n")); 454 return (EINVAL); 455 } 456 break; 457 case SADB_EXT_LIFETIME_CURRENT: 458 case SADB_EXT_LIFETIME_HARD: 459 case SADB_EXT_LIFETIME_SOFT: 460 case SADB_X_EXT_LIFETIME_LASTUSE: 461 if (i != sizeof(struct sadb_lifetime)) { 462 DPRINTF(("pfkeyv2_parsemessage: bad header " 463 "length for LIFETIME extension header " 464 "%d\n", sadb_ext->sadb_ext_type)); 465 return (EINVAL); 466 } 467 break; 468 case SADB_EXT_ADDRESS_SRC: 469 case SADB_EXT_ADDRESS_DST: 470 case SADB_X_EXT_SRC_MASK: 471 case SADB_X_EXT_DST_MASK: 472 case SADB_X_EXT_SRC_FLOW: 473 case SADB_X_EXT_DST_FLOW: 474 case SADB_X_EXT_DST2: 475 case SADB_EXT_ADDRESS_PROXY: 476 { 477 struct sadb_address *sadb_address = 478 (struct sadb_address *)p; 479 struct sockaddr *sa = (struct sockaddr *)(p + 480 sizeof(struct sadb_address)); 481 482 if (i < sizeof(struct sadb_address) + 483 sizeof(struct sockaddr)) { 484 DPRINTF(("pfkeyv2_parsemessage: bad ADDRESS " 485 "extension header %d length\n", 486 sadb_ext->sadb_ext_type)); 487 return (EINVAL); 488 } 489 490 if (sadb_address->sadb_address_reserved) { 491 DPRINTF(("pfkeyv2_parsemessage: ADDRESS " 492 "extension header %d reserved field set\n", 493 sadb_ext->sadb_ext_type)); 494 return (EINVAL); 495 } 496 if (sa->sa_len && 497 (i != sizeof(struct sadb_address) + 498 PADUP(sa->sa_len))) { 499 DPRINTF(("pfkeyv2_parsemessage: bad sockaddr " 500 "length field in ADDRESS extension " 501 "header %d\n", sadb_ext->sadb_ext_type)); 502 return (EINVAL); 503 } 504 505 switch (sa->sa_family) { 506 case AF_INET: 507 if (sizeof(struct sadb_address) + 508 PADUP(sizeof(struct sockaddr_in)) != i) { 509 DPRINTF(("pfkeyv2_parsemessage: " 510 "invalid ADDRESS extension header " 511 "%d length\n", 512 sadb_ext->sadb_ext_type)); 513 return (EINVAL); 514 } 515 516 if (sa->sa_len != sizeof(struct sockaddr_in)) { 517 DPRINTF(("pfkeyv2_parsemessage: bad " 518 "sockaddr_in length in ADDRESS " 519 "extension header %d\n", 520 sadb_ext->sadb_ext_type)); 521 return (EINVAL); 522 } 523 524 /* Only check the right pieces */ 525 switch (sadb_ext->sadb_ext_type) 526 { 527 case SADB_X_EXT_SRC_MASK: 528 case SADB_X_EXT_DST_MASK: 529 case SADB_X_EXT_SRC_FLOW: 530 case SADB_X_EXT_DST_FLOW: 531 break; 532 533 default: 534 if (((struct sockaddr_in *)sa)->sin_port) { 535 DPRINTF(("pfkeyv2_parsemessage" 536 ": port field set in " 537 "sockaddr_in of ADDRESS " 538 "extension header %d\n", 539 sadb_ext->sadb_ext_type)); 540 return (EINVAL); 541 } 542 break; 543 } 544 545 { 546 char zero[sizeof(((struct sockaddr_in *)sa)->sin_zero)]; 547 bzero(zero, sizeof(zero)); 548 549 if (bcmp(&((struct sockaddr_in *)sa)->sin_zero, zero, sizeof(zero))) { 550 DPRINTF(("pfkeyv2_parsemessage" 551 ": reserved sockaddr_in " 552 "field non-zero'ed in " 553 "ADDRESS extension header " 554 "%d\n", 555 sadb_ext->sadb_ext_type)); 556 return (EINVAL); 557 } 558 } 559 break; 560 #ifdef INET6 561 case AF_INET6: 562 if (i != sizeof(struct sadb_address) + 563 PADUP(sizeof(struct sockaddr_in6))) { 564 DPRINTF(("pfkeyv2_parsemessage: " 565 "invalid sockaddr_in6 length in " 566 "ADDRESS extension header %d\n", 567 sadb_ext->sadb_ext_type)); 568 return (EINVAL); 569 } 570 571 if (sa->sa_len != 572 sizeof(struct sockaddr_in6)) { 573 DPRINTF(("pfkeyv2_parsemessage: bad " 574 "sockaddr_in6 length in ADDRESS " 575 "extension header %d\n", 576 sadb_ext->sadb_ext_type)); 577 return (EINVAL); 578 } 579 580 if (((struct sockaddr_in6 *)sa)->sin6_flowinfo) { 581 DPRINTF(("pfkeyv2_parsemessage: " 582 "flowinfo field set in " 583 "sockaddr_in6 of ADDRESS " 584 "extension header %d\n", 585 sadb_ext->sadb_ext_type)); 586 return (EINVAL); 587 } 588 589 /* Only check the right pieces */ 590 switch (sadb_ext->sadb_ext_type) 591 { 592 case SADB_X_EXT_SRC_MASK: 593 case SADB_X_EXT_DST_MASK: 594 case SADB_X_EXT_SRC_FLOW: 595 case SADB_X_EXT_DST_FLOW: 596 break; 597 598 default: 599 if (((struct sockaddr_in6 *)sa)->sin6_port) { 600 DPRINTF(("pfkeyv2_parsemessage" 601 ": port field set in " 602 "sockaddr_in6 of ADDRESS " 603 "extension header %d\n", 604 sadb_ext->sadb_ext_type)); 605 return (EINVAL); 606 } 607 break; 608 } 609 break; 610 #endif /* INET6 */ 611 default: 612 if (sadb_msg->sadb_msg_satype == 613 SADB_X_SATYPE_TCPSIGNATURE && 614 sa->sa_family == 0) 615 break; 616 DPRINTF(("pfkeyv2_parsemessage: unknown " 617 "address family %d in ADDRESS extension " 618 "header %d\n", 619 sa->sa_family, sadb_ext->sadb_ext_type)); 620 return (EINVAL); 621 } 622 } 623 break; 624 case SADB_EXT_KEY_AUTH: 625 case SADB_EXT_KEY_ENCRYPT: 626 { 627 struct sadb_key *sadb_key = (struct sadb_key *)p; 628 629 if (i < sizeof(struct sadb_key)) { 630 DPRINTF(("pfkeyv2_parsemessage: bad header " 631 "length in KEY extension header %d\n", 632 sadb_ext->sadb_ext_type)); 633 return (EINVAL); 634 } 635 636 if (!sadb_key->sadb_key_bits) { 637 DPRINTF(("pfkeyv2_parsemessage: key length " 638 "unset in KEY extension header %d\n", 639 sadb_ext->sadb_ext_type)); 640 return (EINVAL); 641 } 642 643 if (((sadb_key->sadb_key_bits + 63) / 64) * sizeof(uint64_t) != i - sizeof(struct sadb_key)) { 644 DPRINTF(("pfkeyv2_parsemessage: invalid key " 645 "length in KEY extension header %d\n", 646 sadb_ext->sadb_ext_type)); 647 return (EINVAL); 648 } 649 650 if (sadb_key->sadb_key_reserved) { 651 DPRINTF(("pfkeyv2_parsemessage: reserved field" 652 " set in KEY extension header %d\n", 653 sadb_ext->sadb_ext_type)); 654 return (EINVAL); 655 } 656 } 657 break; 658 case SADB_X_EXT_LOCAL_AUTH: 659 case SADB_X_EXT_REMOTE_AUTH: 660 { 661 struct sadb_x_cred *sadb_cred = 662 (struct sadb_x_cred *)p; 663 664 if (i < sizeof(struct sadb_x_cred)) { 665 DPRINTF(("pfkeyv2_parsemessage: bad header " 666 "length for AUTH extension header %d\n", 667 sadb_ext->sadb_ext_type)); 668 return (EINVAL); 669 } 670 671 if (sadb_cred->sadb_x_cred_type > SADB_X_AUTHTYPE_MAX) { 672 DPRINTF(("pfkeyv2_parsemessage: unknown auth " 673 "type %d in AUTH extension header %d\n", 674 sadb_cred->sadb_x_cred_type, 675 sadb_ext->sadb_ext_type)); 676 return (EINVAL); 677 } 678 679 if (sadb_cred->sadb_x_cred_reserved) { 680 DPRINTF(("pfkeyv2_parsemessage: reserved field" 681 " set in AUTH extension header %d\n", 682 sadb_ext->sadb_ext_type)); 683 return (EINVAL); 684 } 685 } 686 break; 687 case SADB_X_EXT_LOCAL_CREDENTIALS: 688 case SADB_X_EXT_REMOTE_CREDENTIALS: 689 { 690 struct sadb_x_cred *sadb_cred = 691 (struct sadb_x_cred *)p; 692 693 if (i < sizeof(struct sadb_x_cred)) { 694 DPRINTF(("pfkeyv2_parsemessage: bad header " 695 "length of CREDENTIALS extension header " 696 "%d\n", sadb_ext->sadb_ext_type)); 697 return (EINVAL); 698 } 699 700 if (sadb_cred->sadb_x_cred_type > SADB_X_CREDTYPE_MAX) { 701 DPRINTF(("pfkeyv2_parsemessage: unknown " 702 "credential type %d in CREDENTIALS " 703 "extension header %d\n", 704 sadb_cred->sadb_x_cred_type, 705 sadb_ext->sadb_ext_type)); 706 return (EINVAL); 707 } 708 709 if (sadb_cred->sadb_x_cred_reserved) { 710 DPRINTF(("pfkeyv2_parsemessage: reserved " 711 "field set in CREDENTIALS extension " 712 "header %d\n", sadb_ext->sadb_ext_type)); 713 return (EINVAL); 714 } 715 } 716 break; 717 case SADB_EXT_IDENTITY_SRC: 718 case SADB_EXT_IDENTITY_DST: 719 { 720 struct sadb_ident *sadb_ident = (struct sadb_ident *)p; 721 722 if (i < sizeof(struct sadb_ident)) { 723 DPRINTF(("pfkeyv2_parsemessage: bad header " 724 "length of IDENTITY extension header %d\n", 725 sadb_ext->sadb_ext_type)); 726 return (EINVAL); 727 } 728 729 if (sadb_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) { 730 DPRINTF(("pfkeyv2_parsemessage: unknown " 731 "identity type %d in IDENTITY extension " 732 "header %d\n", 733 sadb_ident->sadb_ident_type, 734 sadb_ext->sadb_ext_type)); 735 return (EINVAL); 736 } 737 738 if (sadb_ident->sadb_ident_reserved) { 739 DPRINTF(("pfkeyv2_parsemessage: reserved " 740 "field set in IDENTITY extension header " 741 "%d\n", sadb_ext->sadb_ext_type)); 742 return (EINVAL); 743 } 744 745 if (i > sizeof(struct sadb_ident)) { 746 char *c = 747 (char *)(p + sizeof(struct sadb_ident)); 748 int j; 749 750 if (*(char *)(p + i - 1)) { 751 DPRINTF(("pfkeyv2_parsemessage: non " 752 "NUL-terminated identity in " 753 "IDENTITY extension header %d\n", 754 sadb_ext->sadb_ext_type)); 755 return (EINVAL); 756 } 757 758 j = PADUP(strlen(c) + 1) + 759 sizeof(struct sadb_ident); 760 761 if (i != j) { 762 DPRINTF(("pfkeyv2_parsemessage: actual" 763 " identity length does not match " 764 "expected length in identity " 765 "extension header %d\n", 766 sadb_ext->sadb_ext_type)); 767 return (EINVAL); 768 } 769 } 770 } 771 break; 772 case SADB_EXT_SENSITIVITY: 773 { 774 struct sadb_sens *sadb_sens = (struct sadb_sens *)p; 775 776 if (i < sizeof(struct sadb_sens)) { 777 DPRINTF(("pfkeyv2_parsemessage: bad header " 778 "length for SENSITIVITY extension " 779 "header\n")); 780 return (EINVAL); 781 } 782 783 if (i != (sadb_sens->sadb_sens_sens_len + 784 sadb_sens->sadb_sens_integ_len) * 785 sizeof(uint64_t) + 786 sizeof(struct sadb_sens)) { 787 DPRINTF(("pfkeyv2_parsemessage: bad payload " 788 "length for SENSITIVITY extension " 789 "header\n")); 790 return (EINVAL); 791 } 792 } 793 break; 794 case SADB_EXT_PROPOSAL: 795 { 796 struct sadb_prop *sadb_prop = (struct sadb_prop *)p; 797 798 if (i < sizeof(struct sadb_prop)) { 799 DPRINTF(("pfkeyv2_parsemessage: bad PROPOSAL " 800 "header length\n")); 801 return (EINVAL); 802 } 803 804 if (sadb_prop->sadb_prop_reserved) { 805 DPRINTF(("pfkeyv2_parsemessage: reserved field" 806 "set in PROPOSAL extension header\n")); 807 return (EINVAL); 808 } 809 810 if ((i - sizeof(struct sadb_prop)) % 811 sizeof(struct sadb_comb)) { 812 DPRINTF(("pfkeyv2_parsemessage: bad proposal " 813 "length\n")); 814 return (EINVAL); 815 } 816 817 { 818 struct sadb_comb *sadb_comb = 819 (struct sadb_comb *)(p + 820 sizeof(struct sadb_prop)); 821 int j; 822 823 for (j = 0; 824 j < (i - sizeof(struct sadb_prop))/ 825 sizeof(struct sadb_comb); 826 j++) { 827 if (sadb_comb->sadb_comb_auth > 828 SADB_AALG_MAX) { 829 DPRINTF(("pfkeyv2_parsemessage" 830 ": unknown authentication " 831 "algorithm %d in " 832 "PROPOSAL\n", 833 sadb_comb->sadb_comb_auth)); 834 return (EINVAL); 835 } 836 837 if (sadb_comb->sadb_comb_encrypt > 838 SADB_EALG_MAX) { 839 DPRINTF(("pfkeyv2_parsemessage" 840 ": unknown encryption " 841 "algorithm %d in " 842 "PROPOSAL\n", 843 sadb_comb->sadb_comb_encrypt)); 844 return (EINVAL); 845 } 846 847 if (sadb_comb->sadb_comb_reserved) { 848 DPRINTF(("pfkeyv2_parsemessage" 849 ": reserved field set in " 850 "COMB header\n")); 851 return (EINVAL); 852 } 853 } 854 } 855 } 856 break; 857 case SADB_EXT_SUPPORTED_AUTH: 858 case SADB_EXT_SUPPORTED_ENCRYPT: 859 case SADB_X_EXT_SUPPORTED_COMP: 860 { 861 struct sadb_supported *sadb_supported = 862 (struct sadb_supported *)p; 863 int j; 864 865 if (i < sizeof(struct sadb_supported)) { 866 DPRINTF(("pfkeyv2_parsemessage: bad header " 867 "length for SUPPORTED extension header " 868 "%d\n", sadb_ext->sadb_ext_type)); 869 return (EINVAL); 870 } 871 872 if (sadb_supported->sadb_supported_reserved) { 873 DPRINTF(("pfkeyv2_parsemessage: reserved " 874 "field set in SUPPORTED extension " 875 "header %d\n", sadb_ext->sadb_ext_type)); 876 return (EINVAL); 877 } 878 879 { 880 struct sadb_alg *sadb_alg = 881 (struct sadb_alg *)(p + 882 sizeof(struct sadb_supported)); 883 int max_alg; 884 885 max_alg = sadb_ext->sadb_ext_type == 886 SADB_EXT_SUPPORTED_AUTH ? 887 SADB_AALG_MAX : SADB_EXT_SUPPORTED_ENCRYPT ? 888 SADB_EALG_MAX : SADB_X_CALG_MAX; 889 890 for (j = 0; 891 j < sadb_supported->sadb_supported_len - 1; 892 j++) { 893 if (sadb_alg->sadb_alg_id > max_alg) { 894 DPRINTF(("pfkeyv2_parsemessage" 895 ": unknown algorithm %d " 896 "in SUPPORTED extension " 897 "header %d\n", 898 sadb_alg->sadb_alg_id, 899 sadb_ext->sadb_ext_type)); 900 return (EINVAL); 901 } 902 903 if (sadb_alg->sadb_alg_reserved) { 904 DPRINTF(("pfkeyv2_parsemessage" 905 ": reserved field set in " 906 "supported algorithms " 907 "header inside SUPPORTED " 908 "extension header %d\n", 909 sadb_ext->sadb_ext_type)); 910 return (EINVAL); 911 } 912 913 sadb_alg++; 914 } 915 } 916 } 917 break; 918 case SADB_EXT_SPIRANGE: 919 { 920 struct sadb_spirange *sadb_spirange = 921 (struct sadb_spirange *)p; 922 923 if (i != sizeof(struct sadb_spirange)) { 924 DPRINTF(("pfkeyv2_parsemessage: bad header " 925 "length of SPIRANGE extension header\n")); 926 return (EINVAL); 927 } 928 929 if (sadb_spirange->sadb_spirange_min > 930 sadb_spirange->sadb_spirange_max) { 931 DPRINTF(("pfkeyv2_parsemessage: bad SPI " 932 "range\n")); 933 return (EINVAL); 934 } 935 } 936 break; 937 case SADB_X_EXT_UDPENCAP: 938 if (i != sizeof(struct sadb_x_udpencap)) { 939 DPRINTF(("pfkeyv2_parsemessage: bad UDPENCAP " 940 "header length\n")); 941 return (EINVAL); 942 } 943 break; 944 #if NPF > 0 945 case SADB_X_EXT_TAG: 946 if (i < sizeof(struct sadb_x_tag)) { 947 DPRINTF(("pfkeyv2_parsemessage: " 948 "TAG extension header too small")); 949 return (EINVAL); 950 } 951 if (i > (sizeof(struct sadb_x_tag) + 952 PF_TAG_NAME_SIZE)) { 953 DPRINTF(("pfkeyv2_parsemessage: " 954 "TAG extension header too long")); 955 return (EINVAL); 956 } 957 break; 958 case SADB_X_EXT_TAP: 959 if (i < sizeof(struct sadb_x_tap)) { 960 DPRINTF(("pfkeyv2_parsemessage: " 961 "TAP extension header too small")); 962 return (EINVAL); 963 } 964 if (i > sizeof(struct sadb_x_tap)) { 965 DPRINTF(("pfkeyv2_parsemessage: " 966 "TAP extension header too long")); 967 return (EINVAL); 968 } 969 break; 970 #endif 971 default: 972 DPRINTF(("pfkeyv2_parsemessage: unknown extension " 973 "header type %d\n", 974 sadb_ext->sadb_ext_type)); 975 return (EINVAL); 976 } 977 978 headers[sadb_ext->sadb_ext_type] = p; 979 p += i; 980 left -= i; 981 } 982 983 if (left) { 984 DPRINTF(("pfkeyv2_parsemessage: message too long\n")); 985 return (EINVAL); 986 } 987 988 { 989 uint64_t required; 990 991 required = sadb_exts_required_in[sadb_msg->sadb_msg_type]; 992 993 if ((seen & required) != required) { 994 DPRINTF(("pfkeyv2_parsemessage: required fields " 995 "missing\n")); 996 return (EINVAL); 997 } 998 } 999 1000 switch (((struct sadb_msg *)headers[0])->sadb_msg_type) { 1001 case SADB_UPDATE: 1002 if (((struct sadb_sa *)headers[SADB_EXT_SA])->sadb_sa_state != 1003 SADB_SASTATE_MATURE) { 1004 DPRINTF(("pfkeyv2_parsemessage: updating non-mature " 1005 "SA prohibited\n")); 1006 return (EINVAL); 1007 } 1008 break; 1009 case SADB_ADD: 1010 if (((struct sadb_sa *)headers[SADB_EXT_SA])->sadb_sa_state != 1011 SADB_SASTATE_MATURE) { 1012 DPRINTF(("pfkeyv2_parsemessage: adding non-mature " 1013 "SA prohibited\n")); 1014 return (EINVAL); 1015 } 1016 break; 1017 } 1018 1019 return (0); 1020 } 1021