1 /* $FreeBSD$ */ 2 /* $KAME: parse.y,v 1.81 2003/07/01 04:01:48 itojun Exp $ */ 3 4 /* 5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 %{ 34 #include <sys/types.h> 35 #include <sys/param.h> 36 #include <sys/socket.h> 37 38 #include <net/route.h> 39 #include <netinet/in.h> 40 #include <net/pfkeyv2.h> 41 #include <netkey/key_var.h> 42 #include <netinet6/ipsec.h> 43 #include <arpa/inet.h> 44 45 #include <string.h> 46 #include <unistd.h> 47 #include <stdio.h> 48 #include <netdb.h> 49 #include <ctype.h> 50 #include <errno.h> 51 52 #include "libpfkey.h" 53 #include "vchar.h" 54 55 #define ATOX(c) \ 56 (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10))) 57 58 u_int32_t p_spi; 59 u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode; 60 u_int32_t p_reqid; 61 u_int p_key_enc_len, p_key_auth_len; 62 caddr_t p_key_enc, p_key_auth; 63 time_t p_lt_hard, p_lt_soft; 64 65 static int p_aiflags = 0, p_aifamily = PF_UNSPEC; 66 67 static struct addrinfo *parse_addr __P((char *, char *)); 68 static int fix_portstr __P((vchar_t *, vchar_t *, vchar_t *)); 69 static int setvarbuf __P((char *, int *, struct sadb_ext *, int, caddr_t, int)); 70 void parse_init __P((void)); 71 void free_buffer __P((void)); 72 73 int setkeymsg0 __P((struct sadb_msg *, unsigned int, unsigned int, size_t)); 74 static int setkeymsg_spdaddr __P((unsigned int, unsigned int, vchar_t *, 75 struct addrinfo *, int, struct addrinfo *, int)); 76 static int setkeymsg_addr __P((unsigned int, unsigned int, 77 struct addrinfo *, struct addrinfo *, int)); 78 static int setkeymsg_add __P((unsigned int, unsigned int, 79 struct addrinfo *, struct addrinfo *)); 80 extern int setkeymsg __P((char *, size_t *)); 81 extern int sendkeymsg __P((char *, size_t)); 82 83 extern int yylex __P((void)); 84 extern void yyfatal __P((const char *)); 85 extern void yyerror __P((const char *)); 86 %} 87 88 %union { 89 int num; 90 unsigned long ulnum; 91 vchar_t val; 92 struct addrinfo *res; 93 } 94 95 %token EOT SLASH BLCL ELCL 96 %token ADD GET DELETE DELETEALL FLUSH DUMP 97 %token PR_ESP PR_AH PR_IPCOMP 98 %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI 99 %token F_MODE MODE F_REQID 100 %token F_EXT EXTENSION NOCYCLICSEQ 101 %token ALG_AUTH ALG_AUTH_NOKEY 102 %token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD 103 %token ALG_COMP 104 %token F_LIFETIME_HARD F_LIFETIME_SOFT 105 %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY 106 /* SPD management */ 107 %token SPDADD SPDDELETE SPDDUMP SPDFLUSH 108 %token F_POLICY PL_REQUESTS 109 %token F_AIFLAGS 110 %token TAGGED 111 112 %type <num> prefix protocol_spec upper_spec 113 %type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY 114 %type <num> ALG_AUTH ALG_AUTH_NOKEY 115 %type <num> ALG_COMP 116 %type <num> PR_ESP PR_AH PR_IPCOMP 117 %type <num> EXTENSION MODE 118 %type <ulnum> DECSTRING 119 %type <val> PL_REQUESTS portstr key_string 120 %type <val> policy_requests 121 %type <val> QUOTEDSTRING HEXSTRING STRING 122 %type <val> F_AIFLAGS 123 %type <val> upper_misc_spec policy_spec 124 %type <res> ipaddr 125 126 %% 127 commands 128 : /*NOTHING*/ 129 | commands command 130 { 131 free_buffer(); 132 parse_init(); 133 } 134 ; 135 136 command 137 : add_command 138 | get_command 139 | delete_command 140 | deleteall_command 141 | flush_command 142 | dump_command 143 | spdadd_command 144 | spddelete_command 145 | spddump_command 146 | spdflush_command 147 ; 148 /* commands concerned with management, there is in tail of this file. */ 149 150 /* add command */ 151 add_command 152 : ADD ipaddropts ipaddr ipaddr protocol_spec spi extension_spec algorithm_spec EOT 153 { 154 int status; 155 156 status = setkeymsg_add(SADB_ADD, $5, $3, $4); 157 if (status < 0) 158 return -1; 159 } 160 ; 161 162 /* delete */ 163 delete_command 164 : DELETE ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT 165 { 166 int status; 167 168 if ($3->ai_next || $4->ai_next) { 169 yyerror("multiple address specified"); 170 return -1; 171 } 172 if (p_mode != IPSEC_MODE_ANY) 173 yyerror("WARNING: mode is obsolete"); 174 175 status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0); 176 if (status < 0) 177 return -1; 178 } 179 ; 180 181 /* deleteall command */ 182 deleteall_command 183 : DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT 184 { 185 int status; 186 187 status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1); 188 if (status < 0) 189 return -1; 190 } 191 ; 192 193 /* get command */ 194 get_command 195 : GET ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT 196 { 197 int status; 198 199 if (p_mode != IPSEC_MODE_ANY) 200 yyerror("WARNING: mode is obsolete"); 201 202 status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0); 203 if (status < 0) 204 return -1; 205 } 206 ; 207 208 /* flush */ 209 flush_command 210 : FLUSH protocol_spec EOT 211 { 212 struct sadb_msg msg; 213 setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg)); 214 sendkeymsg((char *)&msg, sizeof(msg)); 215 } 216 ; 217 218 /* dump */ 219 dump_command 220 : DUMP protocol_spec EOT 221 { 222 struct sadb_msg msg; 223 setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg)); 224 sendkeymsg((char *)&msg, sizeof(msg)); 225 } 226 ; 227 228 protocol_spec 229 : /*NOTHING*/ 230 { 231 $$ = SADB_SATYPE_UNSPEC; 232 } 233 | PR_ESP 234 { 235 $$ = SADB_SATYPE_ESP; 236 if ($1 == 1) 237 p_ext |= SADB_X_EXT_OLD; 238 else 239 p_ext &= ~SADB_X_EXT_OLD; 240 } 241 | PR_AH 242 { 243 $$ = SADB_SATYPE_AH; 244 if ($1 == 1) 245 p_ext |= SADB_X_EXT_OLD; 246 else 247 p_ext &= ~SADB_X_EXT_OLD; 248 } 249 | PR_IPCOMP 250 { 251 $$ = SADB_X_SATYPE_IPCOMP; 252 } 253 ; 254 255 spi 256 : DECSTRING { p_spi = $1; } 257 | HEXSTRING 258 { 259 char *ep; 260 unsigned long v; 261 262 ep = NULL; 263 v = strtoul($1.buf, &ep, 16); 264 if (!ep || *ep) { 265 yyerror("invalid SPI"); 266 return -1; 267 } 268 if (v & ~0xffffffff) { 269 yyerror("SPI too big."); 270 return -1; 271 } 272 273 p_spi = v; 274 } 275 ; 276 277 algorithm_spec 278 : esp_spec 279 | ah_spec 280 | ipcomp_spec 281 ; 282 283 esp_spec 284 : F_ENC enc_alg F_AUTH auth_alg 285 | F_ENC enc_alg 286 ; 287 288 ah_spec 289 : F_AUTH auth_alg 290 ; 291 292 ipcomp_spec 293 : F_COMP ALG_COMP 294 { 295 if ($2 < 0) { 296 yyerror("unsupported algorithm"); 297 return -1; 298 } 299 p_alg_enc = $2; 300 } 301 | F_COMP ALG_COMP F_RAWCPI 302 { 303 if ($2 < 0) { 304 yyerror("unsupported algorithm"); 305 return -1; 306 } 307 p_alg_enc = $2; 308 p_ext |= SADB_X_EXT_RAWCPI; 309 } 310 ; 311 312 enc_alg 313 : ALG_ENC_NOKEY { 314 if ($1 < 0) { 315 yyerror("unsupported algorithm"); 316 return -1; 317 } 318 p_alg_enc = $1; 319 320 p_key_enc_len = 0; 321 p_key_enc = NULL; 322 } 323 | ALG_ENC key_string { 324 if ($1 < 0) { 325 yyerror("unsupported algorithm"); 326 return -1; 327 } 328 p_alg_enc = $1; 329 330 p_key_enc_len = $2.len; 331 p_key_enc = $2.buf; 332 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 333 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 334 yyerror(ipsec_strerror()); 335 return -1; 336 } 337 } 338 | ALG_ENC_OLD { 339 if ($1 < 0) { 340 yyerror("unsupported algorithm"); 341 return -1; 342 } 343 yyerror("WARNING: obsolete algorithm"); 344 p_alg_enc = $1; 345 346 p_key_enc_len = 0; 347 p_key_enc = NULL; 348 } 349 | ALG_ENC_DESDERIV key_string 350 { 351 if ($1 < 0) { 352 yyerror("unsupported algorithm"); 353 return -1; 354 } 355 p_alg_enc = $1; 356 if (p_ext & SADB_X_EXT_OLD) { 357 yyerror("algorithm mismatched"); 358 return -1; 359 } 360 p_ext |= SADB_X_EXT_DERIV; 361 362 p_key_enc_len = $2.len; 363 p_key_enc = $2.buf; 364 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 365 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 366 yyerror(ipsec_strerror()); 367 return -1; 368 } 369 } 370 | ALG_ENC_DES32IV key_string 371 { 372 if ($1 < 0) { 373 yyerror("unsupported algorithm"); 374 return -1; 375 } 376 p_alg_enc = $1; 377 if (!(p_ext & SADB_X_EXT_OLD)) { 378 yyerror("algorithm mismatched"); 379 return -1; 380 } 381 p_ext |= SADB_X_EXT_IV4B; 382 383 p_key_enc_len = $2.len; 384 p_key_enc = $2.buf; 385 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 386 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 387 yyerror(ipsec_strerror()); 388 return -1; 389 } 390 } 391 ; 392 393 auth_alg 394 : ALG_AUTH key_string { 395 if ($1 < 0) { 396 yyerror("unsupported algorithm"); 397 return -1; 398 } 399 p_alg_auth = $1; 400 401 p_key_auth_len = $2.len; 402 p_key_auth = $2.buf; 403 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, 404 p_alg_auth, PFKEY_UNUNIT64(p_key_auth_len)) < 0) { 405 yyerror(ipsec_strerror()); 406 return -1; 407 } 408 } 409 | ALG_AUTH_NOKEY { 410 if ($1 < 0) { 411 yyerror("unsupported algorithm"); 412 return -1; 413 } 414 p_alg_auth = $1; 415 416 p_key_auth_len = 0; 417 p_key_auth = NULL; 418 } 419 ; 420 421 key_string 422 : QUOTEDSTRING 423 { 424 $$ = $1; 425 } 426 | HEXSTRING 427 { 428 caddr_t pp_key; 429 caddr_t bp; 430 caddr_t yp = $1.buf; 431 int l; 432 433 l = strlen(yp) % 2 + strlen(yp) / 2; 434 if ((pp_key = malloc(l)) == 0) { 435 yyerror("not enough core"); 436 return -1; 437 } 438 memset(pp_key, 0, l); 439 440 bp = pp_key; 441 if (strlen(yp) % 2) { 442 *bp = ATOX(yp[0]); 443 yp++, bp++; 444 } 445 while (*yp) { 446 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); 447 yp += 2, bp++; 448 } 449 450 $$.len = l; 451 $$.buf = pp_key; 452 } 453 ; 454 455 extension_spec 456 : /*NOTHING*/ 457 | extension_spec extension 458 ; 459 460 extension 461 : F_EXT EXTENSION { p_ext |= $2; } 462 | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; } 463 | F_MODE MODE { p_mode = $2; } 464 | F_MODE ANY { p_mode = IPSEC_MODE_ANY; } 465 | F_REQID DECSTRING { p_reqid = $2; } 466 | F_REPLAY DECSTRING 467 { 468 if ((p_ext & SADB_X_EXT_OLD) != 0) { 469 yyerror("replay prevention cannot be used with " 470 "ah/esp-old"); 471 return -1; 472 } 473 p_replay = $2; 474 } 475 | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; } 476 | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; } 477 ; 478 479 /* definition about command for SPD management */ 480 /* spdadd */ 481 spdadd_command 482 : SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT 483 { 484 int status; 485 struct addrinfo *src, *dst; 486 487 /* fixed port fields if ulp is icmpv6 */ 488 if ($10.buf != NULL) { 489 if ($9 != IPPROTO_ICMPV6) 490 return -1; 491 free($5.buf); 492 free($8.buf); 493 if (fix_portstr(&$10, &$5, &$8)) 494 return -1; 495 } 496 497 src = parse_addr($3.buf, $5.buf); 498 dst = parse_addr($6.buf, $8.buf); 499 if (!src || !dst) { 500 /* yyerror is already called */ 501 return -1; 502 } 503 if (src->ai_next || dst->ai_next) { 504 yyerror("multiple address specified"); 505 freeaddrinfo(src); 506 freeaddrinfo(dst); 507 return -1; 508 } 509 510 status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$11, 511 src, $4, dst, $7); 512 freeaddrinfo(src); 513 freeaddrinfo(dst); 514 if (status < 0) 515 return -1; 516 } 517 | SPDADD TAGGED QUOTEDSTRING policy_spec EOT 518 { 519 return -1; 520 } 521 ; 522 523 spddelete_command 524 : SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT 525 { 526 int status; 527 struct addrinfo *src, *dst; 528 529 /* fixed port fields if ulp is icmpv6 */ 530 if ($10.buf != NULL) { 531 if ($9 != IPPROTO_ICMPV6) 532 return -1; 533 free($5.buf); 534 free($8.buf); 535 if (fix_portstr(&$10, &$5, &$8)) 536 return -1; 537 } 538 539 src = parse_addr($3.buf, $5.buf); 540 dst = parse_addr($6.buf, $8.buf); 541 if (!src || !dst) { 542 /* yyerror is already called */ 543 return -1; 544 } 545 if (src->ai_next || dst->ai_next) { 546 yyerror("multiple address specified"); 547 freeaddrinfo(src); 548 freeaddrinfo(dst); 549 return -1; 550 } 551 552 status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$11, 553 src, $4, dst, $7); 554 freeaddrinfo(src); 555 freeaddrinfo(dst); 556 if (status < 0) 557 return -1; 558 } 559 ; 560 561 spddump_command: 562 SPDDUMP EOT 563 { 564 struct sadb_msg msg; 565 setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC, 566 sizeof(msg)); 567 sendkeymsg((char *)&msg, sizeof(msg)); 568 } 569 ; 570 571 spdflush_command: 572 SPDFLUSH EOT 573 { 574 struct sadb_msg msg; 575 setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC, 576 sizeof(msg)); 577 sendkeymsg((char *)&msg, sizeof(msg)); 578 } 579 ; 580 581 ipaddropts 582 : /* nothing */ 583 | ipaddropts ipaddropt 584 ; 585 586 ipaddropt 587 : F_AIFLAGS 588 { 589 char *p; 590 591 for (p = $1.buf + 1; *p; p++) 592 switch (*p) { 593 case '4': 594 p_aifamily = AF_INET; 595 break; 596 #ifdef INET6 597 case '6': 598 p_aifamily = AF_INET6; 599 break; 600 #endif 601 case 'n': 602 p_aiflags = AI_NUMERICHOST; 603 break; 604 default: 605 yyerror("invalid flag"); 606 return -1; 607 } 608 } 609 ; 610 611 ipaddr 612 : STRING 613 { 614 $$ = parse_addr($1.buf, NULL); 615 if ($$ == NULL) { 616 /* yyerror already called by parse_addr */ 617 return -1; 618 } 619 } 620 ; 621 622 prefix 623 : /*NOTHING*/ { $$ = -1; } 624 | SLASH DECSTRING { $$ = $2; } 625 ; 626 627 portstr 628 : /*NOTHING*/ 629 { 630 $$.buf = strdup("0"); 631 if (!$$.buf) { 632 yyerror("insufficient memory"); 633 return -1; 634 } 635 $$.len = strlen($$.buf); 636 } 637 | BLCL ANY ELCL 638 { 639 $$.buf = strdup("0"); 640 if (!$$.buf) { 641 yyerror("insufficient memory"); 642 return -1; 643 } 644 $$.len = strlen($$.buf); 645 } 646 | BLCL DECSTRING ELCL 647 { 648 char buf[20]; 649 snprintf(buf, sizeof(buf), "%lu", $2); 650 $$.buf = strdup(buf); 651 if (!$$.buf) { 652 yyerror("insufficient memory"); 653 return -1; 654 } 655 $$.len = strlen($$.buf); 656 } 657 | BLCL STRING ELCL 658 { 659 $$ = $2; 660 } 661 ; 662 663 upper_spec 664 : DECSTRING { $$ = $1; } 665 | ANY { $$ = IPSEC_ULPROTO_ANY; } 666 | STRING 667 { 668 struct protoent *ent; 669 670 ent = getprotobyname($1.buf); 671 if (ent) 672 $$ = ent->p_proto; 673 else { 674 if (strcmp("icmp6", $1.buf) == 0) { 675 $$ = IPPROTO_ICMPV6; 676 } else if(strcmp("ip4", $1.buf) == 0) { 677 $$ = IPPROTO_IPV4; 678 } else { 679 yyerror("invalid upper layer protocol"); 680 return -1; 681 } 682 } 683 endprotoent(); 684 } 685 ; 686 687 upper_misc_spec 688 : /*NOTHING*/ 689 { 690 $$.buf = NULL; 691 $$.len = 0; 692 } 693 | STRING 694 { 695 $$.buf = strdup($1.buf); 696 if (!$$.buf) { 697 yyerror("insufficient memory"); 698 return -1; 699 } 700 $$.len = strlen($$.buf); 701 } 702 ; 703 704 policy_spec 705 : F_POLICY policy_requests 706 { 707 char *policy; 708 709 policy = ipsec_set_policy($2.buf, $2.len); 710 if (policy == NULL) { 711 yyerror(ipsec_strerror()); 712 return -1; 713 } 714 715 $$.buf = policy; 716 $$.len = ipsec_get_policylen(policy); 717 } 718 ; 719 720 policy_requests 721 : PL_REQUESTS { $$ = $1; } 722 ; 723 724 %% 725 726 int 727 setkeymsg0(msg, type, satype, l) 728 struct sadb_msg *msg; 729 unsigned int type; 730 unsigned int satype; 731 size_t l; 732 { 733 734 msg->sadb_msg_version = PF_KEY_V2; 735 msg->sadb_msg_type = type; 736 msg->sadb_msg_errno = 0; 737 msg->sadb_msg_satype = satype; 738 msg->sadb_msg_reserved = 0; 739 msg->sadb_msg_seq = 0; 740 msg->sadb_msg_pid = getpid(); 741 msg->sadb_msg_len = PFKEY_UNIT64(l); 742 return 0; 743 } 744 745 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 746 static int 747 setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen) 748 unsigned int type; 749 unsigned int upper; 750 vchar_t *policy; 751 struct addrinfo *srcs; 752 int splen; 753 struct addrinfo *dsts; 754 int dplen; 755 { 756 struct sadb_msg *msg; 757 char buf[BUFSIZ]; 758 int l, l0; 759 struct sadb_address m_addr; 760 struct addrinfo *s, *d; 761 int n; 762 int plen; 763 struct sockaddr *sa; 764 int salen; 765 766 msg = (struct sadb_msg *)buf; 767 768 if (!srcs || !dsts) 769 return -1; 770 771 /* fix up length afterwards */ 772 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0); 773 l = sizeof(struct sadb_msg); 774 775 memcpy(buf + l, policy->buf, policy->len); 776 l += policy->len; 777 778 l0 = l; 779 n = 0; 780 781 /* do it for all src/dst pairs */ 782 for (s = srcs; s; s = s->ai_next) { 783 for (d = dsts; d; d = d->ai_next) { 784 /* rewind pointer */ 785 l = l0; 786 787 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 788 continue; 789 switch (s->ai_addr->sa_family) { 790 case AF_INET: 791 plen = sizeof(struct in_addr) << 3; 792 break; 793 #ifdef INET6 794 case AF_INET6: 795 plen = sizeof(struct in6_addr) << 3; 796 break; 797 #endif 798 default: 799 continue; 800 } 801 802 /* set src */ 803 sa = s->ai_addr; 804 salen = s->ai_addr->sa_len; 805 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 806 PFKEY_ALIGN8(salen)); 807 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 808 m_addr.sadb_address_proto = upper; 809 m_addr.sadb_address_prefixlen = 810 (splen >= 0 ? splen : plen); 811 m_addr.sadb_address_reserved = 0; 812 813 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 814 sizeof(m_addr), (caddr_t)sa, salen); 815 816 /* set dst */ 817 sa = d->ai_addr; 818 salen = d->ai_addr->sa_len; 819 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 820 PFKEY_ALIGN8(salen)); 821 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 822 m_addr.sadb_address_proto = upper; 823 m_addr.sadb_address_prefixlen = 824 (dplen >= 0 ? dplen : plen); 825 m_addr.sadb_address_reserved = 0; 826 827 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 828 sizeof(m_addr), (caddr_t)sa, salen); 829 830 msg->sadb_msg_len = PFKEY_UNIT64(l); 831 832 sendkeymsg(buf, l); 833 834 n++; 835 } 836 } 837 838 if (n == 0) 839 return -1; 840 else 841 return 0; 842 } 843 844 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 845 static int 846 setkeymsg_addr(type, satype, srcs, dsts, no_spi) 847 unsigned int type; 848 unsigned int satype; 849 struct addrinfo *srcs; 850 struct addrinfo *dsts; 851 int no_spi; 852 { 853 struct sadb_msg *msg; 854 char buf[BUFSIZ]; 855 int l, l0, len; 856 struct sadb_sa m_sa; 857 struct sadb_x_sa2 m_sa2; 858 struct sadb_address m_addr; 859 struct addrinfo *s, *d; 860 int n; 861 int plen; 862 struct sockaddr *sa; 863 int salen; 864 865 msg = (struct sadb_msg *)buf; 866 867 if (!srcs || !dsts) 868 return -1; 869 870 /* fix up length afterwards */ 871 setkeymsg0(msg, type, satype, 0); 872 l = sizeof(struct sadb_msg); 873 874 if (!no_spi) { 875 len = sizeof(struct sadb_sa); 876 m_sa.sadb_sa_len = PFKEY_UNIT64(len); 877 m_sa.sadb_sa_exttype = SADB_EXT_SA; 878 m_sa.sadb_sa_spi = htonl(p_spi); 879 m_sa.sadb_sa_replay = p_replay; 880 m_sa.sadb_sa_state = 0; 881 m_sa.sadb_sa_auth = p_alg_auth; 882 m_sa.sadb_sa_encrypt = p_alg_enc; 883 m_sa.sadb_sa_flags = p_ext; 884 885 memcpy(buf + l, &m_sa, len); 886 l += len; 887 888 len = sizeof(struct sadb_x_sa2); 889 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 890 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 891 m_sa2.sadb_x_sa2_mode = p_mode; 892 m_sa2.sadb_x_sa2_reqid = p_reqid; 893 894 memcpy(buf + l, &m_sa2, len); 895 l += len; 896 } 897 898 l0 = l; 899 n = 0; 900 901 /* do it for all src/dst pairs */ 902 for (s = srcs; s; s = s->ai_next) { 903 for (d = dsts; d; d = d->ai_next) { 904 /* rewind pointer */ 905 l = l0; 906 907 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 908 continue; 909 switch (s->ai_addr->sa_family) { 910 case AF_INET: 911 plen = sizeof(struct in_addr) << 3; 912 break; 913 #ifdef INET6 914 case AF_INET6: 915 plen = sizeof(struct in6_addr) << 3; 916 break; 917 #endif 918 default: 919 continue; 920 } 921 922 /* set src */ 923 sa = s->ai_addr; 924 salen = s->ai_addr->sa_len; 925 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 926 PFKEY_ALIGN8(salen)); 927 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 928 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 929 m_addr.sadb_address_prefixlen = plen; 930 m_addr.sadb_address_reserved = 0; 931 932 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 933 sizeof(m_addr), (caddr_t)sa, salen); 934 935 /* set dst */ 936 sa = d->ai_addr; 937 salen = d->ai_addr->sa_len; 938 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 939 PFKEY_ALIGN8(salen)); 940 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 941 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 942 m_addr.sadb_address_prefixlen = plen; 943 m_addr.sadb_address_reserved = 0; 944 945 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 946 sizeof(m_addr), (caddr_t)sa, salen); 947 948 msg->sadb_msg_len = PFKEY_UNIT64(l); 949 950 sendkeymsg(buf, l); 951 952 n++; 953 } 954 } 955 956 if (n == 0) 957 return -1; 958 else 959 return 0; 960 } 961 962 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 963 static int 964 setkeymsg_add(type, satype, srcs, dsts) 965 unsigned int type; 966 unsigned int satype; 967 struct addrinfo *srcs; 968 struct addrinfo *dsts; 969 { 970 struct sadb_msg *msg; 971 char buf[BUFSIZ]; 972 int l, l0, len; 973 struct sadb_sa m_sa; 974 struct sadb_x_sa2 m_sa2; 975 struct sadb_address m_addr; 976 struct addrinfo *s, *d; 977 int n; 978 int plen; 979 struct sockaddr *sa; 980 int salen; 981 982 msg = (struct sadb_msg *)buf; 983 984 if (!srcs || !dsts) 985 return -1; 986 987 /* fix up length afterwards */ 988 setkeymsg0(msg, type, satype, 0); 989 l = sizeof(struct sadb_msg); 990 991 /* set encryption algorithm, if present. */ 992 if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) { 993 struct sadb_key m_key; 994 995 m_key.sadb_key_len = 996 PFKEY_UNIT64(sizeof(m_key) 997 + PFKEY_ALIGN8(p_key_enc_len)); 998 m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; 999 m_key.sadb_key_bits = p_key_enc_len * 8; 1000 m_key.sadb_key_reserved = 0; 1001 1002 setvarbuf(buf, &l, 1003 (struct sadb_ext *)&m_key, sizeof(m_key), 1004 (caddr_t)p_key_enc, p_key_enc_len); 1005 } 1006 1007 /* set authentication algorithm, if present. */ 1008 if (p_key_auth) { 1009 struct sadb_key m_key; 1010 1011 m_key.sadb_key_len = 1012 PFKEY_UNIT64(sizeof(m_key) 1013 + PFKEY_ALIGN8(p_key_auth_len)); 1014 m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH; 1015 m_key.sadb_key_bits = p_key_auth_len * 8; 1016 m_key.sadb_key_reserved = 0; 1017 1018 setvarbuf(buf, &l, 1019 (struct sadb_ext *)&m_key, sizeof(m_key), 1020 (caddr_t)p_key_auth, p_key_auth_len); 1021 } 1022 1023 /* set lifetime for HARD */ 1024 if (p_lt_hard != 0) { 1025 struct sadb_lifetime m_lt; 1026 u_int slen = sizeof(struct sadb_lifetime); 1027 1028 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); 1029 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; 1030 m_lt.sadb_lifetime_allocations = 0; 1031 m_lt.sadb_lifetime_bytes = 0; 1032 m_lt.sadb_lifetime_addtime = p_lt_hard; 1033 m_lt.sadb_lifetime_usetime = 0; 1034 1035 memcpy(buf + l, &m_lt, slen); 1036 l += len; 1037 } 1038 1039 /* set lifetime for SOFT */ 1040 if (p_lt_soft != 0) { 1041 struct sadb_lifetime m_lt; 1042 u_int slen = sizeof(struct sadb_lifetime); 1043 1044 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); 1045 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; 1046 m_lt.sadb_lifetime_allocations = 0; 1047 m_lt.sadb_lifetime_bytes = 0; 1048 m_lt.sadb_lifetime_addtime = p_lt_soft; 1049 m_lt.sadb_lifetime_usetime = 0; 1050 1051 memcpy(buf + l, &m_lt, slen); 1052 l += len; 1053 } 1054 1055 len = sizeof(struct sadb_sa); 1056 m_sa.sadb_sa_len = PFKEY_UNIT64(len); 1057 m_sa.sadb_sa_exttype = SADB_EXT_SA; 1058 m_sa.sadb_sa_spi = htonl(p_spi); 1059 m_sa.sadb_sa_replay = p_replay; 1060 m_sa.sadb_sa_state = 0; 1061 m_sa.sadb_sa_auth = p_alg_auth; 1062 m_sa.sadb_sa_encrypt = p_alg_enc; 1063 m_sa.sadb_sa_flags = p_ext; 1064 1065 memcpy(buf + l, &m_sa, len); 1066 l += len; 1067 1068 len = sizeof(struct sadb_x_sa2); 1069 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 1070 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 1071 m_sa2.sadb_x_sa2_mode = p_mode; 1072 m_sa2.sadb_x_sa2_reqid = p_reqid; 1073 1074 memcpy(buf + l, &m_sa2, len); 1075 l += len; 1076 1077 l0 = l; 1078 n = 0; 1079 1080 /* do it for all src/dst pairs */ 1081 for (s = srcs; s; s = s->ai_next) { 1082 for (d = dsts; d; d = d->ai_next) { 1083 /* rewind pointer */ 1084 l = l0; 1085 1086 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 1087 continue; 1088 switch (s->ai_addr->sa_family) { 1089 case AF_INET: 1090 plen = sizeof(struct in_addr) << 3; 1091 break; 1092 #ifdef INET6 1093 case AF_INET6: 1094 plen = sizeof(struct in6_addr) << 3; 1095 break; 1096 #endif 1097 default: 1098 continue; 1099 } 1100 1101 /* set src */ 1102 sa = s->ai_addr; 1103 salen = s->ai_addr->sa_len; 1104 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1105 PFKEY_ALIGN8(salen)); 1106 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 1107 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1108 m_addr.sadb_address_prefixlen = plen; 1109 m_addr.sadb_address_reserved = 0; 1110 1111 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1112 sizeof(m_addr), (caddr_t)sa, salen); 1113 1114 /* set dst */ 1115 sa = d->ai_addr; 1116 salen = d->ai_addr->sa_len; 1117 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1118 PFKEY_ALIGN8(salen)); 1119 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 1120 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1121 m_addr.sadb_address_prefixlen = plen; 1122 m_addr.sadb_address_reserved = 0; 1123 1124 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1125 sizeof(m_addr), (caddr_t)sa, salen); 1126 1127 msg->sadb_msg_len = PFKEY_UNIT64(l); 1128 1129 sendkeymsg(buf, l); 1130 1131 n++; 1132 } 1133 } 1134 1135 if (n == 0) 1136 return -1; 1137 else 1138 return 0; 1139 } 1140 1141 static struct addrinfo * 1142 parse_addr(host, port) 1143 char *host; 1144 char *port; 1145 { 1146 struct addrinfo hints, *res = NULL; 1147 int error; 1148 1149 memset(&hints, 0, sizeof(hints)); 1150 hints.ai_family = p_aifamily; 1151 hints.ai_socktype = SOCK_DGRAM; /*dummy*/ 1152 hints.ai_protocol = IPPROTO_UDP; /*dummy*/ 1153 hints.ai_flags = p_aiflags; 1154 error = getaddrinfo(host, port, &hints, &res); 1155 if (error != 0) { 1156 yyerror(gai_strerror(error)); 1157 return NULL; 1158 } 1159 return res; 1160 } 1161 1162 static int 1163 fix_portstr(spec, sport, dport) 1164 vchar_t *spec, *sport, *dport; 1165 { 1166 char *p, *p2; 1167 u_int l; 1168 1169 l = 0; 1170 for (p = spec->buf; *p != ',' && *p != '\0' && l < spec->len; p++, l++) 1171 ; 1172 if (*p == '\0') { 1173 p2 = "0"; 1174 } else { 1175 if (*p == ',') { 1176 *p = '\0'; 1177 p2 = ++p; 1178 } 1179 for (p = p2; *p != '\0' && l < spec->len; p++, l++) 1180 ; 1181 if (*p != '\0' || *p2 == '\0') { 1182 yyerror("invalid an upper layer protocol spec"); 1183 return -1; 1184 } 1185 } 1186 1187 sport->buf = strdup(spec->buf); 1188 if (!sport->buf) { 1189 yyerror("insufficient memory"); 1190 return -1; 1191 } 1192 sport->len = strlen(sport->buf); 1193 dport->buf = strdup(p2); 1194 if (!dport->buf) { 1195 yyerror("insufficient memory"); 1196 return -1; 1197 } 1198 dport->len = strlen(dport->buf); 1199 1200 return 0; 1201 } 1202 1203 static int 1204 setvarbuf(buf, off, ebuf, elen, vbuf, vlen) 1205 char *buf; 1206 int *off; 1207 struct sadb_ext *ebuf; 1208 int elen; 1209 caddr_t vbuf; 1210 int vlen; 1211 { 1212 memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len)); 1213 memcpy(buf + *off, (caddr_t)ebuf, elen); 1214 memcpy(buf + *off + elen, vbuf, vlen); 1215 (*off) += PFKEY_ALIGN8(elen + vlen); 1216 1217 return 0; 1218 } 1219 1220 void 1221 parse_init() 1222 { 1223 p_spi = 0; 1224 1225 p_ext = SADB_X_EXT_CYCSEQ; 1226 p_alg_enc = SADB_EALG_NONE; 1227 p_alg_auth = SADB_AALG_NONE; 1228 p_mode = IPSEC_MODE_ANY; 1229 p_reqid = 0; 1230 p_replay = 0; 1231 p_key_enc_len = p_key_auth_len = 0; 1232 p_key_enc = p_key_auth = 0; 1233 p_lt_hard = p_lt_soft = 0; 1234 1235 p_aiflags = 0; 1236 p_aifamily = PF_UNSPEC; 1237 1238 return; 1239 } 1240 1241 void 1242 free_buffer() 1243 { 1244 /* we got tons of memory leaks in the parser anyways, leave them */ 1245 1246 return; 1247 } 1248