1 /* $NetBSD: parse.y,v 1.15 2012/01/09 15:25:13 drochner Exp $ */ 2 3 /* $KAME: parse.y,v 1.81 2003/07/01 04:01:48 itojun Exp $ */ 4 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 #ifdef HAVE_CONFIG_H 36 #include "config.h" 37 #endif 38 39 #include <sys/types.h> 40 #include <sys/param.h> 41 #include <sys/socket.h> 42 43 #include <netinet/in.h> 44 #include <net/pfkeyv2.h> 45 #include PATH_IPSEC_H 46 #include <arpa/inet.h> 47 48 #include <string.h> 49 #include <unistd.h> 50 #include <stdio.h> 51 #include <netdb.h> 52 #include <ctype.h> 53 #include <errno.h> 54 #include <stdlib.h> 55 56 #include "libpfkey.h" 57 #include "vchar.h" 58 #include "extern.h" 59 60 #define DEFAULT_NATT_PORT 4500 61 62 #ifndef UDP_ENCAP_ESPINUDP 63 #define UDP_ENCAP_ESPINUDP 2 64 #endif 65 66 #define ATOX(c) \ 67 (isdigit((int)c) ? (c - '0') : \ 68 (isupper((int)c) ? (c - 'A' + 10) : (c - 'a' + 10))) 69 70 u_int32_t p_spi; 71 u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode; 72 u_int32_t p_reqid; 73 u_int p_key_enc_len, p_key_auth_len; 74 const char *p_key_enc; 75 const char *p_key_auth; 76 time_t p_lt_hard, p_lt_soft; 77 size_t p_lb_hard, p_lb_soft; 78 79 struct security_ctx { 80 u_int8_t doi; 81 u_int8_t alg; 82 u_int16_t len; 83 char *buf; 84 }; 85 86 struct security_ctx sec_ctx; 87 88 static u_int p_natt_type, p_esp_frag; 89 static struct addrinfo * p_natt_oa = NULL; 90 91 static int p_aiflags = 0, p_aifamily = PF_UNSPEC; 92 93 static struct addrinfo *parse_addr __P((char *, char *)); 94 static int fix_portstr __P((int, vchar_t *, vchar_t *, vchar_t *)); 95 static int setvarbuf __P((char *, int *, struct sadb_ext *, int, 96 const void *, int)); 97 void parse_init __P((void)); 98 void free_buffer __P((void)); 99 100 int setkeymsg0 __P((struct sadb_msg *, unsigned int, unsigned int, size_t)); 101 static int setkeymsg_spdaddr __P((unsigned int, unsigned int, vchar_t *, 102 struct addrinfo *, int, struct addrinfo *, int)); 103 static int setkeymsg_spdaddr_tag __P((unsigned int, char *, vchar_t *)); 104 static int setkeymsg_addr __P((unsigned int, unsigned int, 105 struct addrinfo *, struct addrinfo *, int)); 106 static int setkeymsg_add __P((unsigned int, unsigned int, 107 struct addrinfo *, struct addrinfo *)); 108 %} 109 110 %union { 111 int num; 112 unsigned long ulnum; 113 vchar_t val; 114 struct addrinfo *res; 115 } 116 117 %token EOT SLASH BLCL ELCL 118 %token ADD GET DELETE DELETEALL FLUSH DUMP EXIT 119 %token PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP 120 %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI 121 %token F_MODE MODE F_REQID 122 %token F_EXT EXTENSION NOCYCLICSEQ 123 %token ALG_AUTH ALG_AUTH_NOKEY 124 %token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD 125 %token ALG_COMP 126 %token F_LIFETIME_HARD F_LIFETIME_SOFT 127 %token F_LIFEBYTE_HARD F_LIFEBYTE_SOFT 128 %token F_ESPFRAG 129 %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY 130 /* SPD management */ 131 %token SPDADD SPDUPDATE SPDDELETE SPDDUMP SPDFLUSH 132 %token F_POLICY PL_REQUESTS 133 %token F_AIFLAGS 134 %token TAGGED 135 %token SECURITY_CTX 136 137 %type <num> prefix protocol_spec upper_spec 138 %type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY 139 %type <num> ALG_AUTH ALG_AUTH_NOKEY 140 %type <num> ALG_COMP 141 %type <num> PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP 142 %type <num> EXTENSION MODE 143 %type <ulnum> DECSTRING 144 %type <val> PL_REQUESTS portstr key_string 145 %type <val> policy_requests 146 %type <val> QUOTEDSTRING HEXSTRING STRING 147 %type <val> F_AIFLAGS 148 %type <val> upper_misc_spec policy_spec 149 %type <res> ipaddr ipandport 150 151 %% 152 commands 153 : /*NOTHING*/ 154 | commands command 155 { 156 free_buffer(); 157 parse_init(); 158 } 159 ; 160 161 command 162 : add_command 163 | get_command 164 | delete_command 165 | deleteall_command 166 | flush_command 167 | dump_command 168 | exit_command 169 | spdadd_command 170 | spdupdate_command 171 | spddelete_command 172 | spddump_command 173 | spdflush_command 174 ; 175 /* commands concerned with management, there is in tail of this file. */ 176 177 /* add command */ 178 add_command 179 : ADD ipaddropts ipandport ipandport protocol_spec spi extension_spec algorithm_spec EOT 180 { 181 int status; 182 183 status = setkeymsg_add(SADB_ADD, $5, $3, $4); 184 if (status < 0) 185 return -1; 186 } 187 ; 188 189 /* delete */ 190 delete_command 191 : DELETE ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT 192 { 193 int status; 194 195 if ($3->ai_next || $4->ai_next) { 196 yyerror("multiple address specified"); 197 return -1; 198 } 199 if (p_mode != IPSEC_MODE_ANY) 200 yyerror("WARNING: mode is obsolete"); 201 202 status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0); 203 if (status < 0) 204 return -1; 205 } 206 ; 207 208 /* deleteall command */ 209 deleteall_command 210 : DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT 211 { 212 #ifndef __linux__ 213 if (setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1) < 0) 214 return -1; 215 #else /* __linux__ */ 216 /* linux strictly adheres to RFC2367, and returns 217 * an error if we send an SADB_DELETE request without 218 * an SPI. Therefore, we must first retrieve a list 219 * of SPIs for all matching SADB entries, and then 220 * delete each one separately. */ 221 u_int32_t *spi; 222 int i, n; 223 224 spi = sendkeymsg_spigrep($5, $3, $4, &n); 225 for (i = 0; i < n; i++) { 226 p_spi = spi[i]; 227 if (setkeymsg_addr(SADB_DELETE, 228 $5, $3, $4, 0) < 0) 229 return -1; 230 } 231 free(spi); 232 #endif /* __linux__ */ 233 } 234 ; 235 236 /* get command */ 237 get_command 238 : GET ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT 239 { 240 int status; 241 242 if (p_mode != IPSEC_MODE_ANY) 243 yyerror("WARNING: mode is obsolete"); 244 245 status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0); 246 if (status < 0) 247 return -1; 248 } 249 ; 250 251 /* flush */ 252 flush_command 253 : FLUSH protocol_spec EOT 254 { 255 struct sadb_msg msg; 256 setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg)); 257 sendkeymsg((char *)&msg, sizeof(msg)); 258 } 259 ; 260 261 /* dump */ 262 dump_command 263 : DUMP protocol_spec EOT 264 { 265 struct sadb_msg msg; 266 setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg)); 267 sendkeymsg((char *)&msg, sizeof(msg)); 268 } 269 ; 270 271 protocol_spec 272 : /*NOTHING*/ 273 { 274 $$ = SADB_SATYPE_UNSPEC; 275 } 276 | PR_ESP 277 { 278 $$ = SADB_SATYPE_ESP; 279 if ($1 == 1) 280 p_ext |= SADB_X_EXT_OLD; 281 else 282 p_ext &= ~SADB_X_EXT_OLD; 283 } 284 | PR_AH 285 { 286 $$ = SADB_SATYPE_AH; 287 if ($1 == 1) 288 p_ext |= SADB_X_EXT_OLD; 289 else 290 p_ext &= ~SADB_X_EXT_OLD; 291 } 292 | PR_IPCOMP 293 { 294 $$ = SADB_X_SATYPE_IPCOMP; 295 } 296 | PR_ESPUDP 297 { 298 $$ = SADB_SATYPE_ESP; 299 p_ext &= ~SADB_X_EXT_OLD; 300 p_natt_oa = 0; 301 p_natt_type = UDP_ENCAP_ESPINUDP; 302 } 303 | PR_ESPUDP ipaddr 304 { 305 $$ = SADB_SATYPE_ESP; 306 p_ext &= ~SADB_X_EXT_OLD; 307 p_natt_oa = $2; 308 p_natt_type = UDP_ENCAP_ESPINUDP; 309 } 310 | PR_TCP 311 { 312 #ifdef SADB_X_SATYPE_TCPSIGNATURE 313 $$ = SADB_X_SATYPE_TCPSIGNATURE; 314 #endif 315 } 316 ; 317 318 spi 319 : DECSTRING { p_spi = $1; } 320 | HEXSTRING 321 { 322 char *ep; 323 unsigned long v; 324 325 ep = NULL; 326 v = strtoul($1.buf, &ep, 16); 327 if (!ep || *ep) { 328 yyerror("invalid SPI"); 329 return -1; 330 } 331 if (v & ~0xffffffff) { 332 yyerror("SPI too big."); 333 return -1; 334 } 335 336 p_spi = v; 337 } 338 ; 339 340 algorithm_spec 341 : esp_spec 342 | ah_spec 343 | ipcomp_spec 344 ; 345 346 esp_spec 347 : F_ENC enc_alg F_AUTH auth_alg 348 | F_ENC enc_alg 349 ; 350 351 ah_spec 352 : F_AUTH auth_alg 353 ; 354 355 ipcomp_spec 356 : F_COMP ALG_COMP 357 { 358 if ($2 < 0) { 359 yyerror("unsupported algorithm"); 360 return -1; 361 } 362 p_alg_enc = $2; 363 } 364 | F_COMP ALG_COMP F_RAWCPI 365 { 366 if ($2 < 0) { 367 yyerror("unsupported algorithm"); 368 return -1; 369 } 370 p_alg_enc = $2; 371 p_ext |= SADB_X_EXT_RAWCPI; 372 } 373 ; 374 375 enc_alg 376 : ALG_ENC_NOKEY { 377 if ($1 < 0) { 378 yyerror("unsupported algorithm"); 379 return -1; 380 } 381 p_alg_enc = $1; 382 383 p_key_enc_len = 0; 384 p_key_enc = ""; 385 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 386 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 387 yyerror(ipsec_strerror()); 388 return -1; 389 } 390 } 391 | ALG_ENC key_string { 392 if ($1 < 0) { 393 yyerror("unsupported algorithm"); 394 return -1; 395 } 396 p_alg_enc = $1; 397 398 p_key_enc_len = $2.len; 399 p_key_enc = $2.buf; 400 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 401 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 402 yyerror(ipsec_strerror()); 403 return -1; 404 } 405 } 406 | ALG_ENC_OLD { 407 if ($1 < 0) { 408 yyerror("unsupported algorithm"); 409 return -1; 410 } 411 yyerror("WARNING: obsolete algorithm"); 412 p_alg_enc = $1; 413 414 p_key_enc_len = 0; 415 p_key_enc = ""; 416 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 417 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 418 yyerror(ipsec_strerror()); 419 return -1; 420 } 421 } 422 | ALG_ENC_DESDERIV key_string 423 { 424 if ($1 < 0) { 425 yyerror("unsupported algorithm"); 426 return -1; 427 } 428 p_alg_enc = $1; 429 if (p_ext & SADB_X_EXT_OLD) { 430 yyerror("algorithm mismatched"); 431 return -1; 432 } 433 p_ext |= SADB_X_EXT_DERIV; 434 435 p_key_enc_len = $2.len; 436 p_key_enc = $2.buf; 437 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 438 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 439 yyerror(ipsec_strerror()); 440 return -1; 441 } 442 } 443 | ALG_ENC_DES32IV key_string 444 { 445 if ($1 < 0) { 446 yyerror("unsupported algorithm"); 447 return -1; 448 } 449 p_alg_enc = $1; 450 if (!(p_ext & SADB_X_EXT_OLD)) { 451 yyerror("algorithm mismatched"); 452 return -1; 453 } 454 p_ext |= SADB_X_EXT_IV4B; 455 456 p_key_enc_len = $2.len; 457 p_key_enc = $2.buf; 458 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 459 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 460 yyerror(ipsec_strerror()); 461 return -1; 462 } 463 } 464 ; 465 466 auth_alg 467 : ALG_AUTH key_string { 468 if ($1 < 0) { 469 yyerror("unsupported algorithm"); 470 return -1; 471 } 472 p_alg_auth = $1; 473 474 p_key_auth_len = $2.len; 475 p_key_auth = $2.buf; 476 #ifdef SADB_X_AALG_TCP_MD5 477 if (p_alg_auth == SADB_X_AALG_TCP_MD5) { 478 if ((p_key_auth_len < 1) || 479 (p_key_auth_len > 80)) 480 return -1; 481 } else 482 #endif 483 { 484 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, 485 p_alg_auth, 486 PFKEY_UNUNIT64(p_key_auth_len)) < 0) { 487 yyerror(ipsec_strerror()); 488 return -1; 489 } 490 } 491 } 492 | ALG_AUTH_NOKEY { 493 if ($1 < 0) { 494 yyerror("unsupported algorithm"); 495 return -1; 496 } 497 p_alg_auth = $1; 498 499 p_key_auth_len = 0; 500 p_key_auth = NULL; 501 } 502 ; 503 504 key_string 505 : QUOTEDSTRING 506 { 507 $$ = $1; 508 } 509 | HEXSTRING 510 { 511 caddr_t pp_key; 512 caddr_t bp; 513 caddr_t yp = $1.buf; 514 int l; 515 516 l = strlen(yp) % 2 + strlen(yp) / 2; 517 if ((pp_key = malloc(l)) == 0) { 518 yyerror("not enough core"); 519 return -1; 520 } 521 memset(pp_key, 0, l); 522 523 bp = pp_key; 524 if (strlen(yp) % 2) { 525 *bp = ATOX(yp[0]); 526 yp++, bp++; 527 } 528 while (*yp) { 529 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); 530 yp += 2, bp++; 531 } 532 533 $$.len = l; 534 $$.buf = pp_key; 535 } 536 ; 537 538 extension_spec 539 : /*NOTHING*/ 540 | extension_spec extension 541 ; 542 543 extension 544 : F_EXT EXTENSION { p_ext |= $2; } 545 | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; } 546 | F_MODE MODE { p_mode = $2; } 547 | F_MODE ANY { p_mode = IPSEC_MODE_ANY; } 548 | F_REQID DECSTRING { p_reqid = $2; } 549 | F_ESPFRAG DECSTRING 550 { 551 if (p_natt_type == 0) { 552 yyerror("esp fragment size only valid for NAT-T"); 553 return -1; 554 } 555 p_esp_frag = $2; 556 } 557 | F_REPLAY DECSTRING 558 { 559 if ((p_ext & SADB_X_EXT_OLD) != 0) { 560 yyerror("replay prevention cannot be used with " 561 "ah/esp-old"); 562 return -1; 563 } 564 p_replay = $2; 565 } 566 | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; } 567 | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; } 568 | F_LIFEBYTE_HARD DECSTRING { p_lb_hard = $2; } 569 | F_LIFEBYTE_SOFT DECSTRING { p_lb_soft = $2; } 570 | SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING { 571 sec_ctx.doi = $2; 572 sec_ctx.alg = $3; 573 sec_ctx.len = $4.len+1; 574 sec_ctx.buf = $4.buf; 575 } 576 ; 577 578 /* definition about command for SPD management */ 579 /* spdadd */ 580 spdadd_command 581 /* XXX merge with spdupdate ??? */ 582 : SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT 583 { 584 int status; 585 struct addrinfo *src, *dst; 586 587 #ifdef HAVE_PFKEY_POLICY_PRIORITY 588 last_msg_type = SADB_X_SPDADD; 589 #endif 590 591 /* fixed port fields if ulp is icmp */ 592 if (fix_portstr($9, &$10, &$5, &$8)) 593 return -1; 594 595 src = parse_addr($3.buf, $5.buf); 596 dst = parse_addr($6.buf, $8.buf); 597 if (!src || !dst) { 598 /* yyerror is already called */ 599 return -1; 600 } 601 if (src->ai_next || dst->ai_next) { 602 yyerror("multiple address specified"); 603 freeaddrinfo(src); 604 freeaddrinfo(dst); 605 return -1; 606 } 607 608 status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$12, 609 src, $4, dst, $7); 610 freeaddrinfo(src); 611 freeaddrinfo(dst); 612 if (status < 0) 613 return -1; 614 } 615 | SPDADD TAGGED QUOTEDSTRING policy_spec EOT 616 { 617 int status; 618 619 status = setkeymsg_spdaddr_tag(SADB_X_SPDADD, 620 $3.buf, &$4); 621 if (status < 0) 622 return -1; 623 } 624 ; 625 626 spdupdate_command 627 /* XXX merge with spdadd ??? */ 628 : SPDUPDATE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT 629 { 630 int status; 631 struct addrinfo *src, *dst; 632 633 #ifdef HAVE_PFKEY_POLICY_PRIORITY 634 last_msg_type = SADB_X_SPDUPDATE; 635 #endif 636 637 /* fixed port fields if ulp is icmp */ 638 if (fix_portstr($9, &$10, &$5, &$8)) 639 return -1; 640 641 src = parse_addr($3.buf, $5.buf); 642 dst = parse_addr($6.buf, $8.buf); 643 if (!src || !dst) { 644 /* yyerror is already called */ 645 return -1; 646 } 647 if (src->ai_next || dst->ai_next) { 648 yyerror("multiple address specified"); 649 freeaddrinfo(src); 650 freeaddrinfo(dst); 651 return -1; 652 } 653 654 status = setkeymsg_spdaddr(SADB_X_SPDUPDATE, $9, &$12, 655 src, $4, dst, $7); 656 freeaddrinfo(src); 657 freeaddrinfo(dst); 658 if (status < 0) 659 return -1; 660 } 661 | SPDUPDATE TAGGED QUOTEDSTRING policy_spec EOT 662 { 663 int status; 664 665 status = setkeymsg_spdaddr_tag(SADB_X_SPDUPDATE, 666 $3.buf, &$4); 667 if (status < 0) 668 return -1; 669 } 670 ; 671 672 spddelete_command 673 : SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT 674 { 675 int status; 676 struct addrinfo *src, *dst; 677 678 /* fixed port fields if ulp is icmp */ 679 if (fix_portstr($9, &$10, &$5, &$8)) 680 return -1; 681 682 src = parse_addr($3.buf, $5.buf); 683 dst = parse_addr($6.buf, $8.buf); 684 if (!src || !dst) { 685 /* yyerror is already called */ 686 return -1; 687 } 688 if (src->ai_next || dst->ai_next) { 689 yyerror("multiple address specified"); 690 freeaddrinfo(src); 691 freeaddrinfo(dst); 692 return -1; 693 } 694 695 status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$12, 696 src, $4, dst, $7); 697 freeaddrinfo(src); 698 freeaddrinfo(dst); 699 if (status < 0) 700 return -1; 701 } 702 ; 703 704 spddump_command: 705 SPDDUMP EOT 706 { 707 struct sadb_msg msg; 708 setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC, 709 sizeof(msg)); 710 sendkeymsg((char *)&msg, sizeof(msg)); 711 } 712 ; 713 714 spdflush_command 715 : 716 SPDFLUSH EOT 717 { 718 struct sadb_msg msg; 719 setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC, 720 sizeof(msg)); 721 sendkeymsg((char *)&msg, sizeof(msg)); 722 } 723 ; 724 725 ipaddropts 726 : /* nothing */ 727 | ipaddropts ipaddropt 728 ; 729 730 ipaddropt 731 : F_AIFLAGS 732 { 733 char *p; 734 735 for (p = $1.buf + 1; *p; p++) 736 switch (*p) { 737 case '4': 738 p_aifamily = AF_INET; 739 break; 740 #ifdef INET6 741 case '6': 742 p_aifamily = AF_INET6; 743 break; 744 #endif 745 case 'n': 746 p_aiflags = AI_NUMERICHOST; 747 break; 748 default: 749 yyerror("invalid flag"); 750 return -1; 751 } 752 } 753 ; 754 755 ipaddr 756 : STRING 757 { 758 $$ = parse_addr($1.buf, NULL); 759 if ($$ == NULL) { 760 /* yyerror already called by parse_addr */ 761 return -1; 762 } 763 } 764 ; 765 766 ipandport 767 : STRING 768 { 769 $$ = parse_addr($1.buf, NULL); 770 if ($$ == NULL) { 771 /* yyerror already called by parse_addr */ 772 return -1; 773 } 774 } 775 | STRING portstr 776 { 777 $$ = parse_addr($1.buf, $2.buf); 778 if ($$ == NULL) { 779 /* yyerror already called by parse_addr */ 780 return -1; 781 } 782 } 783 ; 784 785 prefix 786 : /*NOTHING*/ { $$ = -1; } 787 | SLASH DECSTRING { $$ = $2; } 788 ; 789 790 portstr 791 : /*NOTHING*/ 792 { 793 $$.buf = strdup("0"); 794 if (!$$.buf) { 795 yyerror("insufficient memory"); 796 return -1; 797 } 798 $$.len = strlen($$.buf); 799 } 800 | BLCL ANY ELCL 801 { 802 $$.buf = strdup("0"); 803 if (!$$.buf) { 804 yyerror("insufficient memory"); 805 return -1; 806 } 807 $$.len = strlen($$.buf); 808 } 809 | BLCL DECSTRING ELCL 810 { 811 char buf[20]; 812 snprintf(buf, sizeof(buf), "%lu", $2); 813 $$.buf = strdup(buf); 814 if (!$$.buf) { 815 yyerror("insufficient memory"); 816 return -1; 817 } 818 $$.len = strlen($$.buf); 819 } 820 | BLCL STRING ELCL 821 { 822 $$ = $2; 823 } 824 ; 825 826 upper_spec 827 : DECSTRING { $$ = $1; } 828 | ANY { $$ = IPSEC_ULPROTO_ANY; } 829 | PR_TCP { 830 $$ = IPPROTO_TCP; 831 } 832 | STRING 833 { 834 struct protoent *ent; 835 836 ent = getprotobyname($1.buf); 837 if (ent) 838 $$ = ent->p_proto; 839 else { 840 if (strcmp("icmp6", $1.buf) == 0) { 841 $$ = IPPROTO_ICMPV6; 842 } else if(strcmp("ip4", $1.buf) == 0) { 843 $$ = IPPROTO_IPV4; 844 } else { 845 yyerror("invalid upper layer protocol"); 846 return -1; 847 } 848 } 849 endprotoent(); 850 } 851 ; 852 853 upper_misc_spec 854 : /*NOTHING*/ 855 { 856 $$.buf = NULL; 857 $$.len = 0; 858 } 859 | STRING 860 { 861 $$.buf = strdup($1.buf); 862 if (!$$.buf) { 863 yyerror("insufficient memory"); 864 return -1; 865 } 866 $$.len = strlen($$.buf); 867 } 868 ; 869 870 context_spec 871 : /* NOTHING */ 872 | SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING { 873 sec_ctx.doi = $2; 874 sec_ctx.alg = $3; 875 sec_ctx.len = $4.len+1; 876 sec_ctx.buf = $4.buf; 877 } 878 ; 879 880 policy_spec 881 : F_POLICY policy_requests 882 { 883 char *policy; 884 #ifdef HAVE_PFKEY_POLICY_PRIORITY 885 struct sadb_x_policy *xpl; 886 #endif 887 888 policy = ipsec_set_policy($2.buf, $2.len); 889 if (policy == NULL) { 890 yyerror(ipsec_strerror()); 891 return -1; 892 } 893 894 $$.buf = policy; 895 $$.len = ipsec_get_policylen(policy); 896 897 #ifdef HAVE_PFKEY_POLICY_PRIORITY 898 xpl = (struct sadb_x_policy *) $$.buf; 899 last_priority = xpl->sadb_x_policy_priority; 900 #endif 901 } 902 ; 903 904 policy_requests 905 : PL_REQUESTS { $$ = $1; } 906 ; 907 908 /* exit */ 909 exit_command 910 : EXIT EOT 911 { 912 exit_now = 1; 913 YYACCEPT; 914 } 915 ; 916 %% 917 918 int 919 setkeymsg0(msg, type, satype, l) 920 struct sadb_msg *msg; 921 unsigned int type; 922 unsigned int satype; 923 size_t l; 924 { 925 926 msg->sadb_msg_version = PF_KEY_V2; 927 msg->sadb_msg_type = type; 928 msg->sadb_msg_errno = 0; 929 msg->sadb_msg_satype = satype; 930 msg->sadb_msg_reserved = 0; 931 msg->sadb_msg_seq = 0; 932 msg->sadb_msg_pid = getpid(); 933 msg->sadb_msg_len = PFKEY_UNIT64(l); 934 return 0; 935 } 936 937 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 938 static int 939 setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen) 940 unsigned int type; 941 unsigned int upper; 942 vchar_t *policy; 943 struct addrinfo *srcs; 944 int splen; 945 struct addrinfo *dsts; 946 int dplen; 947 { 948 struct sadb_msg *msg; 949 char buf[BUFSIZ]; 950 int l, l0; 951 struct sadb_address m_addr; 952 struct addrinfo *s, *d; 953 int n; 954 int plen; 955 struct sockaddr *sa; 956 int salen; 957 struct sadb_x_policy *sp; 958 #ifdef HAVE_POLICY_FWD 959 struct sadb_x_ipsecrequest *ps = NULL; 960 int saved_level, saved_id = 0; 961 #endif 962 963 msg = (struct sadb_msg *)buf; 964 965 if (!srcs || !dsts) 966 return -1; 967 968 /* fix up length afterwards */ 969 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0); 970 l = sizeof(struct sadb_msg); 971 972 sp = (struct sadb_x_policy*) (buf + l); 973 memcpy(buf + l, policy->buf, policy->len); 974 l += policy->len; 975 976 l0 = l; 977 n = 0; 978 979 /* do it for all src/dst pairs */ 980 for (s = srcs; s; s = s->ai_next) { 981 for (d = dsts; d; d = d->ai_next) { 982 /* rewind pointer */ 983 l = l0; 984 985 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 986 continue; 987 switch (s->ai_addr->sa_family) { 988 case AF_INET: 989 plen = sizeof(struct in_addr) << 3; 990 break; 991 #ifdef INET6 992 case AF_INET6: 993 plen = sizeof(struct in6_addr) << 3; 994 break; 995 #endif 996 default: 997 continue; 998 } 999 1000 /* set src */ 1001 sa = s->ai_addr; 1002 salen = sysdep_sa_len(s->ai_addr); 1003 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1004 PFKEY_ALIGN8(salen)); 1005 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 1006 m_addr.sadb_address_proto = upper; 1007 m_addr.sadb_address_prefixlen = 1008 (splen >= 0 ? splen : plen); 1009 m_addr.sadb_address_reserved = 0; 1010 1011 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1012 sizeof(m_addr), (caddr_t)sa, salen); 1013 1014 /* set dst */ 1015 sa = d->ai_addr; 1016 salen = sysdep_sa_len(d->ai_addr); 1017 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1018 PFKEY_ALIGN8(salen)); 1019 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 1020 m_addr.sadb_address_proto = upper; 1021 m_addr.sadb_address_prefixlen = 1022 (dplen >= 0 ? dplen : plen); 1023 m_addr.sadb_address_reserved = 0; 1024 1025 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1026 sizeof(m_addr), sa, salen); 1027 #ifdef SADB_X_EXT_SEC_CTX 1028 /* Add security context label */ 1029 if (sec_ctx.doi) { 1030 struct sadb_x_sec_ctx m_sec_ctx; 1031 u_int slen = sizeof(struct sadb_x_sec_ctx); 1032 1033 memset(&m_sec_ctx, 0, slen); 1034 1035 m_sec_ctx.sadb_x_sec_len = 1036 PFKEY_UNIT64(slen + PFKEY_ALIGN8(sec_ctx.len)); 1037 1038 m_sec_ctx.sadb_x_sec_exttype = 1039 SADB_X_EXT_SEC_CTX; 1040 m_sec_ctx.sadb_x_ctx_len = sec_ctx.len;/*bytes*/ 1041 m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi; 1042 m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg; 1043 setvarbuf(buf, &l, 1044 (struct sadb_ext *)&m_sec_ctx, slen, 1045 (caddr_t)sec_ctx.buf, sec_ctx.len); 1046 } 1047 #endif 1048 msg->sadb_msg_len = PFKEY_UNIT64(l); 1049 1050 sendkeymsg(buf, l); 1051 1052 #ifdef HAVE_POLICY_FWD 1053 /* create extra call for FWD policy */ 1054 if (f_rfcmode && sp->sadb_x_policy_dir == IPSEC_DIR_INBOUND) { 1055 sp->sadb_x_policy_dir = IPSEC_DIR_FWD; 1056 ps = (struct sadb_x_ipsecrequest*) (sp+1); 1057 1058 /* if request level is unique, change it to 1059 * require for fwd policy */ 1060 /* XXX: currently, only first policy is updated 1061 * only. Update following too... */ 1062 saved_level = ps->sadb_x_ipsecrequest_level; 1063 if (saved_level == IPSEC_LEVEL_UNIQUE) { 1064 saved_id = ps->sadb_x_ipsecrequest_reqid; 1065 ps->sadb_x_ipsecrequest_reqid=0; 1066 ps->sadb_x_ipsecrequest_level=IPSEC_LEVEL_REQUIRE; 1067 } 1068 1069 sendkeymsg(buf, l); 1070 /* restoring for next message */ 1071 sp->sadb_x_policy_dir = IPSEC_DIR_INBOUND; 1072 if (saved_level == IPSEC_LEVEL_UNIQUE) { 1073 ps->sadb_x_ipsecrequest_reqid = saved_id; 1074 ps->sadb_x_ipsecrequest_level = saved_level; 1075 } 1076 } 1077 #endif 1078 1079 n++; 1080 } 1081 } 1082 1083 if (n == 0) 1084 return -1; 1085 else 1086 return 0; 1087 } 1088 1089 static int 1090 setkeymsg_spdaddr_tag(type, tag, policy) 1091 unsigned int type; 1092 char *tag; 1093 vchar_t *policy; 1094 { 1095 struct sadb_msg *msg; 1096 char buf[BUFSIZ]; 1097 int l, l0; 1098 #ifdef SADB_X_EXT_TAG 1099 struct sadb_x_tag m_tag; 1100 #endif 1101 int n; 1102 1103 msg = (struct sadb_msg *)buf; 1104 1105 /* fix up length afterwards */ 1106 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0); 1107 l = sizeof(struct sadb_msg); 1108 1109 memcpy(buf + l, policy->buf, policy->len); 1110 l += policy->len; 1111 1112 l0 = l; 1113 n = 0; 1114 1115 #ifdef SADB_X_EXT_TAG 1116 memset(&m_tag, 0, sizeof(m_tag)); 1117 m_tag.sadb_x_tag_len = PFKEY_UNIT64(sizeof(m_tag)); 1118 m_tag.sadb_x_tag_exttype = SADB_X_EXT_TAG; 1119 if (strlcpy(m_tag.sadb_x_tag_name, tag, 1120 sizeof(m_tag.sadb_x_tag_name)) >= sizeof(m_tag.sadb_x_tag_name)) 1121 return -1; 1122 memcpy(buf + l, &m_tag, sizeof(m_tag)); 1123 l += sizeof(m_tag); 1124 #endif 1125 1126 msg->sadb_msg_len = PFKEY_UNIT64(l); 1127 1128 sendkeymsg(buf, l); 1129 1130 return 0; 1131 } 1132 1133 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 1134 static int 1135 setkeymsg_addr(type, satype, srcs, dsts, no_spi) 1136 unsigned int type; 1137 unsigned int satype; 1138 struct addrinfo *srcs; 1139 struct addrinfo *dsts; 1140 int no_spi; 1141 { 1142 struct sadb_msg *msg; 1143 char buf[BUFSIZ]; 1144 int l, l0, len; 1145 struct sadb_sa m_sa; 1146 struct sadb_x_sa2 m_sa2; 1147 struct sadb_address m_addr; 1148 struct addrinfo *s, *d; 1149 int n; 1150 int plen; 1151 struct sockaddr *sa; 1152 int salen; 1153 1154 msg = (struct sadb_msg *)buf; 1155 1156 if (!srcs || !dsts) 1157 return -1; 1158 1159 /* fix up length afterwards */ 1160 setkeymsg0(msg, type, satype, 0); 1161 l = sizeof(struct sadb_msg); 1162 1163 if (!no_spi) { 1164 len = sizeof(struct sadb_sa); 1165 m_sa.sadb_sa_len = PFKEY_UNIT64(len); 1166 m_sa.sadb_sa_exttype = SADB_EXT_SA; 1167 m_sa.sadb_sa_spi = htonl(p_spi); 1168 m_sa.sadb_sa_replay = p_replay; 1169 m_sa.sadb_sa_state = 0; 1170 m_sa.sadb_sa_auth = p_alg_auth; 1171 m_sa.sadb_sa_encrypt = p_alg_enc; 1172 m_sa.sadb_sa_flags = p_ext; 1173 1174 memcpy(buf + l, &m_sa, len); 1175 l += len; 1176 1177 len = sizeof(struct sadb_x_sa2); 1178 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 1179 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 1180 m_sa2.sadb_x_sa2_mode = p_mode; 1181 m_sa2.sadb_x_sa2_reqid = p_reqid; 1182 1183 memcpy(buf + l, &m_sa2, len); 1184 l += len; 1185 } 1186 1187 l0 = l; 1188 n = 0; 1189 1190 /* do it for all src/dst pairs */ 1191 for (s = srcs; s; s = s->ai_next) { 1192 for (d = dsts; d; d = d->ai_next) { 1193 /* rewind pointer */ 1194 l = l0; 1195 1196 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 1197 continue; 1198 switch (s->ai_addr->sa_family) { 1199 case AF_INET: 1200 plen = sizeof(struct in_addr) << 3; 1201 break; 1202 #ifdef INET6 1203 case AF_INET6: 1204 plen = sizeof(struct in6_addr) << 3; 1205 break; 1206 #endif 1207 default: 1208 continue; 1209 } 1210 1211 /* set src */ 1212 sa = s->ai_addr; 1213 salen = sysdep_sa_len(s->ai_addr); 1214 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1215 PFKEY_ALIGN8(salen)); 1216 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 1217 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1218 m_addr.sadb_address_prefixlen = plen; 1219 m_addr.sadb_address_reserved = 0; 1220 1221 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1222 sizeof(m_addr), sa, salen); 1223 1224 /* set dst */ 1225 sa = d->ai_addr; 1226 salen = sysdep_sa_len(d->ai_addr); 1227 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1228 PFKEY_ALIGN8(salen)); 1229 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 1230 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1231 m_addr.sadb_address_prefixlen = plen; 1232 m_addr.sadb_address_reserved = 0; 1233 1234 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1235 sizeof(m_addr), sa, salen); 1236 1237 msg->sadb_msg_len = PFKEY_UNIT64(l); 1238 1239 sendkeymsg(buf, l); 1240 1241 n++; 1242 } 1243 } 1244 1245 if (n == 0) 1246 return -1; 1247 else 1248 return 0; 1249 } 1250 1251 #ifdef SADB_X_EXT_NAT_T_TYPE 1252 static u_int16_t get_port (struct addrinfo *addr) 1253 { 1254 struct sockaddr *s = addr->ai_addr; 1255 u_int16_t port = 0; 1256 1257 switch (s->sa_family) { 1258 case AF_INET: 1259 { 1260 struct sockaddr_in *sin4 = (struct sockaddr_in *)s; 1261 port = ntohs(sin4->sin_port); 1262 break; 1263 } 1264 case AF_INET6: 1265 { 1266 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)s; 1267 port = ntohs(sin6->sin6_port); 1268 break; 1269 } 1270 } 1271 1272 if (port == 0) 1273 port = DEFAULT_NATT_PORT; 1274 1275 return port; 1276 } 1277 #endif 1278 1279 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 1280 static int 1281 setkeymsg_add(type, satype, srcs, dsts) 1282 unsigned int type; 1283 unsigned int satype; 1284 struct addrinfo *srcs; 1285 struct addrinfo *dsts; 1286 { 1287 struct sadb_msg *msg; 1288 char buf[BUFSIZ]; 1289 int l, l0, len; 1290 struct sadb_sa m_sa; 1291 struct sadb_x_sa2 m_sa2; 1292 struct sadb_address m_addr; 1293 struct addrinfo *s, *d; 1294 int n; 1295 int plen; 1296 struct sockaddr *sa; 1297 int salen; 1298 1299 msg = (struct sadb_msg *)buf; 1300 1301 if (!srcs || !dsts) 1302 return -1; 1303 1304 /* fix up length afterwards */ 1305 setkeymsg0(msg, type, satype, 0); 1306 l = sizeof(struct sadb_msg); 1307 1308 /* set encryption algorithm, if present. */ 1309 if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) { 1310 union { 1311 struct sadb_key key; 1312 struct sadb_ext ext; 1313 } m; 1314 1315 m.key.sadb_key_len = 1316 PFKEY_UNIT64(sizeof(m.key) 1317 + PFKEY_ALIGN8(p_key_enc_len)); 1318 m.key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; 1319 m.key.sadb_key_bits = p_key_enc_len * 8; 1320 m.key.sadb_key_reserved = 0; 1321 1322 setvarbuf(buf, &l, &m.ext, sizeof(m.key), 1323 p_key_enc, p_key_enc_len); 1324 } 1325 1326 /* set authentication algorithm, if present. */ 1327 if (p_key_auth) { 1328 union { 1329 struct sadb_key key; 1330 struct sadb_ext ext; 1331 } m; 1332 1333 m.key.sadb_key_len = 1334 PFKEY_UNIT64(sizeof(m.key) 1335 + PFKEY_ALIGN8(p_key_auth_len)); 1336 m.key.sadb_key_exttype = SADB_EXT_KEY_AUTH; 1337 m.key.sadb_key_bits = p_key_auth_len * 8; 1338 m.key.sadb_key_reserved = 0; 1339 1340 setvarbuf(buf, &l, &m.ext, sizeof(m.key), 1341 p_key_auth, p_key_auth_len); 1342 } 1343 1344 /* set lifetime for HARD */ 1345 if (p_lt_hard != 0 || p_lb_hard != 0) { 1346 struct sadb_lifetime m_lt; 1347 u_int slen = sizeof(struct sadb_lifetime); 1348 1349 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); 1350 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; 1351 m_lt.sadb_lifetime_allocations = 0; 1352 m_lt.sadb_lifetime_bytes = p_lb_hard; 1353 m_lt.sadb_lifetime_addtime = p_lt_hard; 1354 m_lt.sadb_lifetime_usetime = 0; 1355 1356 memcpy(buf + l, &m_lt, slen); 1357 l += slen; 1358 } 1359 1360 /* set lifetime for SOFT */ 1361 if (p_lt_soft != 0 || p_lb_soft != 0) { 1362 struct sadb_lifetime m_lt; 1363 u_int slen = sizeof(struct sadb_lifetime); 1364 1365 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); 1366 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; 1367 m_lt.sadb_lifetime_allocations = 0; 1368 m_lt.sadb_lifetime_bytes = p_lb_soft; 1369 m_lt.sadb_lifetime_addtime = p_lt_soft; 1370 m_lt.sadb_lifetime_usetime = 0; 1371 1372 memcpy(buf + l, &m_lt, slen); 1373 l += slen; 1374 } 1375 1376 #ifdef SADB_X_EXT_SEC_CTX 1377 /* Add security context label */ 1378 if (sec_ctx.doi) { 1379 struct sadb_x_sec_ctx m_sec_ctx; 1380 u_int slen = sizeof(struct sadb_x_sec_ctx); 1381 1382 memset(&m_sec_ctx, 0, slen); 1383 1384 m_sec_ctx.sadb_x_sec_len = PFKEY_UNIT64(slen + 1385 PFKEY_ALIGN8(sec_ctx.len)); 1386 m_sec_ctx.sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX; 1387 m_sec_ctx.sadb_x_ctx_len = sec_ctx.len; /* bytes */ 1388 m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi; 1389 m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg; 1390 setvarbuf(buf, &l, (struct sadb_ext *)&m_sec_ctx, slen, 1391 (caddr_t)sec_ctx.buf, sec_ctx.len); 1392 } 1393 #endif 1394 1395 len = sizeof(struct sadb_sa); 1396 m_sa.sadb_sa_len = PFKEY_UNIT64(len); 1397 m_sa.sadb_sa_exttype = SADB_EXT_SA; 1398 m_sa.sadb_sa_spi = htonl(p_spi); 1399 m_sa.sadb_sa_replay = p_replay; 1400 m_sa.sadb_sa_state = 0; 1401 m_sa.sadb_sa_auth = p_alg_auth; 1402 m_sa.sadb_sa_encrypt = p_alg_enc; 1403 m_sa.sadb_sa_flags = p_ext; 1404 1405 memcpy(buf + l, &m_sa, len); 1406 l += len; 1407 1408 len = sizeof(struct sadb_x_sa2); 1409 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 1410 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 1411 m_sa2.sadb_x_sa2_mode = p_mode; 1412 m_sa2.sadb_x_sa2_reqid = p_reqid; 1413 1414 memcpy(buf + l, &m_sa2, len); 1415 l += len; 1416 1417 #ifdef SADB_X_EXT_NAT_T_TYPE 1418 if (p_natt_type) { 1419 struct sadb_x_nat_t_type natt_type; 1420 1421 len = sizeof(struct sadb_x_nat_t_type); 1422 memset(&natt_type, 0, len); 1423 natt_type.sadb_x_nat_t_type_len = PFKEY_UNIT64(len); 1424 natt_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE; 1425 natt_type.sadb_x_nat_t_type_type = p_natt_type; 1426 1427 memcpy(buf + l, &natt_type, len); 1428 l += len; 1429 1430 if (p_natt_oa) { 1431 sa = p_natt_oa->ai_addr; 1432 switch (sa->sa_family) { 1433 case AF_INET: 1434 plen = sizeof(struct in_addr) << 3; 1435 break; 1436 #ifdef INET6 1437 case AF_INET6: 1438 plen = sizeof(struct in6_addr) << 3; 1439 break; 1440 #endif 1441 default: 1442 return -1; 1443 } 1444 salen = sysdep_sa_len(sa); 1445 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1446 PFKEY_ALIGN8(salen)); 1447 m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OA; 1448 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1449 m_addr.sadb_address_prefixlen = plen; 1450 m_addr.sadb_address_reserved = 0; 1451 1452 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1453 sizeof(m_addr), sa, salen); 1454 } 1455 } 1456 #endif 1457 1458 l0 = l; 1459 n = 0; 1460 1461 /* do it for all src/dst pairs */ 1462 for (s = srcs; s; s = s->ai_next) { 1463 for (d = dsts; d; d = d->ai_next) { 1464 /* rewind pointer */ 1465 l = l0; 1466 1467 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 1468 continue; 1469 switch (s->ai_addr->sa_family) { 1470 case AF_INET: 1471 plen = sizeof(struct in_addr) << 3; 1472 break; 1473 #ifdef INET6 1474 case AF_INET6: 1475 plen = sizeof(struct in6_addr) << 3; 1476 break; 1477 #endif 1478 default: 1479 continue; 1480 } 1481 1482 /* set src */ 1483 sa = s->ai_addr; 1484 salen = sysdep_sa_len(s->ai_addr); 1485 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1486 PFKEY_ALIGN8(salen)); 1487 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 1488 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1489 m_addr.sadb_address_prefixlen = plen; 1490 m_addr.sadb_address_reserved = 0; 1491 1492 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1493 sizeof(m_addr), sa, salen); 1494 1495 /* set dst */ 1496 sa = d->ai_addr; 1497 salen = sysdep_sa_len(d->ai_addr); 1498 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1499 PFKEY_ALIGN8(salen)); 1500 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 1501 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1502 m_addr.sadb_address_prefixlen = plen; 1503 m_addr.sadb_address_reserved = 0; 1504 1505 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1506 sizeof(m_addr), sa, salen); 1507 1508 #ifdef SADB_X_EXT_NAT_T_TYPE 1509 if (p_natt_type) { 1510 struct sadb_x_nat_t_port natt_port; 1511 1512 /* NATT_SPORT */ 1513 len = sizeof(struct sadb_x_nat_t_port); 1514 memset(&natt_port, 0, len); 1515 natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len); 1516 natt_port.sadb_x_nat_t_port_exttype = 1517 SADB_X_EXT_NAT_T_SPORT; 1518 natt_port.sadb_x_nat_t_port_port = htons(get_port(s)); 1519 1520 memcpy(buf + l, &natt_port, len); 1521 l += len; 1522 1523 /* NATT_DPORT */ 1524 natt_port.sadb_x_nat_t_port_exttype = 1525 SADB_X_EXT_NAT_T_DPORT; 1526 natt_port.sadb_x_nat_t_port_port = htons(get_port(d)); 1527 1528 memcpy(buf + l, &natt_port, len); 1529 l += len; 1530 #ifdef SADB_X_EXT_NAT_T_FRAG 1531 if (p_esp_frag) { 1532 struct sadb_x_nat_t_frag esp_frag; 1533 1534 /* NATT_FRAG */ 1535 len = sizeof(struct sadb_x_nat_t_frag); 1536 memset(&esp_frag, 0, len); 1537 esp_frag.sadb_x_nat_t_frag_len = PFKEY_UNIT64(len); 1538 esp_frag.sadb_x_nat_t_frag_exttype = 1539 SADB_X_EXT_NAT_T_FRAG; 1540 esp_frag.sadb_x_nat_t_frag_fraglen = p_esp_frag; 1541 1542 memcpy(buf + l, &esp_frag, len); 1543 l += len; 1544 } 1545 #endif 1546 } 1547 #endif 1548 msg->sadb_msg_len = PFKEY_UNIT64(l); 1549 1550 sendkeymsg(buf, l); 1551 1552 n++; 1553 } 1554 } 1555 1556 if (n == 0) 1557 return -1; 1558 else 1559 return 0; 1560 } 1561 1562 static struct addrinfo * 1563 parse_addr(host, port) 1564 char *host; 1565 char *port; 1566 { 1567 struct addrinfo hints, *res = NULL; 1568 int error; 1569 1570 memset(&hints, 0, sizeof(hints)); 1571 hints.ai_family = p_aifamily; 1572 hints.ai_socktype = SOCK_DGRAM; /*dummy*/ 1573 hints.ai_protocol = IPPROTO_UDP; /*dummy*/ 1574 hints.ai_flags = p_aiflags; 1575 error = getaddrinfo(host, port, &hints, &res); 1576 if (error != 0) { 1577 yyerror(gai_strerror(error)); 1578 return NULL; 1579 } 1580 return res; 1581 } 1582 1583 static int 1584 fix_portstr(ulproto, spec, sport, dport) 1585 int ulproto; 1586 vchar_t *spec, *sport, *dport; 1587 { 1588 char sp[16], dp[16]; 1589 int a, b, c, d; 1590 unsigned long u; 1591 1592 if (spec->buf == NULL) 1593 return 0; 1594 1595 switch (ulproto) { 1596 case IPPROTO_ICMP: 1597 case IPPROTO_ICMPV6: 1598 case IPPROTO_MH: 1599 if (sscanf(spec->buf, "%d,%d", &a, &b) == 2) { 1600 sprintf(sp, "%d", a); 1601 sprintf(dp, "%d", b); 1602 } else if (sscanf(spec->buf, "%d", &a) == 1) { 1603 sprintf(sp, "%d", a); 1604 } else { 1605 yyerror("invalid an upper layer protocol spec"); 1606 return -1; 1607 } 1608 break; 1609 case IPPROTO_GRE: 1610 if (sscanf(spec->buf, "%d.%d.%d.%d", &a, &b, &c, &d) == 4) { 1611 sprintf(sp, "%d", (a << 8) + b); 1612 sprintf(dp, "%d", (c << 8) + d); 1613 } else if (sscanf(spec->buf, "%lu", &u) == 1) { 1614 sprintf(sp, "%d", (int) (u >> 16)); 1615 sprintf(dp, "%d", (int) (u & 0xffff)); 1616 } else { 1617 yyerror("invalid an upper layer protocol spec"); 1618 return -1; 1619 } 1620 break; 1621 } 1622 1623 free(sport->buf); 1624 sport->buf = strdup(sp); 1625 if (!sport->buf) { 1626 yyerror("insufficient memory"); 1627 return -1; 1628 } 1629 sport->len = strlen(sport->buf); 1630 1631 free(dport->buf); 1632 dport->buf = strdup(dp); 1633 if (!dport->buf) { 1634 yyerror("insufficient memory"); 1635 return -1; 1636 } 1637 dport->len = strlen(dport->buf); 1638 1639 return 0; 1640 } 1641 1642 static int 1643 setvarbuf(buf, off, ebuf, elen, vbuf, vlen) 1644 char *buf; 1645 int *off; 1646 struct sadb_ext *ebuf; 1647 int elen; 1648 const void *vbuf; 1649 int vlen; 1650 { 1651 memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len)); 1652 memcpy(buf + *off, (caddr_t)ebuf, elen); 1653 memcpy(buf + *off + elen, vbuf, vlen); 1654 (*off) += PFKEY_ALIGN8(elen + vlen); 1655 1656 return 0; 1657 } 1658 1659 void 1660 parse_init() 1661 { 1662 p_spi = 0; 1663 1664 p_ext = SADB_X_EXT_CYCSEQ; 1665 p_alg_enc = SADB_EALG_NONE; 1666 p_alg_auth = SADB_AALG_NONE; 1667 p_mode = IPSEC_MODE_ANY; 1668 p_reqid = 0; 1669 p_replay = 0; 1670 p_key_enc_len = p_key_auth_len = 0; 1671 p_key_enc = p_key_auth = 0; 1672 p_lt_hard = p_lt_soft = 0; 1673 p_lb_hard = p_lb_soft = 0; 1674 1675 memset(&sec_ctx, 0, sizeof(struct security_ctx)); 1676 1677 p_aiflags = 0; 1678 p_aifamily = PF_UNSPEC; 1679 1680 /* Clear out any natt OA information */ 1681 if (p_natt_oa) 1682 freeaddrinfo (p_natt_oa); 1683 p_natt_oa = NULL; 1684 p_natt_type = 0; 1685 p_esp_frag = 0; 1686 1687 return; 1688 } 1689 1690 void 1691 free_buffer() 1692 { 1693 /* we got tons of memory leaks in the parser anyways, leave them */ 1694 1695 return; 1696 } 1697