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