1/* 2 * Copyright (c) 2003-2007 Apple Computer, Inc. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16/* $FreeBSD: src/lib/libipsec/pfkey.c,v 1.1.2.2 2001/07/03 11:01:14 ume Exp $ */ 17/* $KAME: pfkey.c,v 1.39 2001/03/05 18:22:17 thorpej Exp $ */ 18 19/* 20 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 21 * All rights reserved. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the above copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. Neither the name of the project nor the names of its contributors 32 * may be used to endorse or promote products derived from this software 33 * without specific prior written permission. 34 * 35 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 36 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 38 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 39 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 45 * SUCH DAMAGE. 46 */ 47 48#include <sys/types.h> 49#include <sys/param.h> 50#include <sys/socket.h> 51#include <net/pfkeyv2.h> 52#include <netinet/in.h> 53#include <netinet6/ipsec.h> 54 55#include <stdlib.h> 56#include <unistd.h> 57#include <string.h> 58#include <errno.h> 59#include <stdio.h> 60#include <TargetConditionals.h> 61 62#include "ipsec_strerror.h" 63#include "libpfkey.h" 64#include "ipsec_options.h" 65 66#if TARGET_OS_EMBEDDED 67#ifndef MDNS_NO_IPSEC 68#define MDNS_NO_IPSEC 1 69#endif 70#endif 71 72#ifndef MDNS_NO_IPSEC 73 74#define CALLOC(size, cast) (cast)calloc(1, (size)) 75 76static int findsupportedmap __P((int)); 77static int setsupportedmap __P((struct sadb_supported *)); 78static struct sadb_alg *findsupportedalg __P((u_int, u_int)); 79static int pfkey_send_x1 __P((int, u_int, u_int, u_int, struct sockaddr *, 80 struct sockaddr *, u_int32_t, u_int32_t, u_int, caddr_t, 81 u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int32_t, 82 u_int32_t, u_int32_t, u_int32_t)); 83static int pfkey_send_x2 __P((int, u_int, u_int, u_int, 84 struct sockaddr *, struct sockaddr *, u_int32_t)); 85static int pfkey_send_x3 __P((int, u_int, u_int)); 86static int pfkey_send_x4 __P((int, u_int, struct sockaddr *, u_int, 87 struct sockaddr *, u_int, u_int, u_int64_t, u_int64_t, 88 char *, int, u_int32_t)); 89static int pfkey_send_x5 __P((int, u_int, u_int32_t)); 90 91static caddr_t pfkey_setsadbmsg __P((caddr_t, caddr_t, u_int, u_int, 92 u_int, u_int32_t, pid_t)); 93static caddr_t pfkey_setsadbsa __P((caddr_t, caddr_t, u_int32_t, u_int, 94 u_int, u_int, u_int32_t)); 95static caddr_t pfkey_setsadbaddr __P((caddr_t, caddr_t, u_int, 96 struct sockaddr *, u_int, u_int)); 97static caddr_t pfkey_setsadbkey __P((caddr_t, caddr_t, u_int, caddr_t, u_int)); 98static caddr_t pfkey_setsadblifetime __P((caddr_t, caddr_t, u_int, u_int32_t, 99 u_int32_t, u_int32_t, u_int32_t)); 100static caddr_t pfkey_setsadbxsa2 __P((caddr_t, caddr_t, u_int32_t, u_int32_t)); 101 102/* 103 * make and search supported algorithm structure. 104 */ 105static struct sadb_supported *ipsec_supported[] = { NULL, NULL, NULL, }; 106 107static int supported_map[] = { 108 SADB_SATYPE_AH, 109 SADB_SATYPE_ESP, 110 SADB_X_SATYPE_IPCOMP, 111}; 112 113static int 114findsupportedmap(satype) 115int satype; 116{ 117 int i; 118 119 for (i = 0; (unsigned int)i < sizeof(supported_map)/sizeof(supported_map[0]); i++) 120 if (supported_map[i] == satype) 121 return i; 122 return -1; 123} 124 125static struct sadb_alg * 126findsupportedalg(satype, alg_id) 127u_int satype, alg_id; 128{ 129 int algno; 130 int tlen; 131 caddr_t p; 132 133 /* validity check */ 134 algno = findsupportedmap(satype); 135 if (algno == -1) { 136 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 137 return NULL; 138 } 139 if (ipsec_supported[algno] == NULL) { 140 __ipsec_errcode = EIPSEC_DO_GET_SUPP_LIST; 141 return NULL; 142 } 143 144 tlen = ipsec_supported[algno]->sadb_supported_len 145 - sizeof(struct sadb_supported); 146 p = (caddr_t)(ipsec_supported[algno] + 1); 147 while (tlen > 0) { 148 if ((unsigned int)tlen < sizeof(struct sadb_alg)) { 149 /* invalid format */ 150 break; 151 } 152 if (((struct sadb_alg *)p)->sadb_alg_id == alg_id) 153 return (struct sadb_alg *)p; 154 155 tlen -= sizeof(struct sadb_alg); 156 p += sizeof(struct sadb_alg); 157 } 158 159 __ipsec_errcode = EIPSEC_NOT_SUPPORTED; 160 return NULL; 161} 162 163static int 164setsupportedmap(sup) 165struct sadb_supported *sup; 166{ 167 struct sadb_supported **ipsup; 168 169 switch (sup->sadb_supported_exttype) { 170 case SADB_EXT_SUPPORTED_AUTH: 171 ipsup = &ipsec_supported[findsupportedmap(SADB_SATYPE_AH)]; 172 break; 173 case SADB_EXT_SUPPORTED_ENCRYPT: 174 ipsup = &ipsec_supported[findsupportedmap(SADB_SATYPE_ESP)]; 175 break; 176 default: 177 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 178 return -1; 179 } 180 181 if (*ipsup) 182 free(*ipsup); 183 184 *ipsup = malloc(sup->sadb_supported_len); 185 if (!*ipsup) { 186 __ipsec_set_strerror(strerror(errno)); 187 return -1; 188 } 189 memcpy(*ipsup, sup, sup->sadb_supported_len); 190 191 return 0; 192} 193 194/* 195 * check key length against algorithm specified. 196 * This function is called with SADB_EXT_SUPPORTED_{AUTH,ENCRYPT} as the 197 * augument, and only calls to ipsec_check_keylen2(); 198 * keylen is the unit of bit. 199 * OUT: 200 * -1: invalid. 201 * 0: valid. 202 */ 203int 204ipsec_check_keylen(supported, alg_id, keylen) 205u_int supported; 206u_int alg_id; 207u_int keylen; 208{ 209 int satype; 210 211 /* validity check */ 212 switch (supported) { 213 case SADB_EXT_SUPPORTED_AUTH: 214 satype = SADB_SATYPE_AH; 215 break; 216 case SADB_EXT_SUPPORTED_ENCRYPT: 217 satype = SADB_SATYPE_ESP; 218 break; 219 default: 220 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 221 return -1; 222 } 223 224 return ipsec_check_keylen2(satype, alg_id, keylen); 225} 226 227/* 228 * check key length against algorithm specified. 229 * satype is one of satype defined at pfkeyv2.h. 230 * keylen is the unit of bit. 231 * OUT: 232 * -1: invalid. 233 * 0: valid. 234 */ 235int 236ipsec_check_keylen2(satype, alg_id, keylen) 237u_int satype; 238u_int alg_id; 239u_int keylen; 240{ 241 struct sadb_alg *alg; 242 243 alg = findsupportedalg(satype, alg_id); 244 if (!alg) 245 return -1; 246 247 if (keylen < alg->sadb_alg_minbits || keylen > alg->sadb_alg_maxbits) { 248 __ipsec_errcode = EIPSEC_INVAL_KEYLEN; 249 return -1; 250 } 251 252 __ipsec_errcode = EIPSEC_NO_ERROR; 253 return 0; 254} 255 256/* 257 * get max/min key length against algorithm specified. 258 * satype is one of satype defined at pfkeyv2.h. 259 * keylen is the unit of bit. 260 * OUT: 261 * -1: invalid. 262 * 0: valid. 263 */ 264int 265ipsec_get_keylen(supported, alg_id, alg0) 266u_int supported, alg_id; 267struct sadb_alg *alg0; 268{ 269 struct sadb_alg *alg; 270 u_int satype; 271 272 /* validity check */ 273 if (!alg0) { 274 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 275 return -1; 276 } 277 278 switch (supported) { 279 case SADB_EXT_SUPPORTED_AUTH: 280 satype = SADB_SATYPE_AH; 281 break; 282 case SADB_EXT_SUPPORTED_ENCRYPT: 283 satype = SADB_SATYPE_ESP; 284 break; 285 default: 286 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 287 return -1; 288 } 289 290 alg = findsupportedalg(satype, alg_id); 291 if (!alg) 292 return -1; 293 294 memcpy(alg0, alg, sizeof(*alg0)); 295 296 __ipsec_errcode = EIPSEC_NO_ERROR; 297 return 0; 298} 299 300/* 301 * set the rate for SOFT lifetime against HARD one. 302 * If rate is more than 100 or equal to zero, then set to 100. 303 */ 304static u_int soft_lifetime_allocations_rate = PFKEY_SOFT_LIFETIME_RATE; 305static u_int soft_lifetime_bytes_rate = PFKEY_SOFT_LIFETIME_RATE; 306static u_int soft_lifetime_addtime_rate = PFKEY_SOFT_LIFETIME_RATE; 307static u_int soft_lifetime_usetime_rate = PFKEY_SOFT_LIFETIME_RATE; 308 309u_int 310pfkey_set_softrate(type, rate) 311u_int type, rate; 312{ 313 __ipsec_errcode = EIPSEC_NO_ERROR; 314 315 if (rate > 100 || rate == 0) 316 rate = 100; 317 318 switch (type) { 319 case SADB_X_LIFETIME_ALLOCATIONS: 320 soft_lifetime_allocations_rate = rate; 321 return 0; 322 case SADB_X_LIFETIME_BYTES: 323 soft_lifetime_bytes_rate = rate; 324 return 0; 325 case SADB_X_LIFETIME_ADDTIME: 326 soft_lifetime_addtime_rate = rate; 327 return 0; 328 case SADB_X_LIFETIME_USETIME: 329 soft_lifetime_usetime_rate = rate; 330 return 0; 331 } 332 333 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 334 return 1; 335} 336 337/* 338 * get current rate for SOFT lifetime against HARD one. 339 * ATTENTION: ~0 is returned if invalid type was passed. 340 */ 341u_int 342pfkey_get_softrate(type) 343u_int type; 344{ 345 switch (type) { 346 case SADB_X_LIFETIME_ALLOCATIONS: 347 return soft_lifetime_allocations_rate; 348 case SADB_X_LIFETIME_BYTES: 349 return soft_lifetime_bytes_rate; 350 case SADB_X_LIFETIME_ADDTIME: 351 return soft_lifetime_addtime_rate; 352 case SADB_X_LIFETIME_USETIME: 353 return soft_lifetime_usetime_rate; 354 } 355 356 return ~0; 357} 358 359/* 360 * sending SADB_GETSPI message to the kernel. 361 * OUT: 362 * positive: success and return length sent. 363 * -1 : error occured, and set errno. 364 */ 365int 366pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq) 367int so; 368u_int satype, mode; 369struct sockaddr *src, *dst; 370u_int32_t min, max, reqid, seq; 371{ 372 struct sadb_msg *newmsg; 373 caddr_t ep; 374 int len; 375 int need_spirange = 0; 376 caddr_t p; 377 int plen; 378 379 /* validity check */ 380 if (src == NULL || dst == NULL) { 381 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 382 return -1; 383 } 384 if (src->sa_family != dst->sa_family) { 385 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 386 return -1; 387 } 388 if (min > max || (min > 0 && min <= 255)) { 389 __ipsec_errcode = EIPSEC_INVAL_SPI; 390 return -1; 391 } 392 switch (src->sa_family) { 393 case AF_INET: 394 plen = sizeof(struct in_addr) << 3; 395 break; 396 case AF_INET6: 397 plen = sizeof(struct in6_addr) << 3; 398 break; 399 default: 400 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 401 return -1; 402 } 403 404 /* create new sadb_msg to send. */ 405 len = sizeof(struct sadb_msg) 406 + sizeof(struct sadb_x_sa2) 407 + sizeof(struct sadb_address) 408 + PFKEY_ALIGN8(src->sa_len) 409 + sizeof(struct sadb_address) 410 + PFKEY_ALIGN8(dst->sa_len); 411 412 if (min > (u_int32_t)255 && max < (u_int32_t) ~0) { 413 need_spirange++; 414 len += sizeof(struct sadb_spirange); 415 } 416 417 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 418 __ipsec_set_strerror(strerror(errno)); 419 return -1; 420 } 421 ep = ((caddr_t)newmsg) + len; 422 423 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, SADB_GETSPI, 424 len, satype, seq, getpid()); 425 if (!p) { 426 free(newmsg); 427 return -1; 428 } 429 430 p = pfkey_setsadbxsa2(p, ep, mode, reqid); 431 if (!p) { 432 free(newmsg); 433 return -1; 434 } 435 436 /* set sadb_address for source */ 437 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen, 438 IPSEC_ULPROTO_ANY); 439 if (!p) { 440 free(newmsg); 441 return -1; 442 } 443 444 /* set sadb_address for destination */ 445 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen, 446 IPSEC_ULPROTO_ANY); 447 if (!p) { 448 free(newmsg); 449 return -1; 450 } 451 452 /* proccessing spi range */ 453 if (need_spirange) { 454 struct sadb_spirange spirange; 455 456 if (p + sizeof(spirange) > ep) { 457 free(newmsg); 458 return -1; 459 } 460 461 memset(&spirange, 0, sizeof(spirange)); 462 spirange.sadb_spirange_len = PFKEY_UNIT64(sizeof(spirange)); 463 spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE; 464 spirange.sadb_spirange_min = min; 465 spirange.sadb_spirange_max = max; 466 467 memcpy(p, &spirange, sizeof(spirange)); 468 469 p += sizeof(spirange); 470 } 471 if (p != ep) { 472 free(newmsg); 473 return -1; 474 } 475 476 /* send message */ 477 len = pfkey_send(so, newmsg, len); 478 free(newmsg); 479 480 if (len < 0) 481 return -1; 482 483 __ipsec_errcode = EIPSEC_NO_ERROR; 484 return len; 485} 486 487/* 488 * sending SADB_UPDATE message to the kernel. 489 * The length of key material is a_keylen + e_keylen. 490 * OUT: 491 * positive: success and return length sent. 492 * -1 : error occured, and set errno. 493 */ 494int 495pfkey_send_update(so, satype, mode, src, dst, spi, reqid, wsize, 496 keymat, e_type, e_keylen, a_type, a_keylen, flags, 497 l_alloc, l_bytes, l_addtime, l_usetime, seq) 498int so; 499u_int satype, mode, wsize; 500struct sockaddr *src, *dst; 501u_int32_t spi, reqid; 502caddr_t keymat; 503u_int e_type, e_keylen, a_type, a_keylen, flags; 504u_int32_t l_alloc; 505u_int64_t l_bytes, l_addtime, l_usetime; 506u_int32_t seq; 507{ 508 int len; 509 if ((len = pfkey_send_x1(so, SADB_UPDATE, satype, mode, src, dst, spi, 510 reqid, wsize, 511 keymat, e_type, e_keylen, a_type, a_keylen, flags, 512 l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0) 513 return -1; 514 515 return len; 516} 517 518/* 519 * sending SADB_ADD message to the kernel. 520 * The length of key material is a_keylen + e_keylen. 521 * OUT: 522 * positive: success and return length sent. 523 * -1 : error occured, and set errno. 524 */ 525int 526pfkey_send_add(so, satype, mode, src, dst, spi, reqid, wsize, 527 keymat, e_type, e_keylen, a_type, a_keylen, flags, 528 l_alloc, l_bytes, l_addtime, l_usetime, seq) 529int so; 530u_int satype, mode, wsize; 531struct sockaddr *src, *dst; 532u_int32_t spi, reqid; 533caddr_t keymat; 534u_int e_type, e_keylen, a_type, a_keylen, flags; 535u_int32_t l_alloc; 536u_int64_t l_bytes, l_addtime, l_usetime; 537u_int32_t seq; 538{ 539 int len; 540 if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi, 541 reqid, wsize, 542 keymat, e_type, e_keylen, a_type, a_keylen, flags, 543 l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0) 544 return -1; 545 546 return len; 547} 548 549/* 550 * sending SADB_DELETE message to the kernel. 551 * OUT: 552 * positive: success and return length sent. 553 * -1 : error occured, and set errno. 554 */ 555int 556pfkey_send_delete(so, satype, mode, src, dst, spi) 557int so; 558u_int satype, mode; 559struct sockaddr *src, *dst; 560u_int32_t spi; 561{ 562 int len; 563 if ((len = pfkey_send_x2(so, SADB_DELETE, satype, mode, src, dst, spi)) < 0) 564 return -1; 565 566 return len; 567} 568 569/* 570 * sending SADB_DELETE without spi to the kernel. This is 571 * the "delete all" request (an extension also present in 572 * Solaris). 573 * 574 * OUT: 575 * positive: success and return length sent 576 * -1 : error occured, and set errno 577 */ 578int 579pfkey_send_delete_all(so, satype, mode, src, dst) 580int so; 581u_int satype, mode; 582struct sockaddr *src, *dst; 583{ 584 struct sadb_msg *newmsg; 585 int len; 586 caddr_t p; 587 int plen; 588 caddr_t ep; 589 590 (void)mode; 591 592 /* validity check */ 593 if (src == NULL || dst == NULL) { 594 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 595 return -1; 596 } 597 if (src->sa_family != dst->sa_family) { 598 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 599 return -1; 600 } 601 switch (src->sa_family) { 602 case AF_INET: 603 plen = sizeof(struct in_addr) << 3; 604 break; 605 case AF_INET6: 606 plen = sizeof(struct in6_addr) << 3; 607 break; 608 default: 609 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 610 return -1; 611 } 612 613 /* create new sadb_msg to reply. */ 614 len = sizeof(struct sadb_msg) 615 + sizeof(struct sadb_address) 616 + PFKEY_ALIGN8(src->sa_len) 617 + sizeof(struct sadb_address) 618 + PFKEY_ALIGN8(dst->sa_len); 619 620 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 621 __ipsec_set_strerror(strerror(errno)); 622 return -1; 623 } 624 ep = ((caddr_t)newmsg) + len; 625 626 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, SADB_DELETE, len, satype, 0, 627 getpid()); 628 if (!p) { 629 free(newmsg); 630 return -1; 631 } 632 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen, 633 IPSEC_ULPROTO_ANY); 634 if (!p) { 635 free(newmsg); 636 return -1; 637 } 638 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen, 639 IPSEC_ULPROTO_ANY); 640 if (!p || p != ep) { 641 free(newmsg); 642 return -1; 643 } 644 645 /* send message */ 646 len = pfkey_send(so, newmsg, len); 647 free(newmsg); 648 649 if (len < 0) 650 return -1; 651 652 __ipsec_errcode = EIPSEC_NO_ERROR; 653 return len; 654} 655 656/* 657 * sending SADB_GET message to the kernel. 658 * OUT: 659 * positive: success and return length sent. 660 * -1 : error occured, and set errno. 661 */ 662int 663pfkey_send_get(so, satype, mode, src, dst, spi) 664int so; 665u_int satype, mode; 666struct sockaddr *src, *dst; 667u_int32_t spi; 668{ 669 int len; 670 if ((len = pfkey_send_x2(so, SADB_GET, satype, mode, src, dst, spi)) < 0) 671 return -1; 672 673 return len; 674} 675 676/* 677 * sending SADB_REGISTER message to the kernel. 678 * OUT: 679 * positive: success and return length sent. 680 * -1 : error occured, and set errno. 681 */ 682int 683pfkey_send_register(so, satype) 684int so; 685u_int satype; 686{ 687 int len, algno; 688 689 if (satype == PF_UNSPEC) { 690 for (algno = 0; 691 (unsigned int)algno < sizeof(supported_map)/sizeof(supported_map[0]); 692 algno++) { 693 if (ipsec_supported[algno]) { 694 free(ipsec_supported[algno]); 695 ipsec_supported[algno] = NULL; 696 } 697 } 698 } else { 699 algno = findsupportedmap(satype); 700 if (algno == -1) { 701 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 702 return -1; 703 } 704 705 if (ipsec_supported[algno]) { 706 free(ipsec_supported[algno]); 707 ipsec_supported[algno] = NULL; 708 } 709 } 710 711 if ((len = pfkey_send_x3(so, SADB_REGISTER, satype)) < 0) 712 return -1; 713 714 return len; 715} 716 717/* 718 * receiving SADB_REGISTER message from the kernel, and copy buffer for 719 * sadb_supported returned into ipsec_supported. 720 * OUT: 721 * 0: success and return length sent. 722 * -1: error occured, and set errno. 723 */ 724int 725pfkey_recv_register(so) 726int so; 727{ 728 pid_t pid = getpid(); 729 struct sadb_msg *newmsg; 730 int error = -1; 731 732 /* receive message */ 733 do { 734 if ((newmsg = pfkey_recv(so)) == NULL) 735 return -1; 736 } while (newmsg->sadb_msg_type != SADB_REGISTER 737 || (pid_t)newmsg->sadb_msg_pid != pid); 738 739 /* check and fix */ 740 newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len); 741 742 error = pfkey_set_supported(newmsg, newmsg->sadb_msg_len); 743 free(newmsg); 744 745 if (error == 0) 746 __ipsec_errcode = EIPSEC_NO_ERROR; 747 748 return error; 749} 750 751/* 752 * receiving SADB_REGISTER message from the kernel, and copy buffer for 753 * sadb_supported returned into ipsec_supported. 754 * NOTE: sadb_msg_len must be host order. 755 * IN: 756 * tlen: msg length, it's to makeing sure. 757 * OUT: 758 * 0: success and return length sent. 759 * -1: error occured, and set errno. 760 */ 761int 762pfkey_set_supported(msg, tlen) 763struct sadb_msg *msg; 764int tlen; 765{ 766 struct sadb_supported *sup; 767 caddr_t p; 768 caddr_t ep; 769 770 /* validity */ 771 if (msg->sadb_msg_len != tlen) { 772 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 773 return -1; 774 } 775 776 p = (caddr_t)msg; 777 ep = p + tlen; 778 779 p += sizeof(struct sadb_msg); 780 781 while (p < ep) { 782 sup = (struct sadb_supported *)p; 783 if (ep < p + sizeof(*sup) || 784 (size_t)PFKEY_EXTLEN(sup) < sizeof(*sup) || 785 ep < p + sup->sadb_supported_len) { 786 /* invalid format */ 787 break; 788 } 789 790 switch (sup->sadb_supported_exttype) { 791 case SADB_EXT_SUPPORTED_AUTH: 792 case SADB_EXT_SUPPORTED_ENCRYPT: 793 break; 794 default: 795 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 796 return -1; 797 } 798 799 /* fixed length */ 800 sup->sadb_supported_len = PFKEY_EXTLEN(sup); 801 802 /* set supported map */ 803 if (setsupportedmap(sup) != 0) 804 return -1; 805 806 p += sup->sadb_supported_len; 807 } 808 809 if (p != ep) { 810 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 811 return -1; 812 } 813 814 __ipsec_errcode = EIPSEC_NO_ERROR; 815 816 return 0; 817} 818 819/* 820 * sending SADB_FLUSH message to the kernel. 821 * OUT: 822 * positive: success and return length sent. 823 * -1 : error occured, and set errno. 824 */ 825int 826pfkey_send_flush(so, satype) 827int so; 828u_int satype; 829{ 830 int len; 831 832 if ((len = pfkey_send_x3(so, SADB_FLUSH, satype)) < 0) 833 return -1; 834 835 return len; 836} 837 838/* 839 * sending SADB_DUMP message to the kernel. 840 * OUT: 841 * positive: success and return length sent. 842 * -1 : error occured, and set errno. 843 */ 844int 845pfkey_send_dump(so, satype) 846int so; 847u_int satype; 848{ 849 int len; 850 851 if ((len = pfkey_send_x3(so, SADB_DUMP, satype)) < 0) 852 return -1; 853 854 return len; 855} 856 857/* 858 * sending SADB_X_PROMISC message to the kernel. 859 * NOTE that this function handles promisc mode toggle only. 860 * IN: 861 * flag: set promisc off if zero, set promisc on if non-zero. 862 * OUT: 863 * positive: success and return length sent. 864 * -1 : error occured, and set errno. 865 * 0 : error occured, and set errno. 866 * others: a pointer to new allocated buffer in which supported 867 * algorithms is. 868 */ 869int 870pfkey_send_promisc_toggle(so, flag) 871int so; 872int flag; 873{ 874 int len; 875 876 if ((len = pfkey_send_x3(so, SADB_X_PROMISC, (flag ? 1 : 0))) < 0) 877 return -1; 878 879 return len; 880} 881 882/* 883 * sending SADB_X_SPDADD message to the kernel. 884 * OUT: 885 * positive: success and return length sent. 886 * -1 : error occured, and set errno. 887 */ 888int 889pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 890int so; 891struct sockaddr *src, *dst; 892u_int prefs, prefd, proto; 893caddr_t policy; 894int policylen; 895u_int32_t seq; 896{ 897 int len; 898 899 if ((len = pfkey_send_x4(so, SADB_X_SPDADD, 900 src, prefs, dst, prefd, proto, 901 0, 0, 902 policy, policylen, seq)) < 0) 903 return -1; 904 905 return len; 906} 907 908/* 909 * sending SADB_X_SPDADD message to the kernel. 910 * OUT: 911 * positive: success and return length sent. 912 * -1 : error occured, and set errno. 913 */ 914int 915pfkey_send_spdadd2(so, src, prefs, dst, prefd, proto, ltime, vtime, 916 policy, policylen, seq) 917int so; 918struct sockaddr *src, *dst; 919u_int prefs, prefd, proto; 920u_int64_t ltime, vtime; 921caddr_t policy; 922int policylen; 923u_int32_t seq; 924{ 925 int len; 926 927 if ((len = pfkey_send_x4(so, SADB_X_SPDADD, 928 src, prefs, dst, prefd, proto, 929 ltime, vtime, 930 policy, policylen, seq)) < 0) 931 return -1; 932 933 return len; 934} 935 936/* 937 * sending SADB_X_SPDUPDATE message to the kernel. 938 * OUT: 939 * positive: success and return length sent. 940 * -1 : error occured, and set errno. 941 */ 942int 943pfkey_send_spdupdate(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 944int so; 945struct sockaddr *src, *dst; 946u_int prefs, prefd, proto; 947caddr_t policy; 948int policylen; 949u_int32_t seq; 950{ 951 int len; 952 953 if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE, 954 src, prefs, dst, prefd, proto, 955 0, 0, 956 policy, policylen, seq)) < 0) 957 return -1; 958 959 return len; 960} 961 962/* 963 * sending SADB_X_SPDUPDATE message to the kernel. 964 * OUT: 965 * positive: success and return length sent. 966 * -1 : error occured, and set errno. 967 */ 968int 969pfkey_send_spdupdate2(so, src, prefs, dst, prefd, proto, ltime, vtime, 970 policy, policylen, seq) 971int so; 972struct sockaddr *src, *dst; 973u_int prefs, prefd, proto; 974u_int64_t ltime, vtime; 975caddr_t policy; 976int policylen; 977u_int32_t seq; 978{ 979 int len; 980 981 if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE, 982 src, prefs, dst, prefd, proto, 983 ltime, vtime, 984 policy, policylen, seq)) < 0) 985 return -1; 986 987 return len; 988} 989 990/* 991 * sending SADB_X_SPDDELETE message to the kernel. 992 * OUT: 993 * positive: success and return length sent. 994 * -1 : error occured, and set errno. 995 */ 996int 997pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 998int so; 999struct sockaddr *src, *dst; 1000u_int prefs, prefd, proto; 1001caddr_t policy; 1002int policylen; 1003u_int32_t seq; 1004{ 1005 int len; 1006 1007 if (policylen != sizeof(struct sadb_x_policy)) { 1008 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1009 return -1; 1010 } 1011 1012 if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE, 1013 src, prefs, dst, prefd, proto, 1014 0, 0, 1015 policy, policylen, seq)) < 0) 1016 return -1; 1017 1018 return len; 1019} 1020 1021/* 1022 * sending SADB_X_SPDDELETE message to the kernel. 1023 * OUT: 1024 * positive: success and return length sent. 1025 * -1 : error occured, and set errno. 1026 */ 1027int 1028pfkey_send_spddelete2(so, spid) 1029int so; 1030u_int32_t spid; 1031{ 1032 int len; 1033 1034 if ((len = pfkey_send_x5(so, SADB_X_SPDDELETE2, spid)) < 0) 1035 return -1; 1036 1037 return len; 1038} 1039 1040/* 1041 * sending SADB_X_SPDGET message to the kernel. 1042 * OUT: 1043 * positive: success and return length sent. 1044 * -1 : error occured, and set errno. 1045 */ 1046int 1047pfkey_send_spdget(so, spid) 1048int so; 1049u_int32_t spid; 1050{ 1051 int len; 1052 1053 if ((len = pfkey_send_x5(so, SADB_X_SPDGET, spid)) < 0) 1054 return -1; 1055 1056 return len; 1057} 1058 1059/* 1060 * sending SADB_X_SPDSETIDX message to the kernel. 1061 * OUT: 1062 * positive: success and return length sent. 1063 * -1 : error occured, and set errno. 1064 */ 1065int 1066pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq) 1067int so; 1068struct sockaddr *src, *dst; 1069u_int prefs, prefd, proto; 1070caddr_t policy; 1071int policylen; 1072u_int32_t seq; 1073{ 1074 int len; 1075 1076 if (policylen != sizeof(struct sadb_x_policy)) { 1077 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1078 return -1; 1079 } 1080 1081 if ((len = pfkey_send_x4(so, SADB_X_SPDSETIDX, 1082 src, prefs, dst, prefd, proto, 1083 0, 0, 1084 policy, policylen, seq)) < 0) 1085 return -1; 1086 1087 return len; 1088} 1089 1090/* 1091 * sending SADB_SPDFLUSH message to the kernel. 1092 * OUT: 1093 * positive: success and return length sent. 1094 * -1 : error occured, and set errno. 1095 */ 1096int 1097pfkey_send_spdflush(so) 1098int so; 1099{ 1100 int len; 1101 1102 if ((len = pfkey_send_x3(so, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC)) < 0) 1103 return -1; 1104 1105 return len; 1106} 1107 1108/* 1109 * sending SADB_SPDDUMP message to the kernel. 1110 * OUT: 1111 * positive: success and return length sent. 1112 * -1 : error occured, and set errno. 1113 */ 1114int 1115pfkey_send_spddump(so) 1116int so; 1117{ 1118 int len; 1119 1120 if ((len = pfkey_send_x3(so, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC)) < 0) 1121 return -1; 1122 1123 return len; 1124} 1125 1126/* sending SADB_ADD or SADB_UPDATE message to the kernel */ 1127static int 1128pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize, 1129 keymat, e_type, e_keylen, a_type, a_keylen, flags, 1130 l_alloc, l_bytes, l_addtime, l_usetime, seq) 1131int so; 1132u_int type, satype, mode; 1133struct sockaddr *src, *dst; 1134u_int32_t spi, reqid; 1135u_int wsize; 1136caddr_t keymat; 1137u_int e_type, e_keylen, a_type, a_keylen, flags; 1138u_int32_t l_alloc, l_bytes, l_addtime, l_usetime, seq; 1139{ 1140 struct sadb_msg *newmsg; 1141 int len; 1142 caddr_t p; 1143 int plen; 1144 caddr_t ep; 1145 1146 /* validity check */ 1147 if (src == NULL || dst == NULL) { 1148 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1149 return -1; 1150 } 1151 if (src->sa_family != dst->sa_family) { 1152 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1153 return -1; 1154 } 1155 switch (src->sa_family) { 1156 case AF_INET: 1157 plen = sizeof(struct in_addr) << 3; 1158 break; 1159 case AF_INET6: 1160 plen = sizeof(struct in6_addr) << 3; 1161 break; 1162 default: 1163 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1164 return -1; 1165 } 1166 1167 switch (satype) { 1168 case SADB_SATYPE_ESP: 1169 if (e_type == SADB_EALG_NONE) { 1170 __ipsec_errcode = EIPSEC_NO_ALGS; 1171 return -1; 1172 } 1173 break; 1174 case SADB_SATYPE_AH: 1175 if (e_type != SADB_EALG_NONE) { 1176 __ipsec_errcode = EIPSEC_INVAL_ALGS; 1177 return -1; 1178 } 1179 if (a_type == SADB_AALG_NONE) { 1180 __ipsec_errcode = EIPSEC_NO_ALGS; 1181 return -1; 1182 } 1183 break; 1184 case SADB_X_SATYPE_IPCOMP: 1185 if (e_type == SADB_X_CALG_NONE) { 1186 __ipsec_errcode = EIPSEC_INVAL_ALGS; 1187 return -1; 1188 } 1189 if (a_type != SADB_AALG_NONE) { 1190 __ipsec_errcode = EIPSEC_NO_ALGS; 1191 return -1; 1192 } 1193 break; 1194 default: 1195 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1196 return -1; 1197 } 1198 1199 /* create new sadb_msg to reply. */ 1200 len = sizeof(struct sadb_msg) 1201 + sizeof(struct sadb_sa) 1202 + sizeof(struct sadb_x_sa2) 1203 + sizeof(struct sadb_address) 1204 + PFKEY_ALIGN8(src->sa_len) 1205 + sizeof(struct sadb_address) 1206 + PFKEY_ALIGN8(dst->sa_len) 1207 + sizeof(struct sadb_lifetime) 1208 + sizeof(struct sadb_lifetime); 1209 1210 if (e_type != SADB_EALG_NONE) 1211 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen)); 1212 if (a_type != SADB_AALG_NONE) 1213 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(a_keylen)); 1214 1215 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 1216 __ipsec_set_strerror(strerror(errno)); 1217 return -1; 1218 } 1219 ep = ((caddr_t)newmsg) + len; 1220 1221 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, 1222 satype, seq, getpid()); 1223 if (!p) { 1224 free(newmsg); 1225 return -1; 1226 } 1227 p = pfkey_setsadbsa(p, ep, spi, wsize, a_type, e_type, flags); 1228 if (!p) { 1229 free(newmsg); 1230 return -1; 1231 } 1232 p = pfkey_setsadbxsa2(p, ep, mode, reqid); 1233 if (!p) { 1234 free(newmsg); 1235 return -1; 1236 } 1237 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen, 1238 IPSEC_ULPROTO_ANY); 1239 if (!p) { 1240 free(newmsg); 1241 return -1; 1242 } 1243 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen, 1244 IPSEC_ULPROTO_ANY); 1245 if (!p) { 1246 free(newmsg); 1247 return -1; 1248 } 1249 1250 if (e_type != SADB_EALG_NONE) { 1251 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_ENCRYPT, 1252 keymat, e_keylen); 1253 if (!p) { 1254 free(newmsg); 1255 return -1; 1256 } 1257 } 1258 if (a_type != SADB_AALG_NONE) { 1259 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_AUTH, 1260 keymat + e_keylen, a_keylen); 1261 if (!p) { 1262 free(newmsg); 1263 return -1; 1264 } 1265 } 1266 1267 /* set sadb_lifetime for destination */ 1268 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD, 1269 l_alloc, l_bytes, l_addtime, l_usetime); 1270 if (!p) { 1271 free(newmsg); 1272 return -1; 1273 } 1274 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_SOFT, 1275 l_alloc, l_bytes, l_addtime, l_usetime); 1276 if (!p || p != ep) { 1277 free(newmsg); 1278 return -1; 1279 } 1280 1281 /* send message */ 1282 len = pfkey_send(so, newmsg, len); 1283 free(newmsg); 1284 1285 if (len < 0) 1286 return -1; 1287 1288 __ipsec_errcode = EIPSEC_NO_ERROR; 1289 return len; 1290} 1291 1292/* sending SADB_DELETE or SADB_GET message to the kernel */ 1293static int 1294pfkey_send_x2(so, type, satype, mode, src, dst, spi) 1295int so; 1296u_int type, satype, mode; 1297struct sockaddr *src, *dst; 1298u_int32_t spi; 1299{ 1300 struct sadb_msg *newmsg; 1301 int len; 1302 caddr_t p; 1303 int plen; 1304 caddr_t ep; 1305 1306 (void)mode; 1307 1308 /* validity check */ 1309 if (src == NULL || dst == NULL) { 1310 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1311 return -1; 1312 } 1313 if (src->sa_family != dst->sa_family) { 1314 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1315 return -1; 1316 } 1317 switch (src->sa_family) { 1318 case AF_INET: 1319 plen = sizeof(struct in_addr) << 3; 1320 break; 1321 case AF_INET6: 1322 plen = sizeof(struct in6_addr) << 3; 1323 break; 1324 default: 1325 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1326 return -1; 1327 } 1328 1329 /* create new sadb_msg to reply. */ 1330 len = sizeof(struct sadb_msg) 1331 + sizeof(struct sadb_sa) 1332 + sizeof(struct sadb_address) 1333 + PFKEY_ALIGN8(src->sa_len) 1334 + sizeof(struct sadb_address) 1335 + PFKEY_ALIGN8(dst->sa_len); 1336 1337 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 1338 __ipsec_set_strerror(strerror(errno)); 1339 return -1; 1340 } 1341 ep = ((caddr_t)newmsg) + len; 1342 1343 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, satype, 0, 1344 getpid()); 1345 if (!p) { 1346 free(newmsg); 1347 return -1; 1348 } 1349 p = pfkey_setsadbsa(p, ep, spi, 0, 0, 0, 0); 1350 if (!p) { 1351 free(newmsg); 1352 return -1; 1353 } 1354 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen, 1355 IPSEC_ULPROTO_ANY); 1356 if (!p) { 1357 free(newmsg); 1358 return -1; 1359 } 1360 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen, 1361 IPSEC_ULPROTO_ANY); 1362 if (!p || p != ep) { 1363 free(newmsg); 1364 return -1; 1365 } 1366 1367 /* send message */ 1368 len = pfkey_send(so, newmsg, len); 1369 free(newmsg); 1370 1371 if (len < 0) 1372 return -1; 1373 1374 __ipsec_errcode = EIPSEC_NO_ERROR; 1375 return len; 1376} 1377 1378/* 1379 * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message 1380 * to the kernel 1381 */ 1382static int 1383pfkey_send_x3(so, type, satype) 1384int so; 1385u_int type, satype; 1386{ 1387 struct sadb_msg *newmsg; 1388 int len; 1389 caddr_t p; 1390 caddr_t ep; 1391 1392 /* validity check */ 1393 switch (type) { 1394 case SADB_X_PROMISC: 1395 if (satype != 0 && satype != 1) { 1396 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1397 return -1; 1398 } 1399 break; 1400 default: 1401 switch (satype) { 1402 case SADB_SATYPE_UNSPEC: 1403 case SADB_SATYPE_AH: 1404 case SADB_SATYPE_ESP: 1405 case SADB_X_SATYPE_IPCOMP: 1406 break; 1407 default: 1408 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1409 return -1; 1410 } 1411 } 1412 1413 /* create new sadb_msg to send. */ 1414 len = sizeof(struct sadb_msg); 1415 1416 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 1417 __ipsec_set_strerror(strerror(errno)); 1418 return -1; 1419 } 1420 ep = ((caddr_t)newmsg) + len; 1421 1422 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, satype, 0, 1423 getpid()); 1424 if (!p || p != ep) { 1425 free(newmsg); 1426 return -1; 1427 } 1428 1429 /* send message */ 1430 len = pfkey_send(so, newmsg, len); 1431 free(newmsg); 1432 1433 if (len < 0) 1434 return -1; 1435 1436 __ipsec_errcode = EIPSEC_NO_ERROR; 1437 return len; 1438} 1439 1440/* sending SADB_X_SPDADD message to the kernel */ 1441static int 1442pfkey_send_x4(so, type, src, prefs, dst, prefd, proto, 1443 ltime, vtime, policy, policylen, seq) 1444int so; 1445struct sockaddr *src, *dst; 1446u_int type, prefs, prefd, proto; 1447u_int64_t ltime, vtime; 1448char *policy; 1449int policylen; 1450u_int32_t seq; 1451{ 1452 struct sadb_msg *newmsg; 1453 int len; 1454 caddr_t p; 1455 int plen; 1456 caddr_t ep; 1457 1458 /* validity check */ 1459 if (src == NULL || dst == NULL) { 1460 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1461 return -1; 1462 } 1463 if (src->sa_family != dst->sa_family) { 1464 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1465 return -1; 1466 } 1467 1468 switch (src->sa_family) { 1469 case AF_INET: 1470 plen = sizeof(struct in_addr) << 3; 1471 break; 1472 case AF_INET6: 1473 plen = sizeof(struct in6_addr) << 3; 1474 break; 1475 default: 1476 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1477 return -1; 1478 } 1479 if (prefs > (u_int)plen || prefd > (u_int)plen) { 1480 __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN; 1481 return -1; 1482 } 1483 1484 /* create new sadb_msg to reply. */ 1485 len = sizeof(struct sadb_msg) 1486 + sizeof(struct sadb_address) 1487 + PFKEY_ALIGN8(src->sa_len) 1488 + sizeof(struct sadb_address) 1489 + PFKEY_ALIGN8(src->sa_len) 1490 + sizeof(struct sadb_lifetime) 1491 + policylen; 1492 1493 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 1494 __ipsec_set_strerror(strerror(errno)); 1495 return -1; 1496 } 1497 ep = ((caddr_t)newmsg) + len; 1498 1499 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, 1500 SADB_SATYPE_UNSPEC, seq, getpid()); 1501 if (!p) { 1502 free(newmsg); 1503 return -1; 1504 } 1505 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, prefs, proto); 1506 if (!p) { 1507 free(newmsg); 1508 return -1; 1509 } 1510 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, prefd, proto); 1511 if (!p) { 1512 free(newmsg); 1513 return -1; 1514 } 1515 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD, 1516 0, 0, ltime, vtime); 1517 if (!p || p + policylen != ep) { 1518 free(newmsg); 1519 return -1; 1520 } 1521 memcpy(p, policy, policylen); 1522 1523 /* send message */ 1524 len = pfkey_send(so, newmsg, len); 1525 free(newmsg); 1526 1527 if (len < 0) 1528 return -1; 1529 1530 __ipsec_errcode = EIPSEC_NO_ERROR; 1531 return len; 1532} 1533 1534/* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */ 1535static int 1536pfkey_send_x5(so, type, spid) 1537int so; 1538u_int type; 1539u_int32_t spid; 1540{ 1541 struct sadb_msg *newmsg; 1542 struct sadb_x_policy xpl; 1543 int len; 1544 caddr_t p; 1545 caddr_t ep; 1546 1547 /* create new sadb_msg to reply. */ 1548 len = sizeof(struct sadb_msg) 1549 + sizeof(xpl); 1550 1551 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) { 1552 __ipsec_set_strerror(strerror(errno)); 1553 return -1; 1554 } 1555 ep = ((caddr_t)newmsg) + len; 1556 1557 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, 1558 SADB_SATYPE_UNSPEC, 0, getpid()); 1559 if (!p) { 1560 free(newmsg); 1561 return -1; 1562 } 1563 1564 if (p + sizeof(xpl) != ep) { 1565 free(newmsg); 1566 return -1; 1567 } 1568 memset(&xpl, 0, sizeof(xpl)); 1569 xpl.sadb_x_policy_len = PFKEY_UNUNIT64(sizeof(xpl)); 1570 xpl.sadb_x_policy_exttype = SADB_X_EXT_POLICY; 1571 xpl.sadb_x_policy_id = spid; 1572 memcpy(p, &xpl, sizeof(xpl)); 1573 1574 /* send message */ 1575 len = pfkey_send(so, newmsg, len); 1576 free(newmsg); 1577 1578 if (len < 0) 1579 return -1; 1580 1581 __ipsec_errcode = EIPSEC_NO_ERROR; 1582 return len; 1583} 1584 1585/* 1586 * open a socket. 1587 * OUT: 1588 * -1: fail. 1589 * others : success and return value of socket. 1590 */ 1591int 1592pfkey_open() 1593{ 1594 int so; 1595 const int bufsiz = 128 * 1024; /*is 128K enough?*/ 1596 1597 if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) { 1598 __ipsec_set_strerror(strerror(errno)); 1599 return -1; 1600 } 1601 1602 /* 1603 * This is a temporary workaround for KAME PR 154. 1604 * Don't really care even if it fails. 1605 */ 1606 (void)setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz)); 1607 (void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz)); 1608 1609 __ipsec_errcode = EIPSEC_NO_ERROR; 1610 return so; 1611} 1612 1613/* 1614 * close a socket. 1615 * OUT: 1616 * 0: success. 1617 * -1: fail. 1618 */ 1619void 1620pfkey_close(so) 1621int so; 1622{ 1623 (void)close(so); 1624 1625 __ipsec_errcode = EIPSEC_NO_ERROR; 1626 return; 1627} 1628 1629/* 1630 * receive sadb_msg data, and return pointer to new buffer allocated. 1631 * Must free this buffer later. 1632 * OUT: 1633 * NULL : error occured. 1634 * others : a pointer to sadb_msg structure. 1635 * 1636 * XXX should be rewritten to pass length explicitly 1637 */ 1638struct sadb_msg * 1639pfkey_recv(so) 1640int so; 1641{ 1642 struct sadb_msg buf, *newmsg; 1643 int len, reallen; 1644 1645 while ((len = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK)) < 0) { 1646 if (errno == EINTR) 1647 continue; 1648 __ipsec_set_strerror(strerror(errno)); 1649 return NULL; 1650 } 1651 1652 if ((size_t)len < sizeof(buf)) { 1653 recv(so, (caddr_t)&buf, sizeof(buf), 0); 1654 __ipsec_errcode = EIPSEC_MAX; 1655 return NULL; 1656 } 1657 1658 /* read real message */ 1659 reallen = PFKEY_UNUNIT64(buf.sadb_msg_len); 1660 if ((newmsg = CALLOC(reallen, struct sadb_msg *)) == 0) { 1661 __ipsec_set_strerror(strerror(errno)); 1662 return NULL; 1663 } 1664 1665 while ((len = recv(so, (caddr_t)newmsg, reallen, 0)) < 0) { 1666 if (errno == EINTR) 1667 continue; 1668 __ipsec_set_strerror(strerror(errno)); 1669 free(newmsg); 1670 return NULL; 1671 } 1672 1673 if (len != reallen) { 1674 __ipsec_errcode = EIPSEC_SYSTEM_ERROR; 1675 free(newmsg); 1676 return NULL; 1677 } 1678 1679 /* don't trust what the kernel says, validate! */ 1680 if (PFKEY_UNUNIT64(newmsg->sadb_msg_len) != len) { 1681 __ipsec_errcode = EIPSEC_SYSTEM_ERROR; 1682 free(newmsg); 1683 return NULL; 1684 } 1685 1686 __ipsec_errcode = EIPSEC_NO_ERROR; 1687 return newmsg; 1688} 1689 1690/* 1691 * send message to a socket. 1692 * OUT: 1693 * others: success and return length sent. 1694 * -1 : fail. 1695 */ 1696int 1697pfkey_send(so, msg, len) 1698int so; 1699struct sadb_msg *msg; 1700int len; 1701{ 1702 if ((len = send(so, (caddr_t)msg, len, 0)) < 0) { 1703 __ipsec_set_strerror(strerror(errno)); 1704 return -1; 1705 } 1706 1707 __ipsec_errcode = EIPSEC_NO_ERROR; 1708 return len; 1709} 1710 1711/* 1712 * %%% Utilities 1713 * NOTE: These functions are derived from netkey/key.c in KAME. 1714 */ 1715/* 1716 * set the pointer to each header in this message buffer. 1717 * IN: msg: pointer to message buffer. 1718 * mhp: pointer to the buffer initialized like below: 1719 * caddr_t mhp[SADB_EXT_MAX + 1]; 1720 * OUT: -1: invalid. 1721 * 0: valid. 1722 * 1723 * XXX should be rewritten to obtain length explicitly 1724 */ 1725int 1726pfkey_align(msg, mhp) 1727struct sadb_msg *msg; 1728caddr_t *mhp; 1729{ 1730 struct sadb_ext *ext; 1731 int i; 1732 caddr_t p; 1733 caddr_t ep; /* XXX should be passed from upper layer */ 1734 1735 /* validity check */ 1736 if (msg == NULL || mhp == NULL) { 1737 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1738 return -1; 1739 } 1740 1741 /* initialize */ 1742 for (i = 0; i < SADB_EXT_MAX + 1; i++) 1743 mhp[i] = NULL; 1744 1745 mhp[0] = (caddr_t)msg; 1746 1747 /* initialize */ 1748 p = (caddr_t) msg; 1749 ep = p + PFKEY_UNUNIT64(msg->sadb_msg_len); 1750 1751 /* skip base header */ 1752 p += sizeof(struct sadb_msg); 1753 1754 while (p < ep) { 1755 ext = (struct sadb_ext *)p; 1756 if (ep < p + sizeof(*ext) || (size_t)PFKEY_EXTLEN(ext) < sizeof(*ext) || 1757 ep < p + PFKEY_EXTLEN(ext)) { 1758 /* invalid format */ 1759 break; 1760 } 1761 1762 /* duplicate check */ 1763 /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/ 1764 if (mhp[ext->sadb_ext_type] != NULL) { 1765 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; 1766 return -1; 1767 } 1768 1769 /* set pointer */ 1770 switch (ext->sadb_ext_type) { 1771 case SADB_EXT_SA: 1772 case SADB_EXT_LIFETIME_CURRENT: 1773 case SADB_EXT_LIFETIME_HARD: 1774 case SADB_EXT_LIFETIME_SOFT: 1775 case SADB_EXT_ADDRESS_SRC: 1776 case SADB_EXT_ADDRESS_DST: 1777 case SADB_EXT_ADDRESS_PROXY: 1778 case SADB_EXT_KEY_AUTH: 1779 /* XXX should to be check weak keys. */ 1780 case SADB_EXT_KEY_ENCRYPT: 1781 /* XXX should to be check weak keys. */ 1782 case SADB_EXT_IDENTITY_SRC: 1783 case SADB_EXT_IDENTITY_DST: 1784 case SADB_EXT_SENSITIVITY: 1785 case SADB_EXT_PROPOSAL: 1786 case SADB_EXT_SUPPORTED_AUTH: 1787 case SADB_EXT_SUPPORTED_ENCRYPT: 1788 case SADB_EXT_SPIRANGE: 1789 case SADB_X_EXT_POLICY: 1790 case SADB_X_EXT_SA2: 1791 mhp[ext->sadb_ext_type] = (caddr_t)ext; 1792 break; 1793 default: 1794 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE; 1795 return -1; 1796 } 1797 1798 p += PFKEY_EXTLEN(ext); 1799 } 1800 1801 if (p != ep) { 1802 __ipsec_errcode = EIPSEC_INVAL_SADBMSG; 1803 return -1; 1804 } 1805 1806 __ipsec_errcode = EIPSEC_NO_ERROR; 1807 return 0; 1808} 1809 1810/* 1811 * check basic usage for sadb_msg, 1812 * NOTE: This routine is derived from netkey/key.c in KAME. 1813 * IN: msg: pointer to message buffer. 1814 * mhp: pointer to the buffer initialized like below: 1815 * 1816 * caddr_t mhp[SADB_EXT_MAX + 1]; 1817 * 1818 * OUT: -1: invalid. 1819 * 0: valid. 1820 */ 1821int 1822pfkey_check(mhp) 1823caddr_t *mhp; 1824{ 1825 struct sadb_msg *msg; 1826 1827 /* validity check */ 1828 if (mhp == NULL || mhp[0] == NULL) { 1829 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; 1830 return -1; 1831 } 1832 1833 msg = (struct sadb_msg *)mhp[0]; 1834 1835 /* check version */ 1836 if (msg->sadb_msg_version != PF_KEY_V2) { 1837 __ipsec_errcode = EIPSEC_INVAL_VERSION; 1838 return -1; 1839 } 1840 1841 /* check type */ 1842 if (msg->sadb_msg_type > SADB_MAX) { 1843 __ipsec_errcode = EIPSEC_INVAL_MSGTYPE; 1844 return -1; 1845 } 1846 1847 /* check SA type */ 1848 switch (msg->sadb_msg_satype) { 1849 case SADB_SATYPE_UNSPEC: 1850 switch (msg->sadb_msg_type) { 1851 case SADB_GETSPI: 1852 case SADB_UPDATE: 1853 case SADB_ADD: 1854 case SADB_DELETE: 1855 case SADB_GET: 1856 case SADB_ACQUIRE: 1857 case SADB_EXPIRE: 1858 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1859 return -1; 1860 } 1861 break; 1862 case SADB_SATYPE_ESP: 1863 case SADB_SATYPE_AH: 1864 case SADB_X_SATYPE_IPCOMP: 1865 switch (msg->sadb_msg_type) { 1866 case SADB_X_SPDADD: 1867 case SADB_X_SPDDELETE: 1868 case SADB_X_SPDGET: 1869 case SADB_X_SPDDUMP: 1870 case SADB_X_SPDFLUSH: 1871 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1872 return -1; 1873 } 1874 break; 1875 case SADB_SATYPE_RSVP: 1876 case SADB_SATYPE_OSPFV2: 1877 case SADB_SATYPE_RIPV2: 1878 case SADB_SATYPE_MIP: 1879 __ipsec_errcode = EIPSEC_NOT_SUPPORTED; 1880 return -1; 1881 case 1: /* XXX: What does it do ? */ 1882 if (msg->sadb_msg_type == SADB_X_PROMISC) 1883 break; 1884 /*FALLTHROUGH*/ 1885 default: 1886 __ipsec_errcode = EIPSEC_INVAL_SATYPE; 1887 return -1; 1888 } 1889 1890 /* check field of upper layer protocol and address family */ 1891 if (mhp[SADB_EXT_ADDRESS_SRC] != NULL 1892 && mhp[SADB_EXT_ADDRESS_DST] != NULL) { 1893 struct sadb_address *src0, *dst0; 1894 1895 src0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_SRC]); 1896 dst0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]); 1897 1898 if (src0->sadb_address_proto != dst0->sadb_address_proto) { 1899 __ipsec_errcode = EIPSEC_PROTO_MISMATCH; 1900 return -1; 1901 } 1902 1903 if (PFKEY_ADDR_SADDR(src0)->sa_family 1904 != PFKEY_ADDR_SADDR(dst0)->sa_family) { 1905 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH; 1906 return -1; 1907 } 1908 1909 switch (PFKEY_ADDR_SADDR(src0)->sa_family) { 1910 case AF_INET: 1911 case AF_INET6: 1912 break; 1913 default: 1914 __ipsec_errcode = EIPSEC_INVAL_FAMILY; 1915 return -1; 1916 } 1917 1918 /* 1919 * prefixlen == 0 is valid because there must be the case 1920 * all addresses are matched. 1921 */ 1922 } 1923 1924 __ipsec_errcode = EIPSEC_NO_ERROR; 1925 return 0; 1926} 1927 1928/* 1929 * set data into sadb_msg. 1930 * `buf' must has been allocated sufficiently. 1931 */ 1932static caddr_t 1933pfkey_setsadbmsg(buf, lim, type, tlen, satype, seq, pid) 1934caddr_t buf; 1935caddr_t lim; 1936u_int type, satype; 1937u_int tlen; 1938u_int32_t seq; 1939pid_t pid; 1940{ 1941 struct sadb_msg *p; 1942 u_int len; 1943 1944 p = (struct sadb_msg *)buf; 1945 len = sizeof(struct sadb_msg); 1946 1947 if (buf + len > lim) 1948 return NULL; 1949 1950 memset(p, 0, len); 1951 p->sadb_msg_version = PF_KEY_V2; 1952 p->sadb_msg_type = type; 1953 p->sadb_msg_errno = 0; 1954 p->sadb_msg_satype = satype; 1955 p->sadb_msg_len = PFKEY_UNIT64(tlen); 1956 p->sadb_msg_reserved = 0; 1957 p->sadb_msg_seq = seq; 1958 p->sadb_msg_pid = (u_int32_t)pid; 1959 1960 return(buf + len); 1961} 1962 1963/* 1964 * copy secasvar data into sadb_address. 1965 * `buf' must has been allocated sufficiently. 1966 */ 1967static caddr_t 1968pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags) 1969caddr_t buf; 1970caddr_t lim; 1971u_int32_t spi, flags; 1972u_int wsize, auth, enc; 1973{ 1974 struct sadb_sa *p; 1975 u_int len; 1976 1977 p = (struct sadb_sa *)buf; 1978 len = sizeof(struct sadb_sa); 1979 1980 if (buf + len > lim) 1981 return NULL; 1982 1983 memset(p, 0, len); 1984 p->sadb_sa_len = PFKEY_UNIT64(len); 1985 p->sadb_sa_exttype = SADB_EXT_SA; 1986 p->sadb_sa_spi = spi; 1987 p->sadb_sa_replay = wsize; 1988 p->sadb_sa_state = SADB_SASTATE_LARVAL; 1989 p->sadb_sa_auth = auth; 1990 p->sadb_sa_encrypt = enc; 1991 p->sadb_sa_flags = flags; 1992 1993 return(buf + len); 1994} 1995 1996/* 1997 * set data into sadb_address. 1998 * `buf' must has been allocated sufficiently. 1999 * prefixlen is in bits. 2000 */ 2001static caddr_t 2002pfkey_setsadbaddr(buf, lim, exttype, saddr, prefixlen, ul_proto) 2003caddr_t buf; 2004caddr_t lim; 2005u_int exttype; 2006struct sockaddr *saddr; 2007u_int prefixlen; 2008u_int ul_proto; 2009{ 2010 struct sadb_address *p; 2011 u_int len; 2012 2013 p = (struct sadb_address *)buf; 2014 len = sizeof(struct sadb_address) + PFKEY_ALIGN8(saddr->sa_len); 2015 2016 if (buf + len > lim) 2017 return NULL; 2018 2019 memset(p, 0, len); 2020 p->sadb_address_len = PFKEY_UNIT64(len); 2021 p->sadb_address_exttype = exttype & 0xffff; 2022 p->sadb_address_proto = ul_proto & 0xff; 2023 p->sadb_address_prefixlen = prefixlen; 2024 p->sadb_address_reserved = 0; 2025 2026 memcpy(p + 1, saddr, saddr->sa_len); 2027 2028 return(buf + len); 2029} 2030 2031/* 2032 * set sadb_key structure after clearing buffer with zero. 2033 * OUT: the pointer of buf + len. 2034 */ 2035static caddr_t 2036pfkey_setsadbkey(buf, lim, type, key, keylen) 2037caddr_t buf; 2038caddr_t lim; 2039caddr_t key; 2040u_int type, keylen; 2041{ 2042 struct sadb_key *p; 2043 u_int len; 2044 2045 p = (struct sadb_key *)buf; 2046 len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen); 2047 2048 if (buf + len > lim) 2049 return NULL; 2050 2051 memset(p, 0, len); 2052 p->sadb_key_len = PFKEY_UNIT64(len); 2053 p->sadb_key_exttype = type; 2054 p->sadb_key_bits = keylen << 3; 2055 p->sadb_key_reserved = 0; 2056 2057 memcpy(p + 1, key, keylen); 2058 2059 return buf + len; 2060} 2061 2062/* 2063 * set sadb_lifetime structure after clearing buffer with zero. 2064 * OUT: the pointer of buf + len. 2065 */ 2066static caddr_t 2067pfkey_setsadblifetime(buf, lim, type, l_alloc, l_bytes, l_addtime, l_usetime) 2068caddr_t buf; 2069caddr_t lim; 2070u_int type; 2071u_int32_t l_alloc, l_bytes, l_addtime, l_usetime; 2072{ 2073 struct sadb_lifetime *p; 2074 u_int len; 2075 2076 p = (struct sadb_lifetime *)buf; 2077 len = sizeof(struct sadb_lifetime); 2078 2079 if (buf + len > lim) 2080 return NULL; 2081 2082 memset(p, 0, len); 2083 p->sadb_lifetime_len = PFKEY_UNIT64(len); 2084 p->sadb_lifetime_exttype = type; 2085 2086 switch (type) { 2087 case SADB_EXT_LIFETIME_SOFT: 2088 p->sadb_lifetime_allocations 2089 = (l_alloc * soft_lifetime_allocations_rate) /100; 2090 p->sadb_lifetime_bytes 2091 = (l_bytes * soft_lifetime_bytes_rate) /100; 2092 p->sadb_lifetime_addtime 2093 = (l_addtime * soft_lifetime_addtime_rate) /100; 2094 p->sadb_lifetime_usetime 2095 = (l_usetime * soft_lifetime_usetime_rate) /100; 2096 break; 2097 case SADB_EXT_LIFETIME_HARD: 2098 p->sadb_lifetime_allocations = l_alloc; 2099 p->sadb_lifetime_bytes = l_bytes; 2100 p->sadb_lifetime_addtime = l_addtime; 2101 p->sadb_lifetime_usetime = l_usetime; 2102 break; 2103 } 2104 2105 return buf + len; 2106} 2107 2108/* 2109 * copy secasvar data into sadb_address. 2110 * `buf' must has been allocated sufficiently. 2111 */ 2112static caddr_t 2113pfkey_setsadbxsa2(buf, lim, mode0, reqid) 2114caddr_t buf; 2115caddr_t lim; 2116u_int32_t mode0; 2117u_int32_t reqid; 2118{ 2119 struct sadb_x_sa2 *p; 2120 u_int8_t mode = mode0 & 0xff; 2121 u_int len; 2122 2123 p = (struct sadb_x_sa2 *)buf; 2124 len = sizeof(struct sadb_x_sa2); 2125 2126 if (buf + len > lim) 2127 return NULL; 2128 2129 memset(p, 0, len); 2130 p->sadb_x_sa2_len = PFKEY_UNIT64(len); 2131 p->sadb_x_sa2_exttype = SADB_X_EXT_SA2; 2132 p->sadb_x_sa2_mode = mode; 2133 p->sadb_x_sa2_reqid = reqid; 2134 2135 return(buf + len); 2136} 2137 2138#endif /* ndef MDNS_NO_IPSEC */ 2139