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