| File: | src/usr.sbin/ldpd/pfkey.c | 
| Warning: | line 296, column 25 The left operand of '!=' is a garbage value | 
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* $OpenBSD: pfkey.c,v 1.12 2019/01/23 02:02:04 dlg 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 <errno(*__errno()).h> | |||
| 22 | #include <stdlib.h> | |||
| 23 | #include <string.h> | |||
| 24 | #include <unistd.h> | |||
| 25 | ||||
| 26 | #include "ldpd.h" | |||
| 27 | #include "ldpe.h" | |||
| 28 | #include "log.h" | |||
| 29 | ||||
| 30 | static int pfkey_send(int, uint8_t, uint8_t, uint8_t, | |||
| 31 | int, union ldpd_addr *, union ldpd_addr *, | |||
| 32 | uint32_t, uint8_t, int, char *, uint8_t, int, char *, | |||
| 33 | uint16_t, uint16_t); | |||
| 34 | static int pfkey_reply(int, uint32_t *); | |||
| 35 | static int pfkey_sa_add(int, union ldpd_addr *, union ldpd_addr *, | |||
| 36 | uint8_t, char *, uint32_t *); | |||
| 37 | static int pfkey_sa_remove(int, union ldpd_addr *, union ldpd_addr *, | |||
| 38 | uint32_t *); | |||
| 39 | static int pfkey_md5sig_establish(struct nbr *, struct ldp_auth *); | |||
| 40 | static int pfkey_md5sig_remove(struct nbr *); | |||
| 41 | ||||
| 42 | #define PFKEY2_CHUNKsizeof(uint64_t) sizeof(uint64_t) | |||
| 43 | #define	ROUNDUP(x)(((x) + (sizeof(uint64_t) - 1)) & ~(sizeof(uint64_t) - 1) ) (((x) + (PFKEY2_CHUNKsizeof(uint64_t) - 1)) & ~(PFKEY2_CHUNKsizeof(uint64_t) - 1)) | |||
| 44 | #define IOV_CNT20 20 | |||
| 45 | ||||
| 46 | static uint32_t sadb_msg_seq; | |||
| 47 | static uint32_t pid; /* should pid_t but pfkey needs uint32_t */ | |||
| 48 | static int fd; | |||
| 49 | ||||
| 50 | static int | |||
| 51 | pfkey_send(int sd, uint8_t satype, uint8_t mtype, uint8_t dir, | |||
| 52 | int af, union ldpd_addr *src, union ldpd_addr *dst, uint32_t spi, | |||
| 53 | uint8_t aalg, int alen, char *akey, uint8_t ealg, int elen, char *ekey, | |||
| 54 | uint16_t sport, uint16_t dport) | |||
| 55 | { | |||
| 56 | struct sadb_msg smsg; | |||
| 57 | struct sadb_sa sa; | |||
| 58 | struct sadb_address sa_src, sa_dst; | |||
| 59 | struct sadb_key sa_akey, sa_ekey; | |||
| 60 | struct sadb_spirange sa_spirange; | |||
| 61 | struct iovec iov[IOV_CNT20]; | |||
| 62 | ssize_t n; | |||
| 63 | int len = 0; | |||
| 64 | int iov_cnt; | |||
| 65 | struct sockaddr_storage ssrc, sdst, smask, dmask; | |||
| 66 | struct sockaddr *saptr; | |||
| 67 | ||||
| 68 | if (!pid) | |||
| 69 | pid = getpid(); | |||
| 70 | ||||
| 71 | /* we need clean sockaddr... no ports set */ | |||
| 72 | memset(&ssrc, 0, sizeof(ssrc)); | |||
| 73 | memset(&smask, 0, sizeof(smask)); | |||
| 74 | if ((saptr = addr2sa(af, src, 0))) | |||
| 75 | memcpy(&ssrc, saptr, sizeof(ssrc)); | |||
| 76 | switch (af) { | |||
| 77 | case AF_INET2: | |||
| 78 | memset(&((struct sockaddr_in *)&smask)->sin_addr, 0xff, 32/8); | |||
| 79 | break; | |||
| 80 | case AF_INET624: | |||
| 81 | memset(&((struct sockaddr_in6 *)&smask)->sin6_addr, 0xff, | |||
| 82 | 128/8); | |||
| 83 | break; | |||
| 84 | default: | |||
| 85 | return (-1); | |||
| 86 | } | |||
| 87 | smask.ss_family = ssrc.ss_family; | |||
| 88 | smask.ss_len = ssrc.ss_len; | |||
| 89 | ||||
| 90 | memset(&sdst, 0, sizeof(sdst)); | |||
| 91 | memset(&dmask, 0, sizeof(dmask)); | |||
| 92 | if ((saptr = addr2sa(af, dst, 0))) | |||
| 93 | memcpy(&sdst, saptr, sizeof(sdst)); | |||
| 94 | switch (af) { | |||
| 95 | case AF_INET2: | |||
| 96 | memset(&((struct sockaddr_in *)&dmask)->sin_addr, 0xff, 32/8); | |||
| 97 | break; | |||
| 98 | case AF_INET624: | |||
| 99 | memset(&((struct sockaddr_in6 *)&dmask)->sin6_addr, 0xff, | |||
| 100 | 128/8); | |||
| 101 | break; | |||
| 102 | default: | |||
| 103 | return (-1); | |||
| 104 | } | |||
| 105 | dmask.ss_family = sdst.ss_family; | |||
| 106 | dmask.ss_len = sdst.ss_len; | |||
| 107 | ||||
| 108 | memset(&smsg, 0, sizeof(smsg)); | |||
| 109 | smsg.sadb_msg_version = PF_KEY_V22; | |||
| 110 | smsg.sadb_msg_seq = ++sadb_msg_seq; | |||
| 111 | smsg.sadb_msg_pid = pid; | |||
| 112 | smsg.sadb_msg_len = sizeof(smsg) / 8; | |||
| 113 | smsg.sadb_msg_type = mtype; | |||
| 114 | smsg.sadb_msg_satype = satype; | |||
| 115 | ||||
| 116 | switch (mtype) { | |||
| 117 | case SADB_GETSPI1: | |||
| 118 | memset(&sa_spirange, 0, sizeof(sa_spirange)); | |||
| 119 | sa_spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE16; | |||
| 120 | sa_spirange.sadb_spirange_len = sizeof(sa_spirange) / 8; | |||
| 121 | sa_spirange.sadb_spirange_min = 0x100; | |||
| 122 | sa_spirange.sadb_spirange_max = 0xffffffff; | |||
| 123 | sa_spirange.sadb_spirange_reserved = 0; | |||
| 124 | break; | |||
| 125 | case SADB_ADD3: | |||
| 126 | case SADB_UPDATE2: | |||
| 127 | case SADB_DELETE4: | |||
| 128 | memset(&sa, 0, sizeof(sa)); | |||
| 129 | sa.sadb_sa_exttype = SADB_EXT_SA1; | |||
| 130 | sa.sadb_sa_len = sizeof(sa) / 8; | |||
| 131 | sa.sadb_sa_replay = 0; | |||
| 132 | sa.sadb_sa_spi = spi; | |||
| 133 | sa.sadb_sa_state = SADB_SASTATE_MATURE1; | |||
| 134 | break; | |||
| 135 | } | |||
| 136 | ||||
| 137 | memset(&sa_src, 0, sizeof(sa_src)); | |||
| 138 | sa_src.sadb_address_exttype = SADB_EXT_ADDRESS_SRC5; | |||
| 139 | sa_src.sadb_address_len = (sizeof(sa_src) + ROUNDUP(ssrc.ss_len)(((ssrc.ss_len) + (sizeof(uint64_t) - 1)) & ~(sizeof(uint64_t ) - 1))) / 8; | |||
| 140 | ||||
| 141 | memset(&sa_dst, 0, sizeof(sa_dst)); | |||
| 142 | sa_dst.sadb_address_exttype = SADB_EXT_ADDRESS_DST6; | |||
| 143 | sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)(((sdst.ss_len) + (sizeof(uint64_t) - 1)) & ~(sizeof(uint64_t ) - 1))) / 8; | |||
| 144 | ||||
| 145 | sa.sadb_sa_auth = aalg; | |||
| 146 | sa.sadb_sa_encrypt = SADB_X_EALG_AES12; /* XXX */ | |||
| 147 | ||||
| 148 | switch (mtype) { | |||
| 149 | case SADB_ADD3: | |||
| 150 | case SADB_UPDATE2: | |||
| 151 | memset(&sa_akey, 0, sizeof(sa_akey)); | |||
| 152 | sa_akey.sadb_key_exttype = SADB_EXT_KEY_AUTH8; | |||
| 153 | sa_akey.sadb_key_len = (sizeof(sa_akey) + | |||
| 154 | ((alen + 7) / 8) * 8) / 8; | |||
| 155 | sa_akey.sadb_key_bits = 8 * alen; | |||
| 156 | ||||
| 157 | memset(&sa_ekey, 0, sizeof(sa_ekey)); | |||
| 158 | sa_ekey.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT9; | |||
| 159 | sa_ekey.sadb_key_len = (sizeof(sa_ekey) + | |||
| 160 | ((elen + 7) / 8) * 8) / 8; | |||
| 161 | sa_ekey.sadb_key_bits = 8 * elen; | |||
| 162 | ||||
| 163 | break; | |||
| 164 | } | |||
| 165 | ||||
| 166 | iov_cnt = 0; | |||
| 167 | ||||
| 168 | /* msghdr */ | |||
| 169 | iov[iov_cnt].iov_base = &smsg; | |||
| 170 | iov[iov_cnt].iov_len = sizeof(smsg); | |||
| 171 | iov_cnt++; | |||
| 172 | ||||
| 173 | switch (mtype) { | |||
| 174 | case SADB_ADD3: | |||
| 175 | case SADB_UPDATE2: | |||
| 176 | case SADB_DELETE4: | |||
| 177 | /* SA hdr */ | |||
| 178 | iov[iov_cnt].iov_base = &sa; | |||
| 179 | iov[iov_cnt].iov_len = sizeof(sa); | |||
| 180 | smsg.sadb_msg_len += sa.sadb_sa_len; | |||
| 181 | iov_cnt++; | |||
| 182 | break; | |||
| 183 | case SADB_GETSPI1: | |||
| 184 | /* SPI range */ | |||
| 185 | iov[iov_cnt].iov_base = &sa_spirange; | |||
| 186 | iov[iov_cnt].iov_len = sizeof(sa_spirange); | |||
| 187 | smsg.sadb_msg_len += sa_spirange.sadb_spirange_len; | |||
| 188 | iov_cnt++; | |||
| 189 | break; | |||
| 190 | } | |||
| 191 | ||||
| 192 | /* dest addr */ | |||
| 193 | iov[iov_cnt].iov_base = &sa_dst; | |||
| 194 | iov[iov_cnt].iov_len = sizeof(sa_dst); | |||
| 195 | iov_cnt++; | |||
| 196 | iov[iov_cnt].iov_base = &sdst; | |||
| 197 | iov[iov_cnt].iov_len = ROUNDUP(sdst.ss_len)(((sdst.ss_len) + (sizeof(uint64_t) - 1)) & ~(sizeof(uint64_t ) - 1)); | |||
| 198 | smsg.sadb_msg_len += sa_dst.sadb_address_len; | |||
| 199 | iov_cnt++; | |||
| 200 | ||||
| 201 | /* src addr */ | |||
| 202 | iov[iov_cnt].iov_base = &sa_src; | |||
| 203 | iov[iov_cnt].iov_len = sizeof(sa_src); | |||
| 204 | iov_cnt++; | |||
| 205 | iov[iov_cnt].iov_base = &ssrc; | |||
| 206 | iov[iov_cnt].iov_len = ROUNDUP(ssrc.ss_len)(((ssrc.ss_len) + (sizeof(uint64_t) - 1)) & ~(sizeof(uint64_t ) - 1)); | |||
| 207 | smsg.sadb_msg_len += sa_src.sadb_address_len; | |||
| 208 | iov_cnt++; | |||
| 209 | ||||
| 210 | switch (mtype) { | |||
| 211 | case SADB_ADD3: | |||
| 212 | case SADB_UPDATE2: | |||
| 213 | if (alen) { | |||
| 214 | /* auth key */ | |||
| 215 | iov[iov_cnt].iov_base = &sa_akey; | |||
| 216 | iov[iov_cnt].iov_len = sizeof(sa_akey); | |||
| 217 | iov_cnt++; | |||
| 218 | iov[iov_cnt].iov_base = akey; | |||
| 219 | iov[iov_cnt].iov_len = ((alen + 7) / 8) * 8; | |||
| 220 | smsg.sadb_msg_len += sa_akey.sadb_key_len; | |||
| 221 | iov_cnt++; | |||
| 222 | } | |||
| 223 | if (elen) { | |||
| 224 | /* encryption key */ | |||
| 225 | iov[iov_cnt].iov_base = &sa_ekey; | |||
| 226 | iov[iov_cnt].iov_len = sizeof(sa_ekey); | |||
| 227 | iov_cnt++; | |||
| 228 | iov[iov_cnt].iov_base = ekey; | |||
| 229 | iov[iov_cnt].iov_len = ((elen + 7) / 8) * 8; | |||
| 230 | smsg.sadb_msg_len += sa_ekey.sadb_key_len; | |||
| 231 | iov_cnt++; | |||
| 232 | } | |||
| 233 | break; | |||
| 234 | } | |||
| 235 | ||||
| 236 | len = smsg.sadb_msg_len * 8; | |||
| 237 | do { | |||
| 238 | n = writev(sd, iov, iov_cnt); | |||
| 239 | } while (n == -1 && (errno(*__errno()) == EAGAIN35 || errno(*__errno()) == EINTR4)); | |||
| 240 | ||||
| 241 | if (n == -1) { | |||
| 242 | log_warn("writev (%d/%d)", iov_cnt, len); | |||
| 243 | return (-1); | |||
| 244 | } | |||
| 245 | ||||
| 246 | return (0); | |||
| 247 | } | |||
| 248 | ||||
| 249 | int | |||
| 250 | pfkey_read(int sd, struct sadb_msg *h) | |||
| 251 | { | |||
| 252 | struct sadb_msg hdr; | |||
| 253 | ||||
| 254 | if (recv(sd, &hdr, sizeof(hdr), MSG_PEEK0x2) != sizeof(hdr)) { | |||
| 255 | if (errno(*__errno()) == EAGAIN35 || errno(*__errno()) == EINTR4) | |||
| 256 | return (0); | |||
| 257 | log_warn("pfkey peek"); | |||
| 258 | return (-1); | |||
| 259 | } | |||
| 260 | ||||
| 261 | /* XXX: Only one message can be outstanding. */ | |||
| 262 | if (hdr.sadb_msg_seq == sadb_msg_seq && | |||
| 263 | hdr.sadb_msg_pid == pid) { | |||
| 264 | if (h) | |||
| 265 | *h = hdr; | |||
| 266 | return (0); | |||
| 267 | } | |||
| 268 | ||||
| 269 | /* not ours, discard */ | |||
| 270 | if (read(sd, &hdr, sizeof(hdr)) == -1) { | |||
| 271 | if (errno(*__errno()) == EAGAIN35 || errno(*__errno()) == EINTR4) | |||
| 272 | return (0); | |||
| 273 | log_warn("pfkey read"); | |||
| 274 | return (-1); | |||
| 275 | } | |||
| 276 | ||||
| 277 | return (1); | |||
| 278 | } | |||
| 279 | ||||
| 280 | static int | |||
| 281 | pfkey_reply(int sd, uint32_t *spip) | |||
| 282 | { | |||
| 283 | struct sadb_msg hdr, *msg; | |||
| 284 | struct sadb_ext *ext; | |||
| 285 | struct sadb_sa *sa; | |||
| 286 | uint8_t *data; | |||
| 287 | ssize_t len; | |||
| 288 | int rv; | |||
| 289 | ||||
| 290 | do { | |||
| 291 | rv = pfkey_read(sd, &hdr); | |||
| 292 | if (rv == -1) | |||
| 293 | return (-1); | |||
| 294 | } while (rv); | |||
| 295 | ||||
| 296 | if (hdr.sadb_msg_errno != 0) { | |||
| 
 | ||||
| 297 | errno(*__errno()) = hdr.sadb_msg_errno; | |||
| 298 | if (errno(*__errno()) == ESRCH3) | |||
| 299 | return (0); | |||
| 300 | else { | |||
| 301 | log_warn("pfkey"); | |||
| 302 | return (-1); | |||
| 303 | } | |||
| 304 | } | |||
| 305 | if ((data = reallocarray(NULL((void *)0), hdr.sadb_msg_len, PFKEY2_CHUNKsizeof(uint64_t))) == NULL((void *)0)) { | |||
| 306 | log_warn("pfkey malloc"); | |||
| 307 | return (-1); | |||
| 308 | } | |||
| 309 | len = hdr.sadb_msg_len * PFKEY2_CHUNKsizeof(uint64_t); | |||
| 310 | if (read(sd, data, len) != len) { | |||
| 311 | log_warn("pfkey read"); | |||
| 312 | freezero(data, len); | |||
| 313 | return (-1); | |||
| 314 | } | |||
| 315 | ||||
| 316 | if (hdr.sadb_msg_type == SADB_GETSPI1) { | |||
| 317 | if (spip == NULL((void *)0)) { | |||
| 318 | freezero(data, len); | |||
| 319 | return (0); | |||
| 320 | } | |||
| 321 | ||||
| 322 | msg = (struct sadb_msg *)data; | |||
| 323 | for (ext = (struct sadb_ext *)(msg + 1); | |||
| 324 | (size_t)((uint8_t *)ext - (uint8_t *)msg) < | |||
| 325 | msg->sadb_msg_len * PFKEY2_CHUNKsizeof(uint64_t); | |||
| 326 | ext = (struct sadb_ext *)((uint8_t *)ext + | |||
| 327 | ext->sadb_ext_len * PFKEY2_CHUNKsizeof(uint64_t))) { | |||
| 328 | if (ext->sadb_ext_type == SADB_EXT_SA1) { | |||
| 329 | sa = (struct sadb_sa *) ext; | |||
| 330 | *spip = sa->sadb_sa_spi; | |||
| 331 | break; | |||
| 332 | } | |||
| 333 | } | |||
| 334 | } | |||
| 335 | freezero(data, len); | |||
| 336 | return (0); | |||
| 337 | } | |||
| 338 | ||||
| 339 | static int | |||
| 340 | pfkey_sa_add(int af, union ldpd_addr *src, union ldpd_addr *dst, uint8_t keylen, | |||
| 341 | char *key, uint32_t *spi) | |||
| 342 | { | |||
| 343 | if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE8, SADB_GETSPI1, 0, | |||
| 344 | af, src, dst, 0, 0, 0, NULL((void *)0), 0, 0, NULL((void *)0), 0, 0) < 0) | |||
| 345 | return (-1); | |||
| 346 | if (pfkey_reply(fd, spi) < 0) | |||
| 347 | return (-1); | |||
| 348 | if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE8, SADB_UPDATE2, 0, | |||
| 349 | af, src, dst, *spi, 0, keylen, key, 0, 0, NULL((void *)0), 0, 0) < 0) | |||
| 350 | return (-1); | |||
| 351 | if (pfkey_reply(fd, NULL((void *)0)) < 0) | |||
| 352 | return (-1); | |||
| 353 | return (0); | |||
| 354 | } | |||
| 355 | ||||
| 356 | static int | |||
| 357 | pfkey_sa_remove(int af, union ldpd_addr *src, union ldpd_addr *dst, | |||
| 358 | uint32_t *spi) | |||
| 359 | { | |||
| 360 | if (pfkey_send(fd, SADB_X_SATYPE_TCPSIGNATURE8, SADB_DELETE4, 0, | |||
| 361 | af, src, dst, *spi, 0, 0, NULL((void *)0), 0, 0, NULL((void *)0), 0, 0) < 0) | |||
| 362 | return (-1); | |||
| 363 | if (pfkey_reply(fd, NULL((void *)0)) < 0) | |||
| 364 | return (-1); | |||
| 365 | *spi = 0; | |||
| 366 | return (0); | |||
| 367 | } | |||
| 368 | ||||
| 369 | static int | |||
| 370 | pfkey_md5sig_establish(struct nbr *nbr, struct ldp_auth *auth) | |||
| 371 | { | |||
| 372 | sleep(1); | |||
| 373 | ||||
| 374 | pfkey_md5sig_remove(nbr); | |||
| 375 | ||||
| 376 | if (pfkey_sa_add(nbr->af, &nbr->laddr, &nbr->raddr, | |||
| 377 | auth->md5key_len, auth->md5key, &nbr->auth_spi_out) == -1) | |||
| 378 | return (-1); | |||
| 379 | ||||
| 380 | if (pfkey_sa_add(nbr->af, &nbr->raddr, &nbr->laddr, | |||
| 381 | auth->md5key_len, auth->md5key, &nbr->auth_spi_in) == -1) | |||
| 382 | return (-1); | |||
| 383 | ||||
| 384 | nbr->auth_established = 1; | |||
| 385 | ||||
| 386 | return (0); | |||
| 387 | } | |||
| 388 | ||||
| 389 | static int | |||
| 390 | pfkey_md5sig_remove(struct nbr *nbr) | |||
| 391 | { | |||
| 392 | if (nbr->auth_spi_out) { | |||
| 393 | if (pfkey_sa_remove(nbr->af, &nbr->laddr, &nbr->raddr, | |||
| 394 | &nbr->auth_spi_out) == -1) | |||
| 395 | return (-1); | |||
| 396 | } | |||
| 397 | if (nbr->auth_spi_in) { | |||
| 398 | if (pfkey_sa_remove(nbr->af, &nbr->raddr, &nbr->laddr, | |||
| 399 | &nbr->auth_spi_in) == -1) | |||
| 400 | return (-1); | |||
| 401 | } | |||
| 402 | ||||
| 403 | nbr->auth_established = 0; | |||
| 404 | nbr->auth_spi_in = 0; | |||
| 405 | nbr->auth_spi_out = 0; | |||
| 406 | ||||
| 407 | return (0); | |||
| 408 | } | |||
| 409 | ||||
| 410 | static struct ldp_auth * | |||
| 411 | pfkey_find_auth(struct ldpd_conf *conf, struct nbr *nbr) | |||
| 412 | { | |||
| 413 | struct ldp_auth *auth, *match = NULL((void *)0); | |||
| 414 | ||||
| 415 | LIST_FOREACH(auth, &conf->auth_list, entry)for((auth) = ((&conf->auth_list)->lh_first); (auth) != ((void *)0); (auth) = ((auth)->entry.le_next)) { | |||
| 416 | in_addr_t mask = prefixlen2mask(auth->idlen); | |||
| 417 | if ((auth->id.s_addr & mask) != (nbr->id.s_addr & mask)) | |||
| 418 | continue; | |||
| 419 | ||||
| 420 | if (match == NULL((void *)0) || | |||
| 421 | match->idlen < auth->idlen) | |||
| 422 | match = auth; | |||
| 423 | } | |||
| 424 | ||||
| 425 | return (match); | |||
| 426 | } | |||
| 427 | ||||
| 428 | int | |||
| 429 | pfkey_establish(struct ldpd_conf *conf, struct nbr *nbr) | |||
| 430 | { | |||
| 431 | struct ldp_auth *auth = NULL((void *)0); | |||
| 432 | ||||
| 433 | auth = pfkey_find_auth(conf, nbr); | |||
| 434 | if (auth == NULL((void *)0) || /* no policy */ | |||
| 435 | auth->md5key_len == 0) /* "no tcpmd5 sig" */ | |||
| 436 | return (0); | |||
| 437 | ||||
| 438 | return (pfkey_md5sig_establish(nbr, auth)); | |||
| 439 | } | |||
| 440 | ||||
| 441 | int | |||
| 442 | pfkey_remove(struct nbr *nbr) | |||
| 443 | { | |||
| 444 | return (pfkey_md5sig_remove(nbr)); | |||
| 
 | ||||
| 445 | } | |||
| 446 | ||||
| 447 | int | |||
| 448 | pfkey_init(void) | |||
| 449 | { | |||
| 450 | if ((fd = socket(PF_KEY30, SOCK_RAW3 | SOCK_CLOEXEC0x8000 | SOCK_NONBLOCK0x4000, | |||
| 451 | PF_KEY_V22)) == -1) { | |||
| 452 | if (errno(*__errno()) == EPROTONOSUPPORT43) { | |||
| 453 | log_warnx("PF_KEY not available"); | |||
| 454 | sysdep.no_pfkey = 1; | |||
| 455 | return (-1); | |||
| 456 | } else | |||
| 457 | fatal("pfkey setup failed"); | |||
| 458 | } | |||
| 459 | return (fd); | |||
| 460 | } |