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