1 /* $OpenBSD: pfkeyv2.c,v 1.228 2021/12/14 17:50:37 bluhm 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/socket.h> 75 #include <sys/socketvar.h> 76 #include <sys/protosw.h> 77 #include <sys/domain.h> 78 #include <sys/systm.h> 79 #include <sys/mbuf.h> 80 #include <sys/kernel.h> 81 #include <sys/proc.h> 82 #include <sys/pool.h> 83 #include <sys/mutex.h> 84 85 #include <net/route.h> 86 #include <netinet/ip_ipsp.h> 87 #include <net/pfkeyv2.h> 88 #include <net/radix.h> 89 #include <netinet/ip_ah.h> 90 #include <netinet/ip_esp.h> 91 #include <netinet/ip_ipcomp.h> 92 #include <crypto/blf.h> 93 94 #if NPF > 0 95 #include <net/if.h> 96 #include <net/pfvar.h> 97 #endif 98 99 #define PFKEYSNDQ 8192 100 #define PFKEYRCVQ 8192 101 102 static const struct sadb_alg ealgs[] = { 103 { SADB_EALG_NULL, 0, 0, 0 }, 104 { SADB_EALG_3DESCBC, 64, 192, 192 }, 105 { SADB_X_EALG_BLF, 64, 40, BLF_MAXKEYLEN * 8}, 106 { SADB_X_EALG_CAST, 64, 40, 128}, 107 { SADB_X_EALG_AES, 128, 128, 256}, 108 { SADB_X_EALG_AESCTR, 128, 128 + 32, 256 + 32} 109 }; 110 111 static const struct sadb_alg aalgs[] = { 112 { SADB_AALG_SHA1HMAC, 0, 160, 160 }, 113 { SADB_AALG_MD5HMAC, 0, 128, 128 }, 114 { SADB_X_AALG_RIPEMD160HMAC, 0, 160, 160 }, 115 { SADB_X_AALG_SHA2_256, 0, 256, 256 }, 116 { SADB_X_AALG_SHA2_384, 0, 384, 384 }, 117 { SADB_X_AALG_SHA2_512, 0, 512, 512 } 118 }; 119 120 static const struct sadb_alg calgs[] = { 121 { SADB_X_CALG_DEFLATE, 0, 0, 0} 122 }; 123 124 struct pool pkpcb_pool; 125 #define PFKEY_MSG_MAXSZ 4096 126 const struct sockaddr pfkey_addr = { 2, PF_KEY, }; 127 const struct domain pfkeydomain; 128 129 /* 130 * pfkey PCB 131 * 132 * Locks used to protect struct members in this file: 133 * I immutable after creation 134 * a atomic operations 135 * l pkptable's lock 136 * s socket lock 137 */ 138 struct pkpcb { 139 struct socket *kcb_socket; /* [I] associated socket */ 140 141 SRPL_ENTRY(pkpcb) kcb_list; /* [l] */ 142 struct refcnt kcb_refcnt; /* [a] */ 143 int kcb_flags; /* [s] */ 144 uint32_t kcb_reg; /* [s] Inc if SATYPE_MAX > 31 */ 145 uint32_t kcb_pid; /* [I] */ 146 unsigned int kcb_rdomain; /* [I] routing domain */ 147 }; 148 #define sotokeycb(so) ((struct pkpcb *)(so)->so_pcb) 149 #define keylock(kp) solock((kp)->kcb_socket) 150 #define keyunlock(kp, s) sounlock((kp)->kcb_socket, s) 151 152 153 struct dump_state { 154 struct sadb_msg *sadb_msg; 155 struct socket *socket; 156 }; 157 158 struct pkptable { 159 SRPL_HEAD(, pkpcb) pkp_list; 160 struct srpl_rc pkp_rc; 161 struct rwlock pkp_lk; 162 }; 163 164 struct pkptable pkptable; 165 struct mutex pfkeyv2_mtx = MUTEX_INITIALIZER(IPL_MPFLOOR); 166 static uint32_t pfkeyv2_seq = 1; 167 static int nregistered = 0; 168 static int npromisc = 0; 169 170 void pfkey_init(void); 171 172 int pfkeyv2_attach(struct socket *, int); 173 int pfkeyv2_detach(struct socket *); 174 int pfkeyv2_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, 175 struct mbuf *, struct proc *); 176 int pfkeyv2_output(struct mbuf *, struct socket *, struct sockaddr *, 177 struct mbuf *); 178 int pfkey_sendup(struct pkpcb *, struct mbuf *, int); 179 int pfkeyv2_sa_flush(struct tdb *, void *, int); 180 int pfkeyv2_policy_flush(struct ipsec_policy *, void *, unsigned int); 181 int pfkeyv2_sysctl_policydumper(struct ipsec_policy *, void *, unsigned int); 182 183 void keycb_ref(void *, void *); 184 void keycb_unref(void *, void *); 185 186 /* 187 * Wrapper around m_devget(); copy data from contiguous buffer to mbuf 188 * chain. 189 */ 190 int 191 pfdatatopacket(void *data, int len, struct mbuf **packet) 192 { 193 if (!(*packet = m_devget(data, len, 0))) 194 return (ENOMEM); 195 196 /* Make sure, all data gets zeroized on free */ 197 (*packet)->m_flags |= M_ZEROIZE; 198 199 return (0); 200 } 201 202 const struct protosw pfkeysw[] = { 203 { 204 .pr_type = SOCK_RAW, 205 .pr_domain = &pfkeydomain, 206 .pr_protocol = PF_KEY_V2, 207 .pr_flags = PR_ATOMIC | PR_ADDR, 208 .pr_output = pfkeyv2_output, 209 .pr_usrreq = pfkeyv2_usrreq, 210 .pr_attach = pfkeyv2_attach, 211 .pr_detach = pfkeyv2_detach, 212 .pr_sysctl = pfkeyv2_sysctl, 213 } 214 }; 215 216 const struct domain pfkeydomain = { 217 .dom_family = PF_KEY, 218 .dom_name = "PF_KEY", 219 .dom_init = pfkey_init, 220 .dom_protosw = pfkeysw, 221 .dom_protoswNPROTOSW = &pfkeysw[nitems(pfkeysw)], 222 }; 223 224 void 225 keycb_ref(void *null, void *v) 226 { 227 struct pkpcb *kp = v; 228 229 refcnt_take(&kp->kcb_refcnt); 230 } 231 232 void 233 keycb_unref(void *null, void *v) 234 { 235 struct pkpcb *kp = v; 236 237 refcnt_rele_wake(&kp->kcb_refcnt); 238 } 239 240 void 241 pfkey_init(void) 242 { 243 rn_init(sizeof(struct sockaddr_encap)); 244 srpl_rc_init(&pkptable.pkp_rc, keycb_ref, keycb_unref, NULL); 245 rw_init(&pkptable.pkp_lk, "pfkey"); 246 SRPL_INIT(&pkptable.pkp_list); 247 pool_init(&pkpcb_pool, sizeof(struct pkpcb), 0, 248 IPL_SOFTNET, PR_WAITOK, "pkpcb", NULL); 249 pool_init(&ipsec_policy_pool, sizeof(struct ipsec_policy), 0, 250 IPL_SOFTNET, 0, "ipsec policy", NULL); 251 pool_init(&ipsec_acquire_pool, sizeof(struct ipsec_acquire), 0, 252 IPL_SOFTNET, 0, "ipsec acquire", NULL); 253 } 254 255 256 /* 257 * Attach a new PF_KEYv2 socket. 258 */ 259 int 260 pfkeyv2_attach(struct socket *so, int proto) 261 { 262 struct pkpcb *kp; 263 int error; 264 265 if ((so->so_state & SS_PRIV) == 0) 266 return EACCES; 267 268 error = soreserve(so, PFKEYSNDQ, PFKEYRCVQ); 269 if (error) 270 return (error); 271 272 kp = pool_get(&pkpcb_pool, PR_WAITOK|PR_ZERO); 273 so->so_pcb = kp; 274 refcnt_init(&kp->kcb_refcnt); 275 kp->kcb_socket = so; 276 kp->kcb_pid = curproc->p_p->ps_pid; 277 kp->kcb_rdomain = rtable_l2(curproc->p_p->ps_rtableid); 278 279 so->so_options |= SO_USELOOPBACK; 280 soisconnected(so); 281 282 rw_enter(&pkptable.pkp_lk, RW_WRITE); 283 SRPL_INSERT_HEAD_LOCKED(&pkptable.pkp_rc, &pkptable.pkp_list, kp, kcb_list); 284 rw_exit(&pkptable.pkp_lk); 285 286 return (0); 287 } 288 289 /* 290 * Close a PF_KEYv2 socket. 291 */ 292 int 293 pfkeyv2_detach(struct socket *so) 294 { 295 struct pkpcb *kp; 296 297 soassertlocked(so); 298 299 kp = sotokeycb(so); 300 if (kp == NULL) 301 return ENOTCONN; 302 303 if (kp->kcb_flags & 304 (PFKEYV2_SOCKETFLAGS_REGISTERED|PFKEYV2_SOCKETFLAGS_PROMISC)) { 305 mtx_enter(&pfkeyv2_mtx); 306 if (kp->kcb_flags & PFKEYV2_SOCKETFLAGS_REGISTERED) 307 nregistered--; 308 309 if (kp->kcb_flags & PFKEYV2_SOCKETFLAGS_PROMISC) 310 npromisc--; 311 mtx_leave(&pfkeyv2_mtx); 312 } 313 314 rw_enter(&pkptable.pkp_lk, RW_WRITE); 315 SRPL_REMOVE_LOCKED(&pkptable.pkp_rc, &pkptable.pkp_list, kp, pkpcb, 316 kcb_list); 317 rw_exit(&pkptable.pkp_lk); 318 319 sounlock(so, SL_LOCKED); 320 /* wait for all references to drop */ 321 refcnt_finalize(&kp->kcb_refcnt, "pfkeyrefs"); 322 solock(so); 323 324 so->so_pcb = NULL; 325 KASSERT((so->so_state & SS_NOFDREF) == 0); 326 pool_put(&pkpcb_pool, kp); 327 328 return (0); 329 } 330 331 int 332 pfkeyv2_usrreq(struct socket *so, int req, struct mbuf *m, 333 struct mbuf *nam, struct mbuf *control, struct proc *p) 334 { 335 struct pkpcb *kp; 336 int error = 0; 337 338 if (req == PRU_CONTROL) 339 return (EOPNOTSUPP); 340 341 soassertlocked(so); 342 343 if (control && control->m_len) { 344 error = EOPNOTSUPP; 345 goto release; 346 } 347 348 kp = sotokeycb(so); 349 if (kp == NULL) { 350 error = EINVAL; 351 goto release; 352 } 353 354 switch (req) { 355 /* no connect, bind, accept. Socket is connected from the start */ 356 case PRU_CONNECT: 357 case PRU_BIND: 358 case PRU_CONNECT2: 359 case PRU_LISTEN: 360 case PRU_ACCEPT: 361 error = EOPNOTSUPP; 362 break; 363 364 case PRU_DISCONNECT: 365 case PRU_ABORT: 366 soisdisconnected(so); 367 break; 368 case PRU_SHUTDOWN: 369 socantsendmore(so); 370 break; 371 case PRU_SENSE: 372 /* stat: don't bother with a blocksize. */ 373 break; 374 375 /* minimal support, just implement a fake peer address */ 376 case PRU_SOCKADDR: 377 error = EINVAL; 378 break; 379 case PRU_PEERADDR: 380 bcopy(&pfkey_addr, mtod(nam, caddr_t), pfkey_addr.sa_len); 381 nam->m_len = pfkey_addr.sa_len; 382 break; 383 384 case PRU_RCVOOB: 385 case PRU_RCVD: 386 case PRU_SENDOOB: 387 error = EOPNOTSUPP; 388 break; 389 case PRU_SEND: 390 if (nam) { 391 error = EISCONN; 392 break; 393 } 394 error = (*so->so_proto->pr_output)(m, so, NULL, NULL); 395 m = NULL; 396 break; 397 default: 398 panic("pfkeyv2_usrreq"); 399 } 400 401 release: 402 if (req != PRU_RCVD && req != PRU_RCVOOB && req != PRU_SENSE) { 403 m_freem(control); 404 m_freem(m); 405 } 406 return (error); 407 } 408 409 int 410 pfkeyv2_output(struct mbuf *mbuf, struct socket *so, 411 struct sockaddr *dstaddr, struct mbuf *control) 412 { 413 void *message; 414 int error = 0; 415 416 #ifdef DIAGNOSTIC 417 if (!mbuf || !(mbuf->m_flags & M_PKTHDR)) { 418 error = EINVAL; 419 goto ret; 420 } 421 #endif /* DIAGNOSTIC */ 422 423 if (mbuf->m_pkthdr.len > PFKEY_MSG_MAXSZ) { 424 error = EMSGSIZE; 425 goto ret; 426 } 427 428 if (!(message = malloc((unsigned long) mbuf->m_pkthdr.len, 429 M_PFKEY, M_DONTWAIT))) { 430 error = ENOMEM; 431 goto ret; 432 } 433 434 m_copydata(mbuf, 0, mbuf->m_pkthdr.len, message); 435 436 /* 437 * The socket can't be closed concurrently because the file 438 * descriptor reference is still held. 439 */ 440 441 sounlock(so, SL_LOCKED); 442 error = pfkeyv2_send(so, message, mbuf->m_pkthdr.len); 443 solock(so); 444 445 ret: 446 m_freem(mbuf); 447 return (error); 448 } 449 450 int 451 pfkey_sendup(struct pkpcb *kp, struct mbuf *m0, int more) 452 { 453 struct socket *so = kp->kcb_socket; 454 struct mbuf *m; 455 456 soassertlocked(so); 457 458 if (more) { 459 if (!(m = m_dup_pkt(m0, 0, M_DONTWAIT))) 460 return (ENOMEM); 461 } else 462 m = m0; 463 464 if (!sbappendaddr(so, &so->so_rcv, &pfkey_addr, m, NULL)) { 465 m_freem(m); 466 return (ENOBUFS); 467 } 468 469 sorwakeup(so); 470 return (0); 471 } 472 473 /* 474 * Send a PFKEYv2 message, possibly to many receivers, based on the 475 * satype of the socket (which is set by the REGISTER message), and the 476 * third argument. 477 */ 478 int 479 pfkeyv2_sendmessage(void **headers, int mode, struct socket *so, 480 u_int8_t satype, int count, u_int rdomain) 481 { 482 int i, j, rval, s; 483 void *p, *buffer = NULL; 484 struct mbuf *packet; 485 struct pkpcb *kp; 486 struct sadb_msg *smsg; 487 struct srp_ref sr; 488 489 /* Find out how much space we'll need... */ 490 j = sizeof(struct sadb_msg); 491 492 for (i = 1; i <= SADB_EXT_MAX; i++) 493 if (headers[i]) 494 j += ((struct sadb_ext *)headers[i])->sadb_ext_len * 495 sizeof(uint64_t); 496 497 /* ...and allocate it */ 498 if (!(buffer = malloc(j + sizeof(struct sadb_msg), M_PFKEY, 499 M_NOWAIT))) { 500 rval = ENOMEM; 501 goto ret; 502 } 503 504 p = buffer + sizeof(struct sadb_msg); 505 bcopy(headers[0], p, sizeof(struct sadb_msg)); 506 ((struct sadb_msg *) p)->sadb_msg_len = j / sizeof(uint64_t); 507 p += sizeof(struct sadb_msg); 508 509 /* Copy payloads in the packet */ 510 for (i = 1; i <= SADB_EXT_MAX; i++) 511 if (headers[i]) { 512 ((struct sadb_ext *) headers[i])->sadb_ext_type = i; 513 bcopy(headers[i], p, EXTLEN(headers[i])); 514 p += EXTLEN(headers[i]); 515 } 516 517 if ((rval = pfdatatopacket(buffer + sizeof(struct sadb_msg), 518 j, &packet)) != 0) 519 goto ret; 520 521 switch (mode) { 522 case PFKEYV2_SENDMESSAGE_UNICAST: 523 /* 524 * Send message to the specified socket, plus all 525 * promiscuous listeners. 526 */ 527 s = solock(so); 528 pfkey_sendup(sotokeycb(so), packet, 0); 529 sounlock(so, s); 530 531 /* 532 * Promiscuous messages contain the original message 533 * encapsulated in another sadb_msg header. 534 */ 535 bzero(buffer, sizeof(struct sadb_msg)); 536 smsg = (struct sadb_msg *) buffer; 537 smsg->sadb_msg_version = PF_KEY_V2; 538 smsg->sadb_msg_type = SADB_X_PROMISC; 539 smsg->sadb_msg_len = (sizeof(struct sadb_msg) + j) / 540 sizeof(uint64_t); 541 smsg->sadb_msg_seq = 0; 542 543 /* Copy to mbuf chain */ 544 if ((rval = pfdatatopacket(buffer, sizeof(struct sadb_msg) + j, 545 &packet)) != 0) 546 goto ret; 547 548 /* 549 * Search for promiscuous listeners, skipping the 550 * original destination. 551 */ 552 SRPL_FOREACH(kp, &sr, &pkptable.pkp_list, kcb_list) { 553 if (kp->kcb_socket == so || kp->kcb_rdomain != rdomain) 554 continue; 555 556 s = keylock(kp); 557 if (kp->kcb_flags & PFKEYV2_SOCKETFLAGS_PROMISC) 558 pfkey_sendup(kp, packet, 1); 559 keyunlock(kp, s); 560 } 561 SRPL_LEAVE(&sr); 562 m_freem(packet); 563 break; 564 565 case PFKEYV2_SENDMESSAGE_REGISTERED: 566 /* 567 * Send the message to all registered sockets that match 568 * the specified satype (e.g., all IPSEC-ESP negotiators) 569 */ 570 SRPL_FOREACH(kp, &sr, &pkptable.pkp_list, kcb_list) { 571 if (kp->kcb_rdomain != rdomain) 572 continue; 573 574 s = keylock(kp); 575 if (kp->kcb_flags & PFKEYV2_SOCKETFLAGS_REGISTERED) { 576 if (!satype) { 577 /* Just send to everyone registered */ 578 pfkey_sendup(kp, packet, 1); 579 } else { 580 /* Check for specified satype */ 581 if ((1 << satype) & kp->kcb_reg) 582 pfkey_sendup(kp, packet, 1); 583 } 584 } 585 keyunlock(kp, s); 586 } 587 SRPL_LEAVE(&sr); 588 /* Free last/original copy of the packet */ 589 m_freem(packet); 590 591 /* Encapsulate the original message "inside" an sadb_msg header */ 592 bzero(buffer, sizeof(struct sadb_msg)); 593 smsg = (struct sadb_msg *) buffer; 594 smsg->sadb_msg_version = PF_KEY_V2; 595 smsg->sadb_msg_type = SADB_X_PROMISC; 596 smsg->sadb_msg_len = (sizeof(struct sadb_msg) + j) / 597 sizeof(uint64_t); 598 smsg->sadb_msg_seq = 0; 599 600 /* Convert to mbuf chain */ 601 if ((rval = pfdatatopacket(buffer, sizeof(struct sadb_msg) + j, 602 &packet)) != 0) 603 goto ret; 604 605 /* Send to all registered promiscuous listeners */ 606 SRPL_FOREACH(kp, &sr, &pkptable.pkp_list, kcb_list) { 607 if (kp->kcb_rdomain != rdomain) 608 continue; 609 610 s = keylock(kp); 611 if ((kp->kcb_flags & PFKEYV2_SOCKETFLAGS_PROMISC) && 612 !(kp->kcb_flags & PFKEYV2_SOCKETFLAGS_REGISTERED)) 613 pfkey_sendup(kp, packet, 1); 614 keyunlock(kp, s); 615 } 616 SRPL_LEAVE(&sr); 617 m_freem(packet); 618 break; 619 620 case PFKEYV2_SENDMESSAGE_BROADCAST: 621 /* Send message to all sockets */ 622 SRPL_FOREACH(kp, &sr, &pkptable.pkp_list, kcb_list) { 623 if (kp->kcb_rdomain != rdomain) 624 continue; 625 626 s = keylock(kp); 627 pfkey_sendup(kp, packet, 1); 628 keyunlock(kp, s); 629 } 630 SRPL_LEAVE(&sr); 631 m_freem(packet); 632 break; 633 } 634 635 ret: 636 if (buffer != NULL) { 637 explicit_bzero(buffer, j + sizeof(struct sadb_msg)); 638 free(buffer, M_PFKEY, j + sizeof(struct sadb_msg)); 639 } 640 641 return (rval); 642 } 643 644 /* 645 * Get SPD information for an ACQUIRE. We setup the message such that 646 * the SRC/DST payloads are relative to us (regardless of whether the 647 * SPD rule was for incoming or outgoing packets). 648 */ 649 int 650 pfkeyv2_policy(struct ipsec_acquire *ipa, void **headers, void **buffer, 651 int *bufferlen) 652 { 653 union sockaddr_union sunion; 654 struct sadb_protocol *sp; 655 int rval, i, dir; 656 void *p; 657 658 /* Find out how big a buffer we need */ 659 i = 4 * sizeof(struct sadb_address) + sizeof(struct sadb_protocol); 660 bzero(&sunion, sizeof(union sockaddr_union)); 661 662 switch (ipa->ipa_info.sen_type) { 663 case SENT_IP4: 664 i += 4 * PADUP(sizeof(struct sockaddr_in)); 665 sunion.sa.sa_family = AF_INET; 666 sunion.sa.sa_len = sizeof(struct sockaddr_in); 667 dir = ipa->ipa_info.sen_direction; 668 break; 669 670 #ifdef INET6 671 case SENT_IP6: 672 i += 4 * PADUP(sizeof(struct sockaddr_in6)); 673 sunion.sa.sa_family = AF_INET6; 674 sunion.sa.sa_len = sizeof(struct sockaddr_in6); 675 dir = ipa->ipa_info.sen_ip6_direction; 676 break; 677 #endif /* INET6 */ 678 679 default: 680 return (EINVAL); 681 } 682 683 if (!(p = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) { 684 rval = ENOMEM; 685 goto ret; 686 } else { 687 *buffer = p; 688 *bufferlen = i; 689 } 690 691 if (dir == IPSP_DIRECTION_OUT) 692 headers[SADB_X_EXT_SRC_FLOW] = p; 693 else 694 headers[SADB_X_EXT_DST_FLOW] = p; 695 switch (sunion.sa.sa_family) { 696 case AF_INET: 697 sunion.sin.sin_addr = ipa->ipa_info.sen_ip_src; 698 sunion.sin.sin_port = ipa->ipa_info.sen_sport; 699 break; 700 701 #ifdef INET6 702 case AF_INET6: 703 sunion.sin6.sin6_addr = ipa->ipa_info.sen_ip6_src; 704 sunion.sin6.sin6_port = ipa->ipa_info.sen_ip6_sport; 705 break; 706 #endif /* INET6 */ 707 } 708 export_address(&p, &sunion.sa); 709 710 if (dir == IPSP_DIRECTION_OUT) 711 headers[SADB_X_EXT_SRC_MASK] = p; 712 else 713 headers[SADB_X_EXT_DST_MASK] = p; 714 switch (sunion.sa.sa_family) { 715 case AF_INET: 716 sunion.sin.sin_addr = ipa->ipa_mask.sen_ip_src; 717 sunion.sin.sin_port = ipa->ipa_mask.sen_sport; 718 break; 719 720 #ifdef INET6 721 case AF_INET6: 722 sunion.sin6.sin6_addr = ipa->ipa_mask.sen_ip6_src; 723 sunion.sin6.sin6_port = ipa->ipa_mask.sen_ip6_sport; 724 break; 725 #endif /* INET6 */ 726 } 727 export_address(&p, &sunion.sa); 728 729 if (dir == IPSP_DIRECTION_OUT) 730 headers[SADB_X_EXT_DST_FLOW] = p; 731 else 732 headers[SADB_X_EXT_SRC_FLOW] = p; 733 switch (sunion.sa.sa_family) { 734 case AF_INET: 735 sunion.sin.sin_addr = ipa->ipa_info.sen_ip_dst; 736 sunion.sin.sin_port = ipa->ipa_info.sen_dport; 737 break; 738 739 #ifdef INET6 740 case AF_INET6: 741 sunion.sin6.sin6_addr = ipa->ipa_info.sen_ip6_dst; 742 sunion.sin6.sin6_port = ipa->ipa_info.sen_ip6_dport; 743 break; 744 #endif /* INET6 */ 745 } 746 export_address(&p, &sunion.sa); 747 748 if (dir == IPSP_DIRECTION_OUT) 749 headers[SADB_X_EXT_DST_MASK] = p; 750 else 751 headers[SADB_X_EXT_SRC_MASK] = p; 752 switch (sunion.sa.sa_family) { 753 case AF_INET: 754 sunion.sin.sin_addr = ipa->ipa_mask.sen_ip_dst; 755 sunion.sin.sin_port = ipa->ipa_mask.sen_dport; 756 break; 757 758 #ifdef INET6 759 case AF_INET6: 760 sunion.sin6.sin6_addr = ipa->ipa_mask.sen_ip6_dst; 761 sunion.sin6.sin6_port = ipa->ipa_mask.sen_ip6_dport; 762 break; 763 #endif /* INET6 */ 764 } 765 export_address(&p, &sunion.sa); 766 767 headers[SADB_X_EXT_FLOW_TYPE] = p; 768 sp = p; 769 sp->sadb_protocol_len = sizeof(struct sadb_protocol) / 770 sizeof(u_int64_t); 771 switch (sunion.sa.sa_family) { 772 case AF_INET: 773 if (ipa->ipa_mask.sen_proto) 774 sp->sadb_protocol_proto = ipa->ipa_info.sen_proto; 775 sp->sadb_protocol_direction = ipa->ipa_info.sen_direction; 776 break; 777 778 #ifdef INET6 779 case AF_INET6: 780 if (ipa->ipa_mask.sen_ip6_proto) 781 sp->sadb_protocol_proto = ipa->ipa_info.sen_ip6_proto; 782 sp->sadb_protocol_direction = ipa->ipa_info.sen_ip6_direction; 783 break; 784 #endif /* INET6 */ 785 } 786 787 rval = 0; 788 789 ret: 790 return (rval); 791 } 792 793 /* 794 * Get all the information contained in an SA to a PFKEYV2 message. 795 */ 796 int 797 pfkeyv2_get(struct tdb *tdb, void **headers, void **buffer, int *lenp, 798 int *lenused) 799 { 800 int rval, i; 801 void *p; 802 803 NET_ASSERT_LOCKED(); 804 805 /* Find how much space we need */ 806 i = sizeof(struct sadb_sa) + sizeof(struct sadb_lifetime) + 807 sizeof(struct sadb_x_counter); 808 809 if (tdb->tdb_soft_allocations || tdb->tdb_soft_bytes || 810 tdb->tdb_soft_timeout || tdb->tdb_soft_first_use) 811 i += sizeof(struct sadb_lifetime); 812 813 if (tdb->tdb_exp_allocations || tdb->tdb_exp_bytes || 814 tdb->tdb_exp_timeout || tdb->tdb_exp_first_use) 815 i += sizeof(struct sadb_lifetime); 816 817 if (tdb->tdb_last_used) 818 i += sizeof(struct sadb_lifetime); 819 820 i += sizeof(struct sadb_address) + PADUP(tdb->tdb_src.sa.sa_len); 821 i += sizeof(struct sadb_address) + PADUP(tdb->tdb_dst.sa.sa_len); 822 823 if (tdb->tdb_ids) { 824 i += sizeof(struct sadb_ident) + PADUP(tdb->tdb_ids->id_local->len); 825 i += sizeof(struct sadb_ident) + PADUP(tdb->tdb_ids->id_remote->len); 826 } 827 828 if (tdb->tdb_amxkey) 829 i += sizeof(struct sadb_key) + PADUP(tdb->tdb_amxkeylen); 830 831 if (tdb->tdb_emxkey) 832 i += sizeof(struct sadb_key) + PADUP(tdb->tdb_emxkeylen); 833 834 if (tdb->tdb_filter.sen_type) { 835 i += 2 * sizeof(struct sadb_protocol); 836 837 /* We'll need four of them: src, src mask, dst, dst mask. */ 838 switch (tdb->tdb_filter.sen_type) { 839 case SENT_IP4: 840 i += 4 * PADUP(sizeof(struct sockaddr_in)); 841 i += 4 * sizeof(struct sadb_address); 842 break; 843 #ifdef INET6 844 case SENT_IP6: 845 i += 4 * PADUP(sizeof(struct sockaddr_in6)); 846 i += 4 * sizeof(struct sadb_address); 847 break; 848 #endif /* INET6 */ 849 default: 850 rval = EINVAL; 851 goto ret; 852 } 853 } 854 855 if (tdb->tdb_onext) { 856 i += sizeof(struct sadb_sa); 857 i += sizeof(struct sadb_address) + 858 PADUP(tdb->tdb_onext->tdb_dst.sa.sa_len); 859 i += sizeof(struct sadb_protocol); 860 } 861 862 if (tdb->tdb_udpencap_port) 863 i += sizeof(struct sadb_x_udpencap); 864 865 i += sizeof(struct sadb_x_replay); 866 867 if (tdb->tdb_mtu > 0) 868 i+= sizeof(struct sadb_x_mtu); 869 870 if (tdb->tdb_rdomain != tdb->tdb_rdomain_post) 871 i += sizeof(struct sadb_x_rdomain); 872 873 #if NPF > 0 874 if (tdb->tdb_tag) 875 i += sizeof(struct sadb_x_tag) + PADUP(PF_TAG_NAME_SIZE); 876 if (tdb->tdb_tap) 877 i += sizeof(struct sadb_x_tap); 878 #endif 879 880 if (lenp) 881 *lenp = i; 882 883 if (buffer == NULL) { 884 rval = 0; 885 goto ret; 886 } 887 888 if (!(p = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) { 889 rval = ENOMEM; 890 goto ret; 891 } else 892 *buffer = p; 893 894 headers[SADB_EXT_SA] = p; 895 896 export_sa(&p, tdb); /* Export SA information (mostly flags) */ 897 898 /* Export lifetimes where applicable */ 899 headers[SADB_EXT_LIFETIME_CURRENT] = p; 900 export_lifetime(&p, tdb, PFKEYV2_LIFETIME_CURRENT); 901 902 if (tdb->tdb_soft_allocations || tdb->tdb_soft_bytes || 903 tdb->tdb_soft_first_use || tdb->tdb_soft_timeout) { 904 headers[SADB_EXT_LIFETIME_SOFT] = p; 905 export_lifetime(&p, tdb, PFKEYV2_LIFETIME_SOFT); 906 } 907 908 if (tdb->tdb_exp_allocations || tdb->tdb_exp_bytes || 909 tdb->tdb_exp_first_use || tdb->tdb_exp_timeout) { 910 headers[SADB_EXT_LIFETIME_HARD] = p; 911 export_lifetime(&p, tdb, PFKEYV2_LIFETIME_HARD); 912 } 913 914 if (tdb->tdb_last_used) { 915 headers[SADB_X_EXT_LIFETIME_LASTUSE] = p; 916 export_lifetime(&p, tdb, PFKEYV2_LIFETIME_LASTUSE); 917 } 918 919 /* Export TDB source address */ 920 headers[SADB_EXT_ADDRESS_SRC] = p; 921 export_address(&p, &tdb->tdb_src.sa); 922 923 /* Export TDB destination address */ 924 headers[SADB_EXT_ADDRESS_DST] = p; 925 export_address(&p, &tdb->tdb_dst.sa); 926 927 /* Export source/destination identities, if present */ 928 if (tdb->tdb_ids) 929 export_identities(&p, tdb->tdb_ids, tdb->tdb_ids_swapped, headers); 930 931 /* Export authentication key, if present */ 932 if (tdb->tdb_amxkey) { 933 headers[SADB_EXT_KEY_AUTH] = p; 934 export_key(&p, tdb, PFKEYV2_AUTHENTICATION_KEY); 935 } 936 937 /* Export encryption key, if present */ 938 if (tdb->tdb_emxkey) { 939 headers[SADB_EXT_KEY_ENCRYPT] = p; 940 export_key(&p, tdb, PFKEYV2_ENCRYPTION_KEY); 941 } 942 943 /* Export flow/filter, if present */ 944 if (tdb->tdb_filter.sen_type) 945 export_flow(&p, IPSP_IPSEC_USE, &tdb->tdb_filter, 946 &tdb->tdb_filtermask, headers); 947 948 if (tdb->tdb_onext) { 949 headers[SADB_X_EXT_SA2] = p; 950 export_sa(&p, tdb->tdb_onext); 951 headers[SADB_X_EXT_DST2] = p; 952 export_address(&p, &tdb->tdb_onext->tdb_dst.sa); 953 headers[SADB_X_EXT_SATYPE2] = p; 954 export_satype(&p, tdb->tdb_onext); 955 } 956 957 /* Export UDP encapsulation port, if present */ 958 if (tdb->tdb_udpencap_port) { 959 headers[SADB_X_EXT_UDPENCAP] = p; 960 export_udpencap(&p, tdb); 961 } 962 963 headers[SADB_X_EXT_REPLAY] = p; 964 export_replay(&p, tdb); 965 966 if (tdb->tdb_mtu > 0) { 967 headers[SADB_X_EXT_MTU] = p; 968 export_mtu(&p, tdb); 969 } 970 971 /* Export rdomain switch, if present */ 972 if (tdb->tdb_rdomain != tdb->tdb_rdomain_post) { 973 headers[SADB_X_EXT_RDOMAIN] = p; 974 export_rdomain(&p, tdb); 975 } 976 977 #if NPF > 0 978 /* Export tag information, if present */ 979 if (tdb->tdb_tag) { 980 headers[SADB_X_EXT_TAG] = p; 981 export_tag(&p, tdb); 982 } 983 984 /* Export tap enc(4) device information, if present */ 985 if (tdb->tdb_tap) { 986 headers[SADB_X_EXT_TAP] = p; 987 export_tap(&p, tdb); 988 } 989 #endif 990 991 headers[SADB_X_EXT_COUNTER] = p; 992 export_counter(&p, tdb); 993 994 if (lenused) 995 *lenused = p - *buffer; 996 rval = 0; 997 998 ret: 999 return (rval); 1000 } 1001 1002 /* 1003 * Dump a TDB. 1004 */ 1005 int 1006 pfkeyv2_dump_walker(struct tdb *tdb, void *state, int last) 1007 { 1008 struct dump_state *dump_state = (struct dump_state *) state; 1009 void *headers[SADB_EXT_MAX+1], *buffer; 1010 int buflen; 1011 int rval; 1012 1013 /* If not satype was specified, dump all TDBs */ 1014 if (!dump_state->sadb_msg->sadb_msg_satype || 1015 (tdb->tdb_satype == dump_state->sadb_msg->sadb_msg_satype)) { 1016 bzero(headers, sizeof(headers)); 1017 headers[0] = (void *) dump_state->sadb_msg; 1018 1019 /* Get the information from the TDB to a PFKEYv2 message */ 1020 if ((rval = pfkeyv2_get(tdb, headers, &buffer, &buflen, NULL)) != 0) 1021 return (rval); 1022 1023 if (last) 1024 ((struct sadb_msg *)headers[0])->sadb_msg_seq = 0; 1025 1026 /* Send the message to the specified socket */ 1027 rval = pfkeyv2_sendmessage(headers, 1028 PFKEYV2_SENDMESSAGE_UNICAST, dump_state->socket, 0, 0, 1029 tdb->tdb_rdomain); 1030 1031 explicit_bzero(buffer, buflen); 1032 free(buffer, M_PFKEY, buflen); 1033 if (rval) 1034 return (rval); 1035 } 1036 1037 return (0); 1038 } 1039 1040 /* 1041 * Delete an SA. 1042 */ 1043 int 1044 pfkeyv2_sa_flush(struct tdb *tdb, void *satype_vp, int last) 1045 { 1046 if (!(*((u_int8_t *) satype_vp)) || 1047 tdb->tdb_satype == *((u_int8_t *) satype_vp)) 1048 tdb_delete_locked(tdb); 1049 return (0); 1050 } 1051 1052 /* 1053 * Convert between SATYPEs and IPsec protocols, taking into consideration 1054 * sysctl variables enabling/disabling ESP/AH and the presence of the old 1055 * IPsec transforms. 1056 */ 1057 int 1058 pfkeyv2_get_proto_alg(u_int8_t satype, u_int8_t *sproto, int *alg) 1059 { 1060 switch (satype) { 1061 #ifdef IPSEC 1062 case SADB_SATYPE_AH: 1063 if (!ah_enable) 1064 return (EOPNOTSUPP); 1065 1066 *sproto = IPPROTO_AH; 1067 1068 if(alg != NULL) 1069 *alg = satype = XF_AH; 1070 1071 break; 1072 1073 case SADB_SATYPE_ESP: 1074 if (!esp_enable) 1075 return (EOPNOTSUPP); 1076 1077 *sproto = IPPROTO_ESP; 1078 1079 if(alg != NULL) 1080 *alg = satype = XF_ESP; 1081 1082 break; 1083 1084 case SADB_X_SATYPE_IPIP: 1085 *sproto = IPPROTO_IPIP; 1086 1087 if (alg != NULL) 1088 *alg = XF_IP4; 1089 1090 break; 1091 1092 case SADB_X_SATYPE_IPCOMP: 1093 if (!ipcomp_enable) 1094 return (EOPNOTSUPP); 1095 1096 *sproto = IPPROTO_IPCOMP; 1097 1098 if(alg != NULL) 1099 *alg = satype = XF_IPCOMP; 1100 1101 break; 1102 #endif /* IPSEC */ 1103 #ifdef TCP_SIGNATURE 1104 case SADB_X_SATYPE_TCPSIGNATURE: 1105 *sproto = IPPROTO_TCP; 1106 1107 if (alg != NULL) 1108 *alg = XF_TCPSIGNATURE; 1109 1110 break; 1111 #endif /* TCP_SIGNATURE */ 1112 1113 default: /* Nothing else supported */ 1114 return (EOPNOTSUPP); 1115 } 1116 1117 return (0); 1118 } 1119 1120 /* 1121 * Handle all messages from userland to kernel. 1122 */ 1123 int 1124 pfkeyv2_send(struct socket *so, void *message, int len) 1125 { 1126 int i, j, rval = 0, mode = PFKEYV2_SENDMESSAGE_BROADCAST; 1127 int delflag = 0; 1128 struct sockaddr_encap encapdst, encapnetmask; 1129 struct ipsec_policy *ipo; 1130 struct ipsec_acquire *ipa; 1131 struct radix_node_head *rnh; 1132 struct radix_node *rn = NULL; 1133 struct pkpcb *kp, *bkp; 1134 void *freeme = NULL, *freeme2 = NULL, *freeme3 = NULL; 1135 int freeme_sz = 0, freeme2_sz = 0, freeme3_sz = 0; 1136 void *bckptr = NULL; 1137 void *headers[SADB_EXT_MAX + 1]; 1138 union sockaddr_union *sunionp; 1139 struct tdb *sa1 = NULL, *sa2 = NULL; 1140 struct sadb_msg *smsg; 1141 struct sadb_spirange *sprng; 1142 struct sadb_sa *ssa; 1143 struct sadb_supported *ssup; 1144 struct sadb_ident *sid, *did; 1145 struct srp_ref sr; 1146 struct sadb_x_rdomain *srdomain; 1147 u_int rdomain = 0; 1148 int promisc, s; 1149 1150 mtx_enter(&pfkeyv2_mtx); 1151 promisc = npromisc; 1152 mtx_leave(&pfkeyv2_mtx); 1153 1154 /* Verify that we received this over a legitimate pfkeyv2 socket */ 1155 bzero(headers, sizeof(headers)); 1156 1157 kp = sotokeycb(so); 1158 if (!kp) { 1159 rval = EINVAL; 1160 goto ret; 1161 } 1162 1163 rdomain = kp->kcb_rdomain; 1164 1165 /* If we have any promiscuous listeners, send them a copy of the message */ 1166 if (promisc) { 1167 struct mbuf *packet; 1168 1169 freeme_sz = sizeof(struct sadb_msg) + len; 1170 if (!(freeme = malloc(freeme_sz, M_PFKEY, M_NOWAIT))) { 1171 rval = ENOMEM; 1172 goto ret; 1173 } 1174 1175 /* Initialize encapsulating header */ 1176 bzero(freeme, sizeof(struct sadb_msg)); 1177 smsg = (struct sadb_msg *) freeme; 1178 smsg->sadb_msg_version = PF_KEY_V2; 1179 smsg->sadb_msg_type = SADB_X_PROMISC; 1180 smsg->sadb_msg_len = (sizeof(struct sadb_msg) + len) / 1181 sizeof(uint64_t); 1182 smsg->sadb_msg_seq = curproc->p_p->ps_pid; 1183 1184 bcopy(message, freeme + sizeof(struct sadb_msg), len); 1185 1186 /* Convert to mbuf chain */ 1187 if ((rval = pfdatatopacket(freeme, freeme_sz, &packet)) != 0) 1188 goto ret; 1189 1190 /* Send to all promiscuous listeners */ 1191 SRPL_FOREACH(bkp, &sr, &pkptable.pkp_list, kcb_list) { 1192 if (bkp->kcb_rdomain != kp->kcb_rdomain) 1193 continue; 1194 1195 s = keylock(bkp); 1196 if (bkp->kcb_flags & PFKEYV2_SOCKETFLAGS_PROMISC) 1197 pfkey_sendup(bkp, packet, 1); 1198 keyunlock(bkp, s); 1199 } 1200 SRPL_LEAVE(&sr); 1201 1202 m_freem(packet); 1203 1204 /* Paranoid */ 1205 explicit_bzero(freeme, freeme_sz); 1206 free(freeme, M_PFKEY, freeme_sz); 1207 freeme = NULL; 1208 freeme_sz = 0; 1209 } 1210 1211 /* Validate message format */ 1212 if ((rval = pfkeyv2_parsemessage(message, len, headers)) != 0) 1213 goto ret; 1214 1215 /* use specified rdomain */ 1216 srdomain = (struct sadb_x_rdomain *) headers[SADB_X_EXT_RDOMAIN]; 1217 if (srdomain) { 1218 if (!rtable_exists(srdomain->sadb_x_rdomain_dom1) || 1219 !rtable_exists(srdomain->sadb_x_rdomain_dom2)) { 1220 rval = EINVAL; 1221 goto ret; 1222 } 1223 rdomain = srdomain->sadb_x_rdomain_dom1; 1224 } 1225 1226 smsg = (struct sadb_msg *) headers[0]; 1227 switch (smsg->sadb_msg_type) { 1228 case SADB_GETSPI: /* Reserve an SPI */ 1229 sa1 = malloc(sizeof (*sa1), M_PFKEY, M_NOWAIT | M_ZERO); 1230 if (sa1 == NULL) { 1231 rval = ENOMEM; 1232 goto ret; 1233 } 1234 1235 sa1->tdb_satype = smsg->sadb_msg_satype; 1236 if ((rval = pfkeyv2_get_proto_alg(sa1->tdb_satype, 1237 &sa1->tdb_sproto, 0))) 1238 goto ret; 1239 1240 import_address(&sa1->tdb_src.sa, headers[SADB_EXT_ADDRESS_SRC]); 1241 import_address(&sa1->tdb_dst.sa, headers[SADB_EXT_ADDRESS_DST]); 1242 1243 /* Find an unused SA identifier */ 1244 sprng = (struct sadb_spirange *) headers[SADB_EXT_SPIRANGE]; 1245 NET_LOCK(); 1246 sa1->tdb_spi = reserve_spi(rdomain, 1247 sprng->sadb_spirange_min, sprng->sadb_spirange_max, 1248 &sa1->tdb_src, &sa1->tdb_dst, sa1->tdb_sproto, &rval); 1249 if (sa1->tdb_spi == 0) { 1250 NET_UNLOCK(); 1251 goto ret; 1252 } 1253 1254 /* Send a message back telling what the SA (the SPI really) is */ 1255 freeme_sz = sizeof(struct sadb_sa); 1256 if (!(freeme = malloc(freeme_sz, M_PFKEY, M_NOWAIT | M_ZERO))) { 1257 rval = ENOMEM; 1258 NET_UNLOCK(); 1259 goto ret; 1260 } 1261 1262 headers[SADB_EXT_SPIRANGE] = NULL; 1263 headers[SADB_EXT_SA] = freeme; 1264 bckptr = freeme; 1265 1266 /* We really only care about the SPI, but we'll export the SA */ 1267 export_sa((void **) &bckptr, sa1); 1268 NET_UNLOCK(); 1269 break; 1270 1271 case SADB_UPDATE: 1272 ssa = (struct sadb_sa *) headers[SADB_EXT_SA]; 1273 sunionp = (union sockaddr_union *) (headers[SADB_EXT_ADDRESS_DST] + 1274 sizeof(struct sadb_address)); 1275 1276 /* Either all or none of the flow must be included */ 1277 if ((headers[SADB_X_EXT_SRC_FLOW] || 1278 headers[SADB_X_EXT_PROTOCOL] || 1279 headers[SADB_X_EXT_FLOW_TYPE] || 1280 headers[SADB_X_EXT_DST_FLOW] || 1281 headers[SADB_X_EXT_SRC_MASK] || 1282 headers[SADB_X_EXT_DST_MASK]) && 1283 !(headers[SADB_X_EXT_SRC_FLOW] && 1284 headers[SADB_X_EXT_PROTOCOL] && 1285 headers[SADB_X_EXT_FLOW_TYPE] && 1286 headers[SADB_X_EXT_DST_FLOW] && 1287 headers[SADB_X_EXT_SRC_MASK] && 1288 headers[SADB_X_EXT_DST_MASK])) { 1289 rval = EINVAL; 1290 goto ret; 1291 } 1292 #ifdef IPSEC 1293 /* UDP encap has to be enabled and is only supported for ESP */ 1294 if (headers[SADB_X_EXT_UDPENCAP] && 1295 (!udpencap_enable || 1296 smsg->sadb_msg_satype != SADB_SATYPE_ESP)) { 1297 rval = EINVAL; 1298 goto ret; 1299 } 1300 #endif /* IPSEC */ 1301 1302 /* Find TDB */ 1303 NET_LOCK(); 1304 sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp, 1305 SADB_X_GETSPROTO(smsg->sadb_msg_satype)); 1306 1307 /* If there's no such SA, we're done */ 1308 if (sa2 == NULL) { 1309 rval = ESRCH; 1310 NET_UNLOCK(); 1311 goto ret; 1312 } 1313 1314 /* If this is a reserved SA */ 1315 if (sa2->tdb_flags & TDBF_INVALID) { 1316 struct tdb *newsa; 1317 struct ipsecinit ii; 1318 int alg; 1319 1320 /* Create new TDB */ 1321 newsa = tdb_alloc(rdomain); 1322 newsa->tdb_satype = smsg->sadb_msg_satype; 1323 1324 if ((rval = pfkeyv2_get_proto_alg(newsa->tdb_satype, 1325 &newsa->tdb_sproto, &alg))) { 1326 tdb_unref(newsa); 1327 NET_UNLOCK(); 1328 goto ret; 1329 } 1330 1331 /* Initialize SA */ 1332 bzero(&ii, sizeof(struct ipsecinit)); 1333 import_sa(newsa, headers[SADB_EXT_SA], &ii); 1334 import_address(&newsa->tdb_src.sa, 1335 headers[SADB_EXT_ADDRESS_SRC]); 1336 import_address(&newsa->tdb_dst.sa, 1337 headers[SADB_EXT_ADDRESS_DST]); 1338 import_lifetime(newsa, 1339 headers[SADB_EXT_LIFETIME_CURRENT], 1340 PFKEYV2_LIFETIME_CURRENT); 1341 import_lifetime(newsa, headers[SADB_EXT_LIFETIME_SOFT], 1342 PFKEYV2_LIFETIME_SOFT); 1343 import_lifetime(newsa, headers[SADB_EXT_LIFETIME_HARD], 1344 PFKEYV2_LIFETIME_HARD); 1345 import_key(&ii, headers[SADB_EXT_KEY_AUTH], 1346 PFKEYV2_AUTHENTICATION_KEY); 1347 import_key(&ii, headers[SADB_EXT_KEY_ENCRYPT], 1348 PFKEYV2_ENCRYPTION_KEY); 1349 newsa->tdb_ids_swapped = 1; /* only on TDB_UPDATE */ 1350 import_identities(&newsa->tdb_ids, 1351 newsa->tdb_ids_swapped, 1352 headers[SADB_EXT_IDENTITY_SRC], 1353 headers[SADB_EXT_IDENTITY_DST]); 1354 if ((rval = import_flow(&newsa->tdb_filter, 1355 &newsa->tdb_filtermask, 1356 headers[SADB_X_EXT_SRC_FLOW], 1357 headers[SADB_X_EXT_SRC_MASK], 1358 headers[SADB_X_EXT_DST_FLOW], 1359 headers[SADB_X_EXT_DST_MASK], 1360 headers[SADB_X_EXT_PROTOCOL], 1361 headers[SADB_X_EXT_FLOW_TYPE]))) { 1362 tdb_unref(newsa); 1363 NET_UNLOCK(); 1364 goto ret; 1365 } 1366 import_udpencap(newsa, headers[SADB_X_EXT_UDPENCAP]); 1367 import_rdomain(newsa, headers[SADB_X_EXT_RDOMAIN]); 1368 #if NPF > 0 1369 import_tag(newsa, headers[SADB_X_EXT_TAG]); 1370 import_tap(newsa, headers[SADB_X_EXT_TAP]); 1371 #endif 1372 1373 /* Exclude sensitive data from reply message. */ 1374 headers[SADB_EXT_KEY_AUTH] = NULL; 1375 headers[SADB_EXT_KEY_ENCRYPT] = NULL; 1376 headers[SADB_X_EXT_LOCAL_AUTH] = NULL; 1377 headers[SADB_X_EXT_REMOTE_AUTH] = NULL; 1378 1379 newsa->tdb_seq = smsg->sadb_msg_seq; 1380 1381 rval = tdb_init(newsa, alg, &ii); 1382 if (rval) { 1383 rval = EINVAL; 1384 tdb_unref(newsa); 1385 NET_UNLOCK(); 1386 goto ret; 1387 } 1388 1389 newsa->tdb_cur_allocations = sa2->tdb_cur_allocations; 1390 1391 /* Delete old version of the SA, insert new one */ 1392 tdb_delete(sa2); 1393 puttdb(newsa); 1394 } else { 1395 /* 1396 * The SA is already initialized, so we're only allowed to 1397 * change lifetimes and some other information; we're 1398 * not allowed to change keys, addresses or identities. 1399 */ 1400 if (headers[SADB_EXT_KEY_AUTH] || 1401 headers[SADB_EXT_KEY_ENCRYPT] || 1402 headers[SADB_EXT_IDENTITY_SRC] || 1403 headers[SADB_EXT_IDENTITY_DST] || 1404 headers[SADB_EXT_SENSITIVITY]) { 1405 rval = EINVAL; 1406 NET_UNLOCK(); 1407 goto ret; 1408 } 1409 1410 import_sa(sa2, headers[SADB_EXT_SA], NULL); 1411 import_lifetime(sa2, 1412 headers[SADB_EXT_LIFETIME_CURRENT], 1413 PFKEYV2_LIFETIME_CURRENT); 1414 import_lifetime(sa2, headers[SADB_EXT_LIFETIME_SOFT], 1415 PFKEYV2_LIFETIME_SOFT); 1416 import_lifetime(sa2, headers[SADB_EXT_LIFETIME_HARD], 1417 PFKEYV2_LIFETIME_HARD); 1418 import_udpencap(sa2, headers[SADB_X_EXT_UDPENCAP]); 1419 #if NPF > 0 1420 import_tag(sa2, headers[SADB_X_EXT_TAG]); 1421 import_tap(sa2, headers[SADB_X_EXT_TAP]); 1422 #endif 1423 if (headers[SADB_EXT_ADDRESS_SRC] || 1424 headers[SADB_EXT_ADDRESS_PROXY]) { 1425 mtx_enter(&tdb_sadb_mtx); 1426 tdb_unlink_locked(sa2); 1427 import_address((struct sockaddr *)&sa2->tdb_src, 1428 headers[SADB_EXT_ADDRESS_SRC]); 1429 import_address((struct sockaddr *)&sa2->tdb_dst, 1430 headers[SADB_EXT_ADDRESS_PROXY]); 1431 puttdb_locked(sa2); 1432 mtx_leave(&tdb_sadb_mtx); 1433 } 1434 } 1435 NET_UNLOCK(); 1436 1437 break; 1438 case SADB_ADD: 1439 ssa = (struct sadb_sa *) headers[SADB_EXT_SA]; 1440 sunionp = (union sockaddr_union *) (headers[SADB_EXT_ADDRESS_DST] + 1441 sizeof(struct sadb_address)); 1442 1443 /* Either all or none of the flow must be included */ 1444 if ((headers[SADB_X_EXT_SRC_FLOW] || 1445 headers[SADB_X_EXT_PROTOCOL] || 1446 headers[SADB_X_EXT_FLOW_TYPE] || 1447 headers[SADB_X_EXT_DST_FLOW] || 1448 headers[SADB_X_EXT_SRC_MASK] || 1449 headers[SADB_X_EXT_DST_MASK]) && 1450 !(headers[SADB_X_EXT_SRC_FLOW] && 1451 headers[SADB_X_EXT_PROTOCOL] && 1452 headers[SADB_X_EXT_FLOW_TYPE] && 1453 headers[SADB_X_EXT_DST_FLOW] && 1454 headers[SADB_X_EXT_SRC_MASK] && 1455 headers[SADB_X_EXT_DST_MASK])) { 1456 rval = EINVAL; 1457 goto ret; 1458 } 1459 #ifdef IPSEC 1460 /* UDP encap has to be enabled and is only supported for ESP */ 1461 if (headers[SADB_X_EXT_UDPENCAP] && 1462 (!udpencap_enable || 1463 smsg->sadb_msg_satype != SADB_SATYPE_ESP)) { 1464 rval = EINVAL; 1465 goto ret; 1466 } 1467 #endif /* IPSEC */ 1468 1469 NET_LOCK(); 1470 sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp, 1471 SADB_X_GETSPROTO(smsg->sadb_msg_satype)); 1472 1473 /* We can't add an existing SA! */ 1474 if (sa2 != NULL) { 1475 rval = EEXIST; 1476 NET_UNLOCK(); 1477 goto ret; 1478 } 1479 1480 /* We can only add "mature" SAs */ 1481 if (ssa->sadb_sa_state != SADB_SASTATE_MATURE) { 1482 rval = EINVAL; 1483 NET_UNLOCK(); 1484 goto ret; 1485 } 1486 1487 { 1488 struct tdb *newsa; 1489 struct ipsecinit ii; 1490 int alg; 1491 1492 /* Create new TDB */ 1493 newsa = tdb_alloc(rdomain); 1494 newsa->tdb_satype = smsg->sadb_msg_satype; 1495 1496 if ((rval = pfkeyv2_get_proto_alg(newsa->tdb_satype, 1497 &newsa->tdb_sproto, &alg))) { 1498 tdb_unref(newsa); 1499 NET_UNLOCK(); 1500 goto ret; 1501 } 1502 1503 /* Initialize SA */ 1504 bzero(&ii, sizeof(struct ipsecinit)); 1505 import_sa(newsa, headers[SADB_EXT_SA], &ii); 1506 import_address(&newsa->tdb_src.sa, 1507 headers[SADB_EXT_ADDRESS_SRC]); 1508 import_address(&newsa->tdb_dst.sa, 1509 headers[SADB_EXT_ADDRESS_DST]); 1510 1511 import_lifetime(newsa, 1512 headers[SADB_EXT_LIFETIME_CURRENT], 1513 PFKEYV2_LIFETIME_CURRENT); 1514 import_lifetime(newsa, headers[SADB_EXT_LIFETIME_SOFT], 1515 PFKEYV2_LIFETIME_SOFT); 1516 import_lifetime(newsa, headers[SADB_EXT_LIFETIME_HARD], 1517 PFKEYV2_LIFETIME_HARD); 1518 1519 import_key(&ii, headers[SADB_EXT_KEY_AUTH], 1520 PFKEYV2_AUTHENTICATION_KEY); 1521 import_key(&ii, headers[SADB_EXT_KEY_ENCRYPT], 1522 PFKEYV2_ENCRYPTION_KEY); 1523 1524 import_identities(&newsa->tdb_ids, 1525 newsa->tdb_ids_swapped, 1526 headers[SADB_EXT_IDENTITY_SRC], 1527 headers[SADB_EXT_IDENTITY_DST]); 1528 1529 if ((rval = import_flow(&newsa->tdb_filter, 1530 &newsa->tdb_filtermask, 1531 headers[SADB_X_EXT_SRC_FLOW], 1532 headers[SADB_X_EXT_SRC_MASK], 1533 headers[SADB_X_EXT_DST_FLOW], 1534 headers[SADB_X_EXT_DST_MASK], 1535 headers[SADB_X_EXT_PROTOCOL], 1536 headers[SADB_X_EXT_FLOW_TYPE]))) { 1537 tdb_unref(newsa); 1538 NET_UNLOCK(); 1539 goto ret; 1540 } 1541 import_udpencap(newsa, headers[SADB_X_EXT_UDPENCAP]); 1542 import_rdomain(newsa, headers[SADB_X_EXT_RDOMAIN]); 1543 #if NPF > 0 1544 import_tag(newsa, headers[SADB_X_EXT_TAG]); 1545 import_tap(newsa, headers[SADB_X_EXT_TAP]); 1546 #endif 1547 1548 /* Exclude sensitive data from reply message. */ 1549 headers[SADB_EXT_KEY_AUTH] = NULL; 1550 headers[SADB_EXT_KEY_ENCRYPT] = NULL; 1551 headers[SADB_X_EXT_LOCAL_AUTH] = NULL; 1552 headers[SADB_X_EXT_REMOTE_AUTH] = NULL; 1553 1554 newsa->tdb_seq = smsg->sadb_msg_seq; 1555 1556 rval = tdb_init(newsa, alg, &ii); 1557 if (rval) { 1558 rval = EINVAL; 1559 tdb_unref(newsa); 1560 NET_UNLOCK(); 1561 goto ret; 1562 } 1563 1564 /* Add TDB in table */ 1565 puttdb(newsa); 1566 } 1567 NET_UNLOCK(); 1568 1569 break; 1570 1571 case SADB_DELETE: 1572 ssa = (struct sadb_sa *) headers[SADB_EXT_SA]; 1573 sunionp = 1574 (union sockaddr_union *)(headers[SADB_EXT_ADDRESS_DST] + 1575 sizeof(struct sadb_address)); 1576 1577 NET_LOCK(); 1578 sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp, 1579 SADB_X_GETSPROTO(smsg->sadb_msg_satype)); 1580 if (sa2 == NULL) { 1581 rval = ESRCH; 1582 NET_UNLOCK(); 1583 goto ret; 1584 } 1585 1586 tdb_delete(sa2); 1587 NET_UNLOCK(); 1588 1589 break; 1590 1591 case SADB_X_ASKPOLICY: 1592 /* Get the relevant policy */ 1593 NET_LOCK(); 1594 ipa = ipsec_get_acquire(((struct sadb_x_policy *) headers[SADB_X_EXT_POLICY])->sadb_x_policy_seq); 1595 if (ipa == NULL) { 1596 rval = ESRCH; 1597 NET_UNLOCK(); 1598 goto ret; 1599 } 1600 1601 rval = pfkeyv2_policy(ipa, headers, &freeme, &freeme_sz); 1602 NET_UNLOCK(); 1603 if (rval) 1604 mode = PFKEYV2_SENDMESSAGE_UNICAST; 1605 1606 break; 1607 1608 case SADB_GET: 1609 ssa = (struct sadb_sa *) headers[SADB_EXT_SA]; 1610 sunionp = 1611 (union sockaddr_union *)(headers[SADB_EXT_ADDRESS_DST] + 1612 sizeof(struct sadb_address)); 1613 1614 NET_LOCK(); 1615 sa2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp, 1616 SADB_X_GETSPROTO(smsg->sadb_msg_satype)); 1617 if (sa2 == NULL) { 1618 rval = ESRCH; 1619 NET_UNLOCK(); 1620 goto ret; 1621 } 1622 1623 rval = pfkeyv2_get(sa2, headers, &freeme, &freeme_sz, NULL); 1624 NET_UNLOCK(); 1625 if (rval) 1626 mode = PFKEYV2_SENDMESSAGE_UNICAST; 1627 1628 break; 1629 1630 case SADB_REGISTER: 1631 s = keylock(kp); 1632 if (!(kp->kcb_flags & PFKEYV2_SOCKETFLAGS_REGISTERED)) { 1633 kp->kcb_flags |= PFKEYV2_SOCKETFLAGS_REGISTERED; 1634 mtx_enter(&pfkeyv2_mtx); 1635 nregistered++; 1636 mtx_leave(&pfkeyv2_mtx); 1637 } 1638 keyunlock(kp, s); 1639 1640 freeme_sz = sizeof(struct sadb_supported) + sizeof(ealgs); 1641 if (!(freeme = malloc(freeme_sz, M_PFKEY, M_NOWAIT | M_ZERO))) { 1642 rval = ENOMEM; 1643 goto ret; 1644 } 1645 1646 ssup = (struct sadb_supported *) freeme; 1647 ssup->sadb_supported_len = freeme_sz / sizeof(uint64_t); 1648 1649 { 1650 void *p = freeme + sizeof(struct sadb_supported); 1651 1652 bcopy(&ealgs[0], p, sizeof(ealgs)); 1653 } 1654 1655 headers[SADB_EXT_SUPPORTED_ENCRYPT] = freeme; 1656 1657 freeme2_sz = sizeof(struct sadb_supported) + sizeof(aalgs); 1658 if (!(freeme2 = malloc(freeme2_sz, M_PFKEY, 1659 M_NOWAIT | M_ZERO))) { 1660 rval = ENOMEM; 1661 goto ret; 1662 } 1663 1664 /* Keep track what this socket has registered for */ 1665 s = keylock(kp); 1666 kp->kcb_reg |= 1667 (1 << ((struct sadb_msg *)message)->sadb_msg_satype); 1668 keyunlock(kp, s); 1669 1670 ssup = (struct sadb_supported *) freeme2; 1671 ssup->sadb_supported_len = freeme2_sz / sizeof(uint64_t); 1672 1673 { 1674 void *p = freeme2 + sizeof(struct sadb_supported); 1675 1676 bcopy(&aalgs[0], p, sizeof(aalgs)); 1677 } 1678 1679 headers[SADB_EXT_SUPPORTED_AUTH] = freeme2; 1680 1681 freeme3_sz = sizeof(struct sadb_supported) + sizeof(calgs); 1682 if (!(freeme3 = malloc(freeme3_sz, M_PFKEY, 1683 M_NOWAIT | M_ZERO))) { 1684 rval = ENOMEM; 1685 goto ret; 1686 } 1687 1688 ssup = (struct sadb_supported *) freeme3; 1689 ssup->sadb_supported_len = freeme3_sz / sizeof(uint64_t); 1690 1691 { 1692 void *p = freeme3 + sizeof(struct sadb_supported); 1693 1694 bcopy(&calgs[0], p, sizeof(calgs)); 1695 } 1696 1697 headers[SADB_X_EXT_SUPPORTED_COMP] = freeme3; 1698 1699 break; 1700 1701 case SADB_ACQUIRE: 1702 case SADB_EXPIRE: 1703 /* Nothing to handle */ 1704 rval = 0; 1705 break; 1706 1707 case SADB_FLUSH: 1708 rval = 0; 1709 1710 NET_LOCK(); 1711 switch (smsg->sadb_msg_satype) { 1712 case SADB_SATYPE_UNSPEC: 1713 spd_table_walk(rdomain, pfkeyv2_policy_flush, NULL); 1714 /* FALLTHROUGH */ 1715 case SADB_SATYPE_AH: 1716 case SADB_SATYPE_ESP: 1717 case SADB_X_SATYPE_IPIP: 1718 case SADB_X_SATYPE_IPCOMP: 1719 #ifdef TCP_SIGNATURE 1720 case SADB_X_SATYPE_TCPSIGNATURE: 1721 #endif /* TCP_SIGNATURE */ 1722 tdb_walk(rdomain, pfkeyv2_sa_flush, 1723 (u_int8_t *) &(smsg->sadb_msg_satype)); 1724 1725 break; 1726 1727 default: 1728 rval = EINVAL; /* Unknown/unsupported type */ 1729 } 1730 NET_UNLOCK(); 1731 1732 break; 1733 1734 case SADB_DUMP: 1735 { 1736 struct dump_state dump_state; 1737 dump_state.sadb_msg = (struct sadb_msg *) headers[0]; 1738 dump_state.socket = so; 1739 1740 NET_LOCK(); 1741 rval = tdb_walk(rdomain, pfkeyv2_dump_walker, &dump_state); 1742 NET_UNLOCK(); 1743 if (!rval) 1744 goto realret; 1745 if ((rval == ENOMEM) || (rval == ENOBUFS)) 1746 rval = 0; 1747 } 1748 break; 1749 1750 case SADB_X_GRPSPIS: 1751 { 1752 struct tdb *tdb1, *tdb2, *tdb3; 1753 struct sadb_protocol *sa_proto; 1754 1755 ssa = (struct sadb_sa *) headers[SADB_EXT_SA]; 1756 sunionp = (union sockaddr_union *) (headers[SADB_EXT_ADDRESS_DST] + 1757 sizeof(struct sadb_address)); 1758 1759 NET_LOCK(); 1760 tdb1 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp, 1761 SADB_X_GETSPROTO(smsg->sadb_msg_satype)); 1762 if (tdb1 == NULL) { 1763 rval = ESRCH; 1764 NET_UNLOCK(); 1765 goto ret; 1766 } 1767 1768 ssa = (struct sadb_sa *) headers[SADB_X_EXT_SA2]; 1769 sunionp = (union sockaddr_union *) (headers[SADB_X_EXT_DST2] + 1770 sizeof(struct sadb_address)); 1771 sa_proto = (struct sadb_protocol *) headers[SADB_X_EXT_SATYPE2]; 1772 1773 /* optionally fetch tdb2 from rdomain2 */ 1774 tdb2 = gettdb(srdomain ? srdomain->sadb_x_rdomain_dom2 : rdomain, 1775 ssa->sadb_sa_spi, sunionp, 1776 SADB_X_GETSPROTO(sa_proto->sadb_protocol_proto)); 1777 if (tdb2 == NULL) { 1778 tdb_unref(tdb1); 1779 rval = ESRCH; 1780 NET_UNLOCK(); 1781 goto ret; 1782 } 1783 1784 /* Detect cycles */ 1785 for (tdb3 = tdb2; tdb3; tdb3 = tdb3->tdb_onext) 1786 if (tdb3 == tdb1) { 1787 tdb_unref(tdb1); 1788 tdb_unref(tdb2); 1789 rval = ESRCH; 1790 NET_UNLOCK(); 1791 goto ret; 1792 } 1793 1794 /* Maintenance */ 1795 if ((tdb1->tdb_onext) && 1796 (tdb1->tdb_onext->tdb_inext == tdb1)) { 1797 tdb_unref(tdb1->tdb_onext->tdb_inext); 1798 tdb1->tdb_onext->tdb_inext = NULL; 1799 } 1800 1801 if ((tdb2->tdb_inext) && 1802 (tdb2->tdb_inext->tdb_onext == tdb2)) { 1803 tdb_unref(tdb2->tdb_inext->tdb_onext); 1804 tdb2->tdb_inext->tdb_onext = NULL; 1805 } 1806 1807 /* Link them */ 1808 tdb1->tdb_onext = tdb2; 1809 tdb2->tdb_inext = tdb1; 1810 NET_UNLOCK(); 1811 } 1812 break; 1813 1814 case SADB_X_DELFLOW: 1815 delflag = 1; 1816 /*FALLTHROUGH*/ 1817 case SADB_X_ADDFLOW: 1818 { 1819 struct sadb_protocol *sab; 1820 union sockaddr_union *ssrc; 1821 int exists = 0; 1822 1823 NET_LOCK(); 1824 if ((rnh = spd_table_add(rdomain)) == NULL) { 1825 rval = ENOMEM; 1826 NET_UNLOCK(); 1827 goto ret; 1828 } 1829 1830 sab = (struct sadb_protocol *) headers[SADB_X_EXT_FLOW_TYPE]; 1831 1832 if ((sab->sadb_protocol_direction != IPSP_DIRECTION_IN) && 1833 (sab->sadb_protocol_direction != IPSP_DIRECTION_OUT)) { 1834 rval = EINVAL; 1835 NET_UNLOCK(); 1836 goto ret; 1837 } 1838 1839 /* If the security protocol wasn't specified, pretend it was ESP */ 1840 if (smsg->sadb_msg_satype == 0) 1841 smsg->sadb_msg_satype = SADB_SATYPE_ESP; 1842 1843 if (headers[SADB_EXT_ADDRESS_DST]) 1844 sunionp = (union sockaddr_union *) 1845 (headers[SADB_EXT_ADDRESS_DST] + 1846 sizeof(struct sadb_address)); 1847 else 1848 sunionp = NULL; 1849 1850 if (headers[SADB_EXT_ADDRESS_SRC]) 1851 ssrc = (union sockaddr_union *) 1852 (headers[SADB_EXT_ADDRESS_SRC] + 1853 sizeof(struct sadb_address)); 1854 else 1855 ssrc = NULL; 1856 1857 if ((rval = import_flow(&encapdst, &encapnetmask, 1858 headers[SADB_X_EXT_SRC_FLOW], headers[SADB_X_EXT_SRC_MASK], 1859 headers[SADB_X_EXT_DST_FLOW], headers[SADB_X_EXT_DST_MASK], 1860 headers[SADB_X_EXT_PROTOCOL], 1861 headers[SADB_X_EXT_FLOW_TYPE]))) { 1862 NET_UNLOCK(); 1863 goto ret; 1864 } 1865 1866 /* Determine whether the exact same SPD entry already exists. */ 1867 if ((rn = rn_match(&encapdst, rnh)) != NULL) { 1868 ipo = (struct ipsec_policy *)rn; 1869 1870 /* Verify that the entry is identical */ 1871 if (bcmp(&ipo->ipo_addr, &encapdst, 1872 sizeof(struct sockaddr_encap)) || 1873 bcmp(&ipo->ipo_mask, &encapnetmask, 1874 sizeof(struct sockaddr_encap))) 1875 ipo = NULL; /* Fall through */ 1876 else 1877 exists = 1; 1878 } else 1879 ipo = NULL; 1880 1881 /* 1882 * If the existing policy is static, only delete or update 1883 * it if the new one is also static. 1884 */ 1885 if (exists && (ipo->ipo_flags & IPSP_POLICY_STATIC)) { 1886 if (!(sab->sadb_protocol_flags & 1887 SADB_X_POLICYFLAGS_POLICY)) { 1888 NET_UNLOCK(); 1889 goto ret; 1890 } 1891 } 1892 1893 /* Delete ? */ 1894 if (delflag) { 1895 if (exists) { 1896 rval = ipsec_delete_policy(ipo); 1897 NET_UNLOCK(); 1898 goto ret; 1899 } 1900 1901 /* If we were asked to delete something non-existent, error. */ 1902 rval = ESRCH; 1903 NET_UNLOCK(); 1904 break; 1905 } 1906 1907 if (!exists) { 1908 /* Allocate policy entry */ 1909 ipo = pool_get(&ipsec_policy_pool, PR_NOWAIT|PR_ZERO); 1910 if (ipo == NULL) { 1911 rval = ENOMEM; 1912 NET_UNLOCK(); 1913 goto ret; 1914 } 1915 } 1916 1917 switch (sab->sadb_protocol_proto) { 1918 case SADB_X_FLOW_TYPE_USE: 1919 ipo->ipo_type = IPSP_IPSEC_USE; 1920 break; 1921 1922 case SADB_X_FLOW_TYPE_ACQUIRE: 1923 ipo->ipo_type = IPSP_IPSEC_ACQUIRE; 1924 break; 1925 1926 case SADB_X_FLOW_TYPE_REQUIRE: 1927 ipo->ipo_type = IPSP_IPSEC_REQUIRE; 1928 break; 1929 1930 case SADB_X_FLOW_TYPE_DENY: 1931 ipo->ipo_type = IPSP_DENY; 1932 break; 1933 1934 case SADB_X_FLOW_TYPE_BYPASS: 1935 ipo->ipo_type = IPSP_PERMIT; 1936 break; 1937 1938 case SADB_X_FLOW_TYPE_DONTACQ: 1939 ipo->ipo_type = IPSP_IPSEC_DONTACQ; 1940 break; 1941 1942 default: 1943 if (!exists) 1944 pool_put(&ipsec_policy_pool, ipo); 1945 else 1946 ipsec_delete_policy(ipo); 1947 1948 rval = EINVAL; 1949 NET_UNLOCK(); 1950 goto ret; 1951 } 1952 1953 if (sab->sadb_protocol_flags & SADB_X_POLICYFLAGS_POLICY) 1954 ipo->ipo_flags |= IPSP_POLICY_STATIC; 1955 1956 if (sunionp) 1957 bcopy(sunionp, &ipo->ipo_dst, 1958 sizeof(union sockaddr_union)); 1959 else 1960 bzero(&ipo->ipo_dst, sizeof(union sockaddr_union)); 1961 1962 if (ssrc) 1963 bcopy(ssrc, &ipo->ipo_src, 1964 sizeof(union sockaddr_union)); 1965 else 1966 bzero(&ipo->ipo_src, sizeof(union sockaddr_union)); 1967 1968 ipo->ipo_sproto = SADB_X_GETSPROTO(smsg->sadb_msg_satype); 1969 1970 if (ipo->ipo_ids) { 1971 ipsp_ids_free(ipo->ipo_ids); 1972 ipo->ipo_ids = NULL; 1973 } 1974 1975 if ((sid = headers[SADB_EXT_IDENTITY_SRC]) != NULL && 1976 (did = headers[SADB_EXT_IDENTITY_DST]) != NULL) { 1977 import_identities(&ipo->ipo_ids, 0, sid, did); 1978 if (ipo->ipo_ids == NULL) { 1979 if (exists) 1980 ipsec_delete_policy(ipo); 1981 else 1982 pool_put(&ipsec_policy_pool, ipo); 1983 rval = ENOBUFS; 1984 NET_UNLOCK(); 1985 goto ret; 1986 } 1987 } 1988 1989 /* Flow type */ 1990 if (!exists) { 1991 /* Initialize policy entry */ 1992 bcopy(&encapdst, &ipo->ipo_addr, 1993 sizeof(struct sockaddr_encap)); 1994 bcopy(&encapnetmask, &ipo->ipo_mask, 1995 sizeof(struct sockaddr_encap)); 1996 1997 TAILQ_INIT(&ipo->ipo_acquires); 1998 ipo->ipo_rdomain = rdomain; 1999 ipo->ipo_ref_count = 1; 2000 2001 /* Add SPD entry */ 2002 if ((rnh = spd_table_get(rdomain)) == NULL || 2003 (rn = rn_addroute((caddr_t)&ipo->ipo_addr, 2004 (caddr_t)&ipo->ipo_mask, rnh, 2005 ipo->ipo_nodes, 0)) == NULL) { 2006 /* Remove from linked list of policies on TDB */ 2007 mtx_enter(&ipo_tdb_mtx); 2008 if (ipo->ipo_tdb != NULL) { 2009 TAILQ_REMOVE( 2010 &ipo->ipo_tdb->tdb_policy_head, 2011 ipo, ipo_tdb_next); 2012 tdb_unref(ipo->ipo_tdb); 2013 ipo->ipo_tdb = NULL; 2014 } 2015 mtx_leave(&ipo_tdb_mtx); 2016 if (ipo->ipo_ids) 2017 ipsp_ids_free(ipo->ipo_ids); 2018 pool_put(&ipsec_policy_pool, ipo); 2019 NET_UNLOCK(); 2020 goto ret; 2021 } 2022 TAILQ_INSERT_HEAD(&ipsec_policy_head, ipo, ipo_list); 2023 ipsec_in_use++; 2024 } else { 2025 ipo->ipo_last_searched = ipo->ipo_flags = 0; 2026 } 2027 NET_UNLOCK(); 2028 } 2029 break; 2030 2031 case SADB_X_PROMISC: 2032 if (len >= 2 * sizeof(struct sadb_msg)) { 2033 struct mbuf *packet; 2034 2035 if ((rval = pfdatatopacket(message, len, &packet)) != 0) 2036 goto ret; 2037 2038 SRPL_FOREACH(bkp, &sr, &pkptable.pkp_list, kcb_list) { 2039 if (bkp == kp || bkp->kcb_rdomain != kp->kcb_rdomain) 2040 continue; 2041 2042 if (!smsg->sadb_msg_seq || 2043 (smsg->sadb_msg_seq == kp->kcb_pid)) { 2044 s = keylock(bkp); 2045 pfkey_sendup(bkp, packet, 1); 2046 keyunlock(bkp, s); 2047 } 2048 } 2049 SRPL_LEAVE(&sr); 2050 2051 m_freem(packet); 2052 } else { 2053 if (len != sizeof(struct sadb_msg)) { 2054 rval = EINVAL; 2055 goto ret; 2056 } 2057 2058 s = keylock(kp); 2059 i = (kp->kcb_flags & 2060 PFKEYV2_SOCKETFLAGS_PROMISC) ? 1 : 0; 2061 j = smsg->sadb_msg_satype ? 1 : 0; 2062 2063 if (i ^ j) { 2064 if (j) { 2065 kp->kcb_flags |= 2066 PFKEYV2_SOCKETFLAGS_PROMISC; 2067 mtx_enter(&pfkeyv2_mtx); 2068 npromisc++; 2069 mtx_leave(&pfkeyv2_mtx); 2070 } else { 2071 kp->kcb_flags &= 2072 ~PFKEYV2_SOCKETFLAGS_PROMISC; 2073 mtx_enter(&pfkeyv2_mtx); 2074 npromisc--; 2075 mtx_leave(&pfkeyv2_mtx); 2076 } 2077 } 2078 keyunlock(kp, s); 2079 } 2080 2081 break; 2082 2083 default: 2084 rval = EINVAL; 2085 goto ret; 2086 } 2087 2088 ret: 2089 if (rval) { 2090 if ((rval == EINVAL) || (rval == ENOMEM) || (rval == ENOBUFS)) 2091 goto realret; 2092 2093 for (i = 1; i <= SADB_EXT_MAX; i++) 2094 headers[i] = NULL; 2095 2096 smsg->sadb_msg_errno = abs(rval); 2097 } else { 2098 uint64_t seen = 0LL; 2099 2100 for (i = 1; i <= SADB_EXT_MAX; i++) 2101 if (headers[i]) 2102 seen |= (1LL << i); 2103 2104 if ((seen & sadb_exts_allowed_out[smsg->sadb_msg_type]) 2105 != seen) { 2106 rval = EPERM; 2107 goto realret; 2108 } 2109 2110 if ((seen & sadb_exts_required_out[smsg->sadb_msg_type]) != 2111 sadb_exts_required_out[smsg->sadb_msg_type]) { 2112 rval = EPERM; 2113 goto realret; 2114 } 2115 } 2116 2117 rval = pfkeyv2_sendmessage(headers, mode, so, 0, 0, kp->kcb_rdomain); 2118 2119 realret: 2120 2121 if (freeme != NULL) 2122 explicit_bzero(freeme, freeme_sz); 2123 free(freeme, M_PFKEY, freeme_sz); 2124 free(freeme2, M_PFKEY, freeme2_sz); 2125 free(freeme3, M_PFKEY, freeme3_sz); 2126 2127 explicit_bzero(message, len); 2128 free(message, M_PFKEY, len); 2129 2130 free(sa1, M_PFKEY, sizeof(*sa1)); 2131 2132 NET_LOCK(); 2133 tdb_unref(sa2); 2134 NET_UNLOCK(); 2135 2136 return (rval); 2137 } 2138 2139 /* 2140 * Send an ACQUIRE message to key management, to get a new SA. 2141 */ 2142 int 2143 pfkeyv2_acquire(struct ipsec_policy *ipo, union sockaddr_union *gw, 2144 union sockaddr_union *laddr, u_int32_t *seq, struct sockaddr_encap *ddst) 2145 { 2146 void *p, *headers[SADB_EXT_MAX + 1], *buffer = NULL; 2147 struct sadb_comb *sadb_comb; 2148 struct sadb_address *sadd; 2149 struct sadb_prop *sa_prop; 2150 struct sadb_msg *smsg; 2151 int rval = 0; 2152 int i, j, registered; 2153 2154 mtx_enter(&pfkeyv2_mtx); 2155 *seq = pfkeyv2_seq++; 2156 2157 registered = nregistered; 2158 mtx_leave(&pfkeyv2_mtx); 2159 2160 if (!registered) { 2161 rval = ESRCH; 2162 goto ret; 2163 } 2164 2165 /* How large a buffer do we need... XXX we only do one proposal for now */ 2166 i = sizeof(struct sadb_msg) + 2167 (laddr == NULL ? 0 : sizeof(struct sadb_address) + 2168 PADUP(ipo->ipo_src.sa.sa_len)) + 2169 sizeof(struct sadb_address) + PADUP(gw->sa.sa_len) + 2170 sizeof(struct sadb_prop) + 1 * sizeof(struct sadb_comb); 2171 2172 if (ipo->ipo_ids) { 2173 i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_ids->id_local->len); 2174 i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_ids->id_remote->len); 2175 } 2176 2177 /* Allocate */ 2178 if (!(p = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) { 2179 rval = ENOMEM; 2180 goto ret; 2181 } 2182 2183 bzero(headers, sizeof(headers)); 2184 2185 buffer = p; 2186 2187 headers[0] = p; 2188 p += sizeof(struct sadb_msg); 2189 2190 smsg = (struct sadb_msg *) headers[0]; 2191 smsg->sadb_msg_version = PF_KEY_V2; 2192 smsg->sadb_msg_type = SADB_ACQUIRE; 2193 smsg->sadb_msg_len = i / sizeof(uint64_t); 2194 smsg->sadb_msg_seq = *seq; 2195 2196 if (ipo->ipo_sproto == IPPROTO_ESP) 2197 smsg->sadb_msg_satype = SADB_SATYPE_ESP; 2198 else if (ipo->ipo_sproto == IPPROTO_AH) 2199 smsg->sadb_msg_satype = SADB_SATYPE_AH; 2200 else if (ipo->ipo_sproto == IPPROTO_IPCOMP) 2201 smsg->sadb_msg_satype = SADB_X_SATYPE_IPCOMP; 2202 2203 if (laddr) { 2204 headers[SADB_EXT_ADDRESS_SRC] = p; 2205 p += sizeof(struct sadb_address) + PADUP(laddr->sa.sa_len); 2206 sadd = (struct sadb_address *) headers[SADB_EXT_ADDRESS_SRC]; 2207 sadd->sadb_address_len = (sizeof(struct sadb_address) + 2208 laddr->sa.sa_len + sizeof(uint64_t) - 1) / 2209 sizeof(uint64_t); 2210 bcopy(laddr, headers[SADB_EXT_ADDRESS_SRC] + 2211 sizeof(struct sadb_address), laddr->sa.sa_len); 2212 } 2213 2214 headers[SADB_EXT_ADDRESS_DST] = p; 2215 p += sizeof(struct sadb_address) + PADUP(gw->sa.sa_len); 2216 sadd = (struct sadb_address *) headers[SADB_EXT_ADDRESS_DST]; 2217 sadd->sadb_address_len = (sizeof(struct sadb_address) + 2218 gw->sa.sa_len + sizeof(uint64_t) - 1) / sizeof(uint64_t); 2219 bcopy(gw, headers[SADB_EXT_ADDRESS_DST] + sizeof(struct sadb_address), 2220 gw->sa.sa_len); 2221 2222 if (ipo->ipo_ids) 2223 export_identities(&p, ipo->ipo_ids, 0, headers); 2224 2225 headers[SADB_EXT_PROPOSAL] = p; 2226 p += sizeof(struct sadb_prop); 2227 sa_prop = (struct sadb_prop *) headers[SADB_EXT_PROPOSAL]; 2228 sa_prop->sadb_prop_num = 1; /* XXX One proposal only */ 2229 sa_prop->sadb_prop_len = (sizeof(struct sadb_prop) + 2230 (sizeof(struct sadb_comb) * sa_prop->sadb_prop_num)) / 2231 sizeof(uint64_t); 2232 2233 sadb_comb = p; 2234 2235 /* XXX Should actually ask the crypto layer what's supported */ 2236 for (j = 0; j < sa_prop->sadb_prop_num; j++) { 2237 sadb_comb->sadb_comb_flags = 0; 2238 #ifdef IPSEC 2239 if (ipsec_require_pfs) 2240 sadb_comb->sadb_comb_flags |= SADB_SAFLAGS_PFS; 2241 2242 /* Set the encryption algorithm */ 2243 if (ipo->ipo_sproto == IPPROTO_ESP) { 2244 if (!strncasecmp(ipsec_def_enc, "aes", 2245 sizeof("aes"))) { 2246 sadb_comb->sadb_comb_encrypt = SADB_X_EALG_AES; 2247 sadb_comb->sadb_comb_encrypt_minbits = 128; 2248 sadb_comb->sadb_comb_encrypt_maxbits = 256; 2249 } else if (!strncasecmp(ipsec_def_enc, "aesctr", 2250 sizeof("aesctr"))) { 2251 sadb_comb->sadb_comb_encrypt = SADB_X_EALG_AESCTR; 2252 sadb_comb->sadb_comb_encrypt_minbits = 128+32; 2253 sadb_comb->sadb_comb_encrypt_maxbits = 256+32; 2254 } else if (!strncasecmp(ipsec_def_enc, "3des", 2255 sizeof("3des"))) { 2256 sadb_comb->sadb_comb_encrypt = SADB_EALG_3DESCBC; 2257 sadb_comb->sadb_comb_encrypt_minbits = 192; 2258 sadb_comb->sadb_comb_encrypt_maxbits = 192; 2259 } else if (!strncasecmp(ipsec_def_enc, "blowfish", 2260 sizeof("blowfish"))) { 2261 sadb_comb->sadb_comb_encrypt = SADB_X_EALG_BLF; 2262 sadb_comb->sadb_comb_encrypt_minbits = 40; 2263 sadb_comb->sadb_comb_encrypt_maxbits = BLF_MAXKEYLEN * 8; 2264 } else if (!strncasecmp(ipsec_def_enc, "cast128", 2265 sizeof("cast128"))) { 2266 sadb_comb->sadb_comb_encrypt = SADB_X_EALG_CAST; 2267 sadb_comb->sadb_comb_encrypt_minbits = 40; 2268 sadb_comb->sadb_comb_encrypt_maxbits = 128; 2269 } 2270 } else if (ipo->ipo_sproto == IPPROTO_IPCOMP) { 2271 /* Set the compression algorithm */ 2272 if (!strncasecmp(ipsec_def_comp, "deflate", 2273 sizeof("deflate"))) { 2274 sadb_comb->sadb_comb_encrypt = SADB_X_CALG_DEFLATE; 2275 sadb_comb->sadb_comb_encrypt_minbits = 0; 2276 sadb_comb->sadb_comb_encrypt_maxbits = 0; 2277 } 2278 } 2279 2280 /* Set the authentication algorithm */ 2281 if (!strncasecmp(ipsec_def_auth, "hmac-sha1", 2282 sizeof("hmac-sha1"))) { 2283 sadb_comb->sadb_comb_auth = SADB_AALG_SHA1HMAC; 2284 sadb_comb->sadb_comb_auth_minbits = 160; 2285 sadb_comb->sadb_comb_auth_maxbits = 160; 2286 } else if (!strncasecmp(ipsec_def_auth, "hmac-ripemd160", 2287 sizeof("hmac_ripemd160"))) { 2288 sadb_comb->sadb_comb_auth = SADB_X_AALG_RIPEMD160HMAC; 2289 sadb_comb->sadb_comb_auth_minbits = 160; 2290 sadb_comb->sadb_comb_auth_maxbits = 160; 2291 } else if (!strncasecmp(ipsec_def_auth, "hmac-md5", 2292 sizeof("hmac-md5"))) { 2293 sadb_comb->sadb_comb_auth = SADB_AALG_MD5HMAC; 2294 sadb_comb->sadb_comb_auth_minbits = 128; 2295 sadb_comb->sadb_comb_auth_maxbits = 128; 2296 } else if (!strncasecmp(ipsec_def_auth, "hmac-sha2-256", 2297 sizeof("hmac-sha2-256"))) { 2298 sadb_comb->sadb_comb_auth = SADB_X_AALG_SHA2_256; 2299 sadb_comb->sadb_comb_auth_minbits = 256; 2300 sadb_comb->sadb_comb_auth_maxbits = 256; 2301 } else if (!strncasecmp(ipsec_def_auth, "hmac-sha2-384", 2302 sizeof("hmac-sha2-384"))) { 2303 sadb_comb->sadb_comb_auth = SADB_X_AALG_SHA2_384; 2304 sadb_comb->sadb_comb_auth_minbits = 384; 2305 sadb_comb->sadb_comb_auth_maxbits = 384; 2306 } else if (!strncasecmp(ipsec_def_auth, "hmac-sha2-512", 2307 sizeof("hmac-sha2-512"))) { 2308 sadb_comb->sadb_comb_auth = SADB_X_AALG_SHA2_512; 2309 sadb_comb->sadb_comb_auth_minbits = 512; 2310 sadb_comb->sadb_comb_auth_maxbits = 512; 2311 } 2312 2313 sadb_comb->sadb_comb_soft_allocations = ipsec_soft_allocations; 2314 sadb_comb->sadb_comb_hard_allocations = ipsec_exp_allocations; 2315 2316 sadb_comb->sadb_comb_soft_bytes = ipsec_soft_bytes; 2317 sadb_comb->sadb_comb_hard_bytes = ipsec_exp_bytes; 2318 2319 sadb_comb->sadb_comb_soft_addtime = ipsec_soft_timeout; 2320 sadb_comb->sadb_comb_hard_addtime = ipsec_exp_timeout; 2321 2322 sadb_comb->sadb_comb_soft_usetime = ipsec_soft_first_use; 2323 sadb_comb->sadb_comb_hard_usetime = ipsec_exp_first_use; 2324 #endif 2325 sadb_comb++; 2326 } 2327 2328 /* Send the ACQUIRE message to all compliant registered listeners. */ 2329 if ((rval = pfkeyv2_sendmessage(headers, 2330 PFKEYV2_SENDMESSAGE_REGISTERED, NULL, smsg->sadb_msg_satype, 0, 2331 ipo->ipo_rdomain)) != 0) 2332 goto ret; 2333 2334 rval = 0; 2335 ret: 2336 if (buffer != NULL) { 2337 explicit_bzero(buffer, i); 2338 free(buffer, M_PFKEY, i); 2339 } 2340 2341 return (rval); 2342 } 2343 2344 /* 2345 * Notify key management that an expiration went off. The second argument 2346 * specifies the type of expiration (soft or hard). 2347 */ 2348 int 2349 pfkeyv2_expire(struct tdb *tdb, u_int16_t type) 2350 { 2351 void *p, *headers[SADB_EXT_MAX+1], *buffer = NULL; 2352 struct sadb_msg *smsg; 2353 int rval = 0; 2354 int i; 2355 2356 NET_ASSERT_LOCKED(); 2357 2358 switch (tdb->tdb_sproto) { 2359 case IPPROTO_AH: 2360 case IPPROTO_ESP: 2361 case IPPROTO_IPIP: 2362 case IPPROTO_IPCOMP: 2363 #ifdef TCP_SIGNATURE 2364 case IPPROTO_TCP: 2365 #endif /* TCP_SIGNATURE */ 2366 break; 2367 2368 default: 2369 rval = EOPNOTSUPP; 2370 goto ret; 2371 } 2372 2373 i = sizeof(struct sadb_msg) + sizeof(struct sadb_sa) + 2374 2 * sizeof(struct sadb_lifetime) + 2375 sizeof(struct sadb_address) + PADUP(tdb->tdb_src.sa.sa_len) + 2376 sizeof(struct sadb_address) + PADUP(tdb->tdb_dst.sa.sa_len); 2377 2378 if (!(p = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) { 2379 rval = ENOMEM; 2380 goto ret; 2381 } 2382 2383 bzero(headers, sizeof(headers)); 2384 2385 buffer = p; 2386 2387 headers[0] = p; 2388 p += sizeof(struct sadb_msg); 2389 2390 smsg = (struct sadb_msg *) headers[0]; 2391 smsg->sadb_msg_version = PF_KEY_V2; 2392 smsg->sadb_msg_type = SADB_EXPIRE; 2393 smsg->sadb_msg_satype = tdb->tdb_satype; 2394 smsg->sadb_msg_len = i / sizeof(uint64_t); 2395 2396 mtx_enter(&pfkeyv2_mtx); 2397 smsg->sadb_msg_seq = pfkeyv2_seq++; 2398 mtx_leave(&pfkeyv2_mtx); 2399 2400 headers[SADB_EXT_SA] = p; 2401 export_sa(&p, tdb); 2402 2403 headers[SADB_EXT_LIFETIME_CURRENT] = p; 2404 export_lifetime(&p, tdb, PFKEYV2_LIFETIME_CURRENT); 2405 2406 headers[type] = p; 2407 export_lifetime(&p, tdb, type == SADB_EXT_LIFETIME_SOFT ? 2408 PFKEYV2_LIFETIME_SOFT : PFKEYV2_LIFETIME_HARD); 2409 2410 headers[SADB_EXT_ADDRESS_SRC] = p; 2411 export_address(&p, &tdb->tdb_src.sa); 2412 2413 headers[SADB_EXT_ADDRESS_DST] = p; 2414 export_address(&p, &tdb->tdb_dst.sa); 2415 2416 if ((rval = pfkeyv2_sendmessage(headers, PFKEYV2_SENDMESSAGE_BROADCAST, 2417 NULL, 0, 0, tdb->tdb_rdomain)) != 0) 2418 goto ret; 2419 /* XXX */ 2420 if (tdb->tdb_rdomain != tdb->tdb_rdomain_post) 2421 if ((rval = pfkeyv2_sendmessage(headers, 2422 PFKEYV2_SENDMESSAGE_BROADCAST, NULL, 0, 0, 2423 tdb->tdb_rdomain_post)) != 0) 2424 goto ret; 2425 2426 rval = 0; 2427 2428 ret: 2429 if (buffer != NULL) { 2430 explicit_bzero(buffer, i); 2431 free(buffer, M_PFKEY, i); 2432 } 2433 2434 return (rval); 2435 } 2436 2437 struct pfkeyv2_sysctl_walk { 2438 void *w_where; 2439 size_t w_len; 2440 int w_op; 2441 u_int8_t w_satype; 2442 }; 2443 2444 int 2445 pfkeyv2_sysctl_walker(struct tdb *tdb, void *arg, int last) 2446 { 2447 struct pfkeyv2_sysctl_walk *w = (struct pfkeyv2_sysctl_walk *)arg; 2448 void *buffer = NULL; 2449 int error = 0; 2450 int usedlen, buflen, i; 2451 2452 if (w->w_satype != SADB_SATYPE_UNSPEC && 2453 w->w_satype != tdb->tdb_satype) 2454 return (0); 2455 2456 if (w->w_where) { 2457 void *headers[SADB_EXT_MAX+1]; 2458 struct sadb_msg msg; 2459 2460 bzero(headers, sizeof(headers)); 2461 if ((error = pfkeyv2_get(tdb, headers, &buffer, &buflen, 2462 &usedlen)) != 0) 2463 goto done; 2464 if (w->w_len < sizeof(msg) + usedlen) { 2465 error = ENOMEM; 2466 goto done; 2467 } 2468 /* prepend header */ 2469 bzero(&msg, sizeof(msg)); 2470 msg.sadb_msg_version = PF_KEY_V2; 2471 msg.sadb_msg_satype = tdb->tdb_satype; 2472 msg.sadb_msg_type = SADB_DUMP; 2473 msg.sadb_msg_len = (sizeof(msg) + usedlen) / sizeof(uint64_t); 2474 if ((error = copyout(&msg, w->w_where, sizeof(msg))) != 0) 2475 goto done; 2476 w->w_where += sizeof(msg); 2477 w->w_len -= sizeof(msg); 2478 /* set extension type */ 2479 for (i = 1; i <= SADB_EXT_MAX; i++) 2480 if (headers[i]) 2481 ((struct sadb_ext *) 2482 headers[i])->sadb_ext_type = i; 2483 if ((error = copyout(buffer, w->w_where, usedlen)) != 0) 2484 goto done; 2485 w->w_where += usedlen; 2486 w->w_len -= usedlen; 2487 } else { 2488 if ((error = pfkeyv2_get(tdb, NULL, NULL, &buflen, NULL)) != 0) 2489 return (error); 2490 w->w_len += buflen; 2491 w->w_len += sizeof(struct sadb_msg); 2492 } 2493 2494 done: 2495 if (buffer != NULL) { 2496 explicit_bzero(buffer, buflen); 2497 free(buffer, M_PFKEY, buflen); 2498 } 2499 return (error); 2500 } 2501 2502 int 2503 pfkeyv2_dump_policy(struct ipsec_policy *ipo, void **headers, void **buffer, 2504 int *lenp) 2505 { 2506 int i, rval, perm; 2507 void *p; 2508 2509 /* Find how much space we need. */ 2510 i = 2 * sizeof(struct sadb_protocol); 2511 2512 /* We'll need four of them: src, src mask, dst, dst mask. */ 2513 switch (ipo->ipo_addr.sen_type) { 2514 case SENT_IP4: 2515 i += 4 * PADUP(sizeof(struct sockaddr_in)); 2516 i += 4 * sizeof(struct sadb_address); 2517 break; 2518 #ifdef INET6 2519 case SENT_IP6: 2520 i += 4 * PADUP(sizeof(struct sockaddr_in6)); 2521 i += 4 * sizeof(struct sadb_address); 2522 break; 2523 #endif /* INET6 */ 2524 default: 2525 return (EINVAL); 2526 } 2527 2528 /* Local address, might be zeroed. */ 2529 switch (ipo->ipo_src.sa.sa_family) { 2530 case 0: 2531 break; 2532 case AF_INET: 2533 i += PADUP(sizeof(struct sockaddr_in)); 2534 i += sizeof(struct sadb_address); 2535 break; 2536 #ifdef INET6 2537 case AF_INET6: 2538 i += PADUP(sizeof(struct sockaddr_in6)); 2539 i += sizeof(struct sadb_address); 2540 break; 2541 #endif /* INET6 */ 2542 default: 2543 return (EINVAL); 2544 } 2545 2546 /* Remote address, might be zeroed. XXX ??? */ 2547 switch (ipo->ipo_dst.sa.sa_family) { 2548 case 0: 2549 break; 2550 case AF_INET: 2551 i += PADUP(sizeof(struct sockaddr_in)); 2552 i += sizeof(struct sadb_address); 2553 break; 2554 #ifdef INET6 2555 case AF_INET6: 2556 i += PADUP(sizeof(struct sockaddr_in6)); 2557 i += sizeof(struct sadb_address); 2558 break; 2559 #endif /* INET6 */ 2560 default: 2561 return (EINVAL); 2562 } 2563 2564 if (ipo->ipo_ids) { 2565 i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_ids->id_local->len); 2566 i += sizeof(struct sadb_ident) + PADUP(ipo->ipo_ids->id_remote->len); 2567 } 2568 2569 if (lenp) 2570 *lenp = i; 2571 2572 if (buffer == NULL) { 2573 rval = 0; 2574 goto ret; 2575 } 2576 2577 if (!(p = malloc(i, M_PFKEY, M_NOWAIT | M_ZERO))) { 2578 rval = ENOMEM; 2579 goto ret; 2580 } else 2581 *buffer = p; 2582 2583 /* Local address. */ 2584 if (ipo->ipo_src.sa.sa_family) { 2585 headers[SADB_EXT_ADDRESS_SRC] = p; 2586 export_address(&p, &ipo->ipo_src.sa); 2587 } 2588 2589 /* Remote address. */ 2590 if (ipo->ipo_dst.sa.sa_family) { 2591 headers[SADB_EXT_ADDRESS_DST] = p; 2592 export_address(&p, &ipo->ipo_dst.sa); 2593 } 2594 2595 /* Get actual flow. */ 2596 export_flow(&p, ipo->ipo_type, &ipo->ipo_addr, &ipo->ipo_mask, 2597 headers); 2598 2599 /* Add ids only when we are root. */ 2600 perm = suser(curproc); 2601 if (perm == 0 && ipo->ipo_ids) 2602 export_identities(&p, ipo->ipo_ids, 0, headers); 2603 2604 rval = 0; 2605 ret: 2606 return (rval); 2607 } 2608 2609 int 2610 pfkeyv2_sysctl_policydumper(struct ipsec_policy *ipo, void *arg, 2611 unsigned int tableid) 2612 { 2613 struct pfkeyv2_sysctl_walk *w = (struct pfkeyv2_sysctl_walk *)arg; 2614 void *buffer = 0; 2615 int i, buflen, error = 0; 2616 2617 if (w->w_where) { 2618 void *headers[SADB_EXT_MAX + 1]; 2619 struct sadb_msg msg; 2620 2621 bzero(headers, sizeof(headers)); 2622 if ((error = pfkeyv2_dump_policy(ipo, headers, &buffer, 2623 &buflen)) != 0) 2624 goto done; 2625 if (w->w_len < buflen) { 2626 error = ENOMEM; 2627 goto done; 2628 } 2629 /* prepend header */ 2630 bzero(&msg, sizeof(msg)); 2631 msg.sadb_msg_version = PF_KEY_V2; 2632 if (ipo->ipo_sproto == IPPROTO_ESP) 2633 msg.sadb_msg_satype = SADB_SATYPE_ESP; 2634 else if (ipo->ipo_sproto == IPPROTO_AH) 2635 msg.sadb_msg_satype = SADB_SATYPE_AH; 2636 else if (ipo->ipo_sproto == IPPROTO_IPCOMP) 2637 msg.sadb_msg_satype = SADB_X_SATYPE_IPCOMP; 2638 else if (ipo->ipo_sproto == IPPROTO_IPIP) 2639 msg.sadb_msg_satype = SADB_X_SATYPE_IPIP; 2640 msg.sadb_msg_type = SADB_X_SPDDUMP; 2641 msg.sadb_msg_len = (sizeof(msg) + buflen) / sizeof(uint64_t); 2642 if ((error = copyout(&msg, w->w_where, sizeof(msg))) != 0) 2643 goto done; 2644 w->w_where += sizeof(msg); 2645 w->w_len -= sizeof(msg); 2646 /* set extension type */ 2647 for (i = 1; i <= SADB_EXT_MAX; i++) 2648 if (headers[i]) 2649 ((struct sadb_ext *) 2650 headers[i])->sadb_ext_type = i; 2651 if ((error = copyout(buffer, w->w_where, buflen)) != 0) 2652 goto done; 2653 w->w_where += buflen; 2654 w->w_len -= buflen; 2655 } else { 2656 if ((error = pfkeyv2_dump_policy(ipo, NULL, NULL, 2657 &buflen)) != 0) 2658 goto done; 2659 w->w_len += buflen; 2660 w->w_len += sizeof(struct sadb_msg); 2661 } 2662 2663 done: 2664 if (buffer) 2665 free(buffer, M_PFKEY, buflen); 2666 return (error); 2667 } 2668 2669 int 2670 pfkeyv2_policy_flush(struct ipsec_policy *ipo, void *arg, unsigned int tableid) 2671 { 2672 int error; 2673 2674 error = ipsec_delete_policy(ipo); 2675 if (error == 0) 2676 error = EAGAIN; 2677 2678 return (error); 2679 } 2680 2681 int 2682 pfkeyv2_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2683 void *new, size_t newlen) 2684 { 2685 struct pfkeyv2_sysctl_walk w; 2686 int error = EINVAL; 2687 u_int rdomain; 2688 u_int tableid; 2689 2690 if (new) 2691 return (EPERM); 2692 if (namelen < 1) 2693 return (EINVAL); 2694 w.w_op = name[0]; 2695 w.w_satype = name[1]; 2696 w.w_where = oldp; 2697 w.w_len = oldp ? *oldlenp : 0; 2698 2699 if (namelen == 3) { 2700 tableid = name[2]; 2701 if (!rtable_exists(tableid)) 2702 return (ENOENT); 2703 } else 2704 tableid = curproc->p_p->ps_rtableid; 2705 rdomain = rtable_l2(tableid); 2706 2707 switch(w.w_op) { 2708 case NET_KEY_SADB_DUMP: 2709 if ((error = suser(curproc)) != 0) 2710 return (error); 2711 NET_LOCK(); 2712 error = tdb_walk(rdomain, pfkeyv2_sysctl_walker, &w); 2713 NET_UNLOCK(); 2714 if (oldp) 2715 *oldlenp = w.w_where - oldp; 2716 else 2717 *oldlenp = w.w_len; 2718 break; 2719 2720 case NET_KEY_SPD_DUMP: 2721 NET_LOCK(); 2722 error = spd_table_walk(rdomain, 2723 pfkeyv2_sysctl_policydumper, &w); 2724 NET_UNLOCK(); 2725 if (oldp) 2726 *oldlenp = w.w_where - oldp; 2727 else 2728 *oldlenp = w.w_len; 2729 break; 2730 } 2731 2732 return (error); 2733 } 2734