1 /* $FreeBSD$ */ 2 /* $KAME: parse.y,v 1.82 2004/04/15 08:03:57 sakane 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 PR_TCP 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 PR_TCP 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 | PR_TCP 254 { 255 $$ = SADB_X_SATYPE_TCPSIGNATURE; 256 } 257 ; 258 259 spi 260 : DECSTRING { p_spi = $1; } 261 | HEXSTRING 262 { 263 char *ep; 264 unsigned long v; 265 266 ep = NULL; 267 v = strtoul($1.buf, &ep, 16); 268 if (!ep || *ep) { 269 yyerror("invalid SPI"); 270 return -1; 271 } 272 if (v & ~0xffffffff) { 273 yyerror("SPI too big."); 274 return -1; 275 } 276 277 p_spi = v; 278 } 279 ; 280 281 algorithm_spec 282 : esp_spec 283 | ah_spec 284 | ipcomp_spec 285 ; 286 287 esp_spec 288 : F_ENC enc_alg F_AUTH auth_alg 289 | F_ENC enc_alg 290 ; 291 292 ah_spec 293 : F_AUTH auth_alg 294 ; 295 296 ipcomp_spec 297 : F_COMP ALG_COMP 298 { 299 if ($2 < 0) { 300 yyerror("unsupported algorithm"); 301 return -1; 302 } 303 p_alg_enc = $2; 304 } 305 | F_COMP ALG_COMP F_RAWCPI 306 { 307 if ($2 < 0) { 308 yyerror("unsupported algorithm"); 309 return -1; 310 } 311 p_alg_enc = $2; 312 p_ext |= SADB_X_EXT_RAWCPI; 313 } 314 ; 315 316 enc_alg 317 : ALG_ENC_NOKEY { 318 if ($1 < 0) { 319 yyerror("unsupported algorithm"); 320 return -1; 321 } 322 p_alg_enc = $1; 323 324 p_key_enc_len = 0; 325 p_key_enc = NULL; 326 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 327 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 328 yyerror(ipsec_strerror()); 329 return -1; 330 } 331 } 332 | ALG_ENC key_string { 333 if ($1 < 0) { 334 yyerror("unsupported algorithm"); 335 return -1; 336 } 337 p_alg_enc = $1; 338 339 p_key_enc_len = $2.len; 340 p_key_enc = $2.buf; 341 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 342 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 343 yyerror(ipsec_strerror()); 344 return -1; 345 } 346 } 347 | ALG_ENC_OLD { 348 if ($1 < 0) { 349 yyerror("unsupported algorithm"); 350 return -1; 351 } 352 yyerror("WARNING: obsolete algorithm"); 353 p_alg_enc = $1; 354 355 p_key_enc_len = 0; 356 p_key_enc = NULL; 357 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 358 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 359 yyerror(ipsec_strerror()); 360 return -1; 361 } 362 } 363 | ALG_ENC_DESDERIV key_string 364 { 365 if ($1 < 0) { 366 yyerror("unsupported algorithm"); 367 return -1; 368 } 369 p_alg_enc = $1; 370 if (p_ext & SADB_X_EXT_OLD) { 371 yyerror("algorithm mismatched"); 372 return -1; 373 } 374 p_ext |= SADB_X_EXT_DERIV; 375 376 p_key_enc_len = $2.len; 377 p_key_enc = $2.buf; 378 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 379 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 380 yyerror(ipsec_strerror()); 381 return -1; 382 } 383 } 384 | ALG_ENC_DES32IV key_string 385 { 386 if ($1 < 0) { 387 yyerror("unsupported algorithm"); 388 return -1; 389 } 390 p_alg_enc = $1; 391 if (!(p_ext & SADB_X_EXT_OLD)) { 392 yyerror("algorithm mismatched"); 393 return -1; 394 } 395 p_ext |= SADB_X_EXT_IV4B; 396 397 p_key_enc_len = $2.len; 398 p_key_enc = $2.buf; 399 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 400 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 401 yyerror(ipsec_strerror()); 402 return -1; 403 } 404 } 405 ; 406 407 auth_alg 408 : ALG_AUTH key_string { 409 if ($1 < 0) { 410 yyerror("unsupported algorithm"); 411 return -1; 412 } 413 p_alg_auth = $1; 414 415 p_key_auth_len = $2.len; 416 p_key_auth = $2.buf; 417 418 if (p_alg_auth == SADB_X_AALG_TCP_MD5) { 419 if ((p_key_auth_len < 1) || (p_key_auth_len > 420 80)) 421 return -1; 422 } else if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, 423 p_alg_auth, PFKEY_UNUNIT64(p_key_auth_len)) < 0) { 424 yyerror(ipsec_strerror()); 425 return -1; 426 } 427 } 428 | ALG_AUTH_NOKEY { 429 if ($1 < 0) { 430 yyerror("unsupported algorithm"); 431 return -1; 432 } 433 p_alg_auth = $1; 434 435 p_key_auth_len = 0; 436 p_key_auth = NULL; 437 } 438 ; 439 440 key_string 441 : QUOTEDSTRING 442 { 443 $$ = $1; 444 } 445 | HEXSTRING 446 { 447 caddr_t pp_key; 448 caddr_t bp; 449 caddr_t yp = $1.buf; 450 int l; 451 452 l = strlen(yp) % 2 + strlen(yp) / 2; 453 if ((pp_key = malloc(l)) == 0) { 454 yyerror("not enough core"); 455 return -1; 456 } 457 memset(pp_key, 0, l); 458 459 bp = pp_key; 460 if (strlen(yp) % 2) { 461 *bp = ATOX(yp[0]); 462 yp++, bp++; 463 } 464 while (*yp) { 465 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); 466 yp += 2, bp++; 467 } 468 469 $$.len = l; 470 $$.buf = pp_key; 471 } 472 ; 473 474 extension_spec 475 : /*NOTHING*/ 476 | extension_spec extension 477 ; 478 479 extension 480 : F_EXT EXTENSION { p_ext |= $2; } 481 | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; } 482 | F_MODE MODE { p_mode = $2; } 483 | F_MODE ANY { p_mode = IPSEC_MODE_ANY; } 484 | F_REQID DECSTRING { p_reqid = $2; } 485 | F_REPLAY DECSTRING 486 { 487 if ((p_ext & SADB_X_EXT_OLD) != 0) { 488 yyerror("replay prevention cannot be used with " 489 "ah/esp-old"); 490 return -1; 491 } 492 p_replay = $2; 493 } 494 | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; } 495 | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; } 496 ; 497 498 /* definition about command for SPD management */ 499 /* spdadd */ 500 spdadd_command 501 : SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT 502 { 503 int status; 504 struct addrinfo *src, *dst; 505 506 /* fixed port fields if ulp is icmpv6 */ 507 if ($10.buf != NULL) { 508 if ($9 != IPPROTO_ICMPV6) 509 return -1; 510 free($5.buf); 511 free($8.buf); 512 if (fix_portstr(&$10, &$5, &$8)) 513 return -1; 514 } 515 516 src = parse_addr($3.buf, $5.buf); 517 dst = parse_addr($6.buf, $8.buf); 518 if (!src || !dst) { 519 /* yyerror is already called */ 520 return -1; 521 } 522 if (src->ai_next || dst->ai_next) { 523 yyerror("multiple address specified"); 524 freeaddrinfo(src); 525 freeaddrinfo(dst); 526 return -1; 527 } 528 529 status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$11, 530 src, $4, dst, $7); 531 freeaddrinfo(src); 532 freeaddrinfo(dst); 533 if (status < 0) 534 return -1; 535 } 536 | SPDADD TAGGED QUOTEDSTRING policy_spec EOT 537 { 538 return -1; 539 } 540 ; 541 542 spddelete_command 543 : SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT 544 { 545 int status; 546 struct addrinfo *src, *dst; 547 548 /* fixed port fields if ulp is icmpv6 */ 549 if ($10.buf != NULL) { 550 if ($9 != IPPROTO_ICMPV6) 551 return -1; 552 free($5.buf); 553 free($8.buf); 554 if (fix_portstr(&$10, &$5, &$8)) 555 return -1; 556 } 557 558 src = parse_addr($3.buf, $5.buf); 559 dst = parse_addr($6.buf, $8.buf); 560 if (!src || !dst) { 561 /* yyerror is already called */ 562 return -1; 563 } 564 if (src->ai_next || dst->ai_next) { 565 yyerror("multiple address specified"); 566 freeaddrinfo(src); 567 freeaddrinfo(dst); 568 return -1; 569 } 570 571 status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$11, 572 src, $4, dst, $7); 573 freeaddrinfo(src); 574 freeaddrinfo(dst); 575 if (status < 0) 576 return -1; 577 } 578 ; 579 580 spddump_command: 581 SPDDUMP EOT 582 { 583 struct sadb_msg msg; 584 setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC, 585 sizeof(msg)); 586 sendkeymsg((char *)&msg, sizeof(msg)); 587 } 588 ; 589 590 spdflush_command: 591 SPDFLUSH EOT 592 { 593 struct sadb_msg msg; 594 setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC, 595 sizeof(msg)); 596 sendkeymsg((char *)&msg, sizeof(msg)); 597 } 598 ; 599 600 ipaddropts 601 : /* nothing */ 602 | ipaddropts ipaddropt 603 ; 604 605 ipaddropt 606 : F_AIFLAGS 607 { 608 char *p; 609 610 for (p = $1.buf + 1; *p; p++) 611 switch (*p) { 612 case '4': 613 p_aifamily = AF_INET; 614 break; 615 #ifdef INET6 616 case '6': 617 p_aifamily = AF_INET6; 618 break; 619 #endif 620 case 'n': 621 p_aiflags = AI_NUMERICHOST; 622 break; 623 default: 624 yyerror("invalid flag"); 625 return -1; 626 } 627 } 628 ; 629 630 ipaddr 631 : STRING 632 { 633 $$ = parse_addr($1.buf, NULL); 634 if ($$ == NULL) { 635 /* yyerror already called by parse_addr */ 636 return -1; 637 } 638 } 639 ; 640 641 prefix 642 : /*NOTHING*/ { $$ = -1; } 643 | SLASH DECSTRING { $$ = $2; } 644 ; 645 646 portstr 647 : /*NOTHING*/ 648 { 649 $$.buf = strdup("0"); 650 if (!$$.buf) { 651 yyerror("insufficient memory"); 652 return -1; 653 } 654 $$.len = strlen($$.buf); 655 } 656 | BLCL ANY ELCL 657 { 658 $$.buf = strdup("0"); 659 if (!$$.buf) { 660 yyerror("insufficient memory"); 661 return -1; 662 } 663 $$.len = strlen($$.buf); 664 } 665 | BLCL DECSTRING ELCL 666 { 667 char buf[20]; 668 snprintf(buf, sizeof(buf), "%lu", $2); 669 $$.buf = strdup(buf); 670 if (!$$.buf) { 671 yyerror("insufficient memory"); 672 return -1; 673 } 674 $$.len = strlen($$.buf); 675 } 676 | BLCL STRING ELCL 677 { 678 $$ = $2; 679 } 680 ; 681 682 upper_spec 683 : DECSTRING { $$ = $1; } 684 | ANY { $$ = IPSEC_ULPROTO_ANY; } 685 | PR_TCP { $$ = IPPROTO_TCP; } 686 | STRING 687 { 688 struct protoent *ent; 689 690 ent = getprotobyname($1.buf); 691 if (ent) 692 $$ = ent->p_proto; 693 else { 694 if (strcmp("icmp6", $1.buf) == 0) { 695 $$ = IPPROTO_ICMPV6; 696 } else if(strcmp("ip4", $1.buf) == 0) { 697 $$ = IPPROTO_IPV4; 698 } else { 699 yyerror("invalid upper layer protocol"); 700 return -1; 701 } 702 } 703 endprotoent(); 704 } 705 ; 706 707 upper_misc_spec 708 : /*NOTHING*/ 709 { 710 $$.buf = NULL; 711 $$.len = 0; 712 } 713 | STRING 714 { 715 $$.buf = strdup($1.buf); 716 if (!$$.buf) { 717 yyerror("insufficient memory"); 718 return -1; 719 } 720 $$.len = strlen($$.buf); 721 } 722 ; 723 724 policy_spec 725 : F_POLICY policy_requests 726 { 727 char *policy; 728 729 policy = ipsec_set_policy($2.buf, $2.len); 730 if (policy == NULL) { 731 yyerror(ipsec_strerror()); 732 return -1; 733 } 734 735 $$.buf = policy; 736 $$.len = ipsec_get_policylen(policy); 737 } 738 ; 739 740 policy_requests 741 : PL_REQUESTS { $$ = $1; } 742 ; 743 744 %% 745 746 int 747 setkeymsg0(msg, type, satype, l) 748 struct sadb_msg *msg; 749 unsigned int type; 750 unsigned int satype; 751 size_t l; 752 { 753 754 msg->sadb_msg_version = PF_KEY_V2; 755 msg->sadb_msg_type = type; 756 msg->sadb_msg_errno = 0; 757 msg->sadb_msg_satype = satype; 758 msg->sadb_msg_reserved = 0; 759 msg->sadb_msg_seq = 0; 760 msg->sadb_msg_pid = getpid(); 761 msg->sadb_msg_len = PFKEY_UNIT64(l); 762 return 0; 763 } 764 765 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 766 static int 767 setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen) 768 unsigned int type; 769 unsigned int upper; 770 vchar_t *policy; 771 struct addrinfo *srcs; 772 int splen; 773 struct addrinfo *dsts; 774 int dplen; 775 { 776 struct sadb_msg *msg; 777 char buf[BUFSIZ]; 778 int l, l0; 779 struct sadb_address m_addr; 780 struct addrinfo *s, *d; 781 int n; 782 int plen; 783 struct sockaddr *sa; 784 int salen; 785 786 msg = (struct sadb_msg *)buf; 787 788 if (!srcs || !dsts) 789 return -1; 790 791 /* fix up length afterwards */ 792 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0); 793 l = sizeof(struct sadb_msg); 794 795 memcpy(buf + l, policy->buf, policy->len); 796 l += policy->len; 797 798 l0 = l; 799 n = 0; 800 801 /* do it for all src/dst pairs */ 802 for (s = srcs; s; s = s->ai_next) { 803 for (d = dsts; d; d = d->ai_next) { 804 /* rewind pointer */ 805 l = l0; 806 807 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 808 continue; 809 switch (s->ai_addr->sa_family) { 810 case AF_INET: 811 plen = sizeof(struct in_addr) << 3; 812 break; 813 #ifdef INET6 814 case AF_INET6: 815 plen = sizeof(struct in6_addr) << 3; 816 break; 817 #endif 818 default: 819 continue; 820 } 821 822 /* set src */ 823 sa = s->ai_addr; 824 salen = s->ai_addr->sa_len; 825 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 826 PFKEY_ALIGN8(salen)); 827 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 828 m_addr.sadb_address_proto = upper; 829 m_addr.sadb_address_prefixlen = 830 (splen >= 0 ? splen : plen); 831 m_addr.sadb_address_reserved = 0; 832 833 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 834 sizeof(m_addr), (caddr_t)sa, salen); 835 836 /* set dst */ 837 sa = d->ai_addr; 838 salen = d->ai_addr->sa_len; 839 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 840 PFKEY_ALIGN8(salen)); 841 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 842 m_addr.sadb_address_proto = upper; 843 m_addr.sadb_address_prefixlen = 844 (dplen >= 0 ? dplen : plen); 845 m_addr.sadb_address_reserved = 0; 846 847 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 848 sizeof(m_addr), (caddr_t)sa, salen); 849 850 msg->sadb_msg_len = PFKEY_UNIT64(l); 851 852 sendkeymsg(buf, l); 853 854 n++; 855 } 856 } 857 858 if (n == 0) 859 return -1; 860 else 861 return 0; 862 } 863 864 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 865 static int 866 setkeymsg_addr(type, satype, srcs, dsts, no_spi) 867 unsigned int type; 868 unsigned int satype; 869 struct addrinfo *srcs; 870 struct addrinfo *dsts; 871 int no_spi; 872 { 873 struct sadb_msg *msg; 874 char buf[BUFSIZ]; 875 int l, l0, len; 876 struct sadb_sa m_sa; 877 struct sadb_x_sa2 m_sa2; 878 struct sadb_address m_addr; 879 struct addrinfo *s, *d; 880 int n; 881 int plen; 882 struct sockaddr *sa; 883 int salen; 884 885 msg = (struct sadb_msg *)buf; 886 887 if (!srcs || !dsts) 888 return -1; 889 890 /* fix up length afterwards */ 891 setkeymsg0(msg, type, satype, 0); 892 l = sizeof(struct sadb_msg); 893 894 if (!no_spi) { 895 len = sizeof(struct sadb_sa); 896 m_sa.sadb_sa_len = PFKEY_UNIT64(len); 897 m_sa.sadb_sa_exttype = SADB_EXT_SA; 898 m_sa.sadb_sa_spi = htonl(p_spi); 899 m_sa.sadb_sa_replay = p_replay; 900 m_sa.sadb_sa_state = 0; 901 m_sa.sadb_sa_auth = p_alg_auth; 902 m_sa.sadb_sa_encrypt = p_alg_enc; 903 m_sa.sadb_sa_flags = p_ext; 904 905 memcpy(buf + l, &m_sa, len); 906 l += len; 907 908 len = sizeof(struct sadb_x_sa2); 909 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 910 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 911 m_sa2.sadb_x_sa2_mode = p_mode; 912 m_sa2.sadb_x_sa2_reqid = p_reqid; 913 914 memcpy(buf + l, &m_sa2, len); 915 l += len; 916 } 917 918 l0 = l; 919 n = 0; 920 921 /* do it for all src/dst pairs */ 922 for (s = srcs; s; s = s->ai_next) { 923 for (d = dsts; d; d = d->ai_next) { 924 /* rewind pointer */ 925 l = l0; 926 927 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 928 continue; 929 switch (s->ai_addr->sa_family) { 930 case AF_INET: 931 plen = sizeof(struct in_addr) << 3; 932 break; 933 #ifdef INET6 934 case AF_INET6: 935 plen = sizeof(struct in6_addr) << 3; 936 break; 937 #endif 938 default: 939 continue; 940 } 941 942 /* set src */ 943 sa = s->ai_addr; 944 salen = s->ai_addr->sa_len; 945 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 946 PFKEY_ALIGN8(salen)); 947 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 948 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 949 m_addr.sadb_address_prefixlen = plen; 950 m_addr.sadb_address_reserved = 0; 951 952 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 953 sizeof(m_addr), (caddr_t)sa, salen); 954 955 /* set dst */ 956 sa = d->ai_addr; 957 salen = d->ai_addr->sa_len; 958 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 959 PFKEY_ALIGN8(salen)); 960 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 961 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 962 m_addr.sadb_address_prefixlen = plen; 963 m_addr.sadb_address_reserved = 0; 964 965 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 966 sizeof(m_addr), (caddr_t)sa, salen); 967 968 msg->sadb_msg_len = PFKEY_UNIT64(l); 969 970 sendkeymsg(buf, l); 971 972 n++; 973 } 974 } 975 976 if (n == 0) 977 return -1; 978 else 979 return 0; 980 } 981 982 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 983 static int 984 setkeymsg_add(type, satype, srcs, dsts) 985 unsigned int type; 986 unsigned int satype; 987 struct addrinfo *srcs; 988 struct addrinfo *dsts; 989 { 990 struct sadb_msg *msg; 991 char buf[BUFSIZ]; 992 int l, l0, len; 993 struct sadb_sa m_sa; 994 struct sadb_x_sa2 m_sa2; 995 struct sadb_address m_addr; 996 struct addrinfo *s, *d; 997 int n; 998 int plen; 999 struct sockaddr *sa; 1000 int salen; 1001 1002 msg = (struct sadb_msg *)buf; 1003 1004 if (!srcs || !dsts) 1005 return -1; 1006 1007 /* fix up length afterwards */ 1008 setkeymsg0(msg, type, satype, 0); 1009 l = sizeof(struct sadb_msg); 1010 1011 /* set encryption algorithm, if present. */ 1012 if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) { 1013 struct sadb_key m_key; 1014 1015 m_key.sadb_key_len = 1016 PFKEY_UNIT64(sizeof(m_key) 1017 + PFKEY_ALIGN8(p_key_enc_len)); 1018 m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; 1019 m_key.sadb_key_bits = p_key_enc_len * 8; 1020 m_key.sadb_key_reserved = 0; 1021 1022 setvarbuf(buf, &l, 1023 (struct sadb_ext *)&m_key, sizeof(m_key), 1024 (caddr_t)p_key_enc, p_key_enc_len); 1025 } 1026 1027 /* set authentication algorithm, if present. */ 1028 if (p_key_auth) { 1029 struct sadb_key m_key; 1030 1031 m_key.sadb_key_len = 1032 PFKEY_UNIT64(sizeof(m_key) 1033 + PFKEY_ALIGN8(p_key_auth_len)); 1034 m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH; 1035 m_key.sadb_key_bits = p_key_auth_len * 8; 1036 m_key.sadb_key_reserved = 0; 1037 1038 setvarbuf(buf, &l, 1039 (struct sadb_ext *)&m_key, sizeof(m_key), 1040 (caddr_t)p_key_auth, p_key_auth_len); 1041 } 1042 1043 /* set lifetime for HARD */ 1044 if (p_lt_hard != 0) { 1045 struct sadb_lifetime m_lt; 1046 u_int slen = sizeof(struct sadb_lifetime); 1047 1048 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); 1049 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; 1050 m_lt.sadb_lifetime_allocations = 0; 1051 m_lt.sadb_lifetime_bytes = 0; 1052 m_lt.sadb_lifetime_addtime = p_lt_hard; 1053 m_lt.sadb_lifetime_usetime = 0; 1054 1055 memcpy(buf + l, &m_lt, slen); 1056 l += len; 1057 } 1058 1059 /* set lifetime for SOFT */ 1060 if (p_lt_soft != 0) { 1061 struct sadb_lifetime m_lt; 1062 u_int slen = sizeof(struct sadb_lifetime); 1063 1064 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); 1065 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; 1066 m_lt.sadb_lifetime_allocations = 0; 1067 m_lt.sadb_lifetime_bytes = 0; 1068 m_lt.sadb_lifetime_addtime = p_lt_soft; 1069 m_lt.sadb_lifetime_usetime = 0; 1070 1071 memcpy(buf + l, &m_lt, slen); 1072 l += len; 1073 } 1074 1075 len = sizeof(struct sadb_sa); 1076 m_sa.sadb_sa_len = PFKEY_UNIT64(len); 1077 m_sa.sadb_sa_exttype = SADB_EXT_SA; 1078 m_sa.sadb_sa_spi = htonl(p_spi); 1079 m_sa.sadb_sa_replay = p_replay; 1080 m_sa.sadb_sa_state = 0; 1081 m_sa.sadb_sa_auth = p_alg_auth; 1082 m_sa.sadb_sa_encrypt = p_alg_enc; 1083 m_sa.sadb_sa_flags = p_ext; 1084 1085 memcpy(buf + l, &m_sa, len); 1086 l += len; 1087 1088 len = sizeof(struct sadb_x_sa2); 1089 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 1090 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 1091 m_sa2.sadb_x_sa2_mode = p_mode; 1092 m_sa2.sadb_x_sa2_reqid = p_reqid; 1093 1094 memcpy(buf + l, &m_sa2, len); 1095 l += len; 1096 1097 l0 = l; 1098 n = 0; 1099 1100 /* do it for all src/dst pairs */ 1101 for (s = srcs; s; s = s->ai_next) { 1102 for (d = dsts; d; d = d->ai_next) { 1103 /* rewind pointer */ 1104 l = l0; 1105 1106 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 1107 continue; 1108 switch (s->ai_addr->sa_family) { 1109 case AF_INET: 1110 plen = sizeof(struct in_addr) << 3; 1111 break; 1112 #ifdef INET6 1113 case AF_INET6: 1114 plen = sizeof(struct in6_addr) << 3; 1115 break; 1116 #endif 1117 default: 1118 continue; 1119 } 1120 1121 /* set src */ 1122 sa = s->ai_addr; 1123 salen = s->ai_addr->sa_len; 1124 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1125 PFKEY_ALIGN8(salen)); 1126 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 1127 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1128 m_addr.sadb_address_prefixlen = plen; 1129 m_addr.sadb_address_reserved = 0; 1130 1131 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1132 sizeof(m_addr), (caddr_t)sa, salen); 1133 1134 /* set dst */ 1135 sa = d->ai_addr; 1136 salen = d->ai_addr->sa_len; 1137 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1138 PFKEY_ALIGN8(salen)); 1139 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 1140 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1141 m_addr.sadb_address_prefixlen = plen; 1142 m_addr.sadb_address_reserved = 0; 1143 1144 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1145 sizeof(m_addr), (caddr_t)sa, salen); 1146 1147 msg->sadb_msg_len = PFKEY_UNIT64(l); 1148 1149 sendkeymsg(buf, l); 1150 1151 n++; 1152 } 1153 } 1154 1155 if (n == 0) 1156 return -1; 1157 else 1158 return 0; 1159 } 1160 1161 static struct addrinfo * 1162 parse_addr(host, port) 1163 char *host; 1164 char *port; 1165 { 1166 struct addrinfo hints, *res = NULL; 1167 int error; 1168 1169 memset(&hints, 0, sizeof(hints)); 1170 hints.ai_family = p_aifamily; 1171 hints.ai_socktype = SOCK_DGRAM; /*dummy*/ 1172 hints.ai_protocol = IPPROTO_UDP; /*dummy*/ 1173 hints.ai_flags = p_aiflags; 1174 error = getaddrinfo(host, port, &hints, &res); 1175 if (error != 0) { 1176 yyerror(gai_strerror(error)); 1177 return NULL; 1178 } 1179 return res; 1180 } 1181 1182 static int 1183 fix_portstr(spec, sport, dport) 1184 vchar_t *spec, *sport, *dport; 1185 { 1186 char *p, *p2; 1187 u_int l; 1188 1189 l = 0; 1190 for (p = spec->buf; *p != ',' && *p != '\0' && l < spec->len; p++, l++) 1191 ; 1192 if (*p == '\0') { 1193 p2 = "0"; 1194 } else { 1195 if (*p == ',') { 1196 *p = '\0'; 1197 p2 = ++p; 1198 } 1199 for (p = p2; *p != '\0' && l < spec->len; p++, l++) 1200 ; 1201 if (*p != '\0' || *p2 == '\0') { 1202 yyerror("invalid an upper layer protocol spec"); 1203 return -1; 1204 } 1205 } 1206 1207 sport->buf = strdup(spec->buf); 1208 if (!sport->buf) { 1209 yyerror("insufficient memory"); 1210 return -1; 1211 } 1212 sport->len = strlen(sport->buf); 1213 dport->buf = strdup(p2); 1214 if (!dport->buf) { 1215 yyerror("insufficient memory"); 1216 return -1; 1217 } 1218 dport->len = strlen(dport->buf); 1219 1220 return 0; 1221 } 1222 1223 static int 1224 setvarbuf(buf, off, ebuf, elen, vbuf, vlen) 1225 char *buf; 1226 int *off; 1227 struct sadb_ext *ebuf; 1228 int elen; 1229 caddr_t vbuf; 1230 int vlen; 1231 { 1232 memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len)); 1233 memcpy(buf + *off, (caddr_t)ebuf, elen); 1234 memcpy(buf + *off + elen, vbuf, vlen); 1235 (*off) += PFKEY_ALIGN8(elen + vlen); 1236 1237 return 0; 1238 } 1239 1240 void 1241 parse_init() 1242 { 1243 p_spi = 0; 1244 1245 p_ext = SADB_X_EXT_CYCSEQ; 1246 p_alg_enc = SADB_EALG_NONE; 1247 p_alg_auth = SADB_AALG_NONE; 1248 p_mode = IPSEC_MODE_ANY; 1249 p_reqid = 0; 1250 p_replay = 0; 1251 p_key_enc_len = p_key_auth_len = 0; 1252 p_key_enc = p_key_auth = 0; 1253 p_lt_hard = p_lt_soft = 0; 1254 1255 p_aiflags = 0; 1256 p_aifamily = PF_UNSPEC; 1257 1258 return; 1259 } 1260 1261 void 1262 free_buffer() 1263 { 1264 /* we got tons of memory leaks in the parser anyways, leave them */ 1265 1266 return; 1267 } 1268