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, *locpfx = NULL, *rempfx = NULL; 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 int pfxlen = 0; 1046 1047 if ((argv[c] == NULL) || (argv[c][0] != '{')) 1048 return (-1); 1049 if (argv[c][1] != 0) { 1050 /* no space between '{' and first token */ 1051 argv[c]++; 1052 } else { 1053 c++; 1054 } 1055 if ((argv[argc - 1][strlen(argv[argc - 1]) - 1] == '}') && 1056 (argv[argc - 1][0] != '}')) { 1057 /* 1058 * whack '}' without a space before it or parsers break. 1059 * Remember this trailing character for later 1060 */ 1061 argv[argc - 1][strlen(argv[argc - 1]) - 1] = '\0'; 1062 whacked = B_TRUE; 1063 } 1064 1065 /* Default to type IP */ 1066 locidtype = remidtype = SADB_IDENTTYPE_RESERVED; 1067 /* Default to base exchanges */ 1068 mtype = IKE_XCHG_BASE; 1069 1070 while ((c < argc) && (argv[c] != NULL) && (argv[c][0] != '}')) { 1071 if ((argv[c + 1] == NULL) || (argv[c + 1][0] == '}')) 1072 goto bail; 1073 if (parse_psfldid(argv[c++], &fldid) < 0) 1074 goto bail; 1075 switch (fldid) { 1076 case PSFLD_LOCID: 1077 locid = argv[c++]; 1078 locidlen = strlen(locid) + 1; 1079 break; 1080 case PSFLD_LOCIDTYPE: 1081 if (parse_idtype(argv[c++], &locidtype) < 0) 1082 goto bail; 1083 break; 1084 case PSFLD_REMID: 1085 remid = argv[c++]; 1086 remidlen = strlen(remid) + 1; 1087 break; 1088 case PSFLD_REMIDTYPE: 1089 if (parse_idtype(argv[c++], &remidtype) < 0) 1090 goto bail; 1091 break; 1092 case PSFLD_MODE: 1093 if (parse_ikmtype(argv[c++], &mtype) < 0) 1094 goto bail; 1095 break; 1096 case PSFLD_KEY: 1097 keyp = parse_key(argv[c++], &keylen, &keybits); 1098 if (keyp == NULL) 1099 goto bail; 1100 break; 1101 } 1102 } 1103 1104 /* Make sure the line was terminated with '}' */ 1105 if (argv[c] == NULL) { 1106 if (!whacked) 1107 goto bail; 1108 } else if (argv[c][0] != '}') { 1109 goto bail; 1110 } 1111 1112 /* 1113 * make sure we got all the required fields. If no idtype, assume 1114 * ip addr; if that translation fails, we'll catch the error then. 1115 */ 1116 if (locid == NULL || remid == NULL || keyp == NULL || mtype == 0) 1117 goto bail; 1118 1119 /* figure out the size buffer we need */ 1120 *len = sizeof (ike_ps_t); 1121 if (locidtype != SADB_IDENTTYPE_RESERVED) { 1122 a_locidtotal = IKEDOORROUNDUP(sizeof (sadb_ident_t) + locidlen); 1123 *len += a_locidtotal; 1124 } 1125 if (remidtype != SADB_IDENTTYPE_RESERVED) { 1126 a_remidtotal = IKEDOORROUNDUP(sizeof (sadb_ident_t) + remidlen); 1127 *len += a_remidtotal; 1128 } 1129 *len += keylen; 1130 1131 psp = malloc(*len); 1132 if (psp == NULL) 1133 goto bail; 1134 (void) memset(psp, 0, *len); 1135 1136 psp->ps_ike_mode = mtype; 1137 1138 psp->ps_localid_off = sizeof (ike_ps_t); 1139 if (locidtype == SADB_IDENTTYPE_RESERVED) { 1140 locpfx = strchr(locid, '/'); 1141 if (locpfx != NULL) { 1142 *locpfx = '\0'; 1143 locpfx++; 1144 } 1145 1146 /* 1147 * this is an ip address, store in the sockaddr field; 1148 * we won't use an sadb_ident_t. 1149 */ 1150 psp->ps_localid_len = 0; 1151 if (parse_addr(1, &locid, &loche) < 0) 1152 goto bail; 1153 if (loche->h_addr_list[1] != NULL) { 1154 message(gettext("preshared key identifier cannot " 1155 "match multiple IP addresses")); 1156 goto bail; 1157 } 1158 headdr2sa(loche->h_addr_list[0], &psp->ps_ipaddrs.loc_addr, 1159 loche->h_length); 1160 FREE_HE(loche); 1161 } else { 1162 psp->ps_localid_len = sizeof (sadb_ident_t) + locidlen; 1163 sidp = (sadb_ident_t *)((int)psp + psp->ps_localid_off); 1164 sidp->sadb_ident_len = psp->ps_localid_len; 1165 sidp->sadb_ident_type = locidtype; 1166 (void) strlcpy((char *)(sidp + 1), locid, a_locidtotal); 1167 } 1168 1169 psp->ps_remoteid_off = psp->ps_localid_off + a_locidtotal; 1170 if (remidtype == SADB_IDENTTYPE_RESERVED) { 1171 rempfx = strchr(remid, '/'); 1172 if (rempfx != NULL) { 1173 *rempfx = '\0'; 1174 rempfx++; 1175 } 1176 1177 /* 1178 * this is an ip address, store in the sockaddr field; 1179 * we won't use an sadb_ident_t. 1180 */ 1181 psp->ps_remoteid_len = 0; 1182 if (parse_addr(1, &remid, &remhe) < 0) 1183 goto bail; 1184 if (remhe->h_addr_list[1] != NULL) { 1185 message(gettext("preshared key identifier cannot " 1186 "match multiple IP addresses")); 1187 goto bail; 1188 } 1189 headdr2sa(remhe->h_addr_list[0], &psp->ps_ipaddrs.rem_addr, 1190 remhe->h_length); 1191 FREE_HE(remhe); 1192 } else { 1193 /* make sure we have at least 16-bit alignment */ 1194 if (remidlen & 0x1) 1195 remidlen++; 1196 psp->ps_remoteid_len = sizeof (sadb_ident_t) + remidlen; 1197 sidp = (sadb_ident_t *)((int)psp + psp->ps_remoteid_off); 1198 sidp->sadb_ident_len = psp->ps_remoteid_len; 1199 sidp->sadb_ident_type = remidtype; 1200 (void) strlcpy((char *)(sidp + 1), remid, a_remidtotal); 1201 } 1202 1203 psp->ps_key_off = psp->ps_remoteid_off + a_remidtotal; 1204 psp->ps_key_len = keylen; 1205 psp->ps_key_bits = keybits; 1206 (void) memcpy((uint8_t *)((int)psp + psp->ps_key_off), keyp, keylen); 1207 if (locpfx != NULL && ((pfxlen = atoi(locpfx)) > 0)) 1208 psp->ps_localid_plen = pfxlen; 1209 if (rempfx != NULL && ((pfxlen = atoi(rempfx)) > 0)) 1210 psp->ps_remoteid_plen = pfxlen; 1211 1212 *presharedpp = psp; 1213 1214 return (c); 1215 1216 bail: 1217 if (loche != NULL) 1218 FREE_HE(loche); 1219 if (remhe != NULL) 1220 FREE_HE(remhe); 1221 if (keyp != NULL) 1222 free(keyp); 1223 if (psp != NULL) 1224 free(psp); 1225 1226 *presharedpp = NULL; 1227 1228 return (-1); 1229 } 1230 1231 /* 1232 * Printing functions 1233 * 1234 * A potential point of confusion here is that the ikeadm-specific string- 1235 * producing functions do not match the ipsec_util.c versions in style: the 1236 * ikeadm-specific functions return a string (and are named foostr), while 1237 * the ipsec_util.c functions actually print the string to the file named 1238 * in the second arg to the function (and are named dump_foo). 1239 * 1240 * Localization for ikeadm seems more straightforward when complete 1241 * phrases are translated rather than: a part of a phrase, a call to 1242 * dump_foo(), and more of the phrase. It could also accommodate 1243 * non-English grammar more easily. 1244 */ 1245 1246 static char * 1247 errstr(int err) 1248 { 1249 static char rtn[MAXLINESIZE]; 1250 1251 switch (err) { 1252 case IKE_ERR_NO_OBJ: 1253 return (gettext("No data returned")); 1254 case IKE_ERR_NO_DESC: 1255 return (gettext("No destination provided")); 1256 case IKE_ERR_ID_INVALID: 1257 return (gettext("Id info invalid")); 1258 case IKE_ERR_LOC_INVALID: 1259 return (gettext("Destination invalid")); 1260 case IKE_ERR_CMD_INVALID: 1261 return (gettext("Command invalid")); 1262 case IKE_ERR_DATA_INVALID: 1263 return (gettext("Supplied data invalid")); 1264 case IKE_ERR_CMD_NOTSUP: 1265 return (gettext("Unknown command")); 1266 case IKE_ERR_REQ_INVALID: 1267 return (gettext("Request invalid")); 1268 case IKE_ERR_NO_PRIV: 1269 return (gettext("Not allowed at current privilege level")); 1270 case IKE_ERR_NO_AUTH: 1271 return (gettext("User not authorized")); 1272 case IKE_ERR_SYS_ERR: 1273 return (gettext("System error")); 1274 case IKE_ERR_DUP_IGNORED: 1275 return (gettext("One or more duplicate entries ignored")); 1276 case IKE_ERR_NO_TOKEN: 1277 return (gettext( 1278 "token login failed or no objects on device")); 1279 case IKE_ERR_IN_PROGRESS: 1280 return (gettext( 1281 "Duplicate operation already in progress")); 1282 case IKE_ERR_NO_MEM: 1283 return (gettext( 1284 "Insufficient memory")); 1285 default: 1286 (void) snprintf(rtn, MAXLINESIZE, 1287 gettext("<unknown error %d>"), err); 1288 return (rtn); 1289 } 1290 } 1291 1292 static char * 1293 dbgstr(int bit) 1294 { 1295 static char rtn[MAXLINESIZE]; 1296 1297 switch (bit) { 1298 case D_CERT: 1299 return (gettext("Certificate management")); 1300 case D_KEY: 1301 return (gettext("Key management")); 1302 case D_OP: 1303 return (gettext("Operational")); 1304 case D_P1: 1305 return (gettext("Phase 1 SA creation")); 1306 case D_P2: 1307 return (gettext("Phase 2 SA creation")); 1308 case D_PFKEY: 1309 return (gettext("PF_KEY interface")); 1310 case D_POL: 1311 return (gettext("Policy management")); 1312 case D_PROP: 1313 return (gettext("Proposal construction")); 1314 case D_DOOR: 1315 return (gettext("Door interface")); 1316 case D_CONFIG: 1317 return (gettext("Config file processing")); 1318 case D_LABEL: 1319 return (gettext("MAC label processing")); 1320 default: 1321 (void) snprintf(rtn, MAXLINESIZE, 1322 gettext("<unknown flag 0x%x>"), bit); 1323 return (rtn); 1324 } 1325 } 1326 1327 static char * 1328 privstr(int priv) 1329 { 1330 static char rtn[MAXLINESIZE]; 1331 1332 switch (priv) { 1333 case IKE_PRIV_MINIMUM: 1334 return (gettext("base privileges")); 1335 case IKE_PRIV_MODKEYS: 1336 return (gettext("access to preshared key information")); 1337 case IKE_PRIV_KEYMAT: 1338 return (gettext("access to keying material")); 1339 default: 1340 (void) snprintf(rtn, MAXLINESIZE, 1341 gettext("<unknown level %d>"), priv); 1342 return (rtn); 1343 } 1344 } 1345 1346 static char * 1347 xchgstr(int xchg) 1348 { 1349 static char rtn[MAXLINESIZE]; 1350 1351 switch (xchg) { 1352 case IKE_XCHG_NONE: 1353 return (gettext("<unspecified>")); 1354 case IKE_XCHG_BASE: 1355 return (gettext("base")); 1356 case IKE_XCHG_IDENTITY_PROTECT: 1357 return (gettext("main mode (identity protect)")); 1358 case IKE_XCHG_AUTH_ONLY: 1359 return (gettext("authentication only")); 1360 case IKE_XCHG_AGGRESSIVE: 1361 return (gettext("aggressive mode")); 1362 case IKE_XCHG_IP_AND_AGGR: 1363 return (gettext("main and aggressive mode")); 1364 case IKE_XCHG_ANY: 1365 return (gettext("any mode")); 1366 default: 1367 (void) snprintf(rtn, MAXLINESIZE, 1368 gettext("<unknown %d>"), xchg); 1369 return (rtn); 1370 } 1371 } 1372 1373 static char * 1374 statestr(int state) 1375 { 1376 static char rtn[MAXLINESIZE]; 1377 1378 switch (state) { 1379 case IKE_SA_STATE_INIT: 1380 return (gettext("INITIALIZING")); 1381 case IKE_SA_STATE_SENT_SA: 1382 return (gettext("SENT FIRST MSG (SA)")); 1383 case IKE_SA_STATE_SENT_KE: 1384 return (gettext("SENT SECOND MSG (KE)")); 1385 case IKE_SA_STATE_SENT_LAST: 1386 return (gettext("SENT FINAL MSG")); 1387 case IKE_SA_STATE_DONE: 1388 return (gettext("ACTIVE")); 1389 case IKE_SA_STATE_DELETED: 1390 return (gettext("DELETED")); 1391 case IKE_SA_STATE_INVALID: 1392 return (gettext("<invalid>")); 1393 default: 1394 (void) snprintf(rtn, MAXLINESIZE, 1395 gettext("<unknown %d>"), state); 1396 return (rtn); 1397 } 1398 } 1399 1400 static char * 1401 authmethstr(int meth) 1402 { 1403 static char rtn[MAXLINESIZE]; 1404 1405 switch (meth) { 1406 case IKE_AUTH_METH_PRE_SHARED_KEY: 1407 return (gettext("pre-shared key")); 1408 case IKE_AUTH_METH_DSS_SIG: 1409 return (gettext("DSS signatures")); 1410 case IKE_AUTH_METH_RSA_SIG: 1411 return (gettext("RSA signatures")); 1412 case IKE_AUTH_METH_RSA_ENCR: 1413 return (gettext("RSA Encryption")); 1414 case IKE_AUTH_METH_RSA_ENCR_REVISED: 1415 return (gettext("Revised RSA Encryption")); 1416 default: 1417 (void) snprintf(rtn, MAXLINESIZE, 1418 gettext("<unknown %d>"), meth); 1419 return (rtn); 1420 } 1421 } 1422 1423 static char * 1424 prfstr(int prf) 1425 { 1426 static char rtn[MAXLINESIZE]; 1427 1428 switch (prf) { 1429 case IKE_PRF_NONE: 1430 return (gettext("<none/unavailable>")); 1431 case IKE_PRF_HMAC_MD5: 1432 return ("HMAC MD5"); 1433 case IKE_PRF_HMAC_SHA1: 1434 return ("HMAC SHA1"); 1435 case IKE_PRF_HMAC_SHA256: 1436 return ("HMAC SHA256"); 1437 case IKE_PRF_HMAC_SHA384: 1438 return ("HMAC SHA384"); 1439 case IKE_PRF_HMAC_SHA512: 1440 return ("HMAC SHA512"); 1441 default: 1442 (void) snprintf(rtn, MAXLINESIZE, 1443 gettext("<unknown %d>"), prf); 1444 return (rtn); 1445 } 1446 } 1447 1448 static char * 1449 dhstr(int grp) 1450 { 1451 static char rtn[MAXLINESIZE]; 1452 1453 switch (grp) { 1454 case 0: 1455 return (gettext("<unavailable>")); 1456 case IKE_GRP_DESC_MODP_768: 1457 return (gettext("768-bit MODP (group 1)")); 1458 case IKE_GRP_DESC_MODP_1024: 1459 return (gettext("1024-bit MODP (group 2)")); 1460 case IKE_GRP_DESC_EC2N_155: 1461 return (gettext("EC2N group on GP[2^155]")); 1462 case IKE_GRP_DESC_EC2N_185: 1463 return (gettext("EC2N group on GP[2^185]")); 1464 case IKE_GRP_DESC_MODP_1536: 1465 return (gettext("1536-bit MODP (group 5)")); 1466 case IKE_GRP_DESC_MODP_2048: 1467 return (gettext("2048-bit MODP (group 14)")); 1468 case IKE_GRP_DESC_MODP_3072: 1469 return (gettext("3072-bit MODP (group 15)")); 1470 case IKE_GRP_DESC_MODP_4096: 1471 return (gettext("4096-bit MODP (group 16)")); 1472 case IKE_GRP_DESC_MODP_6144: 1473 return (gettext("6144-bit MODP (group 17)")); 1474 case IKE_GRP_DESC_MODP_8192: 1475 return (gettext("8192-bit MODP (group 18)")); 1476 case IKE_GRP_DESC_ECP_256: 1477 return (gettext("256-bit ECP (group 19)")); 1478 case IKE_GRP_DESC_ECP_384: 1479 return (gettext("384-bit ECP (group 20)")); 1480 case IKE_GRP_DESC_ECP_521: 1481 return (gettext("521-bit ECP (group 21)")); 1482 case IKE_GRP_DESC_MODP_1024_160: 1483 return ( 1484 gettext("1024-bit MODP with 160-bit subprime (group 22)")); 1485 case IKE_GRP_DESC_MODP_2048_224: 1486 return ( 1487 gettext("2048-bit MODP with 224-bit subprime (group 23)")); 1488 case IKE_GRP_DESC_MODP_2048_256: 1489 return ( 1490 gettext("2048-bit MODP with 256-bit subprime (group 24)")); 1491 case IKE_GRP_DESC_ECP_192: 1492 return (gettext("192-bit ECP (group 25)")); 1493 case IKE_GRP_DESC_ECP_224: 1494 return (gettext("224-bit ECP (group 26)")); 1495 default: 1496 (void) snprintf(rtn, MAXLINESIZE, gettext("<unknown %d>"), grp); 1497 return (rtn); 1498 } 1499 } 1500 1501 static void 1502 print_hdr(char *prefix, ike_p1_hdr_t *hdrp) 1503 { 1504 char sbuf[TBUF_SIZE]; 1505 char tbuf[TBUF_SIZE]; 1506 time_t ltime = (time_t)hdrp->p1hdr_dpd_time; 1507 1508 (void) printf( 1509 gettext("%s Cookies: Initiator 0x%llx Responder 0x%llx\n"), 1510 prefix, ntohll(hdrp->p1hdr_cookies.cky_i), 1511 ntohll(hdrp->p1hdr_cookies.cky_r)); 1512 (void) printf(gettext("%s The local host is the %s.\n"), prefix, 1513 hdrp->p1hdr_isinit ? gettext("initiator") : gettext("responder")); 1514 (void) printf(gettext("%s ISAKMP version %d.%d; %s exchange\n"), prefix, 1515 hdrp->p1hdr_major, hdrp->p1hdr_minor, xchgstr(hdrp->p1hdr_xchg)); 1516 (void) printf(gettext("%s Current state is %s\n"), prefix, 1517 statestr(hdrp->p1hdr_state)); 1518 if (hdrp->p1hdr_support_dpd == B_FALSE) { 1519 return; 1520 } 1521 (void) printf(gettext("%s Dead Peer Detection (RFC 3706)" 1522 " enabled"), prefix); 1523 if (hdrp->p1hdr_dpd_state < DPD_IN_PROGRESS) { 1524 (void) printf("\n"); 1525 return; 1526 } 1527 if (strftime(tbuf, TBUF_SIZE, NULL, 1528 localtime(<ime)) == 0) { 1529 (void) strlcpy(tbuf, gettext("<time conversion failed>"), 1530 TBUF_SIZE); 1531 } 1532 (void) printf(gettext("\n%s Dead Peer Detection handshake "), prefix); 1533 switch (hdrp->p1hdr_dpd_state) { 1534 case DPD_SUCCESSFUL: 1535 (void) strlcpy(sbuf, gettext("was successful at "), TBUF_SIZE); 1536 break; 1537 case DPD_FAILURE: 1538 (void) strlcpy(sbuf, gettext("failed at "), TBUF_SIZE); 1539 break; 1540 case DPD_IN_PROGRESS: 1541 (void) strlcpy(sbuf, gettext("is in progress."), TBUF_SIZE); 1542 break; 1543 } 1544 (void) printf("%s %s", sbuf, 1545 (hdrp->p1hdr_dpd_state == DPD_IN_PROGRESS) ? "" : tbuf); 1546 (void) printf("\n"); 1547 } 1548 1549 static void 1550 print_lt_limits(char *prefix, ike_p1_xform_t *xfp) 1551 { 1552 char byte_str[BYTE_STR_SIZE]; /* byte lifetime string representation */ 1553 char secs_str[SECS_STR_SIZE]; /* lifetime string representation */ 1554 1555 (void) printf(gettext("%s Lifetime limits:\n"), prefix); 1556 (void) printf(gettext("%s %u seconds%s; %u kbytes %sprotected\n"), 1557 prefix, xfp->p1xf_max_secs, secs2out(xfp->p1xf_max_secs, 1558 secs_str, sizeof (secs_str), SPC_BEGIN), xfp->p1xf_max_kbytes, 1559 bytecnt2out((uint64_t)xfp->p1xf_max_kbytes << 10, byte_str, 1560 sizeof (byte_str), SPC_END)); 1561 (void) printf(gettext("%s keying material for IPsec SAs can be " 1562 "provided %u times%s\n"), prefix, xfp->p1xf_max_keyuses, 1563 xfp->p1xf_max_keyuses == 0 ? " (no limit)" : ""); 1564 } 1565 1566 #define LT_USAGE_LEN 16 /* 1 uint64 + 2 uint32s */ 1567 static void 1568 print_lt_usage(char *prefix, ike_p1_stats_t *sp) 1569 { 1570 time_t scratch; 1571 char tbuf[TBUF_SIZE]; 1572 char bytestr[BYTE_STR_SIZE]; /* byte lifetime representation */ 1573 1574 (void) printf(gettext("%s Current usage:\n"), prefix); 1575 scratch = (time_t)sp->p1stat_start; 1576 if (strftime(tbuf, TBUF_SIZE, NULL, localtime(&scratch)) == 0) 1577 (void) strlcpy(tbuf, gettext("<time conversion failed>"), 1578 TBUF_SIZE); 1579 (void) printf(gettext("%s SA was created at %s\n"), prefix, tbuf); 1580 (void) printf(gettext("%s %u kbytes %sprotected\n"), 1581 prefix, sp->p1stat_kbytes, 1582 bytecnt2out((uint64_t)sp->p1stat_kbytes << 10, bytestr, 1583 sizeof (bytestr), SPC_END)); 1584 (void) printf(gettext("%s keying material for IPsec SAs provided " 1585 "%u times\n"), prefix, sp->p1stat_keyuses); 1586 } 1587 1588 static void 1589 print_xform(char *prefix, ike_p1_xform_t *xfp, boolean_t print_lifetimes) 1590 { 1591 (void) printf(gettext("%s Authentication method: %s"), prefix, 1592 authmethstr(xfp->p1xf_auth_meth)); 1593 (void) printf(gettext("\n%s Encryption alg: "), prefix); 1594 (void) dump_ealg(xfp->p1xf_encr_alg, stdout); 1595 if (xfp->p1xf_encr_low_bits != 0) { 1596 (void) printf(gettext("(%d..%d)"), xfp->p1xf_encr_low_bits, 1597 xfp->p1xf_encr_high_bits); 1598 } else if ((xfp->p1xf_encr_low_bits == 0) && 1599 (xfp->p1xf_encr_high_bits != 0)) { 1600 /* 1601 * High bits is a placeholder for 1602 * negotiated algorithm strength 1603 */ 1604 (void) printf(gettext("(%d)"), xfp->p1xf_encr_high_bits); 1605 } 1606 (void) printf(gettext("; Authentication alg: ")); 1607 (void) dump_aalg(xfp->p1xf_auth_alg, stdout); 1608 (void) printf("\n%s ", prefix); 1609 if (xfp->p1xf_prf != 0) 1610 (void) printf(gettext("PRF: %s ; "), prfstr(xfp->p1xf_prf)); 1611 (void) printf(gettext("Oakley Group: %s\n"), 1612 dhstr(xfp->p1xf_dh_group)); 1613 if (xfp->p1xf_pfs == 0) { 1614 (void) printf(gettext("%s Phase 2 PFS is not used\n"), prefix); 1615 } else { 1616 (void) printf(gettext( 1617 "%s Phase 2 PFS is required (Oakley Group: %s)\n"), 1618 prefix, dhstr(xfp->p1xf_pfs)); 1619 } 1620 1621 if (print_lifetimes) 1622 print_lt_limits(prefix, xfp); 1623 } 1624 1625 static void 1626 print_lifetime(char *prefix, ike_p1_xform_t *xfp, ike_p1_stats_t *sp, 1627 int statlen) 1628 { 1629 time_t current, remain, exp; 1630 char tbuf[TBUF_SIZE]; 1631 char byte_str[BYTE_STR_SIZE]; /* byte lifetime representation */ 1632 char secs_str[SECS_STR_SIZE]; /* seconds lifetime representation */ 1633 1634 current = time(NULL); 1635 1636 print_lt_limits(prefix, xfp); 1637 1638 /* 1639 * make sure the stats struct we've been passed is as big 1640 * as we expect it to be. The usage stats are at the end, 1641 * so anything less than the size we expect won't work. 1642 */ 1643 if (statlen >= sizeof (ike_p1_stats_t)) { 1644 print_lt_usage(prefix, sp); 1645 } else { 1646 return; 1647 } 1648 1649 (void) printf(gettext("%s Expiration info:\n"), prefix); 1650 1651 if (xfp->p1xf_max_kbytes != 0) 1652 (void) printf(gettext("%s %u more bytes %scan be " 1653 "protected.\n"), 1654 prefix, xfp->p1xf_max_kbytes - sp->p1stat_kbytes, 1655 bytecnt2out((uint64_t)(xfp->p1xf_max_kbytes - 1656 sp->p1stat_kbytes) << 10, byte_str, sizeof (byte_str), 1657 SPC_END)); 1658 1659 if (xfp->p1xf_max_keyuses != 0) 1660 (void) printf(gettext("%s Keying material can be provided " 1661 "%u more times.\n"), prefix, 1662 xfp->p1xf_max_keyuses - sp->p1stat_keyuses); 1663 1664 if (xfp->p1xf_max_secs != 0) { 1665 exp = (time_t)sp->p1stat_start + (time_t)xfp->p1xf_max_secs; 1666 remain = exp - current; 1667 if (strftime(tbuf, TBUF_SIZE, NULL, localtime(&exp)) == 0) 1668 (void) strlcpy(tbuf, 1669 gettext("<time conversion failed>"), TBUF_SIZE); 1670 /* 1671 * The SA may have expired but still exist because libike 1672 * has not freed it yet. 1673 */ 1674 if (remain > 0) { 1675 (void) printf(gettext( 1676 "%s SA expires in %lu seconds%s\n"), 1677 prefix, remain, secs2out(remain, secs_str, 1678 sizeof (secs_str), SPC_BEGIN)); 1679 (void) printf(gettext("%s Time of expiration: %s\n"), 1680 prefix, tbuf); 1681 } else { 1682 (void) printf(gettext("%s SA Expired at %s\n"), 1683 prefix, tbuf); 1684 } 1685 } 1686 } 1687 1688 /* used to verify structure lengths... */ 1689 #define COUNTER_32BIT 4 1690 #define COUNTER_PAIR 8 1691 1692 static void 1693 print_p1stats(char *prefix, ike_p1_stats_t *sp, int statlen, 1694 boolean_t print_lifetimes) 1695 { 1696 if (statlen < COUNTER_PAIR) 1697 return; 1698 (void) printf(gettext("%s %u Quick Mode SAs created; "), prefix, 1699 sp->p1stat_new_qm_sas); 1700 (void) printf(gettext("%u Quick Mode SAs deleted\n"), 1701 sp->p1stat_del_qm_sas); 1702 statlen -= COUNTER_PAIR; 1703 1704 if ((print_lifetimes) && (statlen >= LT_USAGE_LEN)) 1705 print_lt_usage(prefix, sp); 1706 } 1707 1708 static void 1709 print_errs(char *prefix, ike_p1_errors_t *errp, int errlen) 1710 { 1711 /* 1712 * Don't try to break this one up; it's either all or nothing! 1713 */ 1714 if (errlen < sizeof (ike_p1_errors_t)) 1715 return; 1716 1717 (void) printf(gettext("%s %u RX errors: "), prefix, 1718 errp->p1err_decrypt + errp->p1err_hash + errp->p1err_otherrx); 1719 (void) printf(gettext("%u decryption, %u hash, %u other\n"), 1720 errp->p1err_decrypt, errp->p1err_hash, errp->p1err_otherrx); 1721 (void) printf(gettext("%s %u TX errors\n"), prefix, errp->p1err_tx); 1722 } 1723 1724 static void 1725 print_addr_range(char *prefix, ike_addr_pr_t *pr) 1726 { 1727 boolean_t range = B_TRUE; 1728 struct sockaddr_storage *beg, *end; 1729 struct sockaddr_in *bsin, *esin; 1730 struct sockaddr_in6 *bsin6, *esin6; 1731 1732 beg = &pr->beg_iprange; 1733 end = &pr->end_iprange; 1734 1735 if (beg->ss_family != end->ss_family) { 1736 (void) printf(gettext("%s invalid address range\n"), prefix); 1737 return; 1738 } 1739 1740 switch (beg->ss_family) { 1741 case AF_INET: 1742 bsin = (struct sockaddr_in *)beg; 1743 esin = (struct sockaddr_in *)end; 1744 if ((uint32_t)bsin->sin_addr.s_addr == 1745 (uint32_t)esin->sin_addr.s_addr) 1746 range = B_FALSE; 1747 break; 1748 case AF_INET6: 1749 bsin6 = (struct sockaddr_in6 *)beg; 1750 esin6 = (struct sockaddr_in6 *)end; 1751 if (IN6_ARE_ADDR_EQUAL(&bsin6->sin6_addr, &esin6->sin6_addr)) 1752 range = B_FALSE; 1753 break; 1754 default: 1755 (void) printf(gettext("%s invalid address range\n"), prefix); 1756 return; 1757 } 1758 1759 (void) printf("%s ", prefix); 1760 (void) dump_sockaddr((struct sockaddr *)beg, 0, B_TRUE, stdout, nflag); 1761 if (range) { 1762 (void) printf(" - "); 1763 (void) dump_sockaddr((struct sockaddr *)end, 0, B_TRUE, stdout, 1764 nflag); 1765 } 1766 (void) printf("\n"); 1767 1768 } 1769 1770 /* 1771 * used to tell printing function if info should be identified 1772 * as belonging to initiator, responder, or neither 1773 */ 1774 #define IS_INITIATOR 1 1775 #define IS_RESPONDER 2 1776 #define DONT_PRINT_INIT 3 1777 1778 static void 1779 print_addr(char *prefix, struct sockaddr_storage *sa, int init_instr, 1780 int mask) 1781 { 1782 (void) printf(gettext("%s Address"), prefix); 1783 1784 if (init_instr != DONT_PRINT_INIT) 1785 (void) printf(" (%s):\n", (init_instr == IS_INITIATOR) ? 1786 gettext("Initiator") : gettext("Responder")); 1787 else 1788 (void) printf(":\n"); 1789 1790 (void) printf("%s ", prefix); 1791 (void) dump_sockaddr((struct sockaddr *)sa, mask, B_FALSE, stdout, 1792 nflag); 1793 } 1794 1795 static void 1796 print_id(char *prefix, sadb_ident_t *idp, int init_instr) 1797 { 1798 boolean_t canprint; 1799 1800 switch (init_instr) { 1801 case IS_INITIATOR: 1802 (void) printf(gettext("%s Initiator identity, "), prefix); 1803 break; 1804 case IS_RESPONDER: 1805 (void) printf(gettext("%s Responder identity, "), prefix); 1806 break; 1807 case DONT_PRINT_INIT: 1808 (void) printf(gettext("%s Identity, "), prefix); 1809 break; 1810 default: 1811 (void) printf(gettext("<invalid identity>\n")); 1812 return; 1813 } 1814 (void) printf(gettext("uid=%d, type "), idp->sadb_ident_id); 1815 canprint = dump_sadb_idtype(idp->sadb_ident_type, stdout, NULL); 1816 if (canprint) { 1817 (void) printf("\n%s %s\n", prefix, (char *)(idp + 1)); 1818 } else { 1819 (void) printf(gettext("\n%s "), prefix); 1820 print_asn1_name(stdout, 1821 (const unsigned char *)(idp + 1), 1822 SADB_64TO8(idp->sadb_ident_len) - sizeof (sadb_ident_t)); 1823 } 1824 } 1825 1826 static void 1827 print_idspec(char *prefix, char *idp, int icnt, int ecnt) 1828 { 1829 int i; 1830 1831 (void) printf(gettext("%s Identity descriptors:\n"), prefix); 1832 1833 for (i = 0; i < icnt; i++) { 1834 if (i == 0) 1835 (void) printf(gettext("%s Includes:\n"), prefix); 1836 (void) printf("%s %s\n", prefix, idp); 1837 idp += strlen(idp) + 1; 1838 } 1839 1840 for (i = 0; i < ecnt; i++) { 1841 if (i == 0) 1842 (void) printf(gettext("%s Excludes:\n"), prefix); 1843 (void) printf("%s %s\n", prefix, idp); 1844 idp += strlen(idp) + 1; 1845 } 1846 } 1847 1848 static void 1849 print_keys(char *prefix, ike_p1_key_t *keyp, int size) 1850 { 1851 uint32_t *curp; 1852 ike_p1_key_t *p; 1853 int ssize; 1854 1855 curp = (uint32_t *)keyp; 1856 1857 ssize = sizeof (ike_p1_key_t); 1858 1859 while ((intptr_t)curp - (intptr_t)keyp < size) { 1860 size_t p1klen, len; 1861 1862 p = (ike_p1_key_t *)curp; 1863 p1klen = p->p1key_len; 1864 len = p1klen - ssize; 1865 1866 p1klen = roundup(p1klen, sizeof (ike_p1_key_t)); 1867 if (p1klen < ssize) { 1868 (void) printf(gettext("Short key\n")); 1869 break; 1870 } 1871 1872 switch (p->p1key_type) { 1873 case IKE_KEY_PRESHARED: 1874 (void) printf(gettext("%s Pre-shared key (%d bytes): "), 1875 prefix, len); 1876 break; 1877 case IKE_KEY_SKEYID: 1878 (void) printf(gettext("%s SKEYID (%d bytes): "), 1879 prefix, len); 1880 break; 1881 case IKE_KEY_SKEYID_D: 1882 (void) printf(gettext("%s SKEYID_d (%d bytes): "), 1883 prefix, len); 1884 break; 1885 case IKE_KEY_SKEYID_A: 1886 (void) printf(gettext("%s SKEYID_a (%d bytes): "), 1887 prefix, len); 1888 break; 1889 case IKE_KEY_SKEYID_E: 1890 (void) printf(gettext("%s SKEYID_e (%d bytes): "), 1891 prefix, len); 1892 break; 1893 case IKE_KEY_ENCR: 1894 (void) printf(gettext("%s Encryption key (%d bytes): "), 1895 prefix, len); 1896 break; 1897 case IKE_KEY_IV: 1898 (void) printf( 1899 gettext("%s Initialization vector (%d bytes): "), 1900 prefix, len); 1901 break; 1902 default: 1903 (void) printf(gettext("%s Unidentified key info %p %d"), 1904 prefix, p, p1klen); 1905 goto badkey; 1906 } 1907 (void) dump_key((uint8_t *)(p + 1), SADB_8TO1(len), 0, 1908 stdout, B_FALSE); 1909 badkey: 1910 (void) printf("\n"); 1911 assert(IS_P2ALIGNED(p1klen, 8)); 1912 curp += (p1klen >> 2); 1913 } 1914 } 1915 1916 static void 1917 print_group_header(void) 1918 { 1919 (void) printf(gettext("\nList of Diffie-Hellman groups for setting " 1920 "up IKE SAs")); 1921 (void) printf(gettext("\nThe values match the IPsec attribute " 1922 "assigned numbers published by IANA\n\n")); 1923 (void) printf("%-6s%-9s%-50s\n", 1924 gettext("Value"), gettext("Strength"), gettext("Description")); 1925 } 1926 1927 static void 1928 print_group(ike_group_t *gp) 1929 { 1930 (void) printf("%-6u%-9u%-50s\n", 1931 gp->group_number, gp->group_bits, gp->group_label); 1932 } 1933 1934 static void 1935 print_encralg_header(void) 1936 { 1937 (void) printf(gettext("\nList of encryption algorithms for IKE")); 1938 (void) printf(gettext("\nThe values match the IPsec attribute " 1939 "assigned numbers published by IANA\n\n")); 1940 (void) printf("%-6s%-20s%-15s\n", gettext("Value"), 1941 gettext("Name"), gettext("Keylen range")); 1942 } 1943 1944 static void 1945 print_encralg(ike_encralg_t *ep) 1946 { 1947 char keylen_str[16]; 1948 1949 (void) strlcpy(keylen_str, "N/A", sizeof (keylen_str)); 1950 if (ep->encr_keylen_min != 0 || ep->encr_keylen_max != 0) 1951 (void) snprintf(keylen_str, sizeof (keylen_str), "%d-%d", 1952 ep->encr_keylen_min, ep->encr_keylen_max); 1953 (void) printf("%-6u%-20s%-15s\n", 1954 ep->encr_value, ep->encr_name, keylen_str); 1955 } 1956 1957 static void 1958 print_authalg_header(void) 1959 { 1960 (void) printf(gettext("\nList of authentication algorithms for IKE")); 1961 (void) printf(gettext("\nThe values match the IPsec attribute " 1962 "assigned numbers published by IANA\n\n")); 1963 (void) printf("%-6s%-20s\n", gettext("Value"), gettext("Name")); 1964 } 1965 1966 static void 1967 print_authalg(ike_authalg_t *ap) 1968 { 1969 (void) printf("%-6u%-20s\n", 1970 ap->auth_value, ap->auth_name); 1971 } 1972 1973 static void 1974 print_p1(ike_p1_sa_t *p1) 1975 { 1976 ike_p1_stats_t *sp; 1977 ike_p1_errors_t *ep; 1978 ike_p1_key_t *kp; 1979 sadb_ident_t *lidp, *ridp; 1980 int lstat, rstat; 1981 1982 (void) printf("\n"); 1983 print_hdr("IKESA:", &p1->p1sa_hdr); 1984 print_xform("XFORM:", &p1->p1sa_xform, B_FALSE); 1985 1986 if (p1->p1sa_hdr.p1hdr_isinit) { 1987 lstat = IS_INITIATOR; 1988 rstat = IS_RESPONDER; 1989 } else { 1990 lstat = IS_RESPONDER; 1991 rstat = IS_INITIATOR; 1992 } 1993 print_addr("LOCIP:", &p1->p1sa_ipaddrs.loc_addr, lstat, 0); 1994 print_addr("REMIP:", &p1->p1sa_ipaddrs.rem_addr, rstat, 0); 1995 1996 /* 1997 * the stat len might be 0; but still make the call 1998 * to print_lifetime() to pick up the xform info 1999 */ 2000 sp = (ike_p1_stats_t *)((int)(p1) + p1->p1sa_stat_off); 2001 print_lifetime("LIFTM:", &p1->p1sa_xform, sp, p1->p1sa_stat_len); 2002 2003 if (p1->p1sa_stat_len > 0) { 2004 print_p1stats("STATS:", sp, p1->p1sa_stat_len, B_FALSE); 2005 } 2006 2007 if (p1->p1sa_error_len > 0) { 2008 ep = (ike_p1_errors_t *)((int)(p1) + p1->p1sa_error_off); 2009 print_errs("ERRS: ", ep, p1->p1sa_error_len); 2010 } 2011 2012 if (p1->p1sa_localid_len > 0) { 2013 lidp = (sadb_ident_t *)((int)(p1) + p1->p1sa_localid_off); 2014 print_id("LOCID:", lidp, lstat); 2015 } 2016 2017 if (p1->p1sa_remoteid_len > 0) { 2018 ridp = (sadb_ident_t *)((int)(p1) + p1->p1sa_remoteid_off); 2019 print_id("REMID:", ridp, rstat); 2020 } 2021 2022 if (p1->p1sa_key_len > 0) { 2023 kp = (ike_p1_key_t *)((int)(p1) + p1->p1sa_key_off); 2024 print_keys("KEY: ", kp, p1->p1sa_key_len); 2025 } 2026 } 2027 2028 static void 2029 print_certcache(ike_certcache_t *c) 2030 { 2031 (void) printf("\n"); 2032 2033 (void) printf(gettext("CERTIFICATE CACHE ID: %d\n"), c->cache_id); 2034 (void) printf(gettext("\tSubject Name: <%s>\n"), 2035 (c->subject != NULL) ? c->subject : gettext("Name unavailable")); 2036 (void) printf(gettext("\t Issuer Name: <%s>\n"), 2037 (c->issuer != NULL) ? c->issuer : gettext("Name unavailable")); 2038 if ((int)c->certclass == -1) 2039 (void) printf(gettext("\t\t[trusted certificate]\n")); 2040 switch (c->linkage) { 2041 case CERT_OFF_WIRE: 2042 (void) printf(gettext("\t\t[Public certificate only]\n")); 2043 (void) printf(gettext( 2044 "\t\t[Obtained via certificate payload]\n")); 2045 break; 2046 case CERT_NO_PRIVKEY: 2047 (void) printf(gettext("\t\t[Public certificate only]\n")); 2048 break; 2049 case CERT_PRIVKEY_LOCKED: 2050 (void) printf(gettext( 2051 "\t\t[Private key linked but locked]\n")); 2052 break; 2053 case CERT_PRIVKEY_AVAIL: 2054 (void) printf(gettext("\t\t[Private key available]\n")); 2055 break; 2056 } 2057 } 2058 2059 static void 2060 print_ps(ike_ps_t *ps) 2061 { 2062 sadb_ident_t *lidp, *ridp; 2063 uint8_t *keyp; 2064 2065 (void) printf("\n"); 2066 2067 (void) printf(gettext("PSKEY: For %s exchanges\n"), 2068 xchgstr(ps->ps_ike_mode)); 2069 2070 if (ps->ps_key_len > 0) { 2071 keyp = (uint8_t *)((int)(ps) + ps->ps_key_off); 2072 (void) printf(gettext("PSKEY: Pre-shared key (%d bytes): "), 2073 ps->ps_key_len); 2074 (void) dump_key(keyp, ps->ps_key_bits, 0, stdout, B_FALSE); 2075 (void) printf("\n"); 2076 } 2077 2078 /* 2079 * We get *either* and address or an ident, never both. So if 2080 * the ident is there, don't try printing an address. 2081 */ 2082 if (ps->ps_localid_len > 0) { 2083 lidp = (sadb_ident_t *) 2084 ((int)(ps) + ps->ps_localid_off); 2085 print_id("LOCID:", lidp, DONT_PRINT_INIT); 2086 } else { 2087 print_addr("LOCIP:", &ps->ps_ipaddrs.loc_addr, DONT_PRINT_INIT, 2088 ps->ps_localid_plen > 0 ? ps->ps_localid_plen : 0); 2089 } 2090 2091 if (ps->ps_remoteid_len > 0) { 2092 ridp = (sadb_ident_t *) 2093 ((int)(ps) + ps->ps_remoteid_off); 2094 print_id("REMID:", ridp, DONT_PRINT_INIT); 2095 } else { 2096 print_addr("REMIP:", &ps->ps_ipaddrs.rem_addr, DONT_PRINT_INIT, 2097 ps->ps_remoteid_plen > 0 ? ps->ps_remoteid_plen : 0); 2098 } 2099 } 2100 2101 #define PREFIXLEN 16 2102 2103 static void 2104 print_rule(ike_rule_t *rp) 2105 { 2106 char prefix[PREFIXLEN]; 2107 int i; 2108 ike_p1_xform_t *xfp; 2109 ike_addr_pr_t *lipp, *ripp; 2110 char *lidp, *ridp; 2111 char byte_str[BYTE_STR_SIZE]; /* kbyte string representation */ 2112 char secs_str[SECS_STR_SIZE]; /* seconds string representation */ 2113 2114 (void) printf("\n"); 2115 (void) printf(gettext("GLOBL: Label '%s', key manager cookie %u\n"), 2116 rp->rule_label, rp->rule_kmcookie); 2117 (void) printf(gettext("GLOBL: local_idtype=")); 2118 (void) dump_sadb_idtype(rp->rule_local_idtype, stdout, NULL); 2119 (void) printf(gettext(", ike_mode=%s\n"), xchgstr(rp->rule_ike_mode)); 2120 (void) printf(gettext( 2121 "GLOBL: p1_nonce_len=%u, p2_nonce_len=%u, p2_pfs=%s (group %u)\n"), 2122 rp->rule_p1_nonce_len, rp->rule_p2_nonce_len, 2123 (rp->rule_p2_pfs) ? gettext("true") : gettext("false"), 2124 rp->rule_p2_pfs); 2125 (void) printf( 2126 gettext("GLOBL: p2_lifetime=%u seconds%s\n"), 2127 rp->rule_p2_lifetime_secs, secs2out(rp->rule_p2_lifetime_secs, 2128 secs_str, sizeof (secs_str), SPC_BEGIN)); 2129 (void) printf( 2130 gettext("GLOBL: p2_softlife=%u seconds%s\n"), 2131 rp->rule_p2_softlife_secs, secs2out(rp->rule_p2_softlife_secs, 2132 secs_str, sizeof (secs_str), SPC_BEGIN)); 2133 (void) printf( 2134 gettext("GLOBL: p2_idletime=%u seconds%s\n"), 2135 rp->rule_p2_idletime_secs, secs2out(rp->rule_p2_idletime_secs, 2136 secs_str, sizeof (secs_str), SPC_BEGIN)); 2137 /* 2138 * Perform explicit conversion before passing to bytecnt2out() 2139 * to avoid integer overflow. 2140 */ 2141 (void) printf( 2142 gettext("GLOBL: p2_lifetime_kb=%u kilobytes%s\n"), 2143 rp->rule_p2_lifetime_kb, 2144 bytecnt2out((uint64_t)(rp->rule_p2_lifetime_kb) << 10, 2145 byte_str, sizeof (byte_str), SPC_BEGIN)); 2146 (void) printf( 2147 gettext("GLOBL: p2_softlife_kb=%u kilobytes%s\n"), 2148 rp->rule_p2_softlife_kb, 2149 bytecnt2out(((uint64_t)(rp->rule_p2_softlife_kb)) << 10, 2150 byte_str, sizeof (byte_str), SPC_BEGIN)); 2151 2152 if (rp->rule_locip_cnt > 0) { 2153 (void) printf(gettext("LOCIP: IP address range(s):\n")); 2154 lipp = (ike_addr_pr_t *)((int)rp + rp->rule_locip_off); 2155 for (i = 0; i < rp->rule_locip_cnt; i++, lipp++) { 2156 print_addr_range("LOCIP:", lipp); 2157 } 2158 } 2159 2160 if (rp->rule_remip_cnt > 0) { 2161 (void) printf(gettext("REMIP: IP address range(s):\n")); 2162 ripp = (ike_addr_pr_t *)((int)rp + rp->rule_remip_off); 2163 for (i = 0; i < rp->rule_remip_cnt; i++, ripp++) { 2164 print_addr_range("REMIP:", ripp); 2165 } 2166 } 2167 2168 if (rp->rule_locid_inclcnt + rp->rule_locid_exclcnt > 0) { 2169 lidp = (char *)((int)rp + rp->rule_locid_off); 2170 print_idspec("LOCID:", lidp, rp->rule_locid_inclcnt, 2171 rp->rule_locid_exclcnt); 2172 } 2173 2174 if (rp->rule_remid_inclcnt + rp->rule_remid_exclcnt > 0) { 2175 ridp = (char *)((int)rp + rp->rule_remid_off); 2176 print_idspec("REMID:", ridp, rp->rule_remid_inclcnt, 2177 rp->rule_remid_exclcnt); 2178 } 2179 2180 if (rp->rule_xform_cnt > 0) { 2181 (void) printf(gettext("XFRMS: Available Transforms:\n")); 2182 xfp = (ike_p1_xform_t *)((int)rp + rp->rule_xform_off); 2183 for (i = 0; i < rp->rule_xform_cnt; i++, xfp++) { 2184 (void) snprintf(prefix, PREFIXLEN, "XF %2u:", i); 2185 print_xform(prefix, xfp, B_TRUE); 2186 } 2187 } 2188 } 2189 2190 #undef PREFIXLEN 2191 2192 #define PRSACNTS(init, resp) \ 2193 (void) printf(gettext("initiator: %10u responder: %10u\n"), \ 2194 (init), (resp)) 2195 2196 static void 2197 print_stats(ike_stats_t *sp, int len) 2198 { 2199 /* 2200 * before printing each line, make sure the structure we were 2201 * given is big enough to include the fields needed. 2202 */ 2203 if (len < COUNTER_PAIR) 2204 return; 2205 (void) printf(gettext("Phase 1 SA counts:\n")); 2206 (void) printf(gettext("Current: ")); 2207 PRSACNTS(sp->st_init_p1_current, sp->st_resp_p1_current); 2208 len -= COUNTER_PAIR; 2209 2210 if (len < COUNTER_PAIR) 2211 return; 2212 (void) printf(gettext("Total: ")); 2213 PRSACNTS(sp->st_init_p1_total, sp->st_resp_p1_total); 2214 len -= COUNTER_PAIR; 2215 2216 if (len < COUNTER_PAIR) 2217 return; 2218 (void) printf(gettext("Attempted: ")); 2219 PRSACNTS(sp->st_init_p1_attempts, sp->st_resp_p1_attempts); 2220 len -= COUNTER_PAIR; 2221 2222 if (len < (COUNTER_PAIR + COUNTER_32BIT)) 2223 return; 2224 (void) printf(gettext("Failed: ")); 2225 PRSACNTS(sp->st_init_p1_noresp + sp->st_init_p1_respfail, 2226 sp->st_resp_p1_fail); 2227 (void) printf( 2228 gettext(" initiator fails include %u time-out(s)\n"), 2229 sp->st_init_p1_noresp); 2230 2231 if (len < PATH_MAX) 2232 return; 2233 if (*(sp->st_pkcs11_libname) != '\0') 2234 (void) printf(gettext("PKCS#11 library linked in from %s\n"), 2235 sp->st_pkcs11_libname); 2236 } 2237 2238 /* Print one line of 'get defaults' output (i.e. single value). */ 2239 static void 2240 print_defaults(char *label, char *description, char *unit, 2241 uint_t current, uint_t def) 2242 { 2243 (void) printf("%-18s%-10s%11u %-10s%-26s\n", label, 2244 (current != def) ? gettext("config") : gettext("default"), 2245 current, unit, description); 2246 } 2247 2248 /* 2249 * Print out defaults used by in.iked, the argument is a buffer containing 2250 * two ike_defaults_t's, the first contains the hard coded defaults, the second 2251 * contains the actual values used. If these differ, then the defaults have been 2252 * changed via a config file entry. Note that "-" indicates this default 2253 * is not tunable via ike.config(4) or is system wide tunable. 2254 */ 2255 static void 2256 do_print_defaults(ike_defaults_t *dp) 2257 { 2258 ike_defaults_t *ddp; 2259 ddp = (ike_defaults_t *)(dp + 1); 2260 2261 (void) printf(gettext("\nGlobal defaults. Some values can be" 2262 " over-ridden on a per rule basis.\n")); 2263 (void) printf(gettext("\nSystem defaults are time delayed.\n\n")); 2264 2265 (void) printf("%-18s%-10s%-12s%-10s%-26s\n\n", 2266 gettext("Token:"), gettext("Source:"), gettext("Value:"), 2267 gettext("Unit:"), gettext("Description:")); 2268 2269 /* iked tunables */ 2270 print_defaults("p1_lifetime_secs", gettext("phase 1 lifetime"), 2271 gettext("seconds"), ddp->rule_p1_lifetime_secs, 2272 dp->rule_p1_lifetime_secs); 2273 2274 print_defaults("-", gettext("minimum phase 1 lifetime"), 2275 gettext("seconds"), ddp->rule_p1_minlife, 2276 dp->rule_p1_minlife); 2277 2278 print_defaults("p1_nonce_len", gettext("phase 1 nonce length"), 2279 gettext("bytes"), ddp->rule_p1_nonce_len, 2280 dp->rule_p1_nonce_len); 2281 2282 print_defaults("p2_lifetime_secs", gettext("phase 2 lifetime"), 2283 gettext("seconds"), ddp->rule_p2_lifetime_secs, 2284 dp->rule_p2_lifetime_secs); 2285 2286 print_defaults("p2_softlife_secs", gettext("phase 2 soft lifetime"), 2287 gettext("seconds"), ddp->rule_p2_softlife_secs, 2288 dp->rule_p2_softlife_secs); 2289 2290 print_defaults("p2_idletime_secs", gettext("phase 2 idle time"), 2291 gettext("seconds"), ddp->rule_p2_idletime_secs, 2292 dp->rule_p2_idletime_secs); 2293 2294 print_defaults("p2_lifetime_kb", gettext("phase 2 lifetime"), 2295 gettext("kilobytes"), ddp->rule_p2_lifetime_kb, 2296 dp->rule_p2_lifetime_kb); 2297 2298 print_defaults("p2_softlife_kb", gettext("phase 2 soft lifetime"), 2299 gettext("kilobytes"), ddp->rule_p2_softlife_kb, 2300 dp->rule_p2_softlife_kb); 2301 2302 /* system wide tunables */ 2303 print_defaults("-", gettext("system phase 2 lifetime"), 2304 gettext("seconds"), ddp->sys_p2_lifetime_secs, 2305 dp->sys_p2_lifetime_secs); 2306 2307 print_defaults("-", gettext("system phase 2 soft lifetime"), 2308 gettext("seconds"), ddp->sys_p2_softlife_secs, 2309 dp->sys_p2_softlife_secs); 2310 2311 print_defaults("-", gettext("system phase 2 idle time"), 2312 gettext("seconds"), ddp->sys_p2_idletime_secs, 2313 dp->sys_p2_idletime_secs); 2314 2315 print_defaults("-", gettext("system phase 2 lifetime"), 2316 gettext("bytes"), ddp->sys_p2_lifetime_bytes, 2317 dp->sys_p2_lifetime_bytes); 2318 2319 print_defaults("-", gettext("system phase 2 soft lifetime"), 2320 gettext("bytes"), ddp->sys_p2_softlife_bytes, 2321 dp->sys_p2_softlife_bytes); 2322 2323 /* minimum and maximum values */ 2324 print_defaults("-", gettext("minimum phase 2 hard lifetime"), 2325 gettext("seconds"), ddp->rule_p2_minlife_hard_secs, 2326 dp->rule_p2_minlife_hard_secs); 2327 2328 print_defaults("-", gettext("minimum phase 2 soft lifetime"), 2329 gettext("seconds"), ddp->rule_p2_minlife_soft_secs, 2330 dp->rule_p2_minlife_soft_secs); 2331 2332 print_defaults("-", gettext("minimum phase 2 idle lifetime"), 2333 gettext("seconds"), ddp->rule_p2_minlife_idle_secs, 2334 dp->rule_p2_minlife_idle_secs); 2335 2336 print_defaults("-", gettext("minimum phase 2 hard lifetime"), 2337 gettext("kilobytes"), ddp->rule_p2_minlife_hard_kb, 2338 dp->rule_p2_minlife_hard_kb); 2339 2340 print_defaults("-", gettext("minimum phase 2 soft lifetime"), 2341 gettext("kilobytes"), ddp->rule_p2_minlife_soft_kb, 2342 dp->rule_p2_minlife_soft_kb); 2343 2344 print_defaults("-", gettext("minimum phase 2 delta"), 2345 gettext("seconds"), ddp->rule_p2_mindiff_secs, 2346 dp->rule_p2_mindiff_secs); 2347 2348 print_defaults("-", gettext("minimum phase 2 delta"), 2349 gettext("kilobytes"), ddp->rule_p2_mindiff_kb, 2350 dp->rule_p2_mindiff_kb); 2351 2352 print_defaults("-", gettext("maximum phase 2 lifetime"), 2353 gettext("seconds"), ddp->rule_p2_maxlife_secs, 2354 dp->rule_p2_maxlife_secs); 2355 2356 print_defaults("-", gettext("conversion factor"), 2357 gettext("kbytes/s"), ddp->conversion_factor, 2358 dp->conversion_factor); 2359 2360 print_defaults("-", gettext("maximum phase 2 lifetime"), 2361 gettext("kilobytes"), ddp->rule_p2_maxlife_kb, 2362 dp->rule_p2_maxlife_kb); 2363 2364 /* other values */ 2365 print_defaults("p2_nonce_len", gettext("phase 2 nonce length"), 2366 gettext("bytes"), ddp->rule_p2_nonce_len, 2367 dp->rule_p2_nonce_len); 2368 2369 print_defaults("p2_pfs", gettext("phase 2 PFS"), 2370 " ", ddp->rule_p2_pfs, dp->rule_p2_pfs); 2371 2372 print_defaults("max_certs", gettext("max certificates"), 2373 " ", ddp->rule_max_certs, dp->rule_max_certs); 2374 2375 print_defaults("-", gettext("IKE port number"), 2376 " ", ddp->rule_ike_port, dp->rule_ike_port); 2377 2378 print_defaults("-", gettext("NAT-T port number"), 2379 " ", ddp->rule_natt_port, dp->rule_natt_port); 2380 } 2381 2382 static void 2383 print_categories(int level) 2384 { 2385 int mask; 2386 2387 if (level == 0) { 2388 (void) printf(gettext("No debug categories enabled.\n")); 2389 return; 2390 } 2391 2392 (void) printf(gettext("Debug categories enabled:")); 2393 for (mask = 1; mask <= D_HIGHBIT; mask <<= 1) { 2394 if (level & mask) 2395 (void) printf("\n\t%s", dbgstr(mask)); 2396 } 2397 (void) printf("\n"); 2398 } 2399 2400 /*PRINTFLIKE2*/ 2401 static void 2402 ikeadm_err_exit(ike_err_t *err, char *fmt, ...) 2403 { 2404 va_list ap; 2405 char bailbuf[BUFSIZ]; 2406 2407 va_start(ap, fmt); 2408 (void) vsnprintf(bailbuf, BUFSIZ, fmt, ap); 2409 va_end(ap); 2410 if ((err != NULL) && (err->ike_err == IKE_ERR_SYS_ERR)) { 2411 bail_msg("%s: %s", bailbuf, (err->ike_err_unix == 0) ? 2412 gettext("<unknown error>") : strerror(err->ike_err_unix)); 2413 } else { 2414 bail_msg("%s: %s", bailbuf, (err == NULL) ? 2415 gettext("<unknown error>") : errstr(err->ike_err)); 2416 } 2417 } 2418 2419 /*PRINTFLIKE2*/ 2420 static void 2421 ikeadm_err_msg(ike_err_t *err, char *fmt, ...) 2422 { 2423 va_list ap; 2424 char mbuf[BUFSIZ]; 2425 2426 va_start(ap, fmt); 2427 (void) vsnprintf(mbuf, BUFSIZ, fmt, ap); 2428 va_end(ap); 2429 if ((err != NULL) && (err->ike_err == IKE_ERR_SYS_ERR)) { 2430 message("%s: %s", mbuf, (err->ike_err_unix == 0) ? 2431 gettext("<unknown error>") : 2432 ((err->ike_err_unix == EEXIST) ? 2433 gettext("Duplicate entry") : 2434 strerror(err->ike_err_unix))); 2435 } else { 2436 message("%s: %s", mbuf, (err == NULL) ? 2437 gettext("<unknown error>") : errstr(err->ike_err)); 2438 } 2439 } 2440 2441 2442 /* 2443 * Command functions 2444 */ 2445 2446 /* 2447 * Exploit the fact that ike_dbg_t and ike_priv_t have identical 2448 * formats in the following two functions. 2449 */ 2450 static void 2451 do_getvar(int cmd) 2452 { 2453 ike_service_t req, *rtn; 2454 ike_dbg_t *dreq; 2455 char *varname; 2456 2457 switch (cmd) { 2458 case IKE_SVC_GET_DBG: 2459 varname = gettext("debug"); 2460 break; 2461 case IKE_SVC_GET_PRIV: 2462 varname = gettext("privilege"); 2463 break; 2464 default: 2465 bail_msg(gettext("unrecognized get command (%d)"), cmd); 2466 } 2467 2468 dreq = &req.svc_dbg; 2469 dreq->cmd = cmd; 2470 dreq->dbg_level = 0; 2471 2472 rtn = ikedoor_call((char *)&req, sizeof (ike_dbg_t), NULL, 0); 2473 2474 if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 2475 ikeadm_err_exit(&rtn->svc_err, 2476 gettext("error getting %s level"), varname); 2477 } 2478 dreq = &rtn->svc_dbg; 2479 (void) printf(gettext("Current %s level is 0x%x"), 2480 varname, dreq->dbg_level); 2481 2482 if (cmd == IKE_SVC_GET_DBG) { 2483 (void) printf("\n"); 2484 print_categories(dreq->dbg_level); 2485 } else { 2486 (void) printf(gettext(", %s enabled\n"), 2487 privstr(dreq->dbg_level)); 2488 } 2489 } 2490 2491 /* 2492 * Log into a token and unlock all objects 2493 * referenced by PKCS#11 hint files. 2494 */ 2495 static void 2496 do_setdel_pin(int cmd, int argc, char **argv) 2497 { 2498 ike_service_t req, *rtn; 2499 ike_pin_t *preq; 2500 char token_label[PKCS11_TOKSIZE]; 2501 char *token_pin; 2502 char prompt[80]; 2503 2504 if (argc < 1) 2505 Bail(gettext("Must specify PKCS#11 token object.")); 2506 2507 preq = &req.svc_pin; 2508 preq->cmd = cmd; 2509 2510 switch (cmd) { 2511 case IKE_SVC_SET_PIN: 2512 if (parse_token(argc, argv, token_label) != 0) 2513 Bail("Invalid syntax for \"token login\""); 2514 (void) snprintf(prompt, sizeof (prompt), 2515 "Enter PIN for PKCS#11 token \'%s\': ", token_label); 2516 token_pin = 2517 getpassphrase(prompt); 2518 (void) strlcpy((char *)preq->token_pin, token_pin, MAX_PIN_LEN); 2519 bzero(token_pin, strlen(token_pin)); 2520 break; 2521 case IKE_SVC_DEL_PIN: 2522 if (parse_token(argc, argv, token_label) != 0) 2523 Bail("Invalid syntax for \"token logout\""); 2524 break; 2525 default: 2526 bail_msg(gettext("unrecognized token command (%d)"), cmd); 2527 } 2528 2529 (void) strlcpy(preq->pkcs11_token, token_label, PKCS11_TOKSIZE); 2530 2531 rtn = ikedoor_call((char *)&req, sizeof (ike_pin_t), NULL, 0); 2532 if (cmd == IKE_SVC_SET_PIN) 2533 bzero(preq->token_pin, sizeof (preq->token_pin)); 2534 2535 if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 2536 ikeadm_err_exit(&rtn->svc_err, 2537 gettext("PKCS#11 operation")); 2538 } 2539 preq = &rtn->svc_pin; 2540 message(gettext("PKCS#11 operation successful")); 2541 } 2542 2543 static void 2544 do_setvar(int cmd, int argc, char **argv) 2545 { 2546 ike_service_t req, *rtn; 2547 ike_dbg_t *dreq; 2548 door_desc_t *descp = NULL, desc; 2549 int fd, ndesc = 0; 2550 uint32_t reqlevel; 2551 char *varname; 2552 2553 if (argc < 1) 2554 Bail("unspecified level"); 2555 reqlevel = strtoul(argv[0], NULL, 0); 2556 2557 switch (cmd) { 2558 case IKE_SVC_SET_DBG: 2559 if (argc > 2) 2560 Bail("Too many arguments to \"set debug\""); 2561 varname = gettext("debug"); 2562 if (reqlevel == 0) { 2563 /* check for a string... */ 2564 reqlevel = parsedbgopts(argv[0]); 2565 } 2566 if (reqlevel == D_INVALID) 2567 bail_msg(gettext("Bad debug flag: %s"), argv[0]); 2568 break; 2569 case IKE_SVC_SET_PRIV: 2570 if (argc > 1) 2571 Bail("Too many arguments to \"set priv\""); 2572 2573 varname = gettext("privilege"); 2574 if (reqlevel == 0) { 2575 /* check for a string... */ 2576 reqlevel = privstr2num(argv[0]); 2577 } 2578 if (reqlevel > IKE_PRIV_MAXIMUM) 2579 bail_msg(gettext("Bad privilege flag: %s"), argv[0]); 2580 break; 2581 default: 2582 bail_msg(gettext("unrecognized set command (%d)"), cmd); 2583 } 2584 2585 dreq = &req.svc_dbg; 2586 dreq->cmd = cmd; 2587 dreq->dbg_level = reqlevel; 2588 2589 if ((argc == 2) && (cmd == IKE_SVC_SET_DBG)) { 2590 fd = open(argv[1], O_RDWR | O_CREAT | O_APPEND, 2591 S_IRUSR | S_IWUSR); 2592 if (fd < 0) 2593 Bail("open debug file"); 2594 desc.d_data.d_desc.d_descriptor = fd; 2595 desc.d_attributes = DOOR_DESCRIPTOR; 2596 descp = &desc; 2597 ndesc = 1; 2598 } 2599 2600 rtn = ikedoor_call((char *)&req, sizeof (ike_dbg_t), descp, ndesc); 2601 2602 if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 2603 ikeadm_err_exit(&rtn->svc_err, 2604 gettext("error setting %s level"), varname); 2605 } 2606 dreq = &rtn->svc_dbg; 2607 (void) printf( 2608 gettext("Successfully changed %s level from 0x%x to 0x%x\n"), 2609 varname, dreq->dbg_level, reqlevel); 2610 2611 if (cmd == IKE_SVC_SET_DBG) { 2612 print_categories(reqlevel); 2613 } else { 2614 (void) printf(gettext("New privilege level 0x%x enables %s\n"), 2615 reqlevel, privstr(reqlevel)); 2616 } 2617 } 2618 2619 static void 2620 do_getstats(int cmd) 2621 { 2622 ike_service_t *rtn; 2623 ike_statreq_t sreq, *sreqp; 2624 ike_stats_t *sp; 2625 2626 sreq.cmd = cmd; 2627 2628 rtn = ikedoor_call((char *)&sreq, sizeof (ike_statreq_t), NULL, 0); 2629 if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 2630 ikeadm_err_exit(&rtn->svc_err, gettext("error getting stats")); 2631 } 2632 2633 sreqp = &rtn->svc_stats; 2634 sp = (ike_stats_t *)(sreqp + 1); 2635 print_stats(sp, sreqp->stat_len); 2636 } 2637 2638 static void 2639 do_getdefs(int cmd) 2640 { 2641 ike_service_t *rtn; 2642 ike_defreq_t dreq, *dreqp; 2643 ike_defaults_t *dp; 2644 2645 dreq.cmd = cmd; 2646 2647 rtn = ikedoor_call((char *)&dreq, sizeof (ike_defreq_t), NULL, 0); 2648 if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 2649 ikeadm_err_exit(&rtn->svc_err, 2650 gettext("error getting defaults")); 2651 } 2652 2653 dreqp = &rtn->svc_defaults; 2654 dp = (ike_defaults_t *)(dreqp + 1); 2655 2656 /* 2657 * Before printing each line, make sure the structure we were 2658 * given is big enough to include the fields needed. 2659 * Silently bail out of there is a version mismatch. 2660 */ 2661 if (dreqp->stat_len < ((2 * sizeof (ike_defaults_t)) 2662 + sizeof (ike_defreq_t)) || dreqp->version != DOORVER) { 2663 return; 2664 } 2665 do_print_defaults(dp); 2666 } 2667 2668 static void 2669 do_dump(int cmd) 2670 { 2671 char *name; 2672 ike_service_t req, *rtn; 2673 ike_dump_t *dreq, *dump; 2674 2675 switch (cmd) { 2676 case IKE_SVC_DUMP_P1S: 2677 name = gettext("phase 1 SA info"); 2678 break; 2679 case IKE_SVC_DUMP_RULES: 2680 name = gettext("policy rules"); 2681 break; 2682 case IKE_SVC_DUMP_PS: 2683 name = gettext("preshared keys"); 2684 break; 2685 case IKE_SVC_DUMP_CERTCACHE: 2686 name = gettext("certcache"); 2687 break; 2688 case IKE_SVC_DUMP_GROUPS: 2689 name = gettext("groups"); 2690 print_group_header(); 2691 break; 2692 case IKE_SVC_DUMP_ENCRALGS: 2693 name = gettext("encralgs"); 2694 print_encralg_header(); 2695 break; 2696 case IKE_SVC_DUMP_AUTHALGS: 2697 name = gettext("authalgs"); 2698 print_authalg_header(); 2699 break; 2700 default: 2701 bail_msg(gettext("unrecognized dump command (%d)"), cmd); 2702 } 2703 2704 dreq = &req.svc_dump; 2705 dreq->cmd = cmd; 2706 dreq->dump_len = 0; 2707 dreq->dump_next = 0; 2708 do { 2709 rtn = ikedoor_call((char *)&req, sizeof (ike_dump_t), 2710 NULL, 0); 2711 if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 2712 if (rtn && (rtn->svc_err.ike_err == IKE_ERR_NO_OBJ)) { 2713 /* no entries to print */ 2714 break; 2715 } 2716 ikeadm_err_exit(&rtn->svc_err, 2717 gettext("error getting %s"), name); 2718 } 2719 dump = &rtn->svc_dump; 2720 2721 switch (cmd) { 2722 case IKE_SVC_DUMP_P1S: 2723 print_p1((ike_p1_sa_t *)(dump + 1)); 2724 break; 2725 case IKE_SVC_DUMP_RULES: 2726 print_rule((ike_rule_t *)(dump + 1)); 2727 break; 2728 case IKE_SVC_DUMP_PS: 2729 print_ps((ike_ps_t *)(dump + 1)); 2730 break; 2731 case IKE_SVC_DUMP_CERTCACHE: 2732 print_certcache((ike_certcache_t *)(dump + 1)); 2733 break; 2734 case IKE_SVC_DUMP_GROUPS: 2735 print_group((ike_group_t *)(dump + 1)); 2736 break; 2737 case IKE_SVC_DUMP_ENCRALGS: 2738 print_encralg((ike_encralg_t *)(dump + 1)); 2739 break; 2740 case IKE_SVC_DUMP_AUTHALGS: 2741 print_authalg((ike_authalg_t *)(dump + 1)); 2742 break; 2743 } 2744 2745 dreq->dump_next = dump->dump_next; 2746 2747 (void) munmap((char *)rtn, dump->dump_len); 2748 2749 } while (dreq->dump_next); 2750 2751 (void) printf(gettext("\nCompleted dump of %s\n"), name); 2752 } 2753 2754 static void 2755 do_getdel_doorcall(int cmd, int idlen, int idtype, char *idp, char *name) 2756 { 2757 int totallen; 2758 char *p; 2759 ike_service_t *reqp, *rtnp; 2760 ike_get_t *getp; 2761 boolean_t getcmd; 2762 2763 getcmd = ((cmd == IKE_SVC_GET_P1) || (cmd == IKE_SVC_GET_RULE) || 2764 (cmd == IKE_SVC_GET_PS)); 2765 2766 /* 2767 * WARNING: to avoid being redundant, this code takes advantage 2768 * of the fact that the ike_get_t and ike_del_t structures are 2769 * identical (only the field names differ, their function and 2770 * size are the same). If for some reason those structures 2771 * change, this code will need to be re-written to accomodate 2772 * that difference. 2773 */ 2774 totallen = sizeof (ike_get_t) + idlen; 2775 if ((reqp = (ike_service_t *)malloc(totallen)) == NULL) 2776 Bail("malloc(id)"); 2777 2778 getp = &reqp->svc_get; 2779 getp->cmd = cmd; 2780 getp->get_len = totallen; 2781 getp->get_idtype = idtype; 2782 p = (char *)(getp + 1); 2783 2784 (void) memcpy(p, idp, idlen); 2785 2786 rtnp = ikedoor_call((char *)reqp, totallen, NULL, 0); 2787 if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) { 2788 if (rtnp && (rtnp->svc_err.ike_err == IKE_ERR_NO_OBJ)) { 2789 message(gettext("Could not find requested %s."), name); 2790 } else { 2791 ikeadm_err_msg(&rtnp->svc_err, gettext("error %s %s"), 2792 (getcmd) ? gettext("getting") : gettext("deleting"), 2793 name); 2794 } 2795 free(reqp); 2796 return; 2797 } 2798 getp = &rtnp->svc_get; 2799 2800 if (getcmd) { 2801 switch (cmd) { 2802 case IKE_SVC_GET_P1: 2803 print_p1((ike_p1_sa_t *)(getp + 1)); 2804 break; 2805 case IKE_SVC_GET_PS: 2806 print_ps((ike_ps_t *)(getp + 1)); 2807 break; 2808 case IKE_SVC_GET_RULE: 2809 print_rule((ike_rule_t *)(getp + 1)); 2810 break; 2811 } 2812 } else { 2813 message(gettext("Successfully deleted selected %s."), name); 2814 } 2815 2816 (void) munmap((char *)rtnp, getp->get_len); 2817 free(reqp); 2818 } 2819 2820 static void 2821 do_getdel(int cmd, int argc, char **argv) 2822 { 2823 int idlen, idtype = 0, i, j; 2824 int bytelen1, bytelen2; 2825 char *name, *idp, *p, *p1, *p2; 2826 ike_addr_pr_t apr; 2827 ike_cky_pr_t cpr; 2828 sadb_ident_t *sid1p, *sid2p; 2829 struct hostent *he1p, *he2p; 2830 char label[MAX_LABEL_LEN]; 2831 2832 if ((argc < 1) || (argv[0] == NULL)) { 2833 Bail("not enough identification info"); 2834 } 2835 2836 switch (cmd) { 2837 case IKE_SVC_GET_P1: 2838 case IKE_SVC_DEL_P1: 2839 name = gettext("phase 1 SA"); 2840 /* 2841 * The first token must either be an address (or hostname) 2842 * or a cookie. We require cookies to be entered as hex 2843 * numbers, beginning with 0x; so if our token starts with 2844 * that, it's a cookie. 2845 */ 2846 if (strncmp(argv[0], "0x", 2) == 0) { 2847 if (parse_cky_pr(argc, argv, &cpr) >= 0) { 2848 idtype = IKE_ID_CKY_PAIR; 2849 idlen = sizeof (ike_cky_pr_t); 2850 idp = (char *)&cpr; 2851 } 2852 } else { 2853 if (parse_addr_pr(argc, argv, &he1p, &he2p) >= 0) { 2854 idtype = IKE_ID_ADDR_PAIR; 2855 idlen = sizeof (ike_addr_pr_t); 2856 } 2857 } 2858 break; 2859 2860 case IKE_SVC_GET_RULE: 2861 case IKE_SVC_DEL_RULE: 2862 name = gettext("policy rule"); 2863 if (parse_label(argc, argv, label) >= 0) { 2864 idtype = IKE_ID_LABEL; 2865 idlen = MAX_LABEL_LEN; 2866 idp = label; 2867 } 2868 break; 2869 2870 case IKE_SVC_GET_PS: 2871 case IKE_SVC_DEL_PS: 2872 name = gettext("preshared key"); 2873 /* 2874 * The first token must either be an address or an ident 2875 * type. Check for an ident type to determine which it is. 2876 */ 2877 if (parse_idtype(argv[0], NULL) >= 0) { 2878 if (parse_ident_pr(argc, argv, &sid1p, &sid2p) >= 0) { 2879 idtype = IKE_ID_IDENT_PAIR; 2880 idlen = SADB_64TO8(sid1p->sadb_ident_len) + 2881 SADB_64TO8(sid2p->sadb_ident_len); 2882 } 2883 } else { 2884 if (parse_addr_pr(argc, argv, &he1p, &he2p) >= 0) { 2885 idtype = IKE_ID_ADDR_PAIR; 2886 idlen = sizeof (ike_addr_pr_t); 2887 } 2888 } 2889 break; 2890 2891 default: 2892 bail_msg(gettext("unrecognized get/del command (%d)"), cmd); 2893 } 2894 2895 switch (idtype) { 2896 case IKE_ID_ADDR_PAIR: 2897 /* 2898 * we might have exploding addrs here; do every possible 2899 * combination. 2900 */ 2901 i = 0; 2902 j = 0; 2903 while ((p1 = he1p->h_addr_list[i++]) != NULL) { 2904 headdr2sa(p1, &apr.loc_addr, he1p->h_length); 2905 2906 while ((p2 = he2p->h_addr_list[j++]) != NULL) { 2907 headdr2sa(p2, &apr.rem_addr, he2p->h_length); 2908 do_getdel_doorcall(cmd, idlen, idtype, 2909 (char *)&apr, name); 2910 } 2911 } 2912 FREE_HE(he1p); 2913 FREE_HE(he2p); 2914 break; 2915 2916 case IKE_ID_IDENT_PAIR: 2917 bytelen1 = SADB_64TO8(sid1p->sadb_ident_len); 2918 bytelen2 = SADB_64TO8(sid2p->sadb_ident_len); 2919 if (idlen != bytelen1 + bytelen2) 2920 Bail("ident syntax error"); 2921 idp = p = (char *)malloc(idlen); 2922 if (p == NULL) 2923 Bail("malloc(id)"); 2924 (void) memcpy(p, (char *)sid1p, bytelen1); 2925 p += bytelen1; 2926 (void) memcpy(p, (char *)sid2p, bytelen2); 2927 do_getdel_doorcall(cmd, idlen, idtype, idp, name); 2928 free(idp); 2929 free(sid1p); 2930 free(sid2p); 2931 break; 2932 2933 case IKE_ID_CKY_PAIR: 2934 case IKE_ID_LABEL: 2935 do_getdel_doorcall(cmd, idlen, idtype, idp, name); 2936 break; 2937 2938 case 0: 2939 default: 2940 bail_msg(gettext("invalid %s identification\n"), name); 2941 } 2942 } 2943 2944 /* 2945 * Copy source into target, inserting an escape character ('\') before 2946 * any quotes that appear. Return true on success, false on failure. 2947 */ 2948 static boolean_t 2949 escapequotes(char *target, char *source, int tlen) 2950 { 2951 int s, t, len = strlen(source) + 1; 2952 2953 if (tlen < len) 2954 return (B_FALSE); 2955 2956 for (s = 0, t = 0; s < len && t < tlen; s++) { 2957 if (source[s] == '\"') 2958 target[t++] = '\\'; 2959 target[t++] = source[s]; 2960 } 2961 2962 if ((t == tlen) && (s < len)) 2963 return (B_FALSE); 2964 2965 return (B_TRUE); 2966 } 2967 2968 /* 2969 * Return true if the arg following the given keyword should 2970 * be in quotes (i.e. is a string), false if not. 2971 */ 2972 static boolean_t 2973 quotedfield(char *keywd) 2974 { 2975 if ((strncmp(keywd, "label", strlen("label") + 1) == 0) || 2976 (strncmp(keywd, "local_id", strlen("local_id") + 1) == 0) || 2977 (strncmp(keywd, "remote_id", strlen("remote_id") + 1) == 0)) 2978 return (B_TRUE); 2979 2980 return (B_FALSE); 2981 } 2982 2983 static void 2984 do_new(int cmd, int argc, char **argv) 2985 { 2986 ike_service_t *rtn; 2987 ike_new_t new, *newp = NULL; 2988 door_desc_t desc, *descp = NULL; 2989 int i, fd, ndesc = 0, buflen; 2990 char *name, tmpfilepath[32]; 2991 FILE *tmpfile; 2992 2993 switch (cmd) { 2994 case IKE_SVC_NEW_PS: 2995 name = gettext("preshared key"); 2996 break; 2997 case IKE_SVC_NEW_RULE: 2998 name = gettext("policy rule"); 2999 break; 3000 default: 3001 bail_msg(gettext("unrecognized new command (%d)"), cmd); 3002 } 3003 3004 if (argc == 1) { 3005 /* We've been given a file to read from */ 3006 fd = open(argv[0], O_RDONLY); 3007 if (fd < 0) 3008 Bail("open source file"); 3009 3010 desc.d_data.d_desc.d_descriptor = fd; 3011 desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE; 3012 descp = &desc; 3013 ndesc = 1; 3014 3015 new.cmd = cmd; 3016 new.new_len = 0; 3017 newp = &new; 3018 buflen = sizeof (ike_new_t); 3019 3020 } else if ((argc > 1) && (cmd == IKE_SVC_NEW_PS)) { 3021 /* 3022 * This is an alternative to using the tmpfile method 3023 * for preshared keys. It means we're duplicating the 3024 * parsing effort that happens in readps.c; but it 3025 * does avoid having the key sitting in a file. 3026 */ 3027 ike_ps_t *psp; 3028 int pslen; 3029 3030 /* 3031 * must be in interactive mode; don't want keys in 3032 * the process args. 3033 */ 3034 if (!interactive) 3035 Bail("Must be in interactive mode to add key info."); 3036 if (parse_ps(argc, argv, &psp, &pslen) < 0) { 3037 errno = 0; 3038 Bail("invalid preshared key definition"); 3039 } 3040 newp = malloc(sizeof (ike_new_t) + pslen); 3041 if (newp == NULL) 3042 Bail("alloc pskey"); 3043 newp->cmd = cmd; 3044 newp->new_len = sizeof (ike_new_t) + pslen; 3045 (void) memcpy((char *)(newp + 1), psp, pslen); 3046 buflen = newp->new_len; 3047 /* parse_ps allocated the ike_ps_t buffer; free it now */ 3048 free(psp); 3049 3050 } else if ((argc > 1) && (cmd == IKE_SVC_NEW_RULE)) { 3051 /* 3052 * We've been given the item in argv. However, parsing 3053 * rules can get more than a little messy, and in.iked 3054 * already has a great parser for this stuff! So don't 3055 * fool around with trying to do the parsing here. Just 3056 * write it out to a tempfile, and send the fd to in.iked. 3057 * 3058 * We could conceivably do this for preshared keys, 3059 * rather than duplicating the parsing effort; but that 3060 * would mean the key would be written out to a file, 3061 * which isn't such a good idea. 3062 */ 3063 boolean_t doquotes = B_FALSE; 3064 int rtn; 3065 3066 if ((argv[0][0] != '{') || 3067 (argv[argc - 1][strlen(argv[argc - 1]) - 1] != '}')) 3068 bail_msg(gettext("improperly formatted %s"), name); 3069 3070 /* attempt to use a fairly unpredictable file name... */ 3071 (void) sprintf(tmpfilepath, "/var/run/%x", (int)gethrtime()); 3072 fd = open(tmpfilepath, O_RDWR | O_CREAT | O_EXCL, 3073 S_IRUSR | S_IWUSR); 3074 if (fd < 0) 3075 Bail("cannot open tmpfile"); 3076 3077 /* and make it inaccessible asap */ 3078 if (unlink(tmpfilepath) < 0) { 3079 (void) close(fd); 3080 Bail("tmpfile error"); 3081 } 3082 3083 tmpfile = fdopen(fd, "w"); 3084 if (tmpfile == NULL) { 3085 (void) close(fd); 3086 Bail("cannot write to tmpfile"); 3087 } 3088 3089 for (i = 0; i < argc; i++) { 3090 /* 3091 * We have to do some gyrations with our string here, 3092 * to properly handle quotes. There are two issues: 3093 * - some of the fields of a rule may have embedded 3094 * whitespace, and thus must be quoted on the cmd 3095 * line. The shell removes the quotes, and gives 3096 * us a single argv string; but we need to put the 3097 * quotes back in when we write the string out to 3098 * file. The doquotes boolean is set when we 3099 * process a keyword which will be followed by a 3100 * string value (so the NEXT argv element will be 3101 * quoted). 3102 * - there might be a quote character in a field, 3103 * that was escaped on the cmdline. The shell 3104 * removes the escape char, and leaves the quote 3105 * in the string it gives us. We need to put the 3106 * escape char back in before writing to file. 3107 */ 3108 char field[MAXLINESIZE]; 3109 if (!escapequotes(field, argv[i], MAXLINESIZE)) 3110 Bail("write to tmpfile failed (arg too big)"); 3111 if (doquotes) { 3112 rtn = fprintf(tmpfile, "\"%s\"\n", field); 3113 doquotes = B_FALSE; 3114 } else { 3115 rtn = fprintf(tmpfile, "%s\n", field); 3116 } 3117 if (rtn < 0) 3118 Bail("write to tmpfile failed"); 3119 /* 3120 * check if this is a keyword identifying 3121 * a field that needs to be quoted. 3122 */ 3123 doquotes = quotedfield(argv[i]); 3124 } 3125 if (fflush(tmpfile) == EOF) 3126 Bail("write to tmpfile failed"); 3127 /* rewind so that the daemon will get the beginning */ 3128 rewind(tmpfile); 3129 3130 desc.d_data.d_desc.d_descriptor = fd; 3131 desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE; 3132 descp = &desc; 3133 ndesc = 1; 3134 3135 new.cmd = cmd; 3136 new.new_len = 0; 3137 newp = &new; 3138 buflen = sizeof (ike_new_t); 3139 3140 } else { 3141 /* not enough information! */ 3142 bail_msg(gettext("missing %s description or file name"), name); 3143 } 3144 3145 rtn = ikedoor_call((char *)newp, buflen, descp, ndesc); 3146 3147 if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 3148 ikeadm_err_msg(&rtn->svc_err, 3149 gettext("error creating new %s"), name); 3150 } else { 3151 message(gettext("Successfully created new %s."), name); 3152 } 3153 } 3154 3155 static void 3156 do_flush(int cmd) 3157 { 3158 ike_service_t *rtnp; 3159 ike_flush_t flush; 3160 3161 if (cmd != IKE_SVC_FLUSH_P1S && cmd != IKE_SVC_FLUSH_CERTCACHE) { 3162 bail_msg(gettext("unrecognized flush command (%d)."), cmd); 3163 } 3164 3165 flush.cmd = cmd; 3166 3167 rtnp = ikedoor_call((char *)&flush, sizeof (ike_flush_t), NULL, 0); 3168 if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) { 3169 ikeadm_err_exit(&rtnp->svc_err, gettext("error doing flush")); 3170 } 3171 if (cmd == IKE_SVC_FLUSH_P1S) 3172 message(gettext("Successfully flushed P1 SAs.")); 3173 else 3174 message(gettext("Successfully flushed cert cache.")); 3175 } 3176 3177 static void 3178 do_rw(int cmd, int argc, char **argv) 3179 { 3180 ike_service_t *rtnp; 3181 ike_rw_t rw; 3182 door_desc_t desc, *descp = NULL; 3183 int oflag, omode, fd, ndesc = 0; 3184 char *op, *obj = NULL; 3185 boolean_t writing = B_FALSE; 3186 3187 switch (cmd) { 3188 case IKE_SVC_READ_PS: 3189 obj = gettext("preshared key"); 3190 /* FALLTHRU */ 3191 case IKE_SVC_READ_RULES: 3192 if (obj == NULL) 3193 obj = gettext("policy rule"); 3194 op = gettext("read"); 3195 oflag = O_RDONLY; 3196 omode = 0; 3197 break; 3198 3199 case IKE_SVC_WRITE_PS: 3200 obj = gettext("preshared key"); 3201 /* FALLTHRU */ 3202 case IKE_SVC_WRITE_RULES: 3203 if (obj == NULL) 3204 obj = gettext("policy rule"); 3205 op = gettext("write"); 3206 oflag = O_RDWR | O_CREAT | O_EXCL; 3207 omode = S_IRUSR | S_IWUSR; 3208 3209 /* for write commands, dest location must be specified */ 3210 if (argc < 1) { 3211 bail_msg(gettext("destination location required " 3212 "to write %ss"), obj); 3213 } 3214 writing = B_TRUE; 3215 break; 3216 3217 default: 3218 bail_msg(gettext("unrecognized read/write command (%d)."), cmd); 3219 } 3220 3221 rw.cmd = cmd; 3222 3223 if (argc >= 1) { 3224 rw.rw_loc = IKE_RW_LOC_USER_SPEC; 3225 fd = open(argv[0], oflag, omode); 3226 if (fd < 0) 3227 Bail("open user-specified file"); 3228 3229 desc.d_data.d_desc.d_descriptor = fd; 3230 desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE; 3231 descp = &desc; 3232 ndesc = 1; 3233 } else { 3234 rw.rw_loc = IKE_RW_LOC_DEFAULT; 3235 } 3236 3237 rtnp = ikedoor_call((char *)&rw, sizeof (ike_rw_t), descp, ndesc); 3238 if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) { 3239 /* 3240 * Need to remove the target file in the 3241 * case of a failed write command. 3242 */ 3243 if (writing) { 3244 /* 3245 * argv[0] must be valid if we're writing; we 3246 * exit before setting this boolean if not. 3247 */ 3248 (void) unlink(argv[0]); 3249 (void) close(fd); 3250 3251 if ((rtnp != NULL) && 3252 (rtnp->svc_err.ike_err == IKE_ERR_NO_OBJ)) { 3253 message(gettext("No %s information to write."), 3254 obj); 3255 return; 3256 } 3257 } 3258 ikeadm_err_exit(&rtnp->svc_err, gettext("error doing %s"), op); 3259 } 3260 message(gettext("Completed %s of %s configuration information."), 3261 op, obj); 3262 } 3263 3264 static void 3265 do_rbdump() 3266 { 3267 ike_cmd_t req; 3268 ike_service_t *rtnp; 3269 3270 req.cmd = IKE_SVC_DBG_RBDUMP; 3271 3272 rtnp = ikedoor_call((char *)&req, sizeof (ike_cmd_t), NULL, 0); 3273 if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) { 3274 ikeadm_err_exit(&rtnp->svc_err, gettext("error doing flush")); 3275 } 3276 message(gettext("Successfully dumped rulebase; check iked dbg")); 3277 } 3278 3279 #define REQ_ARG_CNT 1 3280 3281 /*ARGSUSED*/ 3282 static void 3283 parseit(int argc, char **argv, char *notused, boolean_t notused_either) 3284 { 3285 int cmd, cmd_obj_args = 1; 3286 char *cmdstr, *objstr; 3287 3288 if (interactive) { 3289 if (argc == 0) 3290 return; 3291 } 3292 3293 if (argc < REQ_ARG_CNT) { 3294 usage(); 3295 } 3296 3297 cmdstr = argv[0]; 3298 if (argc > REQ_ARG_CNT) { 3299 cmd_obj_args++; 3300 objstr = argv[1]; 3301 } else { 3302 objstr = NULL; 3303 } 3304 cmd = parsecmd(cmdstr, objstr); 3305 3306 /* skip over args specifying command/object */ 3307 argc -= cmd_obj_args; 3308 argv += cmd_obj_args; 3309 3310 switch (cmd) { 3311 case IKE_SVC_GET_DEFS: 3312 if (argc != 0) { 3313 print_get_help(); 3314 break; 3315 } 3316 do_getdefs(cmd); 3317 break; 3318 case IKE_SVC_GET_DBG: 3319 case IKE_SVC_GET_PRIV: 3320 if (argc != 0) { 3321 print_get_help(); 3322 break; 3323 } 3324 do_getvar(cmd); 3325 break; 3326 case IKE_SVC_GET_STATS: 3327 if (argc != 0) { 3328 print_get_help(); 3329 break; 3330 } 3331 do_getstats(cmd); 3332 break; 3333 case IKE_SVC_SET_DBG: 3334 case IKE_SVC_SET_PRIV: 3335 do_setvar(cmd, argc, argv); 3336 break; 3337 case IKE_SVC_SET_PIN: 3338 case IKE_SVC_DEL_PIN: 3339 do_setdel_pin(cmd, argc, argv); 3340 break; 3341 case IKE_SVC_DUMP_P1S: 3342 case IKE_SVC_DUMP_RULES: 3343 case IKE_SVC_DUMP_GROUPS: 3344 case IKE_SVC_DUMP_ENCRALGS: 3345 case IKE_SVC_DUMP_AUTHALGS: 3346 case IKE_SVC_DUMP_PS: 3347 case IKE_SVC_DUMP_CERTCACHE: 3348 if (argc != NULL) { 3349 print_dump_help(); 3350 break; 3351 } 3352 do_dump(cmd); 3353 break; 3354 case IKE_SVC_GET_P1: 3355 case IKE_SVC_GET_RULE: 3356 case IKE_SVC_GET_PS: 3357 case IKE_SVC_DEL_P1: 3358 case IKE_SVC_DEL_RULE: 3359 case IKE_SVC_DEL_PS: 3360 do_getdel(cmd, argc, argv); 3361 break; 3362 case IKE_SVC_NEW_RULE: 3363 case IKE_SVC_NEW_PS: 3364 do_new(cmd, argc, argv); 3365 break; 3366 case IKE_SVC_FLUSH_P1S: 3367 case IKE_SVC_FLUSH_CERTCACHE: 3368 if (argc != 0) { 3369 print_flush_help(); 3370 break; 3371 } 3372 do_flush(cmd); 3373 break; 3374 case IKE_SVC_READ_RULES: 3375 case IKE_SVC_READ_PS: 3376 case IKE_SVC_WRITE_RULES: 3377 case IKE_SVC_WRITE_PS: 3378 do_rw(cmd, argc, argv); 3379 break; 3380 case IKEADM_HELP_GENERAL: 3381 print_help(); 3382 break; 3383 case IKEADM_HELP_GET: 3384 print_get_help(); 3385 break; 3386 case IKEADM_HELP_SET: 3387 print_set_help(); 3388 break; 3389 case IKEADM_HELP_ADD: 3390 print_add_help(); 3391 break; 3392 case IKEADM_HELP_DEL: 3393 print_del_help(); 3394 break; 3395 case IKEADM_HELP_DUMP: 3396 print_dump_help(); 3397 break; 3398 case IKEADM_HELP_FLUSH: 3399 print_flush_help(); 3400 break; 3401 case IKEADM_HELP_READ: 3402 print_read_help(); 3403 break; 3404 case IKEADM_HELP_WRITE: 3405 print_write_help(); 3406 break; 3407 case IKEADM_HELP_TOKEN: 3408 print_token_help(); 3409 break; 3410 case IKEADM_HELP_HELP: 3411 print_help_help(); 3412 break; 3413 case IKEADM_EXIT: 3414 if (interactive) 3415 exit(0); 3416 break; 3417 case IKE_SVC_DBG_RBDUMP: 3418 do_rbdump(); 3419 break; 3420 case IKE_SVC_ERROR: 3421 usage(); 3422 default: 3423 exit(0); 3424 } 3425 } 3426 3427 int 3428 main(int argc, char **argv) 3429 { 3430 char ch; 3431 3432 (void) setlocale(LC_ALL, ""); 3433 #if !defined(TEXT_DOMAIN) 3434 #define TEXT_DOMAIN "SYS_TEST" 3435 #endif 3436 (void) textdomain(TEXT_DOMAIN); 3437 3438 while ((ch = getopt(argc, argv, "hpn")) != EOF) { 3439 switch (ch) { 3440 case 'h': 3441 print_help(); 3442 return (0); 3443 case 'p': 3444 pflag = B_TRUE; 3445 break; 3446 case 'n': 3447 nflag = B_TRUE; 3448 break; 3449 default: 3450 usage(); 3451 } 3452 } 3453 argc -= optind; 3454 argv += optind; 3455 3456 if (open_door() < 0) { 3457 (void) fprintf(stderr, 3458 gettext("Unable to communicate with in.iked\n")); 3459 Bail("open_door failed"); 3460 } 3461 3462 if (*argv == NULL) { 3463 /* no cmd-line args, do interactive mode */ 3464 do_interactive(stdin, NULL, "ikeadm> ", NULL, parseit, 3465 no_match); 3466 } 3467 3468 parseit(argc, argv, NULL, B_FALSE); 3469 3470 return (0); 3471 } 3472