1 /* $OpenBSD: ipsecctl.c,v 1.82 2017/04/19 15:59:38 bluhm Exp $ */ 2 /* 3 * Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/socket.h> 19 #include <sys/sysctl.h> 20 #include <sys/queue.h> 21 #include <sys/stat.h> 22 #include <net/pfkeyv2.h> 23 #include <net/route.h> 24 #include <netinet/in.h> 25 #include <netinet/ip_ipsp.h> 26 #include <arpa/inet.h> 27 28 #include <err.h> 29 #include <errno.h> 30 #include <fcntl.h> 31 #include <netdb.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include <unistd.h> 36 37 #include "ipsecctl.h" 38 #include "pfkey.h" 39 40 int ipsecctl_rules(char *, int); 41 FILE *ipsecctl_fopen(const char *, const char *); 42 int ipsecctl_commit(int, struct ipsecctl *); 43 int ipsecctl_add_rule(struct ipsecctl *, struct ipsec_rule *); 44 void ipsecctl_free_rule(struct ipsec_rule *); 45 void ipsecctl_print_addr(struct ipsec_addr_wrap *); 46 void ipsecctl_print_proto(u_int8_t); 47 void ipsecctl_print_port(u_int16_t, const char *); 48 void ipsecctl_print_key(struct ipsec_key *); 49 void ipsecctl_print_flow(struct ipsec_rule *, int); 50 void ipsecctl_print_sa(struct ipsec_rule *, int); 51 void ipsecctl_print_sabundle(struct ipsec_rule *, int); 52 int ipsecctl_flush(int); 53 void ipsecctl_get_rules(struct ipsecctl *); 54 void ipsecctl_print_title(char *); 55 void ipsecctl_show_flows(int); 56 void ipsecctl_show_sas(int); 57 int ipsecctl_monitor(int); 58 void usage(void); 59 const char *ipsecctl_lookup_option(char *, const char **); 60 static int unmask(struct ipsec_addr *, sa_family_t); 61 int sacompare(const void *, const void *); 62 63 const char *showopt; 64 char *isakmpd_fifo = "/var/run/isakmpd.fifo"; 65 66 int first_title = 1; 67 68 static const char *showopt_list[] = { 69 "flow", "sa", "all", NULL 70 }; 71 72 static const char *direction[] = {"?", "in", "out"}; 73 static const char *flowtype[] = {"?", "use", "acquire", "require", "deny", 74 "bypass", "dontacq"}; 75 static const char *satype[] = {"?", "esp", "ah", "ipcomp", "tcpmd5", "ipip"}; 76 static const char *tmode[] = {"?", "transport", "tunnel"}; 77 static const char *auth[] = {"?", "psk", "rsa"}; 78 79 struct sad { 80 struct sadb_msg *sad_msg; 81 u_int32_t sad_spi; 82 }; 83 84 int 85 sacompare(const void *va, const void *vb) 86 { 87 const struct sad *a = va, *b = vb; 88 89 if (a->sad_spi < b->sad_spi) 90 return (-1); 91 if (a->sad_spi > b->sad_spi) 92 return (1); 93 return (0); 94 } 95 96 int 97 ipsecctl_rules(char *filename, int opts) 98 { 99 struct ipsecctl ipsec; 100 struct ipsec_rule *rp; 101 int action, error = 0; 102 103 bzero(&ipsec, sizeof(ipsec)); 104 ipsec.opts = opts; 105 TAILQ_INIT(&ipsec.rule_queue); 106 TAILQ_INIT(&ipsec.bundle_queue); 107 108 if (parse_rules(filename, &ipsec) < 0) { 109 warnx("Syntax error in config file: ipsec rules not loaded"); 110 error = 1; 111 } else { 112 if (opts & IPSECCTL_OPT_DELETE) 113 action = ACTION_DELETE; 114 else 115 action = ACTION_ADD; 116 117 if ((opts & IPSECCTL_OPT_NOACTION) == 0) 118 error = ipsecctl_commit(action, &ipsec); 119 120 } 121 122 /* This also frees the rules in ipsec.bundle_queue. */ 123 while ((rp = TAILQ_FIRST(&ipsec.rule_queue))) { 124 TAILQ_REMOVE(&ipsec.rule_queue, rp, rule_entry); 125 ipsecctl_free_rule(rp); 126 } 127 128 return (error); 129 } 130 131 FILE * 132 ipsecctl_fopen(const char *name, const char *mode) 133 { 134 struct stat st; 135 FILE *fp; 136 137 fp = fopen(name, mode); 138 if (fp == NULL) 139 return (NULL); 140 141 if (fstat(fileno(fp), &st)) { 142 fclose(fp); 143 return (NULL); 144 } 145 if (S_ISDIR(st.st_mode)) { 146 fclose(fp); 147 errno = EISDIR; 148 return (NULL); 149 } 150 return (fp); 151 } 152 153 int 154 ipsecctl_commit(int action, struct ipsecctl *ipsec) 155 { 156 struct ipsec_rule *rp; 157 int ret = 0; 158 159 if (pfkey_init() == -1) 160 errx(1, "ipsecctl_commit: failed to open PF_KEY socket"); 161 162 TAILQ_FOREACH(rp, &ipsec->rule_queue, rule_entry) { 163 if (rp->type & RULE_IKE) { 164 if (ike_ipsec_establish(action, rp, isakmpd_fifo) == 165 -1) { 166 warnx("failed to %s ike rule %d", 167 action == ACTION_DELETE ? "delete" : "add", 168 rp->nr); 169 ret = 2; 170 } 171 } else { 172 if (pfkey_ipsec_establish(action, rp) == -1) { 173 warnx("failed to %s rule %d", 174 action == ACTION_DELETE ? "delete" : "add", 175 rp->nr); 176 ret = 2; 177 } 178 } 179 } 180 181 return (ret); 182 } 183 184 int 185 ipsecctl_add_rule(struct ipsecctl *ipsec, struct ipsec_rule *r) 186 { 187 TAILQ_INSERT_TAIL(&ipsec->rule_queue, r, rule_entry); 188 189 if ((ipsec->opts & IPSECCTL_OPT_VERBOSE) && !(ipsec->opts & 190 IPSECCTL_OPT_SHOW)) 191 ipsecctl_print_rule(r, ipsec->opts); 192 193 return (0); 194 } 195 196 void 197 ipsecctl_free_rule(struct ipsec_rule *rp) 198 { 199 if (rp->src) { 200 free(rp->src->name); 201 free(rp->src); 202 } 203 if (rp->dst) { 204 free(rp->dst->name); 205 free(rp->dst); 206 } 207 if (rp->dst2) { 208 free(rp->dst2->name); 209 free(rp->dst2); 210 } 211 if (rp->local) { 212 free(rp->local->name); 213 free(rp->local); 214 } 215 if (rp->peer) { 216 free(rp->peer->name); 217 free(rp->peer); 218 } 219 if (rp->auth) { 220 free(rp->auth->srcid); 221 free(rp->auth->dstid); 222 free(rp->auth); 223 } 224 if (rp->ikeauth) { 225 free(rp->ikeauth->string); 226 free(rp->ikeauth); 227 } 228 free(rp->xfs); 229 free(rp->p1xfs); 230 free(rp->p2xfs); 231 free(rp->p1life); 232 free(rp->p2life); 233 if (rp->authkey) { 234 free(rp->authkey->data); 235 free(rp->authkey); 236 } 237 if (rp->enckey) { 238 free(rp->enckey->data); 239 free(rp->enckey); 240 } 241 free(rp->p1name); 242 free(rp->p2name); 243 free(rp->p2lid); 244 free(rp->p2nid); 245 free(rp->p2rid); 246 free(rp); 247 } 248 249 void 250 ipsecctl_print_addr(struct ipsec_addr_wrap *ipa) 251 { 252 int bits; 253 char buf[NI_MAXHOST]; 254 255 if (ipa == NULL) { 256 printf("?"); 257 return; 258 } 259 if (inet_ntop(ipa->af, &ipa->address, buf, sizeof(buf)) == NULL) 260 printf("?"); 261 else 262 printf("%s", buf); 263 264 bits = unmask(&ipa->mask, ipa->af); 265 if (bits != (ipa->af == AF_INET ? 32 : 128)) 266 printf("/%d", bits); 267 } 268 269 void 270 ipsecctl_print_proto(u_int8_t proto) 271 { 272 struct protoent *p; 273 274 if ((p = getprotobynumber(proto)) != NULL) 275 printf("%s", p->p_name); 276 else 277 printf("%u", proto); 278 } 279 280 void 281 ipsecctl_print_port(u_int16_t port, const char *proto) 282 { 283 struct servent *s; 284 285 if ((s = getservbyport(port, proto)) != NULL) 286 printf("%s", s->s_name); 287 else 288 printf("%u", ntohs(port)); 289 } 290 291 void 292 ipsecctl_print_key(struct ipsec_key *key) 293 { 294 int i; 295 296 for (i = 0; i < (int)key->len; i++) 297 printf("%02x", key->data[i]); 298 } 299 300 void 301 ipsecctl_print_flow(struct ipsec_rule *r, int opts) 302 { 303 printf("flow %s %s", satype[r->satype], direction[r->direction]); 304 305 if (r->proto) { 306 printf(" proto "); 307 ipsecctl_print_proto(r->proto); 308 } 309 printf(" from "); 310 ipsecctl_print_addr(r->src); 311 if (r->sport) { 312 printf(" port "); 313 ipsecctl_print_port(r->sport, 314 r->proto == IPPROTO_TCP ? "tcp" : "udp"); 315 } 316 printf(" to "); 317 ipsecctl_print_addr(r->dst); 318 if (r->dport) { 319 printf(" port "); 320 ipsecctl_print_port(r->dport, 321 r->proto == IPPROTO_TCP ? "tcp" : "udp"); 322 } 323 if (r->local) { 324 printf(" local "); 325 ipsecctl_print_addr(r->local); 326 } 327 if (r->peer) { 328 printf(" peer "); 329 ipsecctl_print_addr(r->peer); 330 } 331 if (r->auth) { 332 if (r->auth->srcid) 333 printf(" srcid %s", r->auth->srcid); 334 if (r->auth->dstid) 335 printf(" dstid %s", r->auth->dstid); 336 if (r->auth->type > 0) 337 printf(" %s", auth[r->auth->type]); 338 } 339 printf(" type %s", flowtype[r->flowtype]); 340 printf("\n"); 341 } 342 343 /* ARGSUSED1 */ 344 void 345 ipsecctl_print_sa(struct ipsec_rule *r, int opts) 346 { 347 printf("%s ", satype[r->satype]); 348 /* tunnel/transport is only meaningful for esp/ah/ipcomp */ 349 if (r->satype != IPSEC_TCPMD5 && r->satype != IPSEC_IPIP) 350 printf("%s ", tmode[r->tmode]); 351 printf("from "); 352 ipsecctl_print_addr(r->src); 353 printf(" to "); 354 ipsecctl_print_addr(r->dst); 355 printf(" spi 0x%08x", r->spi); 356 357 if (r->satype != IPSEC_TCPMD5) { 358 if (r->xfs && r->xfs->authxf) 359 printf(" auth %s", r->xfs->authxf->name); 360 if (r->xfs && r->xfs->encxf) 361 printf(" enc %s", r->xfs->encxf->name); 362 if (r->xfs && r->xfs->compxf) 363 printf(" comp %s", r->xfs->compxf->name); 364 } 365 if (r->authkey && (opts & IPSECCTL_OPT_SHOWKEY)) { 366 if (r->satype == IPSEC_TCPMD5) 367 printf(" "); 368 else 369 printf(" \\\n\t"); 370 printf("authkey 0x"); 371 ipsecctl_print_key(r->authkey); 372 } 373 if (r->enckey && (opts & IPSECCTL_OPT_SHOWKEY)) { 374 if (r->satype == IPSEC_TCPMD5) 375 printf(" "); 376 else 377 printf(" \\\n\t"); 378 printf("enckey 0x"); 379 ipsecctl_print_key(r->enckey); 380 } 381 printf("\n"); 382 } 383 384 void 385 ipsecctl_print_sabundle(struct ipsec_rule *r, int opts) 386 { 387 printf("[bundle %s to ", satype[r->proto]); 388 ipsecctl_print_addr(r->dst); 389 printf(" spi 0x%08x with %s to ", r->spi, satype[r->proto2]); 390 ipsecctl_print_addr(r->dst2); 391 printf(" spi 0x%08x", r->spi2); 392 393 printf("]\n"); 394 } 395 396 void 397 ipsecctl_print_rule(struct ipsec_rule *r, int opts) 398 { 399 if (opts & IPSECCTL_OPT_VERBOSE2) 400 printf("@%d ", r->nr); 401 402 if (r->type & RULE_FLOW) 403 ipsecctl_print_flow(r, opts); 404 if (r->type & RULE_SA) 405 ipsecctl_print_sa(r, opts); 406 if (r->type & RULE_IKE) 407 ike_print_config(r, opts); 408 if (r->type & RULE_BUNDLE) 409 ipsecctl_print_sabundle(r, opts); 410 } 411 412 int 413 ipsecctl_flush(int opts) 414 { 415 if (opts & IPSECCTL_OPT_NOACTION) 416 return (0); 417 418 if (pfkey_init() == -1) 419 errx(1, "ipsecctl_flush: failed to open PF_KEY socket"); 420 421 if (pfkey_ipsec_flush() == -1) 422 errx(1, "ipsecctl_flush: failed to flush"); 423 424 return (0); 425 } 426 427 void 428 ipsecctl_get_rules(struct ipsecctl *ipsec) 429 { 430 struct sadb_msg *msg; 431 struct ipsec_rule *rule; 432 int mib[4]; 433 size_t need; 434 char *buf, *lim, *next; 435 436 mib[0] = CTL_NET; 437 mib[1] = PF_KEY; 438 mib[2] = PF_KEY_V2; 439 mib[3] = NET_KEY_SPD_DUMP; 440 441 if (sysctl(mib, 4, NULL, &need, NULL, 0) == -1) 442 err(1, "ipsecctl_get_rules: sysctl"); 443 if (need == 0) 444 return; 445 if ((buf = malloc(need)) == NULL) 446 err(1, "ipsecctl_get_rules: malloc"); 447 if (sysctl(mib, 4, buf, &need, NULL, 0) == -1) 448 err(1, "ipsecctl_get_rules: sysctl"); 449 lim = buf + need; 450 451 for (next = buf; next < lim; next += msg->sadb_msg_len * 452 PFKEYV2_CHUNK) { 453 msg = (struct sadb_msg *)next; 454 if (msg->sadb_msg_len == 0) 455 break; 456 457 rule = calloc(1, sizeof(struct ipsec_rule)); 458 if (rule == NULL) 459 err(1, "ipsecctl_get_rules: calloc"); 460 rule->nr = ipsec->rule_nr++; 461 rule->type |= RULE_FLOW; 462 463 if (pfkey_parse(msg, rule)) 464 errx(1, "ipsecctl_get_rules: " 465 "failed to parse PF_KEY message"); 466 467 ipsecctl_add_rule(ipsec, rule); 468 } 469 470 free(buf); 471 } 472 473 void 474 ipsecctl_print_title(char *title) 475 { 476 if (!first_title) 477 printf("\n"); 478 first_title = 0; 479 printf("%s\n", title); 480 } 481 482 void 483 ipsecctl_show_flows(int opts) 484 { 485 struct ipsecctl ipsec; 486 struct ipsec_rule *rp; 487 488 bzero(&ipsec, sizeof(ipsec)); 489 ipsec.opts = opts; 490 TAILQ_INIT(&ipsec.rule_queue); 491 492 ipsecctl_get_rules(&ipsec); 493 494 if (opts & IPSECCTL_OPT_SHOWALL) 495 ipsecctl_print_title("FLOWS:"); 496 497 if (TAILQ_FIRST(&ipsec.rule_queue) == 0) { 498 if (opts & IPSECCTL_OPT_SHOWALL) 499 printf("No flows\n"); 500 return; 501 } 502 503 while ((rp = TAILQ_FIRST(&ipsec.rule_queue))) { 504 TAILQ_REMOVE(&ipsec.rule_queue, rp, rule_entry); 505 506 ipsecctl_print_rule(rp, ipsec.opts); 507 508 free(rp->src->name); 509 free(rp->src); 510 free(rp->dst->name); 511 free(rp->dst); 512 if (rp->local) { 513 free(rp->local->name); 514 free(rp->local); 515 } 516 if (rp->peer) { 517 free(rp->peer->name); 518 free(rp->peer); 519 } 520 if (rp->auth) { 521 free(rp->auth->srcid); 522 free(rp->auth->dstid); 523 free(rp->auth); 524 } 525 free(rp); 526 } 527 } 528 529 void 530 ipsecctl_show_sas(int opts) 531 { 532 struct sadb_msg *msg; 533 struct sad *sad; 534 int mib[5], sacount, i; 535 size_t need = 0; 536 char *buf, *lim, *next; 537 538 mib[0] = CTL_NET; 539 mib[1] = PF_KEY; 540 mib[2] = PF_KEY_V2; 541 mib[3] = NET_KEY_SADB_DUMP; 542 mib[4] = SADB_SATYPE_UNSPEC; 543 544 if (opts & IPSECCTL_OPT_SHOWALL) 545 ipsecctl_print_title("SAD:"); 546 547 /* When the SAD is empty we get ENOENT, no need to err(). */ 548 if (sysctl(mib, 5, NULL, &need, NULL, 0) == -1 && errno != ENOENT) 549 err(1, "ipsecctl_show_sas: sysctl"); 550 if (need == 0) { 551 if (opts & IPSECCTL_OPT_SHOWALL) 552 printf("No entries\n"); 553 return; 554 } 555 if ((buf = malloc(need)) == NULL) 556 err(1, "ipsecctl_show_sas: malloc"); 557 if (sysctl(mib, 5, buf, &need, NULL, 0) == -1) 558 err(1, "ipsecctl_show_sas: sysctl"); 559 sacount = 0; 560 lim = buf + need; 561 for (next = buf; next < lim; 562 next += msg->sadb_msg_len * PFKEYV2_CHUNK) { 563 msg = (struct sadb_msg *)next; 564 if (msg->sadb_msg_len == 0) 565 break; 566 sacount++; 567 } 568 if ((sad = calloc(sacount, sizeof(*sad))) == NULL) 569 err(1, "ipsecctl_show_sas: calloc"); 570 i = 0; 571 for (next = buf; next < lim; 572 next += msg->sadb_msg_len * PFKEYV2_CHUNK) { 573 msg = (struct sadb_msg *)next; 574 if (msg->sadb_msg_len == 0) 575 break; 576 sad[i].sad_spi = pfkey_get_spi(msg); 577 sad[i].sad_msg = msg; 578 i++; 579 } 580 qsort(sad, sacount, sizeof(*sad), sacompare); 581 for (i = 0; i < sacount; i++) 582 pfkey_print_sa(sad[i].sad_msg, opts); 583 free(sad); 584 free(buf); 585 } 586 587 int 588 ipsecctl_monitor(int opts) 589 { 590 return (pfkey_monitor(opts)); 591 } 592 593 __dead void 594 usage(void) 595 { 596 extern char *__progname; 597 598 fprintf(stderr, "usage: %s [-dFkmnv] [-D macro=value] [-f file]" 599 " [-i fifo] [-s modifier]\n", __progname); 600 exit(1); 601 } 602 603 const char * 604 ipsecctl_lookup_option(char *cmd, const char **list) 605 { 606 if (cmd != NULL && *cmd) 607 for (; *list; list++) 608 if (!strncmp(cmd, *list, strlen(cmd))) 609 return (*list); 610 return (NULL); 611 } 612 613 int 614 main(int argc, char *argv[]) 615 { 616 int error = 0; 617 int ch; 618 int opts = 0; 619 char *rulesopt = NULL; 620 621 if (argc < 2) 622 usage(); 623 624 while ((ch = getopt(argc, argv, "D:df:Fi:kmnvs:")) != -1) { 625 switch (ch) { 626 case 'D': 627 if (cmdline_symset(optarg) < 0) 628 warnx("could not parse macro definition %s", 629 optarg); 630 break; 631 632 case 'd': 633 opts |= IPSECCTL_OPT_DELETE; 634 break; 635 636 case 'f': 637 rulesopt = optarg; 638 break; 639 640 case 'F': 641 opts |= IPSECCTL_OPT_FLUSH; 642 break; 643 644 case 'i': 645 isakmpd_fifo = optarg; 646 break; 647 648 case 'k': 649 opts |= IPSECCTL_OPT_SHOWKEY; 650 break; 651 652 case 'm': 653 opts |= IPSECCTL_OPT_MONITOR; 654 break; 655 656 case 'n': 657 opts |= IPSECCTL_OPT_NOACTION; 658 break; 659 660 case 'v': 661 if (opts & IPSECCTL_OPT_VERBOSE) 662 opts |= IPSECCTL_OPT_VERBOSE2; 663 opts |= IPSECCTL_OPT_VERBOSE; 664 break; 665 666 case 's': 667 showopt = ipsecctl_lookup_option(optarg, showopt_list); 668 if (showopt == NULL) { 669 warnx("Unknown show modifier '%s'", optarg); 670 usage(); 671 /* NOTREACHED */ 672 } 673 opts |= IPSECCTL_OPT_SHOW; 674 break; 675 676 default: 677 usage(); 678 /* NOTREACHED */ 679 } 680 } 681 682 if (argc != optind) { 683 warnx("unknown command line argument: %s ...", argv[optind]); 684 usage(); 685 /* NOTREACHED */ 686 } 687 if (opts & IPSECCTL_OPT_FLUSH) 688 if (ipsecctl_flush(opts)) 689 error = 1; 690 691 if (rulesopt != NULL) 692 if (ipsecctl_rules(rulesopt, opts)) 693 error = 1; 694 695 if (showopt != NULL) { 696 switch (*showopt) { 697 case 'f': 698 ipsecctl_show_flows(opts); 699 break; 700 case 's': 701 ipsecctl_show_sas(opts); 702 break; 703 case 'a': 704 opts |= IPSECCTL_OPT_SHOWALL; 705 ipsecctl_show_flows(opts); 706 ipsecctl_show_sas(opts); 707 } 708 } 709 710 if (opts & IPSECCTL_OPT_MONITOR) 711 if (ipsecctl_monitor(opts)) 712 error = 1; 713 714 exit(error); 715 } 716 717 /* ARGSUSED1 */ 718 static int 719 unmask(struct ipsec_addr *ipa, sa_family_t af) 720 { 721 int i = 31, j = 0, b = 0; 722 u_int32_t tmp; 723 724 while (j < 4 && ipa->addr32[j] == 0xffffffff) { 725 b += 32; 726 j++; 727 } 728 if (j < 4) { 729 tmp = ntohl(ipa->addr32[j]); 730 for (i = 31; tmp & (1 << i); --i) 731 b++; 732 } 733 return (b); 734 } 735