parse.y revision 1.68
1/* $OpenBSD: parse.y,v 1.68 2006/05/28 01:36:06 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_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 1273 set_ipmask(ipa, bits); 1274 if (bits != (ipa->af == AF_INET ? 32 : 128)) 1275 ipa->netaddress = 1; 1276 1277 return (ipa); 1278} 1279 1280struct ipsec_addr_wrap * 1281host_dns(const char *s, int v4mask, int v6mask) 1282{ 1283 struct ipsec_addr_wrap *ipa = NULL; 1284 struct addrinfo hints, *res0, *res; 1285 int error; 1286 int bits = 32; 1287 1288 bzero(&hints, sizeof(struct addrinfo)); 1289 hints.ai_family = PF_UNSPEC; 1290 hints.ai_socktype = SOCK_STREAM; 1291 error = getaddrinfo(s, NULL, &hints, &res0); 1292 if (error) 1293 return (NULL); 1294 1295 for (res = res0; res; res = res->ai_next) { 1296 if (res->ai_family != AF_INET) 1297 continue; 1298 ipa = calloc(1, sizeof(struct ipsec_addr_wrap)); 1299 if (ipa == NULL) 1300 err(1, "host_dns: calloc"); 1301 memcpy(&ipa->address.v4, 1302 &((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr, 1303 sizeof(struct in_addr)); 1304 ipa->name = strdup(inet_ntoa(ipa->address.v4)); 1305 if (ipa->name == NULL) 1306 err(1, "host_dns: strdup"); 1307 ipa->af = AF_INET; 1308 1309 set_ipmask(ipa, bits); 1310 if (bits != (ipa->af == AF_INET ? 32 : 128)) 1311 ipa->netaddress = 1; 1312 break; 1313 } 1314 freeaddrinfo(res0); 1315 1316 return (ipa); 1317} 1318 1319struct ipsec_addr_wrap * 1320host_if(const char *s, int mask) 1321{ 1322 struct ipsec_addr_wrap *ipa = NULL; 1323 1324 if (ifa_exists(s)) 1325 ipa = ifa_lookup(s); 1326 1327 return (ipa); 1328} 1329 1330/* interface lookup routintes */ 1331 1332struct addr_node *iftab; 1333 1334void 1335ifa_load(void) 1336{ 1337 struct ifaddrs *ifap, *ifa; 1338 struct addr_node *n = NULL, *h = NULL; 1339 1340 if (getifaddrs(&ifap) < 0) 1341 err(1, "ifa_load: getiffaddrs"); 1342 1343 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 1344 if (!(ifa->ifa_addr->sa_family == AF_INET || 1345 ifa->ifa_addr->sa_family == AF_INET6 || 1346 ifa->ifa_addr->sa_family == AF_LINK)) 1347 continue; 1348 n = calloc(1, sizeof(struct addr_node)); 1349 if (n == NULL) 1350 err(1, "ifa_load: calloc"); 1351 n->af = ifa->ifa_addr->sa_family; 1352 if ((n->addr.name = strdup(ifa->ifa_name)) == NULL) 1353 err(1, "ifa_load: strdup"); 1354 if (n->af == AF_INET) { 1355 n->addr.af = AF_INET; 1356 memcpy(&n->addr.address.v4, &((struct sockaddr_in *) 1357 ifa->ifa_addr)->sin_addr.s_addr, 1358 sizeof(struct in_addr)); 1359 memcpy(&n->addr.mask.v4, &((struct sockaddr_in *) 1360 ifa->ifa_netmask)->sin_addr.s_addr, 1361 sizeof(struct in_addr)); 1362 } else if (n->af == AF_INET6) { 1363 n->addr.af = AF_INET6; 1364 memcpy(&n->addr.address.v6, &((struct sockaddr_in6 *) 1365 ifa->ifa_addr)->sin6_addr.s6_addr, 1366 sizeof(struct in6_addr)); 1367 memcpy(&n->addr.mask.v6, &((struct sockaddr_in6 *) 1368 ifa->ifa_netmask)->sin6_addr.s6_addr, 1369 sizeof(struct in6_addr)); 1370 } 1371 if ((n->addr.name = strdup(ifa->ifa_name)) == NULL) 1372 err(1, "ifa_load: strdup"); 1373 n->next = NULL; 1374 n->tail = n; 1375 if (h == NULL) 1376 h = n; 1377 else { 1378 h->tail->next = n; 1379 h->tail = n; 1380 } 1381 } 1382 1383 iftab = h; 1384 freeifaddrs(ifap); 1385} 1386 1387int 1388ifa_exists(const char *ifa_name) 1389{ 1390 struct addr_node *n; 1391 struct ifgroupreq ifgr; 1392 int s; 1393 1394 if (iftab == NULL) 1395 ifa_load(); 1396 1397 /* check wether this is a group */ 1398 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 1399 err(1, "ifa_exists: socket"); 1400 bzero(&ifgr, sizeof(ifgr)); 1401 strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name)); 1402 if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == 0) { 1403 close(s); 1404 return (1); 1405 } 1406 close(s); 1407 1408 for (n = iftab; n; n = n->next) { 1409 if (n->af == AF_LINK && !strncmp(n->addr.name, ifa_name, 1410 IFNAMSIZ)) 1411 return (1); 1412 } 1413 1414 return (0); 1415} 1416 1417struct ipsec_addr_wrap * 1418ifa_grouplookup(const char *ifa_name) 1419{ 1420 struct ifg_req *ifg; 1421 struct ifgroupreq ifgr; 1422 int s; 1423 size_t len; 1424 struct ipsec_addr_wrap *ipa = NULL; 1425 1426 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 1427 err(1, "socket"); 1428 bzero(&ifgr, sizeof(ifgr)); 1429 strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name)); 1430 if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) { 1431 close(s); 1432 return (NULL); 1433 } 1434 1435 len = ifgr.ifgr_len; 1436 if ((ifgr.ifgr_groups = calloc(1, len)) == NULL) 1437 err(1, "calloc"); 1438 if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) 1439 err(1, "ioctl"); 1440 1441 for (ifg = ifgr.ifgr_groups; ifg && len >= sizeof(struct ifg_req); 1442 ifg++) { 1443 len -= sizeof(struct ifg_req); 1444 if ((ipa = ifa_lookup(ifg->ifgrq_member)) != NULL) 1445 break; 1446 } 1447 free(ifgr.ifgr_groups); 1448 close(s); 1449 1450 return (ipa); 1451} 1452 1453struct ipsec_addr_wrap * 1454ifa_lookup(const char *ifa_name) 1455{ 1456 struct addr_node *p = NULL; 1457 struct ipsec_addr_wrap *ipa = NULL; 1458 1459 if (iftab == NULL) 1460 ifa_load(); 1461 1462 if ((ipa = ifa_grouplookup(ifa_name)) != NULL) 1463 return (ipa); 1464 1465 for (p = iftab; p; p = p->next) { 1466 if (p->af != AF_INET) 1467 continue; 1468 if (strncmp(p->addr.name, ifa_name, IFNAMSIZ)) 1469 continue; 1470 ipa = calloc(1, sizeof(struct ipsec_addr_wrap)); 1471 if (ipa == NULL) 1472 err(1, "ifa_lookup: calloc"); 1473 memcpy(ipa, &p->addr, sizeof(struct ipsec_addr_wrap)); 1474 if ((ipa->name = strdup(p->addr.name)) == NULL) 1475 err(1, "ifa_lookup: strdup"); 1476 set_ipmask(ipa, 32); 1477 break; 1478 } 1479 1480 return (ipa); 1481} 1482 1483void 1484set_ipmask(struct ipsec_addr_wrap *address, u_int8_t b) 1485{ 1486 struct ipsec_addr *ipa; 1487 int i, j = 0; 1488 1489 ipa = &address->mask; 1490 bzero(ipa, sizeof(struct ipsec_addr)); 1491 1492 while (b >= 32) { 1493 ipa->addr32[j++] = 0xffffffff; 1494 b -= 32; 1495 } 1496 for (i = 31; i > 31 - b; --i) 1497 ipa->addr32[j] |= (1 << i); 1498 if (b) 1499 ipa->addr32[j] = htonl(ipa->addr32[j]); 1500} 1501 1502struct ipsec_addr_wrap * 1503copyhost(const struct ipsec_addr_wrap *src) 1504{ 1505 struct ipsec_addr_wrap *dst; 1506 1507 dst = calloc(1, sizeof(struct ipsec_addr_wrap)); 1508 if (dst == NULL) 1509 err(1, "copyhost: calloc"); 1510 1511 memcpy(dst, src, sizeof(struct ipsec_addr_wrap)); 1512 1513 if ((dst->name = strdup(src->name)) == NULL) 1514 err(1, "copyhost: strdup"); 1515 1516 return dst; 1517} 1518 1519const struct ipsec_xf * 1520parse_xf(const char *name, const struct ipsec_xf xfs[]) 1521{ 1522 int i; 1523 1524 for (i = 0; xfs[i].name != NULL; i++) { 1525 if (strncmp(name, xfs[i].name, strlen(name))) 1526 continue; 1527 return &xfs[i]; 1528 } 1529 return (NULL); 1530} 1531 1532struct ipsec_transforms * 1533copytransforms(const struct ipsec_transforms *xfs) 1534{ 1535 struct ipsec_transforms *newxfs; 1536 1537 if (xfs == NULL) 1538 return (NULL); 1539 1540 newxfs = calloc(1, sizeof(struct ipsec_transforms)); 1541 if (newxfs == NULL) 1542 err(1, "copytransforms: calloc"); 1543 1544 memcpy(newxfs, xfs, sizeof(struct ipsec_transforms)); 1545 return (newxfs); 1546} 1547 1548int 1549validate_sa(u_int32_t spi, u_int8_t satype, struct ipsec_transforms *xfs, 1550 struct ipsec_key *authkey, struct ipsec_key *enckey, u_int8_t tmode) 1551{ 1552 /* Sanity checks */ 1553 if (spi == 0) { 1554 yyerror("no SPI specified"); 1555 return (0); 1556 } 1557 if (satype == IPSEC_AH) { 1558 if (!xfs) { 1559 yyerror("no transforms specified"); 1560 return (0); 1561 } 1562 if (!xfs->authxf) 1563 xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256]; 1564 if (xfs->encxf) { 1565 yyerror("ah does not provide encryption"); 1566 return (0); 1567 } 1568 if (xfs->compxf) { 1569 yyerror("ah does not provide compression"); 1570 return (0); 1571 } 1572 } 1573 if (satype == IPSEC_ESP) { 1574 if (!xfs) { 1575 yyerror("no transforms specified"); 1576 return (0); 1577 } 1578 if (xfs->compxf) { 1579 yyerror("esp does not provide compression"); 1580 return (0); 1581 } 1582 if (!xfs->authxf) 1583 xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256]; 1584 if (!xfs->encxf) 1585 xfs->encxf = &encxfs[ENCXF_AESCTR]; 1586 } 1587 if (satype == IPSEC_IPCOMP) { 1588 if (!xfs) { 1589 yyerror("no transform specified"); 1590 return (0); 1591 } 1592 if (xfs->authxf || xfs->encxf) { 1593 yyerror("no encryption or authentication with ipcomp"); 1594 return (0); 1595 } 1596 if (!xfs->compxf) 1597 xfs->compxf = &compxfs[COMPXF_DEFLATE]; 1598 } 1599 if (satype == IPSEC_IPIP) { 1600 if (!xfs) { 1601 yyerror("no transform specified"); 1602 return (0); 1603 } 1604 if (xfs->authxf || xfs->encxf || xfs->compxf) { 1605 yyerror("no encryption, authentication or compression" 1606 " with ipip"); 1607 return (0); 1608 } 1609 } 1610 if (satype == IPSEC_TCPMD5 && authkey == NULL && tmode != 1611 IPSEC_TRANSPORT) { 1612 yyerror("authentication key needed for tcpmd5"); 1613 return (0); 1614 } 1615 if (xfs && xfs->authxf) { 1616 if (!authkey) { 1617 yyerror("no authentication key specified"); 1618 return (0); 1619 } 1620 if (authkey->len != xfs->authxf->keymin) { 1621 yyerror("wrong authentication key length, needs to be " 1622 "%d bits", xfs->authxf->keymin * 8); 1623 return (0); 1624 } 1625 } 1626 if (xfs && xfs->encxf) { 1627 if (!enckey && xfs->encxf != &encxfs[ENCXF_NULL]) { 1628 yyerror("no encryption key specified"); 1629 return (0); 1630 } 1631 if (enckey) { 1632 if (enckey->len < xfs->encxf->keymin) { 1633 yyerror("encryption key too short, " 1634 "minimum %d bits", xfs->encxf->keymin * 8); 1635 return (0); 1636 } 1637 if (xfs->encxf->keymax < enckey->len) { 1638 yyerror("encryption key too long, " 1639 "maximum %d bits", xfs->encxf->keymax * 8); 1640 return (0); 1641 } 1642 } 1643 } 1644 1645 return 1; 1646} 1647 1648struct ipsec_rule * 1649create_sa(u_int8_t satype, u_int8_t tmode, struct ipsec_addr_wrap *src, struct 1650 ipsec_addr_wrap *dst, u_int32_t spi, struct ipsec_transforms *xfs, 1651 struct ipsec_key *authkey, struct ipsec_key *enckey) 1652{ 1653 struct ipsec_rule *r; 1654 1655 if (validate_sa(spi, satype, xfs, authkey, enckey, tmode) == 0) 1656 return (NULL); 1657 1658 r = calloc(1, sizeof(struct ipsec_rule)); 1659 if (r == NULL) 1660 err(1, "create_sa: calloc"); 1661 1662 r->type |= RULE_SA; 1663 r->satype = satype; 1664 r->tmode = tmode; 1665 r->src = src; 1666 r->dst = dst; 1667 r->spi = spi; 1668 r->xfs = xfs; 1669 r->authkey = authkey; 1670 r->enckey = enckey; 1671 1672 return r; 1673} 1674 1675struct ipsec_rule * 1676reverse_sa(struct ipsec_rule *rule, u_int32_t spi, struct ipsec_key *authkey, 1677 struct ipsec_key *enckey) 1678{ 1679 struct ipsec_rule *reverse; 1680 1681 if (validate_sa(spi, rule->satype, rule->xfs, authkey, enckey, 1682 rule->tmode) == 0) 1683 return (NULL); 1684 1685 reverse = calloc(1, sizeof(struct ipsec_rule)); 1686 if (reverse == NULL) 1687 err(1, "reverse_sa: calloc"); 1688 1689 reverse->type |= RULE_SA; 1690 reverse->satype = rule->satype; 1691 reverse->tmode = rule->tmode; 1692 reverse->src = copyhost(rule->dst); 1693 reverse->dst = copyhost(rule->src); 1694 reverse->spi = spi; 1695 reverse->xfs = copytransforms(rule->xfs); 1696 reverse->authkey = authkey; 1697 reverse->enckey = enckey; 1698 1699 return (reverse); 1700} 1701 1702struct ipsec_rule * 1703create_flow(u_int8_t dir, u_int8_t proto, struct ipsec_addr_wrap *src, 1704 struct ipsec_addr_wrap *dst, struct ipsec_addr_wrap *local, 1705 struct ipsec_addr_wrap *peer, u_int8_t satype, char *srcid, char *dstid, 1706 u_int8_t type) 1707{ 1708 struct ipsec_rule *r; 1709 1710 r = calloc(1, sizeof(struct ipsec_rule)); 1711 if (r == NULL) 1712 err(1, "create_flow: calloc"); 1713 1714 r->type |= RULE_FLOW; 1715 1716 if (dir == IPSEC_INOUT) 1717 r->direction = IPSEC_OUT; 1718 else 1719 r->direction = dir; 1720 1721 r->satype = satype; 1722 r->proto = proto; 1723 r->src = src; 1724 r->dst = dst; 1725 1726 if (type == TYPE_DENY || type == TYPE_BYPASS) { 1727 r->flowtype = type; 1728 return (r); 1729 } 1730 1731 r->flowtype = type; 1732 r->local = local; 1733 if (peer == NULL) { 1734 /* Set peer to remote host. Must be a host address. */ 1735 if (r->direction == IPSEC_IN) { 1736 if (r->src->netaddress) { 1737 yyerror("no peer specified"); 1738 goto errout; 1739 } 1740 r->peer = copyhost(r->src); 1741 } else { 1742 if (r->dst->netaddress) { 1743 yyerror("no peer specified"); 1744 goto errout; 1745 } 1746 r->peer = copyhost(r->dst); 1747 } 1748 } else 1749 r->peer = peer; 1750 1751 r->auth = calloc(1, sizeof(struct ipsec_auth)); 1752 if (r->auth == NULL) 1753 err(1, "create_flow: calloc"); 1754 r->auth->srcid = srcid; 1755 r->auth->dstid = dstid; 1756 r->auth->idtype = ID_FQDN; /* XXX For now only FQDN. */ 1757 1758 return r; 1759 1760errout: 1761 free(r); 1762 if (srcid) 1763 free(srcid); 1764 if (dstid) 1765 free(dstid); 1766 free(src); 1767 free(dst); 1768 1769 return NULL; 1770} 1771 1772struct ipsec_rule * 1773reverse_rule(struct ipsec_rule *rule) 1774{ 1775 struct ipsec_rule *reverse; 1776 1777 reverse = calloc(1, sizeof(struct ipsec_rule)); 1778 if (reverse == NULL) 1779 err(1, "reverse_rule: calloc"); 1780 1781 reverse->type |= RULE_FLOW; 1782 1783 /* Reverse direction */ 1784 if (rule->direction == (u_int8_t)IPSEC_OUT) 1785 reverse->direction = (u_int8_t)IPSEC_IN; 1786 else 1787 reverse->direction = (u_int8_t)IPSEC_OUT; 1788 1789 reverse->flowtype = rule->flowtype; 1790 reverse->src = copyhost(rule->dst); 1791 reverse->dst = copyhost(rule->src); 1792 if (rule->local) 1793 reverse->local = copyhost(rule->local); 1794 if (rule->peer) 1795 reverse->peer = copyhost(rule->peer); 1796 reverse->satype = rule->satype; 1797 reverse->proto = rule->proto; 1798 1799 if (rule->auth) { 1800 reverse->auth = calloc(1, sizeof(struct ipsec_auth)); 1801 if (reverse->auth == NULL) 1802 err(1, "reverse_rule: calloc"); 1803 if (rule->auth->dstid && (reverse->auth->dstid = 1804 strdup(rule->auth->dstid)) == NULL) 1805 err(1, "reverse_rule: strdup"); 1806 if (rule->auth->srcid && (reverse->auth->srcid = 1807 strdup(rule->auth->srcid)) == NULL) 1808 err(1, "reverse_rule: strdup"); 1809 reverse->auth->idtype = rule->auth->idtype; 1810 reverse->auth->type = rule->auth->type; 1811 } 1812 1813 return reverse; 1814} 1815 1816struct ipsec_rule * 1817create_ike(u_int8_t proto, struct ipsec_addr_wrap *src, struct ipsec_addr_wrap 1818 *dst, struct ipsec_addr_wrap *local, struct ipsec_addr_wrap *peer, 1819 struct ipsec_transforms *mmxfs, struct ipsec_transforms *qmxfs, 1820 u_int8_t satype, u_int8_t mode, char *srcid, char *dstid, 1821 struct ike_auth *authtype) 1822{ 1823 struct ipsec_rule *r; 1824 1825 r = calloc(1, sizeof(struct ipsec_rule)); 1826 if (r == NULL) 1827 err(1, "create_ike: calloc"); 1828 1829 r->type = RULE_IKE; 1830 1831 r->proto = proto; 1832 r->src = src; 1833 r->dst = dst; 1834 1835 if (peer == NULL) { 1836 /* Set peer to remote host. Must be a host address. */ 1837 if (r->direction == IPSEC_IN) { 1838 if (r->src->netaddress) { 1839 yyerror("no peer specified"); 1840 goto errout; 1841 } 1842 r->peer = copyhost(r->src); 1843 } else { 1844 if (r->dst->netaddress) { 1845 yyerror("no peer specified"); 1846 goto errout; 1847 } 1848 r->peer = copyhost(r->dst); 1849 } 1850 } else 1851 r->peer = peer; 1852 1853 if (local) 1854 r->local = local; 1855 1856 r->satype = satype; 1857 r->ikemode = mode; 1858 r->mmxfs = mmxfs; 1859 r->qmxfs = qmxfs; 1860 r->auth = calloc(1, sizeof(struct ipsec_auth)); 1861 if (r->auth == NULL) 1862 err(1, "create_ike: calloc"); 1863 r->auth->srcid = srcid; 1864 r->auth->dstid = dstid; 1865 r->auth->idtype = ID_FQDN; /* XXX For now only FQDN. */ 1866 r->ikeauth = calloc(1, sizeof(struct ike_auth)); 1867 if (r->ikeauth == NULL) 1868 err(1, "create_ike: calloc"); 1869 r->ikeauth->type = authtype->type; 1870 r->ikeauth->string = authtype->string; 1871 1872 return (r); 1873 1874errout: 1875 free(r); 1876 if (srcid) 1877 free(srcid); 1878 if (dstid) 1879 free(dstid); 1880 free(src); 1881 free(dst); 1882 if (authtype->string) 1883 free(authtype->string); 1884 1885 return (NULL); 1886} 1887