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