parse.y revision 125681
1/* $FreeBSD: head/sbin/setkey/parse.y 125681 2004-02-11 04:34:34Z 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 | STRING 676 { 677 struct protoent *ent; 678 679 ent = getprotobyname($1.buf); 680 if (ent) 681 $$ = ent->p_proto; 682 else { 683 if (strcmp("icmp6", $1.buf) == 0) { 684 $$ = IPPROTO_ICMPV6; 685 } else if(strcmp("ip4", $1.buf) == 0) { 686 $$ = IPPROTO_IPV4; 687 } else { 688 yyerror("invalid upper layer protocol"); 689 return -1; 690 } 691 } 692 endprotoent(); 693 } 694 ; 695 696upper_misc_spec 697 : /*NOTHING*/ 698 { 699 $$.buf = NULL; 700 $$.len = 0; 701 } 702 | STRING 703 { 704 $$.buf = strdup($1.buf); 705 if (!$$.buf) { 706 yyerror("insufficient memory"); 707 return -1; 708 } 709 $$.len = strlen($$.buf); 710 } 711 ; 712 713policy_spec 714 : F_POLICY policy_requests 715 { 716 char *policy; 717 718 policy = ipsec_set_policy($2.buf, $2.len); 719 if (policy == NULL) { 720 yyerror(ipsec_strerror()); 721 return -1; 722 } 723 724 $$.buf = policy; 725 $$.len = ipsec_get_policylen(policy); 726 } 727 ; 728 729policy_requests 730 : PL_REQUESTS { $$ = $1; } 731 ; 732 733%% 734 735int 736setkeymsg0(msg, type, satype, l) 737 struct sadb_msg *msg; 738 unsigned int type; 739 unsigned int satype; 740 size_t l; 741{ 742 743 msg->sadb_msg_version = PF_KEY_V2; 744 msg->sadb_msg_type = type; 745 msg->sadb_msg_errno = 0; 746 msg->sadb_msg_satype = satype; 747 msg->sadb_msg_reserved = 0; 748 msg->sadb_msg_seq = 0; 749 msg->sadb_msg_pid = getpid(); 750 msg->sadb_msg_len = PFKEY_UNIT64(l); 751 return 0; 752} 753 754/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 755static int 756setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen) 757 unsigned int type; 758 unsigned int upper; 759 vchar_t *policy; 760 struct addrinfo *srcs; 761 int splen; 762 struct addrinfo *dsts; 763 int dplen; 764{ 765 struct sadb_msg *msg; 766 char buf[BUFSIZ]; 767 int l, l0; 768 struct sadb_address m_addr; 769 struct addrinfo *s, *d; 770 int n; 771 int plen; 772 struct sockaddr *sa; 773 int salen; 774 775 msg = (struct sadb_msg *)buf; 776 777 if (!srcs || !dsts) 778 return -1; 779 780 /* fix up length afterwards */ 781 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0); 782 l = sizeof(struct sadb_msg); 783 784 memcpy(buf + l, policy->buf, policy->len); 785 l += policy->len; 786 787 l0 = l; 788 n = 0; 789 790 /* do it for all src/dst pairs */ 791 for (s = srcs; s; s = s->ai_next) { 792 for (d = dsts; d; d = d->ai_next) { 793 /* rewind pointer */ 794 l = l0; 795 796 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 797 continue; 798 switch (s->ai_addr->sa_family) { 799 case AF_INET: 800 plen = sizeof(struct in_addr) << 3; 801 break; 802#ifdef INET6 803 case AF_INET6: 804 plen = sizeof(struct in6_addr) << 3; 805 break; 806#endif 807 default: 808 continue; 809 } 810 811 /* set src */ 812 sa = s->ai_addr; 813 salen = s->ai_addr->sa_len; 814 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 815 PFKEY_ALIGN8(salen)); 816 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 817 m_addr.sadb_address_proto = upper; 818 m_addr.sadb_address_prefixlen = 819 (splen >= 0 ? splen : plen); 820 m_addr.sadb_address_reserved = 0; 821 822 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 823 sizeof(m_addr), (caddr_t)sa, salen); 824 825 /* set dst */ 826 sa = d->ai_addr; 827 salen = d->ai_addr->sa_len; 828 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 829 PFKEY_ALIGN8(salen)); 830 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 831 m_addr.sadb_address_proto = upper; 832 m_addr.sadb_address_prefixlen = 833 (dplen >= 0 ? dplen : plen); 834 m_addr.sadb_address_reserved = 0; 835 836 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 837 sizeof(m_addr), (caddr_t)sa, salen); 838 839 msg->sadb_msg_len = PFKEY_UNIT64(l); 840 841 sendkeymsg(buf, l); 842 843 n++; 844 } 845 } 846 847 if (n == 0) 848 return -1; 849 else 850 return 0; 851} 852 853/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 854static int 855setkeymsg_addr(type, satype, srcs, dsts, no_spi) 856 unsigned int type; 857 unsigned int satype; 858 struct addrinfo *srcs; 859 struct addrinfo *dsts; 860 int no_spi; 861{ 862 struct sadb_msg *msg; 863 char buf[BUFSIZ]; 864 int l, l0, len; 865 struct sadb_sa m_sa; 866 struct sadb_x_sa2 m_sa2; 867 struct sadb_address m_addr; 868 struct addrinfo *s, *d; 869 int n; 870 int plen; 871 struct sockaddr *sa; 872 int salen; 873 874 msg = (struct sadb_msg *)buf; 875 876 if (!srcs || !dsts) 877 return -1; 878 879 /* fix up length afterwards */ 880 setkeymsg0(msg, type, satype, 0); 881 l = sizeof(struct sadb_msg); 882 883 if (!no_spi) { 884 len = sizeof(struct sadb_sa); 885 m_sa.sadb_sa_len = PFKEY_UNIT64(len); 886 m_sa.sadb_sa_exttype = SADB_EXT_SA; 887 m_sa.sadb_sa_spi = htonl(p_spi); 888 m_sa.sadb_sa_replay = p_replay; 889 m_sa.sadb_sa_state = 0; 890 m_sa.sadb_sa_auth = p_alg_auth; 891 m_sa.sadb_sa_encrypt = p_alg_enc; 892 m_sa.sadb_sa_flags = p_ext; 893 894 memcpy(buf + l, &m_sa, len); 895 l += len; 896 897 len = sizeof(struct sadb_x_sa2); 898 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 899 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 900 m_sa2.sadb_x_sa2_mode = p_mode; 901 m_sa2.sadb_x_sa2_reqid = p_reqid; 902 903 memcpy(buf + l, &m_sa2, len); 904 l += len; 905 } 906 907 l0 = l; 908 n = 0; 909 910 /* do it for all src/dst pairs */ 911 for (s = srcs; s; s = s->ai_next) { 912 for (d = dsts; d; d = d->ai_next) { 913 /* rewind pointer */ 914 l = l0; 915 916 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 917 continue; 918 switch (s->ai_addr->sa_family) { 919 case AF_INET: 920 plen = sizeof(struct in_addr) << 3; 921 break; 922#ifdef INET6 923 case AF_INET6: 924 plen = sizeof(struct in6_addr) << 3; 925 break; 926#endif 927 default: 928 continue; 929 } 930 931 /* set src */ 932 sa = s->ai_addr; 933 salen = s->ai_addr->sa_len; 934 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 935 PFKEY_ALIGN8(salen)); 936 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 937 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 938 m_addr.sadb_address_prefixlen = plen; 939 m_addr.sadb_address_reserved = 0; 940 941 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 942 sizeof(m_addr), (caddr_t)sa, salen); 943 944 /* set dst */ 945 sa = d->ai_addr; 946 salen = d->ai_addr->sa_len; 947 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 948 PFKEY_ALIGN8(salen)); 949 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 950 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 951 m_addr.sadb_address_prefixlen = plen; 952 m_addr.sadb_address_reserved = 0; 953 954 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 955 sizeof(m_addr), (caddr_t)sa, salen); 956 957 msg->sadb_msg_len = PFKEY_UNIT64(l); 958 959 sendkeymsg(buf, l); 960 961 n++; 962 } 963 } 964 965 if (n == 0) 966 return -1; 967 else 968 return 0; 969} 970 971/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 972static int 973setkeymsg_add(type, satype, srcs, dsts) 974 unsigned int type; 975 unsigned int satype; 976 struct addrinfo *srcs; 977 struct addrinfo *dsts; 978{ 979 struct sadb_msg *msg; 980 char buf[BUFSIZ]; 981 int l, l0, len; 982 struct sadb_sa m_sa; 983 struct sadb_x_sa2 m_sa2; 984 struct sadb_address m_addr; 985 struct addrinfo *s, *d; 986 int n; 987 int plen; 988 struct sockaddr *sa; 989 int salen; 990 991 msg = (struct sadb_msg *)buf; 992 993 if (!srcs || !dsts) 994 return -1; 995 996 /* fix up length afterwards */ 997 setkeymsg0(msg, type, satype, 0); 998 l = sizeof(struct sadb_msg); 999 1000 /* set encryption algorithm, if present. */ 1001 if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) { 1002 struct sadb_key m_key; 1003 1004 m_key.sadb_key_len = 1005 PFKEY_UNIT64(sizeof(m_key) 1006 + PFKEY_ALIGN8(p_key_enc_len)); 1007 m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; 1008 m_key.sadb_key_bits = p_key_enc_len * 8; 1009 m_key.sadb_key_reserved = 0; 1010 1011 setvarbuf(buf, &l, 1012 (struct sadb_ext *)&m_key, sizeof(m_key), 1013 (caddr_t)p_key_enc, p_key_enc_len); 1014 } 1015 1016 /* set authentication algorithm, if present. */ 1017 if (p_key_auth) { 1018 struct sadb_key m_key; 1019 1020 m_key.sadb_key_len = 1021 PFKEY_UNIT64(sizeof(m_key) 1022 + PFKEY_ALIGN8(p_key_auth_len)); 1023 m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH; 1024 m_key.sadb_key_bits = p_key_auth_len * 8; 1025 m_key.sadb_key_reserved = 0; 1026 1027 setvarbuf(buf, &l, 1028 (struct sadb_ext *)&m_key, sizeof(m_key), 1029 (caddr_t)p_key_auth, p_key_auth_len); 1030 } 1031 1032 /* set lifetime for HARD */ 1033 if (p_lt_hard != 0) { 1034 struct sadb_lifetime m_lt; 1035 u_int slen = sizeof(struct sadb_lifetime); 1036 1037 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); 1038 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; 1039 m_lt.sadb_lifetime_allocations = 0; 1040 m_lt.sadb_lifetime_bytes = 0; 1041 m_lt.sadb_lifetime_addtime = p_lt_hard; 1042 m_lt.sadb_lifetime_usetime = 0; 1043 1044 memcpy(buf + l, &m_lt, slen); 1045 l += len; 1046 } 1047 1048 /* set lifetime for SOFT */ 1049 if (p_lt_soft != 0) { 1050 struct sadb_lifetime m_lt; 1051 u_int slen = sizeof(struct sadb_lifetime); 1052 1053 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); 1054 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; 1055 m_lt.sadb_lifetime_allocations = 0; 1056 m_lt.sadb_lifetime_bytes = 0; 1057 m_lt.sadb_lifetime_addtime = p_lt_soft; 1058 m_lt.sadb_lifetime_usetime = 0; 1059 1060 memcpy(buf + l, &m_lt, slen); 1061 l += len; 1062 } 1063 1064 len = sizeof(struct sadb_sa); 1065 m_sa.sadb_sa_len = PFKEY_UNIT64(len); 1066 m_sa.sadb_sa_exttype = SADB_EXT_SA; 1067 m_sa.sadb_sa_spi = htonl(p_spi); 1068 m_sa.sadb_sa_replay = p_replay; 1069 m_sa.sadb_sa_state = 0; 1070 m_sa.sadb_sa_auth = p_alg_auth; 1071 m_sa.sadb_sa_encrypt = p_alg_enc; 1072 m_sa.sadb_sa_flags = p_ext; 1073 1074 memcpy(buf + l, &m_sa, len); 1075 l += len; 1076 1077 len = sizeof(struct sadb_x_sa2); 1078 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 1079 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 1080 m_sa2.sadb_x_sa2_mode = p_mode; 1081 m_sa2.sadb_x_sa2_reqid = p_reqid; 1082 1083 memcpy(buf + l, &m_sa2, len); 1084 l += len; 1085 1086 l0 = l; 1087 n = 0; 1088 1089 /* do it for all src/dst pairs */ 1090 for (s = srcs; s; s = s->ai_next) { 1091 for (d = dsts; d; d = d->ai_next) { 1092 /* rewind pointer */ 1093 l = l0; 1094 1095 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 1096 continue; 1097 switch (s->ai_addr->sa_family) { 1098 case AF_INET: 1099 plen = sizeof(struct in_addr) << 3; 1100 break; 1101#ifdef INET6 1102 case AF_INET6: 1103 plen = sizeof(struct in6_addr) << 3; 1104 break; 1105#endif 1106 default: 1107 continue; 1108 } 1109 1110 /* set src */ 1111 sa = s->ai_addr; 1112 salen = s->ai_addr->sa_len; 1113 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1114 PFKEY_ALIGN8(salen)); 1115 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 1116 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1117 m_addr.sadb_address_prefixlen = plen; 1118 m_addr.sadb_address_reserved = 0; 1119 1120 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1121 sizeof(m_addr), (caddr_t)sa, salen); 1122 1123 /* set dst */ 1124 sa = d->ai_addr; 1125 salen = d->ai_addr->sa_len; 1126 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1127 PFKEY_ALIGN8(salen)); 1128 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 1129 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1130 m_addr.sadb_address_prefixlen = plen; 1131 m_addr.sadb_address_reserved = 0; 1132 1133 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1134 sizeof(m_addr), (caddr_t)sa, salen); 1135 1136 msg->sadb_msg_len = PFKEY_UNIT64(l); 1137 1138 sendkeymsg(buf, l); 1139 1140 n++; 1141 } 1142 } 1143 1144 if (n == 0) 1145 return -1; 1146 else 1147 return 0; 1148} 1149 1150static struct addrinfo * 1151parse_addr(host, port) 1152 char *host; 1153 char *port; 1154{ 1155 struct addrinfo hints, *res = NULL; 1156 int error; 1157 1158 memset(&hints, 0, sizeof(hints)); 1159 hints.ai_family = p_aifamily; 1160 hints.ai_socktype = SOCK_DGRAM; /*dummy*/ 1161 hints.ai_protocol = IPPROTO_UDP; /*dummy*/ 1162 hints.ai_flags = p_aiflags; 1163 error = getaddrinfo(host, port, &hints, &res); 1164 if (error != 0) { 1165 yyerror(gai_strerror(error)); 1166 return NULL; 1167 } 1168 return res; 1169} 1170 1171static int 1172fix_portstr(spec, sport, dport) 1173 vchar_t *spec, *sport, *dport; 1174{ 1175 char *p, *p2; 1176 u_int l; 1177 1178 l = 0; 1179 for (p = spec->buf; *p != ',' && *p != '\0' && l < spec->len; p++, l++) 1180 ; 1181 if (*p == '\0') { 1182 p2 = "0"; 1183 } else { 1184 if (*p == ',') { 1185 *p = '\0'; 1186 p2 = ++p; 1187 } 1188 for (p = p2; *p != '\0' && l < spec->len; p++, l++) 1189 ; 1190 if (*p != '\0' || *p2 == '\0') { 1191 yyerror("invalid an upper layer protocol spec"); 1192 return -1; 1193 } 1194 } 1195 1196 sport->buf = strdup(spec->buf); 1197 if (!sport->buf) { 1198 yyerror("insufficient memory"); 1199 return -1; 1200 } 1201 sport->len = strlen(sport->buf); 1202 dport->buf = strdup(p2); 1203 if (!dport->buf) { 1204 yyerror("insufficient memory"); 1205 return -1; 1206 } 1207 dport->len = strlen(dport->buf); 1208 1209 return 0; 1210} 1211 1212static int 1213setvarbuf(buf, off, ebuf, elen, vbuf, vlen) 1214 char *buf; 1215 int *off; 1216 struct sadb_ext *ebuf; 1217 int elen; 1218 caddr_t vbuf; 1219 int vlen; 1220{ 1221 memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len)); 1222 memcpy(buf + *off, (caddr_t)ebuf, elen); 1223 memcpy(buf + *off + elen, vbuf, vlen); 1224 (*off) += PFKEY_ALIGN8(elen + vlen); 1225 1226 return 0; 1227} 1228 1229void 1230parse_init() 1231{ 1232 p_spi = 0; 1233 1234 p_ext = SADB_X_EXT_CYCSEQ; 1235 p_alg_enc = SADB_EALG_NONE; 1236 p_alg_auth = SADB_AALG_NONE; 1237 p_mode = IPSEC_MODE_ANY; 1238 p_reqid = 0; 1239 p_replay = 0; 1240 p_key_enc_len = p_key_auth_len = 0; 1241 p_key_enc = p_key_auth = 0; 1242 p_lt_hard = p_lt_soft = 0; 1243 1244 p_aiflags = 0; 1245 p_aifamily = PF_UNSPEC; 1246 1247 return; 1248} 1249 1250void 1251free_buffer() 1252{ 1253 /* we got tons of memory leaks in the parser anyways, leave them */ 1254 1255 return; 1256} 1257