parse.y revision 1.102
1/* $OpenBSD: parse.y,v 1.102 2006/06/08 21:15:21 naddy 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 91const struct ipsec_xf groupxfs[] = { 92 { "unknown", GROUPXF_UNKNOWN, 0, 0 }, 93 { "modp768", GROUPXF_768, 768, 0 }, 94 { "grp1", GROUPXF_768, 768, 0 }, 95 { "modp1024", GROUPXF_1024, 1024, 0 }, 96 { "grp2", GROUPXF_1024, 1024, 0 }, 97 { "modp1536", GROUPXF_1536, 1536, 0 }, 98 { "grp5", GROUPXF_1536, 1536, 0 }, 99 { "modp2048", GROUPXF_2048, 2048, 0 }, 100 { "grp14", GROUPXF_2048, 2048, 0 }, 101 { "modp3072", GROUPXF_3072, 3072, 0 }, 102 { "grp15", GROUPXF_3072, 3072, 0 }, 103 { "modp4096", GROUPXF_4096, 4096, 0 }, 104 { "grp16", GROUPXF_4096, 4096, 0 }, 105 { "modp6144", GROUPXF_6144, 6144, 0 }, 106 { "grp18", GROUPXF_6144, 6144, 0 }, 107 { "modp8192", GROUPXF_8192, 8192, 0 }, 108 { "grp18", GROUPXF_8192, 8192, 0 }, 109 { NULL, 0, 0, 0 }, 110}; 111 112int yyerror(const char *, ...); 113int yyparse(void); 114int kw_cmp(const void *, const void *); 115int lookup(char *); 116int lgetc(FILE *); 117int lungetc(int); 118int findeol(void); 119int yylex(void); 120 121TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead); 122struct sym { 123 TAILQ_ENTRY(sym) entries; 124 int used; 125 int persist; 126 char *nam; 127 char *val; 128}; 129 130int symset(const char *, const char *, int); 131int cmdline_symset(char *); 132char *symget(const char *); 133int atoul(char *, u_long *); 134int atospi(char *, u_int32_t *); 135u_int8_t x2i(unsigned char *); 136struct ipsec_key *parsekey(unsigned char *, size_t); 137struct ipsec_key *parsekeyfile(char *); 138struct ipsec_addr_wrap *host(const char *); 139struct ipsec_addr_wrap *host_v6(const char *, int); 140struct ipsec_addr_wrap *host_v4(const char *, int); 141struct ipsec_addr_wrap *host_dns(const char *, int, int); 142struct ipsec_addr_wrap *host_if(const char *, int); 143void ifa_load(void); 144int ifa_exists(const char *); 145struct ipsec_addr_wrap *ifa_lookup(const char *ifa_name); 146struct ipsec_addr_wrap *ifa_grouplookup(const char *); 147void set_ipmask(struct ipsec_addr_wrap *, u_int8_t); 148const struct ipsec_xf *parse_xf(const char *, const struct ipsec_xf *); 149struct ipsec_life *parse_life(int); 150struct ipsec_transforms *copytransforms(const struct ipsec_transforms *); 151struct ipsec_life *copylife(const struct ipsec_life *); 152struct ipsec_auth *copyipsecauth(const struct ipsec_auth *); 153struct ike_auth *copyikeauth(const struct ike_auth *); 154struct ipsec_key *copykey(struct ipsec_key *); 155struct ipsec_addr_wrap *copyhost(const struct ipsec_addr_wrap *); 156struct ipsec_rule *copyrule(struct ipsec_rule *); 157int validate_sa(u_int32_t, u_int8_t, 158 struct ipsec_transforms *, struct ipsec_key *, 159 struct ipsec_key *, u_int8_t); 160struct ipsec_rule *create_sa(u_int8_t, u_int8_t, struct ipsec_hosts *, 161 u_int32_t, struct ipsec_transforms *, 162 struct ipsec_key *, struct ipsec_key *); 163struct ipsec_rule *reverse_sa(struct ipsec_rule *, u_int32_t, 164 struct ipsec_key *, struct ipsec_key *); 165struct ipsec_rule *create_sagroup(struct ipsec_addr_wrap *, u_int8_t, 166 u_int32_t, struct ipsec_addr_wrap *, u_int8_t, 167 u_int32_t); 168struct ipsec_rule *create_flow(u_int8_t, u_int8_t, struct ipsec_hosts *, 169 struct ipsec_hosts *, u_int8_t, char *, char *, 170 u_int8_t); 171int expand_rule(struct ipsec_rule *, u_int8_t, u_int32_t, 172 struct ipsec_key *, struct ipsec_key *, int); 173struct ipsec_rule *reverse_rule(struct ipsec_rule *); 174struct ipsec_rule *create_ike(u_int8_t, struct ipsec_hosts *, 175 struct ipsec_hosts *, struct ike_mode *, 176 struct ike_mode *, u_int8_t, u_int8_t, u_int8_t, 177 char *, char *, struct ike_auth *); 178int add_sagroup(struct ipsec_rule *); 179 180struct ipsec_transforms *ipsec_transforms; 181 182typedef struct { 183 union { 184 u_int32_t number; 185 u_int8_t ikemode; 186 u_int8_t dir; 187 u_int8_t satype; /* encapsulating prococol */ 188 u_int8_t proto; /* encapsulated protocol */ 189 u_int8_t tmode; 190 char *string; 191 u_int16_t port; 192 struct ipsec_hosts hosts; 193 struct ipsec_hosts peers; 194 struct ipsec_addr_wrap *singlehost; 195 struct ipsec_addr_wrap *host; 196 struct { 197 char *srcid; 198 char *dstid; 199 } ids; 200 char *id; 201 u_int8_t type; 202 struct ike_auth ikeauth; 203 struct { 204 u_int32_t spiout; 205 u_int32_t spiin; 206 } spis; 207 struct { 208 struct ipsec_key *keyout; 209 struct ipsec_key *keyin; 210 } authkeys; 211 struct { 212 struct ipsec_key *keyout; 213 struct ipsec_key *keyin; 214 } enckeys; 215 struct { 216 struct ipsec_key *keyout; 217 struct ipsec_key *keyin; 218 } keys; 219 struct ipsec_transforms *transforms; 220 struct ipsec_life *life; 221 struct ike_mode *mainmode; 222 struct ike_mode *quickmode; 223 } v; 224 int lineno; 225} YYSTYPE; 226 227%} 228 229%token FLOW FROM ESP AH IN PEER ON OUT TO SRCID DSTID RSA PSK TCPMD5 SPI 230%token AUTHKEY ENCKEY FILENAME AUTHXF ENCXF ERROR IKE MAIN QUICK PASSIVE 231%token ACTIVE ANY IPIP IPCOMP COMPXF TUNNEL TRANSPORT DYNAMIC LIFE 232%token TYPE DENY BYPASS LOCAL PROTO USE ACQUIRE REQUIRE DONTACQ GROUP PORT 233%token <v.string> STRING 234%type <v.string> string 235%type <v.dir> dir 236%type <v.satype> satype 237%type <v.proto> proto 238%type <v.tmode> tmode 239%type <v.number> number 240%type <v.hosts> hosts 241%type <v.port> port 242%type <v.peers> peers 243%type <v.singlehost> singlehost 244%type <v.host> host host_list 245%type <v.ids> ids 246%type <v.id> id 247%type <v.spis> spispec 248%type <v.authkeys> authkeyspec 249%type <v.enckeys> enckeyspec 250%type <v.keys> keyspec 251%type <v.transforms> transforms 252%type <v.ikemode> ikemode 253%type <v.ikeauth> ikeauth 254%type <v.type> type 255%type <v.life> life 256%type <v.mainmode> mainmode 257%type <v.quickmode> quickmode 258%% 259 260grammar : /* empty */ 261 | grammar '\n' 262 | grammar ikerule '\n' 263 | grammar flowrule '\n' 264 | grammar sarule '\n' 265 | grammar tcpmd5rule '\n' 266 | grammar varset '\n' 267 | grammar error '\n' { errors++; } 268 ; 269 270number : STRING { 271 unsigned long ulval; 272 273 if (atoul($1, &ulval) == -1) { 274 yyerror("%s is not a number", $1); 275 free($1); 276 YYERROR; 277 } 278 if (ulval > UINT_MAX) { 279 yyerror("0x%lx out of range", ulval); 280 free($1); 281 YYERROR; 282 } 283 $$ = (u_int32_t)ulval; 284 free($1); 285 } 286 ; 287 288comma : ',' 289 | /* empty */ 290 ; 291 292tcpmd5rule : TCPMD5 hosts spispec authkeyspec { 293 struct ipsec_rule *r; 294 295 r = create_sa(IPSEC_TCPMD5, IPSEC_TRANSPORT, &$2, 296 $3.spiout, NULL, $4.keyout, NULL); 297 if (r == NULL) 298 YYERROR; 299 r->nr = ipsec->rule_nr++; 300 301 if (expand_rule(r, 0, $3.spiin, $4.keyin, NULL, 0)) 302 errx(1, "tcpmd5rule: expand_rule"); 303 } 304 ; 305 306sarule : satype tmode hosts spispec transforms authkeyspec 307 enckeyspec { 308 struct ipsec_rule *r; 309 310 r = create_sa($1, $2, &$3, $4.spiout, $5, $6.keyout, 311 $7.keyout); 312 if (r == NULL) 313 YYERROR; 314 r->nr = ipsec->rule_nr++; 315 316 if (expand_rule(r, 0, $4.spiin, $6.keyin, $7.keyin, 1)) 317 errx(1, "sarule: expand_rule"); 318 } 319 ; 320 321flowrule : FLOW satype dir proto hosts peers ids type { 322 struct ipsec_rule *r; 323 324 r = create_flow($3, $4, &$5, &$6, $2, $7.srcid, 325 $7.dstid, $8); 326 if (r == NULL) 327 YYERROR; 328 329 if (expand_rule(r, $3, 0, NULL, NULL, 0)) 330 errx(1, "flowrule: expand_rule"); 331 } 332 ; 333 334ikerule : IKE ikemode satype tmode proto hosts peers mainmode quickmode 335 ids ikeauth { 336 struct ipsec_rule *r; 337 338 r = create_ike($5, &$6, &$7, $8, $9, $3, $4, $2, 339 $10.srcid, $10.dstid, &$11); 340 if (r == NULL) 341 YYERROR; 342 r->nr = ipsec->rule_nr++; 343 344 if (expand_rule(r, 0, 0, NULL, NULL, 0)) 345 errx(1, "ikerule: expand_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, 0, 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 port TO host port { 386 $$.src = $2; 387 $$.sport = $3; 388 $$.dst = $5; 389 $$.dport = $6; 390 } 391 | TO host port FROM host port { 392 $$.src = $5; 393 $$.sport = $6; 394 $$.dst = $2; 395 $$.dport = $3; 396 } 397 ; 398 399port : /* empty */ { $$ = 0; } 400 | PORT STRING { 401 struct servent *s; 402 const char *errstr; 403 int port; 404 405 if ((s = getservbyname($2, "tcp")) != NULL || 406 (s = getservbyname($2, "udp")) != NULL) { 407 $$ = s->s_port; 408 } else { 409 errstr = NULL; 410 port = strtonum($2, 0, USHRT_MAX, &errstr); 411 if (errstr) { 412 yyerror("unknown port: %s", $2); 413 YYERROR; 414 } 415 $$ = htons(port); 416 } 417 } 418 ; 419 420peers : /* empty */ { 421 $$.dst = NULL; 422 $$.src = NULL; 423 } 424 | PEER singlehost LOCAL singlehost { 425 $$.dst = $2; 426 $$.src = $4; 427 } 428 | LOCAL singlehost PEER singlehost { 429 $$.dst = $4; 430 $$.src = $2; 431 } 432 | PEER singlehost { 433 $$.dst = $2; 434 $$.src = NULL; 435 } 436 | LOCAL singlehost { 437 $$.dst = NULL; 438 $$.src = $2; 439 } 440 ; 441 442singlehost : /* empty */ { $$ = NULL; } 443 | STRING { 444 if (($$ = host($1)) == NULL) { 445 free($1); 446 yyerror("could not parse host specification"); 447 YYERROR; 448 } 449 free($1); 450 } 451 ; 452 453host_list : host { $$ = $1; } 454 | host_list comma host { 455 if ($3 == NULL) 456 $$ = $1; 457 else if ($1 == NULL) 458 $$ = $3; 459 else { 460 $1->tail->next = $3; 461 $1->tail = $3->tail; 462 $$ = $1; 463 } 464 } 465 ; 466 467host : STRING { 468 if (($$ = host($1)) == NULL) { 469 free($1); 470 yyerror("could not parse host specification"); 471 YYERROR; 472 } 473 free($1); 474 } 475 | STRING '/' number { 476 char *buf; 477 478 if (asprintf(&buf, "%s/%u", $1, $3) == -1) 479 err(1, "host: asprintf"); 480 free($1); 481 if (($$ = host(buf)) == NULL) { 482 free(buf); 483 yyerror("could not parse host specification"); 484 YYERROR; 485 } 486 free(buf); 487 } 488 | ANY { 489 struct ipsec_addr_wrap *ipa; 490 491 ipa = calloc(1, sizeof(struct ipsec_addr_wrap)); 492 if (ipa == NULL) 493 err(1, "host: calloc"); 494 495 ipa->af = AF_INET; 496 ipa->netaddress = 1; 497 if ((ipa->name = strdup("0.0.0.0/0")) == NULL) 498 err(1, "host: strdup"); 499 500 ipa->next = calloc(1, sizeof(struct ipsec_addr_wrap)); 501 if (ipa->next == NULL) 502 err(1, "host: calloc"); 503 504 ipa->next->af = AF_INET6; 505 ipa->next->netaddress = 1; 506 if ((ipa->next->name = strdup("::/0")) == NULL) 507 err(1, "host: strdup"); 508 509 $$ = ipa; 510 } 511 | '{' host_list '}' { $$ = $2; } 512 ; 513 514ids : /* empty */ { 515 $$.srcid = NULL; 516 $$.dstid = NULL; 517 } 518 | SRCID id DSTID id { 519 $$.srcid = $2; 520 $$.dstid = $4; 521 } 522 | SRCID id { 523 $$.srcid = $2; 524 $$.dstid = NULL; 525 } 526 | DSTID id { 527 $$.srcid = NULL; 528 $$.dstid = $2; 529 } 530 ; 531 532type : /* empty */ { 533 $$ = TYPE_REQUIRE; 534 } 535 | TYPE USE { 536 $$ = TYPE_USE; 537 } 538 | TYPE ACQUIRE { 539 $$ = TYPE_ACQUIRE; 540 } 541 | TYPE REQUIRE { 542 $$ = TYPE_REQUIRE; 543 } 544 | TYPE DENY { 545 $$ = TYPE_DENY; 546 } 547 | TYPE BYPASS { 548 $$ = TYPE_BYPASS; 549 } 550 | TYPE DONTACQ { 551 $$ = TYPE_DONTACQ; 552 } 553 ; 554 555id : STRING { $$ = $1; } 556 ; 557 558spispec : SPI STRING { 559 u_int32_t spi; 560 char *p = strchr($2, ':'); 561 562 if (p != NULL) { 563 *p++ = 0; 564 565 if (atospi(p, &spi) == -1) { 566 yyerror("%s is not a valid spi", p); 567 free($2); 568 YYERROR; 569 } 570 $$.spiin = spi; 571 } else 572 $$.spiin = 0; 573 574 if (atospi($2, &spi) == -1) { 575 yyerror("%s is not a valid spi", $2); 576 free($2); 577 YYERROR; 578 } 579 $$.spiout = spi; 580 581 582 free($2); 583 } 584 ; 585 586transforms : { 587 if ((ipsec_transforms = calloc(1, 588 sizeof(struct ipsec_transforms))) == NULL) 589 err(1, "transforms: calloc"); 590 } 591 transforms_l 592 { $$ = ipsec_transforms; } 593 | /* empty */ { 594 if (($$ = calloc(1, 595 sizeof(struct ipsec_transforms))) == NULL) 596 err(1, "transforms: calloc"); 597 } 598 ; 599 600transforms_l : transforms_l transform 601 | transform 602 ; 603 604transform : AUTHXF STRING { 605 if (ipsec_transforms->authxf) 606 yyerror("auth already set"); 607 else { 608 ipsec_transforms->authxf = parse_xf($2, 609 authxfs); 610 if (!ipsec_transforms->authxf) 611 yyerror("%s not a valid transform", $2); 612 } 613 } 614 | ENCXF STRING { 615 if (ipsec_transforms->encxf) 616 yyerror("enc already set"); 617 else { 618 ipsec_transforms->encxf = parse_xf($2, encxfs); 619 if (!ipsec_transforms->encxf) 620 yyerror("%s not a valid transform", $2); 621 } 622 } 623 | COMPXF STRING { 624 if (ipsec_transforms->compxf) 625 yyerror("comp already set"); 626 else { 627 ipsec_transforms->compxf = parse_xf($2, 628 compxfs); 629 if (!ipsec_transforms->compxf) 630 yyerror("%s not a valid transform", $2); 631 } 632 } 633 | GROUP STRING { 634 if (ipsec_transforms->groupxf) 635 yyerror("group already set"); 636 else { 637 ipsec_transforms->groupxf = parse_xf($2, 638 groupxfs); 639 if (!ipsec_transforms->groupxf) 640 yyerror("%s not a valid transform", $2); 641 } 642 } 643 ; 644 645mainmode : /* empty */ { 646 struct ike_mode *mm; 647 648 /* We create just an empty mode */ 649 if ((mm = calloc(1, sizeof(struct ike_mode))) == NULL) 650 err(1, "mainmode: calloc"); 651 $$ = mm; 652 } 653 | MAIN transforms life { 654 struct ike_mode *mm; 655 656 if ((mm = calloc(1, sizeof(struct ike_mode))) == NULL) 657 err(1, "mainmode: calloc"); 658 mm->xfs = $2; 659 mm->life = $3; 660 $$ = mm; 661 } 662 ; 663 664quickmode : /* empty */ { 665 struct ike_mode *qm; 666 667 /* We create just an empty mode */ 668 if ((qm = calloc(1, sizeof(struct ike_mode))) == NULL) 669 err(1, "quickmode: calloc"); 670 $$ = qm; 671 } 672 | QUICK transforms life { 673 struct ike_mode *qm; 674 675 if ((qm = calloc(1, sizeof(struct ike_mode))) == NULL) 676 err(1, "quickmode: calloc"); 677 qm->xfs = $2; 678 qm->life = $3; 679 $$ = qm; 680 } 681 ; 682 683life : /* empty */ { 684 struct ipsec_life *life; 685 686 /* We create just an empty transform */ 687 if ((life = calloc(1, sizeof(struct ipsec_life))) 688 == NULL) 689 err(1, "life: calloc"); 690 life->lifetime = -1; 691 life->lifevolume = -1; 692 $$ = life; 693 } 694 | LIFE number { 695 struct ipsec_life *life; 696 697 life = parse_life($2); 698 if (life == NULL) 699 yyerror("%s not a valid lifetime", $2); 700 $$ = life; 701 } 702 ; 703 704authkeyspec : /* empty */ { 705 $$.keyout = NULL; 706 $$.keyin = NULL; 707 } 708 | AUTHKEY keyspec { 709 $$.keyout = $2.keyout; 710 $$.keyin = $2.keyin; 711 } 712 ; 713 714enckeyspec : /* empty */ { 715 $$.keyout = NULL; 716 $$.keyin = NULL; 717 } 718 | ENCKEY keyspec { 719 $$.keyout = $2.keyout; 720 $$.keyin = $2.keyin; 721 } 722 ; 723 724keyspec : STRING { 725 unsigned char *hex; 726 unsigned char *p = strchr($1, ':'); 727 728 if (p != NULL ) { 729 *p++ = 0; 730 731 if (!strncmp(p, "0x", 2)) 732 p += 2; 733 $$.keyin = parsekey(p, strlen(p)); 734 } else 735 $$.keyin = NULL; 736 737 hex = $1; 738 if (!strncmp(hex, "0x", 2)) 739 hex += 2; 740 $$.keyout = parsekey(hex, strlen(hex)); 741 742 free($1); 743 } 744 | FILENAME STRING { 745 unsigned char *p = strchr($2, ':'); 746 747 if (p != NULL) { 748 *p++ = 0; 749 $$.keyin = parsekeyfile(p); 750 } 751 $$.keyout = parsekeyfile($2); 752 free($2); 753 } 754 ; 755 756ikemode : /* empty */ { $$ = IKE_ACTIVE; } 757 | PASSIVE { $$ = IKE_PASSIVE; } 758 | DYNAMIC { $$ = IKE_DYNAMIC; } 759 | ACTIVE { $$ = IKE_ACTIVE; } 760 ; 761 762ikeauth : /* empty */ { 763 $$.type = IKE_AUTH_RSA; 764 $$.string = NULL; 765 } 766 | RSA { 767 $$.type = IKE_AUTH_RSA; 768 $$.string = NULL; 769 } 770 | PSK STRING { 771 $$.type = IKE_AUTH_PSK; 772 if (($$.string = strdup($2)) == NULL) 773 err(1, "ikeauth: strdup"); 774 } 775 ; 776 777string : string STRING 778 { 779 if (asprintf(&$$, "%s %s", $1, $2) == -1) 780 err(1, "string: asprintf"); 781 free($1); 782 free($2); 783 } 784 | STRING 785 ; 786 787varset : STRING '=' string 788 { 789 if (ipsec->opts & IPSECCTL_OPT_VERBOSE) 790 printf("%s = \"%s\"\n", $1, $3); 791 if (symset($1, $3, 0) == -1) 792 err(1, "cannot store variable"); 793 free($1); 794 free($3); 795 } 796 ; 797 798%% 799 800struct keywords { 801 const char *k_name; 802 int k_val; 803}; 804 805int 806yyerror(const char *fmt, ...) 807{ 808 va_list ap; 809 extern const char *infile; 810 811 errors = 1; 812 va_start(ap, fmt); 813 fprintf(stderr, "%s: %d: ", infile, yyval.lineno); 814 vfprintf(stderr, fmt, ap); 815 fprintf(stderr, "\n"); 816 va_end(ap); 817 return (0); 818} 819 820int 821kw_cmp(const void *k, const void *e) 822{ 823 return (strcmp(k, ((const struct keywords *)e)->k_name)); 824} 825 826int 827lookup(char *s) 828{ 829 /* this has to be sorted always */ 830 static const struct keywords keywords[] = { 831 { "acquire", ACQUIRE }, 832 { "active", ACTIVE }, 833 { "ah", AH }, 834 { "any", ANY }, 835 { "auth", AUTHXF }, 836 { "authkey", AUTHKEY }, 837 { "bypass", BYPASS }, 838 { "comp", COMPXF }, 839 { "deny", DENY }, 840 { "dontacq", DONTACQ }, 841 { "dstid", DSTID }, 842 { "dynamic", DYNAMIC }, 843 { "enc", ENCXF }, 844 { "enckey", ENCKEY }, 845 { "esp", ESP }, 846 { "file", FILENAME }, 847 { "flow", FLOW }, 848 { "from", FROM }, 849 { "group", GROUP }, 850 { "ike", IKE }, 851 { "in", IN }, 852 { "ipcomp", IPCOMP }, 853 { "ipip", IPIP }, 854 { "life", LIFE }, 855 { "local", LOCAL }, 856 { "main", MAIN }, 857 { "out", OUT }, 858 { "passive", PASSIVE }, 859 { "peer", PEER }, 860 { "port", PORT }, 861 { "proto", PROTO }, 862 { "psk", PSK }, 863 { "quick", QUICK }, 864 { "require", REQUIRE }, 865 { "rsa", RSA }, 866 { "spi", SPI }, 867 { "srcid", SRCID }, 868 { "tcpmd5", TCPMD5 }, 869 { "to", TO }, 870 { "transport", TRANSPORT }, 871 { "tunnel", TUNNEL }, 872 { "type", TYPE }, 873 { "use", USE } 874 }; 875 const struct keywords *p; 876 877 p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]), 878 sizeof(keywords[0]), kw_cmp); 879 880 if (p) { 881 if (debug > 1) 882 fprintf(stderr, "%s: %d\n", s, p->k_val); 883 return (p->k_val); 884 } else { 885 if (debug > 1) 886 fprintf(stderr, "string: %s\n", s); 887 return (STRING); 888 } 889} 890 891#define MAXPUSHBACK 128 892 893char *parsebuf; 894int parseindex; 895char pushback_buffer[MAXPUSHBACK]; 896int pushback_index = 0; 897 898int 899lgetc(FILE *f) 900{ 901 int c, next; 902 903 if (parsebuf) { 904 /* Read character from the parsebuffer instead of input. */ 905 if (parseindex >= 0) { 906 c = parsebuf[parseindex++]; 907 if (c != '\0') 908 return (c); 909 parsebuf = NULL; 910 } else 911 parseindex++; 912 } 913 914 if (pushback_index) 915 return (pushback_buffer[--pushback_index]); 916 917 while ((c = getc(f)) == '\\') { 918 next = getc(f); 919 if (next != '\n') { 920 c = next; 921 break; 922 } 923 yylval.lineno = lineno; 924 lineno++; 925 } 926 if (c == '\t' || c == ' ') { 927 /* Compress blanks to a single space. */ 928 do { 929 c = getc(f); 930 } while (c == '\t' || c == ' '); 931 ungetc(c, f); 932 c = ' '; 933 } 934 935 return (c); 936} 937 938int 939lungetc(int c) 940{ 941 if (c == EOF) 942 return (EOF); 943 if (parsebuf) { 944 parseindex--; 945 if (parseindex >= 0) 946 return (c); 947 } 948 if (pushback_index < MAXPUSHBACK-1) 949 return (pushback_buffer[pushback_index++] = c); 950 else 951 return (EOF); 952} 953 954int 955findeol(void) 956{ 957 int c; 958 959 parsebuf = NULL; 960 pushback_index = 0; 961 962 /* skip to either EOF or the first real EOL */ 963 while (1) { 964 c = lgetc(fin); 965 if (c == '\n') { 966 lineno++; 967 break; 968 } 969 if (c == EOF) 970 break; 971 } 972 return (ERROR); 973} 974 975int 976yylex(void) 977{ 978 char buf[8096]; 979 char *p, *val; 980 int endc, c; 981 int token; 982 983top: 984 p = buf; 985 while ((c = lgetc(fin)) == ' ') 986 ; /* nothing */ 987 988 yylval.lineno = lineno; 989 if (c == '#') 990 while ((c = lgetc(fin)) != '\n' && c != EOF) 991 ; /* nothing */ 992 if (c == '$' && parsebuf == NULL) { 993 while (1) { 994 if ((c = lgetc(fin)) == EOF) 995 return (0); 996 997 if (p + 1 >= buf + sizeof(buf) - 1) { 998 yyerror("string too long"); 999 return (findeol()); 1000 } 1001 if (isalnum(c) || c == '_') { 1002 *p++ = (char)c; 1003 continue; 1004 } 1005 *p = '\0'; 1006 lungetc(c); 1007 break; 1008 } 1009 val = symget(buf); 1010 if (val == NULL) { 1011 yyerror("macro \"%s\" not defined", buf); 1012 return (findeol()); 1013 } 1014 parsebuf = val; 1015 parseindex = 0; 1016 goto top; 1017 } 1018 1019 switch (c) { 1020 case '\'': 1021 case '"': 1022 endc = c; 1023 while (1) { 1024 if ((c = lgetc(fin)) == EOF) 1025 return (0); 1026 if (c == endc) { 1027 *p = '\0'; 1028 break; 1029 } 1030 if (c == '\n') { 1031 lineno++; 1032 continue; 1033 } 1034 if (p + 1 >= buf + sizeof(buf) - 1) { 1035 yyerror("string too long"); 1036 return (findeol()); 1037 } 1038 *p++ = (char)c; 1039 } 1040 yylval.v.string = strdup(buf); 1041 if (yylval.v.string == NULL) 1042 err(1, "yylex: strdup"); 1043 return (STRING); 1044 } 1045 1046#define allowed_in_string(x) \ 1047 (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \ 1048 x != '{' && x != '}' && x != '<' && x != '>' && \ 1049 x != '!' && x != '=' && x != '/' && x != '#' && \ 1050 x != ',')) 1051 1052 if (isalnum(c) || c == ':' || c == '_' || c == '*') { 1053 do { 1054 *p++ = c; 1055 if ((unsigned)(p-buf) >= sizeof(buf)) { 1056 yyerror("string too long"); 1057 return (findeol()); 1058 } 1059 } while ((c = lgetc(fin)) != EOF && (allowed_in_string(c))); 1060 lungetc(c); 1061 *p = '\0'; 1062 if ((token = lookup(buf)) == STRING) 1063 if ((yylval.v.string = strdup(buf)) == NULL) 1064 err(1, "yylex: strdup"); 1065 return (token); 1066 } 1067 if (c == '\n') { 1068 yylval.lineno = lineno; 1069 lineno++; 1070 } 1071 if (c == EOF) 1072 return (0); 1073 return (c); 1074} 1075 1076int 1077parse_rules(FILE *input, struct ipsecctl *ipsecx) 1078{ 1079 struct sym *sym; 1080 1081 ipsec = ipsecx; 1082 fin = input; 1083 lineno = 1; 1084 errors = 0; 1085 1086 yyparse(); 1087 1088 /* Free macros and check which have not been used. */ 1089 while ((sym = TAILQ_FIRST(&symhead))) { 1090 if ((ipsec->opts & IPSECCTL_OPT_VERBOSE2) && !sym->used) 1091 fprintf(stderr, "warning: macro '%s' not " 1092 "used\n", sym->nam); 1093 TAILQ_REMOVE(&symhead, sym, entries); 1094 free(sym->nam); 1095 free(sym->val); 1096 free(sym); 1097 } 1098 1099 return (errors ? -1 : 0); 1100} 1101 1102int 1103symset(const char *nam, const char *val, int persist) 1104{ 1105 struct sym *sym; 1106 1107 for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam); 1108 sym = TAILQ_NEXT(sym, entries)) 1109 ; /* nothing */ 1110 1111 if (sym != NULL) { 1112 if (sym->persist == 1) 1113 return (0); 1114 else { 1115 TAILQ_REMOVE(&symhead, sym, entries); 1116 free(sym->nam); 1117 free(sym->val); 1118 free(sym); 1119 } 1120 } 1121 if ((sym = calloc(1, sizeof(*sym))) == NULL) 1122 return (-1); 1123 1124 sym->nam = strdup(nam); 1125 if (sym->nam == NULL) { 1126 free(sym); 1127 return (-1); 1128 } 1129 sym->val = strdup(val); 1130 if (sym->val == NULL) { 1131 free(sym->nam); 1132 free(sym); 1133 return (-1); 1134 } 1135 sym->used = 0; 1136 sym->persist = persist; 1137 TAILQ_INSERT_TAIL(&symhead, sym, entries); 1138 return (0); 1139} 1140 1141int 1142cmdline_symset(char *s) 1143{ 1144 char *sym, *val; 1145 int ret; 1146 size_t len; 1147 1148 if ((val = strrchr(s, '=')) == NULL) 1149 return (-1); 1150 1151 len = strlen(s) - strlen(val) + 1; 1152 if ((sym = malloc(len)) == NULL) 1153 err(1, "cmdline_symset: malloc"); 1154 1155 strlcpy(sym, s, len); 1156 1157 ret = symset(sym, val + 1, 1); 1158 free(sym); 1159 1160 return (ret); 1161} 1162 1163char * 1164symget(const char *nam) 1165{ 1166 struct sym *sym; 1167 1168 TAILQ_FOREACH(sym, &symhead, entries) 1169 if (strcmp(nam, sym->nam) == 0) { 1170 sym->used = 1; 1171 return (sym->val); 1172 } 1173 return (NULL); 1174} 1175 1176int 1177atoul(char *s, u_long *ulvalp) 1178{ 1179 u_long ulval; 1180 char *ep; 1181 1182 errno = 0; 1183 ulval = strtoul(s, &ep, 0); 1184 if (s[0] == '\0' || *ep != '\0') 1185 return (-1); 1186 if (errno == ERANGE && ulval == ULONG_MAX) 1187 return (-1); 1188 *ulvalp = ulval; 1189 return (0); 1190} 1191 1192int 1193atospi(char *s, u_int32_t *spivalp) 1194{ 1195 unsigned long ulval; 1196 1197 if (atoul(s, &ulval) == -1) 1198 return (-1); 1199 if (ulval >= SPI_RESERVED_MIN && ulval <= SPI_RESERVED_MAX) { 1200 yyerror("illegal SPI value"); 1201 return (-1); 1202 } 1203 *spivalp = ulval; 1204 return (0); 1205} 1206 1207u_int8_t 1208x2i(unsigned char *s) 1209{ 1210 char ss[3]; 1211 1212 ss[0] = s[0]; 1213 ss[1] = s[1]; 1214 ss[2] = 0; 1215 1216 if (!isxdigit(s[0]) || !isxdigit(s[1])) { 1217 yyerror("keys need to be specified in hex digits"); 1218 return (-1); 1219 } 1220 return ((u_int8_t)strtoul(ss, NULL, 16)); 1221} 1222 1223struct ipsec_key * 1224parsekey(unsigned char *hexkey, size_t len) 1225{ 1226 struct ipsec_key *key; 1227 int i; 1228 1229 key = calloc(1, sizeof(struct ipsec_key)); 1230 if (key == NULL) 1231 err(1, "parsekey: calloc"); 1232 1233 key->len = len / 2; 1234 key->data = calloc(key->len, sizeof(u_int8_t)); 1235 if (key->data == NULL) 1236 err(1, "parsekey: calloc"); 1237 1238 for (i = 0; i < (int)key->len; i++) 1239 key->data[i] = x2i(hexkey + 2 * i); 1240 1241 return (key); 1242} 1243 1244struct ipsec_key * 1245parsekeyfile(char *filename) 1246{ 1247 struct stat sb; 1248 int fd; 1249 unsigned char *hex; 1250 1251 if ((fd = open(filename, O_RDONLY)) < 0) 1252 err(1, "parsekeyfile: open"); 1253 if (fstat(fd, &sb) < 0) 1254 err(1, "parsekeyfile: stat %s", filename); 1255 if ((sb.st_size > KEYSIZE_LIMIT) || (sb.st_size == 0)) 1256 errx(1, "parsekeyfile: key too %s", sb.st_size ? "large" : 1257 "small"); 1258 if ((hex = calloc(sb.st_size, sizeof(unsigned char))) == NULL) 1259 err(1, "parsekeyfile: calloc"); 1260 if (read(fd, hex, sb.st_size) < sb.st_size) 1261 err(1, "parsekeyfile: read"); 1262 close(fd); 1263 return (parsekey(hex, sb.st_size)); 1264} 1265 1266struct ipsec_addr_wrap * 1267host(const char *s) 1268{ 1269 struct ipsec_addr_wrap *ipa = NULL; 1270 int mask, v4mask, cont = 1; 1271 char *p, *q, *ps; 1272 1273 if ((p = strrchr(s, '/')) != NULL) { 1274 errno = 0; 1275 mask = strtol(p + 1, &q, 0); 1276 if (errno == ERANGE || !q || *q || mask > 128 || q == (p + 1)) 1277 errx(1, "host: invalid netmask '%s'", p); 1278 if ((ps = malloc(strlen(s) - strlen(p) + 1)) == NULL) 1279 err(1, "host: calloc"); 1280 strlcpy(ps, s, strlen(s) - strlen(p) + 1); 1281 v4mask = mask; 1282 } else { 1283 if ((ps = strdup(s)) == NULL) 1284 err(1, "host: strdup"); 1285 v4mask = 32; 1286 mask = -1; 1287 } 1288 1289 /* Does interface with this name exist? */ 1290 if (cont && (ipa = host_if(ps, mask)) != NULL) 1291 cont = 0; 1292 1293 /* IPv4 address? */ 1294 if (cont && (ipa = host_v4(s, v4mask)) != NULL) 1295 cont = 0; 1296 1297 /* IPv6 address? */ 1298 if (cont && (ipa = host_v6(ps, mask == -1 ? 128 : mask)) != NULL) 1299 cont = 0; 1300 1301 /* dns lookup */ 1302 if (cont && (ipa = host_dns(s, v4mask, 0)) != NULL) 1303 cont = 0; 1304 free(ps); 1305 1306 if (ipa == NULL || cont == 1) { 1307 fprintf(stderr, "no IP address found for %s\n", s); 1308 return (NULL); 1309 } 1310 return (ipa); 1311} 1312 1313struct ipsec_addr_wrap * 1314host_v6(const char *s, int prefixlen) 1315{ 1316 struct ipsec_addr_wrap *ipa = NULL; 1317 struct addrinfo hints, *res0, *res; 1318 char hbuf[NI_MAXHOST]; 1319 1320 bzero(&hints, sizeof(struct addrinfo)); 1321 hints.ai_family = PF_UNSPEC; 1322 hints.ai_socktype = SOCK_STREAM; 1323 hints.ai_flags = AI_NUMERICHOST; 1324 if (getaddrinfo(s, NULL, &hints, &res0)) 1325 return (NULL); 1326 1327 for (res = res0; res; res = res->ai_next) { 1328 if (res->ai_family != AF_INET6) 1329 continue; 1330 break; /* found one */ 1331 } 1332 ipa = calloc(1, sizeof(struct ipsec_addr_wrap)); 1333 if (ipa == NULL) 1334 err(1, "host_addr: calloc"); 1335 ipa->af = res->ai_family; 1336 memcpy(&ipa->address.v6, 1337 &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr.s6_addr, 1338 sizeof(struct in6_addr)); 1339 if (prefixlen > 128) 1340 prefixlen = 128; 1341 ipa->next = NULL; 1342 ipa->tail = ipa; 1343 1344 set_ipmask(ipa, prefixlen); 1345 if (getnameinfo(res->ai_addr, res->ai_addrlen, 1346 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) { 1347 errx(1, "could not get a numeric hostname"); 1348 } 1349 1350 if (prefixlen != 128) { 1351 ipa->netaddress = 1; 1352 asprintf(&ipa->name, "%s/%d", hbuf, prefixlen); 1353 } else 1354 ipa->name = strdup(hbuf); 1355 if (ipa->name == NULL) 1356 err(1, "host_dns: strdup"); 1357 1358 freeaddrinfo(res0); 1359 1360 return (ipa); 1361} 1362 1363struct ipsec_addr_wrap * 1364host_v4(const char *s, int mask) 1365{ 1366 struct ipsec_addr_wrap *ipa = NULL; 1367 struct in_addr ina; 1368 int bits = 32; 1369 1370 bzero(&ina, sizeof(struct in_addr)); 1371 if (strrchr(s, '/') != NULL) { 1372 if ((bits = inet_net_pton(AF_INET, s, &ina, sizeof(ina))) == -1) 1373 return (NULL); 1374 } else { 1375 if (inet_pton(AF_INET, s, &ina) != 1) 1376 return (NULL); 1377 } 1378 1379 ipa = calloc(1, sizeof(struct ipsec_addr_wrap)); 1380 if (ipa == NULL) 1381 err(1, "host_v4: calloc"); 1382 1383 ipa->address.v4 = ina; 1384 ipa->name = strdup(s); 1385 if (ipa->name == NULL) 1386 err(1, "host_v4: strdup"); 1387 ipa->af = AF_INET; 1388 ipa->next = NULL; 1389 ipa->tail = ipa; 1390 1391 set_ipmask(ipa, bits); 1392 if (bits != (ipa->af == AF_INET ? 32 : 128)) 1393 ipa->netaddress = 1; 1394 1395 return (ipa); 1396} 1397 1398struct ipsec_addr_wrap * 1399host_dns(const char *s, int v4mask, int v6mask) 1400{ 1401 struct ipsec_addr_wrap *ipa = NULL; 1402 struct addrinfo hints, *res0, *res; 1403 int error; 1404 int bits = 32; 1405 1406 bzero(&hints, sizeof(struct addrinfo)); 1407 hints.ai_family = PF_UNSPEC; 1408 hints.ai_socktype = SOCK_STREAM; 1409 error = getaddrinfo(s, NULL, &hints, &res0); 1410 if (error) 1411 return (NULL); 1412 1413 for (res = res0; res; res = res->ai_next) { 1414 if (res->ai_family != AF_INET) 1415 continue; 1416 ipa = calloc(1, sizeof(struct ipsec_addr_wrap)); 1417 if (ipa == NULL) 1418 err(1, "host_dns: calloc"); 1419 memcpy(&ipa->address.v4, 1420 &((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr, 1421 sizeof(struct in_addr)); 1422 ipa->name = strdup(inet_ntoa(ipa->address.v4)); 1423 if (ipa->name == NULL) 1424 err(1, "host_dns: strdup"); 1425 ipa->af = AF_INET; 1426 ipa->next = NULL; 1427 ipa->tail = ipa; 1428 1429 set_ipmask(ipa, bits); 1430 if (bits != (ipa->af == AF_INET ? 32 : 128)) 1431 ipa->netaddress = 1; 1432 break; 1433 } 1434 freeaddrinfo(res0); 1435 1436 return (ipa); 1437} 1438 1439struct ipsec_addr_wrap * 1440host_if(const char *s, int mask) 1441{ 1442 struct ipsec_addr_wrap *ipa = NULL; 1443 1444 if (ifa_exists(s)) 1445 ipa = ifa_lookup(s); 1446 1447 return (ipa); 1448} 1449 1450/* interface lookup routintes */ 1451 1452struct ipsec_addr_wrap *iftab; 1453 1454void 1455ifa_load(void) 1456{ 1457 struct ifaddrs *ifap, *ifa; 1458 struct ipsec_addr_wrap *n = NULL, *h = NULL; 1459 1460 if (getifaddrs(&ifap) < 0) 1461 err(1, "ifa_load: getiffaddrs"); 1462 1463 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 1464 if (!(ifa->ifa_addr->sa_family == AF_INET || 1465 ifa->ifa_addr->sa_family == AF_INET6 || 1466 ifa->ifa_addr->sa_family == AF_LINK)) 1467 continue; 1468 n = calloc(1, sizeof(struct ipsec_addr_wrap)); 1469 if (n == NULL) 1470 err(1, "ifa_load: calloc"); 1471 n->af = ifa->ifa_addr->sa_family; 1472 if ((n->name = strdup(ifa->ifa_name)) == NULL) 1473 err(1, "ifa_load: strdup"); 1474 if (n->af == AF_INET) { 1475 n->af = AF_INET; 1476 memcpy(&n->address.v4, &((struct sockaddr_in *) 1477 ifa->ifa_addr)->sin_addr.s_addr, 1478 sizeof(struct in_addr)); 1479 memcpy(&n->mask.v4, &((struct sockaddr_in *) 1480 ifa->ifa_netmask)->sin_addr.s_addr, 1481 sizeof(struct in_addr)); 1482 } else if (n->af == AF_INET6) { 1483 n->af = AF_INET6; 1484 memcpy(&n->address.v6, &((struct sockaddr_in6 *) 1485 ifa->ifa_addr)->sin6_addr.s6_addr, 1486 sizeof(struct in6_addr)); 1487 memcpy(&n->mask.v6, &((struct sockaddr_in6 *) 1488 ifa->ifa_netmask)->sin6_addr.s6_addr, 1489 sizeof(struct in6_addr)); 1490 } 1491 if ((n->name = strdup(ifa->ifa_name)) == NULL) 1492 err(1, "ifa_load: strdup"); 1493 n->next = NULL; 1494 n->tail = n; 1495 if (h == NULL) 1496 h = n; 1497 else { 1498 h->tail->next = n; 1499 h->tail = n; 1500 } 1501 } 1502 1503 iftab = h; 1504 freeifaddrs(ifap); 1505} 1506 1507int 1508ifa_exists(const char *ifa_name) 1509{ 1510 struct ipsec_addr_wrap *n; 1511 struct ifgroupreq ifgr; 1512 int s; 1513 1514 if (iftab == NULL) 1515 ifa_load(); 1516 1517 /* check wether this is a group */ 1518 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 1519 err(1, "ifa_exists: socket"); 1520 bzero(&ifgr, sizeof(ifgr)); 1521 strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name)); 1522 if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == 0) { 1523 close(s); 1524 return (1); 1525 } 1526 close(s); 1527 1528 for (n = iftab; n; n = n->next) { 1529 if (n->af == AF_LINK && !strncmp(n->name, ifa_name, 1530 IFNAMSIZ)) 1531 return (1); 1532 } 1533 1534 return (0); 1535} 1536 1537struct ipsec_addr_wrap * 1538ifa_grouplookup(const char *ifa_name) 1539{ 1540 struct ifg_req *ifg; 1541 struct ifgroupreq ifgr; 1542 int s; 1543 size_t len; 1544 struct ipsec_addr_wrap *n, *h = NULL, *hn; 1545 1546 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 1547 err(1, "socket"); 1548 bzero(&ifgr, sizeof(ifgr)); 1549 strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name)); 1550 if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) { 1551 close(s); 1552 return (NULL); 1553 } 1554 1555 len = ifgr.ifgr_len; 1556 if ((ifgr.ifgr_groups = calloc(1, len)) == NULL) 1557 err(1, "calloc"); 1558 if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) 1559 err(1, "ioctl"); 1560 1561 for (ifg = ifgr.ifgr_groups; ifg && len >= sizeof(struct ifg_req); 1562 ifg++) { 1563 len -= sizeof(struct ifg_req); 1564 if ((n = ifa_lookup(ifg->ifgrq_member)) == NULL) 1565 continue; 1566 if (h == NULL) 1567 h = n; 1568 else { 1569 for (hn = h; hn->next != NULL; hn = hn->next) 1570 ; /* nothing */ 1571 hn->next = n; 1572 n->tail = hn; 1573 } 1574 } 1575 free(ifgr.ifgr_groups); 1576 close(s); 1577 1578 return (h); 1579} 1580 1581struct ipsec_addr_wrap * 1582ifa_lookup(const char *ifa_name) 1583{ 1584 struct ipsec_addr_wrap *p = NULL, *h = NULL, *n = NULL; 1585 1586 if (iftab == NULL) 1587 ifa_load(); 1588 1589 if ((n = ifa_grouplookup(ifa_name)) != NULL) 1590 return (n); 1591 1592 for (p = iftab; p; p = p->next) { 1593 if (p->af != AF_INET && p->af != AF_INET6) 1594 continue; 1595 if (strncmp(p->name, ifa_name, IFNAMSIZ)) 1596 continue; 1597 n = calloc(1, sizeof(struct ipsec_addr_wrap)); 1598 if (n == NULL) 1599 err(1, "ifa_lookup: calloc"); 1600 memcpy(n, p, sizeof(struct ipsec_addr_wrap)); 1601 if ((n->name = strdup(p->name)) == NULL) 1602 err(1, "ifa_lookup: strdup"); 1603 switch(n->af) { 1604 case AF_INET: 1605 set_ipmask(n, 32); 1606 break; 1607 case AF_INET6: 1608 /* route/show.c and bgpd/util.c give KAME credit */ 1609 if (IN6_IS_ADDR_LINKLOCAL(&n->address.v6) || 1610 IN6_IS_ADDR_MC_LINKLOCAL(&n->address.v6)) { 1611 u_int16_t tmp16; 1612 /* for now we can not handle link local, 1613 * therefore bail for now 1614 */ 1615 free(n); 1616 continue; 1617 1618 memcpy(&tmp16, &n->address.v6.s6_addr[2], 1619 sizeof(tmp16)); 1620 /* use this when we support link-local 1621 * n->??.scopeid = ntohs(tmp16); 1622 */ 1623 n->address.v6.s6_addr[2] = 0; 1624 n->address.v6.s6_addr[3] = 0; 1625 } 1626 set_ipmask(n, 128); 1627 break; 1628 } 1629 1630 n->next = NULL; 1631 n->tail = n; 1632 if (h == NULL) 1633 h = n; 1634 else { 1635 h->tail->next = n; 1636 h->tail = n; 1637 } 1638 } 1639 1640 return (h); 1641} 1642 1643void 1644set_ipmask(struct ipsec_addr_wrap *address, u_int8_t b) 1645{ 1646 struct ipsec_addr *ipa; 1647 int i, j = 0; 1648 1649 ipa = &address->mask; 1650 bzero(ipa, sizeof(struct ipsec_addr)); 1651 1652 while (b >= 32) { 1653 ipa->addr32[j++] = 0xffffffff; 1654 b -= 32; 1655 } 1656 for (i = 31; i > 31 - b; --i) 1657 ipa->addr32[j] |= (1 << i); 1658 if (b) 1659 ipa->addr32[j] = htonl(ipa->addr32[j]); 1660} 1661 1662const struct ipsec_xf * 1663parse_xf(const char *name, const struct ipsec_xf xfs[]) 1664{ 1665 int i; 1666 1667 for (i = 0; xfs[i].name != NULL; i++) { 1668 if (strncmp(name, xfs[i].name, strlen(name))) 1669 continue; 1670 return &xfs[i]; 1671 } 1672 return (NULL); 1673} 1674 1675struct ipsec_life * 1676parse_life(int value) 1677{ 1678 struct ipsec_life *life; 1679 1680 life = calloc(1, sizeof(struct ipsec_life)); 1681 if (life == NULL) 1682 err(1, "calloc"); 1683 1684 life->lifetime = value; 1685 1686 return (life); 1687} 1688 1689struct ipsec_transforms * 1690copytransforms(const struct ipsec_transforms *xfs) 1691{ 1692 struct ipsec_transforms *newxfs; 1693 1694 if (xfs == NULL) 1695 return (NULL); 1696 1697 newxfs = calloc(1, sizeof(struct ipsec_transforms)); 1698 if (newxfs == NULL) 1699 err(1, "copytransforms: calloc"); 1700 1701 memcpy(newxfs, xfs, sizeof(struct ipsec_transforms)); 1702 return (newxfs); 1703} 1704 1705struct ipsec_life * 1706copylife(const struct ipsec_life *life) 1707{ 1708 struct ipsec_life *newlife; 1709 1710 if (life == NULL) 1711 return (NULL); 1712 1713 newlife = calloc(1, sizeof(struct ipsec_life)); 1714 if (newlife == NULL) 1715 err(1, "copylife: calloc"); 1716 1717 memcpy(newlife, life, sizeof(struct ipsec_life)); 1718 return (newlife); 1719} 1720 1721struct ipsec_auth * 1722copyipsecauth(const struct ipsec_auth *auth) 1723{ 1724 struct ipsec_auth *newauth; 1725 1726 if (auth == NULL) 1727 return (NULL); 1728 1729 if ((newauth = calloc(1, sizeof(struct ipsec_auth))) == NULL) 1730 err(1, "calloc"); 1731 if (auth->srcid && 1732 asprintf(&newauth->srcid, "%s", auth->srcid) == -1) 1733 err(1, "asprintf"); 1734 if (auth->dstid && 1735 asprintf(&newauth->dstid, "%s", auth->dstid) == -1) 1736 err(1, "asprintf"); 1737 1738 newauth->idtype = auth->idtype; 1739 newauth->type = auth->type; 1740 1741 return (newauth); 1742} 1743 1744struct ike_auth * 1745copyikeauth(const struct ike_auth *auth) 1746{ 1747 struct ike_auth *newauth; 1748 1749 if (auth == NULL) 1750 return (NULL); 1751 1752 if ((newauth = calloc(1, sizeof(struct ike_auth))) == NULL) 1753 err(1, "calloc"); 1754 if (auth->string && 1755 asprintf(&newauth->string, "%s", auth->string) == -1) 1756 err(1, "asprintf"); 1757 1758 newauth->type = auth->type; 1759 1760 return (newauth); 1761} 1762 1763struct ipsec_key * 1764copykey(struct ipsec_key *key) 1765{ 1766 struct ipsec_key *newkey; 1767 1768 if (key == NULL) 1769 return (NULL); 1770 1771 if ((newkey = calloc(1, sizeof(struct ipsec_key))) == NULL) 1772 err(1, "calloc"); 1773 if ((newkey->data = calloc(key->len, sizeof(u_int8_t))) == NULL) 1774 err(1, "calloc"); 1775 memcpy(newkey->data, key->data, key->len); 1776 newkey->len = key->len; 1777 1778 return (newkey); 1779} 1780 1781struct ipsec_addr_wrap * 1782copyhost(const struct ipsec_addr_wrap *src) 1783{ 1784 struct ipsec_addr_wrap *dst; 1785 1786 if (src == NULL) 1787 return (NULL); 1788 1789 dst = calloc(1, sizeof(struct ipsec_addr_wrap)); 1790 if (dst == NULL) 1791 err(1, "copyhost: calloc"); 1792 1793 memcpy(dst, src, sizeof(struct ipsec_addr_wrap)); 1794 1795 if ((dst->name = strdup(src->name)) == NULL) 1796 err(1, "copyhost: strdup"); 1797 1798 return dst; 1799} 1800 1801struct ipsec_rule * 1802copyrule(struct ipsec_rule *rule) 1803{ 1804 struct ipsec_rule *r; 1805 1806 if ((r = calloc(1, sizeof(struct ipsec_rule))) == NULL) 1807 err(1, "calloc"); 1808 1809 r->src = copyhost(rule->src); 1810 r->dst = copyhost(rule->dst); 1811 r->local = copyhost(rule->local); 1812 r->peer = copyhost(rule->peer); 1813 r->auth = copyipsecauth(rule->auth); 1814 r->ikeauth = copyikeauth(rule->ikeauth); 1815 r->xfs = copytransforms(rule->xfs); 1816 r->mmxfs = copytransforms(rule->mmxfs); 1817 r->qmxfs = copytransforms(rule->qmxfs); 1818 r->mmlife = copylife(rule->mmlife); 1819 r->qmlife = copylife(rule->qmlife); 1820 r->authkey = copykey(rule->authkey); 1821 r->enckey = copykey(rule->enckey); 1822 1823 r->type = rule->type; 1824 r->satype = rule->satype; 1825 r->proto = rule->proto; 1826 r->tmode = rule->tmode; 1827 r->direction = rule->direction; 1828 r->flowtype = rule->flowtype; 1829 r->sport = rule->sport; 1830 r->dport = rule->dport; 1831 r->ikemode = rule->ikemode; 1832 r->spi = rule->spi; 1833 r->nr = rule->nr; 1834 1835 return (r); 1836} 1837 1838int 1839validate_sa(u_int32_t spi, u_int8_t satype, struct ipsec_transforms *xfs, 1840 struct ipsec_key *authkey, struct ipsec_key *enckey, u_int8_t tmode) 1841{ 1842 /* Sanity checks */ 1843 if (spi == 0) { 1844 yyerror("no SPI specified"); 1845 return (0); 1846 } 1847 if (satype == IPSEC_AH) { 1848 if (!xfs) { 1849 yyerror("no transforms specified"); 1850 return (0); 1851 } 1852 if (!xfs->authxf) 1853 xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256]; 1854 if (xfs->encxf) { 1855 yyerror("ah does not provide encryption"); 1856 return (0); 1857 } 1858 if (xfs->compxf) { 1859 yyerror("ah does not provide compression"); 1860 return (0); 1861 } 1862 } 1863 if (satype == IPSEC_ESP) { 1864 if (!xfs) { 1865 yyerror("no transforms specified"); 1866 return (0); 1867 } 1868 if (xfs->compxf) { 1869 yyerror("esp does not provide compression"); 1870 return (0); 1871 } 1872 if (!xfs->authxf) 1873 xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256]; 1874 if (!xfs->encxf) 1875 xfs->encxf = &encxfs[ENCXF_AESCTR]; 1876 } 1877 if (satype == IPSEC_IPCOMP) { 1878 if (!xfs) { 1879 yyerror("no transform specified"); 1880 return (0); 1881 } 1882 if (xfs->authxf || xfs->encxf) { 1883 yyerror("no encryption or authentication with ipcomp"); 1884 return (0); 1885 } 1886 if (!xfs->compxf) 1887 xfs->compxf = &compxfs[COMPXF_DEFLATE]; 1888 } 1889 if (satype == IPSEC_IPIP) { 1890 if (!xfs) { 1891 yyerror("no transform specified"); 1892 return (0); 1893 } 1894 if (xfs->authxf || xfs->encxf || xfs->compxf) { 1895 yyerror("no encryption, authentication or compression" 1896 " with ipip"); 1897 return (0); 1898 } 1899 } 1900 if (satype == IPSEC_TCPMD5 && authkey == NULL && tmode != 1901 IPSEC_TRANSPORT) { 1902 yyerror("authentication key needed for tcpmd5"); 1903 return (0); 1904 } 1905 if (xfs && xfs->authxf) { 1906 if (!authkey) { 1907 yyerror("no authentication key specified"); 1908 return (0); 1909 } 1910 if (authkey->len != xfs->authxf->keymin) { 1911 yyerror("wrong authentication key length, needs to be " 1912 "%d bits", xfs->authxf->keymin * 8); 1913 return (0); 1914 } 1915 } 1916 if (xfs && xfs->encxf) { 1917 if (!enckey && xfs->encxf != &encxfs[ENCXF_NULL]) { 1918 yyerror("no encryption key specified"); 1919 return (0); 1920 } 1921 if (enckey) { 1922 if (enckey->len < xfs->encxf->keymin) { 1923 yyerror("encryption key too short (%d bits), " 1924 "minimum %d bits", enckey->len * 8, 1925 xfs->encxf->keymin * 8); 1926 return (0); 1927 } 1928 if (xfs->encxf->keymax < enckey->len) { 1929 yyerror("encryption key too long (%d bits), " 1930 "maximum %d bits", enckey->len * 8, 1931 xfs->encxf->keymax * 8); 1932 return (0); 1933 } 1934 } 1935 } 1936 1937 return 1; 1938} 1939 1940int 1941add_sagroup(struct ipsec_rule *r) 1942{ 1943 struct ipsec_rule *rp, *last, *group; 1944 int found = 0; 1945 1946 TAILQ_FOREACH(rp, &ipsec->group_queue, group_entry) { 1947 if (strcmp(rp->dst->name, r->dst->name) == 0) { 1948 found = 1; 1949 break; 1950 } 1951 } 1952 if (found) { 1953 last = TAILQ_LAST(&rp->dst_group_queue, dst_group_queue); 1954 TAILQ_INSERT_TAIL(&rp->dst_group_queue, r, dst_group_entry); 1955 1956 group = create_sagroup(last->dst, last->satype, last->spi, 1957 r->dst, r->satype, r->spi); 1958 if (group == NULL) 1959 return (1); 1960 group->nr = ipsec->rule_nr++; 1961 if (ipsecctl_add_rule(ipsec, group)) 1962 return (1); 1963 } else { 1964 TAILQ_INSERT_TAIL(&ipsec->group_queue, r, group_entry); 1965 TAILQ_INIT(&r->dst_group_queue); 1966 TAILQ_INSERT_TAIL(&r->dst_group_queue, r, dst_group_entry); 1967 } 1968 1969 return (0); 1970} 1971 1972struct ipsec_rule * 1973create_sa(u_int8_t satype, u_int8_t tmode, struct ipsec_hosts *hosts, 1974 u_int32_t spi, struct ipsec_transforms *xfs, struct ipsec_key *authkey, 1975 struct ipsec_key *enckey) 1976{ 1977 struct ipsec_rule *r; 1978 1979 if (validate_sa(spi, satype, xfs, authkey, enckey, tmode) == 0) 1980 return (NULL); 1981 1982 r = calloc(1, sizeof(struct ipsec_rule)); 1983 if (r == NULL) 1984 err(1, "create_sa: calloc"); 1985 1986 r->type |= RULE_SA; 1987 r->satype = satype; 1988 r->tmode = tmode; 1989 r->src = hosts->src; 1990 r->dst = hosts->dst; 1991 r->spi = spi; 1992 r->xfs = xfs; 1993 r->authkey = authkey; 1994 r->enckey = enckey; 1995 1996 return r; 1997} 1998 1999struct ipsec_rule * 2000reverse_sa(struct ipsec_rule *rule, u_int32_t spi, struct ipsec_key *authkey, 2001 struct ipsec_key *enckey) 2002{ 2003 struct ipsec_rule *reverse; 2004 2005 if (validate_sa(spi, rule->satype, rule->xfs, authkey, enckey, 2006 rule->tmode) == 0) 2007 return (NULL); 2008 2009 reverse = calloc(1, sizeof(struct ipsec_rule)); 2010 if (reverse == NULL) 2011 err(1, "reverse_sa: calloc"); 2012 2013 reverse->type |= RULE_SA; 2014 reverse->satype = rule->satype; 2015 reverse->tmode = rule->tmode; 2016 reverse->src = copyhost(rule->dst); 2017 reverse->dst = copyhost(rule->src); 2018 reverse->spi = spi; 2019 reverse->xfs = copytransforms(rule->xfs); 2020 reverse->authkey = authkey; 2021 reverse->enckey = enckey; 2022 2023 return (reverse); 2024} 2025 2026struct ipsec_rule * 2027create_sagroup(struct ipsec_addr_wrap *dst, u_int8_t proto, u_int32_t spi, 2028 struct ipsec_addr_wrap *dst2, u_int8_t proto2, u_int32_t spi2) 2029{ 2030 struct ipsec_rule *r; 2031 2032 r = calloc(1, sizeof(struct ipsec_rule)); 2033 if (r == NULL) 2034 err(1, "create_sagroup: calloc"); 2035 2036 r->type |= RULE_GROUP; 2037 2038 r->dst = copyhost(dst); 2039 r->dst2 = copyhost(dst2); 2040 r->proto = proto; 2041 r->proto2 = proto2; 2042 r->spi = spi; 2043 r->spi2 = spi2; 2044 r->satype = proto; 2045 2046 return (r); 2047} 2048 2049struct ipsec_rule * 2050create_flow(u_int8_t dir, u_int8_t proto, struct ipsec_hosts *hosts, 2051 struct ipsec_hosts *peers, 2052 u_int8_t satype, char *srcid, char *dstid, u_int8_t type) 2053{ 2054 struct ipsec_rule *r; 2055 2056 r = calloc(1, sizeof(struct ipsec_rule)); 2057 if (r == NULL) 2058 err(1, "create_flow: calloc"); 2059 2060 r->type |= RULE_FLOW; 2061 2062 if (dir == IPSEC_INOUT) 2063 r->direction = IPSEC_OUT; 2064 else 2065 r->direction = dir; 2066 2067 r->satype = satype; 2068 r->proto = proto; 2069 r->src = hosts->src; 2070 r->sport = hosts->sport; 2071 r->dst = hosts->dst; 2072 r->dport = hosts->dport; 2073 if ((hosts->sport != 0 || hosts->dport != 0) && 2074 (proto != IPPROTO_TCP && proto != IPPROTO_UDP)) { 2075 yyerror("no protocol supplied with source/destination ports"); 2076 goto errout; 2077 } 2078 2079 if (type == TYPE_DENY || type == TYPE_BYPASS) { 2080 r->flowtype = type; 2081 return (r); 2082 } 2083 2084 r->flowtype = type; 2085 r->local = peers->src; 2086 if (peers->dst == NULL) { 2087 /* Set peer to remote host. Must be a host address. */ 2088 if (r->direction == IPSEC_IN) { 2089 if (r->src->netaddress) { 2090 yyerror("no peer specified"); 2091 goto errout; 2092 } 2093 r->peer = copyhost(r->src); 2094 } else { 2095 if (r->dst->netaddress) { 2096 yyerror("no peer specified"); 2097 goto errout; 2098 } 2099 r->peer = copyhost(r->dst); 2100 } 2101 } else 2102 r->peer = peers->dst; 2103 2104 r->auth = calloc(1, sizeof(struct ipsec_auth)); 2105 if (r->auth == NULL) 2106 err(1, "create_flow: calloc"); 2107 r->auth->srcid = srcid; 2108 r->auth->dstid = dstid; 2109 r->auth->idtype = ID_FQDN; /* XXX For now only FQDN. */ 2110 2111 return r; 2112 2113errout: 2114 free(r); 2115 if (srcid) 2116 free(srcid); 2117 if (dstid) 2118 free(dstid); 2119 free(hosts->src); 2120 free(hosts->dst); 2121 2122 return NULL; 2123} 2124 2125int 2126expand_rule(struct ipsec_rule *rule, u_int8_t direction, u_int32_t spi, 2127 struct ipsec_key *authkey, struct ipsec_key *enckey, int group) 2128{ 2129 struct ipsec_rule *r, *revr; 2130 struct ipsec_addr_wrap *src, *dst; 2131 int added = 0; 2132 2133 for (src = rule->src; src; src = src->next) { 2134 for (dst = rule->dst; dst; dst = dst->next) { 2135 if (src->af != dst->af) 2136 continue; 2137 r = copyrule(rule); 2138 2139 r->src = copyhost(src); 2140 r->dst = copyhost(dst); 2141 2142 r->nr = ipsec->rule_nr++; 2143 if (ipsecctl_add_rule(ipsec, r)) 2144 return (1); 2145 if (group && add_sagroup(r)) 2146 return (1); 2147 2148 if (direction == IPSEC_INOUT) { 2149 /* Create and add reverse flow rule. */ 2150 revr = reverse_rule(r); 2151 if (revr == NULL) 2152 return (1); 2153 2154 revr->nr = ipsec->rule_nr++; 2155 if (ipsecctl_add_rule(ipsec, revr)) 2156 return (1); 2157 if (group && add_sagroup(revr)) 2158 return (1); 2159 } else if (spi != 0 || authkey || enckey) { 2160 /* Create and add reverse sa rule. */ 2161 revr = reverse_sa(r, spi, authkey, enckey); 2162 if (revr == NULL) 2163 return (1); 2164 2165 revr->nr = ipsec->rule_nr++; 2166 if (ipsecctl_add_rule(ipsec, revr)) 2167 return (1); 2168 if (group && add_sagroup(revr)) 2169 return (1); 2170 } 2171 added++; 2172 } 2173 } 2174 if (!added) 2175 yyerror("rule expands to no valid combination"); 2176 ipsecctl_free_rule(rule); 2177 return (0); 2178} 2179 2180struct ipsec_rule * 2181reverse_rule(struct ipsec_rule *rule) 2182{ 2183 struct ipsec_rule *reverse; 2184 2185 reverse = calloc(1, sizeof(struct ipsec_rule)); 2186 if (reverse == NULL) 2187 err(1, "reverse_rule: calloc"); 2188 2189 reverse->type |= RULE_FLOW; 2190 2191 /* Reverse direction */ 2192 if (rule->direction == (u_int8_t)IPSEC_OUT) 2193 reverse->direction = (u_int8_t)IPSEC_IN; 2194 else 2195 reverse->direction = (u_int8_t)IPSEC_OUT; 2196 2197 reverse->flowtype = rule->flowtype; 2198 reverse->src = copyhost(rule->dst); 2199 reverse->dst = copyhost(rule->src); 2200 reverse->sport = rule->dport; 2201 reverse->dport = rule->sport; 2202 if (rule->local) 2203 reverse->local = copyhost(rule->local); 2204 if (rule->peer) 2205 reverse->peer = copyhost(rule->peer); 2206 reverse->satype = rule->satype; 2207 reverse->proto = rule->proto; 2208 2209 if (rule->auth) { 2210 reverse->auth = calloc(1, sizeof(struct ipsec_auth)); 2211 if (reverse->auth == NULL) 2212 err(1, "reverse_rule: calloc"); 2213 if (rule->auth->dstid && (reverse->auth->dstid = 2214 strdup(rule->auth->dstid)) == NULL) 2215 err(1, "reverse_rule: strdup"); 2216 if (rule->auth->srcid && (reverse->auth->srcid = 2217 strdup(rule->auth->srcid)) == NULL) 2218 err(1, "reverse_rule: strdup"); 2219 reverse->auth->idtype = rule->auth->idtype; 2220 reverse->auth->type = rule->auth->type; 2221 } 2222 2223 return reverse; 2224} 2225 2226struct ipsec_rule * 2227create_ike(u_int8_t proto, struct ipsec_hosts *hosts, struct ipsec_hosts *peers, 2228 struct ike_mode *mainmode, struct ike_mode *quickmode, 2229 u_int8_t satype, u_int8_t tmode, u_int8_t mode, char *srcid, char *dstid, 2230 struct ike_auth *authtype) 2231{ 2232 struct ipsec_rule *r; 2233 2234 r = calloc(1, sizeof(struct ipsec_rule)); 2235 if (r == NULL) 2236 err(1, "create_ike: calloc"); 2237 2238 r->type = RULE_IKE; 2239 2240 r->proto = proto; 2241 r->src = hosts->src; 2242 r->sport = hosts->sport; 2243 r->dst = hosts->dst; 2244 r->dport = hosts->dport; 2245 if ((hosts->sport != 0 || hosts->dport != 0) && 2246 (proto != IPPROTO_TCP && proto != IPPROTO_UDP)) { 2247 yyerror("no protocol supplied with source/destination ports"); 2248 free(r); 2249 free(hosts->src); 2250 free(hosts->dst); 2251 if (mainmode) { 2252 free(mainmode->xfs); 2253 free(mainmode->life); 2254 } 2255 if (quickmode) { 2256 free(quickmode->xfs); 2257 free(quickmode->life); 2258 } 2259 if (srcid) 2260 free(srcid); 2261 if (dstid) 2262 free(dstid); 2263 return NULL; 2264 } 2265 2266 if (peers->dst == NULL) { 2267 /* Set peer to remote host. Must be a host address. */ 2268 if (r->direction == IPSEC_IN) { 2269 if (r->src->netaddress) 2270 r->peer = NULL; 2271 else 2272 r->peer = copyhost(r->src); 2273 } else { 2274 if (r->dst->netaddress) 2275 r->peer = NULL; 2276 else 2277 r->peer = copyhost(r->dst); 2278 } 2279 } else 2280 r->peer = peers->dst; 2281 2282 if (peers->src) 2283 r->local = peers->src; 2284 2285 r->satype = satype; 2286 r->tmode = tmode; 2287 r->ikemode = mode; 2288 if (mainmode) { 2289 r->mmxfs = mainmode->xfs; 2290 r->mmlife = mainmode->life; 2291 } 2292 if (quickmode) { 2293 r->qmxfs = quickmode->xfs; 2294 r->qmlife = quickmode->life; 2295 } 2296 r->auth = calloc(1, sizeof(struct ipsec_auth)); 2297 if (r->auth == NULL) 2298 err(1, "create_ike: calloc"); 2299 r->auth->srcid = srcid; 2300 r->auth->dstid = dstid; 2301 r->auth->idtype = ID_FQDN; /* XXX For now only FQDN. */ 2302 r->ikeauth = calloc(1, sizeof(struct ike_auth)); 2303 if (r->ikeauth == NULL) 2304 err(1, "create_ike: calloc"); 2305 r->ikeauth->type = authtype->type; 2306 r->ikeauth->string = authtype->string; 2307 2308 return (r); 2309} 2310