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