1 /* $OpenBSD: pfkey.c,v 1.41 2010/12/09 13:50:41 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 <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 log_warn("pfkey peek"); 411 return (-1); 412 } 413 414 /* XXX: Only one message can be outstanding. */ 415 if (hdr.sadb_msg_seq == sadb_msg_seq && 416 hdr.sadb_msg_pid == pid) { 417 if (h) 418 bcopy(&hdr, h, sizeof(hdr)); 419 return (0); 420 } 421 422 /* not ours, discard */ 423 if (read(sd, &hdr, sizeof(hdr)) == -1) { 424 log_warn("pfkey read"); 425 return (-1); 426 } 427 428 return (1); 429 } 430 431 int 432 pfkey_reply(int sd, u_int32_t *spip) 433 { 434 struct sadb_msg hdr, *msg; 435 struct sadb_ext *ext; 436 struct sadb_sa *sa; 437 u_int8_t *data; 438 ssize_t len; 439 int rv; 440 441 do { 442 rv = pfkey_read(sd, &hdr); 443 if (rv == -1) 444 return (-1); 445 } while (rv); 446 447 if (hdr.sadb_msg_errno != 0) { 448 errno = hdr.sadb_msg_errno; 449 if (errno == ESRCH) 450 return (0); 451 else { 452 log_warn("pfkey"); 453 return (-1); 454 } 455 } 456 len = hdr.sadb_msg_len * PFKEY2_CHUNK; 457 if ((data = malloc(len)) == NULL) { 458 log_warn("pfkey malloc"); 459 return (-1); 460 } 461 if (read(sd, data, len) != len) { 462 log_warn("pfkey read"); 463 bzero(data, len); 464 free(data); 465 return (-1); 466 } 467 468 if (hdr.sadb_msg_type == SADB_GETSPI) { 469 if (spip == NULL) { 470 bzero(data, len); 471 free(data); 472 return (0); 473 } 474 475 msg = (struct sadb_msg *)data; 476 for (ext = (struct sadb_ext *)(msg + 1); 477 (size_t)((u_int8_t *)ext - (u_int8_t *)msg) < 478 msg->sadb_msg_len * PFKEY2_CHUNK; 479 ext = (struct sadb_ext *)((u_int8_t *)ext + 480 ext->sadb_ext_len * PFKEY2_CHUNK)) { 481 if (ext->sadb_ext_type == SADB_EXT_SA) { 482 sa = (struct sadb_sa *) ext; 483 *spip = sa->sadb_sa_spi; 484 break; 485 } 486 } 487 } 488 bzero(data, len); 489 free(data); 490 return (0); 491 } 492 493 int 494 pfkey_sa_add(struct bgpd_addr *src, struct bgpd_addr *dst, u_int8_t keylen, 495 char *key, u_int32_t *spi) 496 { 497 if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_GETSPI, 0, 498 src, dst, 0, 0, 0, NULL, 0, 0, NULL, 0, 0) < 0) 499 return (-1); 500 if (pfkey_reply(fd, spi) < 0) 501 return (-1); 502 if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_UPDATE, 0, 503 src, dst, *spi, 0, keylen, key, 0, 0, NULL, 0, 0) < 0) 504 return (-1); 505 if (pfkey_reply(fd, NULL) < 0) 506 return (-1); 507 return (0); 508 } 509 510 int 511 pfkey_sa_remove(struct bgpd_addr *src, struct bgpd_addr *dst, u_int32_t *spi) 512 { 513 if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE, SADB_DELETE, 0, 514 src, dst, *spi, 0, 0, NULL, 0, 0, NULL, 0, 0) < 0) 515 return (-1); 516 if (pfkey_reply(fd, NULL) < 0) 517 return (-1); 518 *spi = 0; 519 return (0); 520 } 521 522 int 523 pfkey_md5sig_establish(struct peer *p) 524 { 525 sleep(1); 526 527 if (!p->auth.spi_out) 528 if (pfkey_sa_add(&p->auth.local_addr, &p->conf.remote_addr, 529 p->conf.auth.md5key_len, p->conf.auth.md5key, 530 &p->auth.spi_out) == -1) 531 return (-1); 532 if (!p->auth.spi_in) 533 if (pfkey_sa_add(&p->conf.remote_addr, &p->auth.local_addr, 534 p->conf.auth.md5key_len, p->conf.auth.md5key, 535 &p->auth.spi_in) == -1) 536 return (-1); 537 538 p->auth.established = 1; 539 return (0); 540 } 541 542 int 543 pfkey_md5sig_remove(struct peer *p) 544 { 545 if (p->auth.spi_out) 546 if (pfkey_sa_remove(&p->auth.local_addr, &p->conf.remote_addr, 547 &p->auth.spi_out) == -1) 548 return (-1); 549 if (p->auth.spi_in) 550 if (pfkey_sa_remove(&p->conf.remote_addr, &p->auth.local_addr, 551 &p->auth.spi_in) == -1) 552 return (-1); 553 554 p->auth.established = 0; 555 return (0); 556 } 557 558 int 559 pfkey_ipsec_establish(struct peer *p) 560 { 561 uint8_t satype = SADB_SATYPE_ESP; 562 563 switch (p->auth.method) { 564 case AUTH_IPSEC_IKE_ESP: 565 satype = SADB_SATYPE_ESP; 566 break; 567 case AUTH_IPSEC_IKE_AH: 568 satype = SADB_SATYPE_AH; 569 break; 570 case AUTH_IPSEC_MANUAL_ESP: 571 case AUTH_IPSEC_MANUAL_AH: 572 satype = p->auth.method == AUTH_IPSEC_MANUAL_ESP ? 573 SADB_SATYPE_ESP : SADB_SATYPE_AH; 574 if (pfkey_send(fd, satype, SADB_ADD, 0, 575 &p->auth.local_addr, &p->conf.remote_addr, 576 p->auth.spi_out, 577 p->conf.auth.auth_alg_out, 578 p->conf.auth.auth_keylen_out, 579 p->conf.auth.auth_key_out, 580 p->conf.auth.enc_alg_out, 581 p->conf.auth.enc_keylen_out, 582 p->conf.auth.enc_key_out, 583 0, 0) < 0) 584 return (-1); 585 if (pfkey_reply(fd, NULL) < 0) 586 return (-1); 587 if (pfkey_send(fd, satype, SADB_ADD, 0, 588 &p->conf.remote_addr, &p->auth.local_addr, 589 p->auth.spi_in, 590 p->conf.auth.auth_alg_in, 591 p->conf.auth.auth_keylen_in, 592 p->conf.auth.auth_key_in, 593 p->conf.auth.enc_alg_in, 594 p->conf.auth.enc_keylen_in, 595 p->conf.auth.enc_key_in, 596 0, 0) < 0) 597 return (-1); 598 if (pfkey_reply(fd, NULL) < 0) 599 return (-1); 600 break; 601 default: 602 return (-1); 603 break; 604 } 605 606 if (pfkey_flow(fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_OUT, 607 &p->auth.local_addr, &p->conf.remote_addr, 0, BGP_PORT) < 0) 608 return (-1); 609 if (pfkey_reply(fd, NULL) < 0) 610 return (-1); 611 612 if (pfkey_flow(fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_OUT, 613 &p->auth.local_addr, &p->conf.remote_addr, BGP_PORT, 0) < 0) 614 return (-1); 615 if (pfkey_reply(fd, NULL) < 0) 616 return (-1); 617 618 if (pfkey_flow(fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_IN, 619 &p->conf.remote_addr, &p->auth.local_addr, 0, BGP_PORT) < 0) 620 return (-1); 621 if (pfkey_reply(fd, NULL) < 0) 622 return (-1); 623 624 if (pfkey_flow(fd, satype, SADB_X_ADDFLOW, IPSP_DIRECTION_IN, 625 &p->conf.remote_addr, &p->auth.local_addr, BGP_PORT, 0) < 0) 626 return (-1); 627 if (pfkey_reply(fd, NULL) < 0) 628 return (-1); 629 630 p->auth.established = 1; 631 return (0); 632 } 633 634 int 635 pfkey_ipsec_remove(struct peer *p) 636 { 637 uint8_t satype; 638 639 switch (p->auth.method) { 640 case AUTH_IPSEC_IKE_ESP: 641 satype = SADB_SATYPE_ESP; 642 break; 643 case AUTH_IPSEC_IKE_AH: 644 satype = SADB_SATYPE_AH; 645 break; 646 case AUTH_IPSEC_MANUAL_ESP: 647 case AUTH_IPSEC_MANUAL_AH: 648 satype = p->auth.method == AUTH_IPSEC_MANUAL_ESP ? 649 SADB_SATYPE_ESP : SADB_SATYPE_AH; 650 if (pfkey_send(fd, satype, SADB_DELETE, 0, 651 &p->auth.local_addr, &p->conf.remote_addr, 652 p->auth.spi_out, 0, 0, NULL, 0, 0, NULL, 653 0, 0) < 0) 654 return (-1); 655 if (pfkey_reply(fd, NULL) < 0) 656 return (-1); 657 658 if (pfkey_send(fd, satype, SADB_DELETE, 0, 659 &p->conf.remote_addr, &p->auth.local_addr, 660 p->auth.spi_in, 0, 0, NULL, 0, 0, NULL, 661 0, 0) < 0) 662 return (-1); 663 if (pfkey_reply(fd, NULL) < 0) 664 return (-1); 665 break; 666 default: 667 return (-1); 668 break; 669 } 670 671 if (pfkey_flow(fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_OUT, 672 &p->auth.local_addr, &p->conf.remote_addr, 0, BGP_PORT) < 0) 673 return (-1); 674 if (pfkey_reply(fd, NULL) < 0) 675 return (-1); 676 677 if (pfkey_flow(fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_OUT, 678 &p->auth.local_addr, &p->conf.remote_addr, BGP_PORT, 0) < 0) 679 return (-1); 680 if (pfkey_reply(fd, NULL) < 0) 681 return (-1); 682 683 if (pfkey_flow(fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_IN, 684 &p->conf.remote_addr, &p->auth.local_addr, 0, BGP_PORT) < 0) 685 return (-1); 686 if (pfkey_reply(fd, NULL) < 0) 687 return (-1); 688 689 if (pfkey_flow(fd, satype, SADB_X_DELFLOW, IPSP_DIRECTION_IN, 690 &p->conf.remote_addr, &p->auth.local_addr, BGP_PORT, 0) < 0) 691 return (-1); 692 if (pfkey_reply(fd, NULL) < 0) 693 return (-1); 694 695 p->auth.established = 0; 696 return (0); 697 } 698 699 int 700 pfkey_establish(struct peer *p) 701 { 702 /* 703 * make sure we keep copies of everything we need to 704 * remove SAs and flows later again, even if the 705 * info in p->conf changed due to reload. 706 * We need: SPIs, method, local_addr, remote_addr. 707 * remote_addr cannot change, so no copy. 708 */ 709 memcpy(&p->auth.local_addr, &p->conf.local_addr, 710 sizeof(p->auth.local_addr)); 711 p->auth.method = p->conf.auth.method; 712 p->auth.spi_in = p->conf.auth.spi_in; 713 p->auth.spi_out = p->conf.auth.spi_out; 714 715 if (!p->auth.method) 716 return (0); 717 else if (p->auth.method == AUTH_MD5SIG) 718 return (pfkey_md5sig_establish(p)); 719 else 720 return (pfkey_ipsec_establish(p)); 721 } 722 723 int 724 pfkey_remove(struct peer *p) 725 { 726 if (!p->auth.established) 727 return (0); 728 else if (p->auth.method == AUTH_MD5SIG) 729 return (pfkey_md5sig_remove(p)); 730 else 731 return (pfkey_ipsec_remove(p)); 732 } 733 734 int 735 pfkey_init(struct bgpd_sysdep *sysdep) 736 { 737 if ((fd = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) == -1) { 738 if (errno == EPROTONOSUPPORT) { 739 log_warnx("PF_KEY not available, disabling ipsec"); 740 sysdep->no_pfkey = 1; 741 return (-1); 742 } else 743 fatal("pfkey setup failed"); 744 } 745 return (fd); 746 } 747