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