1 /* $OpenBSD: pfkey.c,v 1.71 2024/10/02 09:45:29 claudio Exp $ */ 2 3 /* 4 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> 5 * Copyright (c) 2003, 2004 Markus Friedl <markus@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <sys/types.h> 21 #include <sys/socket.h> 22 #include <sys/uio.h> 23 #include <net/pfkeyv2.h> 24 #include <netinet/ip_ipsp.h> 25 #include <netinet/in.h> 26 #include <netinet/tcp.h> 27 #include <ctype.h> 28 #include <errno.h> 29 #include <limits.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <unistd.h> 33 34 #include "bgpd.h" 35 #include "session.h" 36 #include "log.h" 37 38 extern struct bgpd_sysdep sysdep; 39 40 #define PFKEY2_CHUNK sizeof(uint64_t) 41 #define ROUNDUP(x) (((x) + (PFKEY2_CHUNK - 1)) & ~(PFKEY2_CHUNK - 1)) 42 #define IOV_CNT 20 43 44 static uint32_t sadb_msg_seq = 0; 45 static uint32_t pid = 0; /* should pid_t but pfkey needs uint32_t */ 46 static int pfkey_fd; 47 48 static int pfkey_reply(int, uint32_t *); 49 static int pfkey_send(int, uint8_t, uint8_t, uint8_t, 50 const struct bgpd_addr *, const struct bgpd_addr *, 51 uint32_t, uint8_t, int, char *, uint8_t, int, char *, 52 uint16_t, uint16_t); 53 54 #define pfkey_flow(fd, satype, cmd, dir, from, to, sport, dport) \ 55 pfkey_send(fd, satype, cmd, dir, from, to, \ 56 0, 0, 0, NULL, 0, 0, NULL, sport, dport) 57 58 static int 59 pfkey_send(int sd, uint8_t satype, uint8_t mtype, uint8_t dir, 60 const struct bgpd_addr *src, const struct bgpd_addr *dst, uint32_t spi, 61 uint8_t aalg, int alen, char *akey, uint8_t ealg, int elen, char *ekey, 62 uint16_t sport, uint16_t dport) 63 { 64 struct sadb_msg smsg; 65 struct sadb_sa sa; 66 struct sadb_address sa_src, sa_dst, sa_peer, sa_smask, sa_dmask; 67 struct sadb_key sa_akey, sa_ekey; 68 struct sadb_spirange sa_spirange; 69 struct sadb_protocol sa_flowtype, sa_protocol; 70 struct iovec iov[IOV_CNT]; 71 ssize_t n; 72 int len = 0; 73 int iov_cnt; 74 struct sockaddr_storage ssrc, sdst, speer, smask, dmask; 75 struct sockaddr *saptr; 76 socklen_t salen; 77 78 if (!pid) 79 pid = getpid(); 80 81 /* we need clean sockaddr... no ports set */ 82 memset(&ssrc, 0, sizeof(ssrc)); 83 memset(&smask, 0, sizeof(smask)); 84 if ((saptr = addr2sa(src, 0, &salen))) { 85 memcpy(&ssrc, saptr, salen); 86 ssrc.ss_len = salen; 87 } 88 switch (src->aid) { 89 case AID_INET: 90 memset(&((struct sockaddr_in *)&smask)->sin_addr, 0xff, 32/8); 91 break; 92 case AID_INET6: 93 memset(&((struct sockaddr_in6 *)&smask)->sin6_addr, 0xff, 94 128/8); 95 break; 96 case AID_UNSPEC: 97 ssrc.ss_len = sizeof(struct sockaddr); 98 break; 99 default: 100 return (-1); 101 } 102 smask.ss_family = ssrc.ss_family; 103 smask.ss_len = ssrc.ss_len; 104 105 memset(&sdst, 0, sizeof(sdst)); 106 memset(&dmask, 0, sizeof(dmask)); 107 if ((saptr = addr2sa(dst, 0, &salen))) { 108 memcpy(&sdst, saptr, salen); 109 sdst.ss_len = salen; 110 } 111 switch (dst->aid) { 112 case AID_INET: 113 memset(&((struct sockaddr_in *)&dmask)->sin_addr, 0xff, 32/8); 114 break; 115 case AID_INET6: 116 memset(&((struct sockaddr_in6 *)&dmask)->sin6_addr, 0xff, 117 128/8); 118 break; 119 case AID_UNSPEC: 120 sdst.ss_len = sizeof(struct sockaddr); 121 break; 122 default: 123 return (-1); 124 } 125 dmask.ss_family = sdst.ss_family; 126 dmask.ss_len = sdst.ss_len; 127 128 memset(&smsg, 0, sizeof(smsg)); 129 smsg.sadb_msg_version = PF_KEY_V2; 130 smsg.sadb_msg_seq = ++sadb_msg_seq; 131 smsg.sadb_msg_pid = pid; 132 smsg.sadb_msg_len = sizeof(smsg) / 8; 133 smsg.sadb_msg_type = mtype; 134 smsg.sadb_msg_satype = satype; 135 136 switch (mtype) { 137 case SADB_GETSPI: 138 memset(&sa_spirange, 0, sizeof(sa_spirange)); 139 sa_spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE; 140 sa_spirange.sadb_spirange_len = sizeof(sa_spirange) / 8; 141 sa_spirange.sadb_spirange_min = 0x100; 142 sa_spirange.sadb_spirange_max = 0xffffffff; 143 sa_spirange.sadb_spirange_reserved = 0; 144 break; 145 case SADB_ADD: 146 case SADB_UPDATE: 147 case SADB_DELETE: 148 memset(&sa, 0, sizeof(sa)); 149 sa.sadb_sa_exttype = SADB_EXT_SA; 150 sa.sadb_sa_len = sizeof(sa) / 8; 151 sa.sadb_sa_replay = 0; 152 sa.sadb_sa_spi = htonl(spi); 153 sa.sadb_sa_state = SADB_SASTATE_MATURE; 154 break; 155 case SADB_X_ADDFLOW: 156 case SADB_X_DELFLOW: 157 memset(&sa_flowtype, 0, sizeof(sa_flowtype)); 158 sa_flowtype.sadb_protocol_exttype = SADB_X_EXT_FLOW_TYPE; 159 sa_flowtype.sadb_protocol_len = sizeof(sa_flowtype) / 8; 160 sa_flowtype.sadb_protocol_direction = dir; 161 sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_REQUIRE; 162 163 memset(&sa_protocol, 0, sizeof(sa_protocol)); 164 sa_protocol.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL; 165 sa_protocol.sadb_protocol_len = sizeof(sa_protocol) / 8; 166 sa_protocol.sadb_protocol_direction = 0; 167 sa_protocol.sadb_protocol_proto = 6; 168 break; 169 } 170 171 memset(&sa_src, 0, sizeof(sa_src)); 172 sa_src.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 173 sa_src.sadb_address_len = (sizeof(sa_src) + ROUNDUP(ssrc.ss_len)) / 8; 174 175 memset(&sa_dst, 0, sizeof(sa_dst)); 176 sa_dst.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 177 sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)) / 8; 178 179 sa.sadb_sa_auth = aalg; 180 sa.sadb_sa_encrypt = SADB_X_EALG_AES; /* XXX */ 181 182 switch (mtype) { 183 case SADB_ADD: 184 case SADB_UPDATE: 185 memset(&sa_akey, 0, sizeof(sa_akey)); 186 sa_akey.sadb_key_exttype = SADB_EXT_KEY_AUTH; 187 sa_akey.sadb_key_len = (sizeof(sa_akey) + 188 ((alen + 7) / 8) * 8) / 8; 189 sa_akey.sadb_key_bits = 8 * alen; 190 191 memset(&sa_ekey, 0, sizeof(sa_ekey)); 192 sa_ekey.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; 193 sa_ekey.sadb_key_len = (sizeof(sa_ekey) + 194 ((elen + 7) / 8) * 8) / 8; 195 sa_ekey.sadb_key_bits = 8 * elen; 196 197 break; 198 case SADB_X_ADDFLOW: 199 case SADB_X_DELFLOW: 200 /* sa_peer always points to the remote machine */ 201 if (dir == IPSP_DIRECTION_IN) { 202 speer = ssrc; 203 sa_peer = sa_src; 204 } else { 205 speer = sdst; 206 sa_peer = sa_dst; 207 } 208 sa_peer.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 209 sa_peer.sadb_address_len = 210 (sizeof(sa_peer) + ROUNDUP(speer.ss_len)) / 8; 211 212 /* for addflow we also use src/dst as the flow destination */ 213 sa_src.sadb_address_exttype = SADB_X_EXT_SRC_FLOW; 214 sa_dst.sadb_address_exttype = SADB_X_EXT_DST_FLOW; 215 216 memset(&smask, 0, sizeof(smask)); 217 switch (src->aid) { 218 case AID_INET: 219 smask.ss_len = sizeof(struct sockaddr_in); 220 smask.ss_family = AF_INET; 221 memset(&((struct sockaddr_in *)&smask)->sin_addr, 222 0xff, 32/8); 223 if (sport) { 224 ((struct sockaddr_in *)&ssrc)->sin_port = 225 htons(sport); 226 ((struct sockaddr_in *)&smask)->sin_port = 227 htons(0xffff); 228 } 229 break; 230 case AID_INET6: 231 smask.ss_len = sizeof(struct sockaddr_in6); 232 smask.ss_family = AF_INET6; 233 memset(&((struct sockaddr_in6 *)&smask)->sin6_addr, 234 0xff, 128/8); 235 if (sport) { 236 ((struct sockaddr_in6 *)&ssrc)->sin6_port = 237 htons(sport); 238 ((struct sockaddr_in6 *)&smask)->sin6_port = 239 htons(0xffff); 240 } 241 break; 242 } 243 memset(&dmask, 0, sizeof(dmask)); 244 switch (dst->aid) { 245 case AID_INET: 246 dmask.ss_len = sizeof(struct sockaddr_in); 247 dmask.ss_family = AF_INET; 248 memset(&((struct sockaddr_in *)&dmask)->sin_addr, 249 0xff, 32/8); 250 if (dport) { 251 ((struct sockaddr_in *)&sdst)->sin_port = 252 htons(dport); 253 ((struct sockaddr_in *)&dmask)->sin_port = 254 htons(0xffff); 255 } 256 break; 257 case AID_INET6: 258 dmask.ss_len = sizeof(struct sockaddr_in6); 259 dmask.ss_family = AF_INET6; 260 memset(&((struct sockaddr_in6 *)&dmask)->sin6_addr, 261 0xff, 128/8); 262 if (dport) { 263 ((struct sockaddr_in6 *)&sdst)->sin6_port = 264 htons(dport); 265 ((struct sockaddr_in6 *)&dmask)->sin6_port = 266 htons(0xffff); 267 } 268 break; 269 } 270 271 memset(&sa_smask, 0, sizeof(sa_smask)); 272 sa_smask.sadb_address_exttype = SADB_X_EXT_SRC_MASK; 273 sa_smask.sadb_address_len = 274 (sizeof(sa_smask) + ROUNDUP(smask.ss_len)) / 8; 275 276 memset(&sa_dmask, 0, sizeof(sa_dmask)); 277 sa_dmask.sadb_address_exttype = SADB_X_EXT_DST_MASK; 278 sa_dmask.sadb_address_len = 279 (sizeof(sa_dmask) + ROUNDUP(dmask.ss_len)) / 8; 280 break; 281 } 282 283 iov_cnt = 0; 284 285 /* msghdr */ 286 iov[iov_cnt].iov_base = &smsg; 287 iov[iov_cnt].iov_len = sizeof(smsg); 288 iov_cnt++; 289 290 switch (mtype) { 291 case SADB_ADD: 292 case SADB_UPDATE: 293 case SADB_DELETE: 294 /* SA hdr */ 295 iov[iov_cnt].iov_base = &sa; 296 iov[iov_cnt].iov_len = sizeof(sa); 297 smsg.sadb_msg_len += sa.sadb_sa_len; 298 iov_cnt++; 299 break; 300 case SADB_GETSPI: 301 /* SPI range */ 302 iov[iov_cnt].iov_base = &sa_spirange; 303 iov[iov_cnt].iov_len = sizeof(sa_spirange); 304 smsg.sadb_msg_len += sa_spirange.sadb_spirange_len; 305 iov_cnt++; 306 break; 307 case SADB_X_ADDFLOW: 308 /* sa_peer always points to the remote machine */ 309 iov[iov_cnt].iov_base = &sa_peer; 310 iov[iov_cnt].iov_len = sizeof(sa_peer); 311 iov_cnt++; 312 iov[iov_cnt].iov_base = &speer; 313 iov[iov_cnt].iov_len = ROUNDUP(speer.ss_len); 314 smsg.sadb_msg_len += sa_peer.sadb_address_len; 315 iov_cnt++; 316 317 /* FALLTHROUGH */ 318 case SADB_X_DELFLOW: 319 /* add flow type */ 320 iov[iov_cnt].iov_base = &sa_flowtype; 321 iov[iov_cnt].iov_len = sizeof(sa_flowtype); 322 smsg.sadb_msg_len += sa_flowtype.sadb_protocol_len; 323 iov_cnt++; 324 325 /* add protocol */ 326 iov[iov_cnt].iov_base = &sa_protocol; 327 iov[iov_cnt].iov_len = sizeof(sa_protocol); 328 smsg.sadb_msg_len += sa_protocol.sadb_protocol_len; 329 iov_cnt++; 330 331 /* add flow masks */ 332 iov[iov_cnt].iov_base = &sa_smask; 333 iov[iov_cnt].iov_len = sizeof(sa_smask); 334 iov_cnt++; 335 iov[iov_cnt].iov_base = &smask; 336 iov[iov_cnt].iov_len = ROUNDUP(smask.ss_len); 337 smsg.sadb_msg_len += sa_smask.sadb_address_len; 338 iov_cnt++; 339 340 iov[iov_cnt].iov_base = &sa_dmask; 341 iov[iov_cnt].iov_len = sizeof(sa_dmask); 342 iov_cnt++; 343 iov[iov_cnt].iov_base = &dmask; 344 iov[iov_cnt].iov_len = ROUNDUP(dmask.ss_len); 345 smsg.sadb_msg_len += sa_dmask.sadb_address_len; 346 iov_cnt++; 347 break; 348 } 349 350 /* dest addr */ 351 iov[iov_cnt].iov_base = &sa_dst; 352 iov[iov_cnt].iov_len = sizeof(sa_dst); 353 iov_cnt++; 354 iov[iov_cnt].iov_base = &sdst; 355 iov[iov_cnt].iov_len = ROUNDUP(sdst.ss_len); 356 smsg.sadb_msg_len += sa_dst.sadb_address_len; 357 iov_cnt++; 358 359 /* src addr */ 360 iov[iov_cnt].iov_base = &sa_src; 361 iov[iov_cnt].iov_len = sizeof(sa_src); 362 iov_cnt++; 363 iov[iov_cnt].iov_base = &ssrc; 364 iov[iov_cnt].iov_len = ROUNDUP(ssrc.ss_len); 365 smsg.sadb_msg_len += sa_src.sadb_address_len; 366 iov_cnt++; 367 368 switch (mtype) { 369 case SADB_ADD: 370 case SADB_UPDATE: 371 if (alen) { 372 /* auth key */ 373 iov[iov_cnt].iov_base = &sa_akey; 374 iov[iov_cnt].iov_len = sizeof(sa_akey); 375 iov_cnt++; 376 iov[iov_cnt].iov_base = akey; 377 iov[iov_cnt].iov_len = ((alen + 7) / 8) * 8; 378 smsg.sadb_msg_len += sa_akey.sadb_key_len; 379 iov_cnt++; 380 } 381 if (elen) { 382 /* encryption key */ 383 iov[iov_cnt].iov_base = &sa_ekey; 384 iov[iov_cnt].iov_len = sizeof(sa_ekey); 385 iov_cnt++; 386 iov[iov_cnt].iov_base = ekey; 387 iov[iov_cnt].iov_len = ((elen + 7) / 8) * 8; 388 smsg.sadb_msg_len += sa_ekey.sadb_key_len; 389 iov_cnt++; 390 } 391 break; 392 } 393 394 len = smsg.sadb_msg_len * 8; 395 do { 396 n = writev(sd, iov, iov_cnt); 397 } while (n == -1 && (errno == EAGAIN || errno == EINTR)); 398 399 if (n == -1) { 400 log_warn("%s: writev (%d/%d)", __func__, iov_cnt, len); 401 return (-1); 402 } 403 404 return (0); 405 } 406 407 int 408 pfkey_read(int sd, struct sadb_msg *h) 409 { 410 struct sadb_msg hdr; 411 412 if (recv(sd, &hdr, sizeof(hdr), MSG_PEEK) != sizeof(hdr)) { 413 if (errno == EAGAIN || errno == EINTR) 414 return (1); 415 log_warn("pfkey peek"); 416 return (-1); 417 } 418 419 /* XXX: Only one message can be outstanding. */ 420 if (hdr.sadb_msg_seq == sadb_msg_seq && 421 hdr.sadb_msg_pid == pid) { 422 if (h) 423 memcpy(h, &hdr, sizeof(hdr)); 424 return (0); 425 } 426 427 /* not ours, discard */ 428 if (read(sd, &hdr, sizeof(hdr)) == -1) { 429 if (errno == EAGAIN || errno == EINTR) 430 return (1); 431 log_warn("pfkey read"); 432 return (-1); 433 } 434 435 return (1); 436 } 437 438 static int 439 pfkey_reply(int sd, uint32_t *spi) 440 { 441 struct sadb_msg hdr, *msg; 442 struct sadb_ext *ext; 443 struct sadb_sa *sa; 444 uint8_t *data; 445 ssize_t len; 446 int rv; 447 448 do { 449 rv = pfkey_read(sd, &hdr); 450 if (rv == -1) 451 return (-1); 452 } while (rv); 453 454 if (hdr.sadb_msg_errno != 0) { 455 errno = hdr.sadb_msg_errno; 456 if (errno == ESRCH) 457 return (0); 458 else { 459 log_warn("pfkey"); 460 /* discard error message */ 461 if (read(sd, &hdr, sizeof(hdr)) == -1) 462 log_warn("pfkey read"); 463 return (-1); 464 } 465 } 466 if ((data = reallocarray(NULL, hdr.sadb_msg_len, PFKEY2_CHUNK)) 467 == NULL) { 468 log_warn("pfkey malloc"); 469 return (-1); 470 } 471 len = hdr.sadb_msg_len * PFKEY2_CHUNK; 472 if (read(sd, data, len) != len) { 473 log_warn("pfkey read"); 474 freezero(data, len); 475 return (-1); 476 } 477 478 if (hdr.sadb_msg_type == SADB_GETSPI) { 479 if (spi == NULL) { 480 freezero(data, len); 481 return (0); 482 } 483 484 msg = (struct sadb_msg *)data; 485 for (ext = (struct sadb_ext *)(msg + 1); 486 (size_t)((uint8_t *)ext - (uint8_t *)msg) < 487 msg->sadb_msg_len * PFKEY2_CHUNK; 488 ext = (struct sadb_ext *)((uint8_t *)ext + 489 ext->sadb_ext_len * PFKEY2_CHUNK)) { 490 if (ext->sadb_ext_type == SADB_EXT_SA) { 491 sa = (struct sadb_sa *) ext; 492 *spi = ntohl(sa->sadb_sa_spi); 493 break; 494 } 495 } 496 } 497 freezero(data, len); 498 return (0); 499 } 500 501 static int 502 pfkey_sa_add(const struct bgpd_addr *src, const struct bgpd_addr *dst, 503 uint8_t keylen, char *key, uint32_t *spi) 504 { 505 if (pfkey_send(pfkey_fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_GETSPI, 0, 506 src, dst, 0, 0, 0, NULL, 0, 0, NULL, 0, 0) == -1) 507 return (-1); 508 if (pfkey_reply(pfkey_fd, spi) == -1) 509 return (-1); 510 if (pfkey_send(pfkey_fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_UPDATE, 0, 511 src, dst, *spi, 0, keylen, key, 0, 0, NULL, 0, 0) == -1) 512 return (-1); 513 if (pfkey_reply(pfkey_fd, NULL) == -1) 514 return (-1); 515 return (0); 516 } 517 518 static int 519 pfkey_sa_remove(const struct bgpd_addr *src, const struct bgpd_addr *dst, 520 uint32_t *spi) 521 { 522 if (pfkey_send(pfkey_fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_DELETE, 0, 523 src, dst, *spi, 0, 0, NULL, 0, 0, NULL, 0, 0) == -1) 524 return (-1); 525 if (pfkey_reply(pfkey_fd, NULL) == -1) 526 return (-1); 527 *spi = 0; 528 return (0); 529 } 530 531 static int 532 pfkey_md5sig_establish(struct auth_state *as, struct auth_config *auth, 533 const struct bgpd_addr *local_addr, const struct bgpd_addr *remote_addr) 534 { 535 uint32_t spi_out = 0; 536 uint32_t spi_in = 0; 537 538 if (pfkey_sa_add(local_addr, remote_addr, 539 auth->md5key_len, auth->md5key, &spi_out) == -1) 540 goto fail; 541 542 if (pfkey_sa_add(remote_addr, local_addr, 543 auth->md5key_len, auth->md5key, &spi_in) == -1) 544 goto fail; 545 546 /* cleanup old flow if one was present */ 547 if (pfkey_remove(as) == -1) 548 return (-1); 549 550 as->established = 1; 551 as->method = auth->method; 552 as->local_addr = *local_addr; 553 as->remote_addr = *remote_addr; 554 as->spi_out = spi_out; 555 as->spi_in = spi_in; 556 return (0); 557 558 fail: 559 return (-1); 560 } 561 562 static int 563 pfkey_md5sig_remove(struct auth_state *as) 564 { 565 if (as->spi_out) 566 if (pfkey_sa_remove(&as->local_addr, &as->remote_addr, 567 &as->spi_out) == -1) 568 goto fail; 569 if (as->spi_in) 570 if (pfkey_sa_remove(&as->remote_addr, &as->local_addr, 571 &as->spi_in) == -1) 572 goto fail; 573 574 explicit_bzero(as, sizeof(*as)); 575 return (0); 576 577 fail: 578 return (-1); 579 } 580 581 static uint8_t 582 pfkey_auth_alg(enum auth_alg alg) 583 { 584 switch (alg) { 585 case AUTH_AALG_SHA1HMAC: 586 return SADB_AALG_SHA1HMAC; 587 case AUTH_AALG_MD5HMAC: 588 return SADB_AALG_MD5HMAC; 589 default: 590 return SADB_AALG_NONE; 591 } 592 } 593 594 static uint8_t 595 pfkey_enc_alg(enum auth_enc_alg alg) 596 { 597 switch (alg) { 598 case AUTH_EALG_3DESCBC: 599 return SADB_EALG_3DESCBC; 600 case AUTH_EALG_AES: 601 return SADB_X_EALG_AES; 602 default: 603 return SADB_AALG_NONE; 604 } 605 } 606 607 static int 608 pfkey_ipsec_establish(struct auth_state *as, struct auth_config *auth, 609 const struct bgpd_addr *local_addr, const struct bgpd_addr *remote_addr) 610 { 611 uint8_t satype = SADB_SATYPE_ESP; 612 613 /* cleanup first, unlike in the TCP MD5 case */ 614 if (pfkey_remove(as) == -1) 615 return (-1); 616 617 switch (auth->method) { 618 case AUTH_IPSEC_IKE_ESP: 619 satype = SADB_SATYPE_ESP; 620 break; 621 case AUTH_IPSEC_IKE_AH: 622 satype = SADB_SATYPE_AH; 623 break; 624 case AUTH_IPSEC_MANUAL_ESP: 625 case AUTH_IPSEC_MANUAL_AH: 626 satype = auth->method == AUTH_IPSEC_MANUAL_ESP ? 627 SADB_SATYPE_ESP : SADB_SATYPE_AH; 628 if (pfkey_send(pfkey_fd, satype, SADB_ADD, 0, 629 local_addr, remote_addr, 630 auth->spi_out, 631 pfkey_auth_alg(auth->auth_alg_out), 632 auth->auth_keylen_out, 633 auth->auth_key_out, 634 pfkey_enc_alg(auth->enc_alg_out), 635 auth->enc_keylen_out, 636 auth->enc_key_out, 637 0, 0) == -1) 638 goto fail_key; 639 if (pfkey_reply(pfkey_fd, NULL) == -1) 640 goto fail_key; 641 if (pfkey_send(pfkey_fd, satype, SADB_ADD, 0, 642 remote_addr, local_addr, 643 auth->spi_in, 644 pfkey_auth_alg(auth->auth_alg_in), 645 auth->auth_keylen_in, 646 auth->auth_key_in, 647 pfkey_enc_alg(auth->enc_alg_in), 648 auth->enc_keylen_in, 649 auth->enc_key_in, 650 0, 0) == -1) 651 goto fail_key; 652 if (pfkey_reply(pfkey_fd, NULL) == -1) 653 goto fail_key; 654 break; 655 default: 656 return (-1); 657 } 658 659 if (pfkey_flow(pfkey_fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_OUT, 660 local_addr, remote_addr, 0, BGP_PORT) == -1) 661 goto fail_flow; 662 if (pfkey_reply(pfkey_fd, NULL) == -1) 663 goto fail_flow; 664 665 if (pfkey_flow(pfkey_fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_OUT, 666 local_addr, remote_addr, BGP_PORT, 0) == -1) 667 goto fail_flow; 668 if (pfkey_reply(pfkey_fd, NULL) == -1) 669 goto fail_flow; 670 671 if (pfkey_flow(pfkey_fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_IN, 672 remote_addr, local_addr, 0, BGP_PORT) == -1) 673 goto fail_flow; 674 if (pfkey_reply(pfkey_fd, NULL) == -1) 675 goto fail_flow; 676 677 if (pfkey_flow(pfkey_fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_IN, 678 remote_addr, local_addr, BGP_PORT, 0) == -1) 679 goto fail_flow; 680 if (pfkey_reply(pfkey_fd, NULL) == -1) 681 goto fail_flow; 682 683 /* save SPI so that they can be removed later on */ 684 as->established = 1; 685 as->method = auth->method; 686 as->local_addr = *local_addr; 687 as->remote_addr = *remote_addr; 688 as->spi_in = auth->spi_in; 689 as->spi_out = auth->spi_out; 690 return (0); 691 692 fail_key: 693 log_warn("failed to insert ipsec key"); 694 return (-1); 695 fail_flow: 696 log_warn("failed to insert ipsec flow"); 697 return (-1); 698 } 699 700 static int 701 pfkey_ipsec_remove(struct auth_state *as) 702 { 703 uint8_t satype; 704 705 switch (as->method) { 706 case AUTH_IPSEC_IKE_ESP: 707 satype = SADB_SATYPE_ESP; 708 break; 709 case AUTH_IPSEC_IKE_AH: 710 satype = SADB_SATYPE_AH; 711 break; 712 case AUTH_IPSEC_MANUAL_ESP: 713 case AUTH_IPSEC_MANUAL_AH: 714 satype = as->method == AUTH_IPSEC_MANUAL_ESP ? 715 SADB_SATYPE_ESP : SADB_SATYPE_AH; 716 if (pfkey_send(pfkey_fd, satype, SADB_DELETE, 0, 717 &as->local_addr, &as->remote_addr, 718 as->spi_out, 0, 0, NULL, 0, 0, NULL, 0, 0) == -1) 719 goto fail_key; 720 if (pfkey_reply(pfkey_fd, NULL) == -1) 721 goto fail_key; 722 723 if (pfkey_send(pfkey_fd, satype, SADB_DELETE, 0, 724 &as->remote_addr, &as->local_addr, 725 as->spi_in, 0, 0, NULL, 0, 0, NULL, 0, 0) == -1) 726 goto fail_key; 727 if (pfkey_reply(pfkey_fd, NULL) == -1) 728 goto fail_key; 729 break; 730 default: 731 return (-1); 732 } 733 734 if (pfkey_flow(pfkey_fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_OUT, 735 &as->local_addr, &as->remote_addr, 0, BGP_PORT) == -1) 736 goto fail_flow; 737 if (pfkey_reply(pfkey_fd, NULL) == -1) 738 goto fail_flow; 739 740 if (pfkey_flow(pfkey_fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_OUT, 741 &as->local_addr, &as->remote_addr, BGP_PORT, 0) == -1) 742 goto fail_flow; 743 if (pfkey_reply(pfkey_fd, NULL) == -1) 744 goto fail_flow; 745 746 if (pfkey_flow(pfkey_fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_IN, 747 &as->remote_addr, &as->local_addr, 0, BGP_PORT) == -1) 748 goto fail_flow; 749 if (pfkey_reply(pfkey_fd, NULL) == -1) 750 goto fail_flow; 751 752 if (pfkey_flow(pfkey_fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_IN, 753 &as->remote_addr, &as->local_addr, BGP_PORT, 0) == -1) 754 goto fail_flow; 755 if (pfkey_reply(pfkey_fd, NULL) == -1) 756 goto fail_flow; 757 758 explicit_bzero(as, sizeof(*as)); 759 return (0); 760 761 fail_key: 762 log_warn("failed to remove ipsec key"); 763 return (-1); 764 fail_flow: 765 log_warn("failed to remove ipsec flow"); 766 return (-1); 767 } 768 769 int 770 pfkey_establish(struct auth_state *as, struct auth_config *auth, 771 const struct bgpd_addr *local_addr, const struct bgpd_addr *remote_addr) 772 { 773 switch (auth->method) { 774 case AUTH_NONE: 775 return pfkey_remove(as); 776 case AUTH_MD5SIG: 777 return pfkey_md5sig_establish(as, auth, local_addr, 778 remote_addr); 779 default: 780 return pfkey_ipsec_establish(as, auth, local_addr, remote_addr); 781 } 782 } 783 784 int 785 pfkey_remove(struct auth_state *as) 786 { 787 if (as->established == 0) 788 return (0); 789 790 switch (as->method) { 791 case AUTH_NONE: 792 return (0); 793 case AUTH_MD5SIG: 794 return (pfkey_md5sig_remove(as)); 795 default: 796 return (pfkey_ipsec_remove(as)); 797 } 798 } 799 800 int 801 pfkey_init(void) 802 { 803 if ((pfkey_fd = socket(PF_KEY, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, 804 PF_KEY_V2)) == -1) { 805 if (errno == EPROTONOSUPPORT) { 806 log_warnx("PF_KEY not available, disabling ipsec"); 807 return (-1); 808 } else 809 fatal("pfkey setup failed"); 810 } 811 return (pfkey_fd); 812 } 813 814 int 815 pfkey_send_conf(struct imsgbuf *imsgbuf, uint32_t id, struct auth_config *auth) 816 { 817 /* SE only needs the auth method */ 818 return imsg_compose(imsgbuf, IMSG_RECONF_PEER_AUTH, id, 0, -1, 819 &auth->method, sizeof(auth->method)); 820 } 821 822 int 823 pfkey_recv_conf(struct peer *p, struct imsg *imsg) 824 { 825 struct auth_config *auth = &p->auth_conf; 826 827 return imsg_get_data(imsg, &auth->method, sizeof(auth->method)); 828 } 829 830 /* verify that connection is using TCP MD5SIG if required by config */ 831 int 832 tcp_md5_check(int fd, struct auth_config *auth) 833 { 834 socklen_t len; 835 int opt; 836 837 if (auth->method == AUTH_MD5SIG) { 838 if (sysdep.no_md5sig) { 839 errno = ENOPROTOOPT; 840 return -1; 841 } 842 len = sizeof(opt); 843 if (getsockopt(fd, IPPROTO_TCP, TCP_MD5SIG, 844 &opt, &len) == -1) 845 return -1; 846 if (!opt) { /* non-md5'd connection! */ 847 errno = ECONNREFUSED; 848 return -1; 849 } 850 } 851 return 0; 852 } 853 854 /* enable or set TCP MD5SIG on a new client connection */ 855 int 856 tcp_md5_set(int fd, struct auth_config *auth, struct bgpd_addr *remote_addr) 857 { 858 int opt = 1; 859 860 if (auth->method == AUTH_MD5SIG) { 861 if (sysdep.no_md5sig) { 862 errno = ENOPROTOOPT; 863 return -1; 864 } 865 if (setsockopt(fd, IPPROTO_TCP, TCP_MD5SIG, 866 &opt, sizeof(opt)) == -1) 867 return -1; 868 } 869 return 0; 870 } 871 872 /* enable or prepare a new listening socket for TCP MD5SIG usage */ 873 int 874 tcp_md5_prep_listener(struct listen_addr *la, struct peer_head *p) 875 { 876 int opt = 1; 877 878 if (setsockopt(la->fd, IPPROTO_TCP, TCP_MD5SIG, 879 &opt, sizeof(opt)) == -1) { 880 if (errno == ENOPROTOOPT) { /* system w/o md5sig */ 881 log_warnx("md5sig not available, disabling"); 882 sysdep.no_md5sig = 1; 883 return 0; 884 } 885 return -1; 886 } 887 return 0; 888 } 889 890 /* add md5 key to all listening sockets, dummy function for portable */ 891 void 892 tcp_md5_add_listener(struct bgpd_config *conf, struct peer *p) 893 { 894 } 895 896 /* delete md5 key form all listening sockets, dummy function for portable */ 897 void 898 tcp_md5_del_listener(struct bgpd_config *conf, struct peer *p) 899 { 900 } 901