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