1 /* $OpenBSD: ipsecctl.c,v 1.80 2015/12/10 17:27:00 mmcc 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 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_sagroup(struct ipsec_rule *r, int opts) 386 { 387 if (!(opts & IPSECCTL_OPT_VERBOSE2)) 388 return; 389 390 printf("[group %s to ", satype[r->proto]); 391 ipsecctl_print_addr(r->dst); 392 printf(" spi 0x%08x with %s to ", r->spi, satype[r->proto2]); 393 ipsecctl_print_addr(r->dst2); 394 printf(" spi 0x%08x", r->spi2); 395 396 printf("]\n"); 397 } 398 399 void 400 ipsecctl_print_rule(struct ipsec_rule *r, int opts) 401 { 402 if (opts & IPSECCTL_OPT_VERBOSE2) 403 printf("@%d ", r->nr); 404 405 if (r->type & RULE_FLOW) 406 ipsecctl_print_flow(r, opts); 407 if (r->type & RULE_SA) 408 ipsecctl_print_sa(r, opts); 409 if (r->type & RULE_IKE) 410 ike_print_config(r, opts); 411 if (r->type & RULE_GROUP) 412 ipsecctl_print_sagroup(r, opts); 413 } 414 415 int 416 ipsecctl_flush(int opts) 417 { 418 if (opts & IPSECCTL_OPT_NOACTION) 419 return (0); 420 421 if (pfkey_init() == -1) 422 errx(1, "ipsecctl_flush: failed to open PF_KEY socket"); 423 424 if (pfkey_ipsec_flush() == -1) 425 errx(1, "ipsecctl_flush: failed to flush"); 426 427 return (0); 428 } 429 430 void 431 ipsecctl_get_rules(struct ipsecctl *ipsec) 432 { 433 struct sadb_msg *msg; 434 struct ipsec_rule *rule; 435 int mib[4]; 436 size_t need; 437 char *buf, *lim, *next; 438 439 mib[0] = CTL_NET; 440 mib[1] = PF_KEY; 441 mib[2] = PF_KEY_V2; 442 mib[3] = NET_KEY_SPD_DUMP; 443 444 if (sysctl(mib, 4, NULL, &need, NULL, 0) == -1) 445 err(1, "ipsecctl_get_rules: sysctl"); 446 if (need == 0) 447 return; 448 if ((buf = malloc(need)) == NULL) 449 err(1, "ipsecctl_get_rules: malloc"); 450 if (sysctl(mib, 4, buf, &need, NULL, 0) == -1) 451 err(1, "ipsecctl_get_rules: sysctl"); 452 lim = buf + need; 453 454 for (next = buf; next < lim; next += msg->sadb_msg_len * 455 PFKEYV2_CHUNK) { 456 msg = (struct sadb_msg *)next; 457 if (msg->sadb_msg_len == 0) 458 break; 459 460 rule = calloc(1, sizeof(struct ipsec_rule)); 461 if (rule == NULL) 462 err(1, "ipsecctl_get_rules: calloc"); 463 rule->nr = ipsec->rule_nr++; 464 rule->type |= RULE_FLOW; 465 466 if (pfkey_parse(msg, rule)) 467 errx(1, "ipsecctl_get_rules: " 468 "failed to parse PF_KEY message"); 469 470 ipsecctl_add_rule(ipsec, rule); 471 } 472 473 free(buf); 474 } 475 476 void 477 ipsecctl_print_title(char *title) 478 { 479 if (!first_title) 480 printf("\n"); 481 first_title = 0; 482 printf("%s\n", title); 483 } 484 485 void 486 ipsecctl_show_flows(int opts) 487 { 488 struct ipsecctl ipsec; 489 struct ipsec_rule *rp; 490 491 bzero(&ipsec, sizeof(ipsec)); 492 ipsec.opts = opts; 493 TAILQ_INIT(&ipsec.rule_queue); 494 495 ipsecctl_get_rules(&ipsec); 496 497 if (opts & IPSECCTL_OPT_SHOWALL) 498 ipsecctl_print_title("FLOWS:"); 499 500 if (TAILQ_FIRST(&ipsec.rule_queue) == 0) { 501 if (opts & IPSECCTL_OPT_SHOWALL) 502 printf("No flows\n"); 503 return; 504 } 505 506 while ((rp = TAILQ_FIRST(&ipsec.rule_queue))) { 507 TAILQ_REMOVE(&ipsec.rule_queue, rp, rule_entry); 508 509 ipsecctl_print_rule(rp, ipsec.opts); 510 511 free(rp->src->name); 512 free(rp->src); 513 free(rp->dst->name); 514 free(rp->dst); 515 if (rp->local) { 516 free(rp->local->name); 517 free(rp->local); 518 } 519 if (rp->peer) { 520 free(rp->peer->name); 521 free(rp->peer); 522 } 523 if (rp->auth) { 524 free(rp->auth->srcid); 525 free(rp->auth->dstid); 526 free(rp->auth); 527 } 528 free(rp); 529 } 530 } 531 532 void 533 ipsecctl_show_sas(int opts) 534 { 535 struct sadb_msg *msg; 536 struct sad *sad; 537 int mib[5], sacount, i; 538 size_t need = 0; 539 char *buf, *lim, *next; 540 541 mib[0] = CTL_NET; 542 mib[1] = PF_KEY; 543 mib[2] = PF_KEY_V2; 544 mib[3] = NET_KEY_SADB_DUMP; 545 mib[4] = SADB_SATYPE_UNSPEC; 546 547 if (opts & IPSECCTL_OPT_SHOWALL) 548 ipsecctl_print_title("SAD:"); 549 550 /* When the SAD is empty we get ENOENT, no need to err(). */ 551 if (sysctl(mib, 5, NULL, &need, NULL, 0) == -1 && errno != ENOENT) 552 err(1, "ipsecctl_show_sas: sysctl"); 553 if (need == 0) { 554 if (opts & IPSECCTL_OPT_SHOWALL) 555 printf("No entries\n"); 556 return; 557 } 558 if ((buf = malloc(need)) == NULL) 559 err(1, "ipsecctl_show_sas: malloc"); 560 if (sysctl(mib, 5, buf, &need, NULL, 0) == -1) 561 err(1, "ipsecctl_show_sas: sysctl"); 562 sacount = 0; 563 lim = buf + need; 564 for (next = buf; next < lim; 565 next += msg->sadb_msg_len * PFKEYV2_CHUNK) { 566 msg = (struct sadb_msg *)next; 567 if (msg->sadb_msg_len == 0) 568 break; 569 sacount++; 570 } 571 if ((sad = calloc(sacount, sizeof(*sad))) == NULL) 572 err(1, "ipsecctl_show_sas: calloc"); 573 i = 0; 574 for (next = buf; next < lim; 575 next += msg->sadb_msg_len * PFKEYV2_CHUNK) { 576 msg = (struct sadb_msg *)next; 577 if (msg->sadb_msg_len == 0) 578 break; 579 sad[i].sad_spi = pfkey_get_spi(msg); 580 sad[i].sad_msg = msg; 581 i++; 582 } 583 qsort(sad, sacount, sizeof(*sad), sacompare); 584 for (i = 0; i < sacount; i++) 585 pfkey_print_sa(sad[i].sad_msg, opts); 586 free(sad); 587 free(buf); 588 } 589 590 int 591 ipsecctl_monitor(int opts) 592 { 593 return (pfkey_monitor(opts)); 594 } 595 596 __dead void 597 usage(void) 598 { 599 extern char *__progname; 600 601 fprintf(stderr, "usage: %s [-dFkmnv] [-D macro=value] [-f file]" 602 " [-i fifo] [-s modifier]\n", __progname); 603 exit(1); 604 } 605 606 const char * 607 ipsecctl_lookup_option(char *cmd, const char **list) 608 { 609 if (cmd != NULL && *cmd) 610 for (; *list; list++) 611 if (!strncmp(cmd, *list, strlen(cmd))) 612 return (*list); 613 return (NULL); 614 } 615 616 int 617 main(int argc, char *argv[]) 618 { 619 int error = 0; 620 int ch; 621 int opts = 0; 622 char *rulesopt = NULL; 623 624 if (argc < 2) 625 usage(); 626 627 while ((ch = getopt(argc, argv, "D:df:Fi:kmnvs:")) != -1) { 628 switch (ch) { 629 case 'D': 630 if (cmdline_symset(optarg) < 0) 631 warnx("could not parse macro definition %s", 632 optarg); 633 break; 634 635 case 'd': 636 opts |= IPSECCTL_OPT_DELETE; 637 break; 638 639 case 'f': 640 rulesopt = optarg; 641 break; 642 643 case 'F': 644 opts |= IPSECCTL_OPT_FLUSH; 645 break; 646 647 case 'i': 648 isakmpd_fifo = optarg; 649 break; 650 651 case 'k': 652 opts |= IPSECCTL_OPT_SHOWKEY; 653 break; 654 655 case 'm': 656 opts |= IPSECCTL_OPT_MONITOR; 657 break; 658 659 case 'n': 660 opts |= IPSECCTL_OPT_NOACTION; 661 break; 662 663 case 'v': 664 if (opts & IPSECCTL_OPT_VERBOSE) 665 opts |= IPSECCTL_OPT_VERBOSE2; 666 opts |= IPSECCTL_OPT_VERBOSE; 667 break; 668 669 case 's': 670 showopt = ipsecctl_lookup_option(optarg, showopt_list); 671 if (showopt == NULL) { 672 warnx("Unknown show modifier '%s'", optarg); 673 usage(); 674 /* NOTREACHED */ 675 } 676 opts |= IPSECCTL_OPT_SHOW; 677 break; 678 679 default: 680 usage(); 681 /* NOTREACHED */ 682 } 683 } 684 685 if (argc != optind) { 686 warnx("unknown command line argument: %s ...", argv[optind]); 687 usage(); 688 /* NOTREACHED */ 689 } 690 if (opts & IPSECCTL_OPT_FLUSH) 691 if (ipsecctl_flush(opts)) 692 error = 1; 693 694 if (rulesopt != NULL) 695 if (ipsecctl_rules(rulesopt, opts)) 696 error = 1; 697 698 if (showopt != NULL) { 699 switch (*showopt) { 700 case 'f': 701 ipsecctl_show_flows(opts); 702 break; 703 case 's': 704 ipsecctl_show_sas(opts); 705 break; 706 case 'a': 707 opts |= IPSECCTL_OPT_SHOWALL; 708 ipsecctl_show_flows(opts); 709 ipsecctl_show_sas(opts); 710 } 711 } 712 713 if (opts & IPSECCTL_OPT_MONITOR) 714 if (ipsecctl_monitor(opts)) 715 error = 1; 716 717 exit(error); 718 } 719 720 /* ARGSUSED1 */ 721 static int 722 unmask(struct ipsec_addr *ipa, sa_family_t af) 723 { 724 int i = 31, j = 0, b = 0; 725 u_int32_t tmp; 726 727 while (j < 4 && ipa->addr32[j] == 0xffffffff) { 728 b += 32; 729 j++; 730 } 731 if (j < 4) { 732 tmp = ntohl(ipa->addr32[j]); 733 for (i = 31; tmp & (1 << i); --i) 734 b++; 735 } 736 return (b); 737 } 738