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