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