1/* $FreeBSD: releng/10.2/sbin/setkey/parse.y 175248 2008-01-12 20:00:23Z maxim $ */ 2/* $KAME: parse.y,v 1.83 2004/05/18 08:48:23 sakane 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 <netipsec/key_var.h> 42#include <netipsec/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(char *, char *); 68static int fix_portstr(vchar_t *, vchar_t *, vchar_t *); 69static int setvarbuf(char *, int *, struct sadb_ext *, int, caddr_t, int); 70void parse_init(void); 71void free_buffer(void); 72 73int setkeymsg0(struct sadb_msg *, unsigned int, unsigned int, size_t); 74static int setkeymsg_spdaddr(unsigned int, unsigned int, vchar_t *, 75 struct addrinfo *, int, struct addrinfo *, int); 76static int setkeymsg_addr(unsigned int, unsigned int, 77 struct addrinfo *, struct addrinfo *, int); 78static int setkeymsg_add(unsigned int, unsigned int, 79 struct addrinfo *, struct addrinfo *); 80extern int setkeymsg(char *, size_t *); 81extern int sendkeymsg(char *, size_t); 82 83extern int yylex(void); 84extern void yyfatal(const char *); 85extern void yyerror(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 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 327 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 328 yyerror(ipsec_strerror()); 329 return -1; 330 } 331 } 332 | ALG_ENC key_string { 333 if ($1 < 0) { 334 yyerror("unsupported algorithm"); 335 return -1; 336 } 337 p_alg_enc = $1; 338 339 p_key_enc_len = $2.len; 340 p_key_enc = $2.buf; 341 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 342 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 343 yyerror(ipsec_strerror()); 344 return -1; 345 } 346 } 347 | ALG_ENC_OLD { 348 if ($1 < 0) { 349 yyerror("unsupported algorithm"); 350 return -1; 351 } 352 yyerror("WARNING: obsolete algorithm"); 353 p_alg_enc = $1; 354 355 p_key_enc_len = 0; 356 p_key_enc = NULL; 357 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 358 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 359 yyerror(ipsec_strerror()); 360 return -1; 361 } 362 } 363 | ALG_ENC_DESDERIV key_string 364 { 365 if ($1 < 0) { 366 yyerror("unsupported algorithm"); 367 return -1; 368 } 369 p_alg_enc = $1; 370 if (p_ext & SADB_X_EXT_OLD) { 371 yyerror("algorithm mismatched"); 372 return -1; 373 } 374 p_ext |= SADB_X_EXT_DERIV; 375 376 p_key_enc_len = $2.len; 377 p_key_enc = $2.buf; 378 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 379 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 380 yyerror(ipsec_strerror()); 381 return -1; 382 } 383 } 384 | ALG_ENC_DES32IV key_string 385 { 386 if ($1 < 0) { 387 yyerror("unsupported algorithm"); 388 return -1; 389 } 390 p_alg_enc = $1; 391 if (!(p_ext & SADB_X_EXT_OLD)) { 392 yyerror("algorithm mismatched"); 393 return -1; 394 } 395 p_ext |= SADB_X_EXT_IV4B; 396 397 p_key_enc_len = $2.len; 398 p_key_enc = $2.buf; 399 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 400 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 401 yyerror(ipsec_strerror()); 402 return -1; 403 } 404 } 405 ; 406 407auth_alg 408 : ALG_AUTH key_string { 409 if ($1 < 0) { 410 yyerror("unsupported algorithm"); 411 return -1; 412 } 413 p_alg_auth = $1; 414 415 p_key_auth_len = $2.len; 416 p_key_auth = $2.buf; 417 418 if (p_alg_auth == SADB_X_AALG_TCP_MD5) { 419 if ((p_key_auth_len < 1) || (p_key_auth_len > 420 80)) 421 return -1; 422 } else if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, 423 p_alg_auth, PFKEY_UNUNIT64(p_key_auth_len)) < 0) { 424 yyerror(ipsec_strerror()); 425 return -1; 426 } 427 } 428 | ALG_AUTH_NOKEY { 429 if ($1 < 0) { 430 yyerror("unsupported algorithm"); 431 return -1; 432 } 433 p_alg_auth = $1; 434 435 p_key_auth_len = 0; 436 p_key_auth = NULL; 437 } 438 ; 439 440key_string 441 : QUOTEDSTRING 442 { 443 $$ = $1; 444 } 445 | HEXSTRING 446 { 447 caddr_t pp_key; 448 caddr_t bp; 449 caddr_t yp = $1.buf; 450 int l; 451 452 l = strlen(yp) % 2 + strlen(yp) / 2; 453 if ((pp_key = malloc(l)) == 0) { 454 yyerror("not enough core"); 455 return -1; 456 } 457 memset(pp_key, 0, l); 458 459 bp = pp_key; 460 if (strlen(yp) % 2) { 461 *bp = ATOX(yp[0]); 462 yp++, bp++; 463 } 464 while (*yp) { 465 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); 466 yp += 2, bp++; 467 } 468 469 $$.len = l; 470 $$.buf = pp_key; 471 } 472 ; 473 474extension_spec 475 : /*NOTHING*/ 476 | extension_spec extension 477 ; 478 479extension 480 : F_EXT EXTENSION { p_ext |= $2; } 481 | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; } 482 | F_MODE MODE { p_mode = $2; } 483 | F_MODE ANY { p_mode = IPSEC_MODE_ANY; } 484 | F_REQID DECSTRING { p_reqid = $2; } 485 | F_REPLAY DECSTRING 486 { 487 if ((p_ext & SADB_X_EXT_OLD) != 0) { 488 yyerror("replay prevention cannot be used with " 489 "ah/esp-old"); 490 return -1; 491 } 492 p_replay = $2; 493 } 494 | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; } 495 | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; } 496 ; 497 498 /* definition about command for SPD management */ 499 /* spdadd */ 500spdadd_command 501 : SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT 502 { 503 int status; 504 struct addrinfo *src, *dst; 505 506 /* fixed port fields if ulp is icmpv6 */ 507 if ($10.buf != NULL) { 508 if ($9 != IPPROTO_ICMPV6) 509 return -1; 510 free($5.buf); 511 free($8.buf); 512 if (fix_portstr(&$10, &$5, &$8)) 513 return -1; 514 } 515 516 src = parse_addr($3.buf, $5.buf); 517 dst = parse_addr($6.buf, $8.buf); 518 if (!src || !dst) { 519 /* yyerror is already called */ 520 return -1; 521 } 522 if (src->ai_next || dst->ai_next) { 523 yyerror("multiple address specified"); 524 freeaddrinfo(src); 525 freeaddrinfo(dst); 526 return -1; 527 } 528 529 status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$11, 530 src, $4, dst, $7); 531 freeaddrinfo(src); 532 freeaddrinfo(dst); 533 if (status < 0) 534 return -1; 535 } 536 | SPDADD TAGGED QUOTEDSTRING policy_spec EOT 537 { 538 return -1; 539 } 540 ; 541 542spddelete_command 543 : SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT 544 { 545 int status; 546 struct addrinfo *src, *dst; 547 548 /* fixed port fields if ulp is icmpv6 */ 549 if ($10.buf != NULL) { 550 if ($9 != IPPROTO_ICMPV6) 551 return -1; 552 free($5.buf); 553 free($8.buf); 554 if (fix_portstr(&$10, &$5, &$8)) 555 return -1; 556 } 557 558 src = parse_addr($3.buf, $5.buf); 559 dst = parse_addr($6.buf, $8.buf); 560 if (!src || !dst) { 561 /* yyerror is already called */ 562 return -1; 563 } 564 if (src->ai_next || dst->ai_next) { 565 yyerror("multiple address specified"); 566 freeaddrinfo(src); 567 freeaddrinfo(dst); 568 return -1; 569 } 570 571 status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$11, 572 src, $4, dst, $7); 573 freeaddrinfo(src); 574 freeaddrinfo(dst); 575 if (status < 0) 576 return -1; 577 } 578 ; 579 580spddump_command: 581 SPDDUMP EOT 582 { 583 struct sadb_msg msg; 584 setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC, 585 sizeof(msg)); 586 sendkeymsg((char *)&msg, sizeof(msg)); 587 } 588 ; 589 590spdflush_command: 591 SPDFLUSH EOT 592 { 593 struct sadb_msg msg; 594 setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC, 595 sizeof(msg)); 596 sendkeymsg((char *)&msg, sizeof(msg)); 597 } 598 ; 599 600ipaddropts 601 : /* nothing */ 602 | ipaddropts ipaddropt 603 ; 604 605ipaddropt 606 : F_AIFLAGS 607 { 608 char *p; 609 610 for (p = $1.buf + 1; *p; p++) 611 switch (*p) { 612 case '4': 613 p_aifamily = AF_INET; 614 break; 615#ifdef INET6 616 case '6': 617 p_aifamily = AF_INET6; 618 break; 619#endif 620 case 'n': 621 p_aiflags = AI_NUMERICHOST; 622 break; 623 default: 624 yyerror("invalid flag"); 625 return -1; 626 } 627 } 628 ; 629 630ipaddr 631 : STRING 632 { 633 $$ = parse_addr($1.buf, NULL); 634 if ($$ == NULL) { 635 /* yyerror already called by parse_addr */ 636 return -1; 637 } 638 } 639 ; 640 641prefix 642 : /*NOTHING*/ { $$ = -1; } 643 | SLASH DECSTRING { $$ = $2; } 644 ; 645 646portstr 647 : /*NOTHING*/ 648 { 649 $$.buf = strdup("0"); 650 if (!$$.buf) { 651 yyerror("insufficient memory"); 652 return -1; 653 } 654 $$.len = strlen($$.buf); 655 } 656 | BLCL ANY ELCL 657 { 658 $$.buf = strdup("0"); 659 if (!$$.buf) { 660 yyerror("insufficient memory"); 661 return -1; 662 } 663 $$.len = strlen($$.buf); 664 } 665 | BLCL DECSTRING ELCL 666 { 667 char buf[20]; 668 snprintf(buf, sizeof(buf), "%lu", $2); 669 $$.buf = strdup(buf); 670 if (!$$.buf) { 671 yyerror("insufficient memory"); 672 return -1; 673 } 674 $$.len = strlen($$.buf); 675 } 676 | BLCL STRING ELCL 677 { 678 $$ = $2; 679 } 680 ; 681 682upper_spec 683 : DECSTRING { $$ = $1; } 684 | ANY { $$ = IPSEC_ULPROTO_ANY; } 685 | PR_TCP { $$ = IPPROTO_TCP; } 686 | PR_ESP { $$ = IPPROTO_ESP; } 687 | STRING 688 { 689 struct protoent *ent; 690 691 ent = getprotobyname($1.buf); 692 if (ent) 693 $$ = ent->p_proto; 694 else { 695 if (strcmp("icmp6", $1.buf) == 0) { 696 $$ = IPPROTO_ICMPV6; 697 } else if(strcmp("ip4", $1.buf) == 0) { 698 $$ = IPPROTO_IPV4; 699 } else { 700 yyerror("invalid upper layer protocol"); 701 return -1; 702 } 703 } 704 endprotoent(); 705 } 706 ; 707 708upper_misc_spec 709 : /*NOTHING*/ 710 { 711 $$.buf = NULL; 712 $$.len = 0; 713 } 714 | STRING 715 { 716 $$.buf = strdup($1.buf); 717 if (!$$.buf) { 718 yyerror("insufficient memory"); 719 return -1; 720 } 721 $$.len = strlen($$.buf); 722 } 723 ; 724 725policy_spec 726 : F_POLICY policy_requests 727 { 728 char *policy; 729 730 policy = ipsec_set_policy($2.buf, $2.len); 731 if (policy == NULL) { 732 yyerror(ipsec_strerror()); 733 return -1; 734 } 735 736 $$.buf = policy; 737 $$.len = ipsec_get_policylen(policy); 738 } 739 ; 740 741policy_requests 742 : PL_REQUESTS { $$ = $1; } 743 ; 744 745%% 746 747int 748setkeymsg0(msg, type, satype, l) 749 struct sadb_msg *msg; 750 unsigned int type; 751 unsigned int satype; 752 size_t l; 753{ 754 755 msg->sadb_msg_version = PF_KEY_V2; 756 msg->sadb_msg_type = type; 757 msg->sadb_msg_errno = 0; 758 msg->sadb_msg_satype = satype; 759 msg->sadb_msg_reserved = 0; 760 msg->sadb_msg_seq = 0; 761 msg->sadb_msg_pid = getpid(); 762 msg->sadb_msg_len = PFKEY_UNIT64(l); 763 return 0; 764} 765 766/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 767static int 768setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen) 769 unsigned int type; 770 unsigned int upper; 771 vchar_t *policy; 772 struct addrinfo *srcs; 773 int splen; 774 struct addrinfo *dsts; 775 int dplen; 776{ 777 struct sadb_msg *msg; 778 char buf[BUFSIZ]; 779 int l, l0; 780 struct sadb_address m_addr; 781 struct addrinfo *s, *d; 782 int n; 783 int plen; 784 struct sockaddr *sa; 785 int salen; 786 787 msg = (struct sadb_msg *)buf; 788 789 if (!srcs || !dsts) 790 return -1; 791 792 /* fix up length afterwards */ 793 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0); 794 l = sizeof(struct sadb_msg); 795 796 memcpy(buf + l, policy->buf, policy->len); 797 l += policy->len; 798 799 l0 = l; 800 n = 0; 801 802 /* do it for all src/dst pairs */ 803 for (s = srcs; s; s = s->ai_next) { 804 for (d = dsts; d; d = d->ai_next) { 805 /* rewind pointer */ 806 l = l0; 807 808 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 809 continue; 810 switch (s->ai_addr->sa_family) { 811 case AF_INET: 812 plen = sizeof(struct in_addr) << 3; 813 break; 814#ifdef INET6 815 case AF_INET6: 816 plen = sizeof(struct in6_addr) << 3; 817 break; 818#endif 819 default: 820 continue; 821 } 822 823 /* set src */ 824 sa = s->ai_addr; 825 salen = s->ai_addr->sa_len; 826 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 827 PFKEY_ALIGN8(salen)); 828 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 829 m_addr.sadb_address_proto = upper; 830 m_addr.sadb_address_prefixlen = 831 (splen >= 0 ? splen : plen); 832 m_addr.sadb_address_reserved = 0; 833 834 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 835 sizeof(m_addr), (caddr_t)sa, salen); 836 837 /* set dst */ 838 sa = d->ai_addr; 839 salen = d->ai_addr->sa_len; 840 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 841 PFKEY_ALIGN8(salen)); 842 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 843 m_addr.sadb_address_proto = upper; 844 m_addr.sadb_address_prefixlen = 845 (dplen >= 0 ? dplen : plen); 846 m_addr.sadb_address_reserved = 0; 847 848 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 849 sizeof(m_addr), (caddr_t)sa, salen); 850 851 msg->sadb_msg_len = PFKEY_UNIT64(l); 852 853 sendkeymsg(buf, l); 854 855 n++; 856 } 857 } 858 859 if (n == 0) 860 return -1; 861 else 862 return 0; 863} 864 865/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 866static int 867setkeymsg_addr(type, satype, srcs, dsts, no_spi) 868 unsigned int type; 869 unsigned int satype; 870 struct addrinfo *srcs; 871 struct addrinfo *dsts; 872 int no_spi; 873{ 874 struct sadb_msg *msg; 875 char buf[BUFSIZ]; 876 int l, l0, len; 877 struct sadb_sa m_sa; 878 struct sadb_x_sa2 m_sa2; 879 struct sadb_address m_addr; 880 struct addrinfo *s, *d; 881 int n; 882 int plen; 883 struct sockaddr *sa; 884 int salen; 885 886 msg = (struct sadb_msg *)buf; 887 888 if (!srcs || !dsts) 889 return -1; 890 891 /* fix up length afterwards */ 892 setkeymsg0(msg, type, satype, 0); 893 l = sizeof(struct sadb_msg); 894 895 if (!no_spi) { 896 len = sizeof(struct sadb_sa); 897 m_sa.sadb_sa_len = PFKEY_UNIT64(len); 898 m_sa.sadb_sa_exttype = SADB_EXT_SA; 899 m_sa.sadb_sa_spi = htonl(p_spi); 900 m_sa.sadb_sa_replay = p_replay; 901 m_sa.sadb_sa_state = 0; 902 m_sa.sadb_sa_auth = p_alg_auth; 903 m_sa.sadb_sa_encrypt = p_alg_enc; 904 m_sa.sadb_sa_flags = p_ext; 905 906 memcpy(buf + l, &m_sa, len); 907 l += len; 908 909 len = sizeof(struct sadb_x_sa2); 910 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 911 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 912 m_sa2.sadb_x_sa2_mode = p_mode; 913 m_sa2.sadb_x_sa2_reqid = p_reqid; 914 915 memcpy(buf + l, &m_sa2, len); 916 l += len; 917 } 918 919 l0 = l; 920 n = 0; 921 922 /* do it for all src/dst pairs */ 923 for (s = srcs; s; s = s->ai_next) { 924 for (d = dsts; d; d = d->ai_next) { 925 /* rewind pointer */ 926 l = l0; 927 928 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 929 continue; 930 switch (s->ai_addr->sa_family) { 931 case AF_INET: 932 plen = sizeof(struct in_addr) << 3; 933 break; 934#ifdef INET6 935 case AF_INET6: 936 plen = sizeof(struct in6_addr) << 3; 937 break; 938#endif 939 default: 940 continue; 941 } 942 943 /* set src */ 944 sa = s->ai_addr; 945 salen = s->ai_addr->sa_len; 946 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 947 PFKEY_ALIGN8(salen)); 948 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 949 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 950 m_addr.sadb_address_prefixlen = plen; 951 m_addr.sadb_address_reserved = 0; 952 953 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 954 sizeof(m_addr), (caddr_t)sa, salen); 955 956 /* set dst */ 957 sa = d->ai_addr; 958 salen = d->ai_addr->sa_len; 959 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 960 PFKEY_ALIGN8(salen)); 961 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 962 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 963 m_addr.sadb_address_prefixlen = plen; 964 m_addr.sadb_address_reserved = 0; 965 966 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 967 sizeof(m_addr), (caddr_t)sa, salen); 968 969 msg->sadb_msg_len = PFKEY_UNIT64(l); 970 971 sendkeymsg(buf, l); 972 973 n++; 974 } 975 } 976 977 if (n == 0) 978 return -1; 979 else 980 return 0; 981} 982 983/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 984static int 985setkeymsg_add(type, satype, srcs, dsts) 986 unsigned int type; 987 unsigned int satype; 988 struct addrinfo *srcs; 989 struct addrinfo *dsts; 990{ 991 struct sadb_msg *msg; 992 char buf[BUFSIZ]; 993 int l, l0, len; 994 struct sadb_sa m_sa; 995 struct sadb_x_sa2 m_sa2; 996 struct sadb_address m_addr; 997 struct addrinfo *s, *d; 998 int n; 999 int plen; 1000 struct sockaddr *sa; 1001 int salen; 1002 1003 msg = (struct sadb_msg *)buf; 1004 1005 if (!srcs || !dsts) 1006 return -1; 1007 1008 /* fix up length afterwards */ 1009 setkeymsg0(msg, type, satype, 0); 1010 l = sizeof(struct sadb_msg); 1011 1012 /* set encryption algorithm, if present. */ 1013 if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) { 1014 struct sadb_key m_key; 1015 1016 m_key.sadb_key_len = 1017 PFKEY_UNIT64(sizeof(m_key) 1018 + PFKEY_ALIGN8(p_key_enc_len)); 1019 m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; 1020 m_key.sadb_key_bits = p_key_enc_len * 8; 1021 m_key.sadb_key_reserved = 0; 1022 1023 setvarbuf(buf, &l, 1024 (struct sadb_ext *)&m_key, sizeof(m_key), 1025 (caddr_t)p_key_enc, p_key_enc_len); 1026 } 1027 1028 /* set authentication algorithm, if present. */ 1029 if (p_key_auth) { 1030 struct sadb_key m_key; 1031 1032 m_key.sadb_key_len = 1033 PFKEY_UNIT64(sizeof(m_key) 1034 + PFKEY_ALIGN8(p_key_auth_len)); 1035 m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH; 1036 m_key.sadb_key_bits = p_key_auth_len * 8; 1037 m_key.sadb_key_reserved = 0; 1038 1039 setvarbuf(buf, &l, 1040 (struct sadb_ext *)&m_key, sizeof(m_key), 1041 (caddr_t)p_key_auth, p_key_auth_len); 1042 } 1043 1044 /* set lifetime for HARD */ 1045 if (p_lt_hard != 0) { 1046 struct sadb_lifetime m_lt; 1047 u_int slen = sizeof(struct sadb_lifetime); 1048 1049 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); 1050 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; 1051 m_lt.sadb_lifetime_allocations = 0; 1052 m_lt.sadb_lifetime_bytes = 0; 1053 m_lt.sadb_lifetime_addtime = p_lt_hard; 1054 m_lt.sadb_lifetime_usetime = 0; 1055 1056 memcpy(buf + l, &m_lt, slen); 1057 l += slen; 1058 } 1059 1060 /* set lifetime for SOFT */ 1061 if (p_lt_soft != 0) { 1062 struct sadb_lifetime m_lt; 1063 u_int slen = sizeof(struct sadb_lifetime); 1064 1065 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); 1066 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; 1067 m_lt.sadb_lifetime_allocations = 0; 1068 m_lt.sadb_lifetime_bytes = 0; 1069 m_lt.sadb_lifetime_addtime = p_lt_soft; 1070 m_lt.sadb_lifetime_usetime = 0; 1071 1072 memcpy(buf + l, &m_lt, slen); 1073 l += slen; 1074 } 1075 1076 len = sizeof(struct sadb_sa); 1077 m_sa.sadb_sa_len = PFKEY_UNIT64(len); 1078 m_sa.sadb_sa_exttype = SADB_EXT_SA; 1079 m_sa.sadb_sa_spi = htonl(p_spi); 1080 m_sa.sadb_sa_replay = p_replay; 1081 m_sa.sadb_sa_state = 0; 1082 m_sa.sadb_sa_auth = p_alg_auth; 1083 m_sa.sadb_sa_encrypt = p_alg_enc; 1084 m_sa.sadb_sa_flags = p_ext; 1085 1086 memcpy(buf + l, &m_sa, len); 1087 l += len; 1088 1089 len = sizeof(struct sadb_x_sa2); 1090 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 1091 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 1092 m_sa2.sadb_x_sa2_mode = p_mode; 1093 m_sa2.sadb_x_sa2_reqid = p_reqid; 1094 1095 memcpy(buf + l, &m_sa2, len); 1096 l += len; 1097 1098 l0 = l; 1099 n = 0; 1100 1101 /* do it for all src/dst pairs */ 1102 for (s = srcs; s; s = s->ai_next) { 1103 for (d = dsts; d; d = d->ai_next) { 1104 /* rewind pointer */ 1105 l = l0; 1106 1107 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 1108 continue; 1109 switch (s->ai_addr->sa_family) { 1110 case AF_INET: 1111 plen = sizeof(struct in_addr) << 3; 1112 break; 1113#ifdef INET6 1114 case AF_INET6: 1115 plen = sizeof(struct in6_addr) << 3; 1116 break; 1117#endif 1118 default: 1119 continue; 1120 } 1121 1122 /* set src */ 1123 sa = s->ai_addr; 1124 salen = s->ai_addr->sa_len; 1125 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1126 PFKEY_ALIGN8(salen)); 1127 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 1128 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1129 m_addr.sadb_address_prefixlen = plen; 1130 m_addr.sadb_address_reserved = 0; 1131 1132 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1133 sizeof(m_addr), (caddr_t)sa, salen); 1134 1135 /* set dst */ 1136 sa = d->ai_addr; 1137 salen = d->ai_addr->sa_len; 1138 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1139 PFKEY_ALIGN8(salen)); 1140 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 1141 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1142 m_addr.sadb_address_prefixlen = plen; 1143 m_addr.sadb_address_reserved = 0; 1144 1145 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1146 sizeof(m_addr), (caddr_t)sa, salen); 1147 1148 msg->sadb_msg_len = PFKEY_UNIT64(l); 1149 1150 sendkeymsg(buf, l); 1151 1152 n++; 1153 } 1154 } 1155 1156 if (n == 0) 1157 return -1; 1158 else 1159 return 0; 1160} 1161 1162static struct addrinfo * 1163parse_addr(host, port) 1164 char *host; 1165 char *port; 1166{ 1167 struct addrinfo hints, *res = NULL; 1168 int error; 1169 1170 memset(&hints, 0, sizeof(hints)); 1171 hints.ai_family = p_aifamily; 1172 hints.ai_socktype = SOCK_DGRAM; /*dummy*/ 1173 hints.ai_protocol = IPPROTO_UDP; /*dummy*/ 1174 hints.ai_flags = p_aiflags; 1175 error = getaddrinfo(host, port, &hints, &res); 1176 if (error != 0) { 1177 yyerror(gai_strerror(error)); 1178 return NULL; 1179 } 1180 return res; 1181} 1182 1183static int 1184fix_portstr(spec, sport, dport) 1185 vchar_t *spec, *sport, *dport; 1186{ 1187 char *p, *p2; 1188 u_int l; 1189 1190 l = 0; 1191 for (p = spec->buf; *p != ',' && *p != '\0' && l < spec->len; p++, l++) 1192 ; 1193 if (*p == '\0') { 1194 p2 = "0"; 1195 } else { 1196 if (*p == ',') { 1197 *p = '\0'; 1198 p2 = ++p; 1199 } 1200 for (p = p2; *p != '\0' && l < spec->len; p++, l++) 1201 ; 1202 if (*p != '\0' || *p2 == '\0') { 1203 yyerror("invalid an upper layer protocol spec"); 1204 return -1; 1205 } 1206 } 1207 1208 sport->buf = strdup(spec->buf); 1209 if (!sport->buf) { 1210 yyerror("insufficient memory"); 1211 return -1; 1212 } 1213 sport->len = strlen(sport->buf); 1214 dport->buf = strdup(p2); 1215 if (!dport->buf) { 1216 yyerror("insufficient memory"); 1217 return -1; 1218 } 1219 dport->len = strlen(dport->buf); 1220 1221 return 0; 1222} 1223 1224static int 1225setvarbuf(buf, off, ebuf, elen, vbuf, vlen) 1226 char *buf; 1227 int *off; 1228 struct sadb_ext *ebuf; 1229 int elen; 1230 caddr_t vbuf; 1231 int vlen; 1232{ 1233 memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len)); 1234 memcpy(buf + *off, (caddr_t)ebuf, elen); 1235 memcpy(buf + *off + elen, vbuf, vlen); 1236 (*off) += PFKEY_ALIGN8(elen + vlen); 1237 1238 return 0; 1239} 1240 1241void 1242parse_init() 1243{ 1244 p_spi = 0; 1245 1246 p_ext = SADB_X_EXT_CYCSEQ; 1247 p_alg_enc = SADB_EALG_NONE; 1248 p_alg_auth = SADB_AALG_NONE; 1249 p_mode = IPSEC_MODE_ANY; 1250 p_reqid = 0; 1251 p_replay = 0; 1252 p_key_enc_len = p_key_auth_len = 0; 1253 p_key_enc = p_key_auth = 0; 1254 p_lt_hard = p_lt_soft = 0; 1255 1256 p_aiflags = 0; 1257 p_aifamily = PF_UNSPEC; 1258 1259 return; 1260} 1261 1262void 1263free_buffer() 1264{ 1265 /* we got tons of memory leaks in the parser anyways, leave them */ 1266 1267 return; 1268} 1269