14235Smarkfen /* 24235Smarkfen * CDDL HEADER START 34235Smarkfen * 44235Smarkfen * The contents of this file are subject to the terms of the 54235Smarkfen * Common Development and Distribution License (the "License"). 64235Smarkfen * You may not use this file except in compliance with the License. 74235Smarkfen * 84235Smarkfen * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 94235Smarkfen * or http://www.opensolaris.org/os/licensing. 104235Smarkfen * See the License for the specific language governing permissions 114235Smarkfen * and limitations under the License. 124235Smarkfen * 134235Smarkfen * When distributing Covered Code, include this CDDL HEADER in each 144235Smarkfen * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 154235Smarkfen * If applicable, add the following below this CDDL HEADER, with the 164235Smarkfen * fields enclosed by brackets "[]" replaced with your own identifying 174235Smarkfen * information: Portions Copyright [yyyy] [name of copyright owner] 184235Smarkfen * 194235Smarkfen * CDDL HEADER END 204235Smarkfen * 21*8596SPaul.Wernau@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 224235Smarkfen * Use is subject to license terms. 234235Smarkfen */ 244235Smarkfen 254235Smarkfen #include <unistd.h> 264235Smarkfen #include <stdio.h> 274235Smarkfen #include <stdarg.h> 284235Smarkfen #include <stdlib.h> 294235Smarkfen #include <sys/sysconf.h> 304235Smarkfen #include <string.h> 314235Smarkfen #include <strings.h> 324235Smarkfen #include <libintl.h> 334235Smarkfen #include <locale.h> 344235Smarkfen #include <ctype.h> 354235Smarkfen #include <time.h> 364235Smarkfen #include <sys/sysmacros.h> 374235Smarkfen #include <sys/stat.h> 384235Smarkfen #include <sys/mman.h> 394235Smarkfen #include <fcntl.h> 404235Smarkfen #include <sys/socket.h> 414235Smarkfen #include <netdb.h> 424235Smarkfen #include <errno.h> 434235Smarkfen #include <assert.h> 444235Smarkfen #include <netinet/in.h> 454235Smarkfen #include <arpa/inet.h> 464235Smarkfen #include <door.h> 474235Smarkfen #include <setjmp.h> 484235Smarkfen 494235Smarkfen #include <ipsec_util.h> 504235Smarkfen #include <ikedoor.h> 514235Smarkfen 524235Smarkfen static int doorfd = -1; 534235Smarkfen 544235Smarkfen /* 554235Smarkfen * These are additional return values for the command line parsing 564235Smarkfen * function (parsecmd()). They are specific to this utility, but 574235Smarkfen * need to share the same space as the IKE_SVC_* defs, without conflicts. 584235Smarkfen * So they're defined relative to the end of that range. 594235Smarkfen */ 604235Smarkfen #define IKEADM_HELP_GENERAL IKE_SVC_MAX + 1 614235Smarkfen #define IKEADM_HELP_GET IKE_SVC_MAX + 2 624235Smarkfen #define IKEADM_HELP_SET IKE_SVC_MAX + 3 634235Smarkfen #define IKEADM_HELP_ADD IKE_SVC_MAX + 4 644235Smarkfen #define IKEADM_HELP_DEL IKE_SVC_MAX + 5 654235Smarkfen #define IKEADM_HELP_DUMP IKE_SVC_MAX + 6 664235Smarkfen #define IKEADM_HELP_FLUSH IKE_SVC_MAX + 7 674235Smarkfen #define IKEADM_HELP_READ IKE_SVC_MAX + 8 684235Smarkfen #define IKEADM_HELP_WRITE IKE_SVC_MAX + 9 69*8596SPaul.Wernau@Sun.COM #define IKEADM_HELP_TOKEN IKE_SVC_MAX + 10 70*8596SPaul.Wernau@Sun.COM #define IKEADM_HELP_HELP IKE_SVC_MAX + 11 71*8596SPaul.Wernau@Sun.COM #define IKEADM_EXIT IKE_SVC_MAX + 12 724235Smarkfen 734235Smarkfen static void 744235Smarkfen command_complete(int s) 754235Smarkfen { 764235Smarkfen if (interactive) { 774235Smarkfen longjmp(env, 1); 784235Smarkfen } else { 794235Smarkfen exit(s); 804235Smarkfen } 814235Smarkfen } 824235Smarkfen 834235Smarkfen static void 844235Smarkfen usage() 854235Smarkfen { 864235Smarkfen if (!interactive) { 874235Smarkfen (void) fprintf(stderr, gettext("Usage:\t" 884235Smarkfen "ikeadm [ -hnp ] cmd obj [cmd-specific options]\n")); 894235Smarkfen (void) fprintf(stderr, gettext(" \tikeadm help\n")); 904235Smarkfen } 914235Smarkfen 924235Smarkfen command_complete(1); 934235Smarkfen } 944235Smarkfen 954235Smarkfen static void 964235Smarkfen print_help() 974235Smarkfen { 984235Smarkfen (void) printf(gettext("Valid commands and objects:\n")); 994235Smarkfen (void) printf( 1004235Smarkfen "\tget debug|priv|stats|p1|rule|preshared|defaults [%s]\n", 1014235Smarkfen gettext("identifier")); 1024235Smarkfen (void) printf("\tset priv %s\n", gettext("level")); 1034235Smarkfen (void) printf("\tset debug %s [%s]\n", 1044235Smarkfen gettext("level"), gettext("filename")); 1054235Smarkfen (void) printf("\tadd rule|preshared {%s}|%s\n", 1064235Smarkfen gettext("definition"), gettext("filename")); 1074235Smarkfen (void) printf("\tdel p1|rule|preshared %s\n", gettext("identifier")); 108*8596SPaul.Wernau@Sun.COM (void) printf("\tdump p1|rule|preshared|certcache\n"); 109*8596SPaul.Wernau@Sun.COM (void) printf("\tflush p1|certcache\n"); 1104235Smarkfen (void) printf("\tread rule|preshared [%s]\n", gettext("filename")); 1114235Smarkfen (void) printf("\twrite rule|preshared %s\n", gettext("filename")); 112*8596SPaul.Wernau@Sun.COM (void) printf("\ttoken <login|logout> %s\n", 113*8596SPaul.Wernau@Sun.COM gettext("<PKCS#11 Token Object>")); 1144235Smarkfen (void) printf( 115*8596SPaul.Wernau@Sun.COM "\thelp [get|set|add|del|dump|flush|read|write|token|help]\n"); 1164235Smarkfen (void) printf("\texit %s\n", gettext("exit the program")); 1174235Smarkfen (void) printf("\tquit %s\n", gettext("exit the program")); 1184235Smarkfen (void) printf("\n"); 1194235Smarkfen 1204235Smarkfen command_complete(0); 1214235Smarkfen } 1224235Smarkfen 1234235Smarkfen static void 1244235Smarkfen print_get_help() 1254235Smarkfen { 1264235Smarkfen (void) printf( 1274235Smarkfen gettext("This command gets information from in.iked.\n\n")); 1284235Smarkfen (void) printf(gettext("Objects that may be retrieved include:\n")); 1294235Smarkfen (void) printf("\tdebug\t\t"); 1304235Smarkfen (void) printf(gettext("the current debug level\n")); 1314235Smarkfen (void) printf("\tpriv\t\t"); 1324235Smarkfen (void) printf(gettext("the current privilege level\n")); 1334235Smarkfen (void) printf("\tstats\t\t"); 1344235Smarkfen (void) printf(gettext("current usage statistics\n")); 1354235Smarkfen (void) printf("\tp1\t\t"); 1364235Smarkfen (void) printf(gettext("a phase 1 SA, identified by\n")); 1374235Smarkfen (void) printf(gettext("\t\t\t local_ip remote_ip OR\n")); 1384235Smarkfen (void) printf(gettext("\t\t\t init_cookie resp_cookie\n")); 1394235Smarkfen (void) printf("\trule\t\t"); 1404235Smarkfen (void) printf(gettext("a phase 1 rule, identified by its label\n")); 1414235Smarkfen (void) printf("\tpreshared\t"); 1424235Smarkfen (void) printf(gettext("a preshared key, identified by\n")); 1434235Smarkfen (void) printf(gettext("\t\t\t local_ip remote_ip OR\n")); 1444235Smarkfen (void) printf(gettext("\t\t\t local_id remote_id\n")); 1454235Smarkfen (void) printf("\n"); 1464235Smarkfen 1474235Smarkfen command_complete(0); 1484235Smarkfen } 1494235Smarkfen 1504235Smarkfen static void 1514235Smarkfen print_set_help() 1524235Smarkfen { 1534235Smarkfen (void) printf(gettext("This command sets values in in.iked.\n\n")); 1544235Smarkfen (void) printf(gettext("Objects that may be set include:\n")); 1554235Smarkfen (void) printf("\tdebug\t\t"); 1564235Smarkfen (void) printf(gettext("change the debug level\n")); 1574235Smarkfen (void) printf("\tpriv\t\t"); 1584235Smarkfen (void) printf( 1594235Smarkfen gettext("change the privilege level (may only be lowered)\n")); 1604235Smarkfen (void) printf("\n"); 1614235Smarkfen 1624235Smarkfen command_complete(0); 1634235Smarkfen } 1644235Smarkfen 1654235Smarkfen static void 1664235Smarkfen print_add_help() 1674235Smarkfen { 1684235Smarkfen (void) printf( 1694235Smarkfen gettext("This command adds items to in.iked's tables.\n\n")); 1704235Smarkfen (void) printf(gettext("Objects that may be set include:\n")); 1714235Smarkfen (void) printf("\trule\t\t"); 1724235Smarkfen (void) printf(gettext("a phase 1 policy rule\n")); 1734235Smarkfen (void) printf("\tpreshared\t"); 1744235Smarkfen (void) printf(gettext("a preshared key\n")); 1754235Smarkfen (void) printf( 1764235Smarkfen gettext("\nObjects may be entered on the command-line, as a\n")); 1774235Smarkfen (void) printf( 1784235Smarkfen gettext("series of keywords and tokens contained in curly\n")); 1794235Smarkfen (void) printf( 1804235Smarkfen gettext("braces ('{', '}'); or the name of a file containing\n")); 1814235Smarkfen (void) printf(gettext("the object definition may be provided.\n\n")); 1824235Smarkfen (void) printf( 1834235Smarkfen gettext("For security purposes, preshared keys may only be\n")); 1844235Smarkfen (void) printf( 1854235Smarkfen gettext("entered on the command-line if ikeadm is running in\n")); 1864235Smarkfen (void) printf(gettext("interactive mode.\n")); 1874235Smarkfen (void) printf("\n"); 1884235Smarkfen 1894235Smarkfen command_complete(0); 1904235Smarkfen } 1914235Smarkfen 1924235Smarkfen static void 1934235Smarkfen print_del_help() 1944235Smarkfen { 1954235Smarkfen (void) printf( 1964235Smarkfen gettext("This command deletes an item from in.iked's tables.\n\n")); 1974235Smarkfen (void) printf(gettext("Objects that may be deleted include:\n")); 1984235Smarkfen (void) printf("\tp1\t\t"); 1994235Smarkfen (void) printf(gettext("a phase 1 SA, identified by\n")); 2004235Smarkfen (void) printf(gettext("\t\t\t local_ip remote_ip OR\n")); 2014235Smarkfen (void) printf(gettext("\t\t\t init_cookie resp_cookie\n")); 2024235Smarkfen (void) printf("\trule\t\t"); 2034235Smarkfen (void) printf(gettext("a phase 1 rule, identified by its label\n")); 2044235Smarkfen (void) printf("\tpreshared\t"); 2054235Smarkfen (void) printf(gettext("a preshared key, identified by\n")); 2064235Smarkfen (void) printf(gettext("\t\t\t local_ip remote_ip OR\n")); 2074235Smarkfen (void) printf(gettext("\t\t\t local_id remote_id\n")); 2084235Smarkfen (void) printf("\n"); 2094235Smarkfen 2104235Smarkfen command_complete(0); 2114235Smarkfen } 2124235Smarkfen 2134235Smarkfen static void 2144235Smarkfen print_dump_help() 2154235Smarkfen { 2164235Smarkfen (void) printf( 2174235Smarkfen gettext("This command dumps one of in.iked's tables.\n\n")); 2184235Smarkfen (void) printf(gettext("Tables that may be dumped include:\n")); 2194235Smarkfen (void) printf("\tp1\t\t"); 2204235Smarkfen (void) printf(gettext("all phase 1 SAs\n")); 2214235Smarkfen (void) printf("\trule\t\t"); 2224235Smarkfen (void) printf(gettext("all phase 1 rules\n")); 2234235Smarkfen (void) printf("\tpreshared\t"); 2244235Smarkfen (void) printf(gettext("all preshared keys\n")); 225*8596SPaul.Wernau@Sun.COM (void) printf("\tcertcache\t"); 226*8596SPaul.Wernau@Sun.COM (void) printf(gettext("all cached certificates\n")); 2274235Smarkfen (void) printf("\n"); 2284235Smarkfen 2294235Smarkfen command_complete(0); 2304235Smarkfen } 2314235Smarkfen 2324235Smarkfen static void 2334235Smarkfen print_flush_help() 2344235Smarkfen { 2354235Smarkfen (void) printf( 2364235Smarkfen gettext("This command clears one of in.iked's tables.\n\n")); 2374235Smarkfen (void) printf(gettext("Tables that may be flushed include:\n")); 2384235Smarkfen (void) printf("\tp1\t\t"); 2394235Smarkfen (void) printf(gettext("all phase 1 SAs\n")); 240*8596SPaul.Wernau@Sun.COM (void) printf("\tcertcache\t"); 241*8596SPaul.Wernau@Sun.COM (void) printf(gettext("all cached certificates\n")); 2424235Smarkfen (void) printf("\n"); 2434235Smarkfen 2444235Smarkfen command_complete(0); 2454235Smarkfen } 2464235Smarkfen 2474235Smarkfen static void 2484235Smarkfen print_read_help() 2494235Smarkfen { 2504235Smarkfen (void) printf( 2514235Smarkfen gettext("This command reads a new configuration file into\n")); 2524235Smarkfen (void) printf( 2534235Smarkfen gettext("in.iked, discarding the old configuration info.\n\n")); 2544235Smarkfen (void) printf(gettext("Sets of data that may be read include:\n")); 2554235Smarkfen (void) printf("\trule\t\t"); 2564235Smarkfen (void) printf(gettext("all phase 1 rules\n")); 2574235Smarkfen (void) printf("\tpreshared\t"); 2584235Smarkfen (void) printf(gettext("all preshared keys\n\n")); 2594235Smarkfen (void) printf( 2604235Smarkfen gettext("A filename may be provided to specify a source file\n")); 2614235Smarkfen (void) printf(gettext("other than the default.\n")); 2624235Smarkfen (void) printf("\n"); 2634235Smarkfen 2644235Smarkfen command_complete(0); 2654235Smarkfen } 2664235Smarkfen 2674235Smarkfen static void 2684235Smarkfen print_write_help() 2694235Smarkfen { 2704235Smarkfen (void) printf( 2714235Smarkfen gettext("This command writes in.iked's current configuration\n")); 2724235Smarkfen (void) printf(gettext("out to a config file.\n\n")); 2734235Smarkfen (void) printf(gettext("Sets of data that may be written include:\n")); 2744235Smarkfen (void) printf("\trule\t\t"); 2754235Smarkfen (void) printf(gettext("all phase 1 rules\n")); 2764235Smarkfen (void) printf("\tpreshared\t"); 2774235Smarkfen (void) printf(gettext("all preshared keys\n\n")); 2784235Smarkfen (void) printf( 2794235Smarkfen gettext("A filename must be provided to specify the file to\n")); 2804235Smarkfen (void) printf(gettext("which the information should be written.\n")); 2814235Smarkfen (void) printf("\n"); 2824235Smarkfen 2834235Smarkfen command_complete(0); 2844235Smarkfen } 2854235Smarkfen 2864235Smarkfen static void 287*8596SPaul.Wernau@Sun.COM print_token_help() 288*8596SPaul.Wernau@Sun.COM { 289*8596SPaul.Wernau@Sun.COM (void) printf(gettext( 290*8596SPaul.Wernau@Sun.COM "This command logs IKE into and out of PKCS#11 tokens.\n\n")); 291*8596SPaul.Wernau@Sun.COM (void) printf(gettext("Commands include:\n")); 292*8596SPaul.Wernau@Sun.COM (void) printf("\tlogin <PKCS#11 Token Object>\t"); 293*8596SPaul.Wernau@Sun.COM (void) printf(gettext("log into token\n")); 294*8596SPaul.Wernau@Sun.COM (void) printf("\tlogout <PKCS#11 Token Object>\t"); 295*8596SPaul.Wernau@Sun.COM (void) printf(gettext("log out of token\n\n")); 296*8596SPaul.Wernau@Sun.COM (void) printf( 297*8596SPaul.Wernau@Sun.COM gettext("The PKCS#11 Token Object name must be " 298*8596SPaul.Wernau@Sun.COM "enclosed in quotation marks.\n")); 299*8596SPaul.Wernau@Sun.COM (void) printf("\n"); 300*8596SPaul.Wernau@Sun.COM 301*8596SPaul.Wernau@Sun.COM command_complete(0); 302*8596SPaul.Wernau@Sun.COM } 303*8596SPaul.Wernau@Sun.COM 304*8596SPaul.Wernau@Sun.COM static void 3054235Smarkfen print_help_help() 3064235Smarkfen { 3074235Smarkfen (void) printf( 3084235Smarkfen gettext("This command provides information about commands.\n\n")); 3094235Smarkfen (void) printf( 3104235Smarkfen gettext("The 'help' command alone provides a list of valid\n")); 3114235Smarkfen (void) printf( 3124235Smarkfen gettext("commands, along with the valid objects for each.\n")); 3134235Smarkfen (void) printf( 3144235Smarkfen gettext("'help' followed by a valid command name provides\n")); 3154235Smarkfen (void) printf(gettext("further information about that command.\n")); 3164235Smarkfen (void) printf("\n"); 3174235Smarkfen 3184235Smarkfen command_complete(0); 3194235Smarkfen } 3204235Smarkfen 3214235Smarkfen /*PRINTFLIKE1*/ 3224235Smarkfen static void 3234235Smarkfen message(char *fmt, ...) 3244235Smarkfen { 3254235Smarkfen va_list ap; 3264235Smarkfen char msgbuf[BUFSIZ]; 3274235Smarkfen 3284235Smarkfen va_start(ap, fmt); 3294235Smarkfen (void) vsnprintf(msgbuf, BUFSIZ, fmt, ap); 3304235Smarkfen (void) fprintf(stderr, gettext("ikeadm: %s\n"), msgbuf); 3314235Smarkfen va_end(ap); 3324235Smarkfen } 3334235Smarkfen 3344235Smarkfen static int 3354235Smarkfen open_door(void) 3364235Smarkfen { 3374235Smarkfen if (doorfd >= 0) 3384235Smarkfen (void) close(doorfd); 339*8596SPaul.Wernau@Sun.COM doorfd = open(DOORNM, O_RDONLY); 3404235Smarkfen return (doorfd); 3414235Smarkfen } 3424235Smarkfen 3434235Smarkfen static ike_service_t * 3444235Smarkfen ikedoor_call(char *reqp, int size, door_desc_t *descp, int ndesc) 3454235Smarkfen { 3464235Smarkfen door_arg_t arg; 3474235Smarkfen int retries = 0; 3484235Smarkfen 3494235Smarkfen arg.data_ptr = reqp; 3504235Smarkfen arg.data_size = size; 3514235Smarkfen arg.desc_ptr = descp; 3524235Smarkfen arg.desc_num = ndesc; 3534235Smarkfen arg.rbuf = (char *)NULL; 3544235Smarkfen arg.rsize = 0; 3554235Smarkfen 3564235Smarkfen retry: 3574235Smarkfen if (door_call(doorfd, &arg) < 0) { 3584235Smarkfen if ((errno == EBADF) && ((++retries < 2) && 3594235Smarkfen (open_door() >= 0))) 3604235Smarkfen goto retry; 3614235Smarkfen (void) fprintf(stderr, 3624235Smarkfen gettext("Unable to communicate with in.iked\n")); 3634235Smarkfen Bail("door_call failed"); 3644235Smarkfen } 3654235Smarkfen 3664235Smarkfen if ((ndesc > 0) && (descp->d_attributes & DOOR_RELEASE) && 3674235Smarkfen ((errno == EBADF) || (errno == EFAULT))) { 3684235Smarkfen /* callers assume passed fds will be closed no matter what */ 3694235Smarkfen (void) close(descp->d_data.d_desc.d_descriptor); 3704235Smarkfen } 3714235Smarkfen 3724235Smarkfen /* LINTED E_BAD_PTR_CAST_ALIGN */ 3734235Smarkfen return ((ike_service_t *)arg.rbuf); 3744235Smarkfen } 3754235Smarkfen 3764235Smarkfen /* 3774235Smarkfen * Parsing functions 3784235Smarkfen */ 3794235Smarkfen 3804235Smarkfen /* stolen from ipseckey.c, with a second tier added */ 3814235Smarkfen static int 3824235Smarkfen parsecmd(char *cmdstr, char *objstr) 3834235Smarkfen { 384*8596SPaul.Wernau@Sun.COM #define MAXOBJS 11 3854235Smarkfen struct objtbl { 3864235Smarkfen char *obj; 3874235Smarkfen int token; 3884235Smarkfen }; 3894235Smarkfen static struct cmdtbl { 3904235Smarkfen char *cmd; 3914235Smarkfen int null_obj_token; 3924235Smarkfen struct objtbl objt[MAXOBJS]; 3934235Smarkfen } table[] = { 3944235Smarkfen {"get", IKE_SVC_ERROR, { 3954235Smarkfen {"debug", IKE_SVC_GET_DBG}, 3964235Smarkfen {"priv", IKE_SVC_GET_PRIV}, 3974235Smarkfen {"stats", IKE_SVC_GET_STATS}, 3984235Smarkfen {"p1", IKE_SVC_GET_P1}, 3994235Smarkfen {"rule", IKE_SVC_GET_RULE}, 4004235Smarkfen {"preshared", IKE_SVC_GET_PS}, 4014235Smarkfen {"defaults", IKE_SVC_GET_DEFS}, 4027421SDaniel.Anderson@Sun.COM {NULL, IKE_SVC_ERROR} 4034235Smarkfen } 4044235Smarkfen }, 4054235Smarkfen {"set", IKE_SVC_ERROR, { 4064235Smarkfen {"debug", IKE_SVC_SET_DBG}, 4074235Smarkfen {"priv", IKE_SVC_SET_PRIV}, 4087421SDaniel.Anderson@Sun.COM {NULL, IKE_SVC_ERROR} 4094235Smarkfen } 4104235Smarkfen }, 411*8596SPaul.Wernau@Sun.COM {"token", IKE_SVC_ERROR, { 412*8596SPaul.Wernau@Sun.COM {"login", IKE_SVC_SET_PIN}, 413*8596SPaul.Wernau@Sun.COM {"logout", IKE_SVC_DEL_PIN}, 414*8596SPaul.Wernau@Sun.COM {NULL, IKE_SVC_ERROR}, 415*8596SPaul.Wernau@Sun.COM } 416*8596SPaul.Wernau@Sun.COM }, 4174235Smarkfen {"add", IKE_SVC_ERROR, { 4184235Smarkfen {"rule", IKE_SVC_NEW_RULE}, 4194235Smarkfen {"preshared", IKE_SVC_NEW_PS}, 4207421SDaniel.Anderson@Sun.COM {NULL, IKE_SVC_ERROR} 4214235Smarkfen } 4224235Smarkfen }, 4234235Smarkfen {"del", IKE_SVC_ERROR, { 4244235Smarkfen {"p1", IKE_SVC_DEL_P1}, 4254235Smarkfen {"rule", IKE_SVC_DEL_RULE}, 4264235Smarkfen {"preshared", IKE_SVC_DEL_PS}, 4277421SDaniel.Anderson@Sun.COM {NULL, IKE_SVC_ERROR} 4284235Smarkfen } 4294235Smarkfen }, 4304235Smarkfen {"dump", IKE_SVC_ERROR, { 4314235Smarkfen {"p1", IKE_SVC_DUMP_P1S}, 4324235Smarkfen {"rule", IKE_SVC_DUMP_RULES}, 4334235Smarkfen {"preshared", IKE_SVC_DUMP_PS}, 434*8596SPaul.Wernau@Sun.COM {"certcache", IKE_SVC_DUMP_CERTCACHE}, 4357421SDaniel.Anderson@Sun.COM {NULL, IKE_SVC_ERROR} 4364235Smarkfen } 4374235Smarkfen }, 4384235Smarkfen {"flush", IKE_SVC_ERROR, { 4394235Smarkfen {"p1", IKE_SVC_FLUSH_P1S}, 440*8596SPaul.Wernau@Sun.COM {"certcache", IKE_SVC_FLUSH_CERTCACHE}, 4417421SDaniel.Anderson@Sun.COM {NULL, IKE_SVC_ERROR} 4424235Smarkfen } 4434235Smarkfen }, 4444235Smarkfen {"read", IKE_SVC_ERROR, { 4454235Smarkfen {"rule", IKE_SVC_READ_RULES}, 4464235Smarkfen {"preshared", IKE_SVC_READ_PS}, 4477421SDaniel.Anderson@Sun.COM {NULL, IKE_SVC_ERROR} 4484235Smarkfen } 4494235Smarkfen }, 4504235Smarkfen {"write", IKE_SVC_ERROR, { 4514235Smarkfen {"rule", IKE_SVC_WRITE_RULES}, 4524235Smarkfen {"preshared", IKE_SVC_WRITE_PS}, 4537421SDaniel.Anderson@Sun.COM {NULL, IKE_SVC_ERROR} 4544235Smarkfen } 4554235Smarkfen }, 4564235Smarkfen {"help", IKEADM_HELP_GENERAL, { 4574235Smarkfen {"get", IKEADM_HELP_GET}, 4584235Smarkfen {"set", IKEADM_HELP_SET}, 4594235Smarkfen {"add", IKEADM_HELP_ADD}, 4604235Smarkfen {"del", IKEADM_HELP_DEL}, 4614235Smarkfen {"dump", IKEADM_HELP_DUMP}, 4624235Smarkfen {"flush", IKEADM_HELP_FLUSH}, 4634235Smarkfen {"read", IKEADM_HELP_READ}, 4644235Smarkfen {"write", IKEADM_HELP_WRITE}, 465*8596SPaul.Wernau@Sun.COM {"token", IKEADM_HELP_TOKEN}, 4664235Smarkfen {"help", IKEADM_HELP_HELP}, 4677421SDaniel.Anderson@Sun.COM {NULL, IKE_SVC_ERROR} 4684235Smarkfen } 4694235Smarkfen }, 4704235Smarkfen {"exit", IKEADM_EXIT, { 4717421SDaniel.Anderson@Sun.COM {NULL, IKE_SVC_ERROR} 4724235Smarkfen } 4734235Smarkfen }, 4744235Smarkfen {"quit", IKEADM_EXIT, { 4757421SDaniel.Anderson@Sun.COM {NULL, IKE_SVC_ERROR} 4764235Smarkfen } 4774235Smarkfen }, 4784235Smarkfen {"dbg", IKE_SVC_ERROR, { 4794235Smarkfen {"rbdump", IKE_SVC_DBG_RBDUMP}, 4807421SDaniel.Anderson@Sun.COM {NULL, IKE_SVC_ERROR} 4814235Smarkfen } 4824235Smarkfen }, 4834235Smarkfen {NULL, IKE_SVC_ERROR, { 4847421SDaniel.Anderson@Sun.COM {NULL, IKE_SVC_ERROR} 4854235Smarkfen } 4867421SDaniel.Anderson@Sun.COM } 4874235Smarkfen }; 4884235Smarkfen struct cmdtbl *ct = table; 4894235Smarkfen struct objtbl *ot; 4904235Smarkfen 4914235Smarkfen if (cmdstr == NULL) { 4924235Smarkfen return (IKE_SVC_ERROR); 4934235Smarkfen } 4944235Smarkfen 4954235Smarkfen while (ct->cmd != NULL && strcmp(ct->cmd, cmdstr) != 0) 4964235Smarkfen ct++; 4974235Smarkfen ot = ct->objt; 4984235Smarkfen 4994235Smarkfen if (ct->cmd == NULL) { 5004235Smarkfen message(gettext("Unrecognized command '%s'"), cmdstr); 5014235Smarkfen return (ot->token); 5024235Smarkfen } 5034235Smarkfen 5044235Smarkfen if (objstr == NULL) { 5054235Smarkfen return (ct->null_obj_token); 5064235Smarkfen } 5074235Smarkfen 5084235Smarkfen while (ot->obj != NULL && strcmp(ot->obj, objstr) != 0) 5094235Smarkfen ot++; 5104235Smarkfen 5114235Smarkfen if (ot->obj == NULL) 5124235Smarkfen message(gettext("Unrecognized object '%s'"), objstr); 5134235Smarkfen 5144235Smarkfen return (ot->token); 5154235Smarkfen } 5164235Smarkfen 5174235Smarkfen /* 5184235Smarkfen * Parsing functions: 5194235Smarkfen * Parse command-line identification info. All return -1 on failure, 5204235Smarkfen * or the number of cmd-line args "consumed" on success (though argc 5214235Smarkfen * and argv params are not actually modified). 5224235Smarkfen */ 5234235Smarkfen 5244235Smarkfen static int 5254235Smarkfen parse_label(int argc, char **argv, char *label) 5264235Smarkfen { 5274235Smarkfen if ((argc < 1) || (argv == NULL)) 5284235Smarkfen return (-1); 5294235Smarkfen 5304235Smarkfen if (strlcpy(label, argv[0], MAX_LABEL_LEN) >= MAX_LABEL_LEN) 5314235Smarkfen return (-1); 5324235Smarkfen 5334235Smarkfen return (1); 5344235Smarkfen } 5354235Smarkfen 5364235Smarkfen /* 537*8596SPaul.Wernau@Sun.COM * Parse a PKCS#11 token get the label. 538*8596SPaul.Wernau@Sun.COM */ 539*8596SPaul.Wernau@Sun.COM static int 540*8596SPaul.Wernau@Sun.COM parse_token(int argc, char **argv, char *token_label) 541*8596SPaul.Wernau@Sun.COM { 542*8596SPaul.Wernau@Sun.COM if ((argc < 1) || (argv == NULL)) 543*8596SPaul.Wernau@Sun.COM return (-1); 544*8596SPaul.Wernau@Sun.COM 545*8596SPaul.Wernau@Sun.COM if (strlcpy(token_label, argv[0], PKCS11_TOKSIZE) >= PKCS11_TOKSIZE) 546*8596SPaul.Wernau@Sun.COM return (-1); 547*8596SPaul.Wernau@Sun.COM 548*8596SPaul.Wernau@Sun.COM return (0); 549*8596SPaul.Wernau@Sun.COM } 550*8596SPaul.Wernau@Sun.COM 551*8596SPaul.Wernau@Sun.COM /* 5524235Smarkfen * Parse an address off the command line. In the hpp param, either 5534235Smarkfen * return a hostent pointer (caller frees) or a pointer to a dummy_he_t 5544235Smarkfen * (must also be freed by the caller; both cases are handled by the 5554235Smarkfen * macro FREE_HE). The new getipnodebyname() call does the Right Thing 5564235Smarkfen * (TM), even with raw addresses (colon-separated IPv6 or dotted decimal 5574235Smarkfen * IPv4). 5584235Smarkfen * (mostly stolen from ipseckey.c, though some tweaks were made 5594235Smarkfen * to better serve our purposes here.) 5604235Smarkfen */ 5614235Smarkfen 5624235Smarkfen typedef struct { 5634235Smarkfen struct hostent he; 5644235Smarkfen char *addtl[2]; 5654235Smarkfen } dummy_he_t; 5664235Smarkfen 5674235Smarkfen static int 5684235Smarkfen parse_addr(int argc, char **argv, struct hostent **hpp) 5694235Smarkfen { 5704235Smarkfen int hp_errno; 5714235Smarkfen struct hostent *hp = NULL; 5724235Smarkfen dummy_he_t *dhp; 5734235Smarkfen char *addr1; 5744235Smarkfen 5754235Smarkfen if ((argc < 1) || (argv == NULL) || (argv[0] == NULL)) 5764235Smarkfen return (-1); 5774235Smarkfen 5784235Smarkfen if (!nflag) { 5794235Smarkfen /* 5804235Smarkfen * Try name->address first. Assume AF_INET6, and 5814235Smarkfen * get IPV4s, plus IPv6s iff IPv6 is configured. 5824235Smarkfen */ 5834235Smarkfen hp = getipnodebyname(argv[0], AF_INET6, AI_DEFAULT | AI_ALL, 5844235Smarkfen &hp_errno); 5854235Smarkfen } else { 5864235Smarkfen /* 5874235Smarkfen * Try a normal address conversion only. malloc a 5884235Smarkfen * dummy_he_t to construct a fake hostent. Caller 5894235Smarkfen * will know to free this one using free_he(). 5904235Smarkfen */ 5914235Smarkfen dhp = (dummy_he_t *)malloc(sizeof (dummy_he_t)); 5924235Smarkfen addr1 = (char *)malloc(sizeof (struct in6_addr)); 5934235Smarkfen if (inet_pton(AF_INET6, argv[0], addr1) == 1) { 5944235Smarkfen dhp->he.h_addr_list = dhp->addtl; 5954235Smarkfen dhp->addtl[0] = addr1; 5964235Smarkfen dhp->addtl[1] = NULL; 5974235Smarkfen hp = &dhp->he; 5984235Smarkfen dhp->he.h_addrtype = AF_INET6; 5994235Smarkfen dhp->he.h_length = sizeof (struct in6_addr); 6004235Smarkfen } else if (inet_pton(AF_INET, argv[0], addr1) == 1) { 6014235Smarkfen dhp->he.h_addr_list = dhp->addtl; 6024235Smarkfen dhp->addtl[0] = addr1; 6034235Smarkfen dhp->addtl[1] = NULL; 6044235Smarkfen hp = &dhp->he; 6054235Smarkfen dhp->he.h_addrtype = AF_INET; 6064235Smarkfen dhp->he.h_length = sizeof (struct in_addr); 6074235Smarkfen } else { 6084235Smarkfen hp = NULL; 6094235Smarkfen } 6104235Smarkfen } 6114235Smarkfen 6124235Smarkfen *hpp = hp; 6134235Smarkfen 6144235Smarkfen if (hp == NULL) { 6154235Smarkfen message(gettext("Unknown address %s."), argv[0]); 6164235Smarkfen return (-1); 6174235Smarkfen } 6184235Smarkfen 6194235Smarkfen return (1); 6204235Smarkfen } 6214235Smarkfen 6224235Smarkfen /* 6234235Smarkfen * Free a dummy_he_t structure that was malloc'd in parse_addr(). 6244235Smarkfen * Unfortunately, callers of parse_addr don't want to know about 6254235Smarkfen * dummy_he_t structs, so all they have is a pointer to the struct 6264235Smarkfen * hostent; so that's what's passed in. To manage this, we make 6274235Smarkfen * the assumption that the struct hostent is the first field in 6284235Smarkfen * the dummy_he_t, and therefore a pointer to it is a pointer to 6294235Smarkfen * the dummy_he_t. 6304235Smarkfen */ 6314235Smarkfen static void 6324235Smarkfen free_he(struct hostent *hep) 6334235Smarkfen { 6344235Smarkfen dummy_he_t *p = (dummy_he_t *)hep; 6354235Smarkfen 6364235Smarkfen assert(p != NULL); 6374235Smarkfen 6384235Smarkfen if (p->addtl[0]) 6394235Smarkfen free(p->addtl[0]); 6404235Smarkfen if (p->addtl[1]) 6414235Smarkfen free(p->addtl[1]); 6424235Smarkfen 6434235Smarkfen free(p); 6444235Smarkfen } 6454235Smarkfen 6464235Smarkfen #define FREE_HE(x) \ 6474235Smarkfen if (nflag) \ 6484235Smarkfen free_he(x); \ 6494235Smarkfen else \ 6504235Smarkfen freehostent(x) 6514235Smarkfen 6524235Smarkfen static void 6534235Smarkfen headdr2sa(char *hea, struct sockaddr_storage *sa, int len) 6544235Smarkfen { 6554235Smarkfen struct sockaddr_in *sin; 6564235Smarkfen struct sockaddr_in6 *sin6; 6574235Smarkfen 6584235Smarkfen if (len == sizeof (struct in6_addr)) { 6594235Smarkfen /* LINTED E_BAD_PTR_CAST_ALIGN */ 6604235Smarkfen if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)hea)) { 6614235Smarkfen sin = (struct sockaddr_in *)sa; 6624235Smarkfen (void) memset(sin, 0, sizeof (*sin)); 6634235Smarkfen /* LINTED E_BAD_PTR_CAST_ALIGN */ 6644235Smarkfen IN6_V4MAPPED_TO_INADDR((struct in6_addr *)hea, 6654235Smarkfen &sin->sin_addr); 6664235Smarkfen sin->sin_family = AF_INET; 6674235Smarkfen } else { 6684235Smarkfen sin6 = (struct sockaddr_in6 *)sa; 6694235Smarkfen (void) memset(sin6, 0, sizeof (*sin6)); 6704235Smarkfen (void) memcpy(&sin6->sin6_addr, hea, 6714235Smarkfen sizeof (struct in6_addr)); 6724235Smarkfen sin6->sin6_family = AF_INET6; 6734235Smarkfen } 6744235Smarkfen } else { 6754235Smarkfen sin = (struct sockaddr_in *)sa; 6764235Smarkfen (void) memset(sin, 0, sizeof (*sin)); 6774235Smarkfen (void) memcpy(&sin->sin_addr, hea, sizeof (struct in_addr)); 6784235Smarkfen sin->sin_family = AF_INET; 6794235Smarkfen } 6804235Smarkfen } 6814235Smarkfen 6824235Smarkfen /* 6834235Smarkfen * The possible ident-type keywords that might be used on the command 6844235Smarkfen * line. This is a superset of the ones supported by ipseckey, those 6854235Smarkfen * in the ike config file, and those in ike.preshared. 6864235Smarkfen */ 6874235Smarkfen static keywdtab_t idtypes[] = { 6884235Smarkfen /* ip, ipv4, and ipv6 are valid for preshared keys... */ 6894235Smarkfen {SADB_IDENTTYPE_RESERVED, "ip"}, 6904235Smarkfen {SADB_IDENTTYPE_RESERVED, "ipv4"}, 6914235Smarkfen {SADB_IDENTTYPE_RESERVED, "ipv6"}, 6924235Smarkfen {SADB_IDENTTYPE_PREFIX, "prefix"}, 6934235Smarkfen {SADB_IDENTTYPE_PREFIX, "ipv4-prefix"}, 6944235Smarkfen {SADB_IDENTTYPE_PREFIX, "ipv6-prefix"}, 6954235Smarkfen {SADB_IDENTTYPE_PREFIX, "subnet"}, 6964235Smarkfen {SADB_IDENTTYPE_PREFIX, "subnetv4"}, 6974235Smarkfen {SADB_IDENTTYPE_PREFIX, "subnetv6"}, 6984235Smarkfen {SADB_IDENTTYPE_FQDN, "fqdn"}, 6994235Smarkfen {SADB_IDENTTYPE_FQDN, "dns"}, 7004235Smarkfen {SADB_IDENTTYPE_FQDN, "domain"}, 7014235Smarkfen {SADB_IDENTTYPE_FQDN, "domainname"}, 7024235Smarkfen {SADB_IDENTTYPE_USER_FQDN, "user_fqdn"}, 7034235Smarkfen {SADB_IDENTTYPE_USER_FQDN, "mbox"}, 7044235Smarkfen {SADB_IDENTTYPE_USER_FQDN, "mailbox"}, 7054235Smarkfen {SADB_X_IDENTTYPE_DN, "dn"}, 7064235Smarkfen {SADB_X_IDENTTYPE_DN, "asn1dn"}, 7074235Smarkfen {SADB_X_IDENTTYPE_GN, "gn"}, 7084235Smarkfen {SADB_X_IDENTTYPE_GN, "asn1gn"}, 7094235Smarkfen {SADB_X_IDENTTYPE_ADDR_RANGE, "ipv4-range"}, 7104235Smarkfen {SADB_X_IDENTTYPE_ADDR_RANGE, "ipv6-range"}, 7114235Smarkfen {SADB_X_IDENTTYPE_ADDR_RANGE, "rangev4"}, 7124235Smarkfen {SADB_X_IDENTTYPE_ADDR_RANGE, "rangev6"}, 7134235Smarkfen {SADB_X_IDENTTYPE_KEY_ID, "keyid"}, 7144235Smarkfen {NULL, 0} 7154235Smarkfen }; 7164235Smarkfen 7174235Smarkfen static int 7184235Smarkfen parse_idtype(char *type, uint16_t *idnum) 7194235Smarkfen { 7204235Smarkfen keywdtab_t *idp; 7214235Smarkfen 7224235Smarkfen if (type == NULL) 7234235Smarkfen return (-1); 7244235Smarkfen 7254235Smarkfen for (idp = idtypes; idp->kw_str != NULL; idp++) { 7264235Smarkfen if (strcasecmp(idp->kw_str, type) == 0) { 7274235Smarkfen if (idnum != NULL) 7284235Smarkfen *idnum = idp->kw_tag; 7294235Smarkfen return (1); 7304235Smarkfen } 7314235Smarkfen } 7324235Smarkfen 7334235Smarkfen return (-1); 7344235Smarkfen } 7354235Smarkfen 7364235Smarkfen /* 7374235Smarkfen * The sadb_ident_t is malloc'd, since its length varies; 7384235Smarkfen * so the caller must free() it when done with the data. 7394235Smarkfen */ 7404235Smarkfen static int 7414235Smarkfen parse_ident(int argc, char **argv, sadb_ident_t **idpp) 7424235Smarkfen { 7434235Smarkfen int alloclen, consumed; 7444235Smarkfen sadb_ident_t *idp; 7454235Smarkfen if ((argc < 2) || (argv == NULL) || (argv[0] == NULL) || 7464235Smarkfen (argv[1] == NULL)) 7474235Smarkfen return (-1); 7484235Smarkfen 7494235Smarkfen alloclen = sizeof (sadb_ident_t) + IKEDOORROUNDUP(strlen(argv[1]) + 1); 7504235Smarkfen *idpp = idp = (sadb_ident_t *)malloc(alloclen); 7514235Smarkfen if (idp == NULL) 7524235Smarkfen Bail("parsing identity"); 7534235Smarkfen 7544235Smarkfen if ((consumed = parse_idtype(argv[0], &idp->sadb_ident_type)) < 0) { 7554235Smarkfen message(gettext("unknown identity type %s."), argv[0]); 7564235Smarkfen return (-1); 7574235Smarkfen } 7584235Smarkfen 7594235Smarkfen idp->sadb_ident_len = SADB_8TO64(alloclen); 7604235Smarkfen idp->sadb_ident_reserved = 0; 7614235Smarkfen idp->sadb_ident_id = 0; 7624235Smarkfen 7634235Smarkfen /* now copy in identity param */ 7644235Smarkfen (void) strlcpy((char *)(idp + 1), argv[1], 7654235Smarkfen alloclen - (sizeof (sadb_ident_t))); 7664235Smarkfen 7674235Smarkfen return (++consumed); 7684235Smarkfen } 7694235Smarkfen 7704235Smarkfen static int 7714235Smarkfen parse_cky(int argc, char **argv, uint64_t *ckyp) 7724235Smarkfen { 7734235Smarkfen u_longlong_t arg; 7744235Smarkfen 7754235Smarkfen if ((argc < 1) || (argv[0] == NULL)) 7764235Smarkfen return (-1); 7774235Smarkfen 7784235Smarkfen errno = 0; 7794235Smarkfen arg = strtoull(argv[0], NULL, 0); 7804235Smarkfen if (errno != 0) { 7814235Smarkfen message(gettext("failed to parse cookie %s."), argv[0]); 7824235Smarkfen return (-1); 7834235Smarkfen } 7844235Smarkfen 7854235Smarkfen *ckyp = (uint64_t)arg; 7864235Smarkfen 7874235Smarkfen return (1); 7884235Smarkfen } 7894235Smarkfen 7904235Smarkfen static int 7914235Smarkfen parse_addr_pr(int argc, char **argv, struct hostent **h1pp, 7924235Smarkfen struct hostent **h2pp) 7934235Smarkfen { 7944235Smarkfen int rtn, consumed = 0; 7954235Smarkfen 7964235Smarkfen if ((rtn = parse_addr(argc, argv, h1pp)) < 0) { 7974235Smarkfen return (-1); 7984235Smarkfen } 7994235Smarkfen consumed = rtn; 8004235Smarkfen argc -= rtn; 8014235Smarkfen argv += rtn; 8024235Smarkfen 8034235Smarkfen if ((rtn = parse_addr(argc, argv, h2pp)) < 0) { 8044235Smarkfen FREE_HE(*h1pp); 8054235Smarkfen return (-1); 8064235Smarkfen } 8074235Smarkfen consumed += rtn; 8084235Smarkfen 8094235Smarkfen return (consumed); 8104235Smarkfen } 8114235Smarkfen 8124235Smarkfen /* 8134235Smarkfen * The sadb_ident_ts are malloc'd, since their length varies; 8144235Smarkfen * so the caller must free() them when done with the data. 8154235Smarkfen */ 8164235Smarkfen static int 8174235Smarkfen parse_ident_pr(int argc, char **argv, sadb_ident_t **id1pp, 8184235Smarkfen sadb_ident_t **id2pp) 8194235Smarkfen { 8204235Smarkfen int rtn, consumed = 0; 8214235Smarkfen 8224235Smarkfen if ((rtn = parse_ident(argc, argv, id1pp)) < 0) { 8234235Smarkfen return (-1); 8244235Smarkfen } 8254235Smarkfen consumed = rtn; 8264235Smarkfen argc -= rtn; 8274235Smarkfen argv += rtn; 8284235Smarkfen 8294235Smarkfen (*id1pp)->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC; 8304235Smarkfen 8314235Smarkfen if ((rtn = parse_ident(argc, argv, id2pp)) < 0) { 8324235Smarkfen free(*id1pp); 8334235Smarkfen return (-1); 8344235Smarkfen } 8354235Smarkfen consumed += rtn; 8364235Smarkfen 8374235Smarkfen (*id2pp)->sadb_ident_exttype = SADB_EXT_IDENTITY_DST; 8384235Smarkfen 8394235Smarkfen return (consumed); 8404235Smarkfen } 8414235Smarkfen 8424235Smarkfen static int 8434235Smarkfen parse_cky_pr(int argc, char **argv, ike_cky_pr_t *cpr) 8444235Smarkfen { 8454235Smarkfen int rtn, consumed = 0; 8464235Smarkfen 8474235Smarkfen if ((rtn = parse_cky(argc, argv, &cpr->cky_i)) < 0) { 8484235Smarkfen return (-1); 8494235Smarkfen } 8504235Smarkfen consumed = rtn; 8514235Smarkfen argc -= rtn; 8524235Smarkfen argv += rtn; 8534235Smarkfen 8544235Smarkfen if ((rtn = parse_cky(argc, argv, &cpr->cky_r)) < 0) { 8554235Smarkfen return (-1); 8564235Smarkfen } 8574235Smarkfen consumed += rtn; 8584235Smarkfen 8594235Smarkfen return (consumed); 8604235Smarkfen } 8614235Smarkfen 8624235Smarkfen /* 8634235Smarkfen * Preshared key field types...used for parsing preshared keys that 8644235Smarkfen * have been entered on the command line. The code to parse preshared 8654235Smarkfen * keys (parse_ps, parse_key, parse_psfldid, parse_ikmtype, ...) is 8664235Smarkfen * mostly duplicated from in.iked's readps.c. 8674235Smarkfen */ 8684235Smarkfen #define PSFLD_LOCID 1 8694235Smarkfen #define PSFLD_LOCIDTYPE 2 8704235Smarkfen #define PSFLD_REMID 3 8714235Smarkfen #define PSFLD_REMIDTYPE 4 8724235Smarkfen #define PSFLD_MODE 5 8734235Smarkfen #define PSFLD_KEY 6 8744235Smarkfen 8754235Smarkfen static keywdtab_t psfldtypes[] = { 8764235Smarkfen {PSFLD_LOCID, "localid"}, 8774235Smarkfen {PSFLD_LOCIDTYPE, "localidtype"}, 8784235Smarkfen {PSFLD_REMID, "remoteid"}, 8794235Smarkfen {PSFLD_REMIDTYPE, "remoteidtype"}, 8804235Smarkfen {PSFLD_MODE, "ike_mode"}, 8814235Smarkfen {PSFLD_KEY, "key"}, 8824235Smarkfen {NULL, 0} 8834235Smarkfen }; 8844235Smarkfen 8854235Smarkfen static int 8864235Smarkfen parse_psfldid(char *type, uint16_t *idnum) 8874235Smarkfen { 8884235Smarkfen keywdtab_t *pfp; 8894235Smarkfen 8904235Smarkfen if (type == NULL) 8914235Smarkfen return (-1); 8924235Smarkfen 8934235Smarkfen for (pfp = psfldtypes; pfp->kw_str != NULL; pfp++) { 8944235Smarkfen if (strcasecmp(pfp->kw_str, type) == 0) { 8954235Smarkfen if (idnum != NULL) 8964235Smarkfen *idnum = pfp->kw_tag; 8974235Smarkfen return (1); 8984235Smarkfen } 8994235Smarkfen } 9004235Smarkfen 9014235Smarkfen return (-1); 9024235Smarkfen } 9034235Smarkfen 9044235Smarkfen static keywdtab_t ikemodes[] = { 9054235Smarkfen {IKE_XCHG_IDENTITY_PROTECT, "main"}, 9064235Smarkfen {IKE_XCHG_AGGRESSIVE, "aggressive"}, 9074235Smarkfen {IKE_XCHG_IP_AND_AGGR, "both"}, 9084235Smarkfen {NULL, 0} 9094235Smarkfen }; 9104235Smarkfen 9114235Smarkfen static int 9124235Smarkfen parse_ikmtype(char *mode, uint16_t *modenum) 9134235Smarkfen { 9144235Smarkfen keywdtab_t *ikmp; 9154235Smarkfen 9164235Smarkfen if (mode == NULL) 9174235Smarkfen return (-1); 9184235Smarkfen 9194235Smarkfen for (ikmp = ikemodes; ikmp->kw_str != NULL; ikmp++) { 9204235Smarkfen if (strcasecmp(ikmp->kw_str, mode) == 0) { 9214235Smarkfen if (modenum != NULL) 9224235Smarkfen *modenum = ikmp->kw_tag; 9234235Smarkfen return (1); 9244235Smarkfen } 9254235Smarkfen } 9264235Smarkfen 9274235Smarkfen return (-1); 9284235Smarkfen } 9294235Smarkfen 9304235Smarkfen #define hd2num(hd) (((hd) >= '0' && (hd) <= '9') ? ((hd) - '0') : \ 9314235Smarkfen (((hd) >= 'a' && (hd) <= 'f') ? ((hd) - 'a' + 10) : ((hd) - 'A' + 10))) 9324235Smarkfen 9334235Smarkfen static uint8_t * 9344235Smarkfen parse_key(char *input, uint_t *keybuflen, uint_t *lbits) 9354235Smarkfen { 9364235Smarkfen uint8_t *keyp, *keybufp; 9374235Smarkfen uint_t i, hexlen = 0, bits, alloclen; 9384235Smarkfen 9394235Smarkfen for (i = 0; input[i] != '\0' && input[i] != '/'; i++) 9404235Smarkfen hexlen++; 9414235Smarkfen 9424235Smarkfen if (input[i] == '\0') { 9434235Smarkfen bits = 0; 9444235Smarkfen } else { 9454235Smarkfen /* Have /nn. */ 9464235Smarkfen input[i] = '\0'; 9474235Smarkfen if (sscanf((input + i + 1), "%u", &bits) != 1) 9484235Smarkfen return (NULL); 9494235Smarkfen 9504235Smarkfen /* hexlen is in nibbles */ 9514235Smarkfen if (((bits + 3) >> 2) > hexlen) 9524235Smarkfen return (NULL); 9534235Smarkfen 9544235Smarkfen /* 9554235Smarkfen * Adjust hexlen down if user gave us too small of a bit 9564235Smarkfen * count. 9574235Smarkfen */ 9584235Smarkfen if ((hexlen << 2) > bits + 3) { 9594235Smarkfen hexlen = (bits + 3) >> 2; 9604235Smarkfen input[hexlen] = '\0'; 9614235Smarkfen } 9624235Smarkfen } 9634235Smarkfen 9644235Smarkfen /* 9654235Smarkfen * Allocate. Remember, hexlen is in nibbles. 9664235Smarkfen */ 9674235Smarkfen 9684235Smarkfen alloclen = (hexlen/2 + (hexlen & 0x1)); 9694235Smarkfen keyp = malloc(alloclen); 9704235Smarkfen 9714235Smarkfen if (keyp == NULL) 9724235Smarkfen return (NULL); 9734235Smarkfen 9744235Smarkfen keybufp = keyp; 9754235Smarkfen *keybuflen = alloclen; 9764235Smarkfen if (bits == 0) 9774235Smarkfen *lbits = (hexlen + (hexlen & 0x1)) << 2; 9784235Smarkfen else 9794235Smarkfen *lbits = bits; 9804235Smarkfen 9814235Smarkfen /* 9824235Smarkfen * Read in nibbles. Read in odd-numbered as shifted high. 9834235Smarkfen * (e.g. 123 becomes 0x1230). 9844235Smarkfen */ 9854235Smarkfen for (i = 0; input[i] != '\0'; i += 2) { 9864235Smarkfen boolean_t second = (input[i + 1] != '\0'); 9874235Smarkfen 9884235Smarkfen if (!isxdigit(input[i]) || 9894235Smarkfen (!isxdigit(input[i + 1]) && second)) { 9904235Smarkfen free(keyp); 9914235Smarkfen return (NULL); 9924235Smarkfen } 9934235Smarkfen *keyp = (hd2num(input[i]) << 4); 9944235Smarkfen if (second) 9954235Smarkfen *keyp |= hd2num(input[i + 1]); 9964235Smarkfen else 9974235Smarkfen break; /* out of for loop. */ 9984235Smarkfen keyp++; 9994235Smarkfen } 10004235Smarkfen 10014235Smarkfen /* zero the remaining bits if we're a non-octet amount. */ 10024235Smarkfen if (bits & 0x7) 10034235Smarkfen *((input[i] == '\0') ? keyp - 1 : keyp) &= 10044235Smarkfen 0xff << (8 - (bits & 0x7)); 10054235Smarkfen return (keybufp); 10064235Smarkfen } 10074235Smarkfen 10084235Smarkfen /* 10094235Smarkfen * the ike_ps_t struct (plus trailing data) will be allocated here, 10104235Smarkfen * so it will need to be freed by the caller. 10114235Smarkfen */ 10124235Smarkfen static int 10134235Smarkfen parse_ps(int argc, char **argv, ike_ps_t **presharedpp, int *len) 10144235Smarkfen { 10154235Smarkfen uint_t c = 0, locidlen, remidlen, keylen, keybits; 10164235Smarkfen uint_t a_locidtotal = 0, a_remidtotal = 0; 10174235Smarkfen char *locid, *remid; 10184235Smarkfen uint8_t *keyp = NULL; 10194235Smarkfen uint16_t fldid, locidtype, remidtype, mtype; 10204235Smarkfen struct hostent *loche = NULL, *remhe = NULL; 10214235Smarkfen ike_ps_t *psp = NULL; 10224235Smarkfen sadb_ident_t *sidp; 10234235Smarkfen boolean_t whacked = B_FALSE; 10244235Smarkfen 10254235Smarkfen if ((argv[c] == NULL) || (argv[c][0] != '{')) 10264235Smarkfen return (-1); 10274235Smarkfen if (argv[c][1] != 0) { 10284235Smarkfen /* no space between '{' and first token */ 10294235Smarkfen argv[c]++; 10304235Smarkfen } else { 10314235Smarkfen c++; 10324235Smarkfen } 10334235Smarkfen if ((argv[argc - 1][strlen(argv[argc - 1]) - 1] == '}') && 10344235Smarkfen (argv[argc - 1][0] != '}')) { 10354235Smarkfen /* 10364235Smarkfen * whack '}' without a space before it or parsers break. 10374235Smarkfen * Remember this trailing character for later 10384235Smarkfen */ 10394235Smarkfen argv[argc - 1][strlen(argv[argc - 1]) - 1] = '\0'; 10404235Smarkfen whacked = B_TRUE; 10414235Smarkfen } 10424235Smarkfen 10434235Smarkfen while ((c < argc) && (argv[c] != NULL) && (argv[c][0] != '}')) { 10444235Smarkfen if ((argv[c + 1] == NULL) || (argv[c + 1][0] == '}')) 10454235Smarkfen goto bail; 10464235Smarkfen if (parse_psfldid(argv[c++], &fldid) < 0) 10474235Smarkfen goto bail; 10484235Smarkfen switch (fldid) { 10494235Smarkfen case PSFLD_LOCID: 10504235Smarkfen locid = argv[c++]; 10514235Smarkfen locidlen = strlen(locid) + 1; 10524235Smarkfen break; 10534235Smarkfen case PSFLD_LOCIDTYPE: 10544235Smarkfen if (parse_idtype(argv[c++], &locidtype) < 0) 10554235Smarkfen goto bail; 10564235Smarkfen break; 10574235Smarkfen case PSFLD_REMID: 10584235Smarkfen remid = argv[c++]; 10594235Smarkfen remidlen = strlen(remid) + 1; 10604235Smarkfen break; 10614235Smarkfen case PSFLD_REMIDTYPE: 10624235Smarkfen if (parse_idtype(argv[c++], &remidtype) < 0) 10634235Smarkfen goto bail; 10644235Smarkfen break; 10654235Smarkfen case PSFLD_MODE: 10664235Smarkfen if (parse_ikmtype(argv[c++], &mtype) < 0) 10674235Smarkfen goto bail; 10684235Smarkfen break; 10694235Smarkfen case PSFLD_KEY: 10704235Smarkfen keyp = parse_key(argv[c++], &keylen, &keybits); 10714235Smarkfen if (keyp == NULL) 10724235Smarkfen goto bail; 10734235Smarkfen break; 10744235Smarkfen } 10754235Smarkfen } 10764235Smarkfen 10774235Smarkfen /* Make sure the line was terminated with '}' */ 10784235Smarkfen if (argv[c] == NULL) { 10794235Smarkfen if (!whacked) 10804235Smarkfen goto bail; 10814235Smarkfen } else if (argv[c][0] != '}') { 10824235Smarkfen goto bail; 10834235Smarkfen } 10844235Smarkfen 10854235Smarkfen /* 10864235Smarkfen * make sure we got all the required fields. If no idtype, assume 10874235Smarkfen * ip addr; if that translation fails, we'll catch the error then. 10884235Smarkfen */ 10894235Smarkfen if (locid == NULL || remid == NULL || keyp == NULL || mtype == 0) 10904235Smarkfen goto bail; 10914235Smarkfen 10924235Smarkfen /* figure out the size buffer we need */ 10934235Smarkfen *len = sizeof (ike_ps_t); 10944235Smarkfen if (locidtype != SADB_IDENTTYPE_RESERVED) { 10954235Smarkfen a_locidtotal = IKEDOORROUNDUP(sizeof (sadb_ident_t) + locidlen); 10964235Smarkfen *len += a_locidtotal; 10974235Smarkfen } 10984235Smarkfen if (remidtype != SADB_IDENTTYPE_RESERVED) { 10994235Smarkfen a_remidtotal = IKEDOORROUNDUP(sizeof (sadb_ident_t) + remidlen); 11004235Smarkfen *len += a_remidtotal; 11014235Smarkfen } 11024235Smarkfen *len += keylen; 11034235Smarkfen 11044235Smarkfen psp = malloc(*len); 11054235Smarkfen if (psp == NULL) 11064235Smarkfen goto bail; 11074235Smarkfen (void) memset(psp, 0, *len); 11084235Smarkfen 11094235Smarkfen psp->ps_ike_mode = mtype; 11104235Smarkfen 11114235Smarkfen psp->ps_localid_off = sizeof (ike_ps_t); 11124235Smarkfen if (locidtype == SADB_IDENTTYPE_RESERVED) { 11134235Smarkfen /* 11144235Smarkfen * this is an ip address, store in the sockaddr field; 11154235Smarkfen * we won't use an sadb_ident_t. 11164235Smarkfen */ 11174235Smarkfen psp->ps_localid_len = 0; 11184235Smarkfen if (parse_addr(1, &locid, &loche) < 0) 11194235Smarkfen goto bail; 11204235Smarkfen if (loche->h_addr_list[1] != NULL) { 11214235Smarkfen message(gettext("preshared key identifier cannot " 11224235Smarkfen "match multiple IP addresses")); 11234235Smarkfen goto bail; 11244235Smarkfen } 11254235Smarkfen headdr2sa(loche->h_addr_list[0], &psp->ps_ipaddrs.loc_addr, 11264235Smarkfen loche->h_length); 11274235Smarkfen FREE_HE(loche); 11284235Smarkfen } else { 11294235Smarkfen psp->ps_localid_len = sizeof (sadb_ident_t) + locidlen; 11304235Smarkfen sidp = (sadb_ident_t *)((int)psp + psp->ps_localid_off); 11314235Smarkfen sidp->sadb_ident_len = psp->ps_localid_len; 11324235Smarkfen sidp->sadb_ident_type = locidtype; 11334235Smarkfen (void) strlcpy((char *)(sidp + 1), locid, a_locidtotal); 11344235Smarkfen } 11354235Smarkfen 11364235Smarkfen psp->ps_remoteid_off = psp->ps_localid_off + a_locidtotal; 11374235Smarkfen if (remidtype == SADB_IDENTTYPE_RESERVED) { 11384235Smarkfen /* 11394235Smarkfen * this is an ip address, store in the sockaddr field; 11404235Smarkfen * we won't use an sadb_ident_t. 11414235Smarkfen */ 11424235Smarkfen psp->ps_remoteid_len = 0; 11434235Smarkfen if (parse_addr(1, &remid, &remhe) < 0) 11444235Smarkfen goto bail; 11454235Smarkfen if (remhe->h_addr_list[1] != NULL) { 11464235Smarkfen message(gettext("preshared key identifier cannot " 11474235Smarkfen "match multiple IP addresses")); 11484235Smarkfen goto bail; 11494235Smarkfen } 11504235Smarkfen headdr2sa(remhe->h_addr_list[0], &psp->ps_ipaddrs.rem_addr, 11514235Smarkfen remhe->h_length); 11524235Smarkfen FREE_HE(remhe); 11534235Smarkfen } else { 11544235Smarkfen /* make sure we have at least 16-bit alignment */ 11554235Smarkfen if (remidlen & 0x1) 11564235Smarkfen remidlen++; 11574235Smarkfen psp->ps_remoteid_len = sizeof (sadb_ident_t) + remidlen; 11584235Smarkfen sidp = (sadb_ident_t *)((int)psp + psp->ps_remoteid_off); 11594235Smarkfen sidp->sadb_ident_len = psp->ps_remoteid_len; 11604235Smarkfen sidp->sadb_ident_type = remidtype; 11614235Smarkfen (void) strlcpy((char *)(sidp + 1), remid, a_remidtotal); 11624235Smarkfen } 11634235Smarkfen 11644235Smarkfen psp->ps_key_off = psp->ps_remoteid_off + a_remidtotal; 11654235Smarkfen psp->ps_key_len = keylen; 11664235Smarkfen psp->ps_key_bits = keybits; 11674235Smarkfen (void) memcpy((uint8_t *)((int)psp + psp->ps_key_off), keyp, keylen); 11684235Smarkfen 11694235Smarkfen *presharedpp = psp; 11704235Smarkfen 11714235Smarkfen return (c); 11724235Smarkfen 11734235Smarkfen bail: 11744235Smarkfen if (loche != NULL) 11754235Smarkfen FREE_HE(loche); 11764235Smarkfen if (remhe != NULL) 11774235Smarkfen FREE_HE(remhe); 11784235Smarkfen if (keyp != NULL) 11794235Smarkfen free(keyp); 11804235Smarkfen if (psp != NULL) 11814235Smarkfen free(psp); 11824235Smarkfen 11834235Smarkfen *presharedpp = NULL; 11844235Smarkfen 11854235Smarkfen return (-1); 11864235Smarkfen } 11874235Smarkfen 11884235Smarkfen /* 11894235Smarkfen * Printing functions 11904235Smarkfen * 11914235Smarkfen * A potential point of confusion here is that the ikeadm-specific string- 11924235Smarkfen * producing functions do not match the ipsec_util.c versions in style: the 11934235Smarkfen * ikeadm-specific functions return a string (and are named foostr), while 11944235Smarkfen * the ipsec_util.c functions actually print the string to the file named 11954235Smarkfen * in the second arg to the function (and are named dump_foo). 11964235Smarkfen * 11977421SDaniel.Anderson@Sun.COM * Localization for ikeadm seems more straightforward when complete 11987421SDaniel.Anderson@Sun.COM * phrases are translated rather than: a part of a phrase, a call to 11997421SDaniel.Anderson@Sun.COM * dump_foo(), and more of the phrase. It could also accommodate 12007421SDaniel.Anderson@Sun.COM * non-English grammar more easily. 12014235Smarkfen */ 12024235Smarkfen 12034235Smarkfen static char * 12044235Smarkfen errstr(int err) 12054235Smarkfen { 12064235Smarkfen static char rtn[MAXLINESIZE]; 12074235Smarkfen 12084235Smarkfen switch (err) { 12094235Smarkfen case IKE_ERR_NO_OBJ: 12104235Smarkfen return (gettext("No data returned")); 12114235Smarkfen case IKE_ERR_NO_DESC: 12124235Smarkfen return (gettext("No destination provided")); 12134235Smarkfen case IKE_ERR_ID_INVALID: 12144235Smarkfen return (gettext("Id info invalid")); 12154235Smarkfen case IKE_ERR_LOC_INVALID: 12164235Smarkfen return (gettext("Destination invalid")); 12174235Smarkfen case IKE_ERR_CMD_INVALID: 12184235Smarkfen return (gettext("Command invalid")); 12194235Smarkfen case IKE_ERR_DATA_INVALID: 12204235Smarkfen return (gettext("Supplied data invalid")); 12214235Smarkfen case IKE_ERR_CMD_NOTSUP: 12224235Smarkfen return (gettext("Unknown command")); 12234235Smarkfen case IKE_ERR_REQ_INVALID: 12244235Smarkfen return (gettext("Request invalid")); 12254235Smarkfen case IKE_ERR_NO_PRIV: 12264235Smarkfen return (gettext("Not allowed at current privilege level")); 1227*8596SPaul.Wernau@Sun.COM case IKE_ERR_NO_AUTH: 1228*8596SPaul.Wernau@Sun.COM return (gettext("User not authorized")); 12294235Smarkfen case IKE_ERR_SYS_ERR: 12304235Smarkfen return (gettext("System error")); 12314235Smarkfen case IKE_ERR_DUP_IGNORED: 12324235Smarkfen return (gettext("One or more duplicate entries ignored")); 1233*8596SPaul.Wernau@Sun.COM case IKE_ERR_NO_TOKEN: 1234*8596SPaul.Wernau@Sun.COM return (gettext( 1235*8596SPaul.Wernau@Sun.COM "token login failed or no objects on device")); 1236*8596SPaul.Wernau@Sun.COM case IKE_ERR_IN_PROGRESS: 1237*8596SPaul.Wernau@Sun.COM return (gettext( 1238*8596SPaul.Wernau@Sun.COM "Duplicate operation already in progress")); 1239*8596SPaul.Wernau@Sun.COM case IKE_ERR_NO_MEM: 1240*8596SPaul.Wernau@Sun.COM return (gettext( 1241*8596SPaul.Wernau@Sun.COM "Insufficient memory")); 12424235Smarkfen default: 12434235Smarkfen (void) snprintf(rtn, MAXLINESIZE, 12444235Smarkfen gettext("<unknown error %d>"), err); 12454235Smarkfen return (rtn); 12464235Smarkfen } 12474235Smarkfen } 12484235Smarkfen 12494235Smarkfen static char * 12504235Smarkfen dbgstr(int bit) 12514235Smarkfen { 12524235Smarkfen static char rtn[MAXLINESIZE]; 12534235Smarkfen 12544235Smarkfen switch (bit) { 12554235Smarkfen case D_CERT: 12564235Smarkfen return (gettext("Certificate management")); 12574235Smarkfen case D_KEY: 12584235Smarkfen return (gettext("Key management")); 12594235Smarkfen case D_OP: 12604235Smarkfen return (gettext("Operational")); 12614235Smarkfen case D_P1: 12624235Smarkfen return (gettext("Phase 1 SA creation")); 12634235Smarkfen case D_P2: 12644235Smarkfen return (gettext("Phase 2 SA creation")); 12654235Smarkfen case D_PFKEY: 12664235Smarkfen return (gettext("PF_KEY interface")); 12674235Smarkfen case D_POL: 12684235Smarkfen return (gettext("Policy management")); 12694235Smarkfen case D_PROP: 12704235Smarkfen return (gettext("Proposal construction")); 12714235Smarkfen case D_DOOR: 12724235Smarkfen return (gettext("Door interface")); 12734235Smarkfen case D_CONFIG: 12744235Smarkfen return (gettext("Config file processing")); 12754235Smarkfen default: 12764235Smarkfen (void) snprintf(rtn, MAXLINESIZE, 12774235Smarkfen gettext("<unknown flag 0x%x>"), bit); 12784235Smarkfen return (rtn); 12794235Smarkfen } 12804235Smarkfen } 12814235Smarkfen 12824235Smarkfen static char * 12834235Smarkfen privstr(int priv) 12844235Smarkfen { 12854235Smarkfen static char rtn[MAXLINESIZE]; 12864235Smarkfen 12874235Smarkfen switch (priv) { 12884235Smarkfen case IKE_PRIV_MINIMUM: 12894235Smarkfen return (gettext("base privileges")); 12904235Smarkfen case IKE_PRIV_MODKEYS: 12914235Smarkfen return (gettext("access to preshared key information")); 12924235Smarkfen case IKE_PRIV_KEYMAT: 12934235Smarkfen return (gettext("access to keying material")); 12944235Smarkfen default: 12954235Smarkfen (void) snprintf(rtn, MAXLINESIZE, 12964235Smarkfen gettext("<unknown level %d>"), priv); 12974235Smarkfen return (rtn); 12984235Smarkfen } 12994235Smarkfen } 13004235Smarkfen 13014235Smarkfen static char * 13024235Smarkfen xchgstr(int xchg) 13034235Smarkfen { 13044235Smarkfen static char rtn[MAXLINESIZE]; 13054235Smarkfen 13064235Smarkfen switch (xchg) { 13074235Smarkfen case IKE_XCHG_NONE: 13084235Smarkfen return (gettext("<unspecified>")); 13094235Smarkfen case IKE_XCHG_BASE: 13104235Smarkfen return (gettext("base")); 13114235Smarkfen case IKE_XCHG_IDENTITY_PROTECT: 13124235Smarkfen return (gettext("main mode (identity protect)")); 13134235Smarkfen case IKE_XCHG_AUTH_ONLY: 13144235Smarkfen return (gettext("authentication only")); 13154235Smarkfen case IKE_XCHG_AGGRESSIVE: 13164235Smarkfen return (gettext("aggressive mode")); 13174235Smarkfen case IKE_XCHG_IP_AND_AGGR: 13184235Smarkfen return (gettext("main and aggressive mode")); 13194235Smarkfen case IKE_XCHG_ANY: 13204235Smarkfen return (gettext("any mode")); 13214235Smarkfen default: 13224235Smarkfen (void) snprintf(rtn, MAXLINESIZE, 13234235Smarkfen gettext("<unknown %d>"), xchg); 13244235Smarkfen return (rtn); 13254235Smarkfen } 13264235Smarkfen } 13274235Smarkfen 13284235Smarkfen static char * 13294235Smarkfen statestr(int state) 13304235Smarkfen { 13314235Smarkfen static char rtn[MAXLINESIZE]; 13324235Smarkfen 13334235Smarkfen switch (state) { 13344235Smarkfen case IKE_SA_STATE_INIT: 13354235Smarkfen return (gettext("INITIALIZING")); 13364235Smarkfen case IKE_SA_STATE_SENT_SA: 13374235Smarkfen return (gettext("SENT FIRST MSG (SA)")); 13384235Smarkfen case IKE_SA_STATE_SENT_KE: 13394235Smarkfen return (gettext("SENT SECOND MSG (KE)")); 13404235Smarkfen case IKE_SA_STATE_SENT_LAST: 13414235Smarkfen return (gettext("SENT FINAL MSG")); 13424235Smarkfen case IKE_SA_STATE_DONE: 13434235Smarkfen return (gettext("ACTIVE")); 13444235Smarkfen case IKE_SA_STATE_DELETED: 13454235Smarkfen return (gettext("DELETED")); 13464235Smarkfen case IKE_SA_STATE_INVALID: 13474235Smarkfen return (gettext("<invalid>")); 13484235Smarkfen default: 13494235Smarkfen (void) snprintf(rtn, MAXLINESIZE, 13504235Smarkfen gettext("<unknown %d>"), state); 13514235Smarkfen return (rtn); 13524235Smarkfen } 13534235Smarkfen } 13544235Smarkfen 13554235Smarkfen static char * 13564235Smarkfen authmethstr(int meth) 13574235Smarkfen { 13584235Smarkfen static char rtn[MAXLINESIZE]; 13594235Smarkfen 13604235Smarkfen switch (meth) { 13614235Smarkfen case IKE_AUTH_METH_PRE_SHARED_KEY: 13624235Smarkfen return (gettext("pre-shared key")); 13634235Smarkfen case IKE_AUTH_METH_DSS_SIG: 13644235Smarkfen return (gettext("DSS signatures")); 13654235Smarkfen case IKE_AUTH_METH_RSA_SIG: 13664235Smarkfen return (gettext("RSA signatures")); 13674235Smarkfen case IKE_AUTH_METH_RSA_ENCR: 13684235Smarkfen return (gettext("RSA Encryption")); 13694235Smarkfen case IKE_AUTH_METH_RSA_ENCR_REVISED: 13704235Smarkfen return (gettext("Revised RSA Encryption")); 13714235Smarkfen default: 13724235Smarkfen (void) snprintf(rtn, MAXLINESIZE, 13734235Smarkfen gettext("<unknown %d>"), meth); 13744235Smarkfen return (rtn); 13754235Smarkfen } 13764235Smarkfen } 13774235Smarkfen 13784235Smarkfen static char * 13794235Smarkfen prfstr(int prf) 13804235Smarkfen { 13814235Smarkfen static char rtn[MAXLINESIZE]; 13824235Smarkfen 13834235Smarkfen switch (prf) { 13844235Smarkfen case IKE_PRF_NONE: 13856209Spwernau return (gettext("<none/unavailable>")); 13864235Smarkfen case IKE_PRF_HMAC_MD5: 13874235Smarkfen return ("HMAC MD5"); 13884235Smarkfen case IKE_PRF_HMAC_SHA1: 13894235Smarkfen return ("HMAC SHA1"); 13906126Sdanmcd case IKE_PRF_HMAC_SHA256: 13916126Sdanmcd return ("HMAC SHA256"); 13926126Sdanmcd case IKE_PRF_HMAC_SHA384: 13936126Sdanmcd return ("HMAC SHA384"); 13946126Sdanmcd case IKE_PRF_HMAC_SHA512: 13956126Sdanmcd return ("HMAC SHA512"); 13964235Smarkfen default: 13974235Smarkfen (void) snprintf(rtn, MAXLINESIZE, 13984235Smarkfen gettext("<unknown %d>"), prf); 13994235Smarkfen return (rtn); 14004235Smarkfen } 14014235Smarkfen } 14024235Smarkfen 14034235Smarkfen static char * 14044235Smarkfen dhstr(int grp) 14054235Smarkfen { 14064235Smarkfen static char rtn[MAXLINESIZE]; 14074235Smarkfen 14084235Smarkfen switch (grp) { 14094235Smarkfen case 0: 14104731Smarkfen return (gettext("<unavailable>")); 14114235Smarkfen case IKE_GRP_DESC_MODP_768: 14124731Smarkfen return (gettext("768-bit MODP (group 1)")); 14134235Smarkfen case IKE_GRP_DESC_MODP_1024: 14144731Smarkfen return (gettext("1024-bit MODP (group 2)")); 14154235Smarkfen case IKE_GRP_DESC_EC2N_155: 14164235Smarkfen return (gettext("EC2N group on GP[2^155]")); 14174235Smarkfen case IKE_GRP_DESC_EC2N_185: 14184235Smarkfen return (gettext("EC2N group on GP[2^185]")); 14194235Smarkfen case IKE_GRP_DESC_MODP_1536: 14204731Smarkfen return (gettext("1536-bit MODP (group 5)")); 14214731Smarkfen case IKE_GRP_DESC_MODP_2048: 14224731Smarkfen return (gettext("2048-bit MODP (group 14)")); 14234731Smarkfen case IKE_GRP_DESC_MODP_3072: 14244731Smarkfen return (gettext("3072-bit MODP (group 15)")); 14254731Smarkfen case IKE_GRP_DESC_MODP_4096: 14264731Smarkfen return (gettext("4096-bit MODP (group 16)")); 14274731Smarkfen case IKE_GRP_DESC_MODP_6144: 14284731Smarkfen return (gettext("6144-bit MODP (group 17)")); 14294731Smarkfen case IKE_GRP_DESC_MODP_8192: 14304731Smarkfen return (gettext("8192-bit MODP (group 18)")); 14314235Smarkfen default: 14324235Smarkfen (void) snprintf(rtn, MAXLINESIZE, gettext("<unknown %d>"), grp); 14334235Smarkfen return (rtn); 14344235Smarkfen } 14354235Smarkfen } 14364235Smarkfen 14374235Smarkfen static void 14384235Smarkfen print_hdr(char *prefix, ike_p1_hdr_t *hdrp) 14394235Smarkfen { 14407749SThejaswini.Singarajipura@Sun.COM char sbuf[TBUF_SIZE]; 14417749SThejaswini.Singarajipura@Sun.COM char tbuf[TBUF_SIZE]; 14427749SThejaswini.Singarajipura@Sun.COM 14434235Smarkfen (void) printf( 14444235Smarkfen gettext("%s Cookies: Initiator 0x%llx Responder 0x%llx\n"), 14457421SDaniel.Anderson@Sun.COM prefix, ntohll(hdrp->p1hdr_cookies.cky_i), 14467421SDaniel.Anderson@Sun.COM ntohll(hdrp->p1hdr_cookies.cky_r)); 14474235Smarkfen (void) printf(gettext("%s The local host is the %s.\n"), prefix, 14484235Smarkfen hdrp->p1hdr_isinit ? gettext("initiator") : gettext("responder")); 14494235Smarkfen (void) printf(gettext("%s ISAKMP version %d.%d; %s exchange\n"), prefix, 14504235Smarkfen hdrp->p1hdr_major, hdrp->p1hdr_minor, xchgstr(hdrp->p1hdr_xchg)); 14517749SThejaswini.Singarajipura@Sun.COM (void) printf(gettext("%s Current state is %s\n"), prefix, 14524235Smarkfen statestr(hdrp->p1hdr_state)); 14537749SThejaswini.Singarajipura@Sun.COM if (hdrp->p1hdr_support_dpd == B_FALSE) { 14547749SThejaswini.Singarajipura@Sun.COM return; 14557749SThejaswini.Singarajipura@Sun.COM } 14567749SThejaswini.Singarajipura@Sun.COM (void) printf(gettext("%s Dead Peer Detection (RFC 3706)" 14577749SThejaswini.Singarajipura@Sun.COM " enabled"), prefix); 14587749SThejaswini.Singarajipura@Sun.COM if (hdrp->p1hdr_dpd_state < DPD_IN_PROGRESS) { 14597749SThejaswini.Singarajipura@Sun.COM (void) printf("\n"); 14607749SThejaswini.Singarajipura@Sun.COM return; 14617749SThejaswini.Singarajipura@Sun.COM } 14627749SThejaswini.Singarajipura@Sun.COM if (strftime(tbuf, TBUF_SIZE, NULL, 14637749SThejaswini.Singarajipura@Sun.COM localtime(&hdrp->p1hdr_dpd_time)) == 0) { 14647749SThejaswini.Singarajipura@Sun.COM (void) strlcpy(tbuf, gettext("<time conversion failed>"), 14657749SThejaswini.Singarajipura@Sun.COM TBUF_SIZE); 14667749SThejaswini.Singarajipura@Sun.COM } 14677749SThejaswini.Singarajipura@Sun.COM (void) printf(gettext("\n%s Dead Peer Detection handshake "), prefix); 14687749SThejaswini.Singarajipura@Sun.COM switch (hdrp->p1hdr_dpd_state) { 14697749SThejaswini.Singarajipura@Sun.COM case DPD_SUCCESSFUL: 14707749SThejaswini.Singarajipura@Sun.COM (void) strlcpy(sbuf, gettext("was successful at "), TBUF_SIZE); 14717749SThejaswini.Singarajipura@Sun.COM break; 14727749SThejaswini.Singarajipura@Sun.COM case DPD_FAILURE: 14737749SThejaswini.Singarajipura@Sun.COM (void) strlcpy(sbuf, gettext("failed at "), TBUF_SIZE); 14747749SThejaswini.Singarajipura@Sun.COM break; 14757749SThejaswini.Singarajipura@Sun.COM case DPD_IN_PROGRESS: 14767749SThejaswini.Singarajipura@Sun.COM (void) strlcpy(sbuf, gettext("is in progress."), TBUF_SIZE); 14777749SThejaswini.Singarajipura@Sun.COM break; 14787749SThejaswini.Singarajipura@Sun.COM } 14798185Sdanmcd@sun.com (void) printf("%s %s", sbuf, 14808185Sdanmcd@sun.com (hdrp->p1hdr_dpd_state == DPD_IN_PROGRESS) ? "" : tbuf); 14814235Smarkfen (void) printf("\n"); 14824235Smarkfen } 14834235Smarkfen 14844235Smarkfen static void 14854235Smarkfen print_lt_limits(char *prefix, ike_p1_xform_t *xfp) 14864235Smarkfen { 14874235Smarkfen (void) printf(gettext("%s Lifetime limits:\n"), prefix); 14884235Smarkfen (void) printf(gettext("%s %u seconds; %u kbytes protected; "), 14894235Smarkfen prefix, xfp->p1xf_max_secs, xfp->p1xf_max_kbytes); 14904235Smarkfen (void) printf(gettext("%u keymat provided.\n"), xfp->p1xf_max_keyuses); 14914235Smarkfen } 14924235Smarkfen 14934235Smarkfen #define LT_USAGE_LEN 16 /* 1 uint64 + 2 uint32s */ 14944235Smarkfen static void 14954235Smarkfen print_lt_usage(char *prefix, ike_p1_stats_t *sp) 14964235Smarkfen { 14974235Smarkfen time_t scratch; 14984235Smarkfen char tbuf[TBUF_SIZE]; 14994235Smarkfen 15004235Smarkfen (void) printf(gettext("%s Current usage:\n"), prefix); 15014235Smarkfen scratch = (time_t)sp->p1stat_start; 15024235Smarkfen if (strftime(tbuf, TBUF_SIZE, NULL, localtime(&scratch)) == 0) 15034235Smarkfen (void) strlcpy(tbuf, gettext("<time conversion failed>"), 15044235Smarkfen TBUF_SIZE); 15054235Smarkfen (void) printf(gettext("%s SA was created at %s\n"), prefix, tbuf); 15064235Smarkfen (void) printf(gettext("%s %u kbytes protected; %u keymat provided.\n"), 15074235Smarkfen prefix, sp->p1stat_kbytes, sp->p1stat_keyuses); 15084235Smarkfen } 15094235Smarkfen 15104235Smarkfen static void 15114235Smarkfen print_xform(char *prefix, ike_p1_xform_t *xfp, boolean_t print_lifetimes) 15124235Smarkfen { 15134235Smarkfen (void) printf(gettext("%s Authentication method: %s"), prefix, 15144235Smarkfen authmethstr(xfp->p1xf_auth_meth)); 15154235Smarkfen (void) printf(gettext("\n%s Encryption alg: "), prefix); 15164235Smarkfen (void) dump_ealg(xfp->p1xf_encr_alg, stdout); 15174235Smarkfen if (xfp->p1xf_encr_low_bits != 0) { 15184235Smarkfen (void) printf(gettext("(%d..%d)"), xfp->p1xf_encr_low_bits, 15194235Smarkfen xfp->p1xf_encr_high_bits); 15206209Spwernau } else if ((xfp->p1xf_encr_low_bits == 0) && 15216209Spwernau (xfp->p1xf_encr_high_bits != 0)) { 15226209Spwernau /* 15236209Spwernau * High bits is a placeholder for 15246209Spwernau * negotiated algorithm strength 15256209Spwernau */ 15266209Spwernau (void) printf(gettext("(%d)"), xfp->p1xf_encr_high_bits); 15274235Smarkfen } 15284235Smarkfen (void) printf(gettext("; Authentication alg: ")); 15294235Smarkfen (void) dump_aalg(xfp->p1xf_auth_alg, stdout); 15306209Spwernau (void) printf("\n%s ", prefix); 15316209Spwernau if (xfp->p1xf_prf != 0) 15326209Spwernau (void) printf(gettext("PRF: %s ; "), prfstr(xfp->p1xf_prf)); 15336209Spwernau (void) printf(gettext("Oakley Group: %s\n"), 15344235Smarkfen dhstr(xfp->p1xf_dh_group)); 15354235Smarkfen if (xfp->p1xf_pfs == 0) { 15364235Smarkfen (void) printf(gettext("%s Phase 2 PFS is not used\n"), prefix); 15374235Smarkfen } else { 15384235Smarkfen (void) printf(gettext( 15394235Smarkfen "%s Phase 2 PFS is required (Oakley Group: %s)\n"), 15404235Smarkfen prefix, dhstr(xfp->p1xf_pfs)); 15414235Smarkfen } 15424235Smarkfen 15434235Smarkfen if (print_lifetimes) 15444235Smarkfen print_lt_limits(prefix, xfp); 15454235Smarkfen } 15464235Smarkfen 15474235Smarkfen static void 15484235Smarkfen print_lifetime(char *prefix, ike_p1_xform_t *xfp, ike_p1_stats_t *sp, 15494235Smarkfen int statlen) 15504235Smarkfen { 15514235Smarkfen time_t current, remain, exp; 15524235Smarkfen char tbuf[TBUF_SIZE]; 15534235Smarkfen 15544235Smarkfen current = time(NULL); 15554235Smarkfen 15564235Smarkfen print_lt_limits(prefix, xfp); 15574235Smarkfen 15584235Smarkfen /* 15594235Smarkfen * make sure the stats struct we've been passed is as big 15604235Smarkfen * as we expect it to be. The usage stats are at the end, 15614235Smarkfen * so anything less than the size we expect won't work. 15624235Smarkfen */ 15634235Smarkfen if (statlen >= sizeof (ike_p1_stats_t)) { 15644235Smarkfen print_lt_usage(prefix, sp); 15654235Smarkfen } else { 15664235Smarkfen return; 15674235Smarkfen } 15684235Smarkfen 15694235Smarkfen (void) printf(gettext("%s Expiration info:\n"), prefix); 15704235Smarkfen 15714235Smarkfen if (xfp->p1xf_max_kbytes != 0) 15724235Smarkfen (void) printf(gettext("%s %u more bytes can be protected.\n"), 15734235Smarkfen prefix, xfp->p1xf_max_kbytes - sp->p1stat_kbytes); 15744235Smarkfen 15754235Smarkfen if (xfp->p1xf_max_keyuses != 0) 15764235Smarkfen (void) printf(gettext("%s Keying material can be provided " 15774235Smarkfen "%u more times.\n"), prefix, 15784235Smarkfen xfp->p1xf_max_keyuses - sp->p1stat_keyuses); 15794235Smarkfen 15804235Smarkfen if (xfp->p1xf_max_secs != 0) { 15814235Smarkfen exp = (time_t)sp->p1stat_start + (time_t)xfp->p1xf_max_secs; 15824235Smarkfen remain = exp - current; 15834235Smarkfen if (strftime(tbuf, TBUF_SIZE, NULL, localtime(&exp)) == 0) 15844235Smarkfen (void) strlcpy(tbuf, 15854235Smarkfen gettext("<time conversion failed>"), TBUF_SIZE); 15864235Smarkfen /* 15874235Smarkfen * The SA may have expired but still exist because libike 15884235Smarkfen * has not freed it yet. 15894235Smarkfen */ 15904235Smarkfen if (remain > 0) 15914235Smarkfen (void) printf(gettext( 15924235Smarkfen "%s SA expires in %lu seconds, at %s\n"), 15934235Smarkfen prefix, remain, tbuf); 15944235Smarkfen else 15954235Smarkfen (void) printf(gettext("%s SA Expired at %s\n"), 15964235Smarkfen prefix, tbuf); 15974235Smarkfen } 15984235Smarkfen } 15994235Smarkfen 16004235Smarkfen /* used to verify structure lengths... */ 16014235Smarkfen #define COUNTER_32BIT 4 16024235Smarkfen #define COUNTER_PAIR 8 16034235Smarkfen 16044235Smarkfen static void 16054235Smarkfen print_p1stats(char *prefix, ike_p1_stats_t *sp, int statlen, 16064235Smarkfen boolean_t print_lifetimes) 16074235Smarkfen { 16084235Smarkfen if (statlen < COUNTER_PAIR) 16094235Smarkfen return; 16104235Smarkfen (void) printf(gettext("%s %u Quick Mode SAs created; "), prefix, 16114235Smarkfen sp->p1stat_new_qm_sas); 16124235Smarkfen (void) printf(gettext("%u Quick Mode SAs deleted\n"), 16134235Smarkfen sp->p1stat_del_qm_sas); 16144235Smarkfen statlen -= COUNTER_PAIR; 16154235Smarkfen 16164235Smarkfen if ((print_lifetimes) && (statlen >= LT_USAGE_LEN)) 16174235Smarkfen print_lt_usage(prefix, sp); 16184235Smarkfen } 16194235Smarkfen 16204235Smarkfen static void 16214235Smarkfen print_errs(char *prefix, ike_p1_errors_t *errp, int errlen) 16224235Smarkfen { 16234235Smarkfen /* 16244235Smarkfen * Don't try to break this one up; it's either all or nothing! 16254235Smarkfen */ 16264235Smarkfen if (errlen < sizeof (ike_p1_errors_t)) 16274235Smarkfen return; 16284235Smarkfen 16294235Smarkfen (void) printf(gettext("%s %u RX errors: "), prefix, 16304235Smarkfen errp->p1err_decrypt + errp->p1err_hash + errp->p1err_otherrx); 16314235Smarkfen (void) printf(gettext("%u decryption, %u hash, %u other\n"), 16324235Smarkfen errp->p1err_decrypt, errp->p1err_hash, errp->p1err_otherrx); 16334235Smarkfen (void) printf(gettext("%s %u TX errors\n"), prefix, errp->p1err_tx); 16344235Smarkfen } 16354235Smarkfen 16364235Smarkfen static void 16374235Smarkfen print_addr_range(char *prefix, ike_addr_pr_t *pr) 16384235Smarkfen { 16394235Smarkfen boolean_t range = B_TRUE; 16404235Smarkfen struct sockaddr_storage *beg, *end; 16414235Smarkfen struct sockaddr_in *bsin, *esin; 16424235Smarkfen struct sockaddr_in6 *bsin6, *esin6; 16434235Smarkfen 16444235Smarkfen beg = &pr->beg_iprange; 16454235Smarkfen end = &pr->end_iprange; 16464235Smarkfen 16474235Smarkfen if (beg->ss_family != end->ss_family) { 16484235Smarkfen (void) printf(gettext("%s invalid address range\n"), prefix); 16494235Smarkfen return; 16504235Smarkfen } 16514235Smarkfen 16524235Smarkfen switch (beg->ss_family) { 16534235Smarkfen case AF_INET: 16544235Smarkfen bsin = (struct sockaddr_in *)beg; 16554235Smarkfen esin = (struct sockaddr_in *)end; 16564235Smarkfen if ((uint32_t)bsin->sin_addr.s_addr == 16574235Smarkfen (uint32_t)esin->sin_addr.s_addr) 16584235Smarkfen range = B_FALSE; 16594235Smarkfen break; 16604235Smarkfen case AF_INET6: 16614235Smarkfen bsin6 = (struct sockaddr_in6 *)beg; 16624235Smarkfen esin6 = (struct sockaddr_in6 *)end; 16634235Smarkfen if (IN6_ARE_ADDR_EQUAL(&bsin6->sin6_addr, &esin6->sin6_addr)) 16644235Smarkfen range = B_FALSE; 16654235Smarkfen break; 16664235Smarkfen default: 16674235Smarkfen (void) printf(gettext("%s invalid address range\n"), prefix); 16684235Smarkfen return; 16694235Smarkfen } 16704235Smarkfen 16714235Smarkfen (void) printf("%s ", prefix); 16724867Spwernau (void) dump_sockaddr((struct sockaddr *)beg, 0, B_TRUE, stdout, nflag); 16734235Smarkfen if (range) { 16744235Smarkfen (void) printf(" - "); 16754867Spwernau (void) dump_sockaddr((struct sockaddr *)end, 0, B_TRUE, stdout, 16764867Spwernau nflag); 16774235Smarkfen } 16784235Smarkfen (void) printf("\n"); 16794235Smarkfen 16804235Smarkfen } 16814235Smarkfen 16824235Smarkfen /* 16834235Smarkfen * used to tell printing function if info should be identified 16844235Smarkfen * as belonging to initiator, responder, or neither 16854235Smarkfen */ 16864235Smarkfen #define IS_INITIATOR 1 16874235Smarkfen #define IS_RESPONDER 2 16884235Smarkfen #define DONT_PRINT_INIT 3 16894235Smarkfen 16904235Smarkfen static void 16914235Smarkfen print_addr(char *prefix, struct sockaddr_storage *sa, int init_instr) 16924235Smarkfen { 16934235Smarkfen (void) printf(gettext("%s Address"), prefix); 16944235Smarkfen 16954235Smarkfen if (init_instr != DONT_PRINT_INIT) 16964235Smarkfen (void) printf(" (%s):\n", (init_instr == IS_INITIATOR) ? 16974235Smarkfen gettext("Initiator") : gettext("Responder")); 16984235Smarkfen else 16994235Smarkfen (void) printf(":\n"); 17004235Smarkfen 17014235Smarkfen (void) printf("%s ", prefix); 17024867Spwernau (void) dump_sockaddr((struct sockaddr *)sa, 0, B_FALSE, stdout, nflag); 17034235Smarkfen } 17044235Smarkfen 17054235Smarkfen static void 17064235Smarkfen print_id(char *prefix, sadb_ident_t *idp, int init_instr) 17074235Smarkfen { 17084235Smarkfen boolean_t canprint; 17094235Smarkfen 17104235Smarkfen switch (init_instr) { 17114235Smarkfen case IS_INITIATOR: 17124235Smarkfen (void) printf(gettext("%s Initiator identity, "), prefix); 17134235Smarkfen break; 17144235Smarkfen case IS_RESPONDER: 17154235Smarkfen (void) printf(gettext("%s Responder identity, "), prefix); 17164235Smarkfen break; 17174235Smarkfen case DONT_PRINT_INIT: 17184235Smarkfen (void) printf(gettext("%s Identity, "), prefix); 17194235Smarkfen break; 17204235Smarkfen default: 17214235Smarkfen (void) printf(gettext("<invalid identity>\n")); 17224235Smarkfen return; 17234235Smarkfen } 17244235Smarkfen (void) printf(gettext("uid=%d, type "), idp->sadb_ident_id); 17254235Smarkfen canprint = dump_sadb_idtype(idp->sadb_ident_type, stdout, NULL); 17266119Spwernau if (canprint) { 17274235Smarkfen (void) printf("\n%s %s\n", prefix, (char *)(idp + 1)); 17286119Spwernau } else { 17296119Spwernau (void) printf(gettext("\n%s "), prefix); 17306119Spwernau print_asn1_name(stdout, 17316119Spwernau (const unsigned char *)(idp + 1), 17326119Spwernau SADB_64TO8(idp->sadb_ident_len) - sizeof (sadb_ident_t)); 17336119Spwernau } 17344235Smarkfen } 17354235Smarkfen 17364235Smarkfen static void 17374235Smarkfen print_idspec(char *prefix, char *idp, int icnt, int ecnt) 17384235Smarkfen { 17394235Smarkfen int i; 17404235Smarkfen 17414235Smarkfen (void) printf(gettext("%s Identity descriptors:\n"), prefix); 17424235Smarkfen 17434235Smarkfen for (i = 0; i < icnt; i++) { 17444235Smarkfen if (i == 0) 17454235Smarkfen (void) printf(gettext("%s Includes:\n"), prefix); 17464235Smarkfen (void) printf("%s %s\n", prefix, idp); 17474235Smarkfen idp += strlen(idp) + 1; 17484235Smarkfen } 17494235Smarkfen 17504235Smarkfen for (i = 0; i < ecnt; i++) { 17514235Smarkfen if (i == 0) 17524235Smarkfen (void) printf(gettext("%s Excludes:\n"), prefix); 17534235Smarkfen (void) printf("%s %s\n", prefix, idp); 17544235Smarkfen idp += strlen(idp) + 1; 17554235Smarkfen } 17564235Smarkfen } 17574235Smarkfen 17584235Smarkfen static void 17594235Smarkfen print_keys(char *prefix, ike_p1_key_t *keyp, int size) 17604235Smarkfen { 17614235Smarkfen uint32_t *curp; 17624235Smarkfen ike_p1_key_t *p; 17634235Smarkfen int ssize; 17644235Smarkfen 17654235Smarkfen curp = (uint32_t *)keyp; 17664235Smarkfen 17674235Smarkfen ssize = sizeof (ike_p1_key_t); 17684235Smarkfen 17694235Smarkfen while ((intptr_t)curp - (intptr_t)keyp < size) { 17704235Smarkfen size_t p1klen, len; 17714235Smarkfen 17724235Smarkfen p = (ike_p1_key_t *)curp; 17734235Smarkfen p1klen = p->p1key_len; 17744235Smarkfen len = p1klen - ssize; 17754235Smarkfen 17764235Smarkfen p1klen = roundup(p1klen, sizeof (ike_p1_key_t)); 17774235Smarkfen if (p1klen < ssize) { 17784235Smarkfen (void) printf(gettext("Short key\n")); 17794235Smarkfen break; 17804235Smarkfen } 17814235Smarkfen 17824235Smarkfen switch (p->p1key_type) { 17834235Smarkfen case IKE_KEY_PRESHARED: 17844235Smarkfen (void) printf(gettext("%s Pre-shared key (%d bytes): "), 17854235Smarkfen prefix, len); 17864235Smarkfen (void) dump_key((uint8_t *)(p + 1), SADB_8TO1(len), 17874235Smarkfen stdout); 17884235Smarkfen break; 17894235Smarkfen case IKE_KEY_SKEYID: 17904235Smarkfen (void) printf(gettext("%s SKEYID (%d bytes): "), 17914235Smarkfen prefix, len); 17924235Smarkfen (void) dump_key((uint8_t *)(p + 1), SADB_8TO1(len), 17934235Smarkfen stdout); 17944235Smarkfen break; 17954235Smarkfen case IKE_KEY_SKEYID_D: 17964235Smarkfen (void) printf(gettext("%s SKEYID_d (%d bytes): "), 17974235Smarkfen prefix, len); 17984235Smarkfen (void) dump_key((uint8_t *)(p + 1), SADB_8TO1(len), 17994235Smarkfen stdout); 18004235Smarkfen break; 18014235Smarkfen case IKE_KEY_SKEYID_A: 18024235Smarkfen (void) printf(gettext("%s SKEYID_a (%d bytes): "), 18034235Smarkfen prefix, len); 18044235Smarkfen (void) dump_key((uint8_t *)(p + 1), SADB_8TO1(len), 18054235Smarkfen stdout); 18064235Smarkfen break; 18074235Smarkfen case IKE_KEY_SKEYID_E: 18084235Smarkfen (void) printf(gettext("%s SKEYID_e (%d bytes): "), 18094235Smarkfen prefix, len); 18104235Smarkfen (void) dump_key((uint8_t *)(p + 1), SADB_8TO1(len), 18114235Smarkfen stdout); 18124235Smarkfen break; 18134235Smarkfen case IKE_KEY_ENCR: 18144235Smarkfen (void) printf(gettext("%s Encryption key (%d bytes): "), 18154235Smarkfen prefix, len); 18164235Smarkfen (void) dump_key((uint8_t *)(p + 1), SADB_8TO1(len), 18174235Smarkfen stdout); 18184235Smarkfen break; 18194235Smarkfen case IKE_KEY_IV: 18204235Smarkfen (void) printf( 18214235Smarkfen gettext("%s Initialization vector (%d bytes): "), 18224235Smarkfen prefix, len); 18234235Smarkfen (void) dump_key((uint8_t *)(p + 1), SADB_8TO1(len), 18244235Smarkfen stdout); 18254235Smarkfen break; 18264235Smarkfen default: 18274235Smarkfen (void) printf(gettext("%s Unidentified key info %p %d"), 18284235Smarkfen prefix, p, p1klen); 18294235Smarkfen } 18304235Smarkfen (void) printf("\n"); 18314235Smarkfen assert(IS_P2ALIGNED(p1klen, 8)); 18324235Smarkfen curp += (p1klen >> 2); 18334235Smarkfen } 18344235Smarkfen } 18354235Smarkfen 18364235Smarkfen static void 18374235Smarkfen print_p1(ike_p1_sa_t *p1) 18384235Smarkfen { 18394235Smarkfen ike_p1_stats_t *sp; 18404235Smarkfen ike_p1_errors_t *ep; 18414235Smarkfen ike_p1_key_t *kp; 18424235Smarkfen sadb_ident_t *lidp, *ridp; 18434235Smarkfen int lstat, rstat; 18444235Smarkfen 18454235Smarkfen (void) printf("\n"); 18464235Smarkfen print_hdr("IKESA:", &p1->p1sa_hdr); 18474235Smarkfen print_xform("XFORM:", &p1->p1sa_xform, B_FALSE); 18484235Smarkfen 18494235Smarkfen if (p1->p1sa_hdr.p1hdr_isinit) { 18504235Smarkfen lstat = IS_INITIATOR; 18514235Smarkfen rstat = IS_RESPONDER; 18524235Smarkfen } else { 18534235Smarkfen lstat = IS_RESPONDER; 18544235Smarkfen rstat = IS_INITIATOR; 18554235Smarkfen } 18564235Smarkfen print_addr("LOCIP:", &p1->p1sa_ipaddrs.loc_addr, lstat); 18574235Smarkfen print_addr("REMIP:", &p1->p1sa_ipaddrs.rem_addr, rstat); 18584235Smarkfen 18594235Smarkfen /* 18604235Smarkfen * the stat len might be 0; but still make the call 18614235Smarkfen * to print_lifetime() to pick up the xform info 18624235Smarkfen */ 18634235Smarkfen sp = (ike_p1_stats_t *)((int)(p1) + p1->p1sa_stat_off); 18644235Smarkfen print_lifetime("LIFTM:", &p1->p1sa_xform, sp, p1->p1sa_stat_len); 18654235Smarkfen 18664235Smarkfen if (p1->p1sa_stat_len > 0) { 18674235Smarkfen print_p1stats("STATS:", sp, p1->p1sa_stat_len, B_FALSE); 18684235Smarkfen } 18694235Smarkfen 18704235Smarkfen if (p1->p1sa_error_len > 0) { 18714235Smarkfen ep = (ike_p1_errors_t *)((int)(p1) + p1->p1sa_error_off); 18724235Smarkfen print_errs("ERRS: ", ep, p1->p1sa_error_len); 18734235Smarkfen } 18744235Smarkfen 18754235Smarkfen if (p1->p1sa_localid_len > 0) { 18764235Smarkfen lidp = (sadb_ident_t *)((int)(p1) + p1->p1sa_localid_off); 18774235Smarkfen print_id("LOCID:", lidp, lstat); 18784235Smarkfen } 18794235Smarkfen 18804235Smarkfen if (p1->p1sa_remoteid_len > 0) { 18814235Smarkfen ridp = (sadb_ident_t *)((int)(p1) + p1->p1sa_remoteid_off); 18824235Smarkfen print_id("REMID:", ridp, rstat); 18834235Smarkfen } 18844235Smarkfen 18854235Smarkfen if (p1->p1sa_key_len > 0) { 18864235Smarkfen kp = (ike_p1_key_t *)((int)(p1) + p1->p1sa_key_off); 18874235Smarkfen print_keys("KEY: ", kp, p1->p1sa_key_len); 18884235Smarkfen } 18894235Smarkfen } 18904235Smarkfen 18914235Smarkfen static void 1892*8596SPaul.Wernau@Sun.COM print_certcache(ike_certcache_t *c) 1893*8596SPaul.Wernau@Sun.COM { 1894*8596SPaul.Wernau@Sun.COM (void) printf("\n"); 1895*8596SPaul.Wernau@Sun.COM 1896*8596SPaul.Wernau@Sun.COM (void) printf(gettext("CERTIFICATE CACHE ID: %d\n"), c->cache_id); 1897*8596SPaul.Wernau@Sun.COM (void) printf(gettext("\tSubject Name: <%s>\n"), 1898*8596SPaul.Wernau@Sun.COM (c->subject != NULL) ? c->subject : gettext("Name unavailable")); 1899*8596SPaul.Wernau@Sun.COM (void) printf(gettext("\t Issuer Name: <%s>\n"), 1900*8596SPaul.Wernau@Sun.COM (c->issuer != NULL) ? c->issuer : gettext("Name unavailable")); 1901*8596SPaul.Wernau@Sun.COM if ((int)c->class == -1) 1902*8596SPaul.Wernau@Sun.COM (void) printf(gettext("\t\t[trusted certificate]\n")); 1903*8596SPaul.Wernau@Sun.COM switch (c->linkage) { 1904*8596SPaul.Wernau@Sun.COM case CERT_OFF_WIRE: 1905*8596SPaul.Wernau@Sun.COM (void) printf(gettext("\t\t[Public certificate only]\n")); 1906*8596SPaul.Wernau@Sun.COM (void) printf(gettext( 1907*8596SPaul.Wernau@Sun.COM "\t\t[Obtained via certificate payload]\n")); 1908*8596SPaul.Wernau@Sun.COM break; 1909*8596SPaul.Wernau@Sun.COM case CERT_NO_PRIVKEY: 1910*8596SPaul.Wernau@Sun.COM (void) printf(gettext("\t\t[Public certificate only]\n")); 1911*8596SPaul.Wernau@Sun.COM break; 1912*8596SPaul.Wernau@Sun.COM case CERT_PRIVKEY_LOCKED: 1913*8596SPaul.Wernau@Sun.COM (void) printf(gettext( 1914*8596SPaul.Wernau@Sun.COM "\t\t[Private key linked but locked]\n")); 1915*8596SPaul.Wernau@Sun.COM break; 1916*8596SPaul.Wernau@Sun.COM case CERT_PRIVKEY_AVAIL: 1917*8596SPaul.Wernau@Sun.COM (void) printf(gettext("\t\t[Private key available]\n")); 1918*8596SPaul.Wernau@Sun.COM break; 1919*8596SPaul.Wernau@Sun.COM } 1920*8596SPaul.Wernau@Sun.COM } 1921*8596SPaul.Wernau@Sun.COM 1922*8596SPaul.Wernau@Sun.COM static void 19234235Smarkfen print_ps(ike_ps_t *ps) 19244235Smarkfen { 19254235Smarkfen sadb_ident_t *lidp, *ridp; 19264235Smarkfen uint8_t *keyp; 19274235Smarkfen 19284235Smarkfen (void) printf("\n"); 19294235Smarkfen 19304235Smarkfen (void) printf(gettext("PSKEY: For %s exchanges\n"), 19314235Smarkfen xchgstr(ps->ps_ike_mode)); 19324235Smarkfen 19334235Smarkfen if (ps->ps_key_len > 0) { 19344235Smarkfen keyp = (uint8_t *)((int)(ps) + ps->ps_key_off); 19354235Smarkfen (void) printf(gettext("PSKEY: Pre-shared key (%d bytes): "), 19364235Smarkfen ps->ps_key_len); 19374235Smarkfen (void) dump_key(keyp, ps->ps_key_bits, stdout); 19384235Smarkfen (void) printf("\n"); 19394235Smarkfen } 19404235Smarkfen 19414235Smarkfen /* 19424235Smarkfen * We get *either* and address or an ident, never both. So if 19434235Smarkfen * the ident is there, don't try printing an address. 19444235Smarkfen */ 19454235Smarkfen if (ps->ps_localid_len > 0) { 19464235Smarkfen lidp = (sadb_ident_t *) 19474235Smarkfen ((int)(ps) + ps->ps_localid_off); 19484235Smarkfen print_id("LOCID:", lidp, DONT_PRINT_INIT); 19494235Smarkfen } else { 19504235Smarkfen print_addr("LOCIP:", &ps->ps_ipaddrs.loc_addr, DONT_PRINT_INIT); 19514235Smarkfen } 19524235Smarkfen 19534235Smarkfen if (ps->ps_remoteid_len > 0) { 19544235Smarkfen ridp = (sadb_ident_t *) 19554235Smarkfen ((int)(ps) + ps->ps_remoteid_off); 19564235Smarkfen print_id("REMID:", ridp, DONT_PRINT_INIT); 19574235Smarkfen } else { 19584235Smarkfen print_addr("REMIP:", &ps->ps_ipaddrs.rem_addr, DONT_PRINT_INIT); 19594235Smarkfen } 19604235Smarkfen } 19614235Smarkfen 19624235Smarkfen #define PREFIXLEN 16 19634235Smarkfen 19644235Smarkfen static void 19654235Smarkfen print_rule(ike_rule_t *rp) 19664235Smarkfen { 19674235Smarkfen char prefix[PREFIXLEN]; 19684235Smarkfen int i; 19694235Smarkfen ike_p1_xform_t *xfp; 19704235Smarkfen ike_addr_pr_t *lipp, *ripp; 19714235Smarkfen char *lidp, *ridp; 19724235Smarkfen 19734235Smarkfen (void) printf("\n"); 19744235Smarkfen (void) printf(gettext("GLOBL: Label '%s', key manager cookie %u\n"), 19754235Smarkfen rp->rule_label, rp->rule_kmcookie); 19764235Smarkfen (void) printf(gettext("GLOBL: local_idtype=")); 19774235Smarkfen (void) dump_sadb_idtype(rp->rule_local_idtype, stdout, NULL); 19784235Smarkfen (void) printf(gettext(", ike_mode=%s\n"), xchgstr(rp->rule_ike_mode)); 19794235Smarkfen (void) printf(gettext( 19804235Smarkfen "GLOBL: p1_nonce_len=%u, p2_nonce_len=%u, p2_pfs=%s (group %u)\n"), 19814235Smarkfen rp->rule_p1_nonce_len, rp->rule_p2_nonce_len, 19824235Smarkfen (rp->rule_p2_pfs) ? gettext("true") : gettext("false"), 19834235Smarkfen rp->rule_p2_pfs); 19844235Smarkfen (void) printf( 19854235Smarkfen gettext("GLOBL: p2_lifetime=%u seconds, p2_softlife=%u seconds\n"), 19864235Smarkfen rp->rule_p2_lifetime_secs, rp->rule_p2_softlife_secs); 19874235Smarkfen (void) printf( 19887749SThejaswini.Singarajipura@Sun.COM gettext("GLOBL: p2_idletime=%u seconds\n"), 19897749SThejaswini.Singarajipura@Sun.COM rp->rule_p2_idletime_secs); 19907749SThejaswini.Singarajipura@Sun.COM (void) printf( 19914235Smarkfen gettext("GLOBL: p2_lifetime_kb=%u seconds," 19924235Smarkfen " p2_softlife_kb=%u seconds\n"), 19934235Smarkfen rp->rule_p2_lifetime_kb, rp->rule_p2_softlife_kb); 19944235Smarkfen 19954235Smarkfen if (rp->rule_locip_cnt > 0) { 19964235Smarkfen (void) printf(gettext("LOCIP: IP address range(s):\n")); 19974235Smarkfen lipp = (ike_addr_pr_t *)((int)rp + rp->rule_locip_off); 19984235Smarkfen for (i = 0; i < rp->rule_locip_cnt; i++, lipp++) { 19994235Smarkfen print_addr_range("LOCIP:", lipp); 20004235Smarkfen } 20014235Smarkfen } 20024235Smarkfen 20034235Smarkfen if (rp->rule_remip_cnt > 0) { 20044235Smarkfen (void) printf(gettext("REMIP: IP address range(s):\n")); 20054235Smarkfen ripp = (ike_addr_pr_t *)((int)rp + rp->rule_remip_off); 20064235Smarkfen for (i = 0; i < rp->rule_remip_cnt; i++, ripp++) { 20074235Smarkfen print_addr_range("REMIP:", ripp); 20084235Smarkfen } 20094235Smarkfen } 20104235Smarkfen 20114235Smarkfen if (rp->rule_locid_inclcnt + rp->rule_locid_exclcnt > 0) { 20124235Smarkfen lidp = (char *)((int)rp + rp->rule_locid_off); 20134235Smarkfen print_idspec("LOCID:", lidp, rp->rule_locid_inclcnt, 20144235Smarkfen rp->rule_locid_exclcnt); 20154235Smarkfen } 20164235Smarkfen 20174235Smarkfen if (rp->rule_remid_inclcnt + rp->rule_remid_exclcnt > 0) { 20184235Smarkfen ridp = (char *)((int)rp + rp->rule_remid_off); 20194235Smarkfen print_idspec("REMID:", ridp, rp->rule_remid_inclcnt, 20204235Smarkfen rp->rule_remid_exclcnt); 20214235Smarkfen } 20224235Smarkfen 20234235Smarkfen if (rp->rule_xform_cnt > 0) { 20244235Smarkfen (void) printf(gettext("XFRMS: Available Transforms:\n")); 20254235Smarkfen xfp = (ike_p1_xform_t *)((int)rp + rp->rule_xform_off); 20264235Smarkfen for (i = 0; i < rp->rule_xform_cnt; i++, xfp++) { 20274235Smarkfen (void) snprintf(prefix, PREFIXLEN, "XF %2u:", i); 20284235Smarkfen print_xform(prefix, xfp, B_TRUE); 20294235Smarkfen } 20304235Smarkfen } 20314235Smarkfen } 20324235Smarkfen 20334235Smarkfen #undef PREFIXLEN 20344235Smarkfen 20354235Smarkfen #define PRSACNTS(init, resp) \ 20364235Smarkfen (void) printf(gettext("initiator: %10u responder: %10u\n"), \ 20374235Smarkfen (init), (resp)) 20384235Smarkfen 20394235Smarkfen static void 20404235Smarkfen print_stats(ike_stats_t *sp, int len) 20414235Smarkfen { 20424235Smarkfen /* 20434235Smarkfen * before printing each line, make sure the structure we were 20444235Smarkfen * given is big enough to include the fields needed. 20454235Smarkfen */ 20464235Smarkfen if (len < COUNTER_PAIR) 20474235Smarkfen return; 20484235Smarkfen (void) printf(gettext("Phase 1 SA counts:\n")); 20494235Smarkfen (void) printf(gettext("Current: ")); 20504235Smarkfen PRSACNTS(sp->st_init_p1_current, sp->st_resp_p1_current); 20514235Smarkfen len -= COUNTER_PAIR; 20524235Smarkfen 20534235Smarkfen if (len < COUNTER_PAIR) 20544235Smarkfen return; 20554235Smarkfen (void) printf(gettext("Total: ")); 20564235Smarkfen PRSACNTS(sp->st_init_p1_total, sp->st_resp_p1_total); 20574235Smarkfen len -= COUNTER_PAIR; 20584235Smarkfen 20594235Smarkfen if (len < COUNTER_PAIR) 20604235Smarkfen return; 20614235Smarkfen (void) printf(gettext("Attempted: ")); 20624235Smarkfen PRSACNTS(sp->st_init_p1_attempts, sp->st_resp_p1_attempts); 20634235Smarkfen len -= COUNTER_PAIR; 20644235Smarkfen 20654235Smarkfen if (len < (COUNTER_PAIR + COUNTER_32BIT)) 20664235Smarkfen return; 20674235Smarkfen (void) printf(gettext("Failed: ")); 20684235Smarkfen PRSACNTS(sp->st_init_p1_noresp + sp->st_init_p1_respfail, 20694235Smarkfen sp->st_resp_p1_fail); 20704235Smarkfen (void) printf( 20714235Smarkfen gettext(" initiator fails include %u time-out(s)\n"), 20724235Smarkfen sp->st_init_p1_noresp); 20734235Smarkfen 20744235Smarkfen if (len < PATH_MAX) 20754235Smarkfen return; 20764235Smarkfen if (*(sp->st_pkcs11_libname) != '\0') 20774235Smarkfen (void) printf(gettext("PKCS#11 library linked in from %s\n"), 20784235Smarkfen sp->st_pkcs11_libname); 20794235Smarkfen } 20804235Smarkfen 20814235Smarkfen static void 20824235Smarkfen print_defaults(char *label, char *description, char *unit, boolean_t kbytes, 20834235Smarkfen uint_t current, uint_t def) 20844235Smarkfen { 20854235Smarkfen (void) printf("%-18s%-10s%14u%s%-10s%-26s\n", label, 20864235Smarkfen (current != def) ? gettext("config") : gettext("default"), 20874235Smarkfen (current != def) ? current : def, (kbytes) ? "K " : " ", 20884235Smarkfen unit, description); 20894235Smarkfen } 20904235Smarkfen 20914235Smarkfen /* 20924235Smarkfen * Print out defaults used by in.iked, the argument is a buffer containing 20934235Smarkfen * two ike_defaults_t's, the first contains the hard coded defaults, the second 20944235Smarkfen * contains the actual values used. If these differ, then the defaults have been 20954235Smarkfen * changed via a config file entry. Note that "-" indicates this default 20964235Smarkfen * is not tunable. 20974235Smarkfen */ 20984235Smarkfen static void 20994235Smarkfen do_print_defaults(ike_defaults_t *dp) 21004235Smarkfen { 21014235Smarkfen ike_defaults_t *ddp; 21024235Smarkfen ddp = (ike_defaults_t *)(dp + 1); 21034235Smarkfen 21044235Smarkfen (void) printf(gettext("\nGlobal defaults. Some values can be" 21054235Smarkfen " over-ridden on a per rule basis.\n\n")); 21064235Smarkfen 21074235Smarkfen (void) printf("%-18s%-10s%-16s%-10s%-26s\n\n", 21084235Smarkfen gettext("Token:"), gettext("Source:"), gettext("Value:"), 21094235Smarkfen gettext("Unit:"), gettext("Description:")); 21104235Smarkfen 21114235Smarkfen print_defaults("p1_lifetime_secs", gettext("phase 1 lifetime"), 21124235Smarkfen gettext("seconds"), B_FALSE, ddp->rule_p1_lifetime_secs, 21134235Smarkfen dp->rule_p1_lifetime_secs); 21144235Smarkfen 21154235Smarkfen print_defaults("-", gettext("minimum phase 1 lifetime"), 21164235Smarkfen gettext("seconds"), B_FALSE, ddp->rule_p1_minlife, 21174235Smarkfen dp->rule_p1_minlife); 21184235Smarkfen 21194235Smarkfen print_defaults("p1_nonce_len", gettext("phase 1 nonce length"), 21204235Smarkfen gettext("bytes"), B_FALSE, ddp->rule_p1_nonce_len, 21214235Smarkfen dp->rule_p1_nonce_len); 21224235Smarkfen 21234235Smarkfen print_defaults("p2_lifetime_secs", gettext("phase 2 lifetime"), 21244235Smarkfen gettext("seconds"), B_FALSE, ddp->rule_p2_lifetime_secs, 21254235Smarkfen dp->rule_p2_lifetime_secs); 21264235Smarkfen 21274235Smarkfen print_defaults("p2_softlife_secs", gettext("phase 2 soft lifetime"), 21284235Smarkfen gettext("seconds"), B_FALSE, ddp->rule_p2_softlife_secs, 21294235Smarkfen dp->rule_p2_softlife_secs); 21304235Smarkfen 21317749SThejaswini.Singarajipura@Sun.COM print_defaults("p2_idletime_secs", gettext("phase 2 idle time"), 21327749SThejaswini.Singarajipura@Sun.COM gettext("seconds"), B_FALSE, ddp->rule_p2_idletime_secs, 21337749SThejaswini.Singarajipura@Sun.COM dp->rule_p2_idletime_secs); 21347749SThejaswini.Singarajipura@Sun.COM 21355213Smarkfen print_defaults("-", gettext("system phase 2 lifetime"), 21365213Smarkfen gettext("seconds"), B_FALSE, ddp->sys_p2_lifetime_secs, 21375213Smarkfen dp->sys_p2_lifetime_secs); 21385213Smarkfen 21395213Smarkfen print_defaults("-", gettext("system phase 2 soft lifetime"), 21405213Smarkfen gettext("seconds"), B_FALSE, ddp->sys_p2_softlife_secs, 21415213Smarkfen dp->sys_p2_softlife_secs); 21425213Smarkfen 21437749SThejaswini.Singarajipura@Sun.COM print_defaults("-", gettext("system phase 2 idle time"), 21447749SThejaswini.Singarajipura@Sun.COM gettext("seconds"), B_FALSE, ddp->sys_p2_idletime_secs, 21457749SThejaswini.Singarajipura@Sun.COM dp->sys_p2_idletime_secs); 21467749SThejaswini.Singarajipura@Sun.COM 21474235Smarkfen print_defaults("p2_lifetime_kb", gettext("phase 2 lifetime"), 21484235Smarkfen gettext("bytes"), B_TRUE, ddp->rule_p2_lifetime_kb, 21494235Smarkfen dp->rule_p2_lifetime_kb); 21504235Smarkfen 21514235Smarkfen print_defaults("p2_softlife_kb", gettext("phase 2 soft lifetime"), 21524235Smarkfen gettext("bytes"), B_TRUE, ddp->rule_p2_softlife_kb, 21534235Smarkfen dp->rule_p2_softlife_kb); 21544235Smarkfen 21555213Smarkfen print_defaults("-", gettext("system phase 2 lifetime"), 21565213Smarkfen gettext("bytes"), B_FALSE, ddp->sys_p2_lifetime_bytes, 21575213Smarkfen dp->sys_p2_lifetime_bytes); 21585213Smarkfen 21595213Smarkfen print_defaults("-", gettext("system phase 2 soft lifetime"), 21605213Smarkfen gettext("bytes"), B_FALSE, ddp->sys_p2_softlife_bytes, 21615213Smarkfen dp->sys_p2_softlife_bytes); 21625213Smarkfen 21634235Smarkfen print_defaults("-", gettext("minimum phase 2 lifetime"), 21644235Smarkfen gettext("seconds"), B_FALSE, ddp->rule_p2_minlife, 21654235Smarkfen dp->rule_p2_minlife); 21664235Smarkfen 21674235Smarkfen print_defaults("p2_nonce_len", gettext("phase 2 nonce length"), 21684235Smarkfen gettext("bytes"), B_FALSE, ddp->rule_p2_nonce_len, 21694235Smarkfen dp->rule_p2_nonce_len); 21704235Smarkfen 21714235Smarkfen print_defaults("-", gettext("default phase 2 lifetime"), 21724235Smarkfen gettext("seconds"), B_FALSE, ddp->rule_p2_def_minlife, 21734235Smarkfen dp->rule_p2_def_minlife); 21744235Smarkfen 21754235Smarkfen print_defaults("-", gettext("minimum phase 2 soft delta"), 21764235Smarkfen gettext("seconds"), B_FALSE, ddp->rule_p2_minsoft, 21774235Smarkfen dp->rule_p2_minsoft); 21784235Smarkfen 21794235Smarkfen print_defaults("p2_pfs", gettext("phase 2 PFS"), 21804235Smarkfen " ", B_FALSE, ddp->rule_p2_pfs, dp->rule_p2_pfs); 21814235Smarkfen 21824235Smarkfen print_defaults("max_certs", gettext("max certificates"), 21834235Smarkfen " ", B_FALSE, ddp->rule_max_certs, dp->rule_max_certs); 21844235Smarkfen 21854235Smarkfen print_defaults("-", gettext("IKE port number"), 21864235Smarkfen " ", B_FALSE, ddp->rule_ike_port, dp->rule_ike_port); 21874235Smarkfen 21884235Smarkfen print_defaults("-", gettext("NAT-T port number"), 21894235Smarkfen " ", B_FALSE, ddp->rule_natt_port, dp->rule_natt_port); 21904235Smarkfen } 21914235Smarkfen 21924235Smarkfen static void 21934235Smarkfen print_categories(int level) 21944235Smarkfen { 21954235Smarkfen int mask; 21964235Smarkfen 21974235Smarkfen if (level == 0) { 21984235Smarkfen (void) printf(gettext("No debug categories enabled.\n")); 21994235Smarkfen return; 22004235Smarkfen } 22014235Smarkfen 22024235Smarkfen (void) printf(gettext("Debug categories enabled:")); 22034235Smarkfen for (mask = 1; mask <= D_HIGHBIT; mask <<= 1) { 22044235Smarkfen if (level & mask) 22054235Smarkfen (void) printf("\n\t%s", dbgstr(mask)); 22064235Smarkfen } 22074235Smarkfen (void) printf("\n"); 22084235Smarkfen } 22094235Smarkfen 22104235Smarkfen /*PRINTFLIKE2*/ 22114235Smarkfen static void 22124235Smarkfen ikeadm_err_exit(ike_err_t *err, char *fmt, ...) 22134235Smarkfen { 22144235Smarkfen va_list ap; 22154235Smarkfen char bailbuf[BUFSIZ]; 22164235Smarkfen 22174235Smarkfen va_start(ap, fmt); 22184235Smarkfen (void) vsnprintf(bailbuf, BUFSIZ, fmt, ap); 22194235Smarkfen va_end(ap); 22204235Smarkfen if ((err != NULL) && (err->ike_err == IKE_ERR_SYS_ERR)) { 22214235Smarkfen bail_msg("%s: %s", bailbuf, (err->ike_err_unix == 0) ? 22224235Smarkfen gettext("<unknown error>") : strerror(err->ike_err_unix)); 22234235Smarkfen } else { 22244235Smarkfen bail_msg("%s: %s", bailbuf, (err == NULL) ? 22254235Smarkfen gettext("<unknown error>") : errstr(err->ike_err)); 22264235Smarkfen } 22274235Smarkfen } 22284235Smarkfen 22294235Smarkfen /*PRINTFLIKE2*/ 22304235Smarkfen static void 22314235Smarkfen ikeadm_err_msg(ike_err_t *err, char *fmt, ...) 22324235Smarkfen { 22334235Smarkfen va_list ap; 22344235Smarkfen char mbuf[BUFSIZ]; 22354235Smarkfen 22364235Smarkfen va_start(ap, fmt); 22374235Smarkfen (void) vsnprintf(mbuf, BUFSIZ, fmt, ap); 22384235Smarkfen va_end(ap); 22394235Smarkfen if ((err != NULL) && (err->ike_err == IKE_ERR_SYS_ERR)) { 22404235Smarkfen message("%s: %s", mbuf, (err->ike_err_unix == 0) ? 22414235Smarkfen gettext("<unknown error>") : 22424235Smarkfen ((err->ike_err_unix == EEXIST) ? 22434235Smarkfen gettext("Duplicate entry") : 22444235Smarkfen strerror(err->ike_err_unix))); 22454235Smarkfen } else { 22464235Smarkfen message("%s: %s", mbuf, (err == NULL) ? 22474235Smarkfen gettext("<unknown error>") : errstr(err->ike_err)); 22484235Smarkfen } 22494235Smarkfen } 22504235Smarkfen 22514235Smarkfen 22524235Smarkfen /* 22534235Smarkfen * Command functions 22544235Smarkfen */ 22554235Smarkfen 22564235Smarkfen /* 22574235Smarkfen * Exploit the fact that ike_dbg_t and ike_priv_t have identical 22584235Smarkfen * formats in the following two functions. 22594235Smarkfen */ 22604235Smarkfen static void 22614235Smarkfen do_getvar(int cmd) 22624235Smarkfen { 22634235Smarkfen ike_service_t req, *rtn; 22644235Smarkfen ike_dbg_t *dreq; 22654235Smarkfen char *varname; 22664235Smarkfen 22674235Smarkfen switch (cmd) { 22684235Smarkfen case IKE_SVC_GET_DBG: 22694235Smarkfen varname = gettext("debug"); 22704235Smarkfen break; 22714235Smarkfen case IKE_SVC_GET_PRIV: 22724235Smarkfen varname = gettext("privilege"); 22734235Smarkfen break; 22744235Smarkfen default: 22754235Smarkfen bail_msg(gettext("unrecognized get command (%d)"), cmd); 22764235Smarkfen } 22774235Smarkfen 22784235Smarkfen dreq = &req.svc_dbg; 22794235Smarkfen dreq->cmd = cmd; 22804235Smarkfen dreq->dbg_level = 0; 22814235Smarkfen 22824235Smarkfen rtn = ikedoor_call((char *)&req, sizeof (ike_dbg_t), NULL, 0); 22834235Smarkfen 22844235Smarkfen if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 22854235Smarkfen ikeadm_err_exit(&rtn->svc_err, 22864235Smarkfen gettext("error getting %s level"), varname); 22874235Smarkfen } 22884235Smarkfen dreq = &rtn->svc_dbg; 22894235Smarkfen (void) printf(gettext("Current %s level is 0x%x"), 22904235Smarkfen varname, dreq->dbg_level); 22914235Smarkfen 22924235Smarkfen if (cmd == IKE_SVC_GET_DBG) { 22934235Smarkfen (void) printf("\n"); 22944235Smarkfen print_categories(dreq->dbg_level); 22954235Smarkfen } else { 22964235Smarkfen (void) printf(gettext(", %s enabled\n"), 22974235Smarkfen privstr(dreq->dbg_level)); 22984235Smarkfen } 22994235Smarkfen } 23004235Smarkfen 2301*8596SPaul.Wernau@Sun.COM /* 2302*8596SPaul.Wernau@Sun.COM * Log into a token and unlock all objects 2303*8596SPaul.Wernau@Sun.COM * referenced by PKCS#11 hint files. 2304*8596SPaul.Wernau@Sun.COM */ 2305*8596SPaul.Wernau@Sun.COM static void 2306*8596SPaul.Wernau@Sun.COM do_setdel_pin(int cmd, int argc, char **argv) 2307*8596SPaul.Wernau@Sun.COM { 2308*8596SPaul.Wernau@Sun.COM ike_service_t req, *rtn; 2309*8596SPaul.Wernau@Sun.COM ike_pin_t *preq; 2310*8596SPaul.Wernau@Sun.COM char token_label[PKCS11_TOKSIZE]; 2311*8596SPaul.Wernau@Sun.COM char *token_pin; 2312*8596SPaul.Wernau@Sun.COM char prompt[80]; 2313*8596SPaul.Wernau@Sun.COM 2314*8596SPaul.Wernau@Sun.COM if (argc < 1) 2315*8596SPaul.Wernau@Sun.COM Bail(gettext("Must specify PKCS#11 token object.")); 2316*8596SPaul.Wernau@Sun.COM 2317*8596SPaul.Wernau@Sun.COM preq = &req.svc_pin; 2318*8596SPaul.Wernau@Sun.COM preq->cmd = cmd; 2319*8596SPaul.Wernau@Sun.COM 2320*8596SPaul.Wernau@Sun.COM switch (cmd) { 2321*8596SPaul.Wernau@Sun.COM case IKE_SVC_SET_PIN: 2322*8596SPaul.Wernau@Sun.COM if (parse_token(argc, argv, token_label) != 0) 2323*8596SPaul.Wernau@Sun.COM Bail("Invalid syntax for \"token login\""); 2324*8596SPaul.Wernau@Sun.COM (void) snprintf(prompt, sizeof (prompt), 2325*8596SPaul.Wernau@Sun.COM "Enter PIN for PKCS#11 token \'%s\': ", token_label); 2326*8596SPaul.Wernau@Sun.COM token_pin = 2327*8596SPaul.Wernau@Sun.COM getpassphrase(prompt); 2328*8596SPaul.Wernau@Sun.COM (void) strlcpy((char *)preq->token_pin, token_pin, MAX_PIN_LEN); 2329*8596SPaul.Wernau@Sun.COM bzero(token_pin, strlen(token_pin)); 2330*8596SPaul.Wernau@Sun.COM break; 2331*8596SPaul.Wernau@Sun.COM case IKE_SVC_DEL_PIN: 2332*8596SPaul.Wernau@Sun.COM if (parse_token(argc, argv, token_label) != 0) 2333*8596SPaul.Wernau@Sun.COM Bail("Invalid syntax for \"token logout\""); 2334*8596SPaul.Wernau@Sun.COM break; 2335*8596SPaul.Wernau@Sun.COM default: 2336*8596SPaul.Wernau@Sun.COM bail_msg(gettext("unrecognized token command (%d)"), cmd); 2337*8596SPaul.Wernau@Sun.COM } 2338*8596SPaul.Wernau@Sun.COM 2339*8596SPaul.Wernau@Sun.COM (void) strlcpy(preq->pkcs11_token, token_label, PKCS11_TOKSIZE); 2340*8596SPaul.Wernau@Sun.COM 2341*8596SPaul.Wernau@Sun.COM rtn = ikedoor_call((char *)&req, sizeof (ike_pin_t), NULL, 0); 2342*8596SPaul.Wernau@Sun.COM if (cmd == IKE_SVC_SET_PIN) 2343*8596SPaul.Wernau@Sun.COM bzero(preq->token_pin, sizeof (preq->token_pin)); 2344*8596SPaul.Wernau@Sun.COM 2345*8596SPaul.Wernau@Sun.COM if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 2346*8596SPaul.Wernau@Sun.COM ikeadm_err_exit(&rtn->svc_err, 2347*8596SPaul.Wernau@Sun.COM gettext("PKCS#11 operation")); 2348*8596SPaul.Wernau@Sun.COM } 2349*8596SPaul.Wernau@Sun.COM preq = &rtn->svc_pin; 2350*8596SPaul.Wernau@Sun.COM message(gettext("PKCS#11 operation successful")); 2351*8596SPaul.Wernau@Sun.COM } 2352*8596SPaul.Wernau@Sun.COM 23534235Smarkfen static void 23544235Smarkfen do_setvar(int cmd, int argc, char **argv) 23554235Smarkfen { 23564235Smarkfen ike_service_t req, *rtn; 23574235Smarkfen ike_dbg_t *dreq; 23584235Smarkfen door_desc_t *descp = NULL, desc; 23594235Smarkfen int fd, ndesc = 0; 23604235Smarkfen uint32_t reqlevel; 23614235Smarkfen char *varname; 23624235Smarkfen 23634235Smarkfen if (argc < 1) 23644235Smarkfen Bail("unspecified level"); 23654235Smarkfen reqlevel = strtoul(argv[0], NULL, 0); 23664235Smarkfen 23674235Smarkfen switch (cmd) { 23684235Smarkfen case IKE_SVC_SET_DBG: 23694235Smarkfen if (argc > 2) 23704235Smarkfen Bail("Too many arguments to \"set debug\""); 23714235Smarkfen varname = gettext("debug"); 23724235Smarkfen if (reqlevel == 0) { 23734235Smarkfen /* check for a string... */ 23744235Smarkfen reqlevel = parsedbgopts(argv[0]); 23754235Smarkfen } 23764235Smarkfen if (reqlevel == D_INVALID) 23774235Smarkfen bail_msg(gettext("Bad debug flag: %s"), argv[0]); 23784235Smarkfen break; 23794235Smarkfen case IKE_SVC_SET_PRIV: 23804235Smarkfen if (argc > 1) 23814235Smarkfen Bail("Too many arguments to \"set priv\""); 23824235Smarkfen 23834235Smarkfen varname = gettext("privilege"); 23844235Smarkfen if (reqlevel == 0) { 23854235Smarkfen /* check for a string... */ 23864235Smarkfen reqlevel = privstr2num(argv[0]); 23874235Smarkfen } 23884235Smarkfen if (reqlevel > IKE_PRIV_MAXIMUM) 23894235Smarkfen bail_msg(gettext("Bad privilege flag: %s"), argv[0]); 23904235Smarkfen break; 23914235Smarkfen default: 23924235Smarkfen bail_msg(gettext("unrecognized set command (%d)"), cmd); 23934235Smarkfen } 23944235Smarkfen 23954235Smarkfen dreq = &req.svc_dbg; 23964235Smarkfen dreq->cmd = cmd; 23974235Smarkfen dreq->dbg_level = reqlevel; 23984235Smarkfen 23994235Smarkfen if ((argc == 2) && (cmd == IKE_SVC_SET_DBG)) { 24004235Smarkfen fd = open(argv[1], O_RDWR | O_CREAT | O_APPEND, 24014235Smarkfen S_IRUSR | S_IWUSR); 24024235Smarkfen if (fd < 0) 24034235Smarkfen Bail("open debug file"); 24044235Smarkfen desc.d_data.d_desc.d_descriptor = fd; 24054235Smarkfen desc.d_attributes = DOOR_DESCRIPTOR; 24064235Smarkfen descp = &desc; 24074235Smarkfen ndesc = 1; 24084235Smarkfen } 24094235Smarkfen 24104235Smarkfen rtn = ikedoor_call((char *)&req, sizeof (ike_dbg_t), descp, ndesc); 24114235Smarkfen 24124235Smarkfen if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 24134235Smarkfen ikeadm_err_exit(&rtn->svc_err, 24144235Smarkfen gettext("error setting %s level"), varname); 24154235Smarkfen } 24164235Smarkfen dreq = &rtn->svc_dbg; 24174235Smarkfen (void) printf( 24184235Smarkfen gettext("Successfully changed %s level from 0x%x to 0x%x\n"), 24194235Smarkfen varname, dreq->dbg_level, reqlevel); 24204235Smarkfen 24214235Smarkfen if (cmd == IKE_SVC_SET_DBG) { 24224235Smarkfen print_categories(reqlevel); 24234235Smarkfen } else { 24244235Smarkfen (void) printf(gettext("New privilege level 0x%x enables %s\n"), 24254235Smarkfen reqlevel, privstr(reqlevel)); 24264235Smarkfen } 24274235Smarkfen } 24284235Smarkfen 24294235Smarkfen static void 24304235Smarkfen do_getstats(int cmd) 24314235Smarkfen { 24324235Smarkfen ike_service_t *rtn; 24334235Smarkfen ike_statreq_t sreq, *sreqp; 24344235Smarkfen ike_stats_t *sp; 24354235Smarkfen 24364235Smarkfen sreq.cmd = cmd; 24374235Smarkfen 24384235Smarkfen rtn = ikedoor_call((char *)&sreq, sizeof (ike_statreq_t), NULL, 0); 24394235Smarkfen if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 24404235Smarkfen ikeadm_err_exit(&rtn->svc_err, gettext("error getting stats")); 24414235Smarkfen } 24424235Smarkfen 24434235Smarkfen sreqp = &rtn->svc_stats; 24444235Smarkfen sp = (ike_stats_t *)(sreqp + 1); 24454235Smarkfen print_stats(sp, sreqp->stat_len); 24464235Smarkfen } 24474235Smarkfen 24484235Smarkfen static void 24494235Smarkfen do_getdefs(int cmd) 24504235Smarkfen { 24514235Smarkfen ike_service_t *rtn; 24524235Smarkfen ike_defreq_t dreq, *dreqp; 24534235Smarkfen ike_defaults_t *dp; 24544235Smarkfen 24554235Smarkfen dreq.cmd = cmd; 24564235Smarkfen 24574235Smarkfen rtn = ikedoor_call((char *)&dreq, sizeof (ike_defreq_t), NULL, 0); 24584235Smarkfen if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 24594235Smarkfen ikeadm_err_exit(&rtn->svc_err, 24604235Smarkfen gettext("error getting defaults")); 24614235Smarkfen } 24624235Smarkfen 24634235Smarkfen dreqp = &rtn->svc_defaults; 24644235Smarkfen dp = (ike_defaults_t *)(dreqp + 1); 24654235Smarkfen 24664235Smarkfen /* 24674235Smarkfen * Before printing each line, make sure the structure we were 24684235Smarkfen * given is big enough to include the fields needed. 24694235Smarkfen * Silently bail out of there is a version mismatch. 24704235Smarkfen */ 24714235Smarkfen if (dreqp->stat_len < ((2 * sizeof (ike_defaults_t)) 24724235Smarkfen + sizeof (ike_defreq_t)) || dreqp->version != DOORVER) { 24734235Smarkfen return; 24744235Smarkfen } 24754235Smarkfen do_print_defaults(dp); 24764235Smarkfen } 24774235Smarkfen 24784235Smarkfen static void 24794235Smarkfen do_dump(int cmd) 24804235Smarkfen { 24814235Smarkfen char *name; 24824235Smarkfen ike_service_t req, *rtn; 24834235Smarkfen ike_dump_t *dreq, *dump; 24844235Smarkfen 24854235Smarkfen switch (cmd) { 24864235Smarkfen case IKE_SVC_DUMP_P1S: 24874235Smarkfen name = gettext("phase 1 SA info"); 24884235Smarkfen break; 24894235Smarkfen case IKE_SVC_DUMP_RULES: 24904235Smarkfen name = gettext("policy rules"); 24914235Smarkfen break; 24924235Smarkfen case IKE_SVC_DUMP_PS: 24934235Smarkfen name = gettext("preshared keys"); 24944235Smarkfen break; 2495*8596SPaul.Wernau@Sun.COM case IKE_SVC_DUMP_CERTCACHE: 2496*8596SPaul.Wernau@Sun.COM name = gettext("certcache"); 2497*8596SPaul.Wernau@Sun.COM break; 24984235Smarkfen default: 24994235Smarkfen bail_msg(gettext("unrecognized dump command (%d)"), cmd); 25004235Smarkfen } 25014235Smarkfen 25024235Smarkfen dreq = &req.svc_dump; 25034235Smarkfen dreq->cmd = cmd; 25044235Smarkfen dreq->dump_len = 0; 25054235Smarkfen dreq->dump_next = 0; 25064235Smarkfen do { 25074235Smarkfen rtn = ikedoor_call((char *)&req, sizeof (ike_dump_t), 25084235Smarkfen NULL, 0); 25094235Smarkfen if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 25104235Smarkfen if (rtn && (rtn->svc_err.ike_err == IKE_ERR_NO_OBJ)) { 25114235Smarkfen /* no entries to print */ 25124235Smarkfen break; 25134235Smarkfen } 25144235Smarkfen ikeadm_err_exit(&rtn->svc_err, 25154235Smarkfen gettext("error getting %s"), name); 25164235Smarkfen } 25174235Smarkfen dump = &rtn->svc_dump; 25184235Smarkfen 25194235Smarkfen switch (cmd) { 25204235Smarkfen case IKE_SVC_DUMP_P1S: 25214235Smarkfen print_p1((ike_p1_sa_t *)(dump + 1)); 25224235Smarkfen break; 25234235Smarkfen case IKE_SVC_DUMP_RULES: 25244235Smarkfen print_rule((ike_rule_t *)(dump + 1)); 25254235Smarkfen break; 25264235Smarkfen case IKE_SVC_DUMP_PS: 25274235Smarkfen print_ps((ike_ps_t *)(dump + 1)); 25284235Smarkfen break; 2529*8596SPaul.Wernau@Sun.COM case IKE_SVC_DUMP_CERTCACHE: 2530*8596SPaul.Wernau@Sun.COM print_certcache((ike_certcache_t *)(dump + 1)); 2531*8596SPaul.Wernau@Sun.COM break; 25324235Smarkfen } 25334235Smarkfen 25344235Smarkfen dreq->dump_next = dump->dump_next; 25354235Smarkfen 25364235Smarkfen (void) munmap((char *)rtn, dump->dump_len); 25374235Smarkfen 25384235Smarkfen } while (dreq->dump_next); 25394235Smarkfen 25404235Smarkfen (void) printf(gettext("\nCompleted dump of %s\n"), name); 25414235Smarkfen } 25424235Smarkfen 25434235Smarkfen static void 25444235Smarkfen do_getdel_doorcall(int cmd, int idlen, int idtype, char *idp, char *name) 25454235Smarkfen { 25464235Smarkfen int totallen; 25474235Smarkfen char *p; 25484235Smarkfen ike_service_t *reqp, *rtnp; 25494235Smarkfen ike_get_t *getp; 25504235Smarkfen boolean_t getcmd; 25514235Smarkfen 25524235Smarkfen getcmd = ((cmd == IKE_SVC_GET_P1) || (cmd == IKE_SVC_GET_RULE) || 25534235Smarkfen (cmd == IKE_SVC_GET_PS)); 25544235Smarkfen 25554235Smarkfen /* 25564235Smarkfen * WARNING: to avoid being redundant, this code takes advantage 25574235Smarkfen * of the fact that the ike_get_t and ike_del_t structures are 25584235Smarkfen * identical (only the field names differ, their function and 25594235Smarkfen * size are the same). If for some reason those structures 25604235Smarkfen * change, this code will need to be re-written to accomodate 25614235Smarkfen * that difference. 25624235Smarkfen */ 25634235Smarkfen totallen = sizeof (ike_get_t) + idlen; 25644235Smarkfen if ((reqp = (ike_service_t *)malloc(totallen)) == NULL) 25654235Smarkfen Bail("malloc(id)"); 25664235Smarkfen 25674235Smarkfen getp = &reqp->svc_get; 25684235Smarkfen getp->cmd = cmd; 25694235Smarkfen getp->get_len = totallen; 25704235Smarkfen getp->get_idtype = idtype; 25714235Smarkfen p = (char *)(getp + 1); 25724235Smarkfen 25734235Smarkfen (void) memcpy(p, idp, idlen); 25744235Smarkfen 25754235Smarkfen rtnp = ikedoor_call((char *)reqp, totallen, NULL, 0); 25764235Smarkfen if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) { 25774235Smarkfen if (rtnp && (rtnp->svc_err.ike_err == IKE_ERR_NO_OBJ)) { 25784235Smarkfen message(gettext("Could not find requested %s."), name); 25794235Smarkfen } else { 25804235Smarkfen ikeadm_err_msg(&rtnp->svc_err, gettext("error %s %s"), 25814235Smarkfen (getcmd) ? gettext("getting") : gettext("deleting"), 25824235Smarkfen name); 25834235Smarkfen } 25844235Smarkfen free(reqp); 25854235Smarkfen return; 25864235Smarkfen } 25874235Smarkfen getp = &rtnp->svc_get; 25884235Smarkfen 25894235Smarkfen if (getcmd) { 25904235Smarkfen switch (cmd) { 25914235Smarkfen case IKE_SVC_GET_P1: 25924235Smarkfen print_p1((ike_p1_sa_t *)(getp + 1)); 25934235Smarkfen break; 25944235Smarkfen case IKE_SVC_GET_PS: 25954235Smarkfen print_ps((ike_ps_t *)(getp + 1)); 25964235Smarkfen break; 25974235Smarkfen case IKE_SVC_GET_RULE: 25984235Smarkfen print_rule((ike_rule_t *)(getp + 1)); 25994235Smarkfen break; 26004235Smarkfen } 26014235Smarkfen } else { 26024235Smarkfen message(gettext("Successfully deleted selected %s."), name); 26034235Smarkfen } 26044235Smarkfen 26054235Smarkfen (void) munmap((char *)rtnp, getp->get_len); 26064235Smarkfen free(reqp); 26074235Smarkfen } 26084235Smarkfen 26094235Smarkfen static void 26104235Smarkfen do_getdel(int cmd, int argc, char **argv) 26114235Smarkfen { 26124235Smarkfen int idlen, idtype = 0, i, j; 26134235Smarkfen int bytelen1, bytelen2; 26144235Smarkfen char *name, *idp, *p, *p1, *p2; 26154235Smarkfen ike_addr_pr_t apr; 26164235Smarkfen ike_cky_pr_t cpr; 26174235Smarkfen sadb_ident_t *sid1p, *sid2p; 26184235Smarkfen struct hostent *he1p, *he2p; 26194235Smarkfen char label[MAX_LABEL_LEN]; 26204235Smarkfen 26214235Smarkfen if ((argc < 1) || (argv[0] == NULL)) { 26224235Smarkfen Bail("not enough identification info"); 26234235Smarkfen } 26244235Smarkfen 26254235Smarkfen switch (cmd) { 26264235Smarkfen case IKE_SVC_GET_P1: 26274235Smarkfen case IKE_SVC_DEL_P1: 26284235Smarkfen name = gettext("phase 1 SA"); 26294235Smarkfen /* 26304235Smarkfen * The first token must either be an address (or hostname) 26314235Smarkfen * or a cookie. We require cookies to be entered as hex 26324235Smarkfen * numbers, beginning with 0x; so if our token starts with 26334235Smarkfen * that, it's a cookie. 26344235Smarkfen */ 26354235Smarkfen if (strncmp(argv[0], "0x", 2) == 0) { 26364235Smarkfen if (parse_cky_pr(argc, argv, &cpr) >= 0) { 26374235Smarkfen idtype = IKE_ID_CKY_PAIR; 26384235Smarkfen idlen = sizeof (ike_cky_pr_t); 26394235Smarkfen idp = (char *)&cpr; 26404235Smarkfen } 26414235Smarkfen } else { 26424235Smarkfen if (parse_addr_pr(argc, argv, &he1p, &he2p) >= 0) { 26434235Smarkfen idtype = IKE_ID_ADDR_PAIR; 26444235Smarkfen idlen = sizeof (ike_addr_pr_t); 26454235Smarkfen } 26464235Smarkfen } 26474235Smarkfen break; 26484235Smarkfen 26494235Smarkfen case IKE_SVC_GET_RULE: 26504235Smarkfen case IKE_SVC_DEL_RULE: 26514235Smarkfen name = gettext("policy rule"); 26524235Smarkfen if (parse_label(argc, argv, label) >= 0) { 26534235Smarkfen idtype = IKE_ID_LABEL; 26544235Smarkfen idlen = MAX_LABEL_LEN; 26554235Smarkfen idp = label; 26564235Smarkfen } 26574235Smarkfen break; 26584235Smarkfen 26594235Smarkfen case IKE_SVC_GET_PS: 26604235Smarkfen case IKE_SVC_DEL_PS: 26614235Smarkfen name = gettext("preshared key"); 26624235Smarkfen /* 26634235Smarkfen * The first token must either be an address or an ident 26644235Smarkfen * type. Check for an ident type to determine which it is. 26654235Smarkfen */ 26664235Smarkfen if (parse_idtype(argv[0], NULL) >= 0) { 26674235Smarkfen if (parse_ident_pr(argc, argv, &sid1p, &sid2p) >= 0) { 26684235Smarkfen idtype = IKE_ID_IDENT_PAIR; 26694235Smarkfen idlen = SADB_64TO8(sid1p->sadb_ident_len) + 26704235Smarkfen SADB_64TO8(sid2p->sadb_ident_len); 26714235Smarkfen } 26724235Smarkfen } else { 26734235Smarkfen if (parse_addr_pr(argc, argv, &he1p, &he2p) >= 0) { 26744235Smarkfen idtype = IKE_ID_ADDR_PAIR; 26754235Smarkfen idlen = sizeof (ike_addr_pr_t); 26764235Smarkfen } 26774235Smarkfen } 26784235Smarkfen break; 26794235Smarkfen 26804235Smarkfen default: 26814235Smarkfen bail_msg(gettext("unrecognized get/del command (%d)"), cmd); 26824235Smarkfen } 26834235Smarkfen 26844235Smarkfen switch (idtype) { 26854235Smarkfen case IKE_ID_ADDR_PAIR: 26864235Smarkfen /* 26874235Smarkfen * we might have exploding addrs here; do every possible 26884235Smarkfen * combination. 26894235Smarkfen */ 26904235Smarkfen i = 0; 26914235Smarkfen j = 0; 26924235Smarkfen while ((p1 = he1p->h_addr_list[i++]) != NULL) { 26934235Smarkfen headdr2sa(p1, &apr.loc_addr, he1p->h_length); 26944235Smarkfen 26954235Smarkfen while ((p2 = he2p->h_addr_list[j++]) != NULL) { 26964235Smarkfen headdr2sa(p2, &apr.rem_addr, he2p->h_length); 26974235Smarkfen do_getdel_doorcall(cmd, idlen, idtype, 26984235Smarkfen (char *)&apr, name); 26994235Smarkfen } 27004235Smarkfen } 27014235Smarkfen FREE_HE(he1p); 27024235Smarkfen FREE_HE(he2p); 27034235Smarkfen break; 27044235Smarkfen 27054235Smarkfen case IKE_ID_IDENT_PAIR: 27064235Smarkfen bytelen1 = SADB_64TO8(sid1p->sadb_ident_len); 27074235Smarkfen bytelen2 = SADB_64TO8(sid2p->sadb_ident_len); 27084235Smarkfen if (idlen != bytelen1 + bytelen2) 27094235Smarkfen Bail("ident syntax error"); 27104235Smarkfen idp = p = (char *)malloc(idlen); 27114235Smarkfen if (p == NULL) 27124235Smarkfen Bail("malloc(id)"); 27134235Smarkfen (void) memcpy(p, (char *)sid1p, bytelen1); 27144235Smarkfen p += bytelen1; 27154235Smarkfen (void) memcpy(p, (char *)sid2p, bytelen2); 27164235Smarkfen do_getdel_doorcall(cmd, idlen, idtype, idp, name); 27174235Smarkfen free(idp); 27184235Smarkfen free(sid1p); 27194235Smarkfen free(sid2p); 27204235Smarkfen break; 27214235Smarkfen 27224235Smarkfen case IKE_ID_CKY_PAIR: 27234235Smarkfen case IKE_ID_LABEL: 27244235Smarkfen do_getdel_doorcall(cmd, idlen, idtype, idp, name); 27254235Smarkfen break; 27264235Smarkfen 27274235Smarkfen case 0: 27284235Smarkfen default: 27294235Smarkfen bail_msg(gettext("invalid %s identification\n"), name); 27304235Smarkfen } 27314235Smarkfen } 27324235Smarkfen 27334235Smarkfen /* 27344235Smarkfen * Copy source into target, inserting an escape character ('\') before 27354235Smarkfen * any quotes that appear. Return true on success, false on failure. 27364235Smarkfen */ 27374235Smarkfen static boolean_t 27384235Smarkfen escapequotes(char *target, char *source, int tlen) 27394235Smarkfen { 27404235Smarkfen int s, t, len = strlen(source) + 1; 27414235Smarkfen 27424235Smarkfen if (tlen < len) 27434235Smarkfen return (B_FALSE); 27444235Smarkfen 27454235Smarkfen for (s = 0, t = 0; s < len && t < tlen; s++) { 27464235Smarkfen if (source[s] == '\"') 27474235Smarkfen target[t++] = '\\'; 27484235Smarkfen target[t++] = source[s]; 27494235Smarkfen } 27504235Smarkfen 27514235Smarkfen if ((t == tlen) && (s < len)) 27524235Smarkfen return (B_FALSE); 27534235Smarkfen 27544235Smarkfen return (B_TRUE); 27554235Smarkfen } 27564235Smarkfen 27574235Smarkfen /* 27584235Smarkfen * Return true if the arg following the given keyword should 27594235Smarkfen * be in quotes (i.e. is a string), false if not. 27604235Smarkfen */ 27614235Smarkfen static boolean_t 27624235Smarkfen quotedfield(char *keywd) 27634235Smarkfen { 27644235Smarkfen if ((strncmp(keywd, "label", strlen("label") + 1) == 0) || 27654235Smarkfen (strncmp(keywd, "local_id", strlen("local_id") + 1) == 0) || 27664235Smarkfen (strncmp(keywd, "remote_id", strlen("remote_id") + 1) == 0)) 27674235Smarkfen return (B_TRUE); 27684235Smarkfen 27694235Smarkfen return (B_FALSE); 27704235Smarkfen } 27714235Smarkfen 27724235Smarkfen static void 27734235Smarkfen do_new(int cmd, int argc, char **argv) 27744235Smarkfen { 27754235Smarkfen ike_service_t *rtn; 27764235Smarkfen ike_new_t new, *newp = NULL; 27774235Smarkfen door_desc_t desc, *descp = NULL; 27784235Smarkfen int i, fd, ndesc = 0, buflen; 27794235Smarkfen char *name, tmpfilepath[32]; 27804235Smarkfen FILE *tmpfile; 27814235Smarkfen 27824235Smarkfen switch (cmd) { 27834235Smarkfen case IKE_SVC_NEW_PS: 27844235Smarkfen name = gettext("preshared key"); 27854235Smarkfen break; 27864235Smarkfen case IKE_SVC_NEW_RULE: 27874235Smarkfen name = gettext("policy rule"); 27884235Smarkfen break; 27894235Smarkfen default: 27904235Smarkfen bail_msg(gettext("unrecognized new command (%d)"), cmd); 27914235Smarkfen } 27924235Smarkfen 27934235Smarkfen if (argc == 1) { 27944235Smarkfen /* We've been given a file to read from */ 27954235Smarkfen fd = open(argv[0], O_RDONLY); 27964235Smarkfen if (fd < 0) 27974235Smarkfen Bail("open source file"); 27984235Smarkfen 27994235Smarkfen desc.d_data.d_desc.d_descriptor = fd; 28004235Smarkfen desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE; 28014235Smarkfen descp = &desc; 28024235Smarkfen ndesc = 1; 28034235Smarkfen 28044235Smarkfen new.cmd = cmd; 28054235Smarkfen new.new_len = 0; 28064235Smarkfen newp = &new; 28074235Smarkfen buflen = sizeof (ike_new_t); 28084235Smarkfen 28094235Smarkfen } else if ((argc > 1) && (cmd == IKE_SVC_NEW_PS)) { 28104235Smarkfen /* 28114235Smarkfen * This is an alternative to using the tmpfile method 28124235Smarkfen * for preshared keys. It means we're duplicating the 28134235Smarkfen * parsing effort that happens in readps.c; but it 28144235Smarkfen * does avoid having the key sitting in a file. 28154235Smarkfen */ 28164235Smarkfen ike_ps_t *psp; 28174235Smarkfen int pslen; 28184235Smarkfen 28194235Smarkfen /* 28204235Smarkfen * must be in interactive mode; don't want keys in 28214235Smarkfen * the process args. 28224235Smarkfen */ 28234235Smarkfen if (!interactive) 28244235Smarkfen Bail("Must be in interactive mode to add key info."); 28254235Smarkfen if (parse_ps(argc, argv, &psp, &pslen) < 0) { 28264235Smarkfen errno = 0; 28274235Smarkfen Bail("invalid preshared key definition"); 28284235Smarkfen } 28294235Smarkfen newp = malloc(sizeof (ike_new_t) + pslen); 28304235Smarkfen if (newp == NULL) 28314235Smarkfen Bail("alloc pskey"); 28324235Smarkfen newp->cmd = cmd; 28334235Smarkfen newp->new_len = sizeof (ike_new_t) + pslen; 28344235Smarkfen (void) memcpy((char *)(newp + 1), psp, pslen); 28354235Smarkfen buflen = newp->new_len; 28364235Smarkfen /* parse_ps allocated the ike_ps_t buffer; free it now */ 28374235Smarkfen free(psp); 28384235Smarkfen 28394235Smarkfen } else if ((argc > 1) && (cmd == IKE_SVC_NEW_RULE)) { 28404235Smarkfen /* 28414235Smarkfen * We've been given the item in argv. However, parsing 28424235Smarkfen * rules can get more than a little messy, and in.iked 28434235Smarkfen * already has a great parser for this stuff! So don't 28444235Smarkfen * fool around with trying to do the parsing here. Just 28454235Smarkfen * write it out to a tempfile, and send the fd to in.iked. 28464235Smarkfen * 28474235Smarkfen * We could conceivably do this for preshared keys, 28484235Smarkfen * rather than duplicating the parsing effort; but that 28494235Smarkfen * would mean the key would be written out to a file, 28504235Smarkfen * which isn't such a good idea. 28514235Smarkfen */ 28524235Smarkfen boolean_t doquotes = B_FALSE; 28534235Smarkfen int rtn; 28544235Smarkfen 28554235Smarkfen if ((argv[0][0] != '{') || 28564235Smarkfen (argv[argc - 1][strlen(argv[argc - 1]) - 1] != '}')) 28574235Smarkfen bail_msg(gettext("improperly formatted %s"), name); 28584235Smarkfen 28594235Smarkfen /* attempt to use a fairly unpredictable file name... */ 28604235Smarkfen (void) sprintf(tmpfilepath, "/var/run/%x", (int)gethrtime()); 28614235Smarkfen fd = open(tmpfilepath, O_RDWR | O_CREAT | O_EXCL, 28624235Smarkfen S_IRUSR | S_IWUSR); 28634235Smarkfen if (fd < 0) 28644235Smarkfen Bail("cannot open tmpfile"); 28654235Smarkfen 28664235Smarkfen /* and make it inaccessible asap */ 28674235Smarkfen if (unlink(tmpfilepath) < 0) { 28684235Smarkfen (void) close(fd); 28694235Smarkfen Bail("tmpfile error"); 28704235Smarkfen } 28714235Smarkfen 28724235Smarkfen tmpfile = fdopen(fd, "w"); 28734235Smarkfen if (tmpfile == NULL) { 28744235Smarkfen (void) close(fd); 28754235Smarkfen Bail("cannot write to tmpfile"); 28764235Smarkfen } 28774235Smarkfen 28784235Smarkfen for (i = 0; i < argc; i++) { 28794235Smarkfen /* 28804235Smarkfen * We have to do some gyrations with our string here, 28814235Smarkfen * to properly handle quotes. There are two issues: 28824235Smarkfen * - some of the fields of a rule may have embedded 28834235Smarkfen * whitespace, and thus must be quoted on the cmd 28844235Smarkfen * line. The shell removes the quotes, and gives 28854235Smarkfen * us a single argv string; but we need to put the 28864235Smarkfen * quotes back in when we write the string out to 28874235Smarkfen * file. The doquotes boolean is set when we 28884235Smarkfen * process a keyword which will be followed by a 28894235Smarkfen * string value (so the NEXT argv element will be 28904235Smarkfen * quoted). 28914235Smarkfen * - there might be a quote character in a field, 28924235Smarkfen * that was escaped on the cmdline. The shell 28934235Smarkfen * removes the escape char, and leaves the quote 28944235Smarkfen * in the string it gives us. We need to put the 28954235Smarkfen * escape char back in before writing to file. 28964235Smarkfen */ 28974235Smarkfen char field[MAXLINESIZE]; 28984235Smarkfen if (!escapequotes(field, argv[i], MAXLINESIZE)) 28994235Smarkfen Bail("write to tmpfile failed (arg too big)"); 29004235Smarkfen if (doquotes) { 29014235Smarkfen rtn = fprintf(tmpfile, "\"%s\"\n", field); 29024235Smarkfen doquotes = B_FALSE; 29034235Smarkfen } else { 29044235Smarkfen rtn = fprintf(tmpfile, "%s\n", field); 29054235Smarkfen } 29064235Smarkfen if (rtn < 0) 29074235Smarkfen Bail("write to tmpfile failed"); 29084235Smarkfen /* 29094235Smarkfen * check if this is a keyword identifying 29104235Smarkfen * a field that needs to be quoted. 29114235Smarkfen */ 29124235Smarkfen doquotes = quotedfield(argv[i]); 29134235Smarkfen } 29144235Smarkfen if (fflush(tmpfile) == EOF) 29154235Smarkfen Bail("write to tmpfile failed"); 29164235Smarkfen /* rewind so that the daemon will get the beginning */ 29174235Smarkfen rewind(tmpfile); 29184235Smarkfen 29194235Smarkfen desc.d_data.d_desc.d_descriptor = fd; 29204235Smarkfen desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE; 29214235Smarkfen descp = &desc; 29224235Smarkfen ndesc = 1; 29234235Smarkfen 29244235Smarkfen new.cmd = cmd; 29254235Smarkfen new.new_len = 0; 29264235Smarkfen newp = &new; 29274235Smarkfen buflen = sizeof (ike_new_t); 29284235Smarkfen 29294235Smarkfen } else { 29304235Smarkfen /* not enough information! */ 29314235Smarkfen bail_msg(gettext("missing %s description or file name"), name); 29324235Smarkfen } 29334235Smarkfen 29344235Smarkfen rtn = ikedoor_call((char *)newp, buflen, descp, ndesc); 29354235Smarkfen 29364235Smarkfen if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 29374235Smarkfen ikeadm_err_msg(&rtn->svc_err, 29384235Smarkfen gettext("error creating new %s"), name); 29394235Smarkfen } else { 29404235Smarkfen message(gettext("Successfully created new %s."), name); 29414235Smarkfen } 29424235Smarkfen } 29434235Smarkfen 29444235Smarkfen static void 29454235Smarkfen do_flush(int cmd) 29464235Smarkfen { 29474235Smarkfen ike_service_t *rtnp; 29484235Smarkfen ike_flush_t flush; 29494235Smarkfen 2950*8596SPaul.Wernau@Sun.COM if (cmd != IKE_SVC_FLUSH_P1S && cmd != IKE_SVC_FLUSH_CERTCACHE) { 29514235Smarkfen bail_msg(gettext("unrecognized flush command (%d)."), cmd); 29524235Smarkfen } 29534235Smarkfen 29544235Smarkfen flush.cmd = cmd; 29554235Smarkfen 29564235Smarkfen rtnp = ikedoor_call((char *)&flush, sizeof (ike_flush_t), NULL, 0); 29574235Smarkfen if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) { 29584235Smarkfen ikeadm_err_exit(&rtnp->svc_err, gettext("error doing flush")); 29594235Smarkfen } 2960*8596SPaul.Wernau@Sun.COM if (cmd == IKE_SVC_FLUSH_P1S) 2961*8596SPaul.Wernau@Sun.COM message(gettext("Successfully flushed P1 SAs.")); 2962*8596SPaul.Wernau@Sun.COM else 2963*8596SPaul.Wernau@Sun.COM message(gettext("Successfully flushed cert cache.")); 29644235Smarkfen } 29654235Smarkfen 29664235Smarkfen static void 29674235Smarkfen do_rw(int cmd, int argc, char **argv) 29684235Smarkfen { 29694235Smarkfen ike_service_t *rtnp; 29704235Smarkfen ike_rw_t rw; 29714235Smarkfen door_desc_t desc, *descp = NULL; 29724235Smarkfen int oflag, omode, fd, ndesc = 0; 29734235Smarkfen char *op, *obj = NULL; 29744235Smarkfen boolean_t writing = B_FALSE; 29754235Smarkfen 29764235Smarkfen switch (cmd) { 29774235Smarkfen case IKE_SVC_READ_PS: 29784235Smarkfen obj = gettext("preshared key"); 29794235Smarkfen /* FALLTHRU */ 29804235Smarkfen case IKE_SVC_READ_RULES: 29814235Smarkfen if (obj == NULL) 29824235Smarkfen obj = gettext("policy rule"); 29834235Smarkfen op = gettext("read"); 29844235Smarkfen oflag = O_RDONLY; 29854235Smarkfen omode = 0; 29864235Smarkfen break; 29874235Smarkfen 29884235Smarkfen case IKE_SVC_WRITE_PS: 29894235Smarkfen obj = gettext("preshared key"); 29904235Smarkfen /* FALLTHRU */ 29914235Smarkfen case IKE_SVC_WRITE_RULES: 29924235Smarkfen if (obj == NULL) 29934235Smarkfen obj = gettext("policy rule"); 29944235Smarkfen op = gettext("write"); 29954235Smarkfen oflag = O_RDWR | O_CREAT | O_EXCL; 29964235Smarkfen omode = S_IRUSR | S_IWUSR; 29974235Smarkfen 29984235Smarkfen /* for write commands, dest location must be specified */ 29994235Smarkfen if (argc < 1) { 30004235Smarkfen bail_msg(gettext("destination location required " 30014235Smarkfen "to write %ss"), obj); 30024235Smarkfen } 30034235Smarkfen writing = B_TRUE; 30044235Smarkfen break; 30054235Smarkfen 30064235Smarkfen default: 30074235Smarkfen bail_msg(gettext("unrecognized read/write command (%d)."), cmd); 30084235Smarkfen } 30094235Smarkfen 30104235Smarkfen rw.cmd = cmd; 30114235Smarkfen 30124235Smarkfen if (argc >= 1) { 30134235Smarkfen rw.rw_loc = IKE_RW_LOC_USER_SPEC; 30144235Smarkfen fd = open(argv[0], oflag, omode); 30154235Smarkfen if (fd < 0) 30164235Smarkfen Bail("open user-specified file"); 30174235Smarkfen 30184235Smarkfen desc.d_data.d_desc.d_descriptor = fd; 30194235Smarkfen desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE; 30204235Smarkfen descp = &desc; 30214235Smarkfen ndesc = 1; 30224235Smarkfen } else { 30234235Smarkfen rw.rw_loc = IKE_RW_LOC_DEFAULT; 30244235Smarkfen } 30254235Smarkfen 30264235Smarkfen rtnp = ikedoor_call((char *)&rw, sizeof (ike_rw_t), descp, ndesc); 30274235Smarkfen if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) { 30284235Smarkfen /* 30294235Smarkfen * Need to remove the target file in the 30304235Smarkfen * case of a failed write command. 30314235Smarkfen */ 30324235Smarkfen if (writing) { 30334235Smarkfen /* 30344235Smarkfen * argv[0] must be valid if we're writing; we 30354235Smarkfen * exit before setting this boolean if not. 30364235Smarkfen */ 30374235Smarkfen (void) unlink(argv[0]); 30384235Smarkfen (void) close(fd); 30394235Smarkfen 30404235Smarkfen if ((rtnp != NULL) && 30414235Smarkfen (rtnp->svc_err.ike_err == IKE_ERR_NO_OBJ)) { 30424235Smarkfen message(gettext("No %s information to write."), 30434235Smarkfen obj); 30444235Smarkfen return; 30454235Smarkfen } 30464235Smarkfen } 30474235Smarkfen ikeadm_err_exit(&rtnp->svc_err, gettext("error doing %s"), op); 30484235Smarkfen } 30494235Smarkfen message(gettext("Completed %s of %s configuration information."), 30504235Smarkfen op, obj); 30514235Smarkfen } 30524235Smarkfen 30534235Smarkfen static void 30544235Smarkfen do_rbdump() 30554235Smarkfen { 30564235Smarkfen ike_cmd_t req; 30574235Smarkfen ike_service_t *rtnp; 30584235Smarkfen 30594235Smarkfen req.cmd = IKE_SVC_DBG_RBDUMP; 30604235Smarkfen 30614235Smarkfen rtnp = ikedoor_call((char *)&req, sizeof (ike_cmd_t), NULL, 0); 30624235Smarkfen if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) { 30634235Smarkfen ikeadm_err_exit(&rtnp->svc_err, gettext("error doing flush")); 30644235Smarkfen } 30654235Smarkfen message(gettext("Successfully dumped rulebase; check iked dbg")); 30664235Smarkfen } 30674235Smarkfen 30684235Smarkfen #define REQ_ARG_CNT 1 30694235Smarkfen 30704235Smarkfen /*ARGSUSED*/ 30714235Smarkfen static void 30724342Spwernau parseit(int argc, char **argv, char *notused, boolean_t notused_either) 30734235Smarkfen { 30744235Smarkfen int cmd, cmd_obj_args = 1; 30754235Smarkfen char *cmdstr, *objstr; 30764235Smarkfen 30774235Smarkfen if (interactive) { 30784235Smarkfen if (argc == 0) 30794235Smarkfen return; 30804235Smarkfen } 30814235Smarkfen 30824235Smarkfen if (argc < REQ_ARG_CNT) { 30834235Smarkfen usage(); 30844235Smarkfen } 30854235Smarkfen 30864235Smarkfen cmdstr = argv[0]; 30874235Smarkfen if (argc > REQ_ARG_CNT) { 30884235Smarkfen cmd_obj_args++; 30894235Smarkfen objstr = argv[1]; 30904235Smarkfen } else { 30914235Smarkfen objstr = NULL; 30924235Smarkfen } 30934235Smarkfen cmd = parsecmd(cmdstr, objstr); 30944235Smarkfen 30954235Smarkfen /* skip over args specifying command/object */ 30964235Smarkfen argc -= cmd_obj_args; 30974235Smarkfen argv += cmd_obj_args; 30984235Smarkfen 30994235Smarkfen switch (cmd) { 31004235Smarkfen case IKE_SVC_GET_DEFS: 31014235Smarkfen do_getdefs(cmd); 31024235Smarkfen break; 31034235Smarkfen case IKE_SVC_GET_DBG: 31044235Smarkfen case IKE_SVC_GET_PRIV: 31054235Smarkfen do_getvar(cmd); 31064235Smarkfen break; 31074235Smarkfen case IKE_SVC_GET_STATS: 31084235Smarkfen do_getstats(cmd); 31094235Smarkfen break; 31104235Smarkfen case IKE_SVC_SET_DBG: 31114235Smarkfen case IKE_SVC_SET_PRIV: 31124235Smarkfen do_setvar(cmd, argc, argv); 31134235Smarkfen break; 3114*8596SPaul.Wernau@Sun.COM case IKE_SVC_SET_PIN: 3115*8596SPaul.Wernau@Sun.COM case IKE_SVC_DEL_PIN: 3116*8596SPaul.Wernau@Sun.COM do_setdel_pin(cmd, argc, argv); 3117*8596SPaul.Wernau@Sun.COM break; 31184235Smarkfen case IKE_SVC_DUMP_P1S: 31194235Smarkfen case IKE_SVC_DUMP_RULES: 31204235Smarkfen case IKE_SVC_DUMP_PS: 3121*8596SPaul.Wernau@Sun.COM case IKE_SVC_DUMP_CERTCACHE: 31224235Smarkfen do_dump(cmd); 31234235Smarkfen break; 31244235Smarkfen case IKE_SVC_GET_P1: 31254235Smarkfen case IKE_SVC_GET_RULE: 31264235Smarkfen case IKE_SVC_GET_PS: 31274235Smarkfen case IKE_SVC_DEL_P1: 31284235Smarkfen case IKE_SVC_DEL_RULE: 31294235Smarkfen case IKE_SVC_DEL_PS: 31304235Smarkfen do_getdel(cmd, argc, argv); 31314235Smarkfen break; 31324235Smarkfen case IKE_SVC_NEW_RULE: 31334235Smarkfen case IKE_SVC_NEW_PS: 31344235Smarkfen do_new(cmd, argc, argv); 31354235Smarkfen break; 31364235Smarkfen case IKE_SVC_FLUSH_P1S: 3137*8596SPaul.Wernau@Sun.COM case IKE_SVC_FLUSH_CERTCACHE: 31384235Smarkfen do_flush(cmd); 31394235Smarkfen break; 31404235Smarkfen case IKE_SVC_READ_RULES: 31414235Smarkfen case IKE_SVC_READ_PS: 31424235Smarkfen case IKE_SVC_WRITE_RULES: 31434235Smarkfen case IKE_SVC_WRITE_PS: 31444235Smarkfen do_rw(cmd, argc, argv); 31454235Smarkfen break; 31464235Smarkfen case IKEADM_HELP_GENERAL: 31474235Smarkfen print_help(); 31484235Smarkfen break; 31494235Smarkfen case IKEADM_HELP_GET: 31504235Smarkfen print_get_help(); 31514235Smarkfen break; 31524235Smarkfen case IKEADM_HELP_SET: 31534235Smarkfen print_set_help(); 31544235Smarkfen break; 31554235Smarkfen case IKEADM_HELP_ADD: 31564235Smarkfen print_add_help(); 31574235Smarkfen break; 31584235Smarkfen case IKEADM_HELP_DEL: 31594235Smarkfen print_del_help(); 31604235Smarkfen break; 31614235Smarkfen case IKEADM_HELP_DUMP: 31624235Smarkfen print_dump_help(); 31634235Smarkfen break; 31644235Smarkfen case IKEADM_HELP_FLUSH: 31654235Smarkfen print_flush_help(); 31664235Smarkfen break; 31674235Smarkfen case IKEADM_HELP_READ: 31684235Smarkfen print_read_help(); 31694235Smarkfen break; 31704235Smarkfen case IKEADM_HELP_WRITE: 31714235Smarkfen print_write_help(); 31724235Smarkfen break; 3173*8596SPaul.Wernau@Sun.COM case IKEADM_HELP_TOKEN: 3174*8596SPaul.Wernau@Sun.COM print_token_help(); 3175*8596SPaul.Wernau@Sun.COM break; 31764235Smarkfen case IKEADM_HELP_HELP: 31774235Smarkfen print_help_help(); 31784235Smarkfen break; 31794235Smarkfen case IKEADM_EXIT: 31804235Smarkfen if (interactive) 31814235Smarkfen exit(0); 31824235Smarkfen break; 31834235Smarkfen case IKE_SVC_DBG_RBDUMP: 31844235Smarkfen do_rbdump(); 31854235Smarkfen break; 31864235Smarkfen case IKE_SVC_ERROR: 31874235Smarkfen usage(); 31884235Smarkfen default: 31894235Smarkfen exit(0); 31904235Smarkfen } 31914235Smarkfen } 31924235Smarkfen 31934235Smarkfen int 31944235Smarkfen main(int argc, char **argv) 31954235Smarkfen { 31964235Smarkfen char ch; 31974235Smarkfen 31984235Smarkfen (void) setlocale(LC_ALL, ""); 31994235Smarkfen #if !defined(TEXT_DOMAIN) 32004235Smarkfen #define TEXT_DOMAIN "SYS_TEST" 32014235Smarkfen #endif 32024235Smarkfen (void) textdomain(TEXT_DOMAIN); 32034235Smarkfen 32044235Smarkfen while ((ch = getopt(argc, argv, "hpn")) != EOF) { 32054235Smarkfen switch (ch) { 32064235Smarkfen case 'h': 32074235Smarkfen print_help(); 32084235Smarkfen return (0); 32094235Smarkfen case 'p': 32104235Smarkfen pflag = B_TRUE; 32114235Smarkfen break; 32124235Smarkfen case 'n': 32134235Smarkfen nflag = B_TRUE; 32144235Smarkfen break; 32154235Smarkfen default: 32164235Smarkfen usage(); 32174235Smarkfen } 32184235Smarkfen } 32194235Smarkfen argc -= optind; 32204235Smarkfen argv += optind; 32214235Smarkfen 32224235Smarkfen if (open_door() < 0) { 32234235Smarkfen (void) fprintf(stderr, 32244235Smarkfen gettext("Unable to communicate with in.iked\n")); 32254235Smarkfen Bail("open_door failed"); 32264235Smarkfen } 32274235Smarkfen 32284235Smarkfen if (*argv == NULL) { 32294235Smarkfen /* no cmd-line args, do interactive mode */ 32304235Smarkfen do_interactive(stdin, NULL, "ikeadm> ", NULL, parseit); 32314235Smarkfen } 32324235Smarkfen 32334342Spwernau parseit(argc, argv, NULL, B_FALSE); 32344235Smarkfen 32354235Smarkfen return (0); 32364235Smarkfen } 3237