1 /* $OpenBSD: pfkey.c,v 1.45 2015/09/13 10:22:16 florian 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 <ctype.h> 26 #include <errno.h> 27 #include <limits.h> 28 #include <stdlib.h> 29 #include <string.h> 30 #include <unistd.h> 31 32 #include "bgpd.h" 33 #include "session.h" 34 35 #define PFKEY2_CHUNK sizeof(u_int64_t) 36 #define ROUNDUP(x) (((x) + (PFKEY2_CHUNK - 1)) & ~(PFKEY2_CHUNK - 1)) 37 #define IOV_CNT 20 38 39 static u_int32_t sadb_msg_seq = 0; 40 static u_int32_t pid = 0; /* should pid_t but pfkey needs u_int32_t */ 41 static int fd; 42 43 int pfkey_reply(int, u_int32_t *); 44 int pfkey_send(int, uint8_t, uint8_t, uint8_t, 45 struct bgpd_addr *, struct bgpd_addr *, 46 u_int32_t, uint8_t, int, char *, uint8_t, int, char *, 47 uint16_t, uint16_t); 48 int pfkey_sa_add(struct bgpd_addr *, struct bgpd_addr *, u_int8_t, char *, 49 u_int32_t *); 50 int pfkey_sa_remove(struct bgpd_addr *, struct bgpd_addr *, u_int32_t *); 51 int pfkey_md5sig_establish(struct peer *); 52 int pfkey_md5sig_remove(struct peer *); 53 int pfkey_ipsec_establish(struct peer *); 54 int pfkey_ipsec_remove(struct peer *); 55 56 #define pfkey_flow(fd, satype, cmd, dir, from, to, sport, dport) \ 57 pfkey_send(fd, satype, cmd, dir, from, to, \ 58 0, 0, 0, NULL, 0, 0, NULL, sport, dport) 59 60 int 61 pfkey_send(int sd, uint8_t satype, uint8_t mtype, uint8_t dir, 62 struct bgpd_addr *src, struct bgpd_addr *dst, u_int32_t spi, 63 uint8_t aalg, int alen, char *akey, uint8_t ealg, int elen, char *ekey, 64 uint16_t sport, uint16_t dport) 65 { 66 struct sadb_msg smsg; 67 struct sadb_sa sa; 68 struct sadb_address sa_src, sa_dst, sa_peer, sa_smask, sa_dmask; 69 struct sadb_key sa_akey, sa_ekey; 70 struct sadb_spirange sa_spirange; 71 struct sadb_protocol sa_flowtype, sa_protocol; 72 struct iovec iov[IOV_CNT]; 73 ssize_t n; 74 int len = 0; 75 int iov_cnt; 76 struct sockaddr_storage ssrc, sdst, speer, smask, dmask; 77 struct sockaddr *saptr; 78 79 if (!pid) 80 pid = getpid(); 81 82 /* we need clean sockaddr... no ports set */ 83 bzero(&ssrc, sizeof(ssrc)); 84 bzero(&smask, sizeof(smask)); 85 if ((saptr = addr2sa(src, 0))) 86 memcpy(&ssrc, saptr, sizeof(ssrc)); 87 switch (src->aid) { 88 case AID_INET: 89 memset(&((struct sockaddr_in *)&smask)->sin_addr, 0xff, 32/8); 90 break; 91 case AID_INET6: 92 memset(&((struct sockaddr_in6 *)&smask)->sin6_addr, 0xff, 93 128/8); 94 break; 95 case AID_UNSPEC: 96 ssrc.ss_len = sizeof(struct sockaddr); 97 break; 98 default: 99 return (-1); 100 } 101 smask.ss_family = ssrc.ss_family; 102 smask.ss_len = ssrc.ss_len; 103 104 bzero(&sdst, sizeof(sdst)); 105 bzero(&dmask, sizeof(dmask)); 106 if ((saptr = addr2sa(dst, 0))) 107 memcpy(&sdst, saptr, sizeof(sdst)); 108 switch (dst->aid) { 109 case AID_INET: 110 memset(&((struct sockaddr_in *)&dmask)->sin_addr, 0xff, 32/8); 111 break; 112 case AID_INET6: 113 memset(&((struct sockaddr_in6 *)&dmask)->sin6_addr, 0xff, 114 128/8); 115 break; 116 case AID_UNSPEC: 117 sdst.ss_len = sizeof(struct sockaddr); 118 break; 119 default: 120 return (-1); 121 } 122 dmask.ss_family = sdst.ss_family; 123 dmask.ss_len = sdst.ss_len; 124 125 bzero(&smsg, sizeof(smsg)); 126 smsg.sadb_msg_version = PF_KEY_V2; 127 smsg.sadb_msg_seq = ++sadb_msg_seq; 128 smsg.sadb_msg_pid = pid; 129 smsg.sadb_msg_len = sizeof(smsg) / 8; 130 smsg.sadb_msg_type = mtype; 131 smsg.sadb_msg_satype = satype; 132 133 switch (mtype) { 134 case SADB_GETSPI: 135 bzero(&sa_spirange, sizeof(sa_spirange)); 136 sa_spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE; 137 sa_spirange.sadb_spirange_len = sizeof(sa_spirange) / 8; 138 sa_spirange.sadb_spirange_min = 0x100; 139 sa_spirange.sadb_spirange_max = 0xffffffff; 140 sa_spirange.sadb_spirange_reserved = 0; 141 break; 142 case SADB_ADD: 143 case SADB_UPDATE: 144 case SADB_DELETE: 145 bzero(&sa, sizeof(sa)); 146 sa.sadb_sa_exttype = SADB_EXT_SA; 147 sa.sadb_sa_len = sizeof(sa) / 8; 148 sa.sadb_sa_replay = 0; 149 sa.sadb_sa_spi = spi; 150 sa.sadb_sa_state = SADB_SASTATE_MATURE; 151 break; 152 case SADB_X_ADDFLOW: 153 case SADB_X_DELFLOW: 154 bzero(&sa_flowtype, sizeof(sa_flowtype)); 155 sa_flowtype.sadb_protocol_exttype = SADB_X_EXT_FLOW_TYPE; 156 sa_flowtype.sadb_protocol_len = sizeof(sa_flowtype) / 8; 157 sa_flowtype.sadb_protocol_direction = dir; 158 sa_flowtype.sadb_protocol_proto = SADB_X_FLOW_TYPE_REQUIRE; 159 160 bzero(&sa_protocol, sizeof(sa_protocol)); 161 sa_protocol.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL; 162 sa_protocol.sadb_protocol_len = sizeof(sa_protocol) / 8; 163 sa_protocol.sadb_protocol_direction = 0; 164 sa_protocol.sadb_protocol_proto = 6; 165 break; 166 } 167 168 bzero(&sa_src, sizeof(sa_src)); 169 sa_src.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 170 sa_src.sadb_address_len = (sizeof(sa_src) + ROUNDUP(ssrc.ss_len)) / 8; 171 172 bzero(&sa_dst, sizeof(sa_dst)); 173 sa_dst.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 174 sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)) / 8; 175 176 sa.sadb_sa_auth = aalg; 177 sa.sadb_sa_encrypt = SADB_X_EALG_AES; /* XXX */ 178 179 switch (mtype) { 180 case SADB_ADD: 181 case SADB_UPDATE: 182 bzero(&sa_akey, sizeof(sa_akey)); 183 sa_akey.sadb_key_exttype = SADB_EXT_KEY_AUTH; 184 sa_akey.sadb_key_len = (sizeof(sa_akey) + 185 ((alen + 7) / 8) * 8) / 8; 186 sa_akey.sadb_key_bits = 8 * alen; 187 188 bzero(&sa_ekey, sizeof(sa_ekey)); 189 sa_ekey.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; 190 sa_ekey.sadb_key_len = (sizeof(sa_ekey) + 191 ((elen + 7) / 8) * 8) / 8; 192 sa_ekey.sadb_key_bits = 8 * elen; 193 194 break; 195 case SADB_X_ADDFLOW: 196 case SADB_X_DELFLOW: 197 /* sa_peer always points to the remote machine */ 198 if (dir == IPSP_DIRECTION_IN) { 199 speer = ssrc; 200 sa_peer = sa_src; 201 } else { 202 speer = sdst; 203 sa_peer = sa_dst; 204 } 205 sa_peer.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 206 sa_peer.sadb_address_len = 207 (sizeof(sa_peer) + ROUNDUP(speer.ss_len)) / 8; 208 209 /* for addflow we also use src/dst as the flow destination */ 210 sa_src.sadb_address_exttype = SADB_X_EXT_SRC_FLOW; 211 sa_dst.sadb_address_exttype = SADB_X_EXT_DST_FLOW; 212 213 bzero(&smask, sizeof(smask)); 214 switch (src->aid) { 215 case AID_INET: 216 smask.ss_len = sizeof(struct sockaddr_in); 217 smask.ss_family = AF_INET; 218 memset(&((struct sockaddr_in *)&smask)->sin_addr, 219 0xff, 32/8); 220 if (sport) { 221 ((struct sockaddr_in *)&ssrc)->sin_port = 222 htons(sport); 223 ((struct sockaddr_in *)&smask)->sin_port = 224 htons(0xffff); 225 } 226 break; 227 case AID_INET6: 228 smask.ss_len = sizeof(struct sockaddr_in6); 229 smask.ss_family = AF_INET6; 230 memset(&((struct sockaddr_in6 *)&smask)->sin6_addr, 231 0xff, 128/8); 232 if (sport) { 233 ((struct sockaddr_in6 *)&ssrc)->sin6_port = 234 htons(sport); 235 ((struct sockaddr_in6 *)&smask)->sin6_port = 236 htons(0xffff); 237 } 238 break; 239 } 240 bzero(&dmask, sizeof(dmask)); 241 switch (dst->aid) { 242 case AID_INET: 243 dmask.ss_len = sizeof(struct sockaddr_in); 244 dmask.ss_family = AF_INET; 245 memset(&((struct sockaddr_in *)&dmask)->sin_addr, 246 0xff, 32/8); 247 if (dport) { 248 ((struct sockaddr_in *)&sdst)->sin_port = 249 htons(dport); 250 ((struct sockaddr_in *)&dmask)->sin_port = 251 htons(0xffff); 252 } 253 break; 254 case AID_INET6: 255 dmask.ss_len = sizeof(struct sockaddr_in6); 256 dmask.ss_family = AF_INET6; 257 memset(&((struct sockaddr_in6 *)&dmask)->sin6_addr, 258 0xff, 128/8); 259 if (dport) { 260 ((struct sockaddr_in6 *)&sdst)->sin6_port = 261 htons(dport); 262 ((struct sockaddr_in6 *)&dmask)->sin6_port = 263 htons(0xffff); 264 } 265 break; 266 } 267 268 bzero(&sa_smask, sizeof(sa_smask)); 269 sa_smask.sadb_address_exttype = SADB_X_EXT_SRC_MASK; 270 sa_smask.sadb_address_len = 271 (sizeof(sa_smask) + ROUNDUP(smask.ss_len)) / 8; 272 273 bzero(&sa_dmask, sizeof(sa_dmask)); 274 sa_dmask.sadb_address_exttype = SADB_X_EXT_DST_MASK; 275 sa_dmask.sadb_address_len = 276 (sizeof(sa_dmask) + ROUNDUP(dmask.ss_len)) / 8; 277 break; 278 } 279 280 iov_cnt = 0; 281 282 /* msghdr */ 283 iov[iov_cnt].iov_base = &smsg; 284 iov[iov_cnt].iov_len = sizeof(smsg); 285 iov_cnt++; 286 287 switch (mtype) { 288 case SADB_ADD: 289 case SADB_UPDATE: 290 case SADB_DELETE: 291 /* SA hdr */ 292 iov[iov_cnt].iov_base = &sa; 293 iov[iov_cnt].iov_len = sizeof(sa); 294 smsg.sadb_msg_len += sa.sadb_sa_len; 295 iov_cnt++; 296 break; 297 case SADB_GETSPI: 298 /* SPI range */ 299 iov[iov_cnt].iov_base = &sa_spirange; 300 iov[iov_cnt].iov_len = sizeof(sa_spirange); 301 smsg.sadb_msg_len += sa_spirange.sadb_spirange_len; 302 iov_cnt++; 303 break; 304 case SADB_X_ADDFLOW: 305 /* sa_peer always points to the remote machine */ 306 iov[iov_cnt].iov_base = &sa_peer; 307 iov[iov_cnt].iov_len = sizeof(sa_peer); 308 iov_cnt++; 309 iov[iov_cnt].iov_base = &speer; 310 iov[iov_cnt].iov_len = ROUNDUP(speer.ss_len); 311 smsg.sadb_msg_len += sa_peer.sadb_address_len; 312 iov_cnt++; 313 314 /* FALLTHROUGH */ 315 case SADB_X_DELFLOW: 316 /* add flow type */ 317 iov[iov_cnt].iov_base = &sa_flowtype; 318 iov[iov_cnt].iov_len = sizeof(sa_flowtype); 319 smsg.sadb_msg_len += sa_flowtype.sadb_protocol_len; 320 iov_cnt++; 321 322 /* add protocol */ 323 iov[iov_cnt].iov_base = &sa_protocol; 324 iov[iov_cnt].iov_len = sizeof(sa_protocol); 325 smsg.sadb_msg_len += sa_protocol.sadb_protocol_len; 326 iov_cnt++; 327 328 /* add flow masks */ 329 iov[iov_cnt].iov_base = &sa_smask; 330 iov[iov_cnt].iov_len = sizeof(sa_smask); 331 iov_cnt++; 332 iov[iov_cnt].iov_base = &smask; 333 iov[iov_cnt].iov_len = ROUNDUP(smask.ss_len); 334 smsg.sadb_msg_len += sa_smask.sadb_address_len; 335 iov_cnt++; 336 337 iov[iov_cnt].iov_base = &sa_dmask; 338 iov[iov_cnt].iov_len = sizeof(sa_dmask); 339 iov_cnt++; 340 iov[iov_cnt].iov_base = &dmask; 341 iov[iov_cnt].iov_len = ROUNDUP(dmask.ss_len); 342 smsg.sadb_msg_len += sa_dmask.sadb_address_len; 343 iov_cnt++; 344 break; 345 } 346 347 /* dest addr */ 348 iov[iov_cnt].iov_base = &sa_dst; 349 iov[iov_cnt].iov_len = sizeof(sa_dst); 350 iov_cnt++; 351 iov[iov_cnt].iov_base = &sdst; 352 iov[iov_cnt].iov_len = ROUNDUP(sdst.ss_len); 353 smsg.sadb_msg_len += sa_dst.sadb_address_len; 354 iov_cnt++; 355 356 /* src addr */ 357 iov[iov_cnt].iov_base = &sa_src; 358 iov[iov_cnt].iov_len = sizeof(sa_src); 359 iov_cnt++; 360 iov[iov_cnt].iov_base = &ssrc; 361 iov[iov_cnt].iov_len = ROUNDUP(ssrc.ss_len); 362 smsg.sadb_msg_len += sa_src.sadb_address_len; 363 iov_cnt++; 364 365 switch (mtype) { 366 case SADB_ADD: 367 case SADB_UPDATE: 368 if (alen) { 369 /* auth key */ 370 iov[iov_cnt].iov_base = &sa_akey; 371 iov[iov_cnt].iov_len = sizeof(sa_akey); 372 iov_cnt++; 373 iov[iov_cnt].iov_base = akey; 374 iov[iov_cnt].iov_len = ((alen + 7) / 8) * 8; 375 smsg.sadb_msg_len += sa_akey.sadb_key_len; 376 iov_cnt++; 377 } 378 if (elen) { 379 /* encryption key */ 380 iov[iov_cnt].iov_base = &sa_ekey; 381 iov[iov_cnt].iov_len = sizeof(sa_ekey); 382 iov_cnt++; 383 iov[iov_cnt].iov_base = ekey; 384 iov[iov_cnt].iov_len = ((elen + 7) / 8) * 8; 385 smsg.sadb_msg_len += sa_ekey.sadb_key_len; 386 iov_cnt++; 387 } 388 break; 389 } 390 391 len = smsg.sadb_msg_len * 8; 392 do { 393 n = writev(sd, iov, iov_cnt); 394 } while (n == -1 && (errno == EAGAIN || errno == EINTR)); 395 396 if (n == -1) { 397 log_warn("writev (%d/%d)", iov_cnt, len); 398 return (-1); 399 } 400 401 return (0); 402 } 403 404 int 405 pfkey_read(int sd, struct sadb_msg *h) 406 { 407 struct sadb_msg hdr; 408 409 if (recv(sd, &hdr, sizeof(hdr), MSG_PEEK) != sizeof(hdr)) { 410 if (errno == EAGAIN || errno == EINTR) 411 return (0); 412 log_warn("pfkey peek"); 413 return (-1); 414 } 415 416 /* XXX: Only one message can be outstanding. */ 417 if (hdr.sadb_msg_seq == sadb_msg_seq && 418 hdr.sadb_msg_pid == pid) { 419 if (h) 420 bcopy(&hdr, h, sizeof(hdr)); 421 return (0); 422 } 423 424 /* not ours, discard */ 425 if (read(sd, &hdr, sizeof(hdr)) == -1) { 426 if (errno == EAGAIN || errno == EINTR) 427 return (0); 428 log_warn("pfkey read"); 429 return (-1); 430 } 431 432 return (1); 433 } 434 435 int 436 pfkey_reply(int sd, u_int32_t *spip) 437 { 438 struct sadb_msg hdr, *msg; 439 struct sadb_ext *ext; 440 struct sadb_sa *sa; 441 u_int8_t *data; 442 ssize_t len; 443 int rv; 444 445 do { 446 rv = pfkey_read(sd, &hdr); 447 if (rv == -1) 448 return (-1); 449 } while (rv); 450 451 if (hdr.sadb_msg_errno != 0) { 452 errno = hdr.sadb_msg_errno; 453 if (errno == ESRCH) 454 return (0); 455 else { 456 log_warn("pfkey"); 457 return (-1); 458 } 459 } 460 if ((data = reallocarray(NULL, hdr.sadb_msg_len, PFKEY2_CHUNK)) == NULL) { 461 log_warn("pfkey malloc"); 462 return (-1); 463 } 464 len = hdr.sadb_msg_len * PFKEY2_CHUNK; 465 if (read(sd, data, len) != len) { 466 log_warn("pfkey read"); 467 explicit_bzero(data, len); 468 free(data); 469 return (-1); 470 } 471 472 if (hdr.sadb_msg_type == SADB_GETSPI) { 473 if (spip == NULL) { 474 explicit_bzero(data, len); 475 free(data); 476 return (0); 477 } 478 479 msg = (struct sadb_msg *)data; 480 for (ext = (struct sadb_ext *)(msg + 1); 481 (size_t)((u_int8_t *)ext - (u_int8_t *)msg) < 482 msg->sadb_msg_len * PFKEY2_CHUNK; 483 ext = (struct sadb_ext *)((u_int8_t *)ext + 484 ext->sadb_ext_len * PFKEY2_CHUNK)) { 485 if (ext->sadb_ext_type == SADB_EXT_SA) { 486 sa = (struct sadb_sa *) ext; 487 *spip = sa->sadb_sa_spi; 488 break; 489 } 490 } 491 } 492 explicit_bzero(data, len); 493 free(data); 494 return (0); 495 } 496 497 int 498 pfkey_sa_add(struct bgpd_addr *src, struct bgpd_addr *dst, u_int8_t keylen, 499 char *key, u_int32_t *spi) 500 { 501 if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_GETSPI, 0, 502 src, dst, 0, 0, 0, NULL, 0, 0, NULL, 0, 0) < 0) 503 return (-1); 504 if (pfkey_reply(fd, spi) < 0) 505 return (-1); 506 if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_UPDATE, 0, 507 src, dst, *spi, 0, keylen, key, 0, 0, NULL, 0, 0) < 0) 508 return (-1); 509 if (pfkey_reply(fd, NULL) < 0) 510 return (-1); 511 return (0); 512 } 513 514 int 515 pfkey_sa_remove(struct bgpd_addr *src, struct bgpd_addr *dst, u_int32_t *spi) 516 { 517 if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_DELETE, 0, 518 src, dst, *spi, 0, 0, NULL, 0, 0, NULL, 0, 0) < 0) 519 return (-1); 520 if (pfkey_reply(fd, NULL) < 0) 521 return (-1); 522 *spi = 0; 523 return (0); 524 } 525 526 int 527 pfkey_md5sig_establish(struct peer *p) 528 { 529 sleep(1); 530 531 if (!p->auth.spi_out) 532 if (pfkey_sa_add(&p->auth.local_addr, &p->conf.remote_addr, 533 p->conf.auth.md5key_len, p->conf.auth.md5key, 534 &p->auth.spi_out) == -1) 535 return (-1); 536 if (!p->auth.spi_in) 537 if (pfkey_sa_add(&p->conf.remote_addr, &p->auth.local_addr, 538 p->conf.auth.md5key_len, p->conf.auth.md5key, 539 &p->auth.spi_in) == -1) 540 return (-1); 541 542 p->auth.established = 1; 543 return (0); 544 } 545 546 int 547 pfkey_md5sig_remove(struct peer *p) 548 { 549 if (p->auth.spi_out) 550 if (pfkey_sa_remove(&p->auth.local_addr, &p->conf.remote_addr, 551 &p->auth.spi_out) == -1) 552 return (-1); 553 if (p->auth.spi_in) 554 if (pfkey_sa_remove(&p->conf.remote_addr, &p->auth.local_addr, 555 &p->auth.spi_in) == -1) 556 return (-1); 557 558 p->auth.established = 0; 559 return (0); 560 } 561 562 int 563 pfkey_ipsec_establish(struct peer *p) 564 { 565 uint8_t satype = SADB_SATYPE_ESP; 566 567 switch (p->auth.method) { 568 case AUTH_IPSEC_IKE_ESP: 569 satype = SADB_SATYPE_ESP; 570 break; 571 case AUTH_IPSEC_IKE_AH: 572 satype = SADB_SATYPE_AH; 573 break; 574 case AUTH_IPSEC_MANUAL_ESP: 575 case AUTH_IPSEC_MANUAL_AH: 576 satype = p->auth.method == AUTH_IPSEC_MANUAL_ESP ? 577 SADB_SATYPE_ESP : SADB_SATYPE_AH; 578 if (pfkey_send(fd, satype, SADB_ADD, 0, 579 &p->auth.local_addr, &p->conf.remote_addr, 580 p->auth.spi_out, 581 p->conf.auth.auth_alg_out, 582 p->conf.auth.auth_keylen_out, 583 p->conf.auth.auth_key_out, 584 p->conf.auth.enc_alg_out, 585 p->conf.auth.enc_keylen_out, 586 p->conf.auth.enc_key_out, 587 0, 0) < 0) 588 return (-1); 589 if (pfkey_reply(fd, NULL) < 0) 590 return (-1); 591 if (pfkey_send(fd, satype, SADB_ADD, 0, 592 &p->conf.remote_addr, &p->auth.local_addr, 593 p->auth.spi_in, 594 p->conf.auth.auth_alg_in, 595 p->conf.auth.auth_keylen_in, 596 p->conf.auth.auth_key_in, 597 p->conf.auth.enc_alg_in, 598 p->conf.auth.enc_keylen_in, 599 p->conf.auth.enc_key_in, 600 0, 0) < 0) 601 return (-1); 602 if (pfkey_reply(fd, NULL) < 0) 603 return (-1); 604 break; 605 default: 606 return (-1); 607 break; 608 } 609 610 if (pfkey_flow(fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_OUT, 611 &p->auth.local_addr, &p->conf.remote_addr, 0, BGP_PORT) < 0) 612 return (-1); 613 if (pfkey_reply(fd, NULL) < 0) 614 return (-1); 615 616 if (pfkey_flow(fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_OUT, 617 &p->auth.local_addr, &p->conf.remote_addr, BGP_PORT, 0) < 0) 618 return (-1); 619 if (pfkey_reply(fd, NULL) < 0) 620 return (-1); 621 622 if (pfkey_flow(fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_IN, 623 &p->conf.remote_addr, &p->auth.local_addr, 0, BGP_PORT) < 0) 624 return (-1); 625 if (pfkey_reply(fd, NULL) < 0) 626 return (-1); 627 628 if (pfkey_flow(fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_IN, 629 &p->conf.remote_addr, &p->auth.local_addr, BGP_PORT, 0) < 0) 630 return (-1); 631 if (pfkey_reply(fd, NULL) < 0) 632 return (-1); 633 634 p->auth.established = 1; 635 return (0); 636 } 637 638 int 639 pfkey_ipsec_remove(struct peer *p) 640 { 641 uint8_t satype; 642 643 switch (p->auth.method) { 644 case AUTH_IPSEC_IKE_ESP: 645 satype = SADB_SATYPE_ESP; 646 break; 647 case AUTH_IPSEC_IKE_AH: 648 satype = SADB_SATYPE_AH; 649 break; 650 case AUTH_IPSEC_MANUAL_ESP: 651 case AUTH_IPSEC_MANUAL_AH: 652 satype = p->auth.method == AUTH_IPSEC_MANUAL_ESP ? 653 SADB_SATYPE_ESP : SADB_SATYPE_AH; 654 if (pfkey_send(fd, satype, SADB_DELETE, 0, 655 &p->auth.local_addr, &p->conf.remote_addr, 656 p->auth.spi_out, 0, 0, NULL, 0, 0, NULL, 657 0, 0) < 0) 658 return (-1); 659 if (pfkey_reply(fd, NULL) < 0) 660 return (-1); 661 662 if (pfkey_send(fd, satype, SADB_DELETE, 0, 663 &p->conf.remote_addr, &p->auth.local_addr, 664 p->auth.spi_in, 0, 0, NULL, 0, 0, NULL, 665 0, 0) < 0) 666 return (-1); 667 if (pfkey_reply(fd, NULL) < 0) 668 return (-1); 669 break; 670 default: 671 return (-1); 672 break; 673 } 674 675 if (pfkey_flow(fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_OUT, 676 &p->auth.local_addr, &p->conf.remote_addr, 0, BGP_PORT) < 0) 677 return (-1); 678 if (pfkey_reply(fd, NULL) < 0) 679 return (-1); 680 681 if (pfkey_flow(fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_OUT, 682 &p->auth.local_addr, &p->conf.remote_addr, BGP_PORT, 0) < 0) 683 return (-1); 684 if (pfkey_reply(fd, NULL) < 0) 685 return (-1); 686 687 if (pfkey_flow(fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_IN, 688 &p->conf.remote_addr, &p->auth.local_addr, 0, BGP_PORT) < 0) 689 return (-1); 690 if (pfkey_reply(fd, NULL) < 0) 691 return (-1); 692 693 if (pfkey_flow(fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_IN, 694 &p->conf.remote_addr, &p->auth.local_addr, BGP_PORT, 0) < 0) 695 return (-1); 696 if (pfkey_reply(fd, NULL) < 0) 697 return (-1); 698 699 p->auth.established = 0; 700 return (0); 701 } 702 703 int 704 pfkey_establish(struct peer *p) 705 { 706 /* 707 * make sure we keep copies of everything we need to 708 * remove SAs and flows later again, even if the 709 * info in p->conf changed due to reload. 710 * We need: SPIs, method, local_addr, remote_addr. 711 * remote_addr cannot change, so no copy. 712 */ 713 memcpy(&p->auth.local_addr, &p->conf.local_addr, 714 sizeof(p->auth.local_addr)); 715 p->auth.method = p->conf.auth.method; 716 p->auth.spi_in = p->conf.auth.spi_in; 717 p->auth.spi_out = p->conf.auth.spi_out; 718 719 if (!p->auth.method) 720 return (0); 721 else if (p->auth.method == AUTH_MD5SIG) 722 return (pfkey_md5sig_establish(p)); 723 else 724 return (pfkey_ipsec_establish(p)); 725 } 726 727 int 728 pfkey_remove(struct peer *p) 729 { 730 if (!p->auth.established) 731 return (0); 732 else if (p->auth.method == AUTH_MD5SIG) 733 return (pfkey_md5sig_remove(p)); 734 else 735 return (pfkey_ipsec_remove(p)); 736 } 737 738 int 739 pfkey_init(struct bgpd_sysdep *sysdep) 740 { 741 if ((fd = socket(PF_KEY, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, 742 PF_KEY_V2)) == -1) { 743 if (errno == EPROTONOSUPPORT) { 744 log_warnx("PF_KEY not available, disabling ipsec"); 745 sysdep->no_pfkey = 1; 746 return (-1); 747 } else 748 fatal("pfkey setup failed"); 749 } 750 return (fd); 751 } 752