1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 * 21 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 22 * Use is subject to license terms. 23 */ 24 25 #include <unistd.h> 26 #include <stdio.h> 27 #include <stdarg.h> 28 #include <stdlib.h> 29 #include <sys/sysconf.h> 30 #include <string.h> 31 #include <strings.h> 32 #include <libintl.h> 33 #include <locale.h> 34 #include <ctype.h> 35 #include <time.h> 36 #include <sys/sysmacros.h> 37 #include <sys/stat.h> 38 #include <sys/mman.h> 39 #include <fcntl.h> 40 #include <sys/socket.h> 41 #include <netdb.h> 42 #include <errno.h> 43 #include <assert.h> 44 #include <netinet/in.h> 45 #include <arpa/inet.h> 46 #include <door.h> 47 #include <setjmp.h> 48 49 #include <ipsec_util.h> 50 #include <ikedoor.h> 51 52 static int doorfd = -1; 53 54 /* 55 * These are additional return values for the command line parsing 56 * function (parsecmd()). They are specific to this utility, but 57 * need to share the same space as the IKE_SVC_* defs, without conflicts. 58 * So they're defined relative to the end of that range. 59 */ 60 #define IKEADM_HELP_GENERAL IKE_SVC_MAX + 1 61 #define IKEADM_HELP_GET IKE_SVC_MAX + 2 62 #define IKEADM_HELP_SET IKE_SVC_MAX + 3 63 #define IKEADM_HELP_ADD IKE_SVC_MAX + 4 64 #define IKEADM_HELP_DEL IKE_SVC_MAX + 5 65 #define IKEADM_HELP_DUMP IKE_SVC_MAX + 6 66 #define IKEADM_HELP_FLUSH IKE_SVC_MAX + 7 67 #define IKEADM_HELP_READ IKE_SVC_MAX + 8 68 #define IKEADM_HELP_WRITE IKE_SVC_MAX + 9 69 #define IKEADM_HELP_TOKEN IKE_SVC_MAX + 10 70 #define IKEADM_HELP_HELP IKE_SVC_MAX + 11 71 #define IKEADM_EXIT IKE_SVC_MAX + 12 72 73 /* 74 * Disable default TAB completion for now (until some brave soul tackles it). 75 */ 76 /* ARGSUSED */ 77 static 78 CPL_MATCH_FN(no_match) 79 { 80 return (0); 81 } 82 83 static void 84 command_complete(int s) 85 { 86 if (interactive) { 87 longjmp(env, 1); 88 } else { 89 exit(s); 90 } 91 } 92 93 static void 94 usage() 95 { 96 if (!interactive) { 97 (void) fprintf(stderr, gettext("Usage:\t" 98 "ikeadm [ -hnp ] cmd obj [cmd-specific options]\n")); 99 (void) fprintf(stderr, gettext(" \tikeadm help\n")); 100 } else { 101 (void) fprintf(stderr, 102 gettext("\nType help for usage info\n")); 103 } 104 105 command_complete(1); 106 } 107 108 static void 109 print_help() 110 { 111 (void) printf(gettext("Valid commands and objects:\n")); 112 (void) printf( 113 "\tget debug|priv|stats|p1|rule|preshared|defaults [%s]\n", 114 gettext("identifier")); 115 (void) printf("\tset priv %s\n", gettext("level")); 116 (void) printf("\tset debug %s [%s]\n", 117 gettext("level"), gettext("filename")); 118 (void) printf("\tadd rule|preshared {%s}|%s\n", 119 gettext("definition"), gettext("filename")); 120 (void) printf("\tdel p1|rule|preshared %s\n", gettext("identifier")); 121 (void) printf("\tdump p1|rule|preshared|certcache\n"); 122 (void) printf("\tflush p1|certcache\n"); 123 (void) printf("\tread rule|preshared [%s]\n", gettext("filename")); 124 (void) printf("\twrite rule|preshared %s\n", gettext("filename")); 125 (void) printf("\ttoken <login|logout> %s\n", 126 gettext("<PKCS#11 Token Object>")); 127 (void) printf( 128 "\thelp [get|set|add|del|dump|flush|read|write|token|help]\n"); 129 (void) printf("\texit %s\n", gettext("exit the program")); 130 (void) printf("\tquit %s\n", gettext("exit the program")); 131 132 command_complete(0); 133 } 134 135 static void 136 print_get_help() 137 { 138 (void) printf( 139 gettext("This command gets information from in.iked.\n\n")); 140 (void) printf(gettext("Objects that may be retrieved include:\n")); 141 (void) printf("\tdebug\t\t"); 142 (void) printf(gettext("the current debug level\n")); 143 (void) printf("\tpriv\t\t"); 144 (void) printf(gettext("the current privilege level\n")); 145 (void) printf("\tstats\t\t"); 146 (void) printf(gettext("current usage statistics\n")); 147 (void) printf("\tp1\t\t"); 148 (void) printf(gettext("a phase 1 SA, identified by\n")); 149 (void) printf(gettext("\t\t\t local_ip remote_ip OR\n")); 150 (void) printf(gettext("\t\t\t init_cookie resp_cookie\n")); 151 (void) printf("\trule\t\t"); 152 (void) printf(gettext("a phase 1 rule, identified by its label\n")); 153 (void) printf("\tpreshared\t"); 154 (void) printf(gettext("a preshared key, identified by\n")); 155 (void) printf(gettext("\t\t\t local_ip remote_ip OR\n")); 156 (void) printf(gettext("\t\t\t local_id remote_id\n")); 157 (void) printf("\n"); 158 159 command_complete(0); 160 } 161 162 static void 163 print_set_help() 164 { 165 (void) printf(gettext("This command sets values in in.iked.\n\n")); 166 (void) printf(gettext("Objects that may be set include:\n")); 167 (void) printf("\tdebug\t\t"); 168 (void) printf(gettext("change the debug level\n")); 169 (void) printf("\tpriv\t\t"); 170 (void) printf( 171 gettext("change the privilege level (may only be lowered)\n")); 172 (void) printf("\n"); 173 174 command_complete(0); 175 } 176 177 static void 178 print_add_help() 179 { 180 (void) printf( 181 gettext("This command adds items to in.iked's tables.\n\n")); 182 (void) printf(gettext("Objects that may be set include:\n")); 183 (void) printf("\trule\t\t"); 184 (void) printf(gettext("a phase 1 policy rule\n")); 185 (void) printf("\tpreshared\t"); 186 (void) printf(gettext("a preshared key\n")); 187 (void) printf( 188 gettext("\nObjects may be entered on the command-line, as a\n")); 189 (void) printf( 190 gettext("series of keywords and tokens contained in curly\n")); 191 (void) printf( 192 gettext("braces ('{', '}'); or the name of a file containing\n")); 193 (void) printf(gettext("the object definition may be provided.\n\n")); 194 (void) printf( 195 gettext("For security purposes, preshared keys may only be\n")); 196 (void) printf( 197 gettext("entered on the command-line if ikeadm is running in\n")); 198 (void) printf(gettext("interactive mode.\n")); 199 (void) printf("\n"); 200 201 command_complete(0); 202 } 203 204 static void 205 print_del_help() 206 { 207 (void) printf( 208 gettext("This command deletes an item from in.iked's tables.\n\n")); 209 (void) printf(gettext("Objects that may be deleted include:\n")); 210 (void) printf("\tp1\t\t"); 211 (void) printf(gettext("a phase 1 SA, identified by\n")); 212 (void) printf(gettext("\t\t\t local_ip remote_ip OR\n")); 213 (void) printf(gettext("\t\t\t init_cookie resp_cookie\n")); 214 (void) printf("\trule\t\t"); 215 (void) printf(gettext("a phase 1 rule, identified by its label\n")); 216 (void) printf("\tpreshared\t"); 217 (void) printf(gettext("a preshared key, identified by\n")); 218 (void) printf(gettext("\t\t\t local_ip remote_ip OR\n")); 219 (void) printf(gettext("\t\t\t local_id remote_id\n")); 220 (void) printf("\n"); 221 222 command_complete(0); 223 } 224 225 static void 226 print_dump_help() 227 { 228 (void) printf( 229 gettext("This command dumps one of in.iked's tables.\n\n")); 230 (void) printf(gettext("Tables that may be dumped include:\n")); 231 (void) printf("\tp1\t\t"); 232 (void) printf(gettext("all phase 1 SAs\n")); 233 (void) printf("\trule\t\t"); 234 (void) printf(gettext("all phase 1 rules\n")); 235 (void) printf("\tpreshared\t"); 236 (void) printf(gettext("all preshared keys\n")); 237 (void) printf("\tcertcache\t"); 238 (void) printf(gettext("all cached certificates\n")); 239 (void) printf("\n"); 240 241 command_complete(0); 242 } 243 244 static void 245 print_flush_help() 246 { 247 (void) printf( 248 gettext("This command clears one of in.iked's tables.\n\n")); 249 (void) printf(gettext("Tables that may be flushed include:\n")); 250 (void) printf("\tp1\t\t"); 251 (void) printf(gettext("all phase 1 SAs\n")); 252 (void) printf("\tcertcache\t"); 253 (void) printf(gettext("all cached certificates\n")); 254 (void) printf("\n"); 255 256 command_complete(0); 257 } 258 259 static void 260 print_read_help() 261 { 262 (void) printf( 263 gettext("This command reads a new configuration file into\n")); 264 (void) printf( 265 gettext("in.iked, discarding the old configuration info.\n\n")); 266 (void) printf(gettext("Sets of data that may be read include:\n")); 267 (void) printf("\trule\t\t"); 268 (void) printf(gettext("all phase 1 rules\n")); 269 (void) printf("\tpreshared\t"); 270 (void) printf(gettext("all preshared keys\n\n")); 271 (void) printf( 272 gettext("A filename may be provided to specify a source file\n")); 273 (void) printf(gettext("other than the default.\n")); 274 (void) printf("\n"); 275 276 command_complete(0); 277 } 278 279 static void 280 print_write_help() 281 { 282 (void) printf( 283 gettext("This command writes in.iked's current configuration\n")); 284 (void) printf(gettext("out to a config file.\n\n")); 285 (void) printf(gettext("Sets of data that may be written include:\n")); 286 (void) printf("\trule\t\t"); 287 (void) printf(gettext("all phase 1 rules\n")); 288 (void) printf("\tpreshared\t"); 289 (void) printf(gettext("all preshared keys\n\n")); 290 (void) printf( 291 gettext("A filename must be provided to specify the file to\n")); 292 (void) printf(gettext("which the information should be written.\n")); 293 (void) printf("\n"); 294 295 command_complete(0); 296 } 297 298 static void 299 print_token_help() 300 { 301 (void) printf(gettext( 302 "This command logs IKE into and out of PKCS#11 tokens.\n\n")); 303 (void) printf(gettext("Commands include:\n")); 304 (void) printf("\tlogin <PKCS#11 Token Object>\t"); 305 (void) printf(gettext("log into token\n")); 306 (void) printf("\tlogout <PKCS#11 Token Object>\t"); 307 (void) printf(gettext("log out of token\n\n")); 308 (void) printf( 309 gettext("The PKCS#11 Token Object name must be " 310 "enclosed in quotation marks.\n")); 311 (void) printf("\n"); 312 313 command_complete(0); 314 } 315 316 static void 317 print_help_help() 318 { 319 (void) printf( 320 gettext("This command provides information about commands.\n\n")); 321 (void) printf( 322 gettext("The 'help' command alone provides a list of valid\n")); 323 (void) printf( 324 gettext("commands, along with the valid objects for each.\n")); 325 (void) printf( 326 gettext("'help' followed by a valid command name provides\n")); 327 (void) printf(gettext("further information about that command.\n")); 328 (void) printf("\n"); 329 330 command_complete(0); 331 } 332 333 /*PRINTFLIKE1*/ 334 static void 335 message(char *fmt, ...) 336 { 337 va_list ap; 338 char msgbuf[BUFSIZ]; 339 340 va_start(ap, fmt); 341 (void) vsnprintf(msgbuf, BUFSIZ, fmt, ap); 342 (void) fprintf(stderr, gettext("ikeadm: %s\n"), msgbuf); 343 va_end(ap); 344 } 345 346 static int 347 open_door(void) 348 { 349 if (doorfd >= 0) 350 (void) close(doorfd); 351 doorfd = open(DOORNM, O_RDONLY); 352 return (doorfd); 353 } 354 355 static ike_service_t * 356 ikedoor_call(char *reqp, int size, door_desc_t *descp, int ndesc) 357 { 358 door_arg_t arg; 359 int retries = 0; 360 361 arg.data_ptr = reqp; 362 arg.data_size = size; 363 arg.desc_ptr = descp; 364 arg.desc_num = ndesc; 365 arg.rbuf = (char *)NULL; 366 arg.rsize = 0; 367 368 retry: 369 if (door_call(doorfd, &arg) < 0) { 370 if ((errno == EBADF) && ((++retries < 2) && 371 (open_door() >= 0))) 372 goto retry; 373 (void) fprintf(stderr, 374 gettext("Unable to communicate with in.iked\n")); 375 Bail("door_call failed"); 376 } 377 378 if ((ndesc > 0) && (descp->d_attributes & DOOR_RELEASE) && 379 ((errno == EBADF) || (errno == EFAULT))) { 380 /* callers assume passed fds will be closed no matter what */ 381 (void) close(descp->d_data.d_desc.d_descriptor); 382 } 383 384 /* LINTED E_BAD_PTR_CAST_ALIGN */ 385 return ((ike_service_t *)arg.rbuf); 386 } 387 388 /* 389 * Parsing functions 390 */ 391 392 /* stolen from ipseckey.c, with a second tier added */ 393 static int 394 parsecmd(char *cmdstr, char *objstr) 395 { 396 #define MAXOBJS 11 397 struct objtbl { 398 char *obj; 399 int token; 400 }; 401 static struct cmdtbl { 402 char *cmd; 403 int null_obj_token; 404 struct objtbl objt[MAXOBJS]; 405 } table[] = { 406 {"get", IKE_SVC_ERROR, { 407 {"debug", IKE_SVC_GET_DBG}, 408 {"priv", IKE_SVC_GET_PRIV}, 409 {"stats", IKE_SVC_GET_STATS}, 410 {"p1", IKE_SVC_GET_P1}, 411 {"rule", IKE_SVC_GET_RULE}, 412 {"preshared", IKE_SVC_GET_PS}, 413 {"defaults", IKE_SVC_GET_DEFS}, 414 {NULL, IKE_SVC_ERROR} 415 } 416 }, 417 {"set", IKE_SVC_ERROR, { 418 {"debug", IKE_SVC_SET_DBG}, 419 {"priv", IKE_SVC_SET_PRIV}, 420 {NULL, IKE_SVC_ERROR} 421 } 422 }, 423 {"token", IKE_SVC_ERROR, { 424 {"login", IKE_SVC_SET_PIN}, 425 {"logout", IKE_SVC_DEL_PIN}, 426 {NULL, IKE_SVC_ERROR}, 427 } 428 }, 429 {"add", IKE_SVC_ERROR, { 430 {"rule", IKE_SVC_NEW_RULE}, 431 {"preshared", IKE_SVC_NEW_PS}, 432 {NULL, IKE_SVC_ERROR} 433 } 434 }, 435 {"del", IKE_SVC_ERROR, { 436 {"p1", IKE_SVC_DEL_P1}, 437 {"rule", IKE_SVC_DEL_RULE}, 438 {"preshared", IKE_SVC_DEL_PS}, 439 {NULL, IKE_SVC_ERROR} 440 } 441 }, 442 {"dump", IKE_SVC_ERROR, { 443 {"p1", IKE_SVC_DUMP_P1S}, 444 {"rule", IKE_SVC_DUMP_RULES}, 445 {"preshared", IKE_SVC_DUMP_PS}, 446 {"certcache", IKE_SVC_DUMP_CERTCACHE}, 447 {NULL, IKE_SVC_ERROR} 448 } 449 }, 450 {"flush", IKE_SVC_ERROR, { 451 {"p1", IKE_SVC_FLUSH_P1S}, 452 {"certcache", IKE_SVC_FLUSH_CERTCACHE}, 453 {NULL, IKE_SVC_ERROR} 454 } 455 }, 456 {"read", IKE_SVC_ERROR, { 457 {"rule", IKE_SVC_READ_RULES}, 458 {"preshared", IKE_SVC_READ_PS}, 459 {NULL, IKE_SVC_ERROR} 460 } 461 }, 462 {"write", IKE_SVC_ERROR, { 463 {"rule", IKE_SVC_WRITE_RULES}, 464 {"preshared", IKE_SVC_WRITE_PS}, 465 {NULL, IKE_SVC_ERROR} 466 } 467 }, 468 {"help", IKEADM_HELP_GENERAL, { 469 {"get", IKEADM_HELP_GET}, 470 {"set", IKEADM_HELP_SET}, 471 {"add", IKEADM_HELP_ADD}, 472 {"del", IKEADM_HELP_DEL}, 473 {"dump", IKEADM_HELP_DUMP}, 474 {"flush", IKEADM_HELP_FLUSH}, 475 {"read", IKEADM_HELP_READ}, 476 {"write", IKEADM_HELP_WRITE}, 477 {"token", IKEADM_HELP_TOKEN}, 478 {"help", IKEADM_HELP_HELP}, 479 {NULL, IKE_SVC_ERROR} 480 } 481 }, 482 {"exit", IKEADM_EXIT, { 483 {NULL, IKE_SVC_ERROR} 484 } 485 }, 486 {"quit", IKEADM_EXIT, { 487 {NULL, IKE_SVC_ERROR} 488 } 489 }, 490 {"dbg", IKE_SVC_ERROR, { 491 {"rbdump", IKE_SVC_DBG_RBDUMP}, 492 {NULL, IKE_SVC_ERROR} 493 } 494 }, 495 {NULL, IKE_SVC_ERROR, { 496 {NULL, IKE_SVC_ERROR} 497 } 498 } 499 }; 500 struct cmdtbl *ct = table; 501 struct objtbl *ot; 502 503 if (cmdstr == NULL) { 504 return (IKE_SVC_ERROR); 505 } 506 507 while (ct->cmd != NULL && strcmp(ct->cmd, cmdstr) != 0) 508 ct++; 509 ot = ct->objt; 510 511 if (ct->cmd == NULL) { 512 message(gettext("Unrecognized command '%s'"), cmdstr); 513 return (ot->token); 514 } 515 516 if (objstr == NULL) { 517 return (ct->null_obj_token); 518 } 519 520 while (ot->obj != NULL && strcmp(ot->obj, objstr) != 0) 521 ot++; 522 523 if (ot->obj == NULL) 524 message(gettext("Unrecognized object '%s'"), objstr); 525 526 return (ot->token); 527 } 528 529 /* 530 * Parsing functions: 531 * Parse command-line identification info. All return -1 on failure, 532 * or the number of cmd-line args "consumed" on success (though argc 533 * and argv params are not actually modified). 534 */ 535 536 static int 537 parse_label(int argc, char **argv, char *label) 538 { 539 if ((argc < 1) || (argv == NULL)) 540 return (-1); 541 542 if (strlcpy(label, argv[0], MAX_LABEL_LEN) >= MAX_LABEL_LEN) 543 return (-1); 544 545 return (1); 546 } 547 548 /* 549 * Parse a PKCS#11 token get the label. 550 */ 551 static int 552 parse_token(int argc, char **argv, char *token_label) 553 { 554 if ((argc < 1) || (argv == NULL)) 555 return (-1); 556 557 if (strlcpy(token_label, argv[0], PKCS11_TOKSIZE) >= PKCS11_TOKSIZE) 558 return (-1); 559 560 return (0); 561 } 562 563 /* 564 * Parse an address off the command line. In the hpp param, either 565 * return a hostent pointer (caller frees) or a pointer to a dummy_he_t 566 * (must also be freed by the caller; both cases are handled by the 567 * macro FREE_HE). The new getipnodebyname() call does the Right Thing 568 * (TM), even with raw addresses (colon-separated IPv6 or dotted decimal 569 * IPv4). 570 * (mostly stolen from ipseckey.c, though some tweaks were made 571 * to better serve our purposes here.) 572 */ 573 574 typedef struct { 575 struct hostent he; 576 char *addtl[2]; 577 } dummy_he_t; 578 579 static int 580 parse_addr(int argc, char **argv, struct hostent **hpp) 581 { 582 int hp_errno; 583 struct hostent *hp = NULL; 584 dummy_he_t *dhp; 585 char *addr1; 586 587 if ((argc < 1) || (argv == NULL) || (argv[0] == NULL)) 588 return (-1); 589 590 if (!nflag) { 591 /* 592 * Try name->address first. Assume AF_INET6, and 593 * get IPV4s, plus IPv6s iff IPv6 is configured. 594 */ 595 hp = getipnodebyname(argv[0], AF_INET6, AI_DEFAULT | AI_ALL, 596 &hp_errno); 597 } else { 598 /* 599 * Try a normal address conversion only. malloc a 600 * dummy_he_t to construct a fake hostent. Caller 601 * will know to free this one using free_he(). 602 */ 603 dhp = (dummy_he_t *)malloc(sizeof (dummy_he_t)); 604 addr1 = (char *)malloc(sizeof (struct in6_addr)); 605 if (inet_pton(AF_INET6, argv[0], addr1) == 1) { 606 dhp->he.h_addr_list = dhp->addtl; 607 dhp->addtl[0] = addr1; 608 dhp->addtl[1] = NULL; 609 hp = &dhp->he; 610 dhp->he.h_addrtype = AF_INET6; 611 dhp->he.h_length = sizeof (struct in6_addr); 612 } else if (inet_pton(AF_INET, argv[0], addr1) == 1) { 613 dhp->he.h_addr_list = dhp->addtl; 614 dhp->addtl[0] = addr1; 615 dhp->addtl[1] = NULL; 616 hp = &dhp->he; 617 dhp->he.h_addrtype = AF_INET; 618 dhp->he.h_length = sizeof (struct in_addr); 619 } else { 620 hp = NULL; 621 } 622 } 623 624 *hpp = hp; 625 626 if (hp == NULL) { 627 message(gettext("Unknown address %s."), argv[0]); 628 return (-1); 629 } 630 631 return (1); 632 } 633 634 /* 635 * Free a dummy_he_t structure that was malloc'd in parse_addr(). 636 * Unfortunately, callers of parse_addr don't want to know about 637 * dummy_he_t structs, so all they have is a pointer to the struct 638 * hostent; so that's what's passed in. To manage this, we make 639 * the assumption that the struct hostent is the first field in 640 * the dummy_he_t, and therefore a pointer to it is a pointer to 641 * the dummy_he_t. 642 */ 643 static void 644 free_he(struct hostent *hep) 645 { 646 dummy_he_t *p = (dummy_he_t *)hep; 647 648 assert(p != NULL); 649 650 if (p->addtl[0]) 651 free(p->addtl[0]); 652 if (p->addtl[1]) 653 free(p->addtl[1]); 654 655 free(p); 656 } 657 658 #define FREE_HE(x) \ 659 if (nflag) \ 660 free_he(x); \ 661 else \ 662 freehostent(x) 663 664 static void 665 headdr2sa(char *hea, struct sockaddr_storage *sa, int len) 666 { 667 struct sockaddr_in *sin; 668 struct sockaddr_in6 *sin6; 669 670 if (len == sizeof (struct in6_addr)) { 671 /* LINTED E_BAD_PTR_CAST_ALIGN */ 672 if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)hea)) { 673 sin = (struct sockaddr_in *)sa; 674 (void) memset(sin, 0, sizeof (*sin)); 675 /* LINTED E_BAD_PTR_CAST_ALIGN */ 676 IN6_V4MAPPED_TO_INADDR((struct in6_addr *)hea, 677 &sin->sin_addr); 678 sin->sin_family = AF_INET; 679 } else { 680 sin6 = (struct sockaddr_in6 *)sa; 681 (void) memset(sin6, 0, sizeof (*sin6)); 682 (void) memcpy(&sin6->sin6_addr, hea, 683 sizeof (struct in6_addr)); 684 sin6->sin6_family = AF_INET6; 685 } 686 } else { 687 sin = (struct sockaddr_in *)sa; 688 (void) memset(sin, 0, sizeof (*sin)); 689 (void) memcpy(&sin->sin_addr, hea, sizeof (struct in_addr)); 690 sin->sin_family = AF_INET; 691 } 692 } 693 694 /* 695 * The possible ident-type keywords that might be used on the command 696 * line. This is a superset of the ones supported by ipseckey, those 697 * in the ike config file, and those in ike.preshared. 698 */ 699 static keywdtab_t idtypes[] = { 700 /* ip, ipv4, and ipv6 are valid for preshared keys... */ 701 {SADB_IDENTTYPE_RESERVED, "ip"}, 702 {SADB_IDENTTYPE_RESERVED, "ipv4"}, 703 {SADB_IDENTTYPE_RESERVED, "ipv6"}, 704 {SADB_IDENTTYPE_PREFIX, "prefix"}, 705 {SADB_IDENTTYPE_PREFIX, "ipv4-prefix"}, 706 {SADB_IDENTTYPE_PREFIX, "ipv6-prefix"}, 707 {SADB_IDENTTYPE_PREFIX, "subnet"}, 708 {SADB_IDENTTYPE_PREFIX, "subnetv4"}, 709 {SADB_IDENTTYPE_PREFIX, "subnetv6"}, 710 {SADB_IDENTTYPE_FQDN, "fqdn"}, 711 {SADB_IDENTTYPE_FQDN, "dns"}, 712 {SADB_IDENTTYPE_FQDN, "domain"}, 713 {SADB_IDENTTYPE_FQDN, "domainname"}, 714 {SADB_IDENTTYPE_USER_FQDN, "user_fqdn"}, 715 {SADB_IDENTTYPE_USER_FQDN, "mbox"}, 716 {SADB_IDENTTYPE_USER_FQDN, "mailbox"}, 717 {SADB_X_IDENTTYPE_DN, "dn"}, 718 {SADB_X_IDENTTYPE_DN, "asn1dn"}, 719 {SADB_X_IDENTTYPE_GN, "gn"}, 720 {SADB_X_IDENTTYPE_GN, "asn1gn"}, 721 {SADB_X_IDENTTYPE_ADDR_RANGE, "ipv4-range"}, 722 {SADB_X_IDENTTYPE_ADDR_RANGE, "ipv6-range"}, 723 {SADB_X_IDENTTYPE_ADDR_RANGE, "rangev4"}, 724 {SADB_X_IDENTTYPE_ADDR_RANGE, "rangev6"}, 725 {SADB_X_IDENTTYPE_KEY_ID, "keyid"}, 726 {NULL, 0} 727 }; 728 729 static int 730 parse_idtype(char *type, uint16_t *idnum) 731 { 732 keywdtab_t *idp; 733 734 if (type == NULL) 735 return (-1); 736 737 for (idp = idtypes; idp->kw_str != NULL; idp++) { 738 if (strcasecmp(idp->kw_str, type) == 0) { 739 if (idnum != NULL) 740 *idnum = idp->kw_tag; 741 return (1); 742 } 743 } 744 745 return (-1); 746 } 747 748 /* 749 * The sadb_ident_t is malloc'd, since its length varies; 750 * so the caller must free() it when done with the data. 751 */ 752 static int 753 parse_ident(int argc, char **argv, sadb_ident_t **idpp) 754 { 755 int alloclen, consumed; 756 sadb_ident_t *idp; 757 if ((argc < 2) || (argv == NULL) || (argv[0] == NULL) || 758 (argv[1] == NULL)) 759 return (-1); 760 761 alloclen = sizeof (sadb_ident_t) + IKEDOORROUNDUP(strlen(argv[1]) + 1); 762 *idpp = idp = (sadb_ident_t *)malloc(alloclen); 763 if (idp == NULL) 764 Bail("parsing identity"); 765 766 if ((consumed = parse_idtype(argv[0], &idp->sadb_ident_type)) < 0) { 767 message(gettext("unknown identity type %s."), argv[0]); 768 return (-1); 769 } 770 771 idp->sadb_ident_len = SADB_8TO64(alloclen); 772 idp->sadb_ident_reserved = 0; 773 idp->sadb_ident_id = 0; 774 775 /* now copy in identity param */ 776 (void) strlcpy((char *)(idp + 1), argv[1], 777 alloclen - (sizeof (sadb_ident_t))); 778 779 return (++consumed); 780 } 781 782 static int 783 parse_cky(int argc, char **argv, uint64_t *ckyp) 784 { 785 u_longlong_t arg; 786 787 if ((argc < 1) || (argv[0] == NULL)) 788 return (-1); 789 790 errno = 0; 791 arg = strtoull(argv[0], NULL, 0); 792 if (errno != 0) { 793 message(gettext("failed to parse cookie %s."), argv[0]); 794 return (-1); 795 } 796 797 *ckyp = (uint64_t)arg; 798 799 return (1); 800 } 801 802 static int 803 parse_addr_pr(int argc, char **argv, struct hostent **h1pp, 804 struct hostent **h2pp) 805 { 806 int rtn, consumed = 0; 807 808 if ((rtn = parse_addr(argc, argv, h1pp)) < 0) { 809 return (-1); 810 } 811 consumed = rtn; 812 argc -= rtn; 813 argv += rtn; 814 815 if ((rtn = parse_addr(argc, argv, h2pp)) < 0) { 816 FREE_HE(*h1pp); 817 return (-1); 818 } 819 consumed += rtn; 820 821 return (consumed); 822 } 823 824 /* 825 * The sadb_ident_ts are malloc'd, since their length varies; 826 * so the caller must free() them when done with the data. 827 */ 828 static int 829 parse_ident_pr(int argc, char **argv, sadb_ident_t **id1pp, 830 sadb_ident_t **id2pp) 831 { 832 int rtn, consumed = 0; 833 834 if ((rtn = parse_ident(argc, argv, id1pp)) < 0) { 835 return (-1); 836 } 837 consumed = rtn; 838 argc -= rtn; 839 argv += rtn; 840 841 (*id1pp)->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC; 842 843 if ((rtn = parse_ident(argc, argv, id2pp)) < 0) { 844 free(*id1pp); 845 return (-1); 846 } 847 consumed += rtn; 848 849 (*id2pp)->sadb_ident_exttype = SADB_EXT_IDENTITY_DST; 850 851 return (consumed); 852 } 853 854 static int 855 parse_cky_pr(int argc, char **argv, ike_cky_pr_t *cpr) 856 { 857 int rtn, consumed = 0; 858 859 if ((rtn = parse_cky(argc, argv, &cpr->cky_i)) < 0) { 860 return (-1); 861 } 862 consumed = rtn; 863 argc -= rtn; 864 argv += rtn; 865 866 if ((rtn = parse_cky(argc, argv, &cpr->cky_r)) < 0) { 867 return (-1); 868 } 869 consumed += rtn; 870 871 return (consumed); 872 } 873 874 /* 875 * Preshared key field types...used for parsing preshared keys that 876 * have been entered on the command line. The code to parse preshared 877 * keys (parse_ps, parse_key, parse_psfldid, parse_ikmtype, ...) is 878 * mostly duplicated from in.iked's readps.c. 879 */ 880 #define PSFLD_LOCID 1 881 #define PSFLD_LOCIDTYPE 2 882 #define PSFLD_REMID 3 883 #define PSFLD_REMIDTYPE 4 884 #define PSFLD_MODE 5 885 #define PSFLD_KEY 6 886 887 static keywdtab_t psfldtypes[] = { 888 {PSFLD_LOCID, "localid"}, 889 {PSFLD_LOCIDTYPE, "localidtype"}, 890 {PSFLD_REMID, "remoteid"}, 891 {PSFLD_REMIDTYPE, "remoteidtype"}, 892 {PSFLD_MODE, "ike_mode"}, 893 {PSFLD_KEY, "key"}, 894 {NULL, 0} 895 }; 896 897 static int 898 parse_psfldid(char *type, uint16_t *idnum) 899 { 900 keywdtab_t *pfp; 901 902 if (type == NULL) 903 return (-1); 904 905 for (pfp = psfldtypes; pfp->kw_str != NULL; pfp++) { 906 if (strcasecmp(pfp->kw_str, type) == 0) { 907 if (idnum != NULL) 908 *idnum = pfp->kw_tag; 909 return (1); 910 } 911 } 912 913 return (-1); 914 } 915 916 static keywdtab_t ikemodes[] = { 917 {IKE_XCHG_IDENTITY_PROTECT, "main"}, 918 {IKE_XCHG_AGGRESSIVE, "aggressive"}, 919 {IKE_XCHG_IP_AND_AGGR, "both"}, 920 {NULL, 0} 921 }; 922 923 static int 924 parse_ikmtype(char *mode, uint16_t *modenum) 925 { 926 keywdtab_t *ikmp; 927 928 if (mode == NULL) 929 return (-1); 930 931 for (ikmp = ikemodes; ikmp->kw_str != NULL; ikmp++) { 932 if (strcasecmp(ikmp->kw_str, mode) == 0) { 933 if (modenum != NULL) 934 *modenum = ikmp->kw_tag; 935 return (1); 936 } 937 } 938 939 return (-1); 940 } 941 942 #define hd2num(hd) (((hd) >= '0' && (hd) <= '9') ? ((hd) - '0') : \ 943 (((hd) >= 'a' && (hd) <= 'f') ? ((hd) - 'a' + 10) : ((hd) - 'A' + 10))) 944 945 static uint8_t * 946 parse_key(char *input, uint_t *keybuflen, uint_t *lbits) 947 { 948 uint8_t *keyp, *keybufp; 949 uint_t i, hexlen = 0, bits, alloclen; 950 951 for (i = 0; input[i] != '\0' && input[i] != '/'; i++) 952 hexlen++; 953 954 if (input[i] == '\0') { 955 bits = 0; 956 } else { 957 /* Have /nn. */ 958 input[i] = '\0'; 959 if (sscanf((input + i + 1), "%u", &bits) != 1) 960 return (NULL); 961 962 /* hexlen is in nibbles */ 963 if (((bits + 3) >> 2) > hexlen) 964 return (NULL); 965 966 /* 967 * Adjust hexlen down if user gave us too small of a bit 968 * count. 969 */ 970 if ((hexlen << 2) > bits + 3) { 971 hexlen = (bits + 3) >> 2; 972 input[hexlen] = '\0'; 973 } 974 } 975 976 /* 977 * Allocate. Remember, hexlen is in nibbles. 978 */ 979 980 alloclen = (hexlen/2 + (hexlen & 0x1)); 981 keyp = malloc(alloclen); 982 983 if (keyp == NULL) 984 return (NULL); 985 986 keybufp = keyp; 987 *keybuflen = alloclen; 988 if (bits == 0) 989 *lbits = (hexlen + (hexlen & 0x1)) << 2; 990 else 991 *lbits = bits; 992 993 /* 994 * Read in nibbles. Read in odd-numbered as shifted high. 995 * (e.g. 123 becomes 0x1230). 996 */ 997 for (i = 0; input[i] != '\0'; i += 2) { 998 boolean_t second = (input[i + 1] != '\0'); 999 1000 if (!isxdigit(input[i]) || 1001 (!isxdigit(input[i + 1]) && second)) { 1002 free(keyp); 1003 return (NULL); 1004 } 1005 *keyp = (hd2num(input[i]) << 4); 1006 if (second) 1007 *keyp |= hd2num(input[i + 1]); 1008 else 1009 break; /* out of for loop. */ 1010 keyp++; 1011 } 1012 1013 /* zero the remaining bits if we're a non-octet amount. */ 1014 if (bits & 0x7) 1015 *((input[i] == '\0') ? keyp - 1 : keyp) &= 1016 0xff << (8 - (bits & 0x7)); 1017 return (keybufp); 1018 } 1019 1020 /* 1021 * the ike_ps_t struct (plus trailing data) will be allocated here, 1022 * so it will need to be freed by the caller. 1023 */ 1024 static int 1025 parse_ps(int argc, char **argv, ike_ps_t **presharedpp, int *len) 1026 { 1027 uint_t c = 0, locidlen, remidlen, keylen, keybits; 1028 uint_t a_locidtotal = 0, a_remidtotal = 0; 1029 char *locid, *remid; 1030 uint8_t *keyp = NULL; 1031 uint16_t fldid, locidtype, remidtype, mtype; 1032 struct hostent *loche = NULL, *remhe = NULL; 1033 ike_ps_t *psp = NULL; 1034 sadb_ident_t *sidp; 1035 boolean_t whacked = B_FALSE; 1036 1037 if ((argv[c] == NULL) || (argv[c][0] != '{')) 1038 return (-1); 1039 if (argv[c][1] != 0) { 1040 /* no space between '{' and first token */ 1041 argv[c]++; 1042 } else { 1043 c++; 1044 } 1045 if ((argv[argc - 1][strlen(argv[argc - 1]) - 1] == '}') && 1046 (argv[argc - 1][0] != '}')) { 1047 /* 1048 * whack '}' without a space before it or parsers break. 1049 * Remember this trailing character for later 1050 */ 1051 argv[argc - 1][strlen(argv[argc - 1]) - 1] = '\0'; 1052 whacked = B_TRUE; 1053 } 1054 1055 while ((c < argc) && (argv[c] != NULL) && (argv[c][0] != '}')) { 1056 if ((argv[c + 1] == NULL) || (argv[c + 1][0] == '}')) 1057 goto bail; 1058 if (parse_psfldid(argv[c++], &fldid) < 0) 1059 goto bail; 1060 switch (fldid) { 1061 case PSFLD_LOCID: 1062 locid = argv[c++]; 1063 locidlen = strlen(locid) + 1; 1064 break; 1065 case PSFLD_LOCIDTYPE: 1066 if (parse_idtype(argv[c++], &locidtype) < 0) 1067 goto bail; 1068 break; 1069 case PSFLD_REMID: 1070 remid = argv[c++]; 1071 remidlen = strlen(remid) + 1; 1072 break; 1073 case PSFLD_REMIDTYPE: 1074 if (parse_idtype(argv[c++], &remidtype) < 0) 1075 goto bail; 1076 break; 1077 case PSFLD_MODE: 1078 if (parse_ikmtype(argv[c++], &mtype) < 0) 1079 goto bail; 1080 break; 1081 case PSFLD_KEY: 1082 keyp = parse_key(argv[c++], &keylen, &keybits); 1083 if (keyp == NULL) 1084 goto bail; 1085 break; 1086 } 1087 } 1088 1089 /* Make sure the line was terminated with '}' */ 1090 if (argv[c] == NULL) { 1091 if (!whacked) 1092 goto bail; 1093 } else if (argv[c][0] != '}') { 1094 goto bail; 1095 } 1096 1097 /* 1098 * make sure we got all the required fields. If no idtype, assume 1099 * ip addr; if that translation fails, we'll catch the error then. 1100 */ 1101 if (locid == NULL || remid == NULL || keyp == NULL || mtype == 0) 1102 goto bail; 1103 1104 /* figure out the size buffer we need */ 1105 *len = sizeof (ike_ps_t); 1106 if (locidtype != SADB_IDENTTYPE_RESERVED) { 1107 a_locidtotal = IKEDOORROUNDUP(sizeof (sadb_ident_t) + locidlen); 1108 *len += a_locidtotal; 1109 } 1110 if (remidtype != SADB_IDENTTYPE_RESERVED) { 1111 a_remidtotal = IKEDOORROUNDUP(sizeof (sadb_ident_t) + remidlen); 1112 *len += a_remidtotal; 1113 } 1114 *len += keylen; 1115 1116 psp = malloc(*len); 1117 if (psp == NULL) 1118 goto bail; 1119 (void) memset(psp, 0, *len); 1120 1121 psp->ps_ike_mode = mtype; 1122 1123 psp->ps_localid_off = sizeof (ike_ps_t); 1124 if (locidtype == SADB_IDENTTYPE_RESERVED) { 1125 /* 1126 * this is an ip address, store in the sockaddr field; 1127 * we won't use an sadb_ident_t. 1128 */ 1129 psp->ps_localid_len = 0; 1130 if (parse_addr(1, &locid, &loche) < 0) 1131 goto bail; 1132 if (loche->h_addr_list[1] != NULL) { 1133 message(gettext("preshared key identifier cannot " 1134 "match multiple IP addresses")); 1135 goto bail; 1136 } 1137 headdr2sa(loche->h_addr_list[0], &psp->ps_ipaddrs.loc_addr, 1138 loche->h_length); 1139 FREE_HE(loche); 1140 } else { 1141 psp->ps_localid_len = sizeof (sadb_ident_t) + locidlen; 1142 sidp = (sadb_ident_t *)((int)psp + psp->ps_localid_off); 1143 sidp->sadb_ident_len = psp->ps_localid_len; 1144 sidp->sadb_ident_type = locidtype; 1145 (void) strlcpy((char *)(sidp + 1), locid, a_locidtotal); 1146 } 1147 1148 psp->ps_remoteid_off = psp->ps_localid_off + a_locidtotal; 1149 if (remidtype == SADB_IDENTTYPE_RESERVED) { 1150 /* 1151 * this is an ip address, store in the sockaddr field; 1152 * we won't use an sadb_ident_t. 1153 */ 1154 psp->ps_remoteid_len = 0; 1155 if (parse_addr(1, &remid, &remhe) < 0) 1156 goto bail; 1157 if (remhe->h_addr_list[1] != NULL) { 1158 message(gettext("preshared key identifier cannot " 1159 "match multiple IP addresses")); 1160 goto bail; 1161 } 1162 headdr2sa(remhe->h_addr_list[0], &psp->ps_ipaddrs.rem_addr, 1163 remhe->h_length); 1164 FREE_HE(remhe); 1165 } else { 1166 /* make sure we have at least 16-bit alignment */ 1167 if (remidlen & 0x1) 1168 remidlen++; 1169 psp->ps_remoteid_len = sizeof (sadb_ident_t) + remidlen; 1170 sidp = (sadb_ident_t *)((int)psp + psp->ps_remoteid_off); 1171 sidp->sadb_ident_len = psp->ps_remoteid_len; 1172 sidp->sadb_ident_type = remidtype; 1173 (void) strlcpy((char *)(sidp + 1), remid, a_remidtotal); 1174 } 1175 1176 psp->ps_key_off = psp->ps_remoteid_off + a_remidtotal; 1177 psp->ps_key_len = keylen; 1178 psp->ps_key_bits = keybits; 1179 (void) memcpy((uint8_t *)((int)psp + psp->ps_key_off), keyp, keylen); 1180 1181 *presharedpp = psp; 1182 1183 return (c); 1184 1185 bail: 1186 if (loche != NULL) 1187 FREE_HE(loche); 1188 if (remhe != NULL) 1189 FREE_HE(remhe); 1190 if (keyp != NULL) 1191 free(keyp); 1192 if (psp != NULL) 1193 free(psp); 1194 1195 *presharedpp = NULL; 1196 1197 return (-1); 1198 } 1199 1200 /* 1201 * Printing functions 1202 * 1203 * A potential point of confusion here is that the ikeadm-specific string- 1204 * producing functions do not match the ipsec_util.c versions in style: the 1205 * ikeadm-specific functions return a string (and are named foostr), while 1206 * the ipsec_util.c functions actually print the string to the file named 1207 * in the second arg to the function (and are named dump_foo). 1208 * 1209 * Localization for ikeadm seems more straightforward when complete 1210 * phrases are translated rather than: a part of a phrase, a call to 1211 * dump_foo(), and more of the phrase. It could also accommodate 1212 * non-English grammar more easily. 1213 */ 1214 1215 static char * 1216 errstr(int err) 1217 { 1218 static char rtn[MAXLINESIZE]; 1219 1220 switch (err) { 1221 case IKE_ERR_NO_OBJ: 1222 return (gettext("No data returned")); 1223 case IKE_ERR_NO_DESC: 1224 return (gettext("No destination provided")); 1225 case IKE_ERR_ID_INVALID: 1226 return (gettext("Id info invalid")); 1227 case IKE_ERR_LOC_INVALID: 1228 return (gettext("Destination invalid")); 1229 case IKE_ERR_CMD_INVALID: 1230 return (gettext("Command invalid")); 1231 case IKE_ERR_DATA_INVALID: 1232 return (gettext("Supplied data invalid")); 1233 case IKE_ERR_CMD_NOTSUP: 1234 return (gettext("Unknown command")); 1235 case IKE_ERR_REQ_INVALID: 1236 return (gettext("Request invalid")); 1237 case IKE_ERR_NO_PRIV: 1238 return (gettext("Not allowed at current privilege level")); 1239 case IKE_ERR_NO_AUTH: 1240 return (gettext("User not authorized")); 1241 case IKE_ERR_SYS_ERR: 1242 return (gettext("System error")); 1243 case IKE_ERR_DUP_IGNORED: 1244 return (gettext("One or more duplicate entries ignored")); 1245 case IKE_ERR_NO_TOKEN: 1246 return (gettext( 1247 "token login failed or no objects on device")); 1248 case IKE_ERR_IN_PROGRESS: 1249 return (gettext( 1250 "Duplicate operation already in progress")); 1251 case IKE_ERR_NO_MEM: 1252 return (gettext( 1253 "Insufficient memory")); 1254 default: 1255 (void) snprintf(rtn, MAXLINESIZE, 1256 gettext("<unknown error %d>"), err); 1257 return (rtn); 1258 } 1259 } 1260 1261 static char * 1262 dbgstr(int bit) 1263 { 1264 static char rtn[MAXLINESIZE]; 1265 1266 switch (bit) { 1267 case D_CERT: 1268 return (gettext("Certificate management")); 1269 case D_KEY: 1270 return (gettext("Key management")); 1271 case D_OP: 1272 return (gettext("Operational")); 1273 case D_P1: 1274 return (gettext("Phase 1 SA creation")); 1275 case D_P2: 1276 return (gettext("Phase 2 SA creation")); 1277 case D_PFKEY: 1278 return (gettext("PF_KEY interface")); 1279 case D_POL: 1280 return (gettext("Policy management")); 1281 case D_PROP: 1282 return (gettext("Proposal construction")); 1283 case D_DOOR: 1284 return (gettext("Door interface")); 1285 case D_CONFIG: 1286 return (gettext("Config file processing")); 1287 case D_LABEL: 1288 return (gettext("MAC label processing")); 1289 default: 1290 (void) snprintf(rtn, MAXLINESIZE, 1291 gettext("<unknown flag 0x%x>"), bit); 1292 return (rtn); 1293 } 1294 } 1295 1296 static char * 1297 privstr(int priv) 1298 { 1299 static char rtn[MAXLINESIZE]; 1300 1301 switch (priv) { 1302 case IKE_PRIV_MINIMUM: 1303 return (gettext("base privileges")); 1304 case IKE_PRIV_MODKEYS: 1305 return (gettext("access to preshared key information")); 1306 case IKE_PRIV_KEYMAT: 1307 return (gettext("access to keying material")); 1308 default: 1309 (void) snprintf(rtn, MAXLINESIZE, 1310 gettext("<unknown level %d>"), priv); 1311 return (rtn); 1312 } 1313 } 1314 1315 static char * 1316 xchgstr(int xchg) 1317 { 1318 static char rtn[MAXLINESIZE]; 1319 1320 switch (xchg) { 1321 case IKE_XCHG_NONE: 1322 return (gettext("<unspecified>")); 1323 case IKE_XCHG_BASE: 1324 return (gettext("base")); 1325 case IKE_XCHG_IDENTITY_PROTECT: 1326 return (gettext("main mode (identity protect)")); 1327 case IKE_XCHG_AUTH_ONLY: 1328 return (gettext("authentication only")); 1329 case IKE_XCHG_AGGRESSIVE: 1330 return (gettext("aggressive mode")); 1331 case IKE_XCHG_IP_AND_AGGR: 1332 return (gettext("main and aggressive mode")); 1333 case IKE_XCHG_ANY: 1334 return (gettext("any mode")); 1335 default: 1336 (void) snprintf(rtn, MAXLINESIZE, 1337 gettext("<unknown %d>"), xchg); 1338 return (rtn); 1339 } 1340 } 1341 1342 static char * 1343 statestr(int state) 1344 { 1345 static char rtn[MAXLINESIZE]; 1346 1347 switch (state) { 1348 case IKE_SA_STATE_INIT: 1349 return (gettext("INITIALIZING")); 1350 case IKE_SA_STATE_SENT_SA: 1351 return (gettext("SENT FIRST MSG (SA)")); 1352 case IKE_SA_STATE_SENT_KE: 1353 return (gettext("SENT SECOND MSG (KE)")); 1354 case IKE_SA_STATE_SENT_LAST: 1355 return (gettext("SENT FINAL MSG")); 1356 case IKE_SA_STATE_DONE: 1357 return (gettext("ACTIVE")); 1358 case IKE_SA_STATE_DELETED: 1359 return (gettext("DELETED")); 1360 case IKE_SA_STATE_INVALID: 1361 return (gettext("<invalid>")); 1362 default: 1363 (void) snprintf(rtn, MAXLINESIZE, 1364 gettext("<unknown %d>"), state); 1365 return (rtn); 1366 } 1367 } 1368 1369 static char * 1370 authmethstr(int meth) 1371 { 1372 static char rtn[MAXLINESIZE]; 1373 1374 switch (meth) { 1375 case IKE_AUTH_METH_PRE_SHARED_KEY: 1376 return (gettext("pre-shared key")); 1377 case IKE_AUTH_METH_DSS_SIG: 1378 return (gettext("DSS signatures")); 1379 case IKE_AUTH_METH_RSA_SIG: 1380 return (gettext("RSA signatures")); 1381 case IKE_AUTH_METH_RSA_ENCR: 1382 return (gettext("RSA Encryption")); 1383 case IKE_AUTH_METH_RSA_ENCR_REVISED: 1384 return (gettext("Revised RSA Encryption")); 1385 default: 1386 (void) snprintf(rtn, MAXLINESIZE, 1387 gettext("<unknown %d>"), meth); 1388 return (rtn); 1389 } 1390 } 1391 1392 static char * 1393 prfstr(int prf) 1394 { 1395 static char rtn[MAXLINESIZE]; 1396 1397 switch (prf) { 1398 case IKE_PRF_NONE: 1399 return (gettext("<none/unavailable>")); 1400 case IKE_PRF_HMAC_MD5: 1401 return ("HMAC MD5"); 1402 case IKE_PRF_HMAC_SHA1: 1403 return ("HMAC SHA1"); 1404 case IKE_PRF_HMAC_SHA256: 1405 return ("HMAC SHA256"); 1406 case IKE_PRF_HMAC_SHA384: 1407 return ("HMAC SHA384"); 1408 case IKE_PRF_HMAC_SHA512: 1409 return ("HMAC SHA512"); 1410 default: 1411 (void) snprintf(rtn, MAXLINESIZE, 1412 gettext("<unknown %d>"), prf); 1413 return (rtn); 1414 } 1415 } 1416 1417 static char * 1418 dhstr(int grp) 1419 { 1420 static char rtn[MAXLINESIZE]; 1421 1422 switch (grp) { 1423 case 0: 1424 return (gettext("<unavailable>")); 1425 case IKE_GRP_DESC_MODP_768: 1426 return (gettext("768-bit MODP (group 1)")); 1427 case IKE_GRP_DESC_MODP_1024: 1428 return (gettext("1024-bit MODP (group 2)")); 1429 case IKE_GRP_DESC_EC2N_155: 1430 return (gettext("EC2N group on GP[2^155]")); 1431 case IKE_GRP_DESC_EC2N_185: 1432 return (gettext("EC2N group on GP[2^185]")); 1433 case IKE_GRP_DESC_MODP_1536: 1434 return (gettext("1536-bit MODP (group 5)")); 1435 case IKE_GRP_DESC_MODP_2048: 1436 return (gettext("2048-bit MODP (group 14)")); 1437 case IKE_GRP_DESC_MODP_3072: 1438 return (gettext("3072-bit MODP (group 15)")); 1439 case IKE_GRP_DESC_MODP_4096: 1440 return (gettext("4096-bit MODP (group 16)")); 1441 case IKE_GRP_DESC_MODP_6144: 1442 return (gettext("6144-bit MODP (group 17)")); 1443 case IKE_GRP_DESC_MODP_8192: 1444 return (gettext("8192-bit MODP (group 18)")); 1445 case IKE_GRP_DESC_ECP_256: 1446 return (gettext("256-bit ECP (group 19)")); 1447 case IKE_GRP_DESC_ECP_384: 1448 return (gettext("384-bit ECP (group 20)")); 1449 case IKE_GRP_DESC_ECP_521: 1450 return (gettext("521-bit ECP (group 21)")); 1451 case IKE_GRP_DESC_MODP_1024_160: 1452 return ( 1453 gettext("1024-bit MODP with 160-bit subprime (group 22)")); 1454 case IKE_GRP_DESC_MODP_2048_224: 1455 return ( 1456 gettext("2048-bit MODP with 224-bit subprime (group 23)")); 1457 case IKE_GRP_DESC_MODP_2048_256: 1458 return ( 1459 gettext("2048-bit MODP with 256-bit subprime (group 24)")); 1460 case IKE_GRP_DESC_ECP_192: 1461 return (gettext("192-bit ECP (group 25)")); 1462 case IKE_GRP_DESC_ECP_224: 1463 return (gettext("224-bit ECP (group 26)")); 1464 default: 1465 (void) snprintf(rtn, MAXLINESIZE, gettext("<unknown %d>"), grp); 1466 return (rtn); 1467 } 1468 } 1469 1470 static void 1471 print_hdr(char *prefix, ike_p1_hdr_t *hdrp) 1472 { 1473 char sbuf[TBUF_SIZE]; 1474 char tbuf[TBUF_SIZE]; 1475 time_t ltime = (time_t)hdrp->p1hdr_dpd_time; 1476 1477 (void) printf( 1478 gettext("%s Cookies: Initiator 0x%llx Responder 0x%llx\n"), 1479 prefix, ntohll(hdrp->p1hdr_cookies.cky_i), 1480 ntohll(hdrp->p1hdr_cookies.cky_r)); 1481 (void) printf(gettext("%s The local host is the %s.\n"), prefix, 1482 hdrp->p1hdr_isinit ? gettext("initiator") : gettext("responder")); 1483 (void) printf(gettext("%s ISAKMP version %d.%d; %s exchange\n"), prefix, 1484 hdrp->p1hdr_major, hdrp->p1hdr_minor, xchgstr(hdrp->p1hdr_xchg)); 1485 (void) printf(gettext("%s Current state is %s\n"), prefix, 1486 statestr(hdrp->p1hdr_state)); 1487 if (hdrp->p1hdr_support_dpd == B_FALSE) { 1488 return; 1489 } 1490 (void) printf(gettext("%s Dead Peer Detection (RFC 3706)" 1491 " enabled"), prefix); 1492 if (hdrp->p1hdr_dpd_state < DPD_IN_PROGRESS) { 1493 (void) printf("\n"); 1494 return; 1495 } 1496 if (strftime(tbuf, TBUF_SIZE, NULL, 1497 localtime(<ime)) == 0) { 1498 (void) strlcpy(tbuf, gettext("<time conversion failed>"), 1499 TBUF_SIZE); 1500 } 1501 (void) printf(gettext("\n%s Dead Peer Detection handshake "), prefix); 1502 switch (hdrp->p1hdr_dpd_state) { 1503 case DPD_SUCCESSFUL: 1504 (void) strlcpy(sbuf, gettext("was successful at "), TBUF_SIZE); 1505 break; 1506 case DPD_FAILURE: 1507 (void) strlcpy(sbuf, gettext("failed at "), TBUF_SIZE); 1508 break; 1509 case DPD_IN_PROGRESS: 1510 (void) strlcpy(sbuf, gettext("is in progress."), TBUF_SIZE); 1511 break; 1512 } 1513 (void) printf("%s %s", sbuf, 1514 (hdrp->p1hdr_dpd_state == DPD_IN_PROGRESS) ? "" : tbuf); 1515 (void) printf("\n"); 1516 } 1517 1518 static void 1519 print_lt_limits(char *prefix, ike_p1_xform_t *xfp) 1520 { 1521 char byte_str[BYTE_STR_SIZE]; /* byte lifetime string representation */ 1522 char secs_str[SECS_STR_SIZE]; /* lifetime string representation */ 1523 1524 (void) printf(gettext("%s Lifetime limits:\n"), prefix); 1525 (void) printf(gettext("%s %u seconds%s; %u kbytes %sprotected\n"), 1526 prefix, xfp->p1xf_max_secs, secs2out(xfp->p1xf_max_secs, 1527 secs_str, sizeof (secs_str), SPC_BEGIN), xfp->p1xf_max_kbytes, 1528 bytecnt2out((uint64_t)xfp->p1xf_max_kbytes << 10, byte_str, 1529 sizeof (byte_str), SPC_END)); 1530 (void) printf(gettext("%s keying material for IPsec SAs can be " 1531 "provided %u times%s\n"), prefix, xfp->p1xf_max_keyuses, 1532 xfp->p1xf_max_keyuses == 0 ? " (no limit)" : ""); 1533 } 1534 1535 #define LT_USAGE_LEN 16 /* 1 uint64 + 2 uint32s */ 1536 static void 1537 print_lt_usage(char *prefix, ike_p1_stats_t *sp) 1538 { 1539 time_t scratch; 1540 char tbuf[TBUF_SIZE]; 1541 char bytestr[BYTE_STR_SIZE]; /* byte lifetime representation */ 1542 1543 (void) printf(gettext("%s Current usage:\n"), prefix); 1544 scratch = (time_t)sp->p1stat_start; 1545 if (strftime(tbuf, TBUF_SIZE, NULL, localtime(&scratch)) == 0) 1546 (void) strlcpy(tbuf, gettext("<time conversion failed>"), 1547 TBUF_SIZE); 1548 (void) printf(gettext("%s SA was created at %s\n"), prefix, tbuf); 1549 (void) printf(gettext("%s %u kbytes %sprotected\n"), 1550 prefix, sp->p1stat_kbytes, 1551 bytecnt2out((uint64_t)sp->p1stat_kbytes << 10, bytestr, 1552 sizeof (bytestr), SPC_END)); 1553 (void) printf(gettext("%s keying material for IPsec SAs provided " 1554 "%u times\n"), prefix, sp->p1stat_keyuses); 1555 } 1556 1557 static void 1558 print_xform(char *prefix, ike_p1_xform_t *xfp, boolean_t print_lifetimes) 1559 { 1560 (void) printf(gettext("%s Authentication method: %s"), prefix, 1561 authmethstr(xfp->p1xf_auth_meth)); 1562 (void) printf(gettext("\n%s Encryption alg: "), prefix); 1563 (void) dump_ealg(xfp->p1xf_encr_alg, stdout); 1564 if (xfp->p1xf_encr_low_bits != 0) { 1565 (void) printf(gettext("(%d..%d)"), xfp->p1xf_encr_low_bits, 1566 xfp->p1xf_encr_high_bits); 1567 } else if ((xfp->p1xf_encr_low_bits == 0) && 1568 (xfp->p1xf_encr_high_bits != 0)) { 1569 /* 1570 * High bits is a placeholder for 1571 * negotiated algorithm strength 1572 */ 1573 (void) printf(gettext("(%d)"), xfp->p1xf_encr_high_bits); 1574 } 1575 (void) printf(gettext("; Authentication alg: ")); 1576 (void) dump_aalg(xfp->p1xf_auth_alg, stdout); 1577 (void) printf("\n%s ", prefix); 1578 if (xfp->p1xf_prf != 0) 1579 (void) printf(gettext("PRF: %s ; "), prfstr(xfp->p1xf_prf)); 1580 (void) printf(gettext("Oakley Group: %s\n"), 1581 dhstr(xfp->p1xf_dh_group)); 1582 if (xfp->p1xf_pfs == 0) { 1583 (void) printf(gettext("%s Phase 2 PFS is not used\n"), prefix); 1584 } else { 1585 (void) printf(gettext( 1586 "%s Phase 2 PFS is required (Oakley Group: %s)\n"), 1587 prefix, dhstr(xfp->p1xf_pfs)); 1588 } 1589 1590 if (print_lifetimes) 1591 print_lt_limits(prefix, xfp); 1592 } 1593 1594 static void 1595 print_lifetime(char *prefix, ike_p1_xform_t *xfp, ike_p1_stats_t *sp, 1596 int statlen) 1597 { 1598 time_t current, remain, exp; 1599 char tbuf[TBUF_SIZE]; 1600 char byte_str[BYTE_STR_SIZE]; /* byte lifetime representation */ 1601 char secs_str[SECS_STR_SIZE]; /* seconds lifetime representation */ 1602 1603 current = time(NULL); 1604 1605 print_lt_limits(prefix, xfp); 1606 1607 /* 1608 * make sure the stats struct we've been passed is as big 1609 * as we expect it to be. The usage stats are at the end, 1610 * so anything less than the size we expect won't work. 1611 */ 1612 if (statlen >= sizeof (ike_p1_stats_t)) { 1613 print_lt_usage(prefix, sp); 1614 } else { 1615 return; 1616 } 1617 1618 (void) printf(gettext("%s Expiration info:\n"), prefix); 1619 1620 if (xfp->p1xf_max_kbytes != 0) 1621 (void) printf(gettext("%s %u more bytes %scan be " 1622 "protected.\n"), 1623 prefix, xfp->p1xf_max_kbytes - sp->p1stat_kbytes, 1624 bytecnt2out((uint64_t)(xfp->p1xf_max_kbytes - 1625 sp->p1stat_kbytes) << 10, byte_str, sizeof (byte_str), 1626 SPC_END)); 1627 1628 if (xfp->p1xf_max_keyuses != 0) 1629 (void) printf(gettext("%s Keying material can be provided " 1630 "%u more times.\n"), prefix, 1631 xfp->p1xf_max_keyuses - sp->p1stat_keyuses); 1632 1633 if (xfp->p1xf_max_secs != 0) { 1634 exp = (time_t)sp->p1stat_start + (time_t)xfp->p1xf_max_secs; 1635 remain = exp - current; 1636 if (strftime(tbuf, TBUF_SIZE, NULL, localtime(&exp)) == 0) 1637 (void) strlcpy(tbuf, 1638 gettext("<time conversion failed>"), TBUF_SIZE); 1639 /* 1640 * The SA may have expired but still exist because libike 1641 * has not freed it yet. 1642 */ 1643 if (remain > 0) { 1644 (void) printf(gettext( 1645 "%s SA expires in %lu seconds%s\n"), 1646 prefix, remain, secs2out(remain, secs_str, 1647 sizeof (secs_str), SPC_BEGIN)); 1648 (void) printf(gettext("%s Time of expiration: %s\n"), 1649 prefix, tbuf); 1650 } else { 1651 (void) printf(gettext("%s SA Expired at %s\n"), 1652 prefix, tbuf); 1653 } 1654 } 1655 } 1656 1657 /* used to verify structure lengths... */ 1658 #define COUNTER_32BIT 4 1659 #define COUNTER_PAIR 8 1660 1661 static void 1662 print_p1stats(char *prefix, ike_p1_stats_t *sp, int statlen, 1663 boolean_t print_lifetimes) 1664 { 1665 if (statlen < COUNTER_PAIR) 1666 return; 1667 (void) printf(gettext("%s %u Quick Mode SAs created; "), prefix, 1668 sp->p1stat_new_qm_sas); 1669 (void) printf(gettext("%u Quick Mode SAs deleted\n"), 1670 sp->p1stat_del_qm_sas); 1671 statlen -= COUNTER_PAIR; 1672 1673 if ((print_lifetimes) && (statlen >= LT_USAGE_LEN)) 1674 print_lt_usage(prefix, sp); 1675 } 1676 1677 static void 1678 print_errs(char *prefix, ike_p1_errors_t *errp, int errlen) 1679 { 1680 /* 1681 * Don't try to break this one up; it's either all or nothing! 1682 */ 1683 if (errlen < sizeof (ike_p1_errors_t)) 1684 return; 1685 1686 (void) printf(gettext("%s %u RX errors: "), prefix, 1687 errp->p1err_decrypt + errp->p1err_hash + errp->p1err_otherrx); 1688 (void) printf(gettext("%u decryption, %u hash, %u other\n"), 1689 errp->p1err_decrypt, errp->p1err_hash, errp->p1err_otherrx); 1690 (void) printf(gettext("%s %u TX errors\n"), prefix, errp->p1err_tx); 1691 } 1692 1693 static void 1694 print_addr_range(char *prefix, ike_addr_pr_t *pr) 1695 { 1696 boolean_t range = B_TRUE; 1697 struct sockaddr_storage *beg, *end; 1698 struct sockaddr_in *bsin, *esin; 1699 struct sockaddr_in6 *bsin6, *esin6; 1700 1701 beg = &pr->beg_iprange; 1702 end = &pr->end_iprange; 1703 1704 if (beg->ss_family != end->ss_family) { 1705 (void) printf(gettext("%s invalid address range\n"), prefix); 1706 return; 1707 } 1708 1709 switch (beg->ss_family) { 1710 case AF_INET: 1711 bsin = (struct sockaddr_in *)beg; 1712 esin = (struct sockaddr_in *)end; 1713 if ((uint32_t)bsin->sin_addr.s_addr == 1714 (uint32_t)esin->sin_addr.s_addr) 1715 range = B_FALSE; 1716 break; 1717 case AF_INET6: 1718 bsin6 = (struct sockaddr_in6 *)beg; 1719 esin6 = (struct sockaddr_in6 *)end; 1720 if (IN6_ARE_ADDR_EQUAL(&bsin6->sin6_addr, &esin6->sin6_addr)) 1721 range = B_FALSE; 1722 break; 1723 default: 1724 (void) printf(gettext("%s invalid address range\n"), prefix); 1725 return; 1726 } 1727 1728 (void) printf("%s ", prefix); 1729 (void) dump_sockaddr((struct sockaddr *)beg, 0, B_TRUE, stdout, nflag); 1730 if (range) { 1731 (void) printf(" - "); 1732 (void) dump_sockaddr((struct sockaddr *)end, 0, B_TRUE, stdout, 1733 nflag); 1734 } 1735 (void) printf("\n"); 1736 1737 } 1738 1739 /* 1740 * used to tell printing function if info should be identified 1741 * as belonging to initiator, responder, or neither 1742 */ 1743 #define IS_INITIATOR 1 1744 #define IS_RESPONDER 2 1745 #define DONT_PRINT_INIT 3 1746 1747 static void 1748 print_addr(char *prefix, struct sockaddr_storage *sa, int init_instr) 1749 { 1750 (void) printf(gettext("%s Address"), prefix); 1751 1752 if (init_instr != DONT_PRINT_INIT) 1753 (void) printf(" (%s):\n", (init_instr == IS_INITIATOR) ? 1754 gettext("Initiator") : gettext("Responder")); 1755 else 1756 (void) printf(":\n"); 1757 1758 (void) printf("%s ", prefix); 1759 (void) dump_sockaddr((struct sockaddr *)sa, 0, B_FALSE, stdout, nflag); 1760 } 1761 1762 static void 1763 print_id(char *prefix, sadb_ident_t *idp, int init_instr) 1764 { 1765 boolean_t canprint; 1766 1767 switch (init_instr) { 1768 case IS_INITIATOR: 1769 (void) printf(gettext("%s Initiator identity, "), prefix); 1770 break; 1771 case IS_RESPONDER: 1772 (void) printf(gettext("%s Responder identity, "), prefix); 1773 break; 1774 case DONT_PRINT_INIT: 1775 (void) printf(gettext("%s Identity, "), prefix); 1776 break; 1777 default: 1778 (void) printf(gettext("<invalid identity>\n")); 1779 return; 1780 } 1781 (void) printf(gettext("uid=%d, type "), idp->sadb_ident_id); 1782 canprint = dump_sadb_idtype(idp->sadb_ident_type, stdout, NULL); 1783 if (canprint) { 1784 (void) printf("\n%s %s\n", prefix, (char *)(idp + 1)); 1785 } else { 1786 (void) printf(gettext("\n%s "), prefix); 1787 print_asn1_name(stdout, 1788 (const unsigned char *)(idp + 1), 1789 SADB_64TO8(idp->sadb_ident_len) - sizeof (sadb_ident_t)); 1790 } 1791 } 1792 1793 static void 1794 print_idspec(char *prefix, char *idp, int icnt, int ecnt) 1795 { 1796 int i; 1797 1798 (void) printf(gettext("%s Identity descriptors:\n"), prefix); 1799 1800 for (i = 0; i < icnt; i++) { 1801 if (i == 0) 1802 (void) printf(gettext("%s Includes:\n"), prefix); 1803 (void) printf("%s %s\n", prefix, idp); 1804 idp += strlen(idp) + 1; 1805 } 1806 1807 for (i = 0; i < ecnt; i++) { 1808 if (i == 0) 1809 (void) printf(gettext("%s Excludes:\n"), prefix); 1810 (void) printf("%s %s\n", prefix, idp); 1811 idp += strlen(idp) + 1; 1812 } 1813 } 1814 1815 static void 1816 print_keys(char *prefix, ike_p1_key_t *keyp, int size) 1817 { 1818 uint32_t *curp; 1819 ike_p1_key_t *p; 1820 int ssize; 1821 1822 curp = (uint32_t *)keyp; 1823 1824 ssize = sizeof (ike_p1_key_t); 1825 1826 while ((intptr_t)curp - (intptr_t)keyp < size) { 1827 size_t p1klen, len; 1828 1829 p = (ike_p1_key_t *)curp; 1830 p1klen = p->p1key_len; 1831 len = p1klen - ssize; 1832 1833 p1klen = roundup(p1klen, sizeof (ike_p1_key_t)); 1834 if (p1klen < ssize) { 1835 (void) printf(gettext("Short key\n")); 1836 break; 1837 } 1838 1839 switch (p->p1key_type) { 1840 case IKE_KEY_PRESHARED: 1841 (void) printf(gettext("%s Pre-shared key (%d bytes): "), 1842 prefix, len); 1843 break; 1844 case IKE_KEY_SKEYID: 1845 (void) printf(gettext("%s SKEYID (%d bytes): "), 1846 prefix, len); 1847 break; 1848 case IKE_KEY_SKEYID_D: 1849 (void) printf(gettext("%s SKEYID_d (%d bytes): "), 1850 prefix, len); 1851 break; 1852 case IKE_KEY_SKEYID_A: 1853 (void) printf(gettext("%s SKEYID_a (%d bytes): "), 1854 prefix, len); 1855 break; 1856 case IKE_KEY_SKEYID_E: 1857 (void) printf(gettext("%s SKEYID_e (%d bytes): "), 1858 prefix, len); 1859 break; 1860 case IKE_KEY_ENCR: 1861 (void) printf(gettext("%s Encryption key (%d bytes): "), 1862 prefix, len); 1863 break; 1864 case IKE_KEY_IV: 1865 (void) printf( 1866 gettext("%s Initialization vector (%d bytes): "), 1867 prefix, len); 1868 break; 1869 default: 1870 (void) printf(gettext("%s Unidentified key info %p %d"), 1871 prefix, p, p1klen); 1872 goto badkey; 1873 } 1874 (void) dump_key((uint8_t *)(p + 1), SADB_8TO1(len), 0, 1875 stdout, B_FALSE); 1876 badkey: 1877 (void) printf("\n"); 1878 assert(IS_P2ALIGNED(p1klen, 8)); 1879 curp += (p1klen >> 2); 1880 } 1881 } 1882 1883 static void 1884 print_p1(ike_p1_sa_t *p1) 1885 { 1886 ike_p1_stats_t *sp; 1887 ike_p1_errors_t *ep; 1888 ike_p1_key_t *kp; 1889 sadb_ident_t *lidp, *ridp; 1890 int lstat, rstat; 1891 1892 (void) printf("\n"); 1893 print_hdr("IKESA:", &p1->p1sa_hdr); 1894 print_xform("XFORM:", &p1->p1sa_xform, B_FALSE); 1895 1896 if (p1->p1sa_hdr.p1hdr_isinit) { 1897 lstat = IS_INITIATOR; 1898 rstat = IS_RESPONDER; 1899 } else { 1900 lstat = IS_RESPONDER; 1901 rstat = IS_INITIATOR; 1902 } 1903 print_addr("LOCIP:", &p1->p1sa_ipaddrs.loc_addr, lstat); 1904 print_addr("REMIP:", &p1->p1sa_ipaddrs.rem_addr, rstat); 1905 1906 /* 1907 * the stat len might be 0; but still make the call 1908 * to print_lifetime() to pick up the xform info 1909 */ 1910 sp = (ike_p1_stats_t *)((int)(p1) + p1->p1sa_stat_off); 1911 print_lifetime("LIFTM:", &p1->p1sa_xform, sp, p1->p1sa_stat_len); 1912 1913 if (p1->p1sa_stat_len > 0) { 1914 print_p1stats("STATS:", sp, p1->p1sa_stat_len, B_FALSE); 1915 } 1916 1917 if (p1->p1sa_error_len > 0) { 1918 ep = (ike_p1_errors_t *)((int)(p1) + p1->p1sa_error_off); 1919 print_errs("ERRS: ", ep, p1->p1sa_error_len); 1920 } 1921 1922 if (p1->p1sa_localid_len > 0) { 1923 lidp = (sadb_ident_t *)((int)(p1) + p1->p1sa_localid_off); 1924 print_id("LOCID:", lidp, lstat); 1925 } 1926 1927 if (p1->p1sa_remoteid_len > 0) { 1928 ridp = (sadb_ident_t *)((int)(p1) + p1->p1sa_remoteid_off); 1929 print_id("REMID:", ridp, rstat); 1930 } 1931 1932 if (p1->p1sa_key_len > 0) { 1933 kp = (ike_p1_key_t *)((int)(p1) + p1->p1sa_key_off); 1934 print_keys("KEY: ", kp, p1->p1sa_key_len); 1935 } 1936 } 1937 1938 static void 1939 print_certcache(ike_certcache_t *c) 1940 { 1941 (void) printf("\n"); 1942 1943 (void) printf(gettext("CERTIFICATE CACHE ID: %d\n"), c->cache_id); 1944 (void) printf(gettext("\tSubject Name: <%s>\n"), 1945 (c->subject != NULL) ? c->subject : gettext("Name unavailable")); 1946 (void) printf(gettext("\t Issuer Name: <%s>\n"), 1947 (c->issuer != NULL) ? c->issuer : gettext("Name unavailable")); 1948 if ((int)c->certclass == -1) 1949 (void) printf(gettext("\t\t[trusted certificate]\n")); 1950 switch (c->linkage) { 1951 case CERT_OFF_WIRE: 1952 (void) printf(gettext("\t\t[Public certificate only]\n")); 1953 (void) printf(gettext( 1954 "\t\t[Obtained via certificate payload]\n")); 1955 break; 1956 case CERT_NO_PRIVKEY: 1957 (void) printf(gettext("\t\t[Public certificate only]\n")); 1958 break; 1959 case CERT_PRIVKEY_LOCKED: 1960 (void) printf(gettext( 1961 "\t\t[Private key linked but locked]\n")); 1962 break; 1963 case CERT_PRIVKEY_AVAIL: 1964 (void) printf(gettext("\t\t[Private key available]\n")); 1965 break; 1966 } 1967 } 1968 1969 static void 1970 print_ps(ike_ps_t *ps) 1971 { 1972 sadb_ident_t *lidp, *ridp; 1973 uint8_t *keyp; 1974 1975 (void) printf("\n"); 1976 1977 (void) printf(gettext("PSKEY: For %s exchanges\n"), 1978 xchgstr(ps->ps_ike_mode)); 1979 1980 if (ps->ps_key_len > 0) { 1981 keyp = (uint8_t *)((int)(ps) + ps->ps_key_off); 1982 (void) printf(gettext("PSKEY: Pre-shared key (%d bytes): "), 1983 ps->ps_key_len); 1984 (void) dump_key(keyp, ps->ps_key_bits, 0, stdout, B_FALSE); 1985 (void) printf("\n"); 1986 } 1987 1988 /* 1989 * We get *either* and address or an ident, never both. So if 1990 * the ident is there, don't try printing an address. 1991 */ 1992 if (ps->ps_localid_len > 0) { 1993 lidp = (sadb_ident_t *) 1994 ((int)(ps) + ps->ps_localid_off); 1995 print_id("LOCID:", lidp, DONT_PRINT_INIT); 1996 } else { 1997 print_addr("LOCIP:", &ps->ps_ipaddrs.loc_addr, DONT_PRINT_INIT); 1998 } 1999 2000 if (ps->ps_remoteid_len > 0) { 2001 ridp = (sadb_ident_t *) 2002 ((int)(ps) + ps->ps_remoteid_off); 2003 print_id("REMID:", ridp, DONT_PRINT_INIT); 2004 } else { 2005 print_addr("REMIP:", &ps->ps_ipaddrs.rem_addr, DONT_PRINT_INIT); 2006 } 2007 } 2008 2009 #define PREFIXLEN 16 2010 2011 static void 2012 print_rule(ike_rule_t *rp) 2013 { 2014 char prefix[PREFIXLEN]; 2015 int i; 2016 ike_p1_xform_t *xfp; 2017 ike_addr_pr_t *lipp, *ripp; 2018 char *lidp, *ridp; 2019 char byte_str[BYTE_STR_SIZE]; /* kbyte string representation */ 2020 char secs_str[SECS_STR_SIZE]; /* seconds string representation */ 2021 2022 (void) printf("\n"); 2023 (void) printf(gettext("GLOBL: Label '%s', key manager cookie %u\n"), 2024 rp->rule_label, rp->rule_kmcookie); 2025 (void) printf(gettext("GLOBL: local_idtype=")); 2026 (void) dump_sadb_idtype(rp->rule_local_idtype, stdout, NULL); 2027 (void) printf(gettext(", ike_mode=%s\n"), xchgstr(rp->rule_ike_mode)); 2028 (void) printf(gettext( 2029 "GLOBL: p1_nonce_len=%u, p2_nonce_len=%u, p2_pfs=%s (group %u)\n"), 2030 rp->rule_p1_nonce_len, rp->rule_p2_nonce_len, 2031 (rp->rule_p2_pfs) ? gettext("true") : gettext("false"), 2032 rp->rule_p2_pfs); 2033 (void) printf( 2034 gettext("GLOBL: p2_lifetime=%u seconds%s\n"), 2035 rp->rule_p2_lifetime_secs, secs2out(rp->rule_p2_lifetime_secs, 2036 secs_str, sizeof (secs_str), SPC_BEGIN)); 2037 (void) printf( 2038 gettext("GLOBL: p2_softlife=%u seconds%s\n"), 2039 rp->rule_p2_softlife_secs, secs2out(rp->rule_p2_softlife_secs, 2040 secs_str, sizeof (secs_str), SPC_BEGIN)); 2041 (void) printf( 2042 gettext("GLOBL: p2_idletime=%u seconds%s\n"), 2043 rp->rule_p2_idletime_secs, secs2out(rp->rule_p2_idletime_secs, 2044 secs_str, sizeof (secs_str), SPC_BEGIN)); 2045 /* 2046 * Perform explicit conversion before passing to bytecnt2out() 2047 * to avoid integer overflow. 2048 */ 2049 (void) printf( 2050 gettext("GLOBL: p2_lifetime_kb=%u kilobytes%s\n"), 2051 rp->rule_p2_lifetime_kb, 2052 bytecnt2out((uint64_t)(rp->rule_p2_lifetime_kb) << 10, 2053 byte_str, sizeof (byte_str), SPC_BEGIN)); 2054 (void) printf( 2055 gettext("GLOBL: p2_softlife_kb=%u kilobytes%s\n"), 2056 rp->rule_p2_softlife_kb, 2057 bytecnt2out(((uint64_t)(rp->rule_p2_softlife_kb)) << 10, 2058 byte_str, sizeof (byte_str), SPC_BEGIN)); 2059 2060 if (rp->rule_locip_cnt > 0) { 2061 (void) printf(gettext("LOCIP: IP address range(s):\n")); 2062 lipp = (ike_addr_pr_t *)((int)rp + rp->rule_locip_off); 2063 for (i = 0; i < rp->rule_locip_cnt; i++, lipp++) { 2064 print_addr_range("LOCIP:", lipp); 2065 } 2066 } 2067 2068 if (rp->rule_remip_cnt > 0) { 2069 (void) printf(gettext("REMIP: IP address range(s):\n")); 2070 ripp = (ike_addr_pr_t *)((int)rp + rp->rule_remip_off); 2071 for (i = 0; i < rp->rule_remip_cnt; i++, ripp++) { 2072 print_addr_range("REMIP:", ripp); 2073 } 2074 } 2075 2076 if (rp->rule_locid_inclcnt + rp->rule_locid_exclcnt > 0) { 2077 lidp = (char *)((int)rp + rp->rule_locid_off); 2078 print_idspec("LOCID:", lidp, rp->rule_locid_inclcnt, 2079 rp->rule_locid_exclcnt); 2080 } 2081 2082 if (rp->rule_remid_inclcnt + rp->rule_remid_exclcnt > 0) { 2083 ridp = (char *)((int)rp + rp->rule_remid_off); 2084 print_idspec("REMID:", ridp, rp->rule_remid_inclcnt, 2085 rp->rule_remid_exclcnt); 2086 } 2087 2088 if (rp->rule_xform_cnt > 0) { 2089 (void) printf(gettext("XFRMS: Available Transforms:\n")); 2090 xfp = (ike_p1_xform_t *)((int)rp + rp->rule_xform_off); 2091 for (i = 0; i < rp->rule_xform_cnt; i++, xfp++) { 2092 (void) snprintf(prefix, PREFIXLEN, "XF %2u:", i); 2093 print_xform(prefix, xfp, B_TRUE); 2094 } 2095 } 2096 } 2097 2098 #undef PREFIXLEN 2099 2100 #define PRSACNTS(init, resp) \ 2101 (void) printf(gettext("initiator: %10u responder: %10u\n"), \ 2102 (init), (resp)) 2103 2104 static void 2105 print_stats(ike_stats_t *sp, int len) 2106 { 2107 /* 2108 * before printing each line, make sure the structure we were 2109 * given is big enough to include the fields needed. 2110 */ 2111 if (len < COUNTER_PAIR) 2112 return; 2113 (void) printf(gettext("Phase 1 SA counts:\n")); 2114 (void) printf(gettext("Current: ")); 2115 PRSACNTS(sp->st_init_p1_current, sp->st_resp_p1_current); 2116 len -= COUNTER_PAIR; 2117 2118 if (len < COUNTER_PAIR) 2119 return; 2120 (void) printf(gettext("Total: ")); 2121 PRSACNTS(sp->st_init_p1_total, sp->st_resp_p1_total); 2122 len -= COUNTER_PAIR; 2123 2124 if (len < COUNTER_PAIR) 2125 return; 2126 (void) printf(gettext("Attempted: ")); 2127 PRSACNTS(sp->st_init_p1_attempts, sp->st_resp_p1_attempts); 2128 len -= COUNTER_PAIR; 2129 2130 if (len < (COUNTER_PAIR + COUNTER_32BIT)) 2131 return; 2132 (void) printf(gettext("Failed: ")); 2133 PRSACNTS(sp->st_init_p1_noresp + sp->st_init_p1_respfail, 2134 sp->st_resp_p1_fail); 2135 (void) printf( 2136 gettext(" initiator fails include %u time-out(s)\n"), 2137 sp->st_init_p1_noresp); 2138 2139 if (len < PATH_MAX) 2140 return; 2141 if (*(sp->st_pkcs11_libname) != '\0') 2142 (void) printf(gettext("PKCS#11 library linked in from %s\n"), 2143 sp->st_pkcs11_libname); 2144 } 2145 2146 /* Print one line of 'get defaults' output (i.e. single value). */ 2147 static void 2148 print_defaults(char *label, char *description, char *unit, 2149 uint_t current, uint_t def) 2150 { 2151 (void) printf("%-18s%-10s%11u %-10s%-26s\n", label, 2152 (current != def) ? gettext("config") : gettext("default"), 2153 current, unit, description); 2154 } 2155 2156 /* 2157 * Print out defaults used by in.iked, the argument is a buffer containing 2158 * two ike_defaults_t's, the first contains the hard coded defaults, the second 2159 * contains the actual values used. If these differ, then the defaults have been 2160 * changed via a config file entry. Note that "-" indicates this default 2161 * is not tunable via ike.config(4) or is system wide tunable. 2162 */ 2163 static void 2164 do_print_defaults(ike_defaults_t *dp) 2165 { 2166 ike_defaults_t *ddp; 2167 ddp = (ike_defaults_t *)(dp + 1); 2168 2169 (void) printf(gettext("\nGlobal defaults. Some values can be" 2170 " over-ridden on a per rule basis.\n")); 2171 (void) printf(gettext("\nSystem defaults are time delayed.\n\n")); 2172 2173 (void) printf("%-18s%-10s%-12s%-10s%-26s\n\n", 2174 gettext("Token:"), gettext("Source:"), gettext("Value:"), 2175 gettext("Unit:"), gettext("Description:")); 2176 2177 /* iked tunables */ 2178 print_defaults("p1_lifetime_secs", gettext("phase 1 lifetime"), 2179 gettext("seconds"), ddp->rule_p1_lifetime_secs, 2180 dp->rule_p1_lifetime_secs); 2181 2182 print_defaults("-", gettext("minimum phase 1 lifetime"), 2183 gettext("seconds"), ddp->rule_p1_minlife, 2184 dp->rule_p1_minlife); 2185 2186 print_defaults("p1_nonce_len", gettext("phase 1 nonce length"), 2187 gettext("bytes"), ddp->rule_p1_nonce_len, 2188 dp->rule_p1_nonce_len); 2189 2190 print_defaults("p2_lifetime_secs", gettext("phase 2 lifetime"), 2191 gettext("seconds"), ddp->rule_p2_lifetime_secs, 2192 dp->rule_p2_lifetime_secs); 2193 2194 print_defaults("p2_softlife_secs", gettext("phase 2 soft lifetime"), 2195 gettext("seconds"), ddp->rule_p2_softlife_secs, 2196 dp->rule_p2_softlife_secs); 2197 2198 print_defaults("p2_idletime_secs", gettext("phase 2 idle time"), 2199 gettext("seconds"), ddp->rule_p2_idletime_secs, 2200 dp->rule_p2_idletime_secs); 2201 2202 print_defaults("p2_lifetime_kb", gettext("phase 2 lifetime"), 2203 gettext("kilobytes"), ddp->rule_p2_lifetime_kb, 2204 dp->rule_p2_lifetime_kb); 2205 2206 print_defaults("p2_softlife_kb", gettext("phase 2 soft lifetime"), 2207 gettext("kilobytes"), ddp->rule_p2_softlife_kb, 2208 dp->rule_p2_softlife_kb); 2209 2210 /* system wide tunables */ 2211 print_defaults("-", gettext("system phase 2 lifetime"), 2212 gettext("seconds"), ddp->sys_p2_lifetime_secs, 2213 dp->sys_p2_lifetime_secs); 2214 2215 print_defaults("-", gettext("system phase 2 soft lifetime"), 2216 gettext("seconds"), ddp->sys_p2_softlife_secs, 2217 dp->sys_p2_softlife_secs); 2218 2219 print_defaults("-", gettext("system phase 2 idle time"), 2220 gettext("seconds"), ddp->sys_p2_idletime_secs, 2221 dp->sys_p2_idletime_secs); 2222 2223 print_defaults("-", gettext("system phase 2 lifetime"), 2224 gettext("bytes"), ddp->sys_p2_lifetime_bytes, 2225 dp->sys_p2_lifetime_bytes); 2226 2227 print_defaults("-", gettext("system phase 2 soft lifetime"), 2228 gettext("bytes"), ddp->sys_p2_softlife_bytes, 2229 dp->sys_p2_softlife_bytes); 2230 2231 /* minimum and maximum values */ 2232 print_defaults("-", gettext("minimum phase 2 hard lifetime"), 2233 gettext("seconds"), ddp->rule_p2_minlife_hard_secs, 2234 dp->rule_p2_minlife_hard_secs); 2235 2236 print_defaults("-", gettext("minimum phase 2 soft lifetime"), 2237 gettext("seconds"), ddp->rule_p2_minlife_soft_secs, 2238 dp->rule_p2_minlife_soft_secs); 2239 2240 print_defaults("-", gettext("minimum phase 2 idle lifetime"), 2241 gettext("seconds"), ddp->rule_p2_minlife_idle_secs, 2242 dp->rule_p2_minlife_idle_secs); 2243 2244 print_defaults("-", gettext("minimum phase 2 hard lifetime"), 2245 gettext("kilobytes"), ddp->rule_p2_minlife_hard_kb, 2246 dp->rule_p2_minlife_hard_kb); 2247 2248 print_defaults("-", gettext("minimum phase 2 soft lifetime"), 2249 gettext("kilobytes"), ddp->rule_p2_minlife_soft_kb, 2250 dp->rule_p2_minlife_soft_kb); 2251 2252 print_defaults("-", gettext("minimum phase 2 delta"), 2253 gettext("seconds"), ddp->rule_p2_mindiff_secs, 2254 dp->rule_p2_mindiff_secs); 2255 2256 print_defaults("-", gettext("minimum phase 2 delta"), 2257 gettext("kilobytes"), ddp->rule_p2_mindiff_kb, 2258 dp->rule_p2_mindiff_kb); 2259 2260 print_defaults("-", gettext("maximum phase 2 lifetime"), 2261 gettext("seconds"), ddp->rule_p2_maxlife_secs, 2262 dp->rule_p2_maxlife_secs); 2263 2264 print_defaults("-", gettext("conversion factor"), 2265 gettext("kbytes/s"), ddp->conversion_factor, 2266 dp->conversion_factor); 2267 2268 print_defaults("-", gettext("maximum phase 2 lifetime"), 2269 gettext("kilobytes"), ddp->rule_p2_maxlife_kb, 2270 dp->rule_p2_maxlife_kb); 2271 2272 /* other values */ 2273 print_defaults("p2_nonce_len", gettext("phase 2 nonce length"), 2274 gettext("bytes"), ddp->rule_p2_nonce_len, 2275 dp->rule_p2_nonce_len); 2276 2277 print_defaults("p2_pfs", gettext("phase 2 PFS"), 2278 " ", ddp->rule_p2_pfs, dp->rule_p2_pfs); 2279 2280 print_defaults("max_certs", gettext("max certificates"), 2281 " ", ddp->rule_max_certs, dp->rule_max_certs); 2282 2283 print_defaults("-", gettext("IKE port number"), 2284 " ", ddp->rule_ike_port, dp->rule_ike_port); 2285 2286 print_defaults("-", gettext("NAT-T port number"), 2287 " ", ddp->rule_natt_port, dp->rule_natt_port); 2288 } 2289 2290 static void 2291 print_categories(int level) 2292 { 2293 int mask; 2294 2295 if (level == 0) { 2296 (void) printf(gettext("No debug categories enabled.\n")); 2297 return; 2298 } 2299 2300 (void) printf(gettext("Debug categories enabled:")); 2301 for (mask = 1; mask <= D_HIGHBIT; mask <<= 1) { 2302 if (level & mask) 2303 (void) printf("\n\t%s", dbgstr(mask)); 2304 } 2305 (void) printf("\n"); 2306 } 2307 2308 /*PRINTFLIKE2*/ 2309 static void 2310 ikeadm_err_exit(ike_err_t *err, char *fmt, ...) 2311 { 2312 va_list ap; 2313 char bailbuf[BUFSIZ]; 2314 2315 va_start(ap, fmt); 2316 (void) vsnprintf(bailbuf, BUFSIZ, fmt, ap); 2317 va_end(ap); 2318 if ((err != NULL) && (err->ike_err == IKE_ERR_SYS_ERR)) { 2319 bail_msg("%s: %s", bailbuf, (err->ike_err_unix == 0) ? 2320 gettext("<unknown error>") : strerror(err->ike_err_unix)); 2321 } else { 2322 bail_msg("%s: %s", bailbuf, (err == NULL) ? 2323 gettext("<unknown error>") : errstr(err->ike_err)); 2324 } 2325 } 2326 2327 /*PRINTFLIKE2*/ 2328 static void 2329 ikeadm_err_msg(ike_err_t *err, char *fmt, ...) 2330 { 2331 va_list ap; 2332 char mbuf[BUFSIZ]; 2333 2334 va_start(ap, fmt); 2335 (void) vsnprintf(mbuf, BUFSIZ, fmt, ap); 2336 va_end(ap); 2337 if ((err != NULL) && (err->ike_err == IKE_ERR_SYS_ERR)) { 2338 message("%s: %s", mbuf, (err->ike_err_unix == 0) ? 2339 gettext("<unknown error>") : 2340 ((err->ike_err_unix == EEXIST) ? 2341 gettext("Duplicate entry") : 2342 strerror(err->ike_err_unix))); 2343 } else { 2344 message("%s: %s", mbuf, (err == NULL) ? 2345 gettext("<unknown error>") : errstr(err->ike_err)); 2346 } 2347 } 2348 2349 2350 /* 2351 * Command functions 2352 */ 2353 2354 /* 2355 * Exploit the fact that ike_dbg_t and ike_priv_t have identical 2356 * formats in the following two functions. 2357 */ 2358 static void 2359 do_getvar(int cmd) 2360 { 2361 ike_service_t req, *rtn; 2362 ike_dbg_t *dreq; 2363 char *varname; 2364 2365 switch (cmd) { 2366 case IKE_SVC_GET_DBG: 2367 varname = gettext("debug"); 2368 break; 2369 case IKE_SVC_GET_PRIV: 2370 varname = gettext("privilege"); 2371 break; 2372 default: 2373 bail_msg(gettext("unrecognized get command (%d)"), cmd); 2374 } 2375 2376 dreq = &req.svc_dbg; 2377 dreq->cmd = cmd; 2378 dreq->dbg_level = 0; 2379 2380 rtn = ikedoor_call((char *)&req, sizeof (ike_dbg_t), NULL, 0); 2381 2382 if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 2383 ikeadm_err_exit(&rtn->svc_err, 2384 gettext("error getting %s level"), varname); 2385 } 2386 dreq = &rtn->svc_dbg; 2387 (void) printf(gettext("Current %s level is 0x%x"), 2388 varname, dreq->dbg_level); 2389 2390 if (cmd == IKE_SVC_GET_DBG) { 2391 (void) printf("\n"); 2392 print_categories(dreq->dbg_level); 2393 } else { 2394 (void) printf(gettext(", %s enabled\n"), 2395 privstr(dreq->dbg_level)); 2396 } 2397 } 2398 2399 /* 2400 * Log into a token and unlock all objects 2401 * referenced by PKCS#11 hint files. 2402 */ 2403 static void 2404 do_setdel_pin(int cmd, int argc, char **argv) 2405 { 2406 ike_service_t req, *rtn; 2407 ike_pin_t *preq; 2408 char token_label[PKCS11_TOKSIZE]; 2409 char *token_pin; 2410 char prompt[80]; 2411 2412 if (argc < 1) 2413 Bail(gettext("Must specify PKCS#11 token object.")); 2414 2415 preq = &req.svc_pin; 2416 preq->cmd = cmd; 2417 2418 switch (cmd) { 2419 case IKE_SVC_SET_PIN: 2420 if (parse_token(argc, argv, token_label) != 0) 2421 Bail("Invalid syntax for \"token login\""); 2422 (void) snprintf(prompt, sizeof (prompt), 2423 "Enter PIN for PKCS#11 token \'%s\': ", token_label); 2424 token_pin = 2425 getpassphrase(prompt); 2426 (void) strlcpy((char *)preq->token_pin, token_pin, MAX_PIN_LEN); 2427 bzero(token_pin, strlen(token_pin)); 2428 break; 2429 case IKE_SVC_DEL_PIN: 2430 if (parse_token(argc, argv, token_label) != 0) 2431 Bail("Invalid syntax for \"token logout\""); 2432 break; 2433 default: 2434 bail_msg(gettext("unrecognized token command (%d)"), cmd); 2435 } 2436 2437 (void) strlcpy(preq->pkcs11_token, token_label, PKCS11_TOKSIZE); 2438 2439 rtn = ikedoor_call((char *)&req, sizeof (ike_pin_t), NULL, 0); 2440 if (cmd == IKE_SVC_SET_PIN) 2441 bzero(preq->token_pin, sizeof (preq->token_pin)); 2442 2443 if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 2444 ikeadm_err_exit(&rtn->svc_err, 2445 gettext("PKCS#11 operation")); 2446 } 2447 preq = &rtn->svc_pin; 2448 message(gettext("PKCS#11 operation successful")); 2449 } 2450 2451 static void 2452 do_setvar(int cmd, int argc, char **argv) 2453 { 2454 ike_service_t req, *rtn; 2455 ike_dbg_t *dreq; 2456 door_desc_t *descp = NULL, desc; 2457 int fd, ndesc = 0; 2458 uint32_t reqlevel; 2459 char *varname; 2460 2461 if (argc < 1) 2462 Bail("unspecified level"); 2463 reqlevel = strtoul(argv[0], NULL, 0); 2464 2465 switch (cmd) { 2466 case IKE_SVC_SET_DBG: 2467 if (argc > 2) 2468 Bail("Too many arguments to \"set debug\""); 2469 varname = gettext("debug"); 2470 if (reqlevel == 0) { 2471 /* check for a string... */ 2472 reqlevel = parsedbgopts(argv[0]); 2473 } 2474 if (reqlevel == D_INVALID) 2475 bail_msg(gettext("Bad debug flag: %s"), argv[0]); 2476 break; 2477 case IKE_SVC_SET_PRIV: 2478 if (argc > 1) 2479 Bail("Too many arguments to \"set priv\""); 2480 2481 varname = gettext("privilege"); 2482 if (reqlevel == 0) { 2483 /* check for a string... */ 2484 reqlevel = privstr2num(argv[0]); 2485 } 2486 if (reqlevel > IKE_PRIV_MAXIMUM) 2487 bail_msg(gettext("Bad privilege flag: %s"), argv[0]); 2488 break; 2489 default: 2490 bail_msg(gettext("unrecognized set command (%d)"), cmd); 2491 } 2492 2493 dreq = &req.svc_dbg; 2494 dreq->cmd = cmd; 2495 dreq->dbg_level = reqlevel; 2496 2497 if ((argc == 2) && (cmd == IKE_SVC_SET_DBG)) { 2498 fd = open(argv[1], O_RDWR | O_CREAT | O_APPEND, 2499 S_IRUSR | S_IWUSR); 2500 if (fd < 0) 2501 Bail("open debug file"); 2502 desc.d_data.d_desc.d_descriptor = fd; 2503 desc.d_attributes = DOOR_DESCRIPTOR; 2504 descp = &desc; 2505 ndesc = 1; 2506 } 2507 2508 rtn = ikedoor_call((char *)&req, sizeof (ike_dbg_t), descp, ndesc); 2509 2510 if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 2511 ikeadm_err_exit(&rtn->svc_err, 2512 gettext("error setting %s level"), varname); 2513 } 2514 dreq = &rtn->svc_dbg; 2515 (void) printf( 2516 gettext("Successfully changed %s level from 0x%x to 0x%x\n"), 2517 varname, dreq->dbg_level, reqlevel); 2518 2519 if (cmd == IKE_SVC_SET_DBG) { 2520 print_categories(reqlevel); 2521 } else { 2522 (void) printf(gettext("New privilege level 0x%x enables %s\n"), 2523 reqlevel, privstr(reqlevel)); 2524 } 2525 } 2526 2527 static void 2528 do_getstats(int cmd) 2529 { 2530 ike_service_t *rtn; 2531 ike_statreq_t sreq, *sreqp; 2532 ike_stats_t *sp; 2533 2534 sreq.cmd = cmd; 2535 2536 rtn = ikedoor_call((char *)&sreq, sizeof (ike_statreq_t), NULL, 0); 2537 if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 2538 ikeadm_err_exit(&rtn->svc_err, gettext("error getting stats")); 2539 } 2540 2541 sreqp = &rtn->svc_stats; 2542 sp = (ike_stats_t *)(sreqp + 1); 2543 print_stats(sp, sreqp->stat_len); 2544 } 2545 2546 static void 2547 do_getdefs(int cmd) 2548 { 2549 ike_service_t *rtn; 2550 ike_defreq_t dreq, *dreqp; 2551 ike_defaults_t *dp; 2552 2553 dreq.cmd = cmd; 2554 2555 rtn = ikedoor_call((char *)&dreq, sizeof (ike_defreq_t), NULL, 0); 2556 if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 2557 ikeadm_err_exit(&rtn->svc_err, 2558 gettext("error getting defaults")); 2559 } 2560 2561 dreqp = &rtn->svc_defaults; 2562 dp = (ike_defaults_t *)(dreqp + 1); 2563 2564 /* 2565 * Before printing each line, make sure the structure we were 2566 * given is big enough to include the fields needed. 2567 * Silently bail out of there is a version mismatch. 2568 */ 2569 if (dreqp->stat_len < ((2 * sizeof (ike_defaults_t)) 2570 + sizeof (ike_defreq_t)) || dreqp->version != DOORVER) { 2571 return; 2572 } 2573 do_print_defaults(dp); 2574 } 2575 2576 static void 2577 do_dump(int cmd) 2578 { 2579 char *name; 2580 ike_service_t req, *rtn; 2581 ike_dump_t *dreq, *dump; 2582 2583 switch (cmd) { 2584 case IKE_SVC_DUMP_P1S: 2585 name = gettext("phase 1 SA info"); 2586 break; 2587 case IKE_SVC_DUMP_RULES: 2588 name = gettext("policy rules"); 2589 break; 2590 case IKE_SVC_DUMP_PS: 2591 name = gettext("preshared keys"); 2592 break; 2593 case IKE_SVC_DUMP_CERTCACHE: 2594 name = gettext("certcache"); 2595 break; 2596 default: 2597 bail_msg(gettext("unrecognized dump command (%d)"), cmd); 2598 } 2599 2600 dreq = &req.svc_dump; 2601 dreq->cmd = cmd; 2602 dreq->dump_len = 0; 2603 dreq->dump_next = 0; 2604 do { 2605 rtn = ikedoor_call((char *)&req, sizeof (ike_dump_t), 2606 NULL, 0); 2607 if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 2608 if (rtn && (rtn->svc_err.ike_err == IKE_ERR_NO_OBJ)) { 2609 /* no entries to print */ 2610 break; 2611 } 2612 ikeadm_err_exit(&rtn->svc_err, 2613 gettext("error getting %s"), name); 2614 } 2615 dump = &rtn->svc_dump; 2616 2617 switch (cmd) { 2618 case IKE_SVC_DUMP_P1S: 2619 print_p1((ike_p1_sa_t *)(dump + 1)); 2620 break; 2621 case IKE_SVC_DUMP_RULES: 2622 print_rule((ike_rule_t *)(dump + 1)); 2623 break; 2624 case IKE_SVC_DUMP_PS: 2625 print_ps((ike_ps_t *)(dump + 1)); 2626 break; 2627 case IKE_SVC_DUMP_CERTCACHE: 2628 print_certcache((ike_certcache_t *)(dump + 1)); 2629 break; 2630 } 2631 2632 dreq->dump_next = dump->dump_next; 2633 2634 (void) munmap((char *)rtn, dump->dump_len); 2635 2636 } while (dreq->dump_next); 2637 2638 (void) printf(gettext("\nCompleted dump of %s\n"), name); 2639 } 2640 2641 static void 2642 do_getdel_doorcall(int cmd, int idlen, int idtype, char *idp, char *name) 2643 { 2644 int totallen; 2645 char *p; 2646 ike_service_t *reqp, *rtnp; 2647 ike_get_t *getp; 2648 boolean_t getcmd; 2649 2650 getcmd = ((cmd == IKE_SVC_GET_P1) || (cmd == IKE_SVC_GET_RULE) || 2651 (cmd == IKE_SVC_GET_PS)); 2652 2653 /* 2654 * WARNING: to avoid being redundant, this code takes advantage 2655 * of the fact that the ike_get_t and ike_del_t structures are 2656 * identical (only the field names differ, their function and 2657 * size are the same). If for some reason those structures 2658 * change, this code will need to be re-written to accomodate 2659 * that difference. 2660 */ 2661 totallen = sizeof (ike_get_t) + idlen; 2662 if ((reqp = (ike_service_t *)malloc(totallen)) == NULL) 2663 Bail("malloc(id)"); 2664 2665 getp = &reqp->svc_get; 2666 getp->cmd = cmd; 2667 getp->get_len = totallen; 2668 getp->get_idtype = idtype; 2669 p = (char *)(getp + 1); 2670 2671 (void) memcpy(p, idp, idlen); 2672 2673 rtnp = ikedoor_call((char *)reqp, totallen, NULL, 0); 2674 if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) { 2675 if (rtnp && (rtnp->svc_err.ike_err == IKE_ERR_NO_OBJ)) { 2676 message(gettext("Could not find requested %s."), name); 2677 } else { 2678 ikeadm_err_msg(&rtnp->svc_err, gettext("error %s %s"), 2679 (getcmd) ? gettext("getting") : gettext("deleting"), 2680 name); 2681 } 2682 free(reqp); 2683 return; 2684 } 2685 getp = &rtnp->svc_get; 2686 2687 if (getcmd) { 2688 switch (cmd) { 2689 case IKE_SVC_GET_P1: 2690 print_p1((ike_p1_sa_t *)(getp + 1)); 2691 break; 2692 case IKE_SVC_GET_PS: 2693 print_ps((ike_ps_t *)(getp + 1)); 2694 break; 2695 case IKE_SVC_GET_RULE: 2696 print_rule((ike_rule_t *)(getp + 1)); 2697 break; 2698 } 2699 } else { 2700 message(gettext("Successfully deleted selected %s."), name); 2701 } 2702 2703 (void) munmap((char *)rtnp, getp->get_len); 2704 free(reqp); 2705 } 2706 2707 static void 2708 do_getdel(int cmd, int argc, char **argv) 2709 { 2710 int idlen, idtype = 0, i, j; 2711 int bytelen1, bytelen2; 2712 char *name, *idp, *p, *p1, *p2; 2713 ike_addr_pr_t apr; 2714 ike_cky_pr_t cpr; 2715 sadb_ident_t *sid1p, *sid2p; 2716 struct hostent *he1p, *he2p; 2717 char label[MAX_LABEL_LEN]; 2718 2719 if ((argc < 1) || (argv[0] == NULL)) { 2720 Bail("not enough identification info"); 2721 } 2722 2723 switch (cmd) { 2724 case IKE_SVC_GET_P1: 2725 case IKE_SVC_DEL_P1: 2726 name = gettext("phase 1 SA"); 2727 /* 2728 * The first token must either be an address (or hostname) 2729 * or a cookie. We require cookies to be entered as hex 2730 * numbers, beginning with 0x; so if our token starts with 2731 * that, it's a cookie. 2732 */ 2733 if (strncmp(argv[0], "0x", 2) == 0) { 2734 if (parse_cky_pr(argc, argv, &cpr) >= 0) { 2735 idtype = IKE_ID_CKY_PAIR; 2736 idlen = sizeof (ike_cky_pr_t); 2737 idp = (char *)&cpr; 2738 } 2739 } else { 2740 if (parse_addr_pr(argc, argv, &he1p, &he2p) >= 0) { 2741 idtype = IKE_ID_ADDR_PAIR; 2742 idlen = sizeof (ike_addr_pr_t); 2743 } 2744 } 2745 break; 2746 2747 case IKE_SVC_GET_RULE: 2748 case IKE_SVC_DEL_RULE: 2749 name = gettext("policy rule"); 2750 if (parse_label(argc, argv, label) >= 0) { 2751 idtype = IKE_ID_LABEL; 2752 idlen = MAX_LABEL_LEN; 2753 idp = label; 2754 } 2755 break; 2756 2757 case IKE_SVC_GET_PS: 2758 case IKE_SVC_DEL_PS: 2759 name = gettext("preshared key"); 2760 /* 2761 * The first token must either be an address or an ident 2762 * type. Check for an ident type to determine which it is. 2763 */ 2764 if (parse_idtype(argv[0], NULL) >= 0) { 2765 if (parse_ident_pr(argc, argv, &sid1p, &sid2p) >= 0) { 2766 idtype = IKE_ID_IDENT_PAIR; 2767 idlen = SADB_64TO8(sid1p->sadb_ident_len) + 2768 SADB_64TO8(sid2p->sadb_ident_len); 2769 } 2770 } else { 2771 if (parse_addr_pr(argc, argv, &he1p, &he2p) >= 0) { 2772 idtype = IKE_ID_ADDR_PAIR; 2773 idlen = sizeof (ike_addr_pr_t); 2774 } 2775 } 2776 break; 2777 2778 default: 2779 bail_msg(gettext("unrecognized get/del command (%d)"), cmd); 2780 } 2781 2782 switch (idtype) { 2783 case IKE_ID_ADDR_PAIR: 2784 /* 2785 * we might have exploding addrs here; do every possible 2786 * combination. 2787 */ 2788 i = 0; 2789 j = 0; 2790 while ((p1 = he1p->h_addr_list[i++]) != NULL) { 2791 headdr2sa(p1, &apr.loc_addr, he1p->h_length); 2792 2793 while ((p2 = he2p->h_addr_list[j++]) != NULL) { 2794 headdr2sa(p2, &apr.rem_addr, he2p->h_length); 2795 do_getdel_doorcall(cmd, idlen, idtype, 2796 (char *)&apr, name); 2797 } 2798 } 2799 FREE_HE(he1p); 2800 FREE_HE(he2p); 2801 break; 2802 2803 case IKE_ID_IDENT_PAIR: 2804 bytelen1 = SADB_64TO8(sid1p->sadb_ident_len); 2805 bytelen2 = SADB_64TO8(sid2p->sadb_ident_len); 2806 if (idlen != bytelen1 + bytelen2) 2807 Bail("ident syntax error"); 2808 idp = p = (char *)malloc(idlen); 2809 if (p == NULL) 2810 Bail("malloc(id)"); 2811 (void) memcpy(p, (char *)sid1p, bytelen1); 2812 p += bytelen1; 2813 (void) memcpy(p, (char *)sid2p, bytelen2); 2814 do_getdel_doorcall(cmd, idlen, idtype, idp, name); 2815 free(idp); 2816 free(sid1p); 2817 free(sid2p); 2818 break; 2819 2820 case IKE_ID_CKY_PAIR: 2821 case IKE_ID_LABEL: 2822 do_getdel_doorcall(cmd, idlen, idtype, idp, name); 2823 break; 2824 2825 case 0: 2826 default: 2827 bail_msg(gettext("invalid %s identification\n"), name); 2828 } 2829 } 2830 2831 /* 2832 * Copy source into target, inserting an escape character ('\') before 2833 * any quotes that appear. Return true on success, false on failure. 2834 */ 2835 static boolean_t 2836 escapequotes(char *target, char *source, int tlen) 2837 { 2838 int s, t, len = strlen(source) + 1; 2839 2840 if (tlen < len) 2841 return (B_FALSE); 2842 2843 for (s = 0, t = 0; s < len && t < tlen; s++) { 2844 if (source[s] == '\"') 2845 target[t++] = '\\'; 2846 target[t++] = source[s]; 2847 } 2848 2849 if ((t == tlen) && (s < len)) 2850 return (B_FALSE); 2851 2852 return (B_TRUE); 2853 } 2854 2855 /* 2856 * Return true if the arg following the given keyword should 2857 * be in quotes (i.e. is a string), false if not. 2858 */ 2859 static boolean_t 2860 quotedfield(char *keywd) 2861 { 2862 if ((strncmp(keywd, "label", strlen("label") + 1) == 0) || 2863 (strncmp(keywd, "local_id", strlen("local_id") + 1) == 0) || 2864 (strncmp(keywd, "remote_id", strlen("remote_id") + 1) == 0)) 2865 return (B_TRUE); 2866 2867 return (B_FALSE); 2868 } 2869 2870 static void 2871 do_new(int cmd, int argc, char **argv) 2872 { 2873 ike_service_t *rtn; 2874 ike_new_t new, *newp = NULL; 2875 door_desc_t desc, *descp = NULL; 2876 int i, fd, ndesc = 0, buflen; 2877 char *name, tmpfilepath[32]; 2878 FILE *tmpfile; 2879 2880 switch (cmd) { 2881 case IKE_SVC_NEW_PS: 2882 name = gettext("preshared key"); 2883 break; 2884 case IKE_SVC_NEW_RULE: 2885 name = gettext("policy rule"); 2886 break; 2887 default: 2888 bail_msg(gettext("unrecognized new command (%d)"), cmd); 2889 } 2890 2891 if (argc == 1) { 2892 /* We've been given a file to read from */ 2893 fd = open(argv[0], O_RDONLY); 2894 if (fd < 0) 2895 Bail("open source file"); 2896 2897 desc.d_data.d_desc.d_descriptor = fd; 2898 desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE; 2899 descp = &desc; 2900 ndesc = 1; 2901 2902 new.cmd = cmd; 2903 new.new_len = 0; 2904 newp = &new; 2905 buflen = sizeof (ike_new_t); 2906 2907 } else if ((argc > 1) && (cmd == IKE_SVC_NEW_PS)) { 2908 /* 2909 * This is an alternative to using the tmpfile method 2910 * for preshared keys. It means we're duplicating the 2911 * parsing effort that happens in readps.c; but it 2912 * does avoid having the key sitting in a file. 2913 */ 2914 ike_ps_t *psp; 2915 int pslen; 2916 2917 /* 2918 * must be in interactive mode; don't want keys in 2919 * the process args. 2920 */ 2921 if (!interactive) 2922 Bail("Must be in interactive mode to add key info."); 2923 if (parse_ps(argc, argv, &psp, &pslen) < 0) { 2924 errno = 0; 2925 Bail("invalid preshared key definition"); 2926 } 2927 newp = malloc(sizeof (ike_new_t) + pslen); 2928 if (newp == NULL) 2929 Bail("alloc pskey"); 2930 newp->cmd = cmd; 2931 newp->new_len = sizeof (ike_new_t) + pslen; 2932 (void) memcpy((char *)(newp + 1), psp, pslen); 2933 buflen = newp->new_len; 2934 /* parse_ps allocated the ike_ps_t buffer; free it now */ 2935 free(psp); 2936 2937 } else if ((argc > 1) && (cmd == IKE_SVC_NEW_RULE)) { 2938 /* 2939 * We've been given the item in argv. However, parsing 2940 * rules can get more than a little messy, and in.iked 2941 * already has a great parser for this stuff! So don't 2942 * fool around with trying to do the parsing here. Just 2943 * write it out to a tempfile, and send the fd to in.iked. 2944 * 2945 * We could conceivably do this for preshared keys, 2946 * rather than duplicating the parsing effort; but that 2947 * would mean the key would be written out to a file, 2948 * which isn't such a good idea. 2949 */ 2950 boolean_t doquotes = B_FALSE; 2951 int rtn; 2952 2953 if ((argv[0][0] != '{') || 2954 (argv[argc - 1][strlen(argv[argc - 1]) - 1] != '}')) 2955 bail_msg(gettext("improperly formatted %s"), name); 2956 2957 /* attempt to use a fairly unpredictable file name... */ 2958 (void) sprintf(tmpfilepath, "/var/run/%x", (int)gethrtime()); 2959 fd = open(tmpfilepath, O_RDWR | O_CREAT | O_EXCL, 2960 S_IRUSR | S_IWUSR); 2961 if (fd < 0) 2962 Bail("cannot open tmpfile"); 2963 2964 /* and make it inaccessible asap */ 2965 if (unlink(tmpfilepath) < 0) { 2966 (void) close(fd); 2967 Bail("tmpfile error"); 2968 } 2969 2970 tmpfile = fdopen(fd, "w"); 2971 if (tmpfile == NULL) { 2972 (void) close(fd); 2973 Bail("cannot write to tmpfile"); 2974 } 2975 2976 for (i = 0; i < argc; i++) { 2977 /* 2978 * We have to do some gyrations with our string here, 2979 * to properly handle quotes. There are two issues: 2980 * - some of the fields of a rule may have embedded 2981 * whitespace, and thus must be quoted on the cmd 2982 * line. The shell removes the quotes, and gives 2983 * us a single argv string; but we need to put the 2984 * quotes back in when we write the string out to 2985 * file. The doquotes boolean is set when we 2986 * process a keyword which will be followed by a 2987 * string value (so the NEXT argv element will be 2988 * quoted). 2989 * - there might be a quote character in a field, 2990 * that was escaped on the cmdline. The shell 2991 * removes the escape char, and leaves the quote 2992 * in the string it gives us. We need to put the 2993 * escape char back in before writing to file. 2994 */ 2995 char field[MAXLINESIZE]; 2996 if (!escapequotes(field, argv[i], MAXLINESIZE)) 2997 Bail("write to tmpfile failed (arg too big)"); 2998 if (doquotes) { 2999 rtn = fprintf(tmpfile, "\"%s\"\n", field); 3000 doquotes = B_FALSE; 3001 } else { 3002 rtn = fprintf(tmpfile, "%s\n", field); 3003 } 3004 if (rtn < 0) 3005 Bail("write to tmpfile failed"); 3006 /* 3007 * check if this is a keyword identifying 3008 * a field that needs to be quoted. 3009 */ 3010 doquotes = quotedfield(argv[i]); 3011 } 3012 if (fflush(tmpfile) == EOF) 3013 Bail("write to tmpfile failed"); 3014 /* rewind so that the daemon will get the beginning */ 3015 rewind(tmpfile); 3016 3017 desc.d_data.d_desc.d_descriptor = fd; 3018 desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE; 3019 descp = &desc; 3020 ndesc = 1; 3021 3022 new.cmd = cmd; 3023 new.new_len = 0; 3024 newp = &new; 3025 buflen = sizeof (ike_new_t); 3026 3027 } else { 3028 /* not enough information! */ 3029 bail_msg(gettext("missing %s description or file name"), name); 3030 } 3031 3032 rtn = ikedoor_call((char *)newp, buflen, descp, ndesc); 3033 3034 if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 3035 ikeadm_err_msg(&rtn->svc_err, 3036 gettext("error creating new %s"), name); 3037 } else { 3038 message(gettext("Successfully created new %s."), name); 3039 } 3040 } 3041 3042 static void 3043 do_flush(int cmd) 3044 { 3045 ike_service_t *rtnp; 3046 ike_flush_t flush; 3047 3048 if (cmd != IKE_SVC_FLUSH_P1S && cmd != IKE_SVC_FLUSH_CERTCACHE) { 3049 bail_msg(gettext("unrecognized flush command (%d)."), cmd); 3050 } 3051 3052 flush.cmd = cmd; 3053 3054 rtnp = ikedoor_call((char *)&flush, sizeof (ike_flush_t), NULL, 0); 3055 if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) { 3056 ikeadm_err_exit(&rtnp->svc_err, gettext("error doing flush")); 3057 } 3058 if (cmd == IKE_SVC_FLUSH_P1S) 3059 message(gettext("Successfully flushed P1 SAs.")); 3060 else 3061 message(gettext("Successfully flushed cert cache.")); 3062 } 3063 3064 static void 3065 do_rw(int cmd, int argc, char **argv) 3066 { 3067 ike_service_t *rtnp; 3068 ike_rw_t rw; 3069 door_desc_t desc, *descp = NULL; 3070 int oflag, omode, fd, ndesc = 0; 3071 char *op, *obj = NULL; 3072 boolean_t writing = B_FALSE; 3073 3074 switch (cmd) { 3075 case IKE_SVC_READ_PS: 3076 obj = gettext("preshared key"); 3077 /* FALLTHRU */ 3078 case IKE_SVC_READ_RULES: 3079 if (obj == NULL) 3080 obj = gettext("policy rule"); 3081 op = gettext("read"); 3082 oflag = O_RDONLY; 3083 omode = 0; 3084 break; 3085 3086 case IKE_SVC_WRITE_PS: 3087 obj = gettext("preshared key"); 3088 /* FALLTHRU */ 3089 case IKE_SVC_WRITE_RULES: 3090 if (obj == NULL) 3091 obj = gettext("policy rule"); 3092 op = gettext("write"); 3093 oflag = O_RDWR | O_CREAT | O_EXCL; 3094 omode = S_IRUSR | S_IWUSR; 3095 3096 /* for write commands, dest location must be specified */ 3097 if (argc < 1) { 3098 bail_msg(gettext("destination location required " 3099 "to write %ss"), obj); 3100 } 3101 writing = B_TRUE; 3102 break; 3103 3104 default: 3105 bail_msg(gettext("unrecognized read/write command (%d)."), cmd); 3106 } 3107 3108 rw.cmd = cmd; 3109 3110 if (argc >= 1) { 3111 rw.rw_loc = IKE_RW_LOC_USER_SPEC; 3112 fd = open(argv[0], oflag, omode); 3113 if (fd < 0) 3114 Bail("open user-specified file"); 3115 3116 desc.d_data.d_desc.d_descriptor = fd; 3117 desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE; 3118 descp = &desc; 3119 ndesc = 1; 3120 } else { 3121 rw.rw_loc = IKE_RW_LOC_DEFAULT; 3122 } 3123 3124 rtnp = ikedoor_call((char *)&rw, sizeof (ike_rw_t), descp, ndesc); 3125 if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) { 3126 /* 3127 * Need to remove the target file in the 3128 * case of a failed write command. 3129 */ 3130 if (writing) { 3131 /* 3132 * argv[0] must be valid if we're writing; we 3133 * exit before setting this boolean if not. 3134 */ 3135 (void) unlink(argv[0]); 3136 (void) close(fd); 3137 3138 if ((rtnp != NULL) && 3139 (rtnp->svc_err.ike_err == IKE_ERR_NO_OBJ)) { 3140 message(gettext("No %s information to write."), 3141 obj); 3142 return; 3143 } 3144 } 3145 ikeadm_err_exit(&rtnp->svc_err, gettext("error doing %s"), op); 3146 } 3147 message(gettext("Completed %s of %s configuration information."), 3148 op, obj); 3149 } 3150 3151 static void 3152 do_rbdump() 3153 { 3154 ike_cmd_t req; 3155 ike_service_t *rtnp; 3156 3157 req.cmd = IKE_SVC_DBG_RBDUMP; 3158 3159 rtnp = ikedoor_call((char *)&req, sizeof (ike_cmd_t), NULL, 0); 3160 if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) { 3161 ikeadm_err_exit(&rtnp->svc_err, gettext("error doing flush")); 3162 } 3163 message(gettext("Successfully dumped rulebase; check iked dbg")); 3164 } 3165 3166 #define REQ_ARG_CNT 1 3167 3168 /*ARGSUSED*/ 3169 static void 3170 parseit(int argc, char **argv, char *notused, boolean_t notused_either) 3171 { 3172 int cmd, cmd_obj_args = 1; 3173 char *cmdstr, *objstr; 3174 3175 if (interactive) { 3176 if (argc == 0) 3177 return; 3178 } 3179 3180 if (argc < REQ_ARG_CNT) { 3181 usage(); 3182 } 3183 3184 cmdstr = argv[0]; 3185 if (argc > REQ_ARG_CNT) { 3186 cmd_obj_args++; 3187 objstr = argv[1]; 3188 } else { 3189 objstr = NULL; 3190 } 3191 cmd = parsecmd(cmdstr, objstr); 3192 3193 /* skip over args specifying command/object */ 3194 argc -= cmd_obj_args; 3195 argv += cmd_obj_args; 3196 3197 switch (cmd) { 3198 case IKE_SVC_GET_DEFS: 3199 if (argc != 0) { 3200 print_get_help(); 3201 break; 3202 } 3203 do_getdefs(cmd); 3204 break; 3205 case IKE_SVC_GET_DBG: 3206 case IKE_SVC_GET_PRIV: 3207 if (argc != 0) { 3208 print_get_help(); 3209 break; 3210 } 3211 do_getvar(cmd); 3212 break; 3213 case IKE_SVC_GET_STATS: 3214 if (argc != 0) { 3215 print_get_help(); 3216 break; 3217 } 3218 do_getstats(cmd); 3219 break; 3220 case IKE_SVC_SET_DBG: 3221 case IKE_SVC_SET_PRIV: 3222 do_setvar(cmd, argc, argv); 3223 break; 3224 case IKE_SVC_SET_PIN: 3225 case IKE_SVC_DEL_PIN: 3226 do_setdel_pin(cmd, argc, argv); 3227 break; 3228 case IKE_SVC_DUMP_P1S: 3229 case IKE_SVC_DUMP_RULES: 3230 case IKE_SVC_DUMP_PS: 3231 case IKE_SVC_DUMP_CERTCACHE: 3232 if (argc != NULL) { 3233 print_dump_help(); 3234 break; 3235 } 3236 do_dump(cmd); 3237 break; 3238 case IKE_SVC_GET_P1: 3239 case IKE_SVC_GET_RULE: 3240 case IKE_SVC_GET_PS: 3241 case IKE_SVC_DEL_P1: 3242 case IKE_SVC_DEL_RULE: 3243 case IKE_SVC_DEL_PS: 3244 do_getdel(cmd, argc, argv); 3245 break; 3246 case IKE_SVC_NEW_RULE: 3247 case IKE_SVC_NEW_PS: 3248 do_new(cmd, argc, argv); 3249 break; 3250 case IKE_SVC_FLUSH_P1S: 3251 case IKE_SVC_FLUSH_CERTCACHE: 3252 if (argc != 0) { 3253 print_flush_help(); 3254 break; 3255 } 3256 do_flush(cmd); 3257 break; 3258 case IKE_SVC_READ_RULES: 3259 case IKE_SVC_READ_PS: 3260 case IKE_SVC_WRITE_RULES: 3261 case IKE_SVC_WRITE_PS: 3262 do_rw(cmd, argc, argv); 3263 break; 3264 case IKEADM_HELP_GENERAL: 3265 print_help(); 3266 break; 3267 case IKEADM_HELP_GET: 3268 print_get_help(); 3269 break; 3270 case IKEADM_HELP_SET: 3271 print_set_help(); 3272 break; 3273 case IKEADM_HELP_ADD: 3274 print_add_help(); 3275 break; 3276 case IKEADM_HELP_DEL: 3277 print_del_help(); 3278 break; 3279 case IKEADM_HELP_DUMP: 3280 print_dump_help(); 3281 break; 3282 case IKEADM_HELP_FLUSH: 3283 print_flush_help(); 3284 break; 3285 case IKEADM_HELP_READ: 3286 print_read_help(); 3287 break; 3288 case IKEADM_HELP_WRITE: 3289 print_write_help(); 3290 break; 3291 case IKEADM_HELP_TOKEN: 3292 print_token_help(); 3293 break; 3294 case IKEADM_HELP_HELP: 3295 print_help_help(); 3296 break; 3297 case IKEADM_EXIT: 3298 if (interactive) 3299 exit(0); 3300 break; 3301 case IKE_SVC_DBG_RBDUMP: 3302 do_rbdump(); 3303 break; 3304 case IKE_SVC_ERROR: 3305 usage(); 3306 default: 3307 exit(0); 3308 } 3309 } 3310 3311 int 3312 main(int argc, char **argv) 3313 { 3314 char ch; 3315 3316 (void) setlocale(LC_ALL, ""); 3317 #if !defined(TEXT_DOMAIN) 3318 #define TEXT_DOMAIN "SYS_TEST" 3319 #endif 3320 (void) textdomain(TEXT_DOMAIN); 3321 3322 while ((ch = getopt(argc, argv, "hpn")) != EOF) { 3323 switch (ch) { 3324 case 'h': 3325 print_help(); 3326 return (0); 3327 case 'p': 3328 pflag = B_TRUE; 3329 break; 3330 case 'n': 3331 nflag = B_TRUE; 3332 break; 3333 default: 3334 usage(); 3335 } 3336 } 3337 argc -= optind; 3338 argv += optind; 3339 3340 if (open_door() < 0) { 3341 (void) fprintf(stderr, 3342 gettext("Unable to communicate with in.iked\n")); 3343 Bail("open_door failed"); 3344 } 3345 3346 if (*argv == NULL) { 3347 /* no cmd-line args, do interactive mode */ 3348 do_interactive(stdin, NULL, "ikeadm> ", NULL, parseit, 3349 no_match); 3350 } 3351 3352 parseit(argc, argv, NULL, B_FALSE); 3353 3354 return (0); 3355 } 3356