parse.y revision 1.61
1/* $OpenBSD: parse.y,v 1.61 2006/04/19 17:19:45 hshoexer Exp $ */ 2 3/* 4 * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> 5 * Copyright (c) 2001 Markus Friedl. All rights reserved. 6 * Copyright (c) 2001 Daniel Hartmeier. All rights reserved. 7 * Copyright (c) 2001 Theo de Raadt. All rights reserved. 8 * Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org> 9 * 10 * Permission to use, copy, modify, and distribute this software for any 11 * purpose with or without fee is hereby granted, provided that the above 12 * copyright notice and this permission notice appear in all copies. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23%{ 24#include <sys/types.h> 25#include <sys/ioctl.h> 26#include <sys/queue.h> 27#include <sys/socket.h> 28#include <sys/stat.h> 29#include <net/if.h> 30#include <netinet/in.h> 31#include <netinet/ip_ipsp.h> 32#include <arpa/inet.h> 33 34#include <ctype.h> 35#include <err.h> 36#include <errno.h> 37#include <fcntl.h> 38#include <ifaddrs.h> 39#include <limits.h> 40#include <netdb.h> 41#include <stdarg.h> 42#include <stdio.h> 43#include <string.h> 44#include <syslog.h> 45#include <unistd.h> 46#include <netdb.h> 47 48#include "ipsecctl.h" 49 50#define KEYSIZE_LIMIT 1024 51 52static struct ipsecctl *ipsec = NULL; 53static FILE *fin = NULL; 54static int lineno = 1; 55static int errors = 0; 56static int debug = 0; 57 58const struct ipsec_xf authxfs[] = { 59 { "unknown", AUTHXF_UNKNOWN, 0, 0 }, 60 { "none", AUTHXF_NONE, 0, 0 }, 61 { "hmac-md5", AUTHXF_HMAC_MD5, 16, 0 }, 62 { "hmac-ripemd160", AUTHXF_HMAC_RIPEMD160, 20, 0 }, 63 { "hmac-sha1", AUTHXF_HMAC_SHA1, 20, 0 }, 64 { "hmac-sha2-256", AUTHXF_HMAC_SHA2_256, 32, 0 }, 65 { "hmac-sha2-384", AUTHXF_HMAC_SHA2_384, 48, 0 }, 66 { "hmac-sha2-512", AUTHXF_HMAC_SHA2_512, 64, 0 }, 67 { NULL, 0, 0, 0 }, 68}; 69 70const struct ipsec_xf encxfs[] = { 71 { "unknown", ENCXF_UNKNOWN, 0, 0 }, 72 { "none", ENCXF_NONE, 0, 0 }, 73 { "3des-cbc", ENCXF_3DES_CBC, 24, 24 }, 74 { "des-cbc", ENCXF_DES_CBC, 8, 8 }, 75 { "aes", ENCXF_AES, 16, 32 }, 76 { "aesctr", ENCXF_AESCTR, 16+4, 32+4 }, 77 { "blowfish", ENCXF_BLOWFISH, 5, 56 }, 78 { "cast128", ENCXF_CAST128, 5, 16 }, 79 { "null", ENCXF_NULL, 0, 0 }, 80 { "skipjack", ENCXF_SKIPJACK, 10, 10 }, 81 { NULL, 0, 0, 0 }, 82}; 83 84const struct ipsec_xf compxfs[] = { 85 { "unknown", COMPXF_UNKNOWN, 0, 0 }, 86 { "deflate", COMPXF_DEFLATE, 0, 0 }, 87 { "lzs", COMPXF_LZS, 0, 0 }, 88 { NULL, 0, 0, 0 }, 89}; 90 91int yyerror(const char *, ...); 92int yyparse(void); 93int kw_cmp(const void *, const void *); 94int lookup(char *); 95int lgetc(FILE *); 96int lungetc(int); 97int findeol(void); 98int yylex(void); 99 100TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead); 101struct sym { 102 TAILQ_ENTRY(sym) entries; 103 int used; 104 int persist; 105 char *nam; 106 char *val; 107}; 108 109int symset(const char *, const char *, int); 110int cmdline_symset(char *); 111char *symget(const char *); 112int atoul(char *, u_long *); 113int atospi(char *, u_int32_t *); 114u_int8_t x2i(unsigned char *); 115struct ipsec_key *parsekey(unsigned char *, size_t); 116struct ipsec_key *parsekeyfile(char *); 117struct ipsec_addr_wrap *host(const char *); 118struct ipsec_addr_wrap *host_v4(const char *, int); 119struct ipsec_addr_wrap *host_dns(const char *, int, int); 120struct ipsec_addr_wrap *host_if(const char *, int); 121void ifa_load(void); 122int ifa_exists(const char *); 123struct ipsec_addr_wrap *ifa_lookup(const char *ifa_name); 124void set_ipmask(struct ipsec_addr_wrap *, u_int8_t); 125struct ipsec_addr_wrap *copyhost(const struct ipsec_addr_wrap *); 126const struct ipsec_xf *parse_xf(const char *, const struct ipsec_xf *); 127struct ipsec_transforms *copytransforms(const struct ipsec_transforms *); 128int validate_sa(u_int32_t, u_int8_t, 129 struct ipsec_transforms *, struct ipsec_key *, 130 struct ipsec_key *, u_int8_t); 131struct ipsec_rule *create_sa(u_int8_t, u_int8_t, struct ipsec_addr_wrap *, 132 struct ipsec_addr_wrap *, u_int32_t, 133 struct ipsec_transforms *, struct ipsec_key *, 134 struct ipsec_key *); 135struct ipsec_rule *reverse_sa(struct ipsec_rule *, u_int32_t, 136 struct ipsec_key *, struct ipsec_key *); 137struct ipsec_rule *create_flow(u_int8_t, u_int8_t, struct 138 ipsec_addr_wrap *, struct ipsec_addr_wrap *, 139 struct ipsec_addr_wrap *, struct ipsec_addr_wrap *, 140 u_int8_t, char *, char *, u_int8_t); 141struct ipsec_rule *reverse_rule(struct ipsec_rule *); 142struct ipsec_rule *create_ike(u_int8_t, struct ipsec_addr_wrap *, struct 143 ipsec_addr_wrap *, struct ipsec_addr_wrap *, 144 struct ipsec_addr_wrap *, 145 struct ipsec_transforms *, struct 146 ipsec_transforms *, u_int8_t, u_int8_t, char *, 147 char *, struct ike_auth *); 148 149struct ipsec_transforms *ipsec_transforms; 150 151typedef struct { 152 union { 153 u_int32_t number; 154 u_int8_t ikemode; 155 u_int8_t dir; 156 u_int8_t satype; /* encapsulating prococol */ 157 u_int8_t proto; /* encapsulated protocol */ 158 u_int8_t tmode; 159 char *string; 160 struct { 161 struct ipsec_addr_wrap *src; 162 struct ipsec_addr_wrap *dst; 163 } hosts; 164 struct { 165 struct ipsec_addr_wrap *peer; 166 struct ipsec_addr_wrap *local; 167 } peers; 168 struct ipsec_addr_wrap *singlehost; 169 struct ipsec_addr_wrap *host; 170 struct { 171 char *srcid; 172 char *dstid; 173 } ids; 174 char *id; 175 u_int8_t type; 176 struct ike_auth ikeauth; 177 struct { 178 u_int32_t spiout; 179 u_int32_t spiin; 180 } spis; 181 struct { 182 struct ipsec_key *keyout; 183 struct ipsec_key *keyin; 184 } authkeys; 185 struct { 186 struct ipsec_key *keyout; 187 struct ipsec_key *keyin; 188 } enckeys; 189 struct { 190 struct ipsec_key *keyout; 191 struct ipsec_key *keyin; 192 } keys; 193 struct ipsec_transforms *transforms; 194 struct ipsec_transforms *mmxfs; 195 struct ipsec_transforms *qmxfs; 196 } v; 197 int lineno; 198} YYSTYPE; 199 200%} 201 202%token FLOW FROM ESP AH IN PEER ON OUT TO SRCID DSTID RSA PSK TCPMD5 SPI 203%token AUTHKEY ENCKEY FILENAME AUTHXF ENCXF ERROR IKE MAIN QUICK PASSIVE 204%token ACTIVE ANY IPIP IPCOMP COMPXF TUNNEL TRANSPORT DYNAMIC 205%token TYPE DENY BYPASS LOCAL PROTO USE ACQUIRE REQUIRE DONTACQ 206%token <v.string> STRING 207%type <v.string> string 208%type <v.dir> dir 209%type <v.satype> satype 210%type <v.proto> proto 211%type <v.tmode> tmode 212%type <v.number> number 213%type <v.hosts> hosts 214%type <v.peers> peers 215%type <v.singlehost> singlehost 216%type <v.host> host 217%type <v.ids> ids 218%type <v.id> id 219%type <v.spis> spispec 220%type <v.authkeys> authkeyspec 221%type <v.enckeys> enckeyspec 222%type <v.keys> keyspec 223%type <v.transforms> transforms 224%type <v.mmxfs> mmxfs 225%type <v.qmxfs> qmxfs 226%type <v.ikemode> ikemode 227%type <v.ikeauth> ikeauth 228%type <v.type> type 229%% 230 231grammar : /* empty */ 232 | grammar '\n' 233 | grammar ikerule '\n' 234 | grammar flowrule '\n' 235 | grammar sarule '\n' 236 | grammar tcpmd5rule '\n' 237 | grammar varset '\n' 238 | grammar error '\n' { errors++; } 239 ; 240 241number : STRING { 242 unsigned long ulval; 243 244 if (atoul($1, &ulval) == -1) { 245 yyerror("%s is not a number", $1); 246 free($1); 247 YYERROR; 248 } 249 if (ulval > UINT_MAX) { 250 yyerror("0x%lx out of range", ulval); 251 free($1); 252 YYERROR; 253 } 254 $$ = (u_int32_t)ulval; 255 free($1); 256 } 257 ; 258 259tcpmd5rule : TCPMD5 hosts spispec authkeyspec { 260 struct ipsec_rule *r; 261 262 r = create_sa(IPSEC_TCPMD5, IPSEC_TRANSPORT, $2.src, 263 $2.dst, $3.spiout, NULL, $4.keyout, NULL); 264 if (r == NULL) 265 YYERROR; 266 r->nr = ipsec->rule_nr++; 267 268 if (ipsecctl_add_rule(ipsec, r)) 269 errx(1, "tcpmd5rule: ipsecctl_add_rule"); 270 271 /* Create and add reverse SA rule. */ 272 if ($3.spiin != 0 || $4.keyin != NULL) { 273 r = reverse_sa(r, $3.spiin, $4.keyin, NULL); 274 if (r == NULL) 275 YYERROR; 276 r->nr = ipsec->rule_nr++; 277 278 if (ipsecctl_add_rule(ipsec, r)) 279 errx(1, "tcpmd5rule: " 280 "ipsecctl_add_rule"); 281 } 282 } 283 ; 284 285sarule : satype tmode hosts spispec transforms authkeyspec 286 enckeyspec { 287 struct ipsec_rule *r; 288 289 r = create_sa($1, $2, $3.src, $3.dst, $4.spiout, $5, 290 $6.keyout, $7.keyout); 291 if (r == NULL) 292 YYERROR; 293 r->nr = ipsec->rule_nr++; 294 295 if (ipsecctl_add_rule(ipsec, r)) 296 errx(1, "sarule: ipsecctl_add_rule"); 297 298 /* Create and add reverse SA rule. */ 299 if ($4.spiin != 0 || $6.keyin || $7.keyin) { 300 r = reverse_sa(r, $4.spiin, $6.keyin, 301 $7.keyin); 302 if (r == NULL) 303 YYERROR; 304 r->nr = ipsec->rule_nr++; 305 306 if (ipsecctl_add_rule(ipsec, r)) 307 errx(1, "sarule: ipsecctl_add_rule"); 308 } 309 } 310 ; 311 312flowrule : FLOW satype dir proto hosts peers ids type { 313 struct ipsec_rule *r; 314 315 r = create_flow($3, $4, $5.src, $5.dst, $6.local, 316 $6.peer, $2, $7.srcid, $7.dstid, $8); 317 if (r == NULL) 318 YYERROR; 319 r->nr = ipsec->rule_nr++; 320 321 if (ipsecctl_add_rule(ipsec, r)) 322 errx(1, "flowrule: ipsecctl_add_rule"); 323 324 /* Create and add reverse flow rule. */ 325 if ($3 == IPSEC_INOUT) { 326 r = reverse_rule(r); 327 r->nr = ipsec->rule_nr++; 328 329 if (ipsecctl_add_rule(ipsec, r)) 330 errx(1, "flowrule: ipsecctl_add_rule"); 331 } 332 } 333 ; 334 335ikerule : IKE ikemode satype proto hosts peers mmxfs qmxfs ids ikeauth { 336 struct ipsec_rule *r; 337 338 r = create_ike($4, $5.src, $5.dst, $6.local, $6.peer, 339 $7, $8, $3, $2, $9.srcid, $9.dstid, &$10); 340 if (r == NULL) 341 YYERROR; 342 r->nr = ipsec->rule_nr++; 343 344 if (ipsecctl_add_rule(ipsec, r)) 345 errx(1, "ikerule: ipsecctl_add_rule"); 346 } 347 ; 348 349satype : /* empty */ { $$ = IPSEC_ESP; } 350 | ESP { $$ = IPSEC_ESP; } 351 | AH { $$ = IPSEC_AH; } 352 | IPCOMP { $$ = IPSEC_IPCOMP; } 353 | IPIP { $$ = IPSEC_IPIP; } 354 ; 355 356proto : /* empty */ { $$ = 0; } 357 | PROTO STRING { 358 struct protoent *p; 359 const char *errstr; 360 int proto; 361 362 if ((p = getprotobyname($2)) != NULL) { 363 $$ = p->p_proto; 364 } else { 365 errstr = NULL; 366 proto = strtonum($2, 1, 255, &errstr); 367 if (errstr) 368 errx(1, "unknown protocol: %s", $2); 369 $$ = proto; 370 } 371 372 } 373 ; 374 375tmode : /* empty */ { $$ = IPSEC_TUNNEL; } 376 | TUNNEL { $$ = IPSEC_TUNNEL; } 377 | TRANSPORT { $$ = IPSEC_TRANSPORT; } 378 ; 379 380dir : /* empty */ { $$ = IPSEC_INOUT; } 381 | IN { $$ = IPSEC_IN; } 382 | OUT { $$ = IPSEC_OUT; } 383 ; 384 385hosts : FROM host TO host { 386 $$.src = $2; 387 $$.dst = $4; 388 } 389 | TO host FROM host { 390 $$.src = $4; 391 $$.dst = $2; 392 } 393 ; 394 395peers : /* empty */ { 396 $$.peer = NULL; 397 $$.local = NULL; 398 } 399 | PEER singlehost LOCAL singlehost { 400 $$.peer = $2; 401 $$.local = $4; 402 } 403 | LOCAL singlehost PEER singlehost { 404 $$.peer = $4; 405 $$.local = $2; 406 } 407 | PEER singlehost { 408 $$.peer = $2; 409 $$.local = NULL; 410 } 411 | LOCAL singlehost { 412 $$.peer = NULL; 413 $$.local = $2; 414 } 415 ; 416 417singlehost : /* empty */ { $$ = NULL; } 418 | STRING { 419 if (($$ = host($1)) == NULL) { 420 free($1); 421 yyerror("could not parse host specification"); 422 YYERROR; 423 } 424 free($1); 425 } 426 ; 427 428host : STRING { 429 if (($$ = host($1)) == NULL) { 430 free($1); 431 yyerror("could not parse host specification"); 432 YYERROR; 433 } 434 free($1); 435 } 436 | STRING '/' number { 437 char *buf; 438 439 if (asprintf(&buf, "%s/%u", $1, $3) == -1) 440 err(1, "host: asprintf"); 441 free($1); 442 if (($$ = host(buf)) == NULL) { 443 free(buf); 444 yyerror("could not parse host specification"); 445 YYERROR; 446 } 447 free(buf); 448 } 449 | ANY { 450 struct ipsec_addr_wrap *ipa; 451 452 ipa = calloc(1, sizeof(struct ipsec_addr_wrap)); 453 if (ipa == NULL) 454 err(1, "host: calloc"); 455 456 ipa->af = AF_INET; 457 ipa->netaddress = 1; 458 if ((ipa->name = strdup("0.0.0.0/0")) == NULL) 459 err(1, "host: strdup"); 460 $$ = ipa; 461 } 462 ; 463 464ids : /* empty */ { 465 $$.srcid = NULL; 466 $$.dstid = NULL; 467 } 468 | SRCID id DSTID id { 469 $$.srcid = $2; 470 $$.dstid = $4; 471 } 472 | SRCID id { 473 $$.srcid = $2; 474 $$.dstid = NULL; 475 } 476 | DSTID id { 477 $$.srcid = NULL; 478 $$.dstid = $2; 479 } 480 ; 481 482type : /* empty */ { 483 $$ = TYPE_REQUIRE; 484 } 485 | TYPE USE { 486 $$ = TYPE_USE; 487 } 488 | TYPE ACQUIRE { 489 $$ = TYPE_ACQUIRE; 490 } 491 | TYPE REQUIRE { 492 $$ = TYPE_REQUIRE; 493 } 494 | TYPE DENY { 495 $$ = TYPE_DENY; 496 } 497 | TYPE BYPASS { 498 $$ = TYPE_BYPASS; 499 } 500 | TYPE DONTACQ { 501 $$ = TYPE_DONTACQ; 502 } 503 ; 504 505id : STRING { $$ = $1; } 506 ; 507 508spispec : SPI STRING { 509 u_int32_t spi; 510 char *p = strchr($2, ':'); 511 512 if (p != NULL) { 513 *p++ = 0; 514 515 if (atospi(p, &spi) == -1) { 516 yyerror("%s is not a valid spi", p); 517 free($2); 518 YYERROR; 519 } 520 $$.spiin = spi; 521 } 522 if (atospi($2, &spi) == -1) { 523 yyerror("%s is not a valid spi", $2); 524 free($2); 525 YYERROR; 526 } 527 $$.spiout = spi; 528 529 530 free($2); 531 } 532 ; 533 534transforms : { 535 if ((ipsec_transforms = calloc(1, 536 sizeof(struct ipsec_transforms))) == NULL) 537 err(1, "transforms: calloc"); 538 } 539 transforms_l 540 { $$ = ipsec_transforms; } 541 | /* empty */ { 542 if (($$ = calloc(1, 543 sizeof(struct ipsec_transforms))) == NULL) 544 err(1, "transforms: calloc"); 545 } 546 ; 547 548transforms_l : transforms_l transform 549 | transform 550 ; 551 552transform : AUTHXF STRING { 553 if (ipsec_transforms->authxf) 554 yyerror("auth already set"); 555 else { 556 ipsec_transforms->authxf = parse_xf($2, 557 authxfs); 558 if (!ipsec_transforms->authxf) 559 yyerror("%s not a valid transform", $2); 560 } 561 } 562 | ENCXF STRING { 563 if (ipsec_transforms->encxf) 564 yyerror("enc already set"); 565 else { 566 ipsec_transforms->encxf = parse_xf($2, encxfs); 567 if (!ipsec_transforms->encxf) 568 yyerror("%s not a valid transform", $2); 569 } 570 } 571 | COMPXF STRING { 572 if (ipsec_transforms->compxf) 573 yyerror("comp already set"); 574 else { 575 ipsec_transforms->compxf = parse_xf($2, 576 compxfs); 577 if (!ipsec_transforms->compxf) 578 yyerror("%s not a valid transform", $2); 579 } 580 } 581 ; 582 583mmxfs : /* empty */ { 584 struct ipsec_transforms *xfs; 585 586 /* We create just an empty transform */ 587 if ((xfs = calloc(1, sizeof(struct ipsec_transforms))) 588 == NULL) 589 err(1, "mmxfs: calloc"); 590 $$ = xfs; 591 } 592 | MAIN transforms { $$ = $2; } 593 ; 594 595qmxfs : /* empty */ { 596 struct ipsec_transforms *xfs; 597 598 /* We create just an empty transform */ 599 if ((xfs = calloc(1, sizeof(struct ipsec_transforms))) 600 == NULL) 601 err(1, "qmxfs: calloc"); 602 $$ = xfs; 603 } 604 | QUICK transforms { $$ = $2; } 605 ; 606 607authkeyspec : /* empty */ { 608 $$.keyout = NULL; 609 $$.keyin = NULL; 610 } 611 | AUTHKEY keyspec { 612 $$.keyout = $2.keyout; 613 $$.keyin = $2.keyin; 614 } 615 ; 616 617enckeyspec : /* empty */ { 618 $$.keyout = NULL; 619 $$.keyin = NULL; 620 } 621 | ENCKEY keyspec { 622 $$.keyout = $2.keyout; 623 $$.keyin = $2.keyin; 624 } 625 ; 626 627keyspec : STRING { 628 unsigned char *hex; 629 unsigned char *p = strchr($1, ':'); 630 631 if (p != NULL ) { 632 *p++ = 0; 633 634 if (!strncmp(p, "0x", 2)) 635 p += 2; 636 $$.keyin = parsekey(p, strlen(p)); 637 } 638 639 hex = $1; 640 if (!strncmp(hex, "0x", 2)) 641 hex += 2; 642 $$.keyout = parsekey(hex, strlen(hex)); 643 644 free($1); 645 } 646 | FILENAME STRING { 647 unsigned char *p = strchr($2, ':'); 648 649 if (p != NULL) { 650 *p++ = 0; 651 $$.keyin = parsekeyfile(p); 652 } 653 $$.keyout = parsekeyfile($2); 654 free($2); 655 } 656 ; 657 658ikemode : /* empty */ { $$ = IKE_ACTIVE; } 659 | PASSIVE { $$ = IKE_PASSIVE; } 660 | DYNAMIC { $$ = IKE_DYNAMIC; } 661 | ACTIVE { $$ = IKE_ACTIVE; } 662 ; 663 664ikeauth : /* empty */ { 665 $$.type = IKE_AUTH_RSA; 666 $$.string = NULL; 667 } 668 | RSA { 669 $$.type = IKE_AUTH_RSA; 670 $$.string = NULL; 671 } 672 | PSK STRING { 673 $$.type = IKE_AUTH_PSK; 674 if (($$.string = strdup($2)) == NULL) 675 err(1, "ikeauth: strdup"); 676 } 677 ; 678 679string : string STRING 680 { 681 if (asprintf(&$$, "%s %s", $1, $2) == -1) 682 err(1, "string: asprintf"); 683 free($1); 684 free($2); 685 } 686 | STRING 687 ; 688 689varset : STRING '=' string 690 { 691 if (ipsec->opts & IPSECCTL_OPT_VERBOSE) 692 printf("%s = \"%s\"\n", $1, $3); 693 if (symset($1, $3, 0) == -1) 694 err(1, "cannot store variable"); 695 free($1); 696 free($3); 697 } 698 ; 699 700%% 701 702struct keywords { 703 const char *k_name; 704 int k_val; 705}; 706 707int 708yyerror(const char *fmt, ...) 709{ 710 va_list ap; 711 extern char *infile; 712 713 errors = 1; 714 va_start(ap, fmt); 715 fprintf(stderr, "%s: %d: ", infile, yyval.lineno); 716 vfprintf(stderr, fmt, ap); 717 fprintf(stderr, "\n"); 718 va_end(ap); 719 return (0); 720} 721 722int 723kw_cmp(const void *k, const void *e) 724{ 725 return (strcmp(k, ((const struct keywords *)e)->k_name)); 726} 727 728int 729lookup(char *s) 730{ 731 /* this has to be sorted always */ 732 static const struct keywords keywords[] = { 733 { "acquire", ACQUIRE }, 734 { "active", ACTIVE }, 735 { "ah", AH }, 736 { "any", ANY }, 737 { "auth", AUTHXF }, 738 { "authkey", AUTHKEY }, 739 { "bypass", BYPASS }, 740 { "comp", COMPXF }, 741 { "deny", DENY }, 742 { "dontacq", DONTACQ }, 743 { "dstid", DSTID }, 744 { "dynamic", DYNAMIC }, 745 { "enc", ENCXF }, 746 { "enckey", ENCKEY }, 747 { "esp", ESP }, 748 { "file", FILENAME }, 749 { "flow", FLOW }, 750 { "from", FROM }, 751 { "ike", IKE }, 752 { "in", IN }, 753 { "ipcomp", IPCOMP }, 754 { "ipip", IPIP }, 755 { "local", LOCAL }, 756 { "main", MAIN }, 757 { "out", OUT }, 758 { "passive", PASSIVE }, 759 { "peer", PEER }, 760 { "proto", PROTO }, 761 { "psk", PSK }, 762 { "quick", QUICK }, 763 { "require", REQUIRE }, 764 { "rsa", RSA }, 765 { "spi", SPI }, 766 { "srcid", SRCID }, 767 { "tcpmd5", TCPMD5 }, 768 { "to", TO }, 769 { "transport", TRANSPORT }, 770 { "tunnel", TUNNEL }, 771 { "type", TYPE }, 772 { "use", USE } 773 }; 774 const struct keywords *p; 775 776 p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]), 777 sizeof(keywords[0]), kw_cmp); 778 779 if (p) { 780 if (debug > 1) 781 fprintf(stderr, "%s: %d\n", s, p->k_val); 782 return (p->k_val); 783 } else { 784 if (debug > 1) 785 fprintf(stderr, "string: %s\n", s); 786 return (STRING); 787 } 788} 789 790#define MAXPUSHBACK 128 791 792char *parsebuf; 793int parseindex; 794char pushback_buffer[MAXPUSHBACK]; 795int pushback_index = 0; 796 797int 798lgetc(FILE *f) 799{ 800 int c, next; 801 802 if (parsebuf) { 803 /* Read character from the parsebuffer instead of input. */ 804 if (parseindex >= 0) { 805 c = parsebuf[parseindex++]; 806 if (c != '\0') 807 return (c); 808 parsebuf = NULL; 809 } else 810 parseindex++; 811 } 812 813 if (pushback_index) 814 return (pushback_buffer[--pushback_index]); 815 816 while ((c = getc(f)) == '\\') { 817 next = getc(f); 818 if (next != '\n') { 819 if (isspace(next)) 820 yyerror("whitespace after \\"); 821 ungetc(next, f); 822 break; 823 } 824 yylval.lineno = lineno; 825 lineno++; 826 } 827 if (c == '\t' || c == ' ') { 828 /* Compress blanks to a single space. */ 829 do { 830 c = getc(f); 831 } while (c == '\t' || c == ' '); 832 ungetc(c, f); 833 c = ' '; 834 } 835 836 return (c); 837} 838 839int 840lungetc(int c) 841{ 842 if (c == EOF) 843 return (EOF); 844 if (parsebuf) { 845 parseindex--; 846 if (parseindex >= 0) 847 return (c); 848 } 849 if (pushback_index < MAXPUSHBACK-1) 850 return (pushback_buffer[pushback_index++] = c); 851 else 852 return (EOF); 853} 854 855int 856findeol(void) 857{ 858 int c; 859 860 parsebuf = NULL; 861 pushback_index = 0; 862 863 /* skip to either EOF or the first real EOL */ 864 while (1) { 865 c = lgetc(fin); 866 if (c == '\n') { 867 lineno++; 868 break; 869 } 870 if (c == EOF) 871 break; 872 } 873 return (ERROR); 874} 875 876int 877yylex(void) 878{ 879 char buf[8096]; 880 char *p, *val; 881 int endc, c; 882 int token; 883 884top: 885 p = buf; 886 while ((c = lgetc(fin)) == ' ') 887 ; /* nothing */ 888 889 yylval.lineno = lineno; 890 if (c == '#') 891 while ((c = lgetc(fin)) != '\n' && c != EOF) 892 ; /* nothing */ 893 if (c == '$' && parsebuf == NULL) { 894 while (1) { 895 if ((c = lgetc(fin)) == EOF) 896 return (0); 897 898 if (p + 1 >= buf + sizeof(buf) - 1) { 899 yyerror("string too long"); 900 return (findeol()); 901 } 902 if (isalnum(c) || c == '_') { 903 *p++ = (char)c; 904 continue; 905 } 906 *p = '\0'; 907 lungetc(c); 908 break; 909 } 910 val = symget(buf); 911 if (val == NULL) { 912 yyerror("macro \"%s\" not defined", buf); 913 return (findeol()); 914 } 915 parsebuf = val; 916 parseindex = 0; 917 goto top; 918 } 919 920 switch (c) { 921 case '\'': 922 case '"': 923 endc = c; 924 while (1) { 925 if ((c = lgetc(fin)) == EOF) 926 return (0); 927 if (c == endc) { 928 *p = '\0'; 929 break; 930 } 931 if (c == '\n') { 932 lineno++; 933 continue; 934 } 935 if (p + 1 >= buf + sizeof(buf) - 1) { 936 yyerror("string too long"); 937 return (findeol()); 938 } 939 *p++ = (char)c; 940 } 941 yylval.v.string = strdup(buf); 942 if (yylval.v.string == NULL) 943 err(1, "yylex: strdup"); 944 return (STRING); 945 } 946 947#define allowed_in_string(x) \ 948 (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \ 949 x != '{' && x != '}' && x != '<' && x != '>' && \ 950 x != '!' && x != '=' && x != '/' && x != '#' && \ 951 x != ',')) 952 953 if (isalnum(c) || c == ':' || c == '_' || c == '*') { 954 do { 955 *p++ = c; 956 if ((unsigned)(p-buf) >= sizeof(buf)) { 957 yyerror("string too long"); 958 return (findeol()); 959 } 960 } while ((c = lgetc(fin)) != EOF && (allowed_in_string(c))); 961 lungetc(c); 962 *p = '\0'; 963 if ((token = lookup(buf)) == STRING) 964 if ((yylval.v.string = strdup(buf)) == NULL) 965 err(1, "yylex: strdup"); 966 return (token); 967 } 968 if (c == '\n') { 969 yylval.lineno = lineno; 970 lineno++; 971 } 972 if (c == EOF) 973 return (0); 974 return (c); 975} 976 977int 978parse_rules(FILE *input, struct ipsecctl *ipsecx) 979{ 980 struct sym *sym; 981 982 ipsec = ipsecx; 983 fin = input; 984 lineno = 1; 985 errors = 0; 986 987 yyparse(); 988 989 /* Free macros and check which have not been used. */ 990 while ((sym = TAILQ_FIRST(&symhead))) { 991 if ((ipsec->opts & IPSECCTL_OPT_VERBOSE2) && !sym->used) 992 fprintf(stderr, "warning: macro '%s' not " 993 "used\n", sym->nam); 994 TAILQ_REMOVE(&symhead, sym, entries); 995 free(sym->nam); 996 free(sym->val); 997 free(sym); 998 } 999 1000 return (errors ? -1 : 0); 1001} 1002 1003int 1004symset(const char *nam, const char *val, int persist) 1005{ 1006 struct sym *sym; 1007 1008 for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam); 1009 sym = TAILQ_NEXT(sym, entries)) 1010 ; /* nothing */ 1011 1012 if (sym != NULL) { 1013 if (sym->persist == 1) 1014 return (0); 1015 else { 1016 TAILQ_REMOVE(&symhead, sym, entries); 1017 free(sym->nam); 1018 free(sym->val); 1019 free(sym); 1020 } 1021 } 1022 if ((sym = calloc(1, sizeof(*sym))) == NULL) 1023 return (-1); 1024 1025 sym->nam = strdup(nam); 1026 if (sym->nam == NULL) { 1027 free(sym); 1028 return (-1); 1029 } 1030 sym->val = strdup(val); 1031 if (sym->val == NULL) { 1032 free(sym->nam); 1033 free(sym); 1034 return (-1); 1035 } 1036 sym->used = 0; 1037 sym->persist = persist; 1038 TAILQ_INSERT_TAIL(&symhead, sym, entries); 1039 return (0); 1040} 1041 1042int 1043cmdline_symset(char *s) 1044{ 1045 char *sym, *val; 1046 int ret; 1047 size_t len; 1048 1049 if ((val = strrchr(s, '=')) == NULL) 1050 return (-1); 1051 1052 len = strlen(s) - strlen(val) + 1; 1053 if ((sym = malloc(len)) == NULL) 1054 err(1, "cmdline_symset: malloc"); 1055 1056 strlcpy(sym, s, len); 1057 1058 ret = symset(sym, val + 1, 1); 1059 free(sym); 1060 1061 return (ret); 1062} 1063 1064char * 1065symget(const char *nam) 1066{ 1067 struct sym *sym; 1068 1069 TAILQ_FOREACH(sym, &symhead, entries) 1070 if (strcmp(nam, sym->nam) == 0) { 1071 sym->used = 1; 1072 return (sym->val); 1073 } 1074 return (NULL); 1075} 1076 1077int 1078atoul(char *s, u_long *ulvalp) 1079{ 1080 u_long ulval; 1081 char *ep; 1082 1083 errno = 0; 1084 ulval = strtoul(s, &ep, 0); 1085 if (s[0] == '\0' || *ep != '\0') 1086 return (-1); 1087 if (errno == ERANGE && ulval == ULONG_MAX) 1088 return (-1); 1089 *ulvalp = ulval; 1090 return (0); 1091} 1092 1093int 1094atospi(char *s, u_int32_t *spivalp) 1095{ 1096 unsigned long ulval; 1097 1098 if (atoul(s, &ulval) == -1) 1099 return (-1); 1100 if (ulval >= SPI_RESERVED_MIN && ulval <= SPI_RESERVED_MAX) { 1101 yyerror("illegal SPI value"); 1102 return (-1); 1103 } 1104 *spivalp = ulval; 1105 return (0); 1106} 1107 1108u_int8_t 1109x2i(unsigned char *s) 1110{ 1111 char ss[3]; 1112 1113 ss[0] = s[0]; 1114 ss[1] = s[1]; 1115 ss[2] = 0; 1116 1117 if (!isxdigit(s[0]) || !isxdigit(s[1])) { 1118 yyerror("keys need to be specified in hex digits"); 1119 return (-1); 1120 } 1121 return ((u_int8_t)strtoul(ss, NULL, 16)); 1122} 1123 1124struct ipsec_key * 1125parsekey(unsigned char *hexkey, size_t len) 1126{ 1127 struct ipsec_key *key; 1128 int i; 1129 1130 key = calloc(1, sizeof(struct ipsec_key)); 1131 if (key == NULL) 1132 err(1, "parsekey: calloc"); 1133 1134 key->len = len / 2; 1135 key->data = calloc(key->len, sizeof(u_int8_t)); 1136 if (key->data == NULL) 1137 err(1, "parsekey: calloc"); 1138 1139 for (i = 0; i < (int)key->len; i++) 1140 key->data[i] = x2i(hexkey + 2 * i); 1141 1142 return (key); 1143} 1144 1145struct ipsec_key * 1146parsekeyfile(char *filename) 1147{ 1148 struct stat sb; 1149 int fd; 1150 unsigned char *hex; 1151 1152 if ((fd = open(filename, O_RDONLY)) < 0) 1153 err(1, "parsekeyfile: open"); 1154 if (fstat(fd, &sb) < 0) 1155 err(1, "parsekeyfile: stat %s", filename); 1156 if ((sb.st_size > KEYSIZE_LIMIT) || (sb.st_size == 0)) 1157 errx(1, "parsekeyfile: key too %s", sb.st_size ? "large" : 1158 "small"); 1159 if ((hex = calloc(sb.st_size, sizeof(unsigned char))) == NULL) 1160 err(1, "parsekeyfile: calloc"); 1161 if (read(fd, hex, sb.st_size) < sb.st_size) 1162 err(1, "parsekeyfile: read"); 1163 close(fd); 1164 return (parsekey(hex, sb.st_size)); 1165} 1166 1167struct ipsec_addr_wrap * 1168host(const char *s) 1169{ 1170 struct ipsec_addr_wrap *ipa = NULL; 1171 int mask, v4mask, cont = 1; 1172 char *p, *q, *ps; 1173 1174 if ((p = strrchr(s, '/')) != NULL) { 1175 mask = strtol(p + 1, &q, 0); 1176 if (!q || *q || mask > 32 || q == (p + 1)) 1177 errx(1, "host: invalid netmask '%s'", p); 1178 if ((ps = malloc(strlen(s) - strlen(p) + 1)) == NULL) 1179 err(1, "host: calloc"); 1180 strlcpy(ps, s, strlen(s) - strlen(p) + 1); 1181 v4mask = mask; 1182 } else { 1183 if ((ps = strdup(s)) == NULL) 1184 err(1, "host: strdup"); 1185 v4mask = 32; 1186 mask = -1; 1187 } 1188 1189 /* Does interface with this name exist? */ 1190 if (cont && (ipa = host_if(ps, mask)) != NULL) 1191 cont = 0; 1192 1193 /* IPv4 address? */ 1194 if (cont && (ipa = host_v4(s, v4mask)) != NULL) 1195 cont = 0; 1196 1197#if notyet 1198 /* IPv6 address? */ 1199 if (cont && (ipa = host_v6(s, v6mask)) != NULL) 1200 cont = 0; 1201#endif 1202 1203 /* dns lookup */ 1204 if (cont && (ipa = host_dns(s, v4mask, 0)) != NULL) 1205 cont = 0; 1206 free(ps); 1207 1208 if (ipa == NULL || cont == 1) { 1209 fprintf(stderr, "no IP address found for %s\n", s); 1210 return (NULL); 1211 } 1212 return (ipa); 1213} 1214 1215struct ipsec_addr_wrap * 1216host_v4(const char *s, int mask) 1217{ 1218 struct ipsec_addr_wrap *ipa = NULL; 1219 struct in_addr ina; 1220 int bits = 32; 1221 1222 bzero(&ina, sizeof(struct in_addr)); 1223 if (strrchr(s, '/') != NULL) { 1224 if ((bits = inet_net_pton(AF_INET, s, &ina, sizeof(ina))) == -1) 1225 return (NULL); 1226 } else { 1227 if (inet_pton(AF_INET, s, &ina) != 1) 1228 return (NULL); 1229 } 1230 1231 ipa = calloc(1, sizeof(struct ipsec_addr_wrap)); 1232 if (ipa == NULL) 1233 err(1, "host_v4: calloc"); 1234 1235 ipa->address.v4 = ina; 1236 ipa->name = strdup(s); 1237 if (ipa->name == NULL) 1238 err(1, "host_v4: strdup"); 1239 ipa->af = AF_INET; 1240 1241 set_ipmask(ipa, bits); 1242 if (bits != (ipa->af == AF_INET ? 32 : 128)) 1243 ipa->netaddress = 1; 1244 1245 return (ipa); 1246} 1247 1248struct ipsec_addr_wrap * 1249host_dns(const char *s, int v4mask, int v6mask) 1250{ 1251 struct ipsec_addr_wrap *ipa = NULL; 1252 struct addrinfo hints, *res0, *res; 1253 int error; 1254 int bits = 32; 1255 1256 bzero(&hints, sizeof(struct addrinfo)); 1257 hints.ai_family = PF_UNSPEC; 1258 hints.ai_socktype = SOCK_STREAM; 1259 error = getaddrinfo(s, NULL, &hints, &res0); 1260 if (error) 1261 return (NULL); 1262 1263 for (res = res0; res; res = res->ai_next) { 1264 if (res->ai_family != AF_INET) 1265 continue; 1266 ipa = calloc(1, sizeof(struct ipsec_addr_wrap)); 1267 if (ipa == NULL) 1268 err(1, "host_dns: calloc"); 1269 memcpy(&ipa->address.v4, 1270 &((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr, 1271 sizeof(struct in_addr)); 1272 ipa->name = strdup(inet_ntoa(ipa->address.v4)); 1273 if (ipa->name == NULL) 1274 err(1, "host_dns: strdup"); 1275 ipa->af = AF_INET; 1276 1277 set_ipmask(ipa, bits); 1278 if (bits != (ipa->af == AF_INET ? 32 : 128)) 1279 ipa->netaddress = 1; 1280 break; 1281 } 1282 freeaddrinfo(res0); 1283 1284 return (ipa); 1285} 1286 1287struct ipsec_addr_wrap * 1288host_if(const char *s, int mask) 1289{ 1290 struct ipsec_addr_wrap *ipa = NULL; 1291 1292 if (ifa_exists(s)) 1293 ipa = ifa_lookup(s); 1294 1295 return (ipa); 1296} 1297 1298/* interface lookup routintes */ 1299 1300struct addr_node *iftab; 1301 1302void 1303ifa_load(void) 1304{ 1305 struct ifaddrs *ifap, *ifa; 1306 struct addr_node *n = NULL, *h = NULL; 1307 1308 if (getifaddrs(&ifap) < 0) 1309 err(1, "ifa_load: getiffaddrs"); 1310 1311 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 1312 if (!(ifa->ifa_addr->sa_family == AF_INET || 1313 ifa->ifa_addr->sa_family == AF_INET6 || 1314 ifa->ifa_addr->sa_family == AF_LINK)) 1315 continue; 1316 n = calloc(1, sizeof(struct addr_node)); 1317 if (n == NULL) 1318 err(1, "ifa_load: calloc"); 1319 n->af = ifa->ifa_addr->sa_family; 1320 if ((n->addr.name = strdup(ifa->ifa_name)) == NULL) 1321 err(1, "ifa_load: strdup"); 1322 if (n->af == AF_INET) { 1323 n->addr.af = AF_INET; 1324 memcpy(&n->addr.address.v4, &((struct sockaddr_in *) 1325 ifa->ifa_addr)->sin_addr.s_addr, 1326 sizeof(struct in_addr)); 1327 memcpy(&n->addr.mask.v4, &((struct sockaddr_in *) 1328 ifa->ifa_netmask)->sin_addr.s_addr, 1329 sizeof(struct in_addr)); 1330 } else if (n->af == AF_INET6) { 1331 n->addr.af = AF_INET6; 1332 memcpy(&n->addr.address.v6, &((struct sockaddr_in6 *) 1333 ifa->ifa_addr)->sin6_addr.s6_addr, 1334 sizeof(struct in6_addr)); 1335 memcpy(&n->addr.mask.v6, &((struct sockaddr_in6 *) 1336 ifa->ifa_netmask)->sin6_addr.s6_addr, 1337 sizeof(struct in6_addr)); 1338 } 1339 if ((n->addr.name = strdup(ifa->ifa_name)) == NULL) 1340 err(1, "ifa_load: strdup"); 1341 n->next = NULL; 1342 n->tail = n; 1343 if (h == NULL) 1344 h = n; 1345 else { 1346 h->tail->next = n; 1347 h->tail = n; 1348 } 1349 } 1350 1351 iftab = h; 1352 freeifaddrs(ifap); 1353} 1354 1355int 1356ifa_exists(const char *ifa_name) 1357{ 1358 struct addr_node *n; 1359 1360 if (iftab == NULL) 1361 ifa_load(); 1362 1363 for (n = iftab; n; n = n->next) { 1364 if (n->af == AF_LINK && !strncmp(n->addr.name, ifa_name, 1365 IFNAMSIZ)) 1366 return (1); 1367 } 1368 1369 return (0); 1370} 1371 1372struct ipsec_addr_wrap * 1373ifa_lookup(const char *ifa_name) 1374{ 1375 struct addr_node *p = NULL; 1376 struct ipsec_addr_wrap *ipa = NULL; 1377 1378 if (iftab == NULL) 1379 ifa_load(); 1380 1381 for (p = iftab; p; p = p->next) { 1382 if (p->af != AF_INET) 1383 continue; 1384 if (strncmp(p->addr.name, ifa_name, IFNAMSIZ)) 1385 continue; 1386 ipa = calloc(1, sizeof(struct ipsec_addr_wrap)); 1387 if (ipa == NULL) 1388 err(1, "ifa_lookup: calloc"); 1389 memcpy(ipa, &p->addr, sizeof(struct ipsec_addr_wrap)); 1390 if ((ipa->name = strdup(p->addr.name)) == NULL) 1391 err(1, "ifa_lookup: strdup"); 1392 set_ipmask(ipa, 32); 1393 break; 1394 } 1395 1396 return (ipa); 1397} 1398 1399void 1400set_ipmask(struct ipsec_addr_wrap *address, u_int8_t b) 1401{ 1402 struct ipsec_addr *ipa; 1403 int i, j = 0; 1404 1405 ipa = &address->mask; 1406 bzero(ipa, sizeof(struct ipsec_addr)); 1407 1408 while (b >= 32) { 1409 ipa->addr32[j++] = 0xffffffff; 1410 b -= 32; 1411 } 1412 for (i = 31; i > 31 - b; --i) 1413 ipa->addr32[j] |= (1 << i); 1414 if (b) 1415 ipa->addr32[j] = htonl(ipa->addr32[j]); 1416} 1417 1418struct ipsec_addr_wrap * 1419copyhost(const struct ipsec_addr_wrap *src) 1420{ 1421 struct ipsec_addr_wrap *dst; 1422 1423 dst = calloc(1, sizeof(struct ipsec_addr_wrap)); 1424 if (dst == NULL) 1425 err(1, "copyhost: calloc"); 1426 1427 memcpy(dst, src, sizeof(struct ipsec_addr_wrap)); 1428 1429 if ((dst->name = strdup(src->name)) == NULL) 1430 err(1, "copyhost: strdup"); 1431 1432 return dst; 1433} 1434 1435const struct ipsec_xf * 1436parse_xf(const char *name, const struct ipsec_xf xfs[]) 1437{ 1438 int i; 1439 1440 for (i = 0; xfs[i].name != NULL; i++) { 1441 if (strncmp(name, xfs[i].name, strlen(name))) 1442 continue; 1443 return &xfs[i]; 1444 } 1445 return (NULL); 1446} 1447 1448struct ipsec_transforms * 1449copytransforms(const struct ipsec_transforms *xfs) 1450{ 1451 struct ipsec_transforms *newxfs; 1452 1453 if (xfs == NULL) 1454 return (NULL); 1455 1456 newxfs = calloc(1, sizeof(struct ipsec_transforms)); 1457 if (newxfs == NULL) 1458 err(1, "copytransforms: calloc"); 1459 1460 memcpy(newxfs, xfs, sizeof(struct ipsec_transforms)); 1461 return (newxfs); 1462} 1463 1464int 1465validate_sa(u_int32_t spi, u_int8_t satype, struct ipsec_transforms *xfs, 1466 struct ipsec_key *authkey, struct ipsec_key *enckey, u_int8_t tmode) 1467{ 1468 /* Sanity checks */ 1469 if (spi == 0) { 1470 yyerror("no SPI specified"); 1471 return (0); 1472 } 1473 if (satype == IPSEC_AH) { 1474 if (!xfs) { 1475 yyerror("no transforms specified"); 1476 return (0); 1477 } 1478 if (!xfs->authxf) 1479 xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256]; 1480 if (xfs->encxf) { 1481 yyerror("ah does not provide encryption"); 1482 return (0); 1483 } 1484 if (xfs->compxf) { 1485 yyerror("ah does not provide compression"); 1486 return (0); 1487 } 1488 } 1489 if (satype == IPSEC_ESP) { 1490 if (!xfs) { 1491 yyerror("no transforms specified"); 1492 return (0); 1493 } 1494 if (xfs->compxf) { 1495 yyerror("esp does not provide compression"); 1496 return (0); 1497 } 1498 if (!xfs->authxf) 1499 xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256]; 1500 if (!xfs->encxf) 1501 xfs->encxf = &encxfs[ENCXF_AESCTR]; 1502 } 1503 if (satype == IPSEC_IPCOMP) { 1504 if (!xfs) { 1505 yyerror("no transform specified"); 1506 return (0); 1507 } 1508 if (xfs->authxf || xfs->encxf) { 1509 yyerror("no encryption or authenticaion with ipcomp"); 1510 return (0); 1511 } 1512 if (!xfs->compxf) 1513 xfs->compxf = &compxfs[COMPXF_DEFLATE]; 1514 } 1515 if (satype == IPSEC_IPIP) { 1516 if (!xfs) { 1517 yyerror("no transform specified"); 1518 return (0); 1519 } 1520 if (xfs->authxf || xfs->encxf || xfs->compxf) { 1521 yyerror("no encryption, authenticaion or compression" 1522 " with ipip"); 1523 return (0); 1524 } 1525 } 1526 if (satype == IPSEC_TCPMD5 && authkey == NULL && tmode != 1527 IPSEC_TRANSPORT) { 1528 yyerror("authentication key needed for tcpmd5"); 1529 return (0); 1530 } 1531 if (xfs && xfs->authxf) { 1532 if (!authkey) { 1533 yyerror("no authentication key specified"); 1534 return (0); 1535 } 1536 if (authkey->len != xfs->authxf->keymin) { 1537 yyerror("wrong authentication key length, needs to be " 1538 "%d bits", xfs->authxf->keymin * 8); 1539 return (0); 1540 } 1541 } 1542 if (xfs && xfs->encxf) { 1543 if (!enckey && xfs->encxf != &encxfs[ENCXF_NULL]) { 1544 yyerror("no encryption key specified"); 1545 return (0); 1546 } 1547 if (enckey) { 1548 if (enckey->len < xfs->encxf->keymin) { 1549 yyerror("encryption key too short, " 1550 "minimum %d bits", xfs->encxf->keymin * 8); 1551 return (0); 1552 } 1553 if (xfs->encxf->keymax < enckey->len) { 1554 yyerror("encryption key too long, " 1555 "maximum %d bits", xfs->encxf->keymax * 8); 1556 return (0); 1557 } 1558 } 1559 } 1560 1561 return 1; 1562} 1563 1564struct ipsec_rule * 1565create_sa(u_int8_t satype, u_int8_t tmode, struct ipsec_addr_wrap *src, struct 1566 ipsec_addr_wrap *dst, u_int32_t spi, struct ipsec_transforms *xfs, 1567 struct ipsec_key *authkey, struct ipsec_key *enckey) 1568{ 1569 struct ipsec_rule *r; 1570 1571 if (validate_sa(spi, satype, xfs, authkey, enckey, tmode) == 0) 1572 return (NULL); 1573 1574 r = calloc(1, sizeof(struct ipsec_rule)); 1575 if (r == NULL) 1576 err(1, "create_sa: calloc"); 1577 1578 r->type |= RULE_SA; 1579 r->satype = satype; 1580 r->tmode = tmode; 1581 r->src = src; 1582 r->dst = dst; 1583 r->spi = spi; 1584 r->xfs = xfs; 1585 r->authkey = authkey; 1586 r->enckey = enckey; 1587 1588 return r; 1589} 1590 1591struct ipsec_rule * 1592reverse_sa(struct ipsec_rule *rule, u_int32_t spi, struct ipsec_key *authkey, 1593 struct ipsec_key *enckey) 1594{ 1595 struct ipsec_rule *reverse; 1596 1597 if (validate_sa(spi, rule->satype, rule->xfs, authkey, enckey, 1598 rule->tmode) == 0) 1599 return (NULL); 1600 1601 reverse = calloc(1, sizeof(struct ipsec_rule)); 1602 if (reverse == NULL) 1603 err(1, "reverse_sa: calloc"); 1604 1605 reverse->type |= RULE_SA; 1606 reverse->satype = rule->satype; 1607 reverse->tmode = rule->tmode; 1608 reverse->src = copyhost(rule->dst); 1609 reverse->dst = copyhost(rule->src); 1610 reverse->spi = spi; 1611 reverse->xfs = copytransforms(rule->xfs); 1612 reverse->authkey = authkey; 1613 reverse->enckey = enckey; 1614 1615 return (reverse); 1616} 1617 1618struct ipsec_rule * 1619create_flow(u_int8_t dir, u_int8_t proto, struct ipsec_addr_wrap *src, 1620 struct ipsec_addr_wrap *dst, struct ipsec_addr_wrap *local, 1621 struct ipsec_addr_wrap *peer, u_int8_t satype, char *srcid, char *dstid, 1622 u_int8_t type) 1623{ 1624 struct ipsec_rule *r; 1625 1626 r = calloc(1, sizeof(struct ipsec_rule)); 1627 if (r == NULL) 1628 err(1, "create_flow: calloc"); 1629 1630 r->type |= RULE_FLOW; 1631 1632 if (dir == IPSEC_INOUT) 1633 r->direction = IPSEC_OUT; 1634 else 1635 r->direction = dir; 1636 1637 r->satype = satype; 1638 r->proto = proto; 1639 r->src = src; 1640 r->dst = dst; 1641 1642 if (type == TYPE_DENY || type == TYPE_BYPASS) { 1643 r->flowtype = type; 1644 return (r); 1645 } 1646 1647 r->flowtype = type; 1648 r->local = local; 1649 if (peer == NULL) { 1650 /* Set peer to remote host. Must be a host address. */ 1651 if (r->direction == IPSEC_IN) { 1652 if (r->src->netaddress) { 1653 yyerror("no peer specified"); 1654 goto errout; 1655 } 1656 r->peer = copyhost(r->src); 1657 } else { 1658 if (r->dst->netaddress) { 1659 yyerror("no peer specified"); 1660 goto errout; 1661 } 1662 r->peer = copyhost(r->dst); 1663 } 1664 } else 1665 r->peer = peer; 1666 1667 r->auth = calloc(1, sizeof(struct ipsec_auth)); 1668 if (r->auth == NULL) 1669 err(1, "create_flow: calloc"); 1670 r->auth->srcid = srcid; 1671 r->auth->dstid = dstid; 1672 r->auth->idtype = ID_FQDN; /* XXX For now only FQDN. */ 1673 1674 return r; 1675 1676errout: 1677 free(r); 1678 if (srcid) 1679 free(srcid); 1680 if (dstid) 1681 free(dstid); 1682 free(src); 1683 free(dst); 1684 1685 return NULL; 1686} 1687 1688struct ipsec_rule * 1689reverse_rule(struct ipsec_rule *rule) 1690{ 1691 struct ipsec_rule *reverse; 1692 1693 reverse = calloc(1, sizeof(struct ipsec_rule)); 1694 if (reverse == NULL) 1695 err(1, "reverse_rule: calloc"); 1696 1697 reverse->type |= RULE_FLOW; 1698 1699 /* Reverse direction */ 1700 if (rule->direction == (u_int8_t)IPSEC_OUT) 1701 reverse->direction = (u_int8_t)IPSEC_IN; 1702 else 1703 reverse->direction = (u_int8_t)IPSEC_OUT; 1704 1705 reverse->flowtype = rule->flowtype; 1706 reverse->src = copyhost(rule->dst); 1707 reverse->dst = copyhost(rule->src); 1708 if (rule->local) 1709 reverse->local = copyhost(rule->local); 1710 if (rule->peer) 1711 reverse->peer = copyhost(rule->peer); 1712 reverse->satype = rule->satype; 1713 reverse->proto = rule->proto; 1714 1715 if (rule->auth) { 1716 reverse->auth = calloc(1, sizeof(struct ipsec_auth)); 1717 if (reverse->auth == NULL) 1718 err(1, "reverse_rule: calloc"); 1719 if (rule->auth->dstid && (reverse->auth->dstid = 1720 strdup(rule->auth->dstid)) == NULL) 1721 err(1, "reverse_rule: strdup"); 1722 if (rule->auth->srcid && (reverse->auth->srcid = 1723 strdup(rule->auth->srcid)) == NULL) 1724 err(1, "reverse_rule: strdup"); 1725 reverse->auth->idtype = rule->auth->idtype; 1726 reverse->auth->type = rule->auth->type; 1727 } 1728 1729 return reverse; 1730} 1731 1732struct ipsec_rule * 1733create_ike(u_int8_t proto, struct ipsec_addr_wrap *src, struct ipsec_addr_wrap 1734 *dst, struct ipsec_addr_wrap *local, struct ipsec_addr_wrap *peer, 1735 struct ipsec_transforms *mmxfs, struct ipsec_transforms *qmxfs, 1736 u_int8_t satype, u_int8_t mode, char *srcid, char *dstid, 1737 struct ike_auth *authtype) 1738{ 1739 struct ipsec_rule *r; 1740 1741 r = calloc(1, sizeof(struct ipsec_rule)); 1742 if (r == NULL) 1743 err(1, "create_ike: calloc"); 1744 1745 r->type = RULE_IKE; 1746 1747 r->proto = proto; 1748 r->src = src; 1749 r->dst = dst; 1750 1751 if (peer == NULL) { 1752 /* Set peer to remote host. Must be a host address. */ 1753 if (r->direction == IPSEC_IN) { 1754 if (r->src->netaddress) { 1755 yyerror("no peer specified"); 1756 goto errout; 1757 } 1758 r->peer = copyhost(r->src); 1759 } else { 1760 if (r->dst->netaddress) { 1761 yyerror("no peer specified"); 1762 goto errout; 1763 } 1764 r->peer = copyhost(r->dst); 1765 } 1766 } else 1767 r->peer = peer; 1768 1769 if (local) 1770 r->local = local; 1771 1772 r->satype = satype; 1773 r->ikemode = mode; 1774 r->mmxfs = mmxfs; 1775 r->qmxfs = qmxfs; 1776 r->auth = calloc(1, sizeof(struct ipsec_auth)); 1777 if (r->auth == NULL) 1778 err(1, "create_ike: calloc"); 1779 r->auth->srcid = srcid; 1780 r->auth->dstid = dstid; 1781 r->auth->idtype = ID_FQDN; /* XXX For now only FQDN. */ 1782 r->ikeauth = calloc(1, sizeof(struct ike_auth)); 1783 if (r->ikeauth == NULL) 1784 err(1, "create_ike: calloc"); 1785 r->ikeauth->type = authtype->type; 1786 r->ikeauth->string = authtype->string; 1787 1788 return (r); 1789 1790errout: 1791 free(r); 1792 if (srcid) 1793 free(srcid); 1794 if (dstid) 1795 free(dstid); 1796 free(src); 1797 free(dst); 1798 if (authtype->string) 1799 free(authtype->string); 1800 1801 return (NULL); 1802} 1803