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