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