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