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