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