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