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