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