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