parse.y revision 1.181
1/* $OpenBSD: parse.y,v 1.181 2021/10/22 12:30:54 bluhm 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 50TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files); 51static struct file { 52 TAILQ_ENTRY(file) entry; 53 FILE *stream; 54 char *name; 55 int lineno; 56 int errors; 57} *file, *topfile; 58struct file *pushfile(const char *, int); 59int popfile(void); 60int check_file_secrecy(int, const char *); 61int yyparse(void); 62int yylex(void); 63int yyerror(const char *, ...) 64 __attribute__((__format__ (printf, 1, 2))) 65 __attribute__((__nonnull__ (1))); 66int yywarn(const char *, ...) 67 __attribute__((__format__ (printf, 1, 2))) 68 __attribute__((__nonnull__ (1))); 69int kw_cmp(const void *, const void *); 70int lookup(char *); 71int lgetc(int); 72int lungetc(int); 73int findeol(void); 74 75TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead); 76struct sym { 77 TAILQ_ENTRY(sym) entry; 78 int used; 79 int persist; 80 char *nam; 81 char *val; 82}; 83int symset(const char *, const char *, int); 84char *symget(const char *); 85int cmdline_symset(char *); 86 87#define KEYSIZE_LIMIT 1024 88 89static struct ipsecctl *ipsec = NULL; 90static int debug = 0; 91 92const struct ipsec_xf authxfs[] = { 93 { "unknown", AUTHXF_UNKNOWN, 0, 0 }, 94 { "none", AUTHXF_NONE, 0, 0 }, 95 { "hmac-md5", AUTHXF_HMAC_MD5, 16, 0 }, 96 { "hmac-ripemd160", AUTHXF_HMAC_RIPEMD160, 20, 0 }, 97 { "hmac-sha1", AUTHXF_HMAC_SHA1, 20, 0 }, 98 { "hmac-sha2-256", AUTHXF_HMAC_SHA2_256, 32, 0 }, 99 { "hmac-sha2-384", AUTHXF_HMAC_SHA2_384, 48, 0 }, 100 { "hmac-sha2-512", AUTHXF_HMAC_SHA2_512, 64, 0 }, 101 { NULL, 0, 0, 0 }, 102}; 103 104const struct ipsec_xf encxfs[] = { 105 { "unknown", ENCXF_UNKNOWN, 0, 0, 0, 0 }, 106 { "none", ENCXF_NONE, 0, 0, 0, 0 }, 107 { "3des-cbc", ENCXF_3DES_CBC, 24, 24, 0, 0 }, 108 { "aes", ENCXF_AES, 16, 32, 0, 0 }, 109 { "aes-128", ENCXF_AES_128, 16, 16, 0, 0 }, 110 { "aes-192", ENCXF_AES_192, 24, 24, 0, 0 }, 111 { "aes-256", ENCXF_AES_256, 32, 32, 0, 0 }, 112 { "aesctr", ENCXF_AESCTR, 16+4, 32+4, 0, 1 }, 113 { "aes-128-ctr", ENCXF_AES_128_CTR, 16+4, 16+4, 0, 1 }, 114 { "aes-192-ctr", ENCXF_AES_192_CTR, 24+4, 24+4, 0, 1 }, 115 { "aes-256-ctr", ENCXF_AES_256_CTR, 32+4, 32+4, 0, 1 }, 116 { "aes-128-gcm", ENCXF_AES_128_GCM, 16+4, 16+4, 1, 1 }, 117 { "aes-192-gcm", ENCXF_AES_192_GCM, 24+4, 24+4, 1, 1 }, 118 { "aes-256-gcm", ENCXF_AES_256_GCM, 32+4, 32+4, 1, 1 }, 119 { "aes-128-gmac", ENCXF_AES_128_GMAC, 16+4, 16+4, 1, 1 }, 120 { "aes-192-gmac", ENCXF_AES_192_GMAC, 24+4, 24+4, 1, 1 }, 121 { "aes-256-gmac", ENCXF_AES_256_GMAC, 32+4, 32+4, 1, 1 }, 122 { "blowfish", ENCXF_BLOWFISH, 5, 56, 0, 0 }, 123 { "cast128", ENCXF_CAST128, 5, 16, 0, 0 }, 124 { "chacha20-poly1305", ENCXF_CHACHA20_POLY1305, 32+4, 32+4, 1, 1 }, 125 { "null", ENCXF_NULL, 0, 0, 0, 0 }, 126 { NULL, 0, 0, 0, 0, 0 }, 127}; 128 129const struct ipsec_xf compxfs[] = { 130 { "unknown", COMPXF_UNKNOWN, 0, 0 }, 131 { "deflate", COMPXF_DEFLATE, 0, 0 }, 132 { NULL, 0, 0, 0 }, 133}; 134 135const struct ipsec_xf groupxfs[] = { 136 { "unknown", GROUPXF_UNKNOWN, 0, 0 }, 137 { "none", GROUPXF_NONE, 0, 0 }, 138 { "modp768", GROUPXF_1, 768, 0 }, 139 { "grp1", GROUPXF_1, 768, 0 }, 140 { "modp1024", GROUPXF_2, 1024, 0 }, 141 { "grp2", GROUPXF_2, 1024, 0 }, 142 { "modp1536", GROUPXF_5, 1536, 0 }, 143 { "grp5", GROUPXF_5, 1536, 0 }, 144 { "modp2048", GROUPXF_14, 2048, 0 }, 145 { "grp14", GROUPXF_14, 2048, 0 }, 146 { "modp3072", GROUPXF_15, 3072, 0 }, 147 { "grp15", GROUPXF_15, 3072, 0 }, 148 { "modp4096", GROUPXF_16, 4096, 0 }, 149 { "grp16", GROUPXF_16, 4096, 0 }, 150 { "modp6144", GROUPXF_17, 6144, 0 }, 151 { "grp17", GROUPXF_17, 6144, 0 }, 152 { "modp8192", GROUPXF_18, 8192, 0 }, 153 { "grp18", GROUPXF_18, 8192, 0 }, 154 { "ecp256", GROUPXF_19, 256, 0 }, 155 { "grp19", GROUPXF_19, 256, 0 }, 156 { "ecp384", GROUPXF_20, 384, 0 }, 157 { "grp20", GROUPXF_20, 384, 0 }, 158 { "ecp521", GROUPXF_21, 521, 0 }, 159 { "grp21", GROUPXF_21, 521, 0 }, 160 { "ecp192", GROUPXF_25, 192, 0 }, 161 { "grp25", GROUPXF_25, 192, 0 }, 162 { "ecp224", GROUPXF_26, 224, 0 }, 163 { "grp26", GROUPXF_26, 224, 0 }, 164 { "bp224", GROUPXF_27, 224, 0 }, 165 { "grp27", GROUPXF_27, 224, 0 }, 166 { "bp256", GROUPXF_28, 256, 0 }, 167 { "grp28", GROUPXF_28, 256, 0 }, 168 { "bp384", GROUPXF_29, 384, 0 }, 169 { "grp29", GROUPXF_29, 384, 0 }, 170 { "bp512", GROUPXF_30, 512, 0 }, 171 { "grp30", GROUPXF_30, 512, 0 }, 172 { NULL, 0, 0, 0 }, 173}; 174 175int atoul(char *, u_long *); 176int atospi(char *, u_int32_t *); 177u_int8_t x2i(unsigned char *); 178struct ipsec_key *parsekey(unsigned char *, size_t); 179struct ipsec_key *parsekeyfile(char *); 180struct ipsec_addr_wrap *host(const char *); 181struct ipsec_addr_wrap *host_v6(const char *, int); 182struct ipsec_addr_wrap *host_v4(const char *, int); 183struct ipsec_addr_wrap *host_dns(const char *, int); 184struct ipsec_addr_wrap *host_if(const char *, int); 185struct ipsec_addr_wrap *host_any(void); 186void ifa_load(void); 187int ifa_exists(const char *); 188struct ipsec_addr_wrap *ifa_lookup(const char *ifa_name); 189struct ipsec_addr_wrap *ifa_grouplookup(const char *); 190void set_ipmask(struct ipsec_addr_wrap *, u_int8_t); 191const struct ipsec_xf *parse_xf(const char *, const struct ipsec_xf *); 192struct ipsec_lifetime *parse_life(const char *); 193struct ipsec_transforms *copytransforms(const struct ipsec_transforms *); 194struct ipsec_lifetime *copylife(const struct ipsec_lifetime *); 195struct ipsec_auth *copyipsecauth(const struct ipsec_auth *); 196struct ike_auth *copyikeauth(const struct ike_auth *); 197struct ipsec_key *copykey(struct ipsec_key *); 198struct ipsec_addr_wrap *copyhost(const struct ipsec_addr_wrap *); 199char *copytag(const char *); 200struct ipsec_rule *copyrule(struct ipsec_rule *); 201int validate_af(struct ipsec_addr_wrap *, 202 struct ipsec_addr_wrap *); 203int validate_sa(u_int32_t, u_int8_t, 204 struct ipsec_transforms *, struct ipsec_key *, 205 struct ipsec_key *, u_int8_t); 206struct ipsec_rule *create_sa(u_int8_t, u_int8_t, struct ipsec_hosts *, 207 u_int32_t, u_int8_t, u_int16_t, 208 struct ipsec_transforms *, 209 struct ipsec_key *, struct ipsec_key *); 210struct ipsec_rule *reverse_sa(struct ipsec_rule *, u_int32_t, 211 struct ipsec_key *, struct ipsec_key *); 212struct ipsec_rule *create_sabundle(struct ipsec_addr_wrap *, u_int8_t, 213 u_int32_t, struct ipsec_addr_wrap *, u_int8_t, 214 u_int32_t); 215struct ipsec_rule *create_flow(u_int8_t, u_int8_t, struct ipsec_hosts *, 216 u_int8_t, char *, char *, u_int8_t); 217int set_rule_peers(struct ipsec_rule *r, 218 struct ipsec_hosts *peers); 219void expand_any(struct ipsec_addr_wrap *); 220int expand_rule(struct ipsec_rule *, struct ipsec_hosts *, 221 u_int8_t, u_int32_t, struct ipsec_key *, 222 struct ipsec_key *, char *); 223struct ipsec_rule *reverse_rule(struct ipsec_rule *); 224struct ipsec_rule *create_ike(u_int8_t, struct ipsec_hosts *, 225 struct ike_mode *, struct ike_mode *, u_int8_t, 226 u_int8_t, u_int8_t, char *, char *, 227 struct ike_auth *, char *); 228int add_sabundle(struct ipsec_rule *, char *); 229int get_id_type(char *); 230 231struct ipsec_transforms *ipsec_transforms; 232 233typedef struct { 234 union { 235 int64_t number; 236 u_int8_t ikemode; 237 u_int8_t dir; 238 u_int8_t satype; /* encapsulating prococol */ 239 u_int8_t proto; /* encapsulated protocol */ 240 u_int8_t tmode; 241 char *string; 242 u_int16_t port; 243 struct ipsec_hosts hosts; 244 struct ipsec_hosts peers; 245 struct ipsec_addr_wrap *anyhost; 246 struct ipsec_addr_wrap *singlehost; 247 struct ipsec_addr_wrap *host; 248 struct { 249 char *srcid; 250 char *dstid; 251 } ids; 252 char *id; 253 u_int8_t type; 254 struct ike_auth ikeauth; 255 struct { 256 u_int32_t spiout; 257 u_int32_t spiin; 258 } spis; 259 struct { 260 u_int8_t encap; 261 u_int16_t port; 262 } udpencap; 263 struct { 264 struct ipsec_key *keyout; 265 struct ipsec_key *keyin; 266 } authkeys; 267 struct { 268 struct ipsec_key *keyout; 269 struct ipsec_key *keyin; 270 } enckeys; 271 struct { 272 struct ipsec_key *keyout; 273 struct ipsec_key *keyin; 274 } keys; 275 struct ipsec_transforms *transforms; 276 struct ipsec_lifetime *life; 277 struct ike_mode *mode; 278 } v; 279 int lineno; 280} YYSTYPE; 281 282%} 283 284%token FLOW FROM ESP AH IN PEER ON OUT TO SRCID DSTID RSA PSK TCPMD5 SPI 285%token AUTHKEY ENCKEY FILENAME AUTHXF ENCXF ERROR IKE MAIN QUICK AGGRESSIVE 286%token PASSIVE ACTIVE ANY IPIP IPCOMP COMPXF TUNNEL TRANSPORT DYNAMIC LIFETIME 287%token TYPE DENY BYPASS LOCAL PROTO USE ACQUIRE REQUIRE DONTACQ GROUP PORT TAG 288%token INCLUDE BUNDLE UDPENCAP 289%token <v.string> STRING 290%token <v.number> NUMBER 291%type <v.string> string 292%type <v.dir> dir 293%type <v.satype> satype 294%type <v.proto> proto 295%type <v.number> protoval 296%type <v.tmode> tmode 297%type <v.hosts> hosts 298%type <v.port> port 299%type <v.number> portval 300%type <v.peers> peers 301%type <v.anyhost> anyhost 302%type <v.singlehost> singlehost 303%type <v.host> host host_list host_spec 304%type <v.ids> ids 305%type <v.id> id 306%type <v.spis> spispec 307%type <v.udpencap> udpencap 308%type <v.authkeys> authkeyspec 309%type <v.enckeys> enckeyspec 310%type <v.string> bundlestring 311%type <v.keys> keyspec 312%type <v.transforms> transforms 313%type <v.ikemode> ikemode 314%type <v.ikeauth> ikeauth 315%type <v.type> type 316%type <v.life> lifetime 317%type <v.mode> phase1mode phase2mode 318%type <v.string> tag 319%% 320 321grammar : /* empty */ 322 | grammar include '\n' 323 | grammar '\n' 324 | grammar ikerule '\n' 325 | grammar flowrule '\n' 326 | grammar sarule '\n' 327 | grammar tcpmd5rule '\n' 328 | grammar varset '\n' 329 | grammar error '\n' { file->errors++; } 330 ; 331 332comma : ',' 333 | /* empty */ 334 ; 335 336include : INCLUDE STRING { 337 struct file *nfile; 338 339 if ((nfile = pushfile($2, 0)) == NULL) { 340 yyerror("failed to include file %s", $2); 341 free($2); 342 YYERROR; 343 } 344 free($2); 345 346 file = nfile; 347 lungetc('\n'); 348 } 349 ; 350 351tcpmd5rule : TCPMD5 hosts spispec authkeyspec { 352 struct ipsec_rule *r; 353 354 r = create_sa(IPSEC_TCPMD5, IPSEC_TRANSPORT, &$2, 355 $3.spiout, 0, 0, NULL, $4.keyout, NULL); 356 if (r == NULL) 357 YYERROR; 358 359 if (expand_rule(r, NULL, 0, $3.spiin, $4.keyin, NULL, 360 NULL)) 361 errx(1, "tcpmd5rule: expand_rule"); 362 } 363 ; 364 365sarule : satype tmode hosts spispec udpencap transforms authkeyspec 366 enckeyspec bundlestring { 367 struct ipsec_rule *r; 368 369 r = create_sa($1, $2, &$3, $4.spiout, $5.encap, $5.port, 370 $6, $7.keyout, $8.keyout); 371 if (r == NULL) 372 YYERROR; 373 374 if (expand_rule(r, NULL, 0, $4.spiin, $7.keyin, 375 $8.keyin, $9)) 376 errx(1, "sarule: expand_rule"); 377 } 378 ; 379 380flowrule : FLOW satype dir proto hosts peers ids type { 381 struct ipsec_rule *r; 382 383 r = create_flow($3, $4, &$5, $2, $7.srcid, 384 $7.dstid, $8); 385 if (r == NULL) 386 YYERROR; 387 388 if (expand_rule(r, &$6, $3, 0, NULL, NULL, NULL)) 389 errx(1, "flowrule: expand_rule"); 390 } 391 ; 392 393ikerule : IKE ikemode satype tmode proto hosts peers 394 phase1mode phase2mode ids ikeauth tag { 395 struct ipsec_rule *r; 396 397 r = create_ike($5, &$6, $8, $9, $3, $4, $2, 398 $10.srcid, $10.dstid, &$11, $12); 399 if (r == NULL) 400 YYERROR; 401 402 if (expand_rule(r, &$7, 0, 0, NULL, NULL, NULL)) 403 errx(1, "ikerule: expand_rule"); 404 } 405 ; 406 407satype : /* empty */ { $$ = IPSEC_ESP; } 408 | ESP { $$ = IPSEC_ESP; } 409 | AH { $$ = IPSEC_AH; } 410 | IPCOMP { $$ = IPSEC_IPCOMP; } 411 | IPIP { $$ = IPSEC_IPIP; } 412 ; 413 414proto : /* empty */ { $$ = 0; } 415 | PROTO protoval { $$ = $2; } 416 | PROTO ESP { $$ = IPPROTO_ESP; } 417 | PROTO AH { $$ = IPPROTO_AH; } 418 ; 419 420protoval : STRING { 421 struct protoent *p; 422 423 p = getprotobyname($1); 424 if (p == NULL) { 425 yyerror("unknown protocol: %s", $1); 426 YYERROR; 427 } 428 $$ = p->p_proto; 429 free($1); 430 } 431 | NUMBER { 432 if ($1 > 255 || $1 < 0) { 433 yyerror("protocol outside range"); 434 YYERROR; 435 } 436 } 437 ; 438 439tmode : /* empty */ { $$ = IPSEC_TUNNEL; } 440 | TUNNEL { $$ = IPSEC_TUNNEL; } 441 | TRANSPORT { $$ = IPSEC_TRANSPORT; } 442 ; 443 444dir : /* empty */ { $$ = IPSEC_INOUT; } 445 | IN { $$ = IPSEC_IN; } 446 | OUT { $$ = IPSEC_OUT; } 447 ; 448 449hosts : FROM host port TO host port { 450 struct ipsec_addr_wrap *ipa; 451 for (ipa = $5; ipa; ipa = ipa->next) { 452 if (ipa->srcnat) { 453 yyerror("no flow NAT support for" 454 " destination network: %s", ipa->name); 455 YYERROR; 456 } 457 } 458 $$.src = $2; 459 $$.sport = $3; 460 $$.dst = $5; 461 $$.dport = $6; 462 } 463 | TO host port FROM host port { 464 struct ipsec_addr_wrap *ipa; 465 for (ipa = $2; ipa; ipa = ipa->next) { 466 if (ipa->srcnat) { 467 yyerror("no flow NAT support for" 468 " destination network: %s", ipa->name); 469 YYERROR; 470 } 471 } 472 $$.src = $5; 473 $$.sport = $6; 474 $$.dst = $2; 475 $$.dport = $3; 476 } 477 ; 478 479port : /* empty */ { $$ = 0; } 480 | PORT portval { $$ = $2; } 481 ; 482 483portval : STRING { 484 struct servent *s; 485 486 if ((s = getservbyname($1, "tcp")) != NULL || 487 (s = getservbyname($1, "udp")) != NULL) { 488 $$ = s->s_port; 489 } else { 490 yyerror("unknown port: %s", $1); 491 YYERROR; 492 } 493 } 494 | NUMBER { 495 if ($1 > USHRT_MAX || $1 < 0) { 496 yyerror("port outside range"); 497 YYERROR; 498 } 499 $$ = htons($1); 500 } 501 ; 502 503peers : /* empty */ { 504 $$.dst = NULL; 505 $$.src = NULL; 506 } 507 | PEER anyhost LOCAL singlehost { 508 $$.dst = $2; 509 $$.src = $4; 510 } 511 | LOCAL singlehost PEER anyhost { 512 $$.dst = $4; 513 $$.src = $2; 514 } 515 | PEER anyhost { 516 $$.dst = $2; 517 $$.src = NULL; 518 } 519 | LOCAL singlehost { 520 $$.dst = NULL; 521 $$.src = $2; 522 } 523 ; 524 525anyhost : singlehost { $$ = $1; } 526 | ANY { 527 $$ = host_any(); 528 } 529 530singlehost : /* empty */ { $$ = NULL; } 531 | STRING { 532 if (($$ = host($1)) == NULL) { 533 free($1); 534 yyerror("could not parse host specification"); 535 YYERROR; 536 } 537 free($1); 538 } 539 ; 540 541host_list : host { $$ = $1; } 542 | host_list comma host { 543 if ($3 == NULL) 544 $$ = $1; 545 else if ($1 == NULL) 546 $$ = $3; 547 else { 548 $1->tail->next = $3; 549 $1->tail = $3->tail; 550 $$ = $1; 551 } 552 } 553 ; 554 555host_spec : STRING { 556 if (($$ = host($1)) == NULL) { 557 free($1); 558 yyerror("could not parse host specification"); 559 YYERROR; 560 } 561 free($1); 562 } 563 | STRING '/' NUMBER { 564 char *buf; 565 566 if (asprintf(&buf, "%s/%lld", $1, $3) == -1) 567 err(1, "host: asprintf"); 568 free($1); 569 if (($$ = host(buf)) == NULL) { 570 free(buf); 571 yyerror("could not parse host specification"); 572 YYERROR; 573 } 574 free(buf); 575 } 576 ; 577 578host : host_spec { $$ = $1; } 579 | host_spec '(' host_spec ')' { 580 if ($3->af != $1->af) { 581 yyerror("Flow NAT address family mismatch"); 582 YYERROR; 583 } 584 $$ = $1; 585 $$->srcnat = $3; 586 } 587 | ANY { 588 $$ = host_any(); 589 } 590 | '{' host_list '}' { $$ = $2; } 591 ; 592 593ids : /* empty */ { 594 $$.srcid = NULL; 595 $$.dstid = NULL; 596 } 597 | SRCID id DSTID id { 598 $$.srcid = $2; 599 $$.dstid = $4; 600 } 601 | SRCID id { 602 $$.srcid = $2; 603 $$.dstid = NULL; 604 } 605 | DSTID id { 606 $$.srcid = NULL; 607 $$.dstid = $2; 608 } 609 ; 610 611type : /* empty */ { 612 $$ = TYPE_UNKNOWN; 613 } 614 | TYPE USE { 615 $$ = TYPE_USE; 616 } 617 | TYPE ACQUIRE { 618 $$ = TYPE_ACQUIRE; 619 } 620 | TYPE REQUIRE { 621 $$ = TYPE_REQUIRE; 622 } 623 | TYPE DENY { 624 $$ = TYPE_DENY; 625 } 626 | TYPE BYPASS { 627 $$ = TYPE_BYPASS; 628 } 629 | TYPE DONTACQ { 630 $$ = TYPE_DONTACQ; 631 } 632 ; 633 634id : STRING { $$ = $1; } 635 ; 636 637spispec : SPI STRING { 638 u_int32_t spi; 639 char *p = strchr($2, ':'); 640 641 if (p != NULL) { 642 *p++ = 0; 643 644 if (atospi(p, &spi) == -1) { 645 free($2); 646 YYERROR; 647 } 648 $$.spiin = spi; 649 } else 650 $$.spiin = 0; 651 652 if (atospi($2, &spi) == -1) { 653 free($2); 654 YYERROR; 655 } 656 $$.spiout = spi; 657 658 659 free($2); 660 } 661 | SPI NUMBER { 662 if ($2 > UINT_MAX || $2 < 0) { 663 yyerror("%lld not a valid spi", $2); 664 YYERROR; 665 } 666 if ($2 >= SPI_RESERVED_MIN && $2 <= SPI_RESERVED_MAX) { 667 yyerror("%lld within reserved spi range", $2); 668 YYERROR; 669 } 670 671 $$.spiin = 0; 672 $$.spiout = $2; 673 } 674 ; 675 676udpencap : /* empty */ { 677 $$.encap = 0; 678 } 679 | UDPENCAP { 680 $$.encap = 1; 681 $$.port = 0; 682 } 683 | UDPENCAP PORT NUMBER { 684 $$.encap = 1; 685 $$.port = $3; 686 } 687 ; 688 689transforms : { 690 if ((ipsec_transforms = calloc(1, 691 sizeof(struct ipsec_transforms))) == NULL) 692 err(1, "transforms: calloc"); 693 } 694 transforms_l 695 { $$ = ipsec_transforms; } 696 | /* empty */ { 697 if (($$ = calloc(1, 698 sizeof(struct ipsec_transforms))) == NULL) 699 err(1, "transforms: calloc"); 700 } 701 ; 702 703transforms_l : transforms_l transform 704 | transform 705 ; 706 707transform : AUTHXF STRING { 708 if (ipsec_transforms->authxf) 709 yyerror("auth already set"); 710 else { 711 ipsec_transforms->authxf = parse_xf($2, 712 authxfs); 713 if (!ipsec_transforms->authxf) 714 yyerror("%s not a valid transform", $2); 715 } 716 } 717 | ENCXF STRING { 718 if (ipsec_transforms->encxf) 719 yyerror("enc already set"); 720 else { 721 ipsec_transforms->encxf = parse_xf($2, encxfs); 722 if (!ipsec_transforms->encxf) 723 yyerror("%s not a valid transform", $2); 724 } 725 } 726 | COMPXF STRING { 727 if (ipsec_transforms->compxf) 728 yyerror("comp already set"); 729 else { 730 ipsec_transforms->compxf = parse_xf($2, 731 compxfs); 732 if (!ipsec_transforms->compxf) 733 yyerror("%s not a valid transform", $2); 734 } 735 } 736 | GROUP STRING { 737 if (ipsec_transforms->groupxf) 738 yyerror("group already set"); 739 else { 740 ipsec_transforms->groupxf = parse_xf($2, 741 groupxfs); 742 if (!ipsec_transforms->groupxf) 743 yyerror("%s not a valid transform", $2); 744 } 745 } 746 ; 747 748phase1mode : /* empty */ { 749 struct ike_mode *p1; 750 751 /* We create just an empty main mode */ 752 if ((p1 = calloc(1, sizeof(struct ike_mode))) == NULL) 753 err(1, "phase1mode: calloc"); 754 p1->ike_exch = IKE_MM; 755 $$ = p1; 756 } 757 | MAIN transforms lifetime { 758 struct ike_mode *p1; 759 760 if ((p1 = calloc(1, sizeof(struct ike_mode))) == NULL) 761 err(1, "phase1mode: calloc"); 762 p1->xfs = $2; 763 p1->life = $3; 764 p1->ike_exch = IKE_MM; 765 $$ = p1; 766 } 767 | AGGRESSIVE transforms lifetime { 768 struct ike_mode *p1; 769 770 if ((p1 = calloc(1, sizeof(struct ike_mode))) == NULL) 771 err(1, "phase1mode: calloc"); 772 p1->xfs = $2; 773 p1->life = $3; 774 p1->ike_exch = IKE_AM; 775 $$ = p1; 776 } 777 ; 778 779phase2mode : /* empty */ { 780 struct ike_mode *p2; 781 782 /* We create just an empty quick mode */ 783 if ((p2 = calloc(1, sizeof(struct ike_mode))) == NULL) 784 err(1, "phase2mode: calloc"); 785 p2->ike_exch = IKE_QM; 786 $$ = p2; 787 } 788 | QUICK transforms lifetime { 789 struct ike_mode *p2; 790 791 if ((p2 = calloc(1, sizeof(struct ike_mode))) == NULL) 792 err(1, "phase2mode: calloc"); 793 p2->xfs = $2; 794 p2->life = $3; 795 p2->ike_exch = IKE_QM; 796 $$ = p2; 797 } 798 ; 799 800lifetime : /* empty */ { 801 struct ipsec_lifetime *life; 802 803 /* We create just an empty transform */ 804 if ((life = calloc(1, sizeof(struct ipsec_lifetime))) 805 == NULL) 806 err(1, "life: calloc"); 807 life->lt_seconds = -1; 808 life->lt_bytes = -1; 809 $$ = life; 810 } 811 | LIFETIME NUMBER { 812 struct ipsec_lifetime *life; 813 814 if ((life = calloc(1, sizeof(struct ipsec_lifetime))) 815 == NULL) 816 err(1, "life: calloc"); 817 life->lt_seconds = $2; 818 life->lt_bytes = -1; 819 $$ = life; 820 } 821 | LIFETIME STRING { 822 $$ = parse_life($2); 823 } 824 ; 825 826authkeyspec : /* empty */ { 827 $$.keyout = NULL; 828 $$.keyin = NULL; 829 } 830 | AUTHKEY keyspec { 831 $$.keyout = $2.keyout; 832 $$.keyin = $2.keyin; 833 } 834 ; 835 836enckeyspec : /* empty */ { 837 $$.keyout = NULL; 838 $$.keyin = NULL; 839 } 840 | ENCKEY keyspec { 841 $$.keyout = $2.keyout; 842 $$.keyin = $2.keyin; 843 } 844 ; 845 846bundlestring : /* empty */ { $$ = NULL; } 847 | BUNDLE STRING { $$ = $2; } 848 ; 849 850keyspec : STRING { 851 unsigned char *hex; 852 unsigned char *p = strchr($1, ':'); 853 854 if (p != NULL ) { 855 *p++ = 0; 856 857 if (!strncmp(p, "0x", 2)) 858 p += 2; 859 $$.keyin = parsekey(p, strlen(p)); 860 } else 861 $$.keyin = NULL; 862 863 hex = $1; 864 if (!strncmp(hex, "0x", 2)) 865 hex += 2; 866 $$.keyout = parsekey(hex, strlen(hex)); 867 868 free($1); 869 } 870 | FILENAME STRING { 871 unsigned char *p = strchr($2, ':'); 872 873 if (p != NULL) { 874 *p++ = 0; 875 $$.keyin = parsekeyfile(p); 876 } 877 $$.keyout = parsekeyfile($2); 878 free($2); 879 } 880 ; 881 882ikemode : /* empty */ { $$ = IKE_ACTIVE; } 883 | PASSIVE { $$ = IKE_PASSIVE; } 884 | DYNAMIC { $$ = IKE_DYNAMIC; } 885 | ACTIVE { $$ = IKE_ACTIVE; } 886 ; 887 888ikeauth : /* empty */ { 889 $$.type = IKE_AUTH_RSA; 890 $$.string = NULL; 891 } 892 | RSA { 893 $$.type = IKE_AUTH_RSA; 894 $$.string = NULL; 895 } 896 | PSK STRING { 897 $$.type = IKE_AUTH_PSK; 898 if (($$.string = strdup($2)) == NULL) 899 err(1, "ikeauth: strdup"); 900 } 901 ; 902 903tag : /* empty */ 904 { 905 $$ = NULL; 906 } 907 | TAG STRING 908 { 909 $$ = $2; 910 } 911 ; 912 913string : string STRING 914 { 915 if (asprintf(&$$, "%s %s", $1, $2) == -1) 916 err(1, "string: asprintf"); 917 free($1); 918 free($2); 919 } 920 | STRING 921 ; 922 923varset : STRING '=' string 924 { 925 char *s = $1; 926 if (ipsec->opts & IPSECCTL_OPT_VERBOSE) 927 printf("%s = \"%s\"\n", $1, $3); 928 while (*s++) { 929 if (isspace((unsigned char)*s)) { 930 yyerror("macro name cannot contain " 931 "whitespace"); 932 free($1); 933 free($3); 934 YYERROR; 935 } 936 } 937 if (symset($1, $3, 0) == -1) 938 err(1, "cannot store variable"); 939 free($1); 940 free($3); 941 } 942 ; 943 944%% 945 946struct keywords { 947 const char *k_name; 948 int k_val; 949}; 950 951int 952yyerror(const char *fmt, ...) 953{ 954 va_list ap; 955 956 file->errors++; 957 va_start(ap, fmt); 958 fprintf(stderr, "%s: %d: ", file->name, yylval.lineno); 959 vfprintf(stderr, fmt, ap); 960 fprintf(stderr, "\n"); 961 va_end(ap); 962 return (0); 963} 964 965int 966yywarn(const char *fmt, ...) 967{ 968 va_list ap; 969 970 va_start(ap, fmt); 971 fprintf(stderr, "%s: %d: ", file->name, yylval.lineno); 972 vfprintf(stderr, fmt, ap); 973 fprintf(stderr, "\n"); 974 va_end(ap); 975 return (0); 976} 977 978int 979kw_cmp(const void *k, const void *e) 980{ 981 return (strcmp(k, ((const struct keywords *)e)->k_name)); 982} 983 984int 985lookup(char *s) 986{ 987 /* this has to be sorted always */ 988 static const struct keywords keywords[] = { 989 { "acquire", ACQUIRE }, 990 { "active", ACTIVE }, 991 { "aggressive", AGGRESSIVE }, 992 { "ah", AH }, 993 { "any", ANY }, 994 { "auth", AUTHXF }, 995 { "authkey", AUTHKEY }, 996 { "bundle", BUNDLE }, 997 { "bypass", BYPASS }, 998 { "comp", COMPXF }, 999 { "deny", DENY }, 1000 { "dontacq", DONTACQ }, 1001 { "dstid", DSTID }, 1002 { "dynamic", DYNAMIC }, 1003 { "enc", ENCXF }, 1004 { "enckey", ENCKEY }, 1005 { "esp", ESP }, 1006 { "file", FILENAME }, 1007 { "flow", FLOW }, 1008 { "from", FROM }, 1009 { "group", GROUP }, 1010 { "ike", IKE }, 1011 { "in", IN }, 1012 { "include", INCLUDE }, 1013 { "ipcomp", IPCOMP }, 1014 { "ipip", IPIP }, 1015 { "lifetime", LIFETIME }, 1016 { "local", LOCAL }, 1017 { "main", MAIN }, 1018 { "out", OUT }, 1019 { "passive", PASSIVE }, 1020 { "peer", PEER }, 1021 { "port", PORT }, 1022 { "proto", PROTO }, 1023 { "psk", PSK }, 1024 { "quick", QUICK }, 1025 { "require", REQUIRE }, 1026 { "rsa", RSA }, 1027 { "spi", SPI }, 1028 { "srcid", SRCID }, 1029 { "tag", TAG }, 1030 { "tcpmd5", TCPMD5 }, 1031 { "to", TO }, 1032 { "transport", TRANSPORT }, 1033 { "tunnel", TUNNEL }, 1034 { "type", TYPE }, 1035 { "udpencap", UDPENCAP }, 1036 { "use", USE } 1037 }; 1038 const struct keywords *p; 1039 1040 p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]), 1041 sizeof(keywords[0]), kw_cmp); 1042 1043 if (p) { 1044 if (debug > 1) 1045 fprintf(stderr, "%s: %d\n", s, p->k_val); 1046 return (p->k_val); 1047 } else { 1048 if (debug > 1) 1049 fprintf(stderr, "string: %s\n", s); 1050 return (STRING); 1051 } 1052} 1053 1054#define MAXPUSHBACK 128 1055 1056char *parsebuf; 1057int parseindex; 1058char pushback_buffer[MAXPUSHBACK]; 1059int pushback_index = 0; 1060 1061int 1062lgetc(int quotec) 1063{ 1064 int c, next; 1065 1066 if (parsebuf) { 1067 /* Read character from the parsebuffer instead of input. */ 1068 if (parseindex >= 0) { 1069 c = (unsigned char)parsebuf[parseindex++]; 1070 if (c != '\0') 1071 return (c); 1072 parsebuf = NULL; 1073 } else 1074 parseindex++; 1075 } 1076 1077 if (pushback_index) 1078 return ((unsigned char)pushback_buffer[--pushback_index]); 1079 1080 if (quotec) { 1081 if ((c = getc(file->stream)) == EOF) { 1082 yyerror("reached end of file while parsing quoted string"); 1083 if (file == topfile || popfile() == EOF) 1084 return (EOF); 1085 return (quotec); 1086 } 1087 return (c); 1088 } 1089 1090 while ((c = getc(file->stream)) == '\\') { 1091 next = getc(file->stream); 1092 if (next != '\n') { 1093 c = next; 1094 break; 1095 } 1096 yylval.lineno = file->lineno; 1097 file->lineno++; 1098 } 1099 1100 while (c == EOF) { 1101 if (file == topfile || popfile() == EOF) 1102 return (EOF); 1103 c = getc(file->stream); 1104 } 1105 return (c); 1106} 1107 1108int 1109lungetc(int c) 1110{ 1111 if (c == EOF) 1112 return (EOF); 1113 if (parsebuf) { 1114 parseindex--; 1115 if (parseindex >= 0) 1116 return (c); 1117 } 1118 if (pushback_index + 1 >= MAXPUSHBACK) 1119 return (EOF); 1120 pushback_buffer[pushback_index++] = c; 1121 return (c); 1122} 1123 1124int 1125findeol(void) 1126{ 1127 int c; 1128 1129 parsebuf = NULL; 1130 1131 /* skip to either EOF or the first real EOL */ 1132 while (1) { 1133 if (pushback_index) 1134 c = (unsigned char)pushback_buffer[--pushback_index]; 1135 else 1136 c = lgetc(0); 1137 if (c == '\n') { 1138 file->lineno++; 1139 break; 1140 } 1141 if (c == EOF) 1142 break; 1143 } 1144 return (ERROR); 1145} 1146 1147int 1148yylex(void) 1149{ 1150 char buf[8096]; 1151 char *p, *val; 1152 int quotec, next, c; 1153 int token; 1154 1155top: 1156 p = buf; 1157 while ((c = lgetc(0)) == ' ' || c == '\t') 1158 ; /* nothing */ 1159 1160 yylval.lineno = file->lineno; 1161 if (c == '#') 1162 while ((c = lgetc(0)) != '\n' && c != EOF) 1163 ; /* nothing */ 1164 if (c == '$' && parsebuf == NULL) { 1165 while (1) { 1166 if ((c = lgetc(0)) == EOF) 1167 return (0); 1168 1169 if (p + 1 >= buf + sizeof(buf) - 1) { 1170 yyerror("string too long"); 1171 return (findeol()); 1172 } 1173 if (isalnum(c) || c == '_') { 1174 *p++ = c; 1175 continue; 1176 } 1177 *p = '\0'; 1178 lungetc(c); 1179 break; 1180 } 1181 val = symget(buf); 1182 if (val == NULL) { 1183 yyerror("macro '%s' not defined", buf); 1184 return (findeol()); 1185 } 1186 parsebuf = val; 1187 parseindex = 0; 1188 goto top; 1189 } 1190 1191 switch (c) { 1192 case '\'': 1193 case '"': 1194 quotec = c; 1195 while (1) { 1196 if ((c = lgetc(quotec)) == EOF) 1197 return (0); 1198 if (c == '\n') { 1199 file->lineno++; 1200 continue; 1201 } else if (c == '\\') { 1202 if ((next = lgetc(quotec)) == EOF) 1203 return (0); 1204 if (next == quotec || next == ' ' || 1205 next == '\t') 1206 c = next; 1207 else if (next == '\n') { 1208 file->lineno++; 1209 continue; 1210 } else 1211 lungetc(next); 1212 } else if (c == quotec) { 1213 *p = '\0'; 1214 break; 1215 } else if (c == '\0') { 1216 yyerror("syntax error"); 1217 return (findeol()); 1218 } 1219 if (p + 1 >= buf + sizeof(buf) - 1) { 1220 yyerror("string too long"); 1221 return (findeol()); 1222 } 1223 *p++ = c; 1224 } 1225 yylval.v.string = strdup(buf); 1226 if (yylval.v.string == NULL) 1227 err(1, "%s", __func__); 1228 return (STRING); 1229 } 1230 1231#define allowed_to_end_number(x) \ 1232 (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=') 1233 1234 if (c == '-' || isdigit(c)) { 1235 do { 1236 *p++ = c; 1237 if ((size_t)(p-buf) >= sizeof(buf)) { 1238 yyerror("string too long"); 1239 return (findeol()); 1240 } 1241 } while ((c = lgetc(0)) != EOF && isdigit(c)); 1242 lungetc(c); 1243 if (p == buf + 1 && buf[0] == '-') 1244 goto nodigits; 1245 if (c == EOF || allowed_to_end_number(c)) { 1246 const char *errstr = NULL; 1247 1248 *p = '\0'; 1249 yylval.v.number = strtonum(buf, LLONG_MIN, 1250 LLONG_MAX, &errstr); 1251 if (errstr) { 1252 yyerror("\"%s\" invalid number: %s", 1253 buf, errstr); 1254 return (findeol()); 1255 } 1256 return (NUMBER); 1257 } else { 1258nodigits: 1259 while (p > buf + 1) 1260 lungetc((unsigned char)*--p); 1261 c = (unsigned char)*--p; 1262 if (c == '-') 1263 return (c); 1264 } 1265 } 1266 1267#define allowed_in_string(x) \ 1268 (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \ 1269 x != '{' && x != '}' && x != '<' && x != '>' && \ 1270 x != '!' && x != '=' && x != '/' && x != '#' && \ 1271 x != ',')) 1272 1273 if (isalnum(c) || c == ':' || c == '_' || c == '*') { 1274 do { 1275 *p++ = c; 1276 if ((size_t)(p-buf) >= sizeof(buf)) { 1277 yyerror("string too long"); 1278 return (findeol()); 1279 } 1280 } while ((c = lgetc(0)) != EOF && (allowed_in_string(c))); 1281 lungetc(c); 1282 *p = '\0'; 1283 if ((token = lookup(buf)) == STRING) 1284 if ((yylval.v.string = strdup(buf)) == NULL) 1285 err(1, "%s", __func__); 1286 return (token); 1287 } 1288 if (c == '\n') { 1289 yylval.lineno = file->lineno; 1290 file->lineno++; 1291 } 1292 if (c == EOF) 1293 return (0); 1294 return (c); 1295} 1296 1297int 1298check_file_secrecy(int fd, const char *fname) 1299{ 1300 struct stat st; 1301 1302 if (fstat(fd, &st)) { 1303 warn("cannot stat %s", fname); 1304 return (-1); 1305 } 1306 if (st.st_uid != 0 && st.st_uid != getuid()) { 1307 warnx("%s: owner not root or current user", fname); 1308 return (-1); 1309 } 1310 if (st.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)) { 1311 warnx("%s: group writable or world read/writable", fname); 1312 return (-1); 1313 } 1314 return (0); 1315} 1316 1317struct file * 1318pushfile(const char *name, int secret) 1319{ 1320 struct file *nfile; 1321 1322 if ((nfile = calloc(1, sizeof(struct file))) == NULL) { 1323 warn("%s", __func__); 1324 return (NULL); 1325 } 1326 if ((nfile->name = strdup(name)) == NULL) { 1327 warn("%s", __func__); 1328 free(nfile); 1329 return (NULL); 1330 } 1331 if (TAILQ_FIRST(&files) == NULL && strcmp(nfile->name, "-") == 0) { 1332 nfile->stream = stdin; 1333 free(nfile->name); 1334 if ((nfile->name = strdup("stdin")) == NULL) { 1335 warn("%s", __func__); 1336 free(nfile); 1337 return (NULL); 1338 } 1339 } else if ((nfile->stream = fopen(nfile->name, "r")) == NULL) { 1340 warn("%s: %s", __func__, nfile->name); 1341 free(nfile->name); 1342 free(nfile); 1343 return (NULL); 1344 } else if (secret && 1345 check_file_secrecy(fileno(nfile->stream), nfile->name)) { 1346 fclose(nfile->stream); 1347 free(nfile->name); 1348 free(nfile); 1349 return (NULL); 1350 } 1351 nfile->lineno = 1; 1352 TAILQ_INSERT_TAIL(&files, nfile, entry); 1353 return (nfile); 1354} 1355 1356int 1357popfile(void) 1358{ 1359 struct file *prev; 1360 1361 if ((prev = TAILQ_PREV(file, files, entry)) != NULL) 1362 prev->errors += file->errors; 1363 1364 TAILQ_REMOVE(&files, file, entry); 1365 fclose(file->stream); 1366 free(file->name); 1367 free(file); 1368 file = prev; 1369 1370 return (file ? 0 : EOF); 1371} 1372 1373int 1374parse_rules(const char *filename, struct ipsecctl *ipsecx) 1375{ 1376 struct sym *sym; 1377 int errors = 0; 1378 1379 ipsec = ipsecx; 1380 1381 if ((file = pushfile(filename, 1)) == NULL) { 1382 return (-1); 1383 } 1384 topfile = file; 1385 1386 yyparse(); 1387 errors = file->errors; 1388 popfile(); 1389 1390 /* Free macros and check which have not been used. */ 1391 while ((sym = TAILQ_FIRST(&symhead))) { 1392 if ((ipsec->opts & IPSECCTL_OPT_VERBOSE2) && !sym->used) 1393 fprintf(stderr, "warning: macro '%s' not " 1394 "used\n", sym->nam); 1395 free(sym->nam); 1396 free(sym->val); 1397 TAILQ_REMOVE(&symhead, sym, entry); 1398 free(sym); 1399 } 1400 1401 return (errors ? -1 : 0); 1402} 1403 1404int 1405symset(const char *nam, const char *val, int persist) 1406{ 1407 struct sym *sym; 1408 1409 TAILQ_FOREACH(sym, &symhead, entry) { 1410 if (strcmp(nam, sym->nam) == 0) 1411 break; 1412 } 1413 1414 if (sym != NULL) { 1415 if (sym->persist == 1) 1416 return (0); 1417 else { 1418 free(sym->nam); 1419 free(sym->val); 1420 TAILQ_REMOVE(&symhead, sym, entry); 1421 free(sym); 1422 } 1423 } 1424 if ((sym = calloc(1, sizeof(*sym))) == NULL) 1425 return (-1); 1426 1427 sym->nam = strdup(nam); 1428 if (sym->nam == NULL) { 1429 free(sym); 1430 return (-1); 1431 } 1432 sym->val = strdup(val); 1433 if (sym->val == NULL) { 1434 free(sym->nam); 1435 free(sym); 1436 return (-1); 1437 } 1438 sym->used = 0; 1439 sym->persist = persist; 1440 TAILQ_INSERT_TAIL(&symhead, sym, entry); 1441 return (0); 1442} 1443 1444int 1445cmdline_symset(char *s) 1446{ 1447 char *sym, *val; 1448 int ret; 1449 1450 if ((val = strrchr(s, '=')) == NULL) 1451 return (-1); 1452 1453 sym = strndup(s, val - s); 1454 if (sym == NULL) 1455 err(1, "%s", __func__); 1456 ret = symset(sym, val + 1, 1); 1457 free(sym); 1458 1459 return (ret); 1460} 1461 1462char * 1463symget(const char *nam) 1464{ 1465 struct sym *sym; 1466 1467 TAILQ_FOREACH(sym, &symhead, entry) { 1468 if (strcmp(nam, sym->nam) == 0) { 1469 sym->used = 1; 1470 return (sym->val); 1471 } 1472 } 1473 return (NULL); 1474} 1475 1476int 1477atoul(char *s, u_long *ulvalp) 1478{ 1479 u_long ulval; 1480 char *ep; 1481 1482 errno = 0; 1483 ulval = strtoul(s, &ep, 0); 1484 if (s[0] == '\0' || *ep != '\0') 1485 return (-1); 1486 if (errno == ERANGE && ulval == ULONG_MAX) 1487 return (-1); 1488 *ulvalp = ulval; 1489 return (0); 1490} 1491 1492int 1493atospi(char *s, u_int32_t *spivalp) 1494{ 1495 unsigned long ulval; 1496 1497 if (atoul(s, &ulval) == -1) 1498 return (-1); 1499 if (ulval > UINT_MAX) { 1500 yyerror("%lu not a valid spi", ulval); 1501 return (-1); 1502 } 1503 if (ulval >= SPI_RESERVED_MIN && ulval <= SPI_RESERVED_MAX) { 1504 yyerror("%lu within reserved spi range", ulval); 1505 return (-1); 1506 } 1507 *spivalp = ulval; 1508 return (0); 1509} 1510 1511u_int8_t 1512x2i(unsigned char *s) 1513{ 1514 char ss[3]; 1515 1516 ss[0] = s[0]; 1517 ss[1] = s[1]; 1518 ss[2] = 0; 1519 1520 if (!isxdigit(s[0]) || !isxdigit(s[1])) { 1521 yyerror("keys need to be specified in hex digits"); 1522 return (-1); 1523 } 1524 return ((u_int8_t)strtoul(ss, NULL, 16)); 1525} 1526 1527struct ipsec_key * 1528parsekey(unsigned char *hexkey, size_t len) 1529{ 1530 struct ipsec_key *key; 1531 int i; 1532 1533 key = calloc(1, sizeof(struct ipsec_key)); 1534 if (key == NULL) 1535 err(1, "%s", __func__); 1536 1537 key->len = len / 2; 1538 key->data = calloc(key->len, sizeof(u_int8_t)); 1539 if (key->data == NULL) 1540 err(1, "%s", __func__); 1541 1542 for (i = 0; i < (int)key->len; i++) 1543 key->data[i] = x2i(hexkey + 2 * i); 1544 1545 return (key); 1546} 1547 1548struct ipsec_key * 1549parsekeyfile(char *filename) 1550{ 1551 struct stat sb; 1552 int fd; 1553 unsigned char *hex; 1554 1555 if ((fd = open(filename, O_RDONLY)) < 0) 1556 err(1, "open %s", filename); 1557 if (fstat(fd, &sb) < 0) 1558 err(1, "parsekeyfile: stat %s", filename); 1559 if ((sb.st_size > KEYSIZE_LIMIT) || (sb.st_size == 0)) 1560 errx(1, "%s: key too %s", filename, sb.st_size ? "large" : 1561 "small"); 1562 if ((hex = calloc(sb.st_size, sizeof(unsigned char))) == NULL) 1563 err(1, "%s", __func__); 1564 if (read(fd, hex, sb.st_size) < sb.st_size) 1565 err(1, "parsekeyfile: read"); 1566 close(fd); 1567 return (parsekey(hex, sb.st_size)); 1568} 1569 1570int 1571get_id_type(char *string) 1572{ 1573 struct in6_addr ia; 1574 1575 if (string == NULL) 1576 return (ID_UNKNOWN); 1577 1578 if (inet_pton(AF_INET, string, &ia) == 1) 1579 return (ID_IPV4); 1580 else if (inet_pton(AF_INET6, string, &ia) == 1) 1581 return (ID_IPV6); 1582 else if (strchr(string, '@')) 1583 return (ID_UFQDN); 1584 else 1585 return (ID_FQDN); 1586} 1587 1588struct ipsec_addr_wrap * 1589host(const char *s) 1590{ 1591 struct ipsec_addr_wrap *ipa = NULL; 1592 int mask, cont = 1; 1593 char *p, *q, *ps; 1594 1595 if ((p = strrchr(s, '/')) != NULL) { 1596 errno = 0; 1597 mask = strtol(p + 1, &q, 0); 1598 if (errno == ERANGE || !q || *q || mask > 128 || q == (p + 1)) 1599 errx(1, "host: invalid netmask '%s'", p); 1600 if ((ps = malloc(strlen(s) - strlen(p) + 1)) == NULL) 1601 err(1, "%s", __func__); 1602 strlcpy(ps, s, strlen(s) - strlen(p) + 1); 1603 } else { 1604 if ((ps = strdup(s)) == NULL) 1605 err(1, "%s", __func__); 1606 mask = -1; 1607 } 1608 1609 /* Does interface with this name exist? */ 1610 if (cont && (ipa = host_if(ps, mask)) != NULL) 1611 cont = 0; 1612 1613 /* IPv4 address? */ 1614 if (cont && (ipa = host_v4(s, mask == -1 ? 32 : mask)) != NULL) 1615 cont = 0; 1616 1617 /* IPv6 address? */ 1618 if (cont && (ipa = host_v6(ps, mask == -1 ? 128 : mask)) != NULL) 1619 cont = 0; 1620 1621 /* dns lookup */ 1622 if (cont && mask == -1 && (ipa = host_dns(s, mask)) != NULL) 1623 cont = 0; 1624 free(ps); 1625 1626 if (ipa == NULL || cont == 1) { 1627 fprintf(stderr, "no IP address found for %s\n", s); 1628 return (NULL); 1629 } 1630 return (ipa); 1631} 1632 1633struct ipsec_addr_wrap * 1634host_v6(const char *s, int prefixlen) 1635{ 1636 struct ipsec_addr_wrap *ipa = NULL; 1637 struct addrinfo hints, *res; 1638 char hbuf[NI_MAXHOST]; 1639 1640 bzero(&hints, sizeof(struct addrinfo)); 1641 hints.ai_family = AF_INET6; 1642 hints.ai_socktype = SOCK_STREAM; 1643 hints.ai_flags = AI_NUMERICHOST; 1644 if (getaddrinfo(s, NULL, &hints, &res)) 1645 return (NULL); 1646 if (res->ai_next) 1647 err(1, "host_v6: numeric hostname expanded to multiple item"); 1648 1649 ipa = calloc(1, sizeof(struct ipsec_addr_wrap)); 1650 if (ipa == NULL) 1651 err(1, "%s", __func__); 1652 ipa->af = res->ai_family; 1653 memcpy(&ipa->address.v6, 1654 &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 1655 sizeof(struct in6_addr)); 1656 if (prefixlen > 128) 1657 prefixlen = 128; 1658 ipa->next = NULL; 1659 ipa->tail = ipa; 1660 1661 set_ipmask(ipa, prefixlen); 1662 if (getnameinfo(res->ai_addr, res->ai_addrlen, 1663 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) { 1664 errx(1, "could not get a numeric hostname"); 1665 } 1666 1667 if (prefixlen != 128) { 1668 ipa->netaddress = 1; 1669 if (asprintf(&ipa->name, "%s/%d", hbuf, prefixlen) == -1) 1670 err(1, "%s", __func__); 1671 } else { 1672 if ((ipa->name = strdup(hbuf)) == NULL) 1673 err(1, "%s", __func__); 1674 } 1675 1676 freeaddrinfo(res); 1677 1678 return (ipa); 1679} 1680 1681struct ipsec_addr_wrap * 1682host_v4(const char *s, int mask) 1683{ 1684 struct ipsec_addr_wrap *ipa = NULL; 1685 struct in_addr ina; 1686 int bits = 32; 1687 1688 bzero(&ina, sizeof(struct in_addr)); 1689 if (strrchr(s, '/') != NULL) { 1690 if ((bits = inet_net_pton(AF_INET, s, &ina, sizeof(ina))) == -1) 1691 return (NULL); 1692 } else { 1693 if (inet_pton(AF_INET, s, &ina) != 1) 1694 return (NULL); 1695 } 1696 1697 ipa = calloc(1, sizeof(struct ipsec_addr_wrap)); 1698 if (ipa == NULL) 1699 err(1, "%s", __func__); 1700 1701 ipa->address.v4 = ina; 1702 ipa->name = strdup(s); 1703 if (ipa->name == NULL) 1704 err(1, "%s", __func__); 1705 ipa->af = AF_INET; 1706 ipa->next = NULL; 1707 ipa->tail = ipa; 1708 1709 set_ipmask(ipa, bits); 1710 if (strrchr(s, '/') != NULL) 1711 ipa->netaddress = 1; 1712 1713 return (ipa); 1714} 1715 1716struct ipsec_addr_wrap * 1717host_dns(const char *s, int mask) 1718{ 1719 struct ipsec_addr_wrap *ipa = NULL, *head = NULL; 1720 struct addrinfo hints, *res0, *res; 1721 int error; 1722 char hbuf[NI_MAXHOST]; 1723 1724 bzero(&hints, sizeof(struct addrinfo)); 1725 hints.ai_family = PF_UNSPEC; 1726 hints.ai_socktype = SOCK_STREAM; 1727 error = getaddrinfo(s, NULL, &hints, &res0); 1728 if (error) 1729 return (NULL); 1730 1731 for (res = res0; res; res = res->ai_next) { 1732 if (res->ai_family != AF_INET && res->ai_family != AF_INET6) 1733 continue; 1734 1735 ipa = calloc(1, sizeof(struct ipsec_addr_wrap)); 1736 if (ipa == NULL) 1737 err(1, "%s", __func__); 1738 switch (res->ai_family) { 1739 case AF_INET: 1740 memcpy(&ipa->address.v4, 1741 &((struct sockaddr_in *)res->ai_addr)->sin_addr, 1742 sizeof(struct in_addr)); 1743 break; 1744 case AF_INET6: 1745 /* XXX we do not support scoped IPv6 address yet */ 1746 if (((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id) { 1747 free(ipa); 1748 continue; 1749 } 1750 memcpy(&ipa->address.v6, 1751 &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 1752 sizeof(struct in6_addr)); 1753 break; 1754 } 1755 error = getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, 1756 sizeof(hbuf), NULL, 0, NI_NUMERICHOST); 1757 if (error) 1758 err(1, "host_dns: getnameinfo"); 1759 ipa->name = strdup(hbuf); 1760 if (ipa->name == NULL) 1761 err(1, "%s", __func__); 1762 ipa->af = res->ai_family; 1763 ipa->next = NULL; 1764 ipa->tail = ipa; 1765 if (head == NULL) 1766 head = ipa; 1767 else { 1768 head->tail->next = ipa; 1769 head->tail = ipa; 1770 } 1771 1772 /* 1773 * XXX for now, no netmask support for IPv6. 1774 * but since there's no way to specify address family, once you 1775 * have IPv6 address on a host, you cannot use dns/netmask 1776 * syntax. 1777 */ 1778 if (ipa->af == AF_INET) 1779 set_ipmask(ipa, mask == -1 ? 32 : mask); 1780 else 1781 if (mask != -1) 1782 err(1, "host_dns: cannot apply netmask " 1783 "on non-IPv4 address"); 1784 } 1785 freeaddrinfo(res0); 1786 1787 return (head); 1788} 1789 1790struct ipsec_addr_wrap * 1791host_if(const char *s, int mask) 1792{ 1793 struct ipsec_addr_wrap *ipa = NULL; 1794 1795 if (ifa_exists(s)) 1796 ipa = ifa_lookup(s); 1797 1798 return (ipa); 1799} 1800 1801struct ipsec_addr_wrap * 1802host_any(void) 1803{ 1804 struct ipsec_addr_wrap *ipa; 1805 1806 ipa = calloc(1, sizeof(struct ipsec_addr_wrap)); 1807 if (ipa == NULL) 1808 err(1, "%s", __func__); 1809 ipa->af = AF_UNSPEC; 1810 ipa->netaddress = 1; 1811 ipa->tail = ipa; 1812 return (ipa); 1813} 1814 1815/* interface lookup routintes */ 1816 1817struct ipsec_addr_wrap *iftab; 1818 1819void 1820ifa_load(void) 1821{ 1822 struct ifaddrs *ifap, *ifa; 1823 struct ipsec_addr_wrap *n = NULL, *h = NULL; 1824 1825 if (getifaddrs(&ifap) < 0) 1826 err(1, "ifa_load: getifaddrs"); 1827 1828 for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 1829 if (ifa->ifa_addr == NULL || 1830 !(ifa->ifa_addr->sa_family == AF_INET || 1831 ifa->ifa_addr->sa_family == AF_INET6 || 1832 ifa->ifa_addr->sa_family == AF_LINK)) 1833 continue; 1834 n = calloc(1, sizeof(struct ipsec_addr_wrap)); 1835 if (n == NULL) 1836 err(1, "%s", __func__); 1837 n->af = ifa->ifa_addr->sa_family; 1838 if ((n->name = strdup(ifa->ifa_name)) == NULL) 1839 err(1, "%s", __func__); 1840 if (n->af == AF_INET) { 1841 n->af = AF_INET; 1842 memcpy(&n->address.v4, &((struct sockaddr_in *) 1843 ifa->ifa_addr)->sin_addr, 1844 sizeof(struct in_addr)); 1845 memcpy(&n->mask.v4, &((struct sockaddr_in *) 1846 ifa->ifa_netmask)->sin_addr, 1847 sizeof(struct in_addr)); 1848 } else if (n->af == AF_INET6) { 1849 n->af = AF_INET6; 1850 memcpy(&n->address.v6, &((struct sockaddr_in6 *) 1851 ifa->ifa_addr)->sin6_addr, 1852 sizeof(struct in6_addr)); 1853 memcpy(&n->mask.v6, &((struct sockaddr_in6 *) 1854 ifa->ifa_netmask)->sin6_addr, 1855 sizeof(struct in6_addr)); 1856 } 1857 n->next = NULL; 1858 n->tail = n; 1859 if (h == NULL) 1860 h = n; 1861 else { 1862 h->tail->next = n; 1863 h->tail = n; 1864 } 1865 } 1866 1867 iftab = h; 1868 freeifaddrs(ifap); 1869} 1870 1871int 1872ifa_exists(const char *ifa_name) 1873{ 1874 struct ipsec_addr_wrap *n; 1875 struct ifgroupreq ifgr; 1876 int s; 1877 1878 if (iftab == NULL) 1879 ifa_load(); 1880 1881 /* check whether this is a group */ 1882 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 1883 err(1, "ifa_exists: socket"); 1884 bzero(&ifgr, sizeof(ifgr)); 1885 strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name)); 1886 if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == 0) { 1887 close(s); 1888 return (1); 1889 } 1890 close(s); 1891 1892 for (n = iftab; n; n = n->next) { 1893 if (n->af == AF_LINK && !strncmp(n->name, ifa_name, 1894 IFNAMSIZ)) 1895 return (1); 1896 } 1897 1898 return (0); 1899} 1900 1901struct ipsec_addr_wrap * 1902ifa_grouplookup(const char *ifa_name) 1903{ 1904 struct ifg_req *ifg; 1905 struct ifgroupreq ifgr; 1906 int s; 1907 size_t len; 1908 struct ipsec_addr_wrap *n, *h = NULL, *hn; 1909 1910 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 1911 err(1, "socket"); 1912 bzero(&ifgr, sizeof(ifgr)); 1913 strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name)); 1914 if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) { 1915 close(s); 1916 return (NULL); 1917 } 1918 1919 len = ifgr.ifgr_len; 1920 if ((ifgr.ifgr_groups = calloc(1, len)) == NULL) 1921 err(1, "%s", __func__); 1922 if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) 1923 err(1, "ioctl"); 1924 1925 for (ifg = ifgr.ifgr_groups; ifg && len >= sizeof(struct ifg_req); 1926 ifg++) { 1927 len -= sizeof(struct ifg_req); 1928 if ((n = ifa_lookup(ifg->ifgrq_member)) == NULL) 1929 continue; 1930 if (h == NULL) 1931 h = n; 1932 else { 1933 for (hn = h; hn->next != NULL; hn = hn->next) 1934 ; /* nothing */ 1935 hn->next = n; 1936 n->tail = hn; 1937 } 1938 } 1939 free(ifgr.ifgr_groups); 1940 close(s); 1941 1942 return (h); 1943} 1944 1945struct ipsec_addr_wrap * 1946ifa_lookup(const char *ifa_name) 1947{ 1948 struct ipsec_addr_wrap *p = NULL, *h = NULL, *n = NULL; 1949 1950 if (iftab == NULL) 1951 ifa_load(); 1952 1953 if ((n = ifa_grouplookup(ifa_name)) != NULL) 1954 return (n); 1955 1956 for (p = iftab; p; p = p->next) { 1957 if (p->af != AF_INET && p->af != AF_INET6) 1958 continue; 1959 if (strncmp(p->name, ifa_name, IFNAMSIZ)) 1960 continue; 1961 n = calloc(1, sizeof(struct ipsec_addr_wrap)); 1962 if (n == NULL) 1963 err(1, "%s", __func__); 1964 memcpy(n, p, sizeof(struct ipsec_addr_wrap)); 1965 if ((n->name = strdup(p->name)) == NULL) 1966 err(1, "%s", __func__); 1967 switch (n->af) { 1968 case AF_INET: 1969 set_ipmask(n, 32); 1970 break; 1971 case AF_INET6: 1972 /* route/show.c and bgpd/util.c give KAME credit */ 1973 if (IN6_IS_ADDR_LINKLOCAL(&n->address.v6)) { 1974 u_int16_t tmp16; 1975 /* for now we can not handle link local, 1976 * therefore bail for now 1977 */ 1978 free(n); 1979 continue; 1980 1981 memcpy(&tmp16, &n->address.v6.s6_addr[2], 1982 sizeof(tmp16)); 1983 /* use this when we support link-local 1984 * n->??.scopeid = ntohs(tmp16); 1985 */ 1986 n->address.v6.s6_addr[2] = 0; 1987 n->address.v6.s6_addr[3] = 0; 1988 } 1989 set_ipmask(n, 128); 1990 break; 1991 } 1992 1993 n->next = NULL; 1994 n->tail = n; 1995 if (h == NULL) 1996 h = n; 1997 else { 1998 h->tail->next = n; 1999 h->tail = n; 2000 } 2001 } 2002 2003 return (h); 2004} 2005 2006void 2007set_ipmask(struct ipsec_addr_wrap *address, u_int8_t b) 2008{ 2009 struct ipsec_addr *ipa; 2010 int i, j = 0; 2011 2012 ipa = &address->mask; 2013 bzero(ipa, sizeof(struct ipsec_addr)); 2014 2015 while (b >= 32) { 2016 ipa->addr32[j++] = 0xffffffff; 2017 b -= 32; 2018 } 2019 for (i = 31; i > 31 - b; --i) 2020 ipa->addr32[j] |= (1 << i); 2021 if (b) 2022 ipa->addr32[j] = htonl(ipa->addr32[j]); 2023} 2024 2025const struct ipsec_xf * 2026parse_xf(const char *name, const struct ipsec_xf xfs[]) 2027{ 2028 int i; 2029 2030 for (i = 0; xfs[i].name != NULL; i++) { 2031 if (strncmp(name, xfs[i].name, strlen(name))) 2032 continue; 2033 return &xfs[i]; 2034 } 2035 return (NULL); 2036} 2037 2038struct ipsec_lifetime * 2039parse_life(const char *value) 2040{ 2041 struct ipsec_lifetime *life; 2042 int ret; 2043 int seconds = 0; 2044 char unit = 0; 2045 2046 ret = sscanf(value, "%d%c", &seconds, &unit); 2047 if (ret == 2) { 2048 switch (tolower((unsigned char)unit)) { 2049 case 'm': 2050 seconds *= 60; 2051 break; 2052 case 'h': 2053 seconds *= 60 * 60; 2054 break; 2055 default: 2056 err(1, "invalid time unit"); 2057 } 2058 } else if (ret != 1) 2059 err(1, "invalid time specification: %s", value); 2060 2061 life = calloc(1, sizeof(struct ipsec_lifetime)); 2062 if (life == NULL) 2063 err(1, "%s", __func__); 2064 2065 life->lt_seconds = seconds; 2066 life->lt_bytes = -1; 2067 2068 return (life); 2069} 2070 2071struct ipsec_transforms * 2072copytransforms(const struct ipsec_transforms *xfs) 2073{ 2074 struct ipsec_transforms *newxfs; 2075 2076 if (xfs == NULL) 2077 return (NULL); 2078 2079 newxfs = calloc(1, sizeof(struct ipsec_transforms)); 2080 if (newxfs == NULL) 2081 err(1, "%s", __func__); 2082 2083 memcpy(newxfs, xfs, sizeof(struct ipsec_transforms)); 2084 return (newxfs); 2085} 2086 2087struct ipsec_lifetime * 2088copylife(const struct ipsec_lifetime *life) 2089{ 2090 struct ipsec_lifetime *newlife; 2091 2092 if (life == NULL) 2093 return (NULL); 2094 2095 newlife = calloc(1, sizeof(struct ipsec_lifetime)); 2096 if (newlife == NULL) 2097 err(1, "%s", __func__); 2098 2099 memcpy(newlife, life, sizeof(struct ipsec_lifetime)); 2100 return (newlife); 2101} 2102 2103struct ipsec_auth * 2104copyipsecauth(const struct ipsec_auth *auth) 2105{ 2106 struct ipsec_auth *newauth; 2107 2108 if (auth == NULL) 2109 return (NULL); 2110 2111 if ((newauth = calloc(1, sizeof(struct ipsec_auth))) == NULL) 2112 err(1, "%s", __func__); 2113 if (auth->srcid && 2114 asprintf(&newauth->srcid, "%s", auth->srcid) == -1) 2115 err(1, "%s", __func__); 2116 if (auth->dstid && 2117 asprintf(&newauth->dstid, "%s", auth->dstid) == -1) 2118 err(1, "%s", __func__); 2119 2120 newauth->srcid_type = auth->srcid_type; 2121 newauth->dstid_type = auth->dstid_type; 2122 newauth->type = auth->type; 2123 2124 return (newauth); 2125} 2126 2127struct ike_auth * 2128copyikeauth(const struct ike_auth *auth) 2129{ 2130 struct ike_auth *newauth; 2131 2132 if (auth == NULL) 2133 return (NULL); 2134 2135 if ((newauth = calloc(1, sizeof(struct ike_auth))) == NULL) 2136 err(1, "%s", __func__); 2137 if (auth->string && 2138 asprintf(&newauth->string, "%s", auth->string) == -1) 2139 err(1, "%s", __func__); 2140 2141 newauth->type = auth->type; 2142 2143 return (newauth); 2144} 2145 2146struct ipsec_key * 2147copykey(struct ipsec_key *key) 2148{ 2149 struct ipsec_key *newkey; 2150 2151 if (key == NULL) 2152 return (NULL); 2153 2154 if ((newkey = calloc(1, sizeof(struct ipsec_key))) == NULL) 2155 err(1, "%s", __func__); 2156 if ((newkey->data = calloc(key->len, sizeof(u_int8_t))) == NULL) 2157 err(1, "%s", __func__); 2158 memcpy(newkey->data, key->data, key->len); 2159 newkey->len = key->len; 2160 2161 return (newkey); 2162} 2163 2164struct ipsec_addr_wrap * 2165copyhost(const struct ipsec_addr_wrap *src) 2166{ 2167 struct ipsec_addr_wrap *dst; 2168 2169 if (src == NULL) 2170 return (NULL); 2171 2172 dst = calloc(1, sizeof(struct ipsec_addr_wrap)); 2173 if (dst == NULL) 2174 err(1, "%s", __func__); 2175 2176 memcpy(dst, src, sizeof(struct ipsec_addr_wrap)); 2177 2178 if (src->name != NULL && (dst->name = strdup(src->name)) == NULL) 2179 err(1, "%s", __func__); 2180 2181 return dst; 2182} 2183 2184char * 2185copytag(const char *src) 2186{ 2187 char *tag; 2188 2189 if (src == NULL) 2190 return (NULL); 2191 if ((tag = strdup(src)) == NULL) 2192 err(1, "%s", __func__); 2193 2194 return (tag); 2195} 2196 2197struct ipsec_rule * 2198copyrule(struct ipsec_rule *rule) 2199{ 2200 struct ipsec_rule *r; 2201 2202 if ((r = calloc(1, sizeof(struct ipsec_rule))) == NULL) 2203 err(1, "%s", __func__); 2204 2205 r->src = copyhost(rule->src); 2206 r->dst = copyhost(rule->dst); 2207 r->local = copyhost(rule->local); 2208 r->peer = copyhost(rule->peer); 2209 r->auth = copyipsecauth(rule->auth); 2210 r->ikeauth = copyikeauth(rule->ikeauth); 2211 r->xfs = copytransforms(rule->xfs); 2212 r->p1xfs = copytransforms(rule->p1xfs); 2213 r->p2xfs = copytransforms(rule->p2xfs); 2214 r->p1life = copylife(rule->p1life); 2215 r->p2life = copylife(rule->p2life); 2216 r->authkey = copykey(rule->authkey); 2217 r->enckey = copykey(rule->enckey); 2218 r->tag = copytag(rule->tag); 2219 2220 r->p1ie = rule->p1ie; 2221 r->p2ie = rule->p2ie; 2222 r->type = rule->type; 2223 r->satype = rule->satype; 2224 r->proto = rule->proto; 2225 r->tmode = rule->tmode; 2226 r->direction = rule->direction; 2227 r->flowtype = rule->flowtype; 2228 r->sport = rule->sport; 2229 r->dport = rule->dport; 2230 r->ikemode = rule->ikemode; 2231 r->spi = rule->spi; 2232 r->udpencap = rule->udpencap; 2233 r->udpdport = rule->udpdport; 2234 r->nr = rule->nr; 2235 2236 return (r); 2237} 2238 2239int 2240validate_af(struct ipsec_addr_wrap *src, struct ipsec_addr_wrap *dst) 2241{ 2242 struct ipsec_addr_wrap *ta; 2243 u_int8_t src_v4 = 0; 2244 u_int8_t dst_v4 = 0; 2245 u_int8_t src_v6 = 0; 2246 u_int8_t dst_v6 = 0; 2247 2248 for (ta = src; ta; ta = ta->next) { 2249 if (ta->af == AF_INET) 2250 src_v4 = 1; 2251 if (ta->af == AF_INET6) 2252 src_v6 = 1; 2253 if (ta->af == AF_UNSPEC) 2254 return 0; 2255 if (src_v4 && src_v6) 2256 break; 2257 } 2258 for (ta = dst; ta; ta = ta->next) { 2259 if (ta->af == AF_INET) 2260 dst_v4 = 1; 2261 if (ta->af == AF_INET6) 2262 dst_v6 = 1; 2263 if (ta->af == AF_UNSPEC) 2264 return 0; 2265 if (dst_v4 && dst_v6) 2266 break; 2267 } 2268 if (src_v4 != dst_v4 && src_v6 != dst_v6) 2269 return (1); 2270 2271 return (0); 2272} 2273 2274 2275int 2276validate_sa(u_int32_t spi, u_int8_t satype, struct ipsec_transforms *xfs, 2277 struct ipsec_key *authkey, struct ipsec_key *enckey, u_int8_t tmode) 2278{ 2279 /* Sanity checks */ 2280 if (spi == 0) { 2281 yyerror("no SPI specified"); 2282 return (0); 2283 } 2284 if (satype == IPSEC_AH) { 2285 if (!xfs) { 2286 yyerror("no transforms specified"); 2287 return (0); 2288 } 2289 if (!xfs->authxf) 2290 xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256]; 2291 if (xfs->encxf) { 2292 yyerror("ah does not provide encryption"); 2293 return (0); 2294 } 2295 if (xfs->compxf) { 2296 yyerror("ah does not provide compression"); 2297 return (0); 2298 } 2299 } 2300 if (satype == IPSEC_ESP) { 2301 if (!xfs) { 2302 yyerror("no transforms specified"); 2303 return (0); 2304 } 2305 if (xfs->compxf) { 2306 yyerror("esp does not provide compression"); 2307 return (0); 2308 } 2309 if (!xfs->encxf) 2310 xfs->encxf = &encxfs[ENCXF_AES]; 2311 if (xfs->encxf->nostatic) { 2312 yyerror("%s is disallowed with static keys", 2313 xfs->encxf->name); 2314 return 0; 2315 } 2316 if (xfs->encxf->noauth && xfs->authxf) { 2317 yyerror("authentication is implicit for %s", 2318 xfs->encxf->name); 2319 return (0); 2320 } else if (!xfs->encxf->noauth && !xfs->authxf) 2321 xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256]; 2322 } 2323 if (satype == IPSEC_IPCOMP) { 2324 if (!xfs) { 2325 yyerror("no transform specified"); 2326 return (0); 2327 } 2328 if (xfs->authxf || xfs->encxf) { 2329 yyerror("no encryption or authentication with ipcomp"); 2330 return (0); 2331 } 2332 if (!xfs->compxf) 2333 xfs->compxf = &compxfs[COMPXF_DEFLATE]; 2334 } 2335 if (satype == IPSEC_IPIP) { 2336 if (!xfs) { 2337 yyerror("no transform specified"); 2338 return (0); 2339 } 2340 if (xfs->authxf || xfs->encxf || xfs->compxf) { 2341 yyerror("no encryption, authentication or compression" 2342 " with ipip"); 2343 return (0); 2344 } 2345 } 2346 if (satype == IPSEC_TCPMD5 && authkey == NULL && tmode != 2347 IPSEC_TRANSPORT) { 2348 yyerror("authentication key needed for tcpmd5"); 2349 return (0); 2350 } 2351 if (xfs && xfs->authxf) { 2352 if (!authkey && xfs->authxf != &authxfs[AUTHXF_NONE]) { 2353 yyerror("no authentication key specified"); 2354 return (0); 2355 } 2356 if (authkey && authkey->len != xfs->authxf->keymin) { 2357 yyerror("wrong authentication key length, needs to be " 2358 "%zu bits", xfs->authxf->keymin * 8); 2359 return (0); 2360 } 2361 } 2362 if (xfs && xfs->encxf) { 2363 if (!enckey && xfs->encxf != &encxfs[ENCXF_NULL]) { 2364 yyerror("no encryption key specified"); 2365 return (0); 2366 } 2367 if (enckey) { 2368 if (enckey->len < xfs->encxf->keymin) { 2369 yyerror("encryption key too short (%zu bits), " 2370 "minimum %zu bits", enckey->len * 8, 2371 xfs->encxf->keymin * 8); 2372 return (0); 2373 } 2374 if (xfs->encxf->keymax < enckey->len) { 2375 yyerror("encryption key too long (%zu bits), " 2376 "maximum %zu bits", enckey->len * 8, 2377 xfs->encxf->keymax * 8); 2378 return (0); 2379 } 2380 } 2381 } 2382 2383 return 1; 2384} 2385 2386int 2387add_sabundle(struct ipsec_rule *r, char *bundle) 2388{ 2389 struct ipsec_rule *rp, *last, *sabundle; 2390 int found = 0; 2391 2392 TAILQ_FOREACH(rp, &ipsec->bundle_queue, bundle_entry) { 2393 if ((strcmp(rp->src->name, r->src->name) == 0) && 2394 (strcmp(rp->dst->name, r->dst->name) == 0) && 2395 (strcmp(rp->bundle, bundle) == 0)) { 2396 found = 1; 2397 break; 2398 } 2399 } 2400 if (found) { 2401 last = TAILQ_LAST(&rp->dst_bundle_queue, dst_bundle_queue); 2402 TAILQ_INSERT_TAIL(&rp->dst_bundle_queue, r, dst_bundle_entry); 2403 2404 sabundle = create_sabundle(last->dst, last->satype, last->spi, 2405 r->dst, r->satype, r->spi); 2406 if (sabundle == NULL) 2407 return (1); 2408 sabundle->nr = ipsec->rule_nr++; 2409 if (ipsecctl_add_rule(ipsec, sabundle)) 2410 return (1); 2411 } else { 2412 TAILQ_INSERT_TAIL(&ipsec->bundle_queue, r, bundle_entry); 2413 TAILQ_INIT(&r->dst_bundle_queue); 2414 TAILQ_INSERT_TAIL(&r->dst_bundle_queue, r, dst_bundle_entry); 2415 r->bundle = bundle; 2416 } 2417 2418 return (0); 2419} 2420 2421struct ipsec_rule * 2422create_sa(u_int8_t satype, u_int8_t tmode, struct ipsec_hosts *hosts, 2423 u_int32_t spi, u_int8_t udpencap, u_int16_t udpdport, 2424 struct ipsec_transforms *xfs, struct ipsec_key *authkey, struct ipsec_key *enckey) 2425{ 2426 struct ipsec_rule *r; 2427 2428 if (validate_sa(spi, satype, xfs, authkey, enckey, tmode) == 0) 2429 return (NULL); 2430 2431 r = calloc(1, sizeof(struct ipsec_rule)); 2432 if (r == NULL) 2433 err(1, "%s", __func__); 2434 2435 r->type |= RULE_SA; 2436 r->satype = satype; 2437 r->tmode = tmode; 2438 r->src = hosts->src; 2439 r->dst = hosts->dst; 2440 r->spi = spi; 2441 r->udpencap = udpencap; 2442 r->udpdport = udpdport; 2443 r->xfs = xfs; 2444 r->authkey = authkey; 2445 r->enckey = enckey; 2446 2447 return r; 2448} 2449 2450struct ipsec_rule * 2451reverse_sa(struct ipsec_rule *rule, u_int32_t spi, struct ipsec_key *authkey, 2452 struct ipsec_key *enckey) 2453{ 2454 struct ipsec_rule *reverse; 2455 2456 if (validate_sa(spi, rule->satype, rule->xfs, authkey, enckey, 2457 rule->tmode) == 0) 2458 return (NULL); 2459 2460 reverse = calloc(1, sizeof(struct ipsec_rule)); 2461 if (reverse == NULL) 2462 err(1, "%s", __func__); 2463 2464 reverse->type |= RULE_SA; 2465 reverse->satype = rule->satype; 2466 reverse->tmode = rule->tmode; 2467 reverse->src = copyhost(rule->dst); 2468 reverse->dst = copyhost(rule->src); 2469 reverse->spi = spi; 2470 reverse->udpencap = rule->udpencap; 2471 reverse->udpdport = rule->udpdport; 2472 reverse->xfs = copytransforms(rule->xfs); 2473 reverse->authkey = authkey; 2474 reverse->enckey = enckey; 2475 2476 return (reverse); 2477} 2478 2479struct ipsec_rule * 2480create_sabundle(struct ipsec_addr_wrap *dst, u_int8_t proto, u_int32_t spi, 2481 struct ipsec_addr_wrap *dst2, u_int8_t proto2, u_int32_t spi2) 2482{ 2483 struct ipsec_rule *r; 2484 2485 r = calloc(1, sizeof(struct ipsec_rule)); 2486 if (r == NULL) 2487 err(1, "%s", __func__); 2488 2489 r->type |= RULE_BUNDLE; 2490 2491 r->dst = copyhost(dst); 2492 r->dst2 = copyhost(dst2); 2493 r->proto = proto; 2494 r->proto2 = proto2; 2495 r->spi = spi; 2496 r->spi2 = spi2; 2497 r->satype = proto; 2498 2499 return (r); 2500} 2501 2502struct ipsec_rule * 2503create_flow(u_int8_t dir, u_int8_t proto, struct ipsec_hosts *hosts, 2504 u_int8_t satype, char *srcid, char *dstid, u_int8_t type) 2505{ 2506 struct ipsec_rule *r; 2507 2508 r = calloc(1, sizeof(struct ipsec_rule)); 2509 if (r == NULL) 2510 err(1, "%s", __func__); 2511 2512 r->type |= RULE_FLOW; 2513 2514 if (dir == IPSEC_INOUT) 2515 r->direction = IPSEC_OUT; 2516 else 2517 r->direction = dir; 2518 2519 r->satype = satype; 2520 r->proto = proto; 2521 r->src = hosts->src; 2522 r->sport = hosts->sport; 2523 r->dst = hosts->dst; 2524 r->dport = hosts->dport; 2525 if ((hosts->sport != 0 || hosts->dport != 0) && 2526 (proto != IPPROTO_TCP && proto != IPPROTO_UDP)) { 2527 yyerror("no protocol supplied with source/destination ports"); 2528 goto errout; 2529 } 2530 2531 switch (satype) { 2532 case IPSEC_IPCOMP: 2533 case IPSEC_IPIP: 2534 if (type == TYPE_UNKNOWN) 2535 type = TYPE_USE; 2536 break; 2537 default: 2538 if (type == TYPE_UNKNOWN) 2539 type = TYPE_REQUIRE; 2540 break; 2541 } 2542 2543 r->flowtype = type; 2544 if (type == TYPE_DENY || type == TYPE_BYPASS) 2545 return (r); 2546 2547 r->auth = calloc(1, sizeof(struct ipsec_auth)); 2548 if (r->auth == NULL) 2549 err(1, "%s", __func__); 2550 r->auth->srcid = srcid; 2551 r->auth->dstid = dstid; 2552 r->auth->srcid_type = get_id_type(srcid); 2553 r->auth->dstid_type = get_id_type(dstid); 2554 return r; 2555 2556errout: 2557 free(r); 2558 if (srcid) 2559 free(srcid); 2560 if (dstid) 2561 free(dstid); 2562 free(hosts->src); 2563 hosts->src = NULL; 2564 free(hosts->dst); 2565 hosts->dst = NULL; 2566 2567 return NULL; 2568} 2569 2570void 2571expand_any(struct ipsec_addr_wrap *ipa_in) 2572{ 2573 struct ipsec_addr_wrap *oldnext, *ipa; 2574 2575 for (ipa = ipa_in; ipa; ipa = ipa->next) { 2576 if (ipa->af != AF_UNSPEC) 2577 continue; 2578 oldnext = ipa->next; 2579 2580 ipa->af = AF_INET; 2581 ipa->netaddress = 1; 2582 if ((ipa->name = strdup("0.0.0.0/0")) == NULL) 2583 err(1, "%s", __func__); 2584 2585 ipa->next = calloc(1, sizeof(struct ipsec_addr_wrap)); 2586 if (ipa->next == NULL) 2587 err(1, "%s", __func__); 2588 ipa->next->af = AF_INET6; 2589 ipa->next->netaddress = 1; 2590 if ((ipa->next->name = strdup("::/0")) == NULL) 2591 err(1, "%s", __func__); 2592 2593 ipa->next->next = oldnext; 2594 } 2595} 2596 2597int 2598set_rule_peers(struct ipsec_rule *r, struct ipsec_hosts *peers) 2599{ 2600 if (r->type == RULE_FLOW && 2601 (r->flowtype == TYPE_DENY || r->flowtype == TYPE_BYPASS)) 2602 return (0); 2603 2604 r->local = copyhost(peers->src); 2605 r->peer = copyhost(peers->dst); 2606 if (r->peer == NULL) { 2607 /* Set peer to remote host. Must be a host address. */ 2608 if (r->direction == IPSEC_IN) { 2609 if (!r->src->netaddress) 2610 r->peer = copyhost(r->src); 2611 } else { 2612 if (!r->dst->netaddress) 2613 r->peer = copyhost(r->dst); 2614 } 2615 } 2616 if (r->type == RULE_FLOW && r->peer == NULL) { 2617 yyerror("no peer specified for destination %s", 2618 r->dst->name); 2619 return (1); 2620 } 2621 if (r->peer != NULL && r->peer->af == AF_UNSPEC) { 2622 /* If peer has been specified as any, use the default peer. */ 2623 free(r->peer); 2624 r->peer = NULL; 2625 } 2626 if (r->type == RULE_IKE && r->peer == NULL) { 2627 /* 2628 * Check if the default peer is consistent for all 2629 * rules. Only warn to avoid breaking existing configs. 2630 */ 2631 static struct ipsec_rule *pdr = NULL; 2632 2633 if (pdr == NULL) { 2634 /* Remember first default peer rule for comparison. */ 2635 pdr = r; 2636 } else { 2637 /* The new default peer must create the same config. */ 2638 if ((pdr->local == NULL && r->local != NULL) || 2639 (pdr->local != NULL && r->local == NULL) || 2640 (pdr->local != NULL && r->local != NULL && 2641 strcmp(pdr->local->name, r->local->name))) 2642 yywarn("default peer local mismatch"); 2643 if (pdr->ikeauth->type != r->ikeauth->type) 2644 yywarn("default peer phase 1 auth mismatch"); 2645 if (pdr->ikeauth->type == IKE_AUTH_PSK && 2646 r->ikeauth->type == IKE_AUTH_PSK && 2647 strcmp(pdr->ikeauth->string, r->ikeauth->string)) 2648 yywarn("default peer psk mismatch"); 2649 if (pdr->p1ie != r->p1ie) 2650 yywarn("default peer phase 1 mode mismatch"); 2651 /* 2652 * Transforms have ADD insted of SET so they may be 2653 * different and are not checked here. 2654 */ 2655 if ((pdr->auth->srcid == NULL && 2656 r->auth->srcid != NULL) || 2657 (pdr->auth->srcid != NULL && 2658 r->auth->srcid == NULL) || 2659 (pdr->auth->srcid != NULL && 2660 r->auth->srcid != NULL && 2661 strcmp(pdr->auth->srcid, r->auth->srcid))) 2662 yywarn("default peer srcid mismatch"); 2663 if ((pdr->auth->dstid == NULL && 2664 r->auth->dstid != NULL) || 2665 (pdr->auth->dstid != NULL && 2666 r->auth->dstid == NULL) || 2667 (pdr->auth->dstid != NULL && 2668 r->auth->dstid != NULL && 2669 strcmp(pdr->auth->dstid, r->auth->dstid))) 2670 yywarn("default peer dstid mismatch"); 2671 } 2672 } 2673 return (0); 2674} 2675 2676int 2677expand_rule(struct ipsec_rule *rule, struct ipsec_hosts *peers, 2678 u_int8_t direction, u_int32_t spi, struct ipsec_key *authkey, 2679 struct ipsec_key *enckey, char *bundle) 2680{ 2681 struct ipsec_rule *r, *revr; 2682 struct ipsec_addr_wrap *src, *dst; 2683 int added = 0, ret = 1; 2684 2685 if (validate_af(rule->src, rule->dst)) { 2686 yyerror("source/destination address families do not match"); 2687 goto errout; 2688 } 2689 expand_any(rule->src); 2690 expand_any(rule->dst); 2691 for (src = rule->src; src; src = src->next) { 2692 for (dst = rule->dst; dst; dst = dst->next) { 2693 if (src->af != dst->af) 2694 continue; 2695 r = copyrule(rule); 2696 2697 r->src = copyhost(src); 2698 r->dst = copyhost(dst); 2699 2700 if (peers && set_rule_peers(r, peers)) { 2701 ipsecctl_free_rule(r); 2702 goto errout; 2703 } 2704 2705 r->nr = ipsec->rule_nr++; 2706 if (ipsecctl_add_rule(ipsec, r)) 2707 goto out; 2708 if (bundle && add_sabundle(r, bundle)) 2709 goto out; 2710 2711 if (direction == IPSEC_INOUT) { 2712 /* Create and add reverse flow rule. */ 2713 revr = reverse_rule(r); 2714 if (revr == NULL) 2715 goto out; 2716 2717 revr->nr = ipsec->rule_nr++; 2718 if (ipsecctl_add_rule(ipsec, revr)) 2719 goto out; 2720 if (bundle && add_sabundle(revr, bundle)) 2721 goto out; 2722 } else if (spi != 0 || authkey || enckey) { 2723 /* Create and add reverse sa rule. */ 2724 revr = reverse_sa(r, spi, authkey, enckey); 2725 if (revr == NULL) 2726 goto out; 2727 2728 revr->nr = ipsec->rule_nr++; 2729 if (ipsecctl_add_rule(ipsec, revr)) 2730 goto out; 2731 if (bundle && add_sabundle(revr, bundle)) 2732 goto out; 2733 } 2734 added++; 2735 } 2736 } 2737 if (!added) 2738 yyerror("rule expands to no valid combination"); 2739 errout: 2740 ret = 0; 2741 ipsecctl_free_rule(rule); 2742 out: 2743 if (peers) { 2744 if (peers->src) 2745 free(peers->src); 2746 if (peers->dst) 2747 free(peers->dst); 2748 } 2749 return (ret); 2750} 2751 2752struct ipsec_rule * 2753reverse_rule(struct ipsec_rule *rule) 2754{ 2755 struct ipsec_rule *reverse; 2756 2757 reverse = calloc(1, sizeof(struct ipsec_rule)); 2758 if (reverse == NULL) 2759 err(1, "%s", __func__); 2760 2761 reverse->type |= RULE_FLOW; 2762 2763 /* Reverse direction */ 2764 if (rule->direction == (u_int8_t)IPSEC_OUT) 2765 reverse->direction = (u_int8_t)IPSEC_IN; 2766 else 2767 reverse->direction = (u_int8_t)IPSEC_OUT; 2768 2769 reverse->flowtype = rule->flowtype; 2770 reverse->src = copyhost(rule->dst); 2771 reverse->dst = copyhost(rule->src); 2772 reverse->sport = rule->dport; 2773 reverse->dport = rule->sport; 2774 if (rule->local) 2775 reverse->local = copyhost(rule->local); 2776 if (rule->peer) 2777 reverse->peer = copyhost(rule->peer); 2778 reverse->satype = rule->satype; 2779 reverse->proto = rule->proto; 2780 2781 if (rule->auth) { 2782 reverse->auth = calloc(1, sizeof(struct ipsec_auth)); 2783 if (reverse->auth == NULL) 2784 err(1, "%s", __func__); 2785 if (rule->auth->dstid && (reverse->auth->dstid = 2786 strdup(rule->auth->dstid)) == NULL) 2787 err(1, "%s", __func__); 2788 if (rule->auth->srcid && (reverse->auth->srcid = 2789 strdup(rule->auth->srcid)) == NULL) 2790 err(1, "%s", __func__); 2791 reverse->auth->srcid_type = rule->auth->srcid_type; 2792 reverse->auth->dstid_type = rule->auth->dstid_type; 2793 reverse->auth->type = rule->auth->type; 2794 } 2795 2796 return reverse; 2797} 2798 2799struct ipsec_rule * 2800create_ike(u_int8_t proto, struct ipsec_hosts *hosts, 2801 struct ike_mode *phase1mode, struct ike_mode *phase2mode, u_int8_t satype, 2802 u_int8_t tmode, u_int8_t mode, char *srcid, char *dstid, 2803 struct ike_auth *authtype, char *tag) 2804{ 2805 struct ipsec_rule *r; 2806 2807 r = calloc(1, sizeof(struct ipsec_rule)); 2808 if (r == NULL) 2809 err(1, "%s", __func__); 2810 2811 r->type = RULE_IKE; 2812 2813 r->proto = proto; 2814 r->src = hosts->src; 2815 r->sport = hosts->sport; 2816 r->dst = hosts->dst; 2817 r->dport = hosts->dport; 2818 if ((hosts->sport != 0 || hosts->dport != 0) && 2819 (proto != IPPROTO_TCP && proto != IPPROTO_UDP)) { 2820 yyerror("no protocol supplied with source/destination ports"); 2821 goto errout; 2822 } 2823 2824 r->satype = satype; 2825 r->tmode = tmode; 2826 r->ikemode = mode; 2827 if (phase1mode) { 2828 r->p1xfs = phase1mode->xfs; 2829 r->p1life = phase1mode->life; 2830 r->p1ie = phase1mode->ike_exch; 2831 } else { 2832 r->p1ie = IKE_MM; 2833 } 2834 if (phase2mode) { 2835 if (phase2mode->xfs && phase2mode->xfs->encxf && 2836 phase2mode->xfs->encxf->noauth && 2837 phase2mode->xfs->authxf) { 2838 yyerror("authentication is implicit for %s", 2839 phase2mode->xfs->encxf->name); 2840 goto errout; 2841 } 2842 r->p2xfs = phase2mode->xfs; 2843 r->p2life = phase2mode->life; 2844 r->p2ie = phase2mode->ike_exch; 2845 } else { 2846 r->p2ie = IKE_QM; 2847 } 2848 2849 r->auth = calloc(1, sizeof(struct ipsec_auth)); 2850 if (r->auth == NULL) 2851 err(1, "%s", __func__); 2852 r->auth->srcid = srcid; 2853 r->auth->dstid = dstid; 2854 r->auth->srcid_type = get_id_type(srcid); 2855 r->auth->dstid_type = get_id_type(dstid); 2856 r->ikeauth = calloc(1, sizeof(struct ike_auth)); 2857 if (r->ikeauth == NULL) 2858 err(1, "%s", __func__); 2859 r->ikeauth->type = authtype->type; 2860 r->ikeauth->string = authtype->string; 2861 r->tag = tag; 2862 2863 return (r); 2864 2865errout: 2866 free(r); 2867 free(hosts->src); 2868 hosts->src = NULL; 2869 free(hosts->dst); 2870 hosts->dst = NULL; 2871 if (phase1mode) { 2872 free(phase1mode->xfs); 2873 phase1mode->xfs = NULL; 2874 free(phase1mode->life); 2875 phase1mode->life = NULL; 2876 } 2877 if (phase2mode) { 2878 free(phase2mode->xfs); 2879 phase2mode->xfs = NULL; 2880 free(phase2mode->life); 2881 phase2mode->life = NULL; 2882 } 2883 if (srcid) 2884 free(srcid); 2885 if (dstid) 2886 free(dstid); 2887 return NULL; 2888} 2889