1 /* $OpenBSD: ipsecctl.c,v 1.79 2015/01/16 06:39:58 deraadt 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_sagroup(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.group_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.group_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 if (rp->auth->srcid) 221 free(rp->auth->srcid); 222 if (rp->auth->dstid) 223 free(rp->auth->dstid); 224 free(rp->auth); 225 } 226 if (rp->ikeauth) { 227 if (rp->ikeauth->string) 228 free(rp->ikeauth->string); 229 free(rp->ikeauth); 230 } 231 if (rp->xfs) 232 free(rp->xfs); 233 if (rp->p1xfs) 234 free(rp->p1xfs); 235 if (rp->p2xfs) 236 free(rp->p2xfs); 237 if (rp->p1life) 238 free(rp->p1life); 239 if (rp->p2life) 240 free(rp->p2life); 241 if (rp->authkey) { 242 free(rp->authkey->data); 243 free(rp->authkey); 244 } 245 if (rp->enckey) { 246 free(rp->enckey->data); 247 free(rp->enckey); 248 } 249 if (rp->p1name) 250 free(rp->p1name); 251 if (rp->p2name) 252 free(rp->p2name); 253 if (rp->p2lid) 254 free(rp->p2lid); 255 if (rp->p2nid) 256 free(rp->p2nid); 257 if (rp->p2rid) 258 free(rp->p2rid); 259 free(rp); 260 } 261 262 void 263 ipsecctl_print_addr(struct ipsec_addr_wrap *ipa) 264 { 265 int bits; 266 char buf[NI_MAXHOST]; 267 268 if (ipa == NULL) { 269 printf("?"); 270 return; 271 } 272 if (inet_ntop(ipa->af, &ipa->address, buf, sizeof(buf)) == NULL) 273 printf("?"); 274 else 275 printf("%s", buf); 276 277 bits = unmask(&ipa->mask, ipa->af); 278 if (bits != (ipa->af == AF_INET ? 32 : 128)) 279 printf("/%d", bits); 280 } 281 282 void 283 ipsecctl_print_proto(u_int8_t proto) 284 { 285 struct protoent *p; 286 287 if ((p = getprotobynumber(proto)) != NULL) 288 printf("%s", p->p_name); 289 else 290 printf("%u", proto); 291 } 292 293 void 294 ipsecctl_print_port(u_int16_t port, const char *proto) 295 { 296 struct servent *s; 297 298 if ((s = getservbyport(port, proto)) != NULL) 299 printf("%s", s->s_name); 300 else 301 printf("%u", ntohs(port)); 302 } 303 304 void 305 ipsecctl_print_key(struct ipsec_key *key) 306 { 307 int i; 308 309 for (i = 0; i < (int)key->len; i++) 310 printf("%02x", key->data[i]); 311 } 312 313 void 314 ipsecctl_print_flow(struct ipsec_rule *r, int opts) 315 { 316 printf("flow %s %s", satype[r->satype], direction[r->direction]); 317 318 if (r->proto) { 319 printf(" proto "); 320 ipsecctl_print_proto(r->proto); 321 } 322 printf(" from "); 323 ipsecctl_print_addr(r->src); 324 if (r->sport) { 325 printf(" port "); 326 ipsecctl_print_port(r->sport, 327 r->proto == IPPROTO_TCP ? "tcp" : "udp"); 328 } 329 printf(" to "); 330 ipsecctl_print_addr(r->dst); 331 if (r->dport) { 332 printf(" port "); 333 ipsecctl_print_port(r->dport, 334 r->proto == IPPROTO_TCP ? "tcp" : "udp"); 335 } 336 if (r->local) { 337 printf(" local "); 338 ipsecctl_print_addr(r->local); 339 } 340 if (r->peer) { 341 printf(" peer "); 342 ipsecctl_print_addr(r->peer); 343 } 344 if (r->auth) { 345 if (r->auth->srcid) 346 printf(" srcid %s", r->auth->srcid); 347 if (r->auth->dstid) 348 printf(" dstid %s", r->auth->dstid); 349 if (r->auth->type > 0) 350 printf(" %s", auth[r->auth->type]); 351 } 352 printf(" type %s", flowtype[r->flowtype]); 353 printf("\n"); 354 } 355 356 /* ARGSUSED1 */ 357 void 358 ipsecctl_print_sa(struct ipsec_rule *r, int opts) 359 { 360 printf("%s ", satype[r->satype]); 361 /* tunnel/transport is only meaningful for esp/ah/ipcomp */ 362 if (r->satype != IPSEC_TCPMD5 && r->satype != IPSEC_IPIP) 363 printf("%s ", tmode[r->tmode]); 364 printf("from "); 365 ipsecctl_print_addr(r->src); 366 printf(" to "); 367 ipsecctl_print_addr(r->dst); 368 printf(" spi 0x%08x", r->spi); 369 370 if (r->satype != IPSEC_TCPMD5) { 371 if (r->xfs && r->xfs->authxf) 372 printf(" auth %s", r->xfs->authxf->name); 373 if (r->xfs && r->xfs->encxf) 374 printf(" enc %s", r->xfs->encxf->name); 375 if (r->xfs && r->xfs->compxf) 376 printf(" comp %s", r->xfs->compxf->name); 377 } 378 if (r->authkey && (opts & IPSECCTL_OPT_SHOWKEY)) { 379 if (r->satype == IPSEC_TCPMD5) 380 printf(" "); 381 else 382 printf(" \\\n\t"); 383 printf("authkey 0x"); 384 ipsecctl_print_key(r->authkey); 385 } 386 if (r->enckey && (opts & IPSECCTL_OPT_SHOWKEY)) { 387 if (r->satype == IPSEC_TCPMD5) 388 printf(" "); 389 else 390 printf(" \\\n\t"); 391 printf("enckey 0x"); 392 ipsecctl_print_key(r->enckey); 393 } 394 printf("\n"); 395 } 396 397 void 398 ipsecctl_print_sagroup(struct ipsec_rule *r, int opts) 399 { 400 if (!(opts & IPSECCTL_OPT_VERBOSE2)) 401 return; 402 403 printf("[group %s to ", satype[r->proto]); 404 ipsecctl_print_addr(r->dst); 405 printf(" spi 0x%08x with %s to ", r->spi, satype[r->proto2]); 406 ipsecctl_print_addr(r->dst2); 407 printf(" spi 0x%08x", r->spi2); 408 409 printf("]\n"); 410 } 411 412 void 413 ipsecctl_print_rule(struct ipsec_rule *r, int opts) 414 { 415 if (opts & IPSECCTL_OPT_VERBOSE2) 416 printf("@%d ", r->nr); 417 418 if (r->type & RULE_FLOW) 419 ipsecctl_print_flow(r, opts); 420 if (r->type & RULE_SA) 421 ipsecctl_print_sa(r, opts); 422 if (r->type & RULE_IKE) 423 ike_print_config(r, opts); 424 if (r->type & RULE_GROUP) 425 ipsecctl_print_sagroup(r, opts); 426 } 427 428 int 429 ipsecctl_flush(int opts) 430 { 431 if (opts & IPSECCTL_OPT_NOACTION) 432 return (0); 433 434 if (pfkey_init() == -1) 435 errx(1, "ipsecctl_flush: failed to open PF_KEY socket"); 436 437 if (pfkey_ipsec_flush() == -1) 438 errx(1, "ipsecctl_flush: failed to flush"); 439 440 return (0); 441 } 442 443 void 444 ipsecctl_get_rules(struct ipsecctl *ipsec) 445 { 446 struct sadb_msg *msg; 447 struct ipsec_rule *rule; 448 int mib[4]; 449 size_t need; 450 char *buf, *lim, *next; 451 452 mib[0] = CTL_NET; 453 mib[1] = PF_KEY; 454 mib[2] = PF_KEY_V2; 455 mib[3] = NET_KEY_SPD_DUMP; 456 457 if (sysctl(mib, 4, NULL, &need, NULL, 0) == -1) 458 err(1, "ipsecctl_get_rules: sysctl"); 459 if (need == 0) 460 return; 461 if ((buf = malloc(need)) == NULL) 462 err(1, "ipsecctl_get_rules: malloc"); 463 if (sysctl(mib, 4, buf, &need, NULL, 0) == -1) 464 err(1, "ipsecctl_get_rules: sysctl"); 465 lim = buf + need; 466 467 for (next = buf; next < lim; next += msg->sadb_msg_len * 468 PFKEYV2_CHUNK) { 469 msg = (struct sadb_msg *)next; 470 if (msg->sadb_msg_len == 0) 471 break; 472 473 rule = calloc(1, sizeof(struct ipsec_rule)); 474 if (rule == NULL) 475 err(1, "ipsecctl_get_rules: calloc"); 476 rule->nr = ipsec->rule_nr++; 477 rule->type |= RULE_FLOW; 478 479 if (pfkey_parse(msg, rule)) 480 errx(1, "ipsecctl_get_rules: " 481 "failed to parse PF_KEY message"); 482 483 ipsecctl_add_rule(ipsec, rule); 484 } 485 486 free(buf); 487 } 488 489 void 490 ipsecctl_print_title(char *title) 491 { 492 if (!first_title) 493 printf("\n"); 494 first_title = 0; 495 printf("%s\n", title); 496 } 497 498 void 499 ipsecctl_show_flows(int opts) 500 { 501 struct ipsecctl ipsec; 502 struct ipsec_rule *rp; 503 504 bzero(&ipsec, sizeof(ipsec)); 505 ipsec.opts = opts; 506 TAILQ_INIT(&ipsec.rule_queue); 507 508 ipsecctl_get_rules(&ipsec); 509 510 if (opts & IPSECCTL_OPT_SHOWALL) 511 ipsecctl_print_title("FLOWS:"); 512 513 if (TAILQ_FIRST(&ipsec.rule_queue) == 0) { 514 if (opts & IPSECCTL_OPT_SHOWALL) 515 printf("No flows\n"); 516 return; 517 } 518 519 while ((rp = TAILQ_FIRST(&ipsec.rule_queue))) { 520 TAILQ_REMOVE(&ipsec.rule_queue, rp, rule_entry); 521 522 ipsecctl_print_rule(rp, ipsec.opts); 523 524 free(rp->src->name); 525 free(rp->src); 526 free(rp->dst->name); 527 free(rp->dst); 528 if (rp->local) { 529 free(rp->local->name); 530 free(rp->local); 531 } 532 if (rp->peer) { 533 free(rp->peer->name); 534 free(rp->peer); 535 } 536 if (rp->auth) { 537 if (rp->auth->srcid) 538 free(rp->auth->srcid); 539 if (rp->auth->dstid) 540 free(rp->auth->dstid); 541 free(rp->auth); 542 } 543 free(rp); 544 } 545 } 546 547 void 548 ipsecctl_show_sas(int opts) 549 { 550 struct sadb_msg *msg; 551 struct sad *sad; 552 int mib[5], sacount, i; 553 size_t need = 0; 554 char *buf, *lim, *next; 555 556 mib[0] = CTL_NET; 557 mib[1] = PF_KEY; 558 mib[2] = PF_KEY_V2; 559 mib[3] = NET_KEY_SADB_DUMP; 560 mib[4] = SADB_SATYPE_UNSPEC; 561 562 if (opts & IPSECCTL_OPT_SHOWALL) 563 ipsecctl_print_title("SAD:"); 564 565 /* When the SAD is empty we get ENOENT, no need to err(). */ 566 if (sysctl(mib, 5, NULL, &need, NULL, 0) == -1 && errno != ENOENT) 567 err(1, "ipsecctl_show_sas: sysctl"); 568 if (need == 0) { 569 if (opts & IPSECCTL_OPT_SHOWALL) 570 printf("No entries\n"); 571 return; 572 } 573 if ((buf = malloc(need)) == NULL) 574 err(1, "ipsecctl_show_sas: malloc"); 575 if (sysctl(mib, 5, buf, &need, NULL, 0) == -1) 576 err(1, "ipsecctl_show_sas: sysctl"); 577 sacount = 0; 578 lim = buf + need; 579 for (next = buf; next < lim; 580 next += msg->sadb_msg_len * PFKEYV2_CHUNK) { 581 msg = (struct sadb_msg *)next; 582 if (msg->sadb_msg_len == 0) 583 break; 584 sacount++; 585 } 586 if ((sad = calloc(sacount, sizeof(*sad))) == NULL) 587 err(1, "ipsecctl_show_sas: calloc"); 588 i = 0; 589 for (next = buf; next < lim; 590 next += msg->sadb_msg_len * PFKEYV2_CHUNK) { 591 msg = (struct sadb_msg *)next; 592 if (msg->sadb_msg_len == 0) 593 break; 594 sad[i].sad_spi = pfkey_get_spi(msg); 595 sad[i].sad_msg = msg; 596 i++; 597 } 598 qsort(sad, sacount, sizeof(*sad), sacompare); 599 for (i = 0; i < sacount; i++) 600 pfkey_print_sa(sad[i].sad_msg, opts); 601 free(sad); 602 free(buf); 603 } 604 605 int 606 ipsecctl_monitor(int opts) 607 { 608 return (pfkey_monitor(opts)); 609 } 610 611 __dead void 612 usage(void) 613 { 614 extern char *__progname; 615 616 fprintf(stderr, "usage: %s [-dFkmnv] [-D macro=value] [-f file]" 617 " [-i fifo] [-s modifier]\n", __progname); 618 exit(1); 619 } 620 621 const char * 622 ipsecctl_lookup_option(char *cmd, const char **list) 623 { 624 if (cmd != NULL && *cmd) 625 for (; *list; list++) 626 if (!strncmp(cmd, *list, strlen(cmd))) 627 return (*list); 628 return (NULL); 629 } 630 631 int 632 main(int argc, char *argv[]) 633 { 634 int error = 0; 635 int ch; 636 int opts = 0; 637 char *rulesopt = NULL; 638 639 if (argc < 2) 640 usage(); 641 642 while ((ch = getopt(argc, argv, "D:df:Fi:kmnvs:")) != -1) { 643 switch (ch) { 644 case 'D': 645 if (cmdline_symset(optarg) < 0) 646 warnx("could not parse macro definition %s", 647 optarg); 648 break; 649 650 case 'd': 651 opts |= IPSECCTL_OPT_DELETE; 652 break; 653 654 case 'f': 655 rulesopt = optarg; 656 break; 657 658 case 'F': 659 opts |= IPSECCTL_OPT_FLUSH; 660 break; 661 662 case 'i': 663 isakmpd_fifo = optarg; 664 break; 665 666 case 'k': 667 opts |= IPSECCTL_OPT_SHOWKEY; 668 break; 669 670 case 'm': 671 opts |= IPSECCTL_OPT_MONITOR; 672 break; 673 674 case 'n': 675 opts |= IPSECCTL_OPT_NOACTION; 676 break; 677 678 case 'v': 679 if (opts & IPSECCTL_OPT_VERBOSE) 680 opts |= IPSECCTL_OPT_VERBOSE2; 681 opts |= IPSECCTL_OPT_VERBOSE; 682 break; 683 684 case 's': 685 showopt = ipsecctl_lookup_option(optarg, showopt_list); 686 if (showopt == NULL) { 687 warnx("Unknown show modifier '%s'", optarg); 688 usage(); 689 /* NOTREACHED */ 690 } 691 opts |= IPSECCTL_OPT_SHOW; 692 break; 693 694 default: 695 usage(); 696 /* NOTREACHED */ 697 } 698 } 699 700 if (argc != optind) { 701 warnx("unknown command line argument: %s ...", argv[optind]); 702 usage(); 703 /* NOTREACHED */ 704 } 705 if (opts & IPSECCTL_OPT_FLUSH) 706 if (ipsecctl_flush(opts)) 707 error = 1; 708 709 if (rulesopt != NULL) 710 if (ipsecctl_rules(rulesopt, opts)) 711 error = 1; 712 713 if (showopt != NULL) { 714 switch (*showopt) { 715 case 'f': 716 ipsecctl_show_flows(opts); 717 break; 718 case 's': 719 ipsecctl_show_sas(opts); 720 break; 721 case 'a': 722 opts |= IPSECCTL_OPT_SHOWALL; 723 ipsecctl_show_flows(opts); 724 ipsecctl_show_sas(opts); 725 } 726 } 727 728 if (opts & IPSECCTL_OPT_MONITOR) 729 if (ipsecctl_monitor(opts)) 730 error = 1; 731 732 exit(error); 733 } 734 735 /* ARGSUSED1 */ 736 static int 737 unmask(struct ipsec_addr *ipa, sa_family_t af) 738 { 739 int i = 31, j = 0, b = 0; 740 u_int32_t tmp; 741 742 while (j < 4 && ipa->addr32[j] == 0xffffffff) { 743 b += 32; 744 j++; 745 } 746 if (j < 4) { 747 tmp = ntohl(ipa->addr32[j]); 748 for (i = 31; tmp & (1 << i); --i) 749 b++; 750 } 751 return (b); 752 } 753