parse.y revision 1.81
1/* $OpenBSD: parse.y,v 1.81 2006/05/31 09:03:43 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 $$ = ipa; 476 } 477 | '{' host_list '}' { $$ = $2; } 478 ; 479 480ids : /* empty */ { 481 $$.srcid = NULL; 482 $$.dstid = NULL; 483 } 484 | SRCID id DSTID id { 485 $$.srcid = $2; 486 $$.dstid = $4; 487 } 488 | SRCID id { 489 $$.srcid = $2; 490 $$.dstid = NULL; 491 } 492 | DSTID id { 493 $$.srcid = NULL; 494 $$.dstid = $2; 495 } 496 ; 497 498type : /* empty */ { 499 $$ = TYPE_REQUIRE; 500 } 501 | TYPE USE { 502 $$ = TYPE_USE; 503 } 504 | TYPE ACQUIRE { 505 $$ = TYPE_ACQUIRE; 506 } 507 | TYPE REQUIRE { 508 $$ = TYPE_REQUIRE; 509 } 510 | TYPE DENY { 511 $$ = TYPE_DENY; 512 } 513 | TYPE BYPASS { 514 $$ = TYPE_BYPASS; 515 } 516 | TYPE DONTACQ { 517 $$ = TYPE_DONTACQ; 518 } 519 ; 520 521id : STRING { $$ = $1; } 522 ; 523 524spispec : SPI STRING { 525 u_int32_t spi; 526 char *p = strchr($2, ':'); 527 528 if (p != NULL) { 529 *p++ = 0; 530 531 if (atospi(p, &spi) == -1) { 532 yyerror("%s is not a valid spi", p); 533 free($2); 534 YYERROR; 535 } 536 $$.spiin = spi; 537 } 538 if (atospi($2, &spi) == -1) { 539 yyerror("%s is not a valid spi", $2); 540 free($2); 541 YYERROR; 542 } 543 $$.spiout = spi; 544 545 546 free($2); 547 } 548 ; 549 550transforms : { 551 if ((ipsec_transforms = calloc(1, 552 sizeof(struct ipsec_transforms))) == NULL) 553 err(1, "transforms: calloc"); 554 } 555 transforms_l 556 { $$ = ipsec_transforms; } 557 | /* empty */ { 558 if (($$ = calloc(1, 559 sizeof(struct ipsec_transforms))) == NULL) 560 err(1, "transforms: calloc"); 561 } 562 ; 563 564transforms_l : transforms_l transform 565 | transform 566 ; 567 568transform : AUTHXF STRING { 569 if (ipsec_transforms->authxf) 570 yyerror("auth already set"); 571 else { 572 ipsec_transforms->authxf = parse_xf($2, 573 authxfs); 574 if (!ipsec_transforms->authxf) 575 yyerror("%s not a valid transform", $2); 576 } 577 } 578 | ENCXF STRING { 579 if (ipsec_transforms->encxf) 580 yyerror("enc already set"); 581 else { 582 ipsec_transforms->encxf = parse_xf($2, encxfs); 583 if (!ipsec_transforms->encxf) 584 yyerror("%s not a valid transform", $2); 585 } 586 } 587 | COMPXF STRING { 588 if (ipsec_transforms->compxf) 589 yyerror("comp already set"); 590 else { 591 ipsec_transforms->compxf = parse_xf($2, 592 compxfs); 593 if (!ipsec_transforms->compxf) 594 yyerror("%s not a valid transform", $2); 595 } 596 } 597 | GROUP STRING { 598 if (ipsec_transforms->groupxf) 599 yyerror("group already set"); 600 else { 601 ipsec_transforms->groupxf = parse_xf($2, 602 groupxfs); 603 if (!ipsec_transforms->groupxf) 604 yyerror("%s not a valid transform", $2); 605 } 606 } 607 ; 608 609mmxfs : /* empty */ { 610 struct ipsec_transforms *xfs; 611 612 /* We create just an empty transform */ 613 if ((xfs = calloc(1, sizeof(struct ipsec_transforms))) 614 == NULL) 615 err(1, "mmxfs: calloc"); 616 $$ = xfs; 617 } 618 | MAIN transforms { $$ = $2; } 619 ; 620 621qmxfs : /* empty */ { 622 struct ipsec_transforms *xfs; 623 624 /* We create just an empty transform */ 625 if ((xfs = calloc(1, sizeof(struct ipsec_transforms))) 626 == NULL) 627 err(1, "qmxfs: calloc"); 628 $$ = xfs; 629 } 630 | QUICK transforms { $$ = $2; } 631 ; 632 633authkeyspec : /* empty */ { 634 $$.keyout = NULL; 635 $$.keyin = NULL; 636 } 637 | AUTHKEY keyspec { 638 $$.keyout = $2.keyout; 639 $$.keyin = $2.keyin; 640 } 641 ; 642 643enckeyspec : /* empty */ { 644 $$.keyout = NULL; 645 $$.keyin = NULL; 646 } 647 | ENCKEY keyspec { 648 $$.keyout = $2.keyout; 649 $$.keyin = $2.keyin; 650 } 651 ; 652 653keyspec : STRING { 654 unsigned char *hex; 655 unsigned char *p = strchr($1, ':'); 656 657 if (p != NULL ) { 658 *p++ = 0; 659 660 if (!strncmp(p, "0x", 2)) 661 p += 2; 662 $$.keyin = parsekey(p, strlen(p)); 663 } 664 665 hex = $1; 666 if (!strncmp(hex, "0x", 2)) 667 hex += 2; 668 $$.keyout = parsekey(hex, strlen(hex)); 669 670 free($1); 671 } 672 | FILENAME STRING { 673 unsigned char *p = strchr($2, ':'); 674 675 if (p != NULL) { 676 *p++ = 0; 677 $$.keyin = parsekeyfile(p); 678 } 679 $$.keyout = parsekeyfile($2); 680 free($2); 681 } 682 ; 683 684ikemode : /* empty */ { $$ = IKE_ACTIVE; } 685 | PASSIVE { $$ = IKE_PASSIVE; } 686 | DYNAMIC { $$ = IKE_DYNAMIC; } 687 | ACTIVE { $$ = IKE_ACTIVE; } 688 ; 689 690ikeauth : /* empty */ { 691 $$.type = IKE_AUTH_RSA; 692 $$.string = NULL; 693 } 694 | RSA { 695 $$.type = IKE_AUTH_RSA; 696 $$.string = NULL; 697 } 698 | PSK STRING { 699 $$.type = IKE_AUTH_PSK; 700 if (($$.string = strdup($2)) == NULL) 701 err(1, "ikeauth: strdup"); 702 } 703 ; 704 705string : string STRING 706 { 707 if (asprintf(&$$, "%s %s", $1, $2) == -1) 708 err(1, "string: asprintf"); 709 free($1); 710 free($2); 711 } 712 | STRING 713 ; 714 715varset : STRING '=' string 716 { 717 if (ipsec->opts & IPSECCTL_OPT_VERBOSE) 718 printf("%s = \"%s\"\n", $1, $3); 719 if (symset($1, $3, 0) == -1) 720 err(1, "cannot store variable"); 721 free($1); 722 free($3); 723 } 724 ; 725 726%% 727 728struct keywords { 729 const char *k_name; 730 int k_val; 731}; 732 733int 734yyerror(const char *fmt, ...) 735{ 736 va_list ap; 737 extern const char *infile; 738 739 errors = 1; 740 va_start(ap, fmt); 741 fprintf(stderr, "%s: %d: ", infile, yyval.lineno); 742 vfprintf(stderr, fmt, ap); 743 fprintf(stderr, "\n"); 744 va_end(ap); 745 return (0); 746} 747 748int 749kw_cmp(const void *k, const void *e) 750{ 751 return (strcmp(k, ((const struct keywords *)e)->k_name)); 752} 753 754int 755lookup(char *s) 756{ 757 /* this has to be sorted always */ 758 static const struct keywords keywords[] = { 759 { "acquire", ACQUIRE }, 760 { "active", ACTIVE }, 761 { "ah", AH }, 762 { "any", ANY }, 763 { "auth", AUTHXF }, 764 { "authkey", AUTHKEY }, 765 { "bypass", BYPASS }, 766 { "comp", COMPXF }, 767 { "deny", DENY }, 768 { "dontacq", DONTACQ }, 769 { "dstid", DSTID }, 770 { "dynamic", DYNAMIC }, 771 { "enc", ENCXF }, 772 { "enckey", ENCKEY }, 773 { "esp", ESP }, 774 { "file", FILENAME }, 775 { "flow", FLOW }, 776 { "from", FROM }, 777 { "group", GROUP }, 778 { "ike", IKE }, 779 { "in", IN }, 780 { "ipcomp", IPCOMP }, 781 { "ipip", IPIP }, 782 { "local", LOCAL }, 783 { "main", MAIN }, 784 { "out", OUT }, 785 { "passive", PASSIVE }, 786 { "peer", PEER }, 787 { "proto", PROTO }, 788 { "psk", PSK }, 789 { "quick", QUICK }, 790 { "require", REQUIRE }, 791 { "rsa", RSA }, 792 { "spi", SPI }, 793 { "srcid", SRCID }, 794 { "tcpmd5", TCPMD5 }, 795 { "to", TO }, 796 { "transport", TRANSPORT }, 797 { "tunnel", TUNNEL }, 798 { "type", TYPE }, 799 { "use", USE } 800 }; 801 const struct keywords *p; 802 803 p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]), 804 sizeof(keywords[0]), kw_cmp); 805 806 if (p) { 807 if (debug > 1) 808 fprintf(stderr, "%s: %d\n", s, p->k_val); 809 return (p->k_val); 810 } else { 811 if (debug > 1) 812 fprintf(stderr, "string: %s\n", s); 813 return (STRING); 814 } 815} 816 817#define MAXPUSHBACK 128 818 819char *parsebuf; 820int parseindex; 821char pushback_buffer[MAXPUSHBACK]; 822int pushback_index = 0; 823 824int 825lgetc(FILE *f) 826{ 827 int c, next; 828 829 if (parsebuf) { 830 /* Read character from the parsebuffer instead of input. */ 831 if (parseindex >= 0) { 832 c = parsebuf[parseindex++]; 833 if (c != '\0') 834 return (c); 835 parsebuf = NULL; 836 } else 837 parseindex++; 838 } 839 840 if (pushback_index) 841 return (pushback_buffer[--pushback_index]); 842 843 while ((c = getc(f)) == '\\') { 844 next = getc(f); 845 if (next != '\n') { 846 c = next; 847 break; 848 } 849 yylval.lineno = lineno; 850 lineno++; 851 } 852 if (c == '\t' || c == ' ') { 853 /* Compress blanks to a single space. */ 854 do { 855 c = getc(f); 856 } while (c == '\t' || c == ' '); 857 ungetc(c, f); 858 c = ' '; 859 } 860 861 return (c); 862} 863 864int 865lungetc(int c) 866{ 867 if (c == EOF) 868 return (EOF); 869 if (parsebuf) { 870 parseindex--; 871 if (parseindex >= 0) 872 return (c); 873 } 874 if (pushback_index < MAXPUSHBACK-1) 875 return (pushback_buffer[pushback_index++] = c); 876 else 877 return (EOF); 878} 879 880int 881findeol(void) 882{ 883 int c; 884 885 parsebuf = NULL; 886 pushback_index = 0; 887 888 /* skip to either EOF or the first real EOL */ 889 while (1) { 890 c = lgetc(fin); 891 if (c == '\n') { 892 lineno++; 893 break; 894 } 895 if (c == EOF) 896 break; 897 } 898 return (ERROR); 899} 900 901int 902yylex(void) 903{ 904 char buf[8096]; 905 char *p, *val; 906 int endc, c; 907 int token; 908 909top: 910 p = buf; 911 while ((c = lgetc(fin)) == ' ') 912 ; /* nothing */ 913 914 yylval.lineno = lineno; 915 if (c == '#') 916 while ((c = lgetc(fin)) != '\n' && c != EOF) 917 ; /* nothing */ 918 if (c == '$' && parsebuf == NULL) { 919 while (1) { 920 if ((c = lgetc(fin)) == EOF) 921 return (0); 922 923 if (p + 1 >= buf + sizeof(buf) - 1) { 924 yyerror("string too long"); 925 return (findeol()); 926 } 927 if (isalnum(c) || c == '_') { 928 *p++ = (char)c; 929 continue; 930 } 931 *p = '\0'; 932 lungetc(c); 933 break; 934 } 935 val = symget(buf); 936 if (val == NULL) { 937 yyerror("macro \"%s\" not defined", buf); 938 return (findeol()); 939 } 940 parsebuf = val; 941 parseindex = 0; 942 goto top; 943 } 944 945 switch (c) { 946 case '\'': 947 case '"': 948 endc = c; 949 while (1) { 950 if ((c = lgetc(fin)) == EOF) 951 return (0); 952 if (c == endc) { 953 *p = '\0'; 954 break; 955 } 956 if (c == '\n') { 957 lineno++; 958 continue; 959 } 960 if (p + 1 >= buf + sizeof(buf) - 1) { 961 yyerror("string too long"); 962 return (findeol()); 963 } 964 *p++ = (char)c; 965 } 966 yylval.v.string = strdup(buf); 967 if (yylval.v.string == NULL) 968 err(1, "yylex: strdup"); 969 return (STRING); 970 } 971 972#define allowed_in_string(x) \ 973 (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \ 974 x != '{' && x != '}' && x != '<' && x != '>' && \ 975 x != '!' && x != '=' && x != '/' && x != '#' && \ 976 x != ',')) 977 978 if (isalnum(c) || c == ':' || c == '_' || c == '*') { 979 do { 980 *p++ = c; 981 if ((unsigned)(p-buf) >= sizeof(buf)) { 982 yyerror("string too long"); 983 return (findeol()); 984 } 985 } while ((c = lgetc(fin)) != EOF && (allowed_in_string(c))); 986 lungetc(c); 987 *p = '\0'; 988 if ((token = lookup(buf)) == STRING) 989 if ((yylval.v.string = strdup(buf)) == NULL) 990 err(1, "yylex: strdup"); 991 return (token); 992 } 993 if (c == '\n') { 994 yylval.lineno = lineno; 995 lineno++; 996 } 997 if (c == EOF) 998 return (0); 999 return (c); 1000} 1001 1002int 1003parse_rules(FILE *input, struct ipsecctl *ipsecx) 1004{ 1005 struct sym *sym; 1006 1007 ipsec = ipsecx; 1008 fin = input; 1009 lineno = 1; 1010 errors = 0; 1011 1012 yyparse(); 1013 1014 /* Free macros and check which have not been used. */ 1015 while ((sym = TAILQ_FIRST(&symhead))) { 1016 if ((ipsec->opts & IPSECCTL_OPT_VERBOSE2) && !sym->used) 1017 fprintf(stderr, "warning: macro '%s' not " 1018 "used\n", sym->nam); 1019 TAILQ_REMOVE(&symhead, sym, entries); 1020 free(sym->nam); 1021 free(sym->val); 1022 free(sym); 1023 } 1024 1025 return (errors ? -1 : 0); 1026} 1027 1028int 1029symset(const char *nam, const char *val, int persist) 1030{ 1031 struct sym *sym; 1032 1033 for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam); 1034 sym = TAILQ_NEXT(sym, entries)) 1035 ; /* nothing */ 1036 1037 if (sym != NULL) { 1038 if (sym->persist == 1) 1039 return (0); 1040 else { 1041 TAILQ_REMOVE(&symhead, sym, entries); 1042 free(sym->nam); 1043 free(sym->val); 1044 free(sym); 1045 } 1046 } 1047 if ((sym = calloc(1, sizeof(*sym))) == NULL) 1048 return (-1); 1049 1050 sym->nam = strdup(nam); 1051 if (sym->nam == NULL) { 1052 free(sym); 1053 return (-1); 1054 } 1055 sym->val = strdup(val); 1056 if (sym->val == NULL) { 1057 free(sym->nam); 1058 free(sym); 1059 return (-1); 1060 } 1061 sym->used = 0; 1062 sym->persist = persist; 1063 TAILQ_INSERT_TAIL(&symhead, sym, entries); 1064 return (0); 1065} 1066 1067int 1068cmdline_symset(char *s) 1069{ 1070 char *sym, *val; 1071 int ret; 1072 size_t len; 1073 1074 if ((val = strrchr(s, '=')) == NULL) 1075 return (-1); 1076 1077 len = strlen(s) - strlen(val) + 1; 1078 if ((sym = malloc(len)) == NULL) 1079 err(1, "cmdline_symset: malloc"); 1080 1081 strlcpy(sym, s, len); 1082 1083 ret = symset(sym, val + 1, 1); 1084 free(sym); 1085 1086 return (ret); 1087} 1088 1089char * 1090symget(const char *nam) 1091{ 1092 struct sym *sym; 1093 1094 TAILQ_FOREACH(sym, &symhead, entries) 1095 if (strcmp(nam, sym->nam) == 0) { 1096 sym->used = 1; 1097 return (sym->val); 1098 } 1099 return (NULL); 1100} 1101 1102int 1103atoul(char *s, u_long *ulvalp) 1104{ 1105 u_long ulval; 1106 char *ep; 1107 1108 errno = 0; 1109 ulval = strtoul(s, &ep, 0); 1110 if (s[0] == '\0' || *ep != '\0') 1111 return (-1); 1112 if (errno == ERANGE && ulval == ULONG_MAX) 1113 return (-1); 1114 *ulvalp = ulval; 1115 return (0); 1116} 1117 1118int 1119atospi(char *s, u_int32_t *spivalp) 1120{ 1121 unsigned long ulval; 1122 1123 if (atoul(s, &ulval) == -1) 1124 return (-1); 1125 if (ulval >= SPI_RESERVED_MIN && ulval <= SPI_RESERVED_MAX) { 1126 yyerror("illegal SPI value"); 1127 return (-1); 1128 } 1129 *spivalp = ulval; 1130 return (0); 1131} 1132 1133u_int8_t 1134x2i(unsigned char *s) 1135{ 1136 char ss[3]; 1137 1138 ss[0] = s[0]; 1139 ss[1] = s[1]; 1140 ss[2] = 0; 1141 1142 if (!isxdigit(s[0]) || !isxdigit(s[1])) { 1143 yyerror("keys need to be specified in hex digits"); 1144 return (-1); 1145 } 1146 return ((u_int8_t)strtoul(ss, NULL, 16)); 1147} 1148 1149struct ipsec_key * 1150parsekey(unsigned char *hexkey, size_t len) 1151{ 1152 struct ipsec_key *key; 1153 int i; 1154 1155 key = calloc(1, sizeof(struct ipsec_key)); 1156 if (key == NULL) 1157 err(1, "parsekey: calloc"); 1158 1159 key->len = len / 2; 1160 key->data = calloc(key->len, sizeof(u_int8_t)); 1161 if (key->data == NULL) 1162 err(1, "parsekey: calloc"); 1163 1164 for (i = 0; i < (int)key->len; i++) 1165 key->data[i] = x2i(hexkey + 2 * i); 1166 1167 return (key); 1168} 1169 1170struct ipsec_key * 1171parsekeyfile(char *filename) 1172{ 1173 struct stat sb; 1174 int fd; 1175 unsigned char *hex; 1176 1177 if ((fd = open(filename, O_RDONLY)) < 0) 1178 err(1, "parsekeyfile: open"); 1179 if (fstat(fd, &sb) < 0) 1180 err(1, "parsekeyfile: stat %s", filename); 1181 if ((sb.st_size > KEYSIZE_LIMIT) || (sb.st_size == 0)) 1182 errx(1, "parsekeyfile: key too %s", sb.st_size ? "large" : 1183 "small"); 1184 if ((hex = calloc(sb.st_size, sizeof(unsigned char))) == NULL) 1185 err(1, "parsekeyfile: calloc"); 1186 if (read(fd, hex, sb.st_size) < sb.st_size) 1187 err(1, "parsekeyfile: read"); 1188 close(fd); 1189 return (parsekey(hex, sb.st_size)); 1190} 1191 1192struct ipsec_addr_wrap * 1193host(const char *s) 1194{ 1195 struct ipsec_addr_wrap *ipa = NULL; 1196 int mask, v4mask, cont = 1; 1197 char *p, *q, *ps; 1198 1199 if ((p = strrchr(s, '/')) != NULL) { 1200 errno = 0; 1201 mask = strtol(p + 1, &q, 0); 1202 if (errno == ERANGE || !q || *q || mask > 128 || q == (p + 1)) 1203 errx(1, "host: invalid netmask '%s'", p); 1204 if ((ps = malloc(strlen(s) - strlen(p) + 1)) == NULL) 1205 err(1, "host: calloc"); 1206 strlcpy(ps, s, strlen(s) - strlen(p) + 1); 1207 v4mask = mask; 1208 } else { 1209 if ((ps = strdup(s)) == NULL) 1210 err(1, "host: strdup"); 1211 v4mask = 32; 1212 mask = -1; 1213 } 1214 1215 /* Does interface with this name exist? */ 1216 if (cont && (ipa = host_if(ps, mask)) != NULL) 1217 cont = 0; 1218 1219 /* IPv4 address? */ 1220 if (cont && (ipa = host_v4(s, v4mask)) != NULL) 1221 cont = 0; 1222 1223 /* IPv6 address? */ 1224 if (cont && (ipa = host_v6(ps, mask == -1 ? 128 : mask)) != NULL) 1225 cont = 0; 1226 1227 /* dns lookup */ 1228 if (cont && (ipa = host_dns(s, v4mask, 0)) != NULL) 1229 cont = 0; 1230 free(ps); 1231 1232 if (ipa == NULL || cont == 1) { 1233 fprintf(stderr, "no IP address found for %s\n", s); 1234 return (NULL); 1235 } 1236 return (ipa); 1237} 1238 1239struct ipsec_addr_wrap * 1240host_v6(const char *s, int prefixlen) 1241{ 1242 struct ipsec_addr_wrap *ipa = NULL; 1243 struct addrinfo hints, *res0, *res; 1244 char hbuf[NI_MAXHOST]; 1245 1246 bzero(&hints, sizeof(struct addrinfo)); 1247 hints.ai_family = PF_UNSPEC; 1248 hints.ai_socktype = SOCK_STREAM; 1249 hints.ai_flags = AI_NUMERICHOST; 1250 if (getaddrinfo(s, NULL, &hints, &res0)) 1251 return (NULL); 1252 1253 for (res = res0; res; res = res->ai_next) { 1254 if (res->ai_family != AF_INET6) 1255 continue; 1256 break; /* found one */ 1257 } 1258 ipa = calloc(1, sizeof(struct ipsec_addr_wrap)); 1259 if (ipa == NULL) 1260 err(1, "host_addr: calloc"); 1261 ipa->af = res->ai_family; 1262 memcpy(&ipa->address.v6, 1263 &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr.s6_addr, 1264 sizeof(struct in6_addr)); 1265 if (prefixlen > 128) 1266 prefixlen = 128; 1267 ipa->next = NULL; 1268 ipa->tail = ipa; 1269 1270 set_ipmask(ipa, prefixlen); 1271 if (getnameinfo(res->ai_addr, res->ai_addrlen, 1272 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) { 1273 errx(1, "could not get a numeric hostname"); 1274 } 1275 1276 if (prefixlen != 128) { 1277 ipa->netaddress = 1; 1278 asprintf(&ipa->name, "%s/%d", hbuf, prefixlen); 1279 } else 1280 ipa->name = strdup(hbuf); 1281 if (ipa->name == NULL) 1282 err(1, "host_dns: strdup"); 1283 1284 freeaddrinfo(res0); 1285 1286 return (ipa); 1287} 1288 1289struct ipsec_addr_wrap * 1290host_v4(const char *s, int mask) 1291{ 1292 struct ipsec_addr_wrap *ipa = NULL; 1293 struct in_addr ina; 1294 int bits = 32; 1295 1296 bzero(&ina, sizeof(struct in_addr)); 1297 if (strrchr(s, '/') != NULL) { 1298 if ((bits = inet_net_pton(AF_INET, s, &ina, sizeof(ina))) == -1) 1299 return (NULL); 1300 } else { 1301 if (inet_pton(AF_INET, s, &ina) != 1) 1302 return (NULL); 1303 } 1304 1305 ipa = calloc(1, sizeof(struct ipsec_addr_wrap)); 1306 if (ipa == NULL) 1307 err(1, "host_v4: calloc"); 1308 1309 ipa->address.v4 = ina; 1310 ipa->name = strdup(s); 1311 if (ipa->name == NULL) 1312 err(1, "host_v4: strdup"); 1313 ipa->af = AF_INET; 1314 ipa->next = NULL; 1315 ipa->tail = ipa; 1316 1317 set_ipmask(ipa, bits); 1318 if (bits != (ipa->af == AF_INET ? 32 : 128)) 1319 ipa->netaddress = 1; 1320 1321 return (ipa); 1322} 1323 1324struct ipsec_addr_wrap * 1325host_dns(const char *s, int v4mask, int v6mask) 1326{ 1327 struct ipsec_addr_wrap *ipa = NULL; 1328 struct addrinfo hints, *res0, *res; 1329 int error; 1330 int bits = 32; 1331 1332 bzero(&hints, sizeof(struct addrinfo)); 1333 hints.ai_family = PF_UNSPEC; 1334 hints.ai_socktype = SOCK_STREAM; 1335 error = getaddrinfo(s, NULL, &hints, &res0); 1336 if (error) 1337 return (NULL); 1338 1339 for (res = res0; res; res = res->ai_next) { 1340 if (res->ai_family != AF_INET) 1341 continue; 1342 ipa = calloc(1, sizeof(struct ipsec_addr_wrap)); 1343 if (ipa == NULL) 1344 err(1, "host_dns: calloc"); 1345 memcpy(&ipa->address.v4, 1346 &((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr, 1347 sizeof(struct in_addr)); 1348 ipa->name = strdup(inet_ntoa(ipa->address.v4)); 1349 if (ipa->name == NULL) 1350 err(1, "host_dns: strdup"); 1351 ipa->af = AF_INET; 1352 ipa->next = NULL; 1353 ipa->tail = ipa; 1354 1355 set_ipmask(ipa, bits); 1356 if (bits != (ipa->af == AF_INET ? 32 : 128)) 1357 ipa->netaddress = 1; 1358 break; 1359 } 1360 freeaddrinfo(res0); 1361 1362 return (ipa); 1363} 1364 1365struct ipsec_addr_wrap * 1366host_if(const char *s, int mask) 1367{ 1368 struct ipsec_addr_wrap *ipa = NULL; 1369 1370 if (ifa_exists(s)) 1371 ipa = ifa_lookup(s); 1372 1373 return (ipa); 1374} 1375 1376/* interface lookup routintes */ 1377 1378struct ipsec_addr_wrap *iftab; 1379 1380void 1381ifa_load(void) 1382{ 1383 struct ifaddrs *ifap, *ifa; 1384 struct ipsec_addr_wrap *n = NULL, *h = NULL; 1385 1386 if (getifaddrs(&ifap) < 0) 1387 err(1, "ifa_load: getiffaddrs"); 1388 1389 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 1390 if (!(ifa->ifa_addr->sa_family == AF_INET || 1391 ifa->ifa_addr->sa_family == AF_INET6 || 1392 ifa->ifa_addr->sa_family == AF_LINK)) 1393 continue; 1394 n = calloc(1, sizeof(struct ipsec_addr_wrap)); 1395 if (n == NULL) 1396 err(1, "ifa_load: calloc"); 1397 n->af = ifa->ifa_addr->sa_family; 1398 if ((n->name = strdup(ifa->ifa_name)) == NULL) 1399 err(1, "ifa_load: strdup"); 1400 if (n->af == AF_INET) { 1401 n->af = AF_INET; 1402 memcpy(&n->address.v4, &((struct sockaddr_in *) 1403 ifa->ifa_addr)->sin_addr.s_addr, 1404 sizeof(struct in_addr)); 1405 memcpy(&n->mask.v4, &((struct sockaddr_in *) 1406 ifa->ifa_netmask)->sin_addr.s_addr, 1407 sizeof(struct in_addr)); 1408 } else if (n->af == AF_INET6) { 1409 n->af = AF_INET6; 1410 memcpy(&n->address.v6, &((struct sockaddr_in6 *) 1411 ifa->ifa_addr)->sin6_addr.s6_addr, 1412 sizeof(struct in6_addr)); 1413 memcpy(&n->mask.v6, &((struct sockaddr_in6 *) 1414 ifa->ifa_netmask)->sin6_addr.s6_addr, 1415 sizeof(struct in6_addr)); 1416 } 1417 if ((n->name = strdup(ifa->ifa_name)) == NULL) 1418 err(1, "ifa_load: strdup"); 1419 n->next = NULL; 1420 n->tail = n; 1421 if (h == NULL) 1422 h = n; 1423 else { 1424 h->tail->next = n; 1425 h->tail = n; 1426 } 1427 } 1428 1429 iftab = h; 1430 freeifaddrs(ifap); 1431} 1432 1433int 1434ifa_exists(const char *ifa_name) 1435{ 1436 struct ipsec_addr_wrap *n; 1437 struct ifgroupreq ifgr; 1438 int s; 1439 1440 if (iftab == NULL) 1441 ifa_load(); 1442 1443 /* check wether this is a group */ 1444 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 1445 err(1, "ifa_exists: socket"); 1446 bzero(&ifgr, sizeof(ifgr)); 1447 strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name)); 1448 if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == 0) { 1449 close(s); 1450 return (1); 1451 } 1452 close(s); 1453 1454 for (n = iftab; n; n = n->next) { 1455 if (n->af == AF_LINK && !strncmp(n->name, ifa_name, 1456 IFNAMSIZ)) 1457 return (1); 1458 } 1459 1460 return (0); 1461} 1462 1463struct ipsec_addr_wrap * 1464ifa_grouplookup(const char *ifa_name) 1465{ 1466 struct ifg_req *ifg; 1467 struct ifgroupreq ifgr; 1468 int s; 1469 size_t len; 1470 struct ipsec_addr_wrap *n, *h = NULL, *hn; 1471 1472 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 1473 err(1, "socket"); 1474 bzero(&ifgr, sizeof(ifgr)); 1475 strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name)); 1476 if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) { 1477 close(s); 1478 return (NULL); 1479 } 1480 1481 len = ifgr.ifgr_len; 1482 if ((ifgr.ifgr_groups = calloc(1, len)) == NULL) 1483 err(1, "calloc"); 1484 if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) 1485 err(1, "ioctl"); 1486 1487 for (ifg = ifgr.ifgr_groups; ifg && len >= sizeof(struct ifg_req); 1488 ifg++) { 1489 len -= sizeof(struct ifg_req); 1490 if ((n = ifa_lookup(ifg->ifgrq_member)) == NULL) 1491 continue; 1492 if (h == NULL) 1493 h = n; 1494 else { 1495 for (hn = h; hn->next != NULL; hn = hn->next) 1496 ; /* nothing */ 1497 hn->next = n; 1498 n->tail = hn; 1499 } 1500 } 1501 free(ifgr.ifgr_groups); 1502 close(s); 1503 1504 return (h); 1505} 1506 1507struct ipsec_addr_wrap * 1508ifa_lookup(const char *ifa_name) 1509{ 1510 struct ipsec_addr_wrap *p = NULL, *h = NULL, *n = NULL; 1511 1512 if (iftab == NULL) 1513 ifa_load(); 1514 1515 if ((n = ifa_grouplookup(ifa_name)) != NULL) 1516 return (n); 1517 1518 for (p = iftab; p; p = p->next) { 1519 if (p->af != AF_INET) 1520 continue; 1521 if (strncmp(p->name, ifa_name, IFNAMSIZ)) 1522 continue; 1523 n = calloc(1, sizeof(struct ipsec_addr_wrap)); 1524 if (n == NULL) 1525 err(1, "ifa_lookup: calloc"); 1526 memcpy(n, p, sizeof(struct ipsec_addr_wrap)); 1527 if ((n->name = strdup(p->name)) == NULL) 1528 err(1, "ifa_lookup: strdup"); 1529 set_ipmask(n, 32); 1530 1531 n->next = NULL; 1532 n->tail = n; 1533 if (h == NULL) 1534 h = n; 1535 else { 1536 h->tail->next = n; 1537 h->tail = n; 1538 } 1539 } 1540 1541 return (h); 1542} 1543 1544void 1545set_ipmask(struct ipsec_addr_wrap *address, u_int8_t b) 1546{ 1547 struct ipsec_addr *ipa; 1548 int i, j = 0; 1549 1550 ipa = &address->mask; 1551 bzero(ipa, sizeof(struct ipsec_addr)); 1552 1553 while (b >= 32) { 1554 ipa->addr32[j++] = 0xffffffff; 1555 b -= 32; 1556 } 1557 for (i = 31; i > 31 - b; --i) 1558 ipa->addr32[j] |= (1 << i); 1559 if (b) 1560 ipa->addr32[j] = htonl(ipa->addr32[j]); 1561} 1562 1563const struct ipsec_xf * 1564parse_xf(const char *name, const struct ipsec_xf xfs[]) 1565{ 1566 int i; 1567 1568 for (i = 0; xfs[i].name != NULL; i++) { 1569 if (strncmp(name, xfs[i].name, strlen(name))) 1570 continue; 1571 return &xfs[i]; 1572 } 1573 return (NULL); 1574} 1575 1576struct ipsec_transforms * 1577copytransforms(const struct ipsec_transforms *xfs) 1578{ 1579 struct ipsec_transforms *newxfs; 1580 1581 if (xfs == NULL) 1582 return (NULL); 1583 1584 newxfs = calloc(1, sizeof(struct ipsec_transforms)); 1585 if (newxfs == NULL) 1586 err(1, "copytransforms: calloc"); 1587 1588 memcpy(newxfs, xfs, sizeof(struct ipsec_transforms)); 1589 return (newxfs); 1590} 1591 1592struct ipsec_auth * 1593copyipsecauth(const struct ipsec_auth *auth) 1594{ 1595 struct ipsec_auth *newauth; 1596 1597 if (auth == NULL) 1598 return (NULL); 1599 1600 if ((newauth = calloc(1, sizeof(struct ipsec_auth))) == NULL) 1601 err(1, "calloc"); 1602 if (auth->srcid && 1603 asprintf(&newauth->srcid, "%s", auth->srcid) == -1) 1604 err(1, "asprintf"); 1605 if (auth->dstid && 1606 asprintf(&newauth->dstid, "%s", auth->dstid) == -1) 1607 err(1, "asprintf"); 1608 1609 newauth->idtype = auth->idtype; 1610 newauth->type = auth->type; 1611 1612 return (newauth); 1613} 1614 1615struct ike_auth * 1616copyikeauth(const struct ike_auth *auth) 1617{ 1618 struct ike_auth *newauth; 1619 1620 if (auth == NULL) 1621 return (NULL); 1622 1623 if ((newauth = calloc(1, sizeof(struct ike_auth))) == NULL) 1624 err(1, "calloc"); 1625 if (auth->string && 1626 asprintf(&newauth->string, "%s", auth->string) == -1) 1627 err(1, "asprintf"); 1628 1629 newauth->type = auth->type; 1630 1631 return (newauth); 1632} 1633 1634struct ipsec_key * 1635copykey(struct ipsec_key *key) 1636{ 1637 struct ipsec_key *newkey; 1638 1639 if (key == NULL) 1640 return (NULL); 1641 1642 if ((newkey = calloc(1, sizeof(struct ipsec_key))) == NULL) 1643 err(1, "calloc"); 1644 if ((newkey->data = calloc(key->len, sizeof(u_int8_t))) == NULL) 1645 err(1, "calloc"); 1646 memcpy(newkey->data, key->data, key->len); 1647 newkey->len = key->len; 1648 1649 return (newkey); 1650} 1651 1652struct ipsec_addr_wrap * 1653copyhost(const struct ipsec_addr_wrap *src) 1654{ 1655 struct ipsec_addr_wrap *dst; 1656 1657 if (src == NULL) 1658 return (NULL); 1659 1660 dst = calloc(1, sizeof(struct ipsec_addr_wrap)); 1661 if (dst == NULL) 1662 err(1, "copyhost: calloc"); 1663 1664 memcpy(dst, src, sizeof(struct ipsec_addr_wrap)); 1665 1666 if ((dst->name = strdup(src->name)) == NULL) 1667 err(1, "copyhost: strdup"); 1668 1669 return dst; 1670} 1671 1672struct ipsec_rule * 1673copyrule(struct ipsec_rule *rule) 1674{ 1675 struct ipsec_rule *r; 1676 1677 if ((r = calloc(1, sizeof(struct ipsec_rule))) == NULL) 1678 err(1, "calloc"); 1679 1680 r->src = copyhost(rule->src); 1681 r->dst = copyhost(rule->dst); 1682 r->local = copyhost(rule->local); 1683 r->peer = copyhost(rule->peer); 1684 r->auth = copyipsecauth(rule->auth); 1685 r->ikeauth = copyikeauth(rule->ikeauth); 1686 r->xfs = copytransforms(rule->xfs); 1687 r->mmxfs = copytransforms(rule->mmxfs); 1688 r->qmxfs = copytransforms(rule->qmxfs); 1689 r->authkey = copykey(rule->authkey); 1690 r->enckey = copykey(rule->enckey); 1691 1692 r->type = rule->type; 1693 r->satype = rule->satype; 1694 r->proto = rule->proto; 1695 r->tmode = rule->tmode; 1696 r->direction = rule->direction; 1697 r->flowtype = rule->flowtype; 1698 r->ikemode = rule->ikemode; 1699 r->spi = rule->spi; 1700 r->nr = rule->nr; 1701 1702 return (r); 1703} 1704 1705int 1706validate_sa(u_int32_t spi, u_int8_t satype, struct ipsec_transforms *xfs, 1707 struct ipsec_key *authkey, struct ipsec_key *enckey, u_int8_t tmode) 1708{ 1709 /* Sanity checks */ 1710 if (spi == 0) { 1711 yyerror("no SPI specified"); 1712 return (0); 1713 } 1714 if (satype == IPSEC_AH) { 1715 if (!xfs) { 1716 yyerror("no transforms specified"); 1717 return (0); 1718 } 1719 if (!xfs->authxf) 1720 xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256]; 1721 if (xfs->encxf) { 1722 yyerror("ah does not provide encryption"); 1723 return (0); 1724 } 1725 if (xfs->compxf) { 1726 yyerror("ah does not provide compression"); 1727 return (0); 1728 } 1729 } 1730 if (satype == IPSEC_ESP) { 1731 if (!xfs) { 1732 yyerror("no transforms specified"); 1733 return (0); 1734 } 1735 if (xfs->compxf) { 1736 yyerror("esp does not provide compression"); 1737 return (0); 1738 } 1739 if (!xfs->authxf) 1740 xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256]; 1741 if (!xfs->encxf) 1742 xfs->encxf = &encxfs[ENCXF_AESCTR]; 1743 } 1744 if (satype == IPSEC_IPCOMP) { 1745 if (!xfs) { 1746 yyerror("no transform specified"); 1747 return (0); 1748 } 1749 if (xfs->authxf || xfs->encxf) { 1750 yyerror("no encryption or authentication with ipcomp"); 1751 return (0); 1752 } 1753 if (!xfs->compxf) 1754 xfs->compxf = &compxfs[COMPXF_DEFLATE]; 1755 } 1756 if (satype == IPSEC_IPIP) { 1757 if (!xfs) { 1758 yyerror("no transform specified"); 1759 return (0); 1760 } 1761 if (xfs->authxf || xfs->encxf || xfs->compxf) { 1762 yyerror("no encryption, authentication or compression" 1763 " with ipip"); 1764 return (0); 1765 } 1766 } 1767 if (satype == IPSEC_TCPMD5 && authkey == NULL && tmode != 1768 IPSEC_TRANSPORT) { 1769 yyerror("authentication key needed for tcpmd5"); 1770 return (0); 1771 } 1772 if (xfs && xfs->authxf) { 1773 if (!authkey) { 1774 yyerror("no authentication key specified"); 1775 return (0); 1776 } 1777 if (authkey->len != xfs->authxf->keymin) { 1778 yyerror("wrong authentication key length, needs to be " 1779 "%d bits", xfs->authxf->keymin * 8); 1780 return (0); 1781 } 1782 } 1783 if (xfs && xfs->encxf) { 1784 if (!enckey && xfs->encxf != &encxfs[ENCXF_NULL]) { 1785 yyerror("no encryption key specified"); 1786 return (0); 1787 } 1788 if (enckey) { 1789 if (enckey->len < xfs->encxf->keymin) { 1790 yyerror("encryption key too short, " 1791 "minimum %d bits", xfs->encxf->keymin * 8); 1792 return (0); 1793 } 1794 if (xfs->encxf->keymax < enckey->len) { 1795 yyerror("encryption key too long, " 1796 "maximum %d bits", xfs->encxf->keymax * 8); 1797 return (0); 1798 } 1799 } 1800 } 1801 1802 return 1; 1803} 1804 1805struct ipsec_rule * 1806create_sa(u_int8_t satype, u_int8_t tmode, struct ipsec_addr_wrap *src, struct 1807 ipsec_addr_wrap *dst, u_int32_t spi, struct ipsec_transforms *xfs, 1808 struct ipsec_key *authkey, struct ipsec_key *enckey) 1809{ 1810 struct ipsec_rule *r; 1811 1812 if (validate_sa(spi, satype, xfs, authkey, enckey, tmode) == 0) 1813 return (NULL); 1814 1815 r = calloc(1, sizeof(struct ipsec_rule)); 1816 if (r == NULL) 1817 err(1, "create_sa: calloc"); 1818 1819 r->type |= RULE_SA; 1820 r->satype = satype; 1821 r->tmode = tmode; 1822 r->src = src; 1823 r->dst = dst; 1824 r->spi = spi; 1825 r->xfs = xfs; 1826 r->authkey = authkey; 1827 r->enckey = enckey; 1828 1829 return r; 1830} 1831 1832struct ipsec_rule * 1833reverse_sa(struct ipsec_rule *rule, u_int32_t spi, struct ipsec_key *authkey, 1834 struct ipsec_key *enckey) 1835{ 1836 struct ipsec_rule *reverse; 1837 1838 if (validate_sa(spi, rule->satype, rule->xfs, authkey, enckey, 1839 rule->tmode) == 0) 1840 return (NULL); 1841 1842 reverse = calloc(1, sizeof(struct ipsec_rule)); 1843 if (reverse == NULL) 1844 err(1, "reverse_sa: calloc"); 1845 1846 reverse->type |= RULE_SA; 1847 reverse->satype = rule->satype; 1848 reverse->tmode = rule->tmode; 1849 reverse->src = copyhost(rule->dst); 1850 reverse->dst = copyhost(rule->src); 1851 reverse->spi = spi; 1852 reverse->xfs = copytransforms(rule->xfs); 1853 reverse->authkey = authkey; 1854 reverse->enckey = enckey; 1855 1856 return (reverse); 1857} 1858 1859struct ipsec_rule * 1860create_flow(u_int8_t dir, u_int8_t proto, struct ipsec_addr_wrap *src, 1861 struct ipsec_addr_wrap *dst, struct ipsec_addr_wrap *local, 1862 struct ipsec_addr_wrap *peer, u_int8_t satype, char *srcid, char *dstid, 1863 u_int8_t type) 1864{ 1865 struct ipsec_rule *r; 1866 1867 r = calloc(1, sizeof(struct ipsec_rule)); 1868 if (r == NULL) 1869 err(1, "create_flow: calloc"); 1870 1871 r->type |= RULE_FLOW; 1872 1873 if (dir == IPSEC_INOUT) 1874 r->direction = IPSEC_OUT; 1875 else 1876 r->direction = dir; 1877 1878 r->satype = satype; 1879 r->proto = proto; 1880 r->src = src; 1881 r->dst = dst; 1882 1883 if (type == TYPE_DENY || type == TYPE_BYPASS) { 1884 r->flowtype = type; 1885 return (r); 1886 } 1887 1888 r->flowtype = type; 1889 r->local = local; 1890 if (peer == NULL) { 1891 /* Set peer to remote host. Must be a host address. */ 1892 if (r->direction == IPSEC_IN) { 1893 if (r->src->netaddress) { 1894 yyerror("no peer specified"); 1895 goto errout; 1896 } 1897 r->peer = copyhost(r->src); 1898 } else { 1899 if (r->dst->netaddress) { 1900 yyerror("no peer specified"); 1901 goto errout; 1902 } 1903 r->peer = copyhost(r->dst); 1904 } 1905 } else 1906 r->peer = peer; 1907 1908 r->auth = calloc(1, sizeof(struct ipsec_auth)); 1909 if (r->auth == NULL) 1910 err(1, "create_flow: calloc"); 1911 r->auth->srcid = srcid; 1912 r->auth->dstid = dstid; 1913 r->auth->idtype = ID_FQDN; /* XXX For now only FQDN. */ 1914 1915 return r; 1916 1917errout: 1918 free(r); 1919 if (srcid) 1920 free(srcid); 1921 if (dstid) 1922 free(dstid); 1923 free(src); 1924 free(dst); 1925 1926 return NULL; 1927} 1928 1929int 1930expand_rule(struct ipsec_rule *rule, u_int8_t direction, u_int32_t spi, 1931 struct ipsec_key *authkey, struct ipsec_key *enckey) 1932{ 1933 struct ipsec_rule *r, *revr; 1934 struct ipsec_addr_wrap *src, *dst; 1935 int added = 0; 1936 1937 for (src = rule->src; src; src = src->next) { 1938 for (dst = rule->dst; dst; dst = dst->next) { 1939 if (src->af != dst->af) 1940 continue; 1941 r = copyrule(rule); 1942 1943 r->src = copyhost(src); 1944 r->dst = copyhost(dst); 1945 1946 r->nr = ipsec->rule_nr++; 1947 if (ipsecctl_add_rule(ipsec, r)) 1948 return (1); 1949 1950 if (direction == IPSEC_INOUT) { 1951 /* Create and add reverse flow rule. */ 1952 revr = reverse_rule(r); 1953 if (revr == NULL) 1954 return (1); 1955 1956 revr->nr = ipsec->rule_nr++; 1957 if (ipsecctl_add_rule(ipsec, revr)) 1958 return (1); 1959 } else if (spi != 0 || authkey || enckey) { 1960 /* Create and add reverse sa rule. */ 1961 revr = reverse_sa(r, spi, authkey, enckey); 1962 if (revr == NULL) 1963 return (1); 1964 1965 revr->nr = ipsec->rule_nr++; 1966 if (ipsecctl_add_rule(ipsec, revr)) 1967 return (1); 1968 } 1969 added++; 1970 } 1971 } 1972 if (!added) 1973 yyerror("rule expands to no valid combination"); 1974 ipsecctl_free_rule(rule); 1975 return (0); 1976} 1977 1978struct ipsec_rule * 1979reverse_rule(struct ipsec_rule *rule) 1980{ 1981 struct ipsec_rule *reverse; 1982 1983 reverse = calloc(1, sizeof(struct ipsec_rule)); 1984 if (reverse == NULL) 1985 err(1, "reverse_rule: calloc"); 1986 1987 reverse->type |= RULE_FLOW; 1988 1989 /* Reverse direction */ 1990 if (rule->direction == (u_int8_t)IPSEC_OUT) 1991 reverse->direction = (u_int8_t)IPSEC_IN; 1992 else 1993 reverse->direction = (u_int8_t)IPSEC_OUT; 1994 1995 reverse->flowtype = rule->flowtype; 1996 reverse->src = copyhost(rule->dst); 1997 reverse->dst = copyhost(rule->src); 1998 if (rule->local) 1999 reverse->local = copyhost(rule->local); 2000 if (rule->peer) 2001 reverse->peer = copyhost(rule->peer); 2002 reverse->satype = rule->satype; 2003 reverse->proto = rule->proto; 2004 2005 if (rule->auth) { 2006 reverse->auth = calloc(1, sizeof(struct ipsec_auth)); 2007 if (reverse->auth == NULL) 2008 err(1, "reverse_rule: calloc"); 2009 if (rule->auth->dstid && (reverse->auth->dstid = 2010 strdup(rule->auth->dstid)) == NULL) 2011 err(1, "reverse_rule: strdup"); 2012 if (rule->auth->srcid && (reverse->auth->srcid = 2013 strdup(rule->auth->srcid)) == NULL) 2014 err(1, "reverse_rule: strdup"); 2015 reverse->auth->idtype = rule->auth->idtype; 2016 reverse->auth->type = rule->auth->type; 2017 } 2018 2019 return reverse; 2020} 2021 2022struct ipsec_rule * 2023create_ike(u_int8_t proto, struct ipsec_addr_wrap *src, struct ipsec_addr_wrap 2024 *dst, struct ipsec_addr_wrap *local, struct ipsec_addr_wrap *peer, 2025 struct ipsec_transforms *mmxfs, struct ipsec_transforms *qmxfs, 2026 u_int8_t satype, u_int8_t mode, char *srcid, char *dstid, 2027 struct ike_auth *authtype) 2028{ 2029 struct ipsec_rule *r; 2030 2031 r = calloc(1, sizeof(struct ipsec_rule)); 2032 if (r == NULL) 2033 err(1, "create_ike: calloc"); 2034 2035 r->type = RULE_IKE; 2036 2037 r->proto = proto; 2038 r->src = src; 2039 r->dst = dst; 2040 2041 if (peer == NULL) { 2042 /* Set peer to remote host. Must be a host address. */ 2043 if (r->direction == IPSEC_IN) { 2044 if (r->src->netaddress) { 2045 yyerror("no peer specified"); 2046 goto errout; 2047 } 2048 r->peer = copyhost(r->src); 2049 } else { 2050 if (r->dst->netaddress) { 2051 yyerror("no peer specified"); 2052 goto errout; 2053 } 2054 r->peer = copyhost(r->dst); 2055 } 2056 } else 2057 r->peer = peer; 2058 2059 if (local) 2060 r->local = local; 2061 2062 r->satype = satype; 2063 r->ikemode = mode; 2064 r->mmxfs = mmxfs; 2065 r->qmxfs = qmxfs; 2066 r->auth = calloc(1, sizeof(struct ipsec_auth)); 2067 if (r->auth == NULL) 2068 err(1, "create_ike: calloc"); 2069 r->auth->srcid = srcid; 2070 r->auth->dstid = dstid; 2071 r->auth->idtype = ID_FQDN; /* XXX For now only FQDN. */ 2072 r->ikeauth = calloc(1, sizeof(struct ike_auth)); 2073 if (r->ikeauth == NULL) 2074 err(1, "create_ike: calloc"); 2075 r->ikeauth->type = authtype->type; 2076 r->ikeauth->string = authtype->string; 2077 2078 return (r); 2079 2080errout: 2081 free(r); 2082 if (srcid) 2083 free(srcid); 2084 if (dstid) 2085 free(dstid); 2086 free(src); 2087 free(dst); 2088 if (authtype->string) 2089 free(authtype->string); 2090 2091 return (NULL); 2092} 2093