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