1 /* $NetBSD: parse.y,v 1.17 2014/09/10 21:04:08 christos 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 portstr_notempty 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_notempty 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 | portstr_notempty 801 ; 802 803 portstr_notempty 804 : BLCL ANY ELCL 805 { 806 $$.buf = strdup("0"); 807 if (!$$.buf) { 808 yyerror("insufficient memory"); 809 return -1; 810 } 811 $$.len = strlen($$.buf); 812 } 813 | BLCL DECSTRING ELCL 814 { 815 char buf[20]; 816 snprintf(buf, sizeof(buf), "%lu", $2); 817 $$.buf = strdup(buf); 818 if (!$$.buf) { 819 yyerror("insufficient memory"); 820 return -1; 821 } 822 $$.len = strlen($$.buf); 823 } 824 | BLCL STRING ELCL 825 { 826 $$ = $2; 827 } 828 ; 829 830 upper_spec 831 : DECSTRING { $$ = $1; } 832 | ANY { $$ = IPSEC_ULPROTO_ANY; } 833 | PR_TCP { 834 $$ = IPPROTO_TCP; 835 } 836 | STRING 837 { 838 struct protoent *ent; 839 840 ent = getprotobyname($1.buf); 841 if (ent) 842 $$ = ent->p_proto; 843 else { 844 if (strcmp("icmp6", $1.buf) == 0) { 845 $$ = IPPROTO_ICMPV6; 846 } else if(strcmp("ip4", $1.buf) == 0) { 847 $$ = IPPROTO_IPV4; 848 } else { 849 yyerror("invalid upper layer protocol"); 850 return -1; 851 } 852 } 853 endprotoent(); 854 } 855 ; 856 857 upper_misc_spec 858 : /*NOTHING*/ 859 { 860 $$.buf = NULL; 861 $$.len = 0; 862 } 863 | STRING 864 { 865 $$.buf = strdup($1.buf); 866 if (!$$.buf) { 867 yyerror("insufficient memory"); 868 return -1; 869 } 870 $$.len = strlen($$.buf); 871 } 872 ; 873 874 context_spec 875 : /* NOTHING */ 876 | SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING { 877 sec_ctx.doi = $2; 878 sec_ctx.alg = $3; 879 sec_ctx.len = $4.len+1; 880 sec_ctx.buf = $4.buf; 881 } 882 ; 883 884 policy_spec 885 : F_POLICY policy_requests 886 { 887 char *policy; 888 #ifdef HAVE_PFKEY_POLICY_PRIORITY 889 struct sadb_x_policy *xpl; 890 #endif 891 892 policy = ipsec_set_policy($2.buf, $2.len); 893 if (policy == NULL) { 894 yyerror(ipsec_strerror()); 895 return -1; 896 } 897 898 $$.buf = policy; 899 $$.len = ipsec_get_policylen(policy); 900 901 #ifdef HAVE_PFKEY_POLICY_PRIORITY 902 xpl = (struct sadb_x_policy *) $$.buf; 903 last_priority = xpl->sadb_x_policy_priority; 904 #endif 905 } 906 ; 907 908 policy_requests 909 : PL_REQUESTS { $$ = $1; } 910 ; 911 912 /* exit */ 913 exit_command 914 : EXIT EOT 915 { 916 exit_now = 1; 917 YYACCEPT; 918 } 919 ; 920 %% 921 922 int 923 setkeymsg0(msg, type, satype, l) 924 struct sadb_msg *msg; 925 unsigned int type; 926 unsigned int satype; 927 size_t l; 928 { 929 930 msg->sadb_msg_version = PF_KEY_V2; 931 msg->sadb_msg_type = type; 932 msg->sadb_msg_errno = 0; 933 msg->sadb_msg_satype = satype; 934 msg->sadb_msg_reserved = 0; 935 msg->sadb_msg_seq = 0; 936 msg->sadb_msg_pid = getpid(); 937 msg->sadb_msg_len = PFKEY_UNIT64(l); 938 return 0; 939 } 940 941 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 942 static int 943 setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen) 944 unsigned int type; 945 unsigned int upper; 946 vchar_t *policy; 947 struct addrinfo *srcs; 948 int splen; 949 struct addrinfo *dsts; 950 int dplen; 951 { 952 struct sadb_msg *msg; 953 char buf[BUFSIZ]; 954 int l, l0; 955 struct sadb_address m_addr; 956 struct addrinfo *s, *d; 957 int n; 958 int plen; 959 struct sockaddr *sa; 960 int salen; 961 #ifdef HAVE_POLICY_FWD 962 struct sadb_x_ipsecrequest *ps = NULL; 963 int saved_level, saved_id = 0; 964 #endif 965 966 msg = (struct sadb_msg *)buf; 967 968 if (!srcs || !dsts) 969 return -1; 970 971 /* fix up length afterwards */ 972 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0); 973 l = sizeof(struct sadb_msg); 974 975 memcpy(buf + l, policy->buf, policy->len); 976 l += policy->len; 977 978 l0 = l; 979 n = 0; 980 981 /* do it for all src/dst pairs */ 982 for (s = srcs; s; s = s->ai_next) { 983 for (d = dsts; d; d = d->ai_next) { 984 /* rewind pointer */ 985 l = l0; 986 987 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 988 continue; 989 switch (s->ai_addr->sa_family) { 990 case AF_INET: 991 plen = sizeof(struct in_addr) << 3; 992 break; 993 #ifdef INET6 994 case AF_INET6: 995 plen = sizeof(struct in6_addr) << 3; 996 break; 997 #endif 998 default: 999 continue; 1000 } 1001 1002 /* set src */ 1003 sa = s->ai_addr; 1004 salen = sysdep_sa_len(s->ai_addr); 1005 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1006 PFKEY_ALIGN8(salen)); 1007 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 1008 m_addr.sadb_address_proto = upper; 1009 m_addr.sadb_address_prefixlen = 1010 (splen >= 0 ? splen : plen); 1011 m_addr.sadb_address_reserved = 0; 1012 1013 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1014 sizeof(m_addr), (caddr_t)sa, salen); 1015 1016 /* set dst */ 1017 sa = d->ai_addr; 1018 salen = sysdep_sa_len(d->ai_addr); 1019 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1020 PFKEY_ALIGN8(salen)); 1021 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 1022 m_addr.sadb_address_proto = upper; 1023 m_addr.sadb_address_prefixlen = 1024 (dplen >= 0 ? dplen : plen); 1025 m_addr.sadb_address_reserved = 0; 1026 1027 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1028 sizeof(m_addr), sa, salen); 1029 #ifdef SADB_X_EXT_SEC_CTX 1030 /* Add security context label */ 1031 if (sec_ctx.doi) { 1032 struct sadb_x_sec_ctx m_sec_ctx; 1033 u_int slen = sizeof(struct sadb_x_sec_ctx); 1034 1035 memset(&m_sec_ctx, 0, slen); 1036 1037 m_sec_ctx.sadb_x_sec_len = 1038 PFKEY_UNIT64(slen + PFKEY_ALIGN8(sec_ctx.len)); 1039 1040 m_sec_ctx.sadb_x_sec_exttype = 1041 SADB_X_EXT_SEC_CTX; 1042 m_sec_ctx.sadb_x_ctx_len = sec_ctx.len;/*bytes*/ 1043 m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi; 1044 m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg; 1045 setvarbuf(buf, &l, 1046 (struct sadb_ext *)&m_sec_ctx, slen, 1047 (caddr_t)sec_ctx.buf, sec_ctx.len); 1048 } 1049 #endif 1050 msg->sadb_msg_len = PFKEY_UNIT64(l); 1051 1052 sendkeymsg(buf, l); 1053 1054 #ifdef HAVE_POLICY_FWD 1055 /* create extra call for FWD policy */ 1056 if (f_rfcmode && sp->sadb_x_policy_dir == IPSEC_DIR_INBOUND) { 1057 sp->sadb_x_policy_dir = IPSEC_DIR_FWD; 1058 ps = (struct sadb_x_ipsecrequest*) (sp+1); 1059 1060 /* if request level is unique, change it to 1061 * require for fwd policy */ 1062 /* XXX: currently, only first policy is updated 1063 * only. Update following too... */ 1064 saved_level = ps->sadb_x_ipsecrequest_level; 1065 if (saved_level == IPSEC_LEVEL_UNIQUE) { 1066 saved_id = ps->sadb_x_ipsecrequest_reqid; 1067 ps->sadb_x_ipsecrequest_reqid=0; 1068 ps->sadb_x_ipsecrequest_level=IPSEC_LEVEL_REQUIRE; 1069 } 1070 1071 sendkeymsg(buf, l); 1072 /* restoring for next message */ 1073 sp->sadb_x_policy_dir = IPSEC_DIR_INBOUND; 1074 if (saved_level == IPSEC_LEVEL_UNIQUE) { 1075 ps->sadb_x_ipsecrequest_reqid = saved_id; 1076 ps->sadb_x_ipsecrequest_level = saved_level; 1077 } 1078 } 1079 #endif 1080 1081 n++; 1082 } 1083 } 1084 1085 if (n == 0) 1086 return -1; 1087 else 1088 return 0; 1089 } 1090 1091 static int 1092 setkeymsg_spdaddr_tag(type, tag, policy) 1093 unsigned int type; 1094 char *tag; 1095 vchar_t *policy; 1096 { 1097 struct sadb_msg *msg; 1098 char buf[BUFSIZ]; 1099 int l; 1100 #ifdef SADB_X_EXT_TAG 1101 struct sadb_x_tag m_tag; 1102 #endif 1103 1104 msg = (struct sadb_msg *)buf; 1105 1106 /* fix up length afterwards */ 1107 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0); 1108 l = sizeof(struct sadb_msg); 1109 1110 memcpy(buf + l, policy->buf, policy->len); 1111 l += policy->len; 1112 1113 #ifdef SADB_X_EXT_TAG 1114 memset(&m_tag, 0, sizeof(m_tag)); 1115 m_tag.sadb_x_tag_len = PFKEY_UNIT64(sizeof(m_tag)); 1116 m_tag.sadb_x_tag_exttype = SADB_X_EXT_TAG; 1117 if (strlcpy(m_tag.sadb_x_tag_name, tag, 1118 sizeof(m_tag.sadb_x_tag_name)) >= sizeof(m_tag.sadb_x_tag_name)) 1119 return -1; 1120 memcpy(buf + l, &m_tag, sizeof(m_tag)); 1121 l += sizeof(m_tag); 1122 #endif 1123 1124 msg->sadb_msg_len = PFKEY_UNIT64(l); 1125 1126 sendkeymsg(buf, l); 1127 1128 return 0; 1129 } 1130 1131 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 1132 static int 1133 setkeymsg_addr(type, satype, srcs, dsts, no_spi) 1134 unsigned int type; 1135 unsigned int satype; 1136 struct addrinfo *srcs; 1137 struct addrinfo *dsts; 1138 int no_spi; 1139 { 1140 struct sadb_msg *msg; 1141 char buf[BUFSIZ]; 1142 int l, l0, len; 1143 struct sadb_sa m_sa; 1144 struct sadb_x_sa2 m_sa2; 1145 struct sadb_address m_addr; 1146 struct addrinfo *s, *d; 1147 int n; 1148 int plen; 1149 struct sockaddr *sa; 1150 int salen; 1151 1152 msg = (struct sadb_msg *)buf; 1153 1154 if (!srcs || !dsts) 1155 return -1; 1156 1157 /* fix up length afterwards */ 1158 setkeymsg0(msg, type, satype, 0); 1159 l = sizeof(struct sadb_msg); 1160 1161 if (!no_spi) { 1162 len = sizeof(struct sadb_sa); 1163 m_sa.sadb_sa_len = PFKEY_UNIT64(len); 1164 m_sa.sadb_sa_exttype = SADB_EXT_SA; 1165 m_sa.sadb_sa_spi = htonl(p_spi); 1166 m_sa.sadb_sa_replay = p_replay; 1167 m_sa.sadb_sa_state = 0; 1168 m_sa.sadb_sa_auth = p_alg_auth; 1169 m_sa.sadb_sa_encrypt = p_alg_enc; 1170 m_sa.sadb_sa_flags = p_ext; 1171 1172 memcpy(buf + l, &m_sa, len); 1173 l += len; 1174 1175 len = sizeof(struct sadb_x_sa2); 1176 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 1177 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 1178 m_sa2.sadb_x_sa2_mode = p_mode; 1179 m_sa2.sadb_x_sa2_reqid = p_reqid; 1180 1181 memcpy(buf + l, &m_sa2, len); 1182 l += len; 1183 } 1184 1185 l0 = l; 1186 n = 0; 1187 1188 /* do it for all src/dst pairs */ 1189 for (s = srcs; s; s = s->ai_next) { 1190 for (d = dsts; d; d = d->ai_next) { 1191 /* rewind pointer */ 1192 l = l0; 1193 1194 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 1195 continue; 1196 switch (s->ai_addr->sa_family) { 1197 case AF_INET: 1198 plen = sizeof(struct in_addr) << 3; 1199 break; 1200 #ifdef INET6 1201 case AF_INET6: 1202 plen = sizeof(struct in6_addr) << 3; 1203 break; 1204 #endif 1205 default: 1206 continue; 1207 } 1208 1209 /* set src */ 1210 sa = s->ai_addr; 1211 salen = sysdep_sa_len(s->ai_addr); 1212 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1213 PFKEY_ALIGN8(salen)); 1214 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 1215 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1216 m_addr.sadb_address_prefixlen = plen; 1217 m_addr.sadb_address_reserved = 0; 1218 1219 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1220 sizeof(m_addr), sa, salen); 1221 1222 /* set dst */ 1223 sa = d->ai_addr; 1224 salen = sysdep_sa_len(d->ai_addr); 1225 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1226 PFKEY_ALIGN8(salen)); 1227 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 1228 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1229 m_addr.sadb_address_prefixlen = plen; 1230 m_addr.sadb_address_reserved = 0; 1231 1232 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1233 sizeof(m_addr), sa, salen); 1234 1235 msg->sadb_msg_len = PFKEY_UNIT64(l); 1236 1237 sendkeymsg(buf, l); 1238 1239 n++; 1240 } 1241 } 1242 1243 if (n == 0) 1244 return -1; 1245 else 1246 return 0; 1247 } 1248 1249 #ifdef SADB_X_EXT_NAT_T_TYPE 1250 static u_int16_t get_port (struct addrinfo *addr) 1251 { 1252 struct sockaddr *s = addr->ai_addr; 1253 u_int16_t port = 0; 1254 1255 switch (s->sa_family) { 1256 case AF_INET: 1257 { 1258 struct sockaddr_in *sin4 = (struct sockaddr_in *)s; 1259 port = ntohs(sin4->sin_port); 1260 break; 1261 } 1262 case AF_INET6: 1263 { 1264 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)s; 1265 port = ntohs(sin6->sin6_port); 1266 break; 1267 } 1268 } 1269 1270 if (port == 0) 1271 port = DEFAULT_NATT_PORT; 1272 1273 return port; 1274 } 1275 #endif 1276 1277 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 1278 static int 1279 setkeymsg_add(type, satype, srcs, dsts) 1280 unsigned int type; 1281 unsigned int satype; 1282 struct addrinfo *srcs; 1283 struct addrinfo *dsts; 1284 { 1285 struct sadb_msg *msg; 1286 char buf[BUFSIZ]; 1287 int l, l0, len; 1288 struct sadb_sa m_sa; 1289 struct sadb_x_sa2 m_sa2; 1290 struct sadb_address m_addr; 1291 struct addrinfo *s, *d; 1292 int n; 1293 int plen; 1294 struct sockaddr *sa; 1295 int salen; 1296 1297 msg = (struct sadb_msg *)buf; 1298 1299 if (!srcs || !dsts) 1300 return -1; 1301 1302 /* fix up length afterwards */ 1303 setkeymsg0(msg, type, satype, 0); 1304 l = sizeof(struct sadb_msg); 1305 1306 /* set encryption algorithm, if present. */ 1307 if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) { 1308 union { 1309 struct sadb_key key; 1310 struct sadb_ext ext; 1311 } m; 1312 1313 m.key.sadb_key_len = 1314 PFKEY_UNIT64(sizeof(m.key) 1315 + PFKEY_ALIGN8(p_key_enc_len)); 1316 m.key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; 1317 m.key.sadb_key_bits = p_key_enc_len * 8; 1318 m.key.sadb_key_reserved = 0; 1319 1320 setvarbuf(buf, &l, &m.ext, sizeof(m.key), 1321 p_key_enc, p_key_enc_len); 1322 } 1323 1324 /* set authentication algorithm, if present. */ 1325 if (p_key_auth) { 1326 union { 1327 struct sadb_key key; 1328 struct sadb_ext ext; 1329 } m; 1330 1331 m.key.sadb_key_len = 1332 PFKEY_UNIT64(sizeof(m.key) 1333 + PFKEY_ALIGN8(p_key_auth_len)); 1334 m.key.sadb_key_exttype = SADB_EXT_KEY_AUTH; 1335 m.key.sadb_key_bits = p_key_auth_len * 8; 1336 m.key.sadb_key_reserved = 0; 1337 1338 setvarbuf(buf, &l, &m.ext, sizeof(m.key), 1339 p_key_auth, p_key_auth_len); 1340 } 1341 1342 /* set lifetime for HARD */ 1343 if (p_lt_hard != 0 || p_lb_hard != 0) { 1344 struct sadb_lifetime m_lt; 1345 u_int slen = sizeof(struct sadb_lifetime); 1346 1347 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); 1348 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; 1349 m_lt.sadb_lifetime_allocations = 0; 1350 m_lt.sadb_lifetime_bytes = p_lb_hard; 1351 m_lt.sadb_lifetime_addtime = p_lt_hard; 1352 m_lt.sadb_lifetime_usetime = 0; 1353 1354 memcpy(buf + l, &m_lt, slen); 1355 l += slen; 1356 } 1357 1358 /* set lifetime for SOFT */ 1359 if (p_lt_soft != 0 || p_lb_soft != 0) { 1360 struct sadb_lifetime m_lt; 1361 u_int slen = sizeof(struct sadb_lifetime); 1362 1363 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); 1364 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; 1365 m_lt.sadb_lifetime_allocations = 0; 1366 m_lt.sadb_lifetime_bytes = p_lb_soft; 1367 m_lt.sadb_lifetime_addtime = p_lt_soft; 1368 m_lt.sadb_lifetime_usetime = 0; 1369 1370 memcpy(buf + l, &m_lt, slen); 1371 l += slen; 1372 } 1373 1374 #ifdef SADB_X_EXT_SEC_CTX 1375 /* Add security context label */ 1376 if (sec_ctx.doi) { 1377 struct sadb_x_sec_ctx m_sec_ctx; 1378 u_int slen = sizeof(struct sadb_x_sec_ctx); 1379 1380 memset(&m_sec_ctx, 0, slen); 1381 1382 m_sec_ctx.sadb_x_sec_len = PFKEY_UNIT64(slen + 1383 PFKEY_ALIGN8(sec_ctx.len)); 1384 m_sec_ctx.sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX; 1385 m_sec_ctx.sadb_x_ctx_len = sec_ctx.len; /* bytes */ 1386 m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi; 1387 m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg; 1388 setvarbuf(buf, &l, (struct sadb_ext *)&m_sec_ctx, slen, 1389 (caddr_t)sec_ctx.buf, sec_ctx.len); 1390 } 1391 #endif 1392 1393 len = sizeof(struct sadb_sa); 1394 m_sa.sadb_sa_len = PFKEY_UNIT64(len); 1395 m_sa.sadb_sa_exttype = SADB_EXT_SA; 1396 m_sa.sadb_sa_spi = htonl(p_spi); 1397 m_sa.sadb_sa_replay = p_replay; 1398 m_sa.sadb_sa_state = 0; 1399 m_sa.sadb_sa_auth = p_alg_auth; 1400 m_sa.sadb_sa_encrypt = p_alg_enc; 1401 m_sa.sadb_sa_flags = p_ext; 1402 1403 memcpy(buf + l, &m_sa, len); 1404 l += len; 1405 1406 len = sizeof(struct sadb_x_sa2); 1407 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 1408 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 1409 m_sa2.sadb_x_sa2_mode = p_mode; 1410 m_sa2.sadb_x_sa2_reqid = p_reqid; 1411 1412 memcpy(buf + l, &m_sa2, len); 1413 l += len; 1414 1415 #ifdef SADB_X_EXT_NAT_T_TYPE 1416 if (p_natt_type) { 1417 struct sadb_x_nat_t_type natt_type; 1418 1419 len = sizeof(struct sadb_x_nat_t_type); 1420 memset(&natt_type, 0, len); 1421 natt_type.sadb_x_nat_t_type_len = PFKEY_UNIT64(len); 1422 natt_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE; 1423 natt_type.sadb_x_nat_t_type_type = p_natt_type; 1424 1425 memcpy(buf + l, &natt_type, len); 1426 l += len; 1427 1428 if (p_natt_oa) { 1429 sa = p_natt_oa->ai_addr; 1430 switch (sa->sa_family) { 1431 case AF_INET: 1432 plen = sizeof(struct in_addr) << 3; 1433 break; 1434 #ifdef INET6 1435 case AF_INET6: 1436 plen = sizeof(struct in6_addr) << 3; 1437 break; 1438 #endif 1439 default: 1440 return -1; 1441 } 1442 salen = sysdep_sa_len(sa); 1443 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1444 PFKEY_ALIGN8(salen)); 1445 m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OA; 1446 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1447 m_addr.sadb_address_prefixlen = plen; 1448 m_addr.sadb_address_reserved = 0; 1449 1450 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1451 sizeof(m_addr), sa, salen); 1452 } 1453 } 1454 #endif 1455 1456 l0 = l; 1457 n = 0; 1458 1459 /* do it for all src/dst pairs */ 1460 for (s = srcs; s; s = s->ai_next) { 1461 for (d = dsts; d; d = d->ai_next) { 1462 /* rewind pointer */ 1463 l = l0; 1464 1465 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 1466 continue; 1467 switch (s->ai_addr->sa_family) { 1468 case AF_INET: 1469 plen = sizeof(struct in_addr) << 3; 1470 break; 1471 #ifdef INET6 1472 case AF_INET6: 1473 plen = sizeof(struct in6_addr) << 3; 1474 break; 1475 #endif 1476 default: 1477 continue; 1478 } 1479 1480 /* set src */ 1481 sa = s->ai_addr; 1482 salen = sysdep_sa_len(s->ai_addr); 1483 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1484 PFKEY_ALIGN8(salen)); 1485 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 1486 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1487 m_addr.sadb_address_prefixlen = plen; 1488 m_addr.sadb_address_reserved = 0; 1489 1490 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1491 sizeof(m_addr), sa, salen); 1492 1493 /* set dst */ 1494 sa = d->ai_addr; 1495 salen = sysdep_sa_len(d->ai_addr); 1496 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1497 PFKEY_ALIGN8(salen)); 1498 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 1499 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1500 m_addr.sadb_address_prefixlen = plen; 1501 m_addr.sadb_address_reserved = 0; 1502 1503 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1504 sizeof(m_addr), sa, salen); 1505 1506 #ifdef SADB_X_EXT_NAT_T_TYPE 1507 if (p_natt_type) { 1508 struct sadb_x_nat_t_port natt_port; 1509 1510 /* NATT_SPORT */ 1511 len = sizeof(struct sadb_x_nat_t_port); 1512 memset(&natt_port, 0, len); 1513 natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len); 1514 natt_port.sadb_x_nat_t_port_exttype = 1515 SADB_X_EXT_NAT_T_SPORT; 1516 natt_port.sadb_x_nat_t_port_port = htons(get_port(s)); 1517 1518 memcpy(buf + l, &natt_port, len); 1519 l += len; 1520 1521 /* NATT_DPORT */ 1522 natt_port.sadb_x_nat_t_port_exttype = 1523 SADB_X_EXT_NAT_T_DPORT; 1524 natt_port.sadb_x_nat_t_port_port = htons(get_port(d)); 1525 1526 memcpy(buf + l, &natt_port, len); 1527 l += len; 1528 #ifdef SADB_X_EXT_NAT_T_FRAG 1529 if (p_esp_frag) { 1530 struct sadb_x_nat_t_frag esp_frag; 1531 1532 /* NATT_FRAG */ 1533 len = sizeof(struct sadb_x_nat_t_frag); 1534 memset(&esp_frag, 0, len); 1535 esp_frag.sadb_x_nat_t_frag_len = PFKEY_UNIT64(len); 1536 esp_frag.sadb_x_nat_t_frag_exttype = 1537 SADB_X_EXT_NAT_T_FRAG; 1538 esp_frag.sadb_x_nat_t_frag_fraglen = p_esp_frag; 1539 1540 memcpy(buf + l, &esp_frag, len); 1541 l += len; 1542 } 1543 #endif 1544 } 1545 #endif 1546 msg->sadb_msg_len = PFKEY_UNIT64(l); 1547 1548 sendkeymsg(buf, l); 1549 1550 n++; 1551 } 1552 } 1553 1554 if (n == 0) 1555 return -1; 1556 else 1557 return 0; 1558 } 1559 1560 static struct addrinfo * 1561 parse_addr(host, port) 1562 char *host; 1563 char *port; 1564 { 1565 struct addrinfo hints, *res = NULL; 1566 int error; 1567 1568 memset(&hints, 0, sizeof(hints)); 1569 hints.ai_family = p_aifamily; 1570 hints.ai_socktype = SOCK_DGRAM; /*dummy*/ 1571 hints.ai_protocol = IPPROTO_UDP; /*dummy*/ 1572 hints.ai_flags = p_aiflags; 1573 error = getaddrinfo(host, port, &hints, &res); 1574 if (error != 0) { 1575 yyerror(gai_strerror(error)); 1576 return NULL; 1577 } 1578 return res; 1579 } 1580 1581 static int 1582 fix_portstr(ulproto, spec, sport, dport) 1583 int ulproto; 1584 vchar_t *spec, *sport, *dport; 1585 { 1586 char sp[16], dp[16]; 1587 int a, b, c, d; 1588 unsigned long u; 1589 1590 if (spec->buf == NULL) 1591 return 0; 1592 1593 switch (ulproto) { 1594 case IPPROTO_ICMP: 1595 case IPPROTO_ICMPV6: 1596 case IPPROTO_MH: 1597 if (sscanf(spec->buf, "%d,%d", &a, &b) == 2) { 1598 sprintf(sp, "%d", a); 1599 sprintf(dp, "%d", b); 1600 } else if (sscanf(spec->buf, "%d", &a) == 1) { 1601 sprintf(sp, "%d", a); 1602 } else { 1603 yyerror("invalid an upper layer protocol spec"); 1604 return -1; 1605 } 1606 break; 1607 case IPPROTO_GRE: 1608 if (sscanf(spec->buf, "%d.%d.%d.%d", &a, &b, &c, &d) == 4) { 1609 sprintf(sp, "%d", (a << 8) + b); 1610 sprintf(dp, "%d", (c << 8) + d); 1611 } else if (sscanf(spec->buf, "%lu", &u) == 1) { 1612 sprintf(sp, "%d", (int) (u >> 16)); 1613 sprintf(dp, "%d", (int) (u & 0xffff)); 1614 } else { 1615 yyerror("invalid an upper layer protocol spec"); 1616 return -1; 1617 } 1618 break; 1619 } 1620 1621 free(sport->buf); 1622 sport->buf = strdup(sp); 1623 if (!sport->buf) { 1624 yyerror("insufficient memory"); 1625 return -1; 1626 } 1627 sport->len = strlen(sport->buf); 1628 1629 free(dport->buf); 1630 dport->buf = strdup(dp); 1631 if (!dport->buf) { 1632 yyerror("insufficient memory"); 1633 return -1; 1634 } 1635 dport->len = strlen(dport->buf); 1636 1637 return 0; 1638 } 1639 1640 static int 1641 setvarbuf(buf, off, ebuf, elen, vbuf, vlen) 1642 char *buf; 1643 int *off; 1644 struct sadb_ext *ebuf; 1645 int elen; 1646 const void *vbuf; 1647 int vlen; 1648 { 1649 memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len)); 1650 memcpy(buf + *off, (caddr_t)ebuf, elen); 1651 memcpy(buf + *off + elen, vbuf, vlen); 1652 (*off) += PFKEY_ALIGN8(elen + vlen); 1653 1654 return 0; 1655 } 1656 1657 void 1658 parse_init() 1659 { 1660 p_spi = 0; 1661 1662 p_ext = SADB_X_EXT_CYCSEQ; 1663 p_alg_enc = SADB_EALG_NONE; 1664 p_alg_auth = SADB_AALG_NONE; 1665 p_mode = IPSEC_MODE_ANY; 1666 p_reqid = 0; 1667 p_replay = 0; 1668 p_key_enc_len = p_key_auth_len = 0; 1669 p_key_enc = p_key_auth = 0; 1670 p_lt_hard = p_lt_soft = 0; 1671 p_lb_hard = p_lb_soft = 0; 1672 1673 memset(&sec_ctx, 0, sizeof(struct security_ctx)); 1674 1675 p_aiflags = 0; 1676 p_aifamily = PF_UNSPEC; 1677 1678 /* Clear out any natt OA information */ 1679 if (p_natt_oa) 1680 freeaddrinfo (p_natt_oa); 1681 p_natt_oa = NULL; 1682 p_natt_type = 0; 1683 p_esp_frag = 0; 1684 1685 return; 1686 } 1687 1688 void 1689 free_buffer() 1690 { 1691 /* we got tons of memory leaks in the parser anyways, leave them */ 1692 1693 return; 1694 } 1695