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