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 * 216119Spwernau * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 224235Smarkfen * Use is subject to license terms. 234235Smarkfen */ 244235Smarkfen 254235Smarkfen #pragma ident "%Z%%M% %I% %E% SMI" 264235Smarkfen 274235Smarkfen #include <unistd.h> 284235Smarkfen #include <stdio.h> 294235Smarkfen #include <stdarg.h> 304235Smarkfen #include <stdlib.h> 314235Smarkfen #include <sys/sysconf.h> 324235Smarkfen #include <string.h> 334235Smarkfen #include <strings.h> 344235Smarkfen #include <libintl.h> 354235Smarkfen #include <locale.h> 364235Smarkfen #include <ctype.h> 374235Smarkfen #include <time.h> 384235Smarkfen #include <sys/sysmacros.h> 394235Smarkfen #include <sys/stat.h> 404235Smarkfen #include <sys/mman.h> 414235Smarkfen #include <fcntl.h> 424235Smarkfen #include <sys/socket.h> 434235Smarkfen #include <netdb.h> 444235Smarkfen #include <errno.h> 454235Smarkfen #include <assert.h> 464235Smarkfen #include <netinet/in.h> 474235Smarkfen #include <arpa/inet.h> 484235Smarkfen #include <door.h> 494235Smarkfen #include <setjmp.h> 504235Smarkfen 514235Smarkfen #include <ipsec_util.h> 524235Smarkfen #include <ikedoor.h> 534235Smarkfen 544235Smarkfen static int doorfd = -1; 554235Smarkfen 564235Smarkfen /* 574235Smarkfen * These are additional return values for the command line parsing 584235Smarkfen * function (parsecmd()). They are specific to this utility, but 594235Smarkfen * need to share the same space as the IKE_SVC_* defs, without conflicts. 604235Smarkfen * So they're defined relative to the end of that range. 614235Smarkfen */ 624235Smarkfen #define IKEADM_HELP_GENERAL IKE_SVC_MAX + 1 634235Smarkfen #define IKEADM_HELP_GET IKE_SVC_MAX + 2 644235Smarkfen #define IKEADM_HELP_SET IKE_SVC_MAX + 3 654235Smarkfen #define IKEADM_HELP_ADD IKE_SVC_MAX + 4 664235Smarkfen #define IKEADM_HELP_DEL IKE_SVC_MAX + 5 674235Smarkfen #define IKEADM_HELP_DUMP IKE_SVC_MAX + 6 684235Smarkfen #define IKEADM_HELP_FLUSH IKE_SVC_MAX + 7 694235Smarkfen #define IKEADM_HELP_READ IKE_SVC_MAX + 8 704235Smarkfen #define IKEADM_HELP_WRITE IKE_SVC_MAX + 9 714235Smarkfen #define IKEADM_HELP_HELP IKE_SVC_MAX + 10 724235Smarkfen #define IKEADM_EXIT IKE_SVC_MAX + 11 734235Smarkfen 744235Smarkfen static void 754235Smarkfen command_complete(int s) 764235Smarkfen { 774235Smarkfen if (interactive) { 784235Smarkfen longjmp(env, 1); 794235Smarkfen } else { 804235Smarkfen exit(s); 814235Smarkfen } 824235Smarkfen } 834235Smarkfen 844235Smarkfen static void 854235Smarkfen usage() 864235Smarkfen { 874235Smarkfen if (!interactive) { 884235Smarkfen (void) fprintf(stderr, gettext("Usage:\t" 894235Smarkfen "ikeadm [ -hnp ] cmd obj [cmd-specific options]\n")); 904235Smarkfen (void) fprintf(stderr, gettext(" \tikeadm help\n")); 914235Smarkfen } 924235Smarkfen 934235Smarkfen command_complete(1); 944235Smarkfen } 954235Smarkfen 964235Smarkfen static void 974235Smarkfen print_help() 984235Smarkfen { 994235Smarkfen (void) printf(gettext("Valid commands and objects:\n")); 1004235Smarkfen (void) printf( 1014235Smarkfen "\tget debug|priv|stats|p1|rule|preshared|defaults [%s]\n", 1024235Smarkfen gettext("identifier")); 1034235Smarkfen (void) printf("\tset priv %s\n", gettext("level")); 1044235Smarkfen (void) printf("\tset debug %s [%s]\n", 1054235Smarkfen gettext("level"), gettext("filename")); 1064235Smarkfen (void) printf("\tadd rule|preshared {%s}|%s\n", 1074235Smarkfen gettext("definition"), gettext("filename")); 1084235Smarkfen (void) printf("\tdel p1|rule|preshared %s\n", gettext("identifier")); 1094235Smarkfen (void) printf("\tdump p1|rule|preshared\n"); 1104235Smarkfen (void) printf("\tflush p1\n"); 1114235Smarkfen (void) printf("\tread rule|preshared [%s]\n", gettext("filename")); 1124235Smarkfen (void) printf("\twrite rule|preshared %s\n", gettext("filename")); 1134235Smarkfen (void) printf( 1144235Smarkfen "\thelp [get|set|add|del|dump|flush|read|write|help]\n"); 1154235Smarkfen (void) printf("\texit %s\n", gettext("exit the program")); 1164235Smarkfen (void) printf("\tquit %s\n", gettext("exit the program")); 1174235Smarkfen (void) printf("\n"); 1184235Smarkfen 1194235Smarkfen command_complete(0); 1204235Smarkfen } 1214235Smarkfen 1224235Smarkfen static void 1234235Smarkfen print_get_help() 1244235Smarkfen { 1254235Smarkfen (void) printf( 1264235Smarkfen gettext("This command gets information from in.iked.\n\n")); 1274235Smarkfen (void) printf(gettext("Objects that may be retrieved include:\n")); 1284235Smarkfen (void) printf("\tdebug\t\t"); 1294235Smarkfen (void) printf(gettext("the current debug level\n")); 1304235Smarkfen (void) printf("\tpriv\t\t"); 1314235Smarkfen (void) printf(gettext("the current privilege level\n")); 1324235Smarkfen (void) printf("\tstats\t\t"); 1334235Smarkfen (void) printf(gettext("current usage statistics\n")); 1344235Smarkfen (void) printf("\tp1\t\t"); 1354235Smarkfen (void) printf(gettext("a phase 1 SA, identified by\n")); 1364235Smarkfen (void) printf(gettext("\t\t\t local_ip remote_ip OR\n")); 1374235Smarkfen (void) printf(gettext("\t\t\t init_cookie resp_cookie\n")); 1384235Smarkfen (void) printf("\trule\t\t"); 1394235Smarkfen (void) printf(gettext("a phase 1 rule, identified by its label\n")); 1404235Smarkfen (void) printf("\tpreshared\t"); 1414235Smarkfen (void) printf(gettext("a preshared key, identified by\n")); 1424235Smarkfen (void) printf(gettext("\t\t\t local_ip remote_ip OR\n")); 1434235Smarkfen (void) printf(gettext("\t\t\t local_id remote_id\n")); 1444235Smarkfen (void) printf("\n"); 1454235Smarkfen 1464235Smarkfen command_complete(0); 1474235Smarkfen } 1484235Smarkfen 1494235Smarkfen static void 1504235Smarkfen print_set_help() 1514235Smarkfen { 1524235Smarkfen (void) printf(gettext("This command sets values in in.iked.\n\n")); 1534235Smarkfen (void) printf(gettext("Objects that may be set include:\n")); 1544235Smarkfen (void) printf("\tdebug\t\t"); 1554235Smarkfen (void) printf(gettext("change the debug level\n")); 1564235Smarkfen (void) printf("\tpriv\t\t"); 1574235Smarkfen (void) printf( 1584235Smarkfen gettext("change the privilege level (may only be lowered)\n")); 1594235Smarkfen (void) printf("\n"); 1604235Smarkfen 1614235Smarkfen command_complete(0); 1624235Smarkfen } 1634235Smarkfen 1644235Smarkfen static void 1654235Smarkfen print_add_help() 1664235Smarkfen { 1674235Smarkfen (void) printf( 1684235Smarkfen gettext("This command adds items to in.iked's tables.\n\n")); 1694235Smarkfen (void) printf(gettext("Objects that may be set include:\n")); 1704235Smarkfen (void) printf("\trule\t\t"); 1714235Smarkfen (void) printf(gettext("a phase 1 policy rule\n")); 1724235Smarkfen (void) printf("\tpreshared\t"); 1734235Smarkfen (void) printf(gettext("a preshared key\n")); 1744235Smarkfen (void) printf( 1754235Smarkfen gettext("\nObjects may be entered on the command-line, as a\n")); 1764235Smarkfen (void) printf( 1774235Smarkfen gettext("series of keywords and tokens contained in curly\n")); 1784235Smarkfen (void) printf( 1794235Smarkfen gettext("braces ('{', '}'); or the name of a file containing\n")); 1804235Smarkfen (void) printf(gettext("the object definition may be provided.\n\n")); 1814235Smarkfen (void) printf( 1824235Smarkfen gettext("For security purposes, preshared keys may only be\n")); 1834235Smarkfen (void) printf( 1844235Smarkfen gettext("entered on the command-line if ikeadm is running in\n")); 1854235Smarkfen (void) printf(gettext("interactive mode.\n")); 1864235Smarkfen (void) printf("\n"); 1874235Smarkfen 1884235Smarkfen command_complete(0); 1894235Smarkfen } 1904235Smarkfen 1914235Smarkfen static void 1924235Smarkfen print_del_help() 1934235Smarkfen { 1944235Smarkfen (void) printf( 1954235Smarkfen gettext("This command deletes an item from in.iked's tables.\n\n")); 1964235Smarkfen (void) printf(gettext("Objects that may be deleted include:\n")); 1974235Smarkfen (void) printf("\tp1\t\t"); 1984235Smarkfen (void) printf(gettext("a phase 1 SA, identified by\n")); 1994235Smarkfen (void) printf(gettext("\t\t\t local_ip remote_ip OR\n")); 2004235Smarkfen (void) printf(gettext("\t\t\t init_cookie resp_cookie\n")); 2014235Smarkfen (void) printf("\trule\t\t"); 2024235Smarkfen (void) printf(gettext("a phase 1 rule, identified by its label\n")); 2034235Smarkfen (void) printf("\tpreshared\t"); 2044235Smarkfen (void) printf(gettext("a preshared key, identified by\n")); 2054235Smarkfen (void) printf(gettext("\t\t\t local_ip remote_ip OR\n")); 2064235Smarkfen (void) printf(gettext("\t\t\t local_id remote_id\n")); 2074235Smarkfen (void) printf("\n"); 2084235Smarkfen 2094235Smarkfen command_complete(0); 2104235Smarkfen } 2114235Smarkfen 2124235Smarkfen static void 2134235Smarkfen print_dump_help() 2144235Smarkfen { 2154235Smarkfen (void) printf( 2164235Smarkfen gettext("This command dumps one of in.iked's tables.\n\n")); 2174235Smarkfen (void) printf(gettext("Tables that may be dumped include:\n")); 2184235Smarkfen (void) printf("\tp1\t\t"); 2194235Smarkfen (void) printf(gettext("all phase 1 SAs\n")); 2204235Smarkfen (void) printf("\trule\t\t"); 2214235Smarkfen (void) printf(gettext("all phase 1 rules\n")); 2224235Smarkfen (void) printf("\tpreshared\t"); 2234235Smarkfen (void) printf(gettext("all preshared keys\n")); 2244235Smarkfen (void) printf("\n"); 2254235Smarkfen 2264235Smarkfen command_complete(0); 2274235Smarkfen } 2284235Smarkfen 2294235Smarkfen static void 2304235Smarkfen print_flush_help() 2314235Smarkfen { 2324235Smarkfen (void) printf( 2334235Smarkfen gettext("This command clears one of in.iked's tables.\n\n")); 2344235Smarkfen (void) printf(gettext("Tables that may be flushed include:\n")); 2354235Smarkfen (void) printf("\tp1\t\t"); 2364235Smarkfen (void) printf(gettext("all phase 1 SAs\n")); 2374235Smarkfen (void) printf("\n"); 2384235Smarkfen 2394235Smarkfen command_complete(0); 2404235Smarkfen } 2414235Smarkfen 2424235Smarkfen static void 2434235Smarkfen print_read_help() 2444235Smarkfen { 2454235Smarkfen (void) printf( 2464235Smarkfen gettext("This command reads a new configuration file into\n")); 2474235Smarkfen (void) printf( 2484235Smarkfen gettext("in.iked, discarding the old configuration info.\n\n")); 2494235Smarkfen (void) printf(gettext("Sets of data that may be read include:\n")); 2504235Smarkfen (void) printf("\trule\t\t"); 2514235Smarkfen (void) printf(gettext("all phase 1 rules\n")); 2524235Smarkfen (void) printf("\tpreshared\t"); 2534235Smarkfen (void) printf(gettext("all preshared keys\n\n")); 2544235Smarkfen (void) printf( 2554235Smarkfen gettext("A filename may be provided to specify a source file\n")); 2564235Smarkfen (void) printf(gettext("other than the default.\n")); 2574235Smarkfen (void) printf("\n"); 2584235Smarkfen 2594235Smarkfen command_complete(0); 2604235Smarkfen } 2614235Smarkfen 2624235Smarkfen static void 2634235Smarkfen print_write_help() 2644235Smarkfen { 2654235Smarkfen (void) printf( 2664235Smarkfen gettext("This command writes in.iked's current configuration\n")); 2674235Smarkfen (void) printf(gettext("out to a config file.\n\n")); 2684235Smarkfen (void) printf(gettext("Sets of data that may be written include:\n")); 2694235Smarkfen (void) printf("\trule\t\t"); 2704235Smarkfen (void) printf(gettext("all phase 1 rules\n")); 2714235Smarkfen (void) printf("\tpreshared\t"); 2724235Smarkfen (void) printf(gettext("all preshared keys\n\n")); 2734235Smarkfen (void) printf( 2744235Smarkfen gettext("A filename must be provided to specify the file to\n")); 2754235Smarkfen (void) printf(gettext("which the information should be written.\n")); 2764235Smarkfen (void) printf("\n"); 2774235Smarkfen 2784235Smarkfen command_complete(0); 2794235Smarkfen } 2804235Smarkfen 2814235Smarkfen static void 2824235Smarkfen print_help_help() 2834235Smarkfen { 2844235Smarkfen (void) printf( 2854235Smarkfen gettext("This command provides information about commands.\n\n")); 2864235Smarkfen (void) printf( 2874235Smarkfen gettext("The 'help' command alone provides a list of valid\n")); 2884235Smarkfen (void) printf( 2894235Smarkfen gettext("commands, along with the valid objects for each.\n")); 2904235Smarkfen (void) printf( 2914235Smarkfen gettext("'help' followed by a valid command name provides\n")); 2924235Smarkfen (void) printf(gettext("further information about that command.\n")); 2934235Smarkfen (void) printf("\n"); 2944235Smarkfen 2954235Smarkfen command_complete(0); 2964235Smarkfen } 2974235Smarkfen 2984235Smarkfen /*PRINTFLIKE1*/ 2994235Smarkfen static void 3004235Smarkfen message(char *fmt, ...) 3014235Smarkfen { 3024235Smarkfen va_list ap; 3034235Smarkfen char msgbuf[BUFSIZ]; 3044235Smarkfen 3054235Smarkfen va_start(ap, fmt); 3064235Smarkfen (void) vsnprintf(msgbuf, BUFSIZ, fmt, ap); 3074235Smarkfen (void) fprintf(stderr, gettext("ikeadm: %s\n"), msgbuf); 3084235Smarkfen va_end(ap); 3094235Smarkfen } 3104235Smarkfen 3114235Smarkfen static int 3124235Smarkfen open_door(void) 3134235Smarkfen { 3144235Smarkfen if (doorfd >= 0) 3154235Smarkfen (void) close(doorfd); 3164235Smarkfen doorfd = open(DOORNM, O_RDWR); 3174235Smarkfen return (doorfd); 3184235Smarkfen } 3194235Smarkfen 3204235Smarkfen static ike_service_t * 3214235Smarkfen ikedoor_call(char *reqp, int size, door_desc_t *descp, int ndesc) 3224235Smarkfen { 3234235Smarkfen door_arg_t arg; 3244235Smarkfen int retries = 0; 3254235Smarkfen 3264235Smarkfen arg.data_ptr = reqp; 3274235Smarkfen arg.data_size = size; 3284235Smarkfen arg.desc_ptr = descp; 3294235Smarkfen arg.desc_num = ndesc; 3304235Smarkfen arg.rbuf = (char *)NULL; 3314235Smarkfen arg.rsize = 0; 3324235Smarkfen 3334235Smarkfen retry: 3344235Smarkfen if (door_call(doorfd, &arg) < 0) { 3354235Smarkfen if ((errno == EBADF) && ((++retries < 2) && 3364235Smarkfen (open_door() >= 0))) 3374235Smarkfen goto retry; 3384235Smarkfen (void) fprintf(stderr, 3394235Smarkfen gettext("Unable to communicate with in.iked\n")); 3404235Smarkfen Bail("door_call failed"); 3414235Smarkfen } 3424235Smarkfen 3434235Smarkfen if ((ndesc > 0) && (descp->d_attributes & DOOR_RELEASE) && 3444235Smarkfen ((errno == EBADF) || (errno == EFAULT))) { 3454235Smarkfen /* callers assume passed fds will be closed no matter what */ 3464235Smarkfen (void) close(descp->d_data.d_desc.d_descriptor); 3474235Smarkfen } 3484235Smarkfen 3494235Smarkfen /* LINTED E_BAD_PTR_CAST_ALIGN */ 3504235Smarkfen return ((ike_service_t *)arg.rbuf); 3514235Smarkfen } 3524235Smarkfen 3534235Smarkfen /* 3544235Smarkfen * Parsing functions 3554235Smarkfen */ 3564235Smarkfen 3574235Smarkfen /* stolen from ipseckey.c, with a second tier added */ 3584235Smarkfen static int 3594235Smarkfen parsecmd(char *cmdstr, char *objstr) 3604235Smarkfen { 3614235Smarkfen #define MAXOBJS 10 3624235Smarkfen struct objtbl { 3634235Smarkfen char *obj; 3644235Smarkfen int token; 3654235Smarkfen }; 3664235Smarkfen static struct cmdtbl { 3674235Smarkfen char *cmd; 3684235Smarkfen int null_obj_token; 3694235Smarkfen struct objtbl objt[MAXOBJS]; 3704235Smarkfen } table[] = { 3714235Smarkfen {"get", IKE_SVC_ERROR, { 3724235Smarkfen {"debug", IKE_SVC_GET_DBG}, 3734235Smarkfen {"priv", IKE_SVC_GET_PRIV}, 3744235Smarkfen {"stats", IKE_SVC_GET_STATS}, 3754235Smarkfen {"p1", IKE_SVC_GET_P1}, 3764235Smarkfen {"rule", IKE_SVC_GET_RULE}, 3774235Smarkfen {"preshared", IKE_SVC_GET_PS}, 3784235Smarkfen {"defaults", IKE_SVC_GET_DEFS}, 3794235Smarkfen {NULL, IKE_SVC_ERROR}, 3804235Smarkfen } 3814235Smarkfen }, 3824235Smarkfen {"set", IKE_SVC_ERROR, { 3834235Smarkfen {"debug", IKE_SVC_SET_DBG}, 3844235Smarkfen {"priv", IKE_SVC_SET_PRIV}, 3854235Smarkfen {NULL, IKE_SVC_ERROR}, 3864235Smarkfen } 3874235Smarkfen }, 3884235Smarkfen {"add", IKE_SVC_ERROR, { 3894235Smarkfen {"rule", IKE_SVC_NEW_RULE}, 3904235Smarkfen {"preshared", IKE_SVC_NEW_PS}, 3914235Smarkfen {NULL, IKE_SVC_ERROR}, 3924235Smarkfen } 3934235Smarkfen }, 3944235Smarkfen {"del", IKE_SVC_ERROR, { 3954235Smarkfen {"p1", IKE_SVC_DEL_P1}, 3964235Smarkfen {"rule", IKE_SVC_DEL_RULE}, 3974235Smarkfen {"preshared", IKE_SVC_DEL_PS}, 3984235Smarkfen {NULL, IKE_SVC_ERROR}, 3994235Smarkfen } 4004235Smarkfen }, 4014235Smarkfen {"dump", IKE_SVC_ERROR, { 4024235Smarkfen {"p1", IKE_SVC_DUMP_P1S}, 4034235Smarkfen {"rule", IKE_SVC_DUMP_RULES}, 4044235Smarkfen {"preshared", IKE_SVC_DUMP_PS}, 4054235Smarkfen {NULL, IKE_SVC_ERROR}, 4064235Smarkfen } 4074235Smarkfen }, 4084235Smarkfen {"flush", IKE_SVC_ERROR, { 4094235Smarkfen {"p1", IKE_SVC_FLUSH_P1S}, 4104235Smarkfen {NULL, IKE_SVC_ERROR}, 4114235Smarkfen } 4124235Smarkfen }, 4134235Smarkfen {"read", IKE_SVC_ERROR, { 4144235Smarkfen {"rule", IKE_SVC_READ_RULES}, 4154235Smarkfen {"preshared", IKE_SVC_READ_PS}, 4164235Smarkfen {NULL, IKE_SVC_ERROR}, 4174235Smarkfen } 4184235Smarkfen }, 4194235Smarkfen {"write", IKE_SVC_ERROR, { 4204235Smarkfen {"rule", IKE_SVC_WRITE_RULES}, 4214235Smarkfen {"preshared", IKE_SVC_WRITE_PS}, 4224235Smarkfen {NULL, IKE_SVC_ERROR}, 4234235Smarkfen } 4244235Smarkfen }, 4254235Smarkfen {"help", IKEADM_HELP_GENERAL, { 4264235Smarkfen {"get", IKEADM_HELP_GET}, 4274235Smarkfen {"set", IKEADM_HELP_SET}, 4284235Smarkfen {"add", IKEADM_HELP_ADD}, 4294235Smarkfen {"del", IKEADM_HELP_DEL}, 4304235Smarkfen {"dump", IKEADM_HELP_DUMP}, 4314235Smarkfen {"flush", IKEADM_HELP_FLUSH}, 4324235Smarkfen {"read", IKEADM_HELP_READ}, 4334235Smarkfen {"write", IKEADM_HELP_WRITE}, 4344235Smarkfen {"help", IKEADM_HELP_HELP}, 4354235Smarkfen {NULL, IKE_SVC_ERROR}, 4364235Smarkfen } 4374235Smarkfen }, 4384235Smarkfen {"exit", IKEADM_EXIT, { 4394235Smarkfen {NULL, IKE_SVC_ERROR}, 4404235Smarkfen } 4414235Smarkfen }, 4424235Smarkfen {"quit", IKEADM_EXIT, { 4434235Smarkfen {NULL, IKE_SVC_ERROR}, 4444235Smarkfen } 4454235Smarkfen }, 4464235Smarkfen {"dbg", IKE_SVC_ERROR, { 4474235Smarkfen {"rbdump", IKE_SVC_DBG_RBDUMP}, 4484235Smarkfen {NULL, IKE_SVC_ERROR}, 4494235Smarkfen } 4504235Smarkfen }, 4514235Smarkfen {NULL, IKE_SVC_ERROR, { 4524235Smarkfen {NULL, IKE_SVC_ERROR}, 4534235Smarkfen } 4544235Smarkfen }, 4554235Smarkfen }; 4564235Smarkfen struct cmdtbl *ct = table; 4574235Smarkfen struct objtbl *ot; 4584235Smarkfen 4594235Smarkfen if (cmdstr == NULL) { 4604235Smarkfen return (IKE_SVC_ERROR); 4614235Smarkfen } 4624235Smarkfen 4634235Smarkfen while (ct->cmd != NULL && strcmp(ct->cmd, cmdstr) != 0) 4644235Smarkfen ct++; 4654235Smarkfen ot = ct->objt; 4664235Smarkfen 4674235Smarkfen if (ct->cmd == NULL) { 4684235Smarkfen message(gettext("Unrecognized command '%s'"), cmdstr); 4694235Smarkfen return (ot->token); 4704235Smarkfen } 4714235Smarkfen 4724235Smarkfen if (objstr == NULL) { 4734235Smarkfen return (ct->null_obj_token); 4744235Smarkfen } 4754235Smarkfen 4764235Smarkfen while (ot->obj != NULL && strcmp(ot->obj, objstr) != 0) 4774235Smarkfen ot++; 4784235Smarkfen 4794235Smarkfen if (ot->obj == NULL) 4804235Smarkfen message(gettext("Unrecognized object '%s'"), objstr); 4814235Smarkfen 4824235Smarkfen return (ot->token); 4834235Smarkfen } 4844235Smarkfen 4854235Smarkfen /* 4864235Smarkfen * Parsing functions: 4874235Smarkfen * Parse command-line identification info. All return -1 on failure, 4884235Smarkfen * or the number of cmd-line args "consumed" on success (though argc 4894235Smarkfen * and argv params are not actually modified). 4904235Smarkfen */ 4914235Smarkfen 4924235Smarkfen static int 4934235Smarkfen parse_label(int argc, char **argv, char *label) 4944235Smarkfen { 4954235Smarkfen if ((argc < 1) || (argv == NULL)) 4964235Smarkfen return (-1); 4974235Smarkfen 4984235Smarkfen if (strlcpy(label, argv[0], MAX_LABEL_LEN) >= MAX_LABEL_LEN) 4994235Smarkfen return (-1); 5004235Smarkfen 5014235Smarkfen return (1); 5024235Smarkfen } 5034235Smarkfen 5044235Smarkfen /* 5054235Smarkfen * Parse an address off the command line. In the hpp param, either 5064235Smarkfen * return a hostent pointer (caller frees) or a pointer to a dummy_he_t 5074235Smarkfen * (must also be freed by the caller; both cases are handled by the 5084235Smarkfen * macro FREE_HE). The new getipnodebyname() call does the Right Thing 5094235Smarkfen * (TM), even with raw addresses (colon-separated IPv6 or dotted decimal 5104235Smarkfen * IPv4). 5114235Smarkfen * (mostly stolen from ipseckey.c, though some tweaks were made 5124235Smarkfen * to better serve our purposes here.) 5134235Smarkfen */ 5144235Smarkfen 5154235Smarkfen typedef struct { 5164235Smarkfen struct hostent he; 5174235Smarkfen char *addtl[2]; 5184235Smarkfen } dummy_he_t; 5194235Smarkfen 5204235Smarkfen static int 5214235Smarkfen parse_addr(int argc, char **argv, struct hostent **hpp) 5224235Smarkfen { 5234235Smarkfen int hp_errno; 5244235Smarkfen struct hostent *hp = NULL; 5254235Smarkfen dummy_he_t *dhp; 5264235Smarkfen char *addr1; 5274235Smarkfen 5284235Smarkfen if ((argc < 1) || (argv == NULL) || (argv[0] == NULL)) 5294235Smarkfen return (-1); 5304235Smarkfen 5314235Smarkfen if (!nflag) { 5324235Smarkfen /* 5334235Smarkfen * Try name->address first. Assume AF_INET6, and 5344235Smarkfen * get IPV4s, plus IPv6s iff IPv6 is configured. 5354235Smarkfen */ 5364235Smarkfen hp = getipnodebyname(argv[0], AF_INET6, AI_DEFAULT | AI_ALL, 5374235Smarkfen &hp_errno); 5384235Smarkfen } else { 5394235Smarkfen /* 5404235Smarkfen * Try a normal address conversion only. malloc a 5414235Smarkfen * dummy_he_t to construct a fake hostent. Caller 5424235Smarkfen * will know to free this one using free_he(). 5434235Smarkfen */ 5444235Smarkfen dhp = (dummy_he_t *)malloc(sizeof (dummy_he_t)); 5454235Smarkfen addr1 = (char *)malloc(sizeof (struct in6_addr)); 5464235Smarkfen if (inet_pton(AF_INET6, argv[0], addr1) == 1) { 5474235Smarkfen dhp->he.h_addr_list = dhp->addtl; 5484235Smarkfen dhp->addtl[0] = addr1; 5494235Smarkfen dhp->addtl[1] = NULL; 5504235Smarkfen hp = &dhp->he; 5514235Smarkfen dhp->he.h_addrtype = AF_INET6; 5524235Smarkfen dhp->he.h_length = sizeof (struct in6_addr); 5534235Smarkfen } else if (inet_pton(AF_INET, argv[0], addr1) == 1) { 5544235Smarkfen dhp->he.h_addr_list = dhp->addtl; 5554235Smarkfen dhp->addtl[0] = addr1; 5564235Smarkfen dhp->addtl[1] = NULL; 5574235Smarkfen hp = &dhp->he; 5584235Smarkfen dhp->he.h_addrtype = AF_INET; 5594235Smarkfen dhp->he.h_length = sizeof (struct in_addr); 5604235Smarkfen } else { 5614235Smarkfen hp = NULL; 5624235Smarkfen } 5634235Smarkfen } 5644235Smarkfen 5654235Smarkfen *hpp = hp; 5664235Smarkfen 5674235Smarkfen if (hp == NULL) { 5684235Smarkfen message(gettext("Unknown address %s."), argv[0]); 5694235Smarkfen return (-1); 5704235Smarkfen } 5714235Smarkfen 5724235Smarkfen return (1); 5734235Smarkfen } 5744235Smarkfen 5754235Smarkfen /* 5764235Smarkfen * Free a dummy_he_t structure that was malloc'd in parse_addr(). 5774235Smarkfen * Unfortunately, callers of parse_addr don't want to know about 5784235Smarkfen * dummy_he_t structs, so all they have is a pointer to the struct 5794235Smarkfen * hostent; so that's what's passed in. To manage this, we make 5804235Smarkfen * the assumption that the struct hostent is the first field in 5814235Smarkfen * the dummy_he_t, and therefore a pointer to it is a pointer to 5824235Smarkfen * the dummy_he_t. 5834235Smarkfen */ 5844235Smarkfen static void 5854235Smarkfen free_he(struct hostent *hep) 5864235Smarkfen { 5874235Smarkfen dummy_he_t *p = (dummy_he_t *)hep; 5884235Smarkfen 5894235Smarkfen assert(p != NULL); 5904235Smarkfen 5914235Smarkfen if (p->addtl[0]) 5924235Smarkfen free(p->addtl[0]); 5934235Smarkfen if (p->addtl[1]) 5944235Smarkfen free(p->addtl[1]); 5954235Smarkfen 5964235Smarkfen free(p); 5974235Smarkfen } 5984235Smarkfen 5994235Smarkfen #define FREE_HE(x) \ 6004235Smarkfen if (nflag) \ 6014235Smarkfen free_he(x); \ 6024235Smarkfen else \ 6034235Smarkfen freehostent(x) 6044235Smarkfen 6054235Smarkfen static void 6064235Smarkfen headdr2sa(char *hea, struct sockaddr_storage *sa, int len) 6074235Smarkfen { 6084235Smarkfen struct sockaddr_in *sin; 6094235Smarkfen struct sockaddr_in6 *sin6; 6104235Smarkfen 6114235Smarkfen if (len == sizeof (struct in6_addr)) { 6124235Smarkfen /* LINTED E_BAD_PTR_CAST_ALIGN */ 6134235Smarkfen if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)hea)) { 6144235Smarkfen sin = (struct sockaddr_in *)sa; 6154235Smarkfen (void) memset(sin, 0, sizeof (*sin)); 6164235Smarkfen /* LINTED E_BAD_PTR_CAST_ALIGN */ 6174235Smarkfen IN6_V4MAPPED_TO_INADDR((struct in6_addr *)hea, 6184235Smarkfen &sin->sin_addr); 6194235Smarkfen sin->sin_family = AF_INET; 6204235Smarkfen } else { 6214235Smarkfen sin6 = (struct sockaddr_in6 *)sa; 6224235Smarkfen (void) memset(sin6, 0, sizeof (*sin6)); 6234235Smarkfen (void) memcpy(&sin6->sin6_addr, hea, 6244235Smarkfen sizeof (struct in6_addr)); 6254235Smarkfen sin6->sin6_family = AF_INET6; 6264235Smarkfen } 6274235Smarkfen } else { 6284235Smarkfen sin = (struct sockaddr_in *)sa; 6294235Smarkfen (void) memset(sin, 0, sizeof (*sin)); 6304235Smarkfen (void) memcpy(&sin->sin_addr, hea, sizeof (struct in_addr)); 6314235Smarkfen sin->sin_family = AF_INET; 6324235Smarkfen } 6334235Smarkfen } 6344235Smarkfen 6354235Smarkfen /* 6364235Smarkfen * The possible ident-type keywords that might be used on the command 6374235Smarkfen * line. This is a superset of the ones supported by ipseckey, those 6384235Smarkfen * in the ike config file, and those in ike.preshared. 6394235Smarkfen */ 6404235Smarkfen static keywdtab_t idtypes[] = { 6414235Smarkfen /* ip, ipv4, and ipv6 are valid for preshared keys... */ 6424235Smarkfen {SADB_IDENTTYPE_RESERVED, "ip"}, 6434235Smarkfen {SADB_IDENTTYPE_RESERVED, "ipv4"}, 6444235Smarkfen {SADB_IDENTTYPE_RESERVED, "ipv6"}, 6454235Smarkfen {SADB_IDENTTYPE_PREFIX, "prefix"}, 6464235Smarkfen {SADB_IDENTTYPE_PREFIX, "ipv4-prefix"}, 6474235Smarkfen {SADB_IDENTTYPE_PREFIX, "ipv6-prefix"}, 6484235Smarkfen {SADB_IDENTTYPE_PREFIX, "subnet"}, 6494235Smarkfen {SADB_IDENTTYPE_PREFIX, "subnetv4"}, 6504235Smarkfen {SADB_IDENTTYPE_PREFIX, "subnetv6"}, 6514235Smarkfen {SADB_IDENTTYPE_FQDN, "fqdn"}, 6524235Smarkfen {SADB_IDENTTYPE_FQDN, "dns"}, 6534235Smarkfen {SADB_IDENTTYPE_FQDN, "domain"}, 6544235Smarkfen {SADB_IDENTTYPE_FQDN, "domainname"}, 6554235Smarkfen {SADB_IDENTTYPE_USER_FQDN, "user_fqdn"}, 6564235Smarkfen {SADB_IDENTTYPE_USER_FQDN, "mbox"}, 6574235Smarkfen {SADB_IDENTTYPE_USER_FQDN, "mailbox"}, 6584235Smarkfen {SADB_X_IDENTTYPE_DN, "dn"}, 6594235Smarkfen {SADB_X_IDENTTYPE_DN, "asn1dn"}, 6604235Smarkfen {SADB_X_IDENTTYPE_GN, "gn"}, 6614235Smarkfen {SADB_X_IDENTTYPE_GN, "asn1gn"}, 6624235Smarkfen {SADB_X_IDENTTYPE_ADDR_RANGE, "ipv4-range"}, 6634235Smarkfen {SADB_X_IDENTTYPE_ADDR_RANGE, "ipv6-range"}, 6644235Smarkfen {SADB_X_IDENTTYPE_ADDR_RANGE, "rangev4"}, 6654235Smarkfen {SADB_X_IDENTTYPE_ADDR_RANGE, "rangev6"}, 6664235Smarkfen {SADB_X_IDENTTYPE_KEY_ID, "keyid"}, 6674235Smarkfen {NULL, 0} 6684235Smarkfen }; 6694235Smarkfen 6704235Smarkfen static int 6714235Smarkfen parse_idtype(char *type, uint16_t *idnum) 6724235Smarkfen { 6734235Smarkfen keywdtab_t *idp; 6744235Smarkfen 6754235Smarkfen if (type == NULL) 6764235Smarkfen return (-1); 6774235Smarkfen 6784235Smarkfen for (idp = idtypes; idp->kw_str != NULL; idp++) { 6794235Smarkfen if (strcasecmp(idp->kw_str, type) == 0) { 6804235Smarkfen if (idnum != NULL) 6814235Smarkfen *idnum = idp->kw_tag; 6824235Smarkfen return (1); 6834235Smarkfen } 6844235Smarkfen } 6854235Smarkfen 6864235Smarkfen return (-1); 6874235Smarkfen } 6884235Smarkfen 6894235Smarkfen /* 6904235Smarkfen * The sadb_ident_t is malloc'd, since its length varies; 6914235Smarkfen * so the caller must free() it when done with the data. 6924235Smarkfen */ 6934235Smarkfen static int 6944235Smarkfen parse_ident(int argc, char **argv, sadb_ident_t **idpp) 6954235Smarkfen { 6964235Smarkfen int alloclen, consumed; 6974235Smarkfen sadb_ident_t *idp; 6984235Smarkfen if ((argc < 2) || (argv == NULL) || (argv[0] == NULL) || 6994235Smarkfen (argv[1] == NULL)) 7004235Smarkfen return (-1); 7014235Smarkfen 7024235Smarkfen alloclen = sizeof (sadb_ident_t) + IKEDOORROUNDUP(strlen(argv[1]) + 1); 7034235Smarkfen *idpp = idp = (sadb_ident_t *)malloc(alloclen); 7044235Smarkfen if (idp == NULL) 7054235Smarkfen Bail("parsing identity"); 7064235Smarkfen 7074235Smarkfen if ((consumed = parse_idtype(argv[0], &idp->sadb_ident_type)) < 0) { 7084235Smarkfen message(gettext("unknown identity type %s."), argv[0]); 7094235Smarkfen return (-1); 7104235Smarkfen } 7114235Smarkfen 7124235Smarkfen idp->sadb_ident_len = SADB_8TO64(alloclen); 7134235Smarkfen idp->sadb_ident_reserved = 0; 7144235Smarkfen idp->sadb_ident_id = 0; 7154235Smarkfen 7164235Smarkfen /* now copy in identity param */ 7174235Smarkfen (void) strlcpy((char *)(idp + 1), argv[1], 7184235Smarkfen alloclen - (sizeof (sadb_ident_t))); 7194235Smarkfen 7204235Smarkfen return (++consumed); 7214235Smarkfen } 7224235Smarkfen 7234235Smarkfen static int 7244235Smarkfen parse_cky(int argc, char **argv, uint64_t *ckyp) 7254235Smarkfen { 7264235Smarkfen u_longlong_t arg; 7274235Smarkfen 7284235Smarkfen if ((argc < 1) || (argv[0] == NULL)) 7294235Smarkfen return (-1); 7304235Smarkfen 7314235Smarkfen errno = 0; 7324235Smarkfen arg = strtoull(argv[0], NULL, 0); 7334235Smarkfen if (errno != 0) { 7344235Smarkfen message(gettext("failed to parse cookie %s."), argv[0]); 7354235Smarkfen return (-1); 7364235Smarkfen } 7374235Smarkfen 7384235Smarkfen *ckyp = (uint64_t)arg; 7394235Smarkfen 7404235Smarkfen return (1); 7414235Smarkfen } 7424235Smarkfen 7434235Smarkfen static int 7444235Smarkfen parse_addr_pr(int argc, char **argv, struct hostent **h1pp, 7454235Smarkfen struct hostent **h2pp) 7464235Smarkfen { 7474235Smarkfen int rtn, consumed = 0; 7484235Smarkfen 7494235Smarkfen if ((rtn = parse_addr(argc, argv, h1pp)) < 0) { 7504235Smarkfen return (-1); 7514235Smarkfen } 7524235Smarkfen consumed = rtn; 7534235Smarkfen argc -= rtn; 7544235Smarkfen argv += rtn; 7554235Smarkfen 7564235Smarkfen if ((rtn = parse_addr(argc, argv, h2pp)) < 0) { 7574235Smarkfen FREE_HE(*h1pp); 7584235Smarkfen return (-1); 7594235Smarkfen } 7604235Smarkfen consumed += rtn; 7614235Smarkfen 7624235Smarkfen return (consumed); 7634235Smarkfen } 7644235Smarkfen 7654235Smarkfen /* 7664235Smarkfen * The sadb_ident_ts are malloc'd, since their length varies; 7674235Smarkfen * so the caller must free() them when done with the data. 7684235Smarkfen */ 7694235Smarkfen static int 7704235Smarkfen parse_ident_pr(int argc, char **argv, sadb_ident_t **id1pp, 7714235Smarkfen sadb_ident_t **id2pp) 7724235Smarkfen { 7734235Smarkfen int rtn, consumed = 0; 7744235Smarkfen 7754235Smarkfen if ((rtn = parse_ident(argc, argv, id1pp)) < 0) { 7764235Smarkfen return (-1); 7774235Smarkfen } 7784235Smarkfen consumed = rtn; 7794235Smarkfen argc -= rtn; 7804235Smarkfen argv += rtn; 7814235Smarkfen 7824235Smarkfen (*id1pp)->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC; 7834235Smarkfen 7844235Smarkfen if ((rtn = parse_ident(argc, argv, id2pp)) < 0) { 7854235Smarkfen free(*id1pp); 7864235Smarkfen return (-1); 7874235Smarkfen } 7884235Smarkfen consumed += rtn; 7894235Smarkfen 7904235Smarkfen (*id2pp)->sadb_ident_exttype = SADB_EXT_IDENTITY_DST; 7914235Smarkfen 7924235Smarkfen return (consumed); 7934235Smarkfen } 7944235Smarkfen 7954235Smarkfen static int 7964235Smarkfen parse_cky_pr(int argc, char **argv, ike_cky_pr_t *cpr) 7974235Smarkfen { 7984235Smarkfen int rtn, consumed = 0; 7994235Smarkfen 8004235Smarkfen if ((rtn = parse_cky(argc, argv, &cpr->cky_i)) < 0) { 8014235Smarkfen return (-1); 8024235Smarkfen } 8034235Smarkfen consumed = rtn; 8044235Smarkfen argc -= rtn; 8054235Smarkfen argv += rtn; 8064235Smarkfen 8074235Smarkfen if ((rtn = parse_cky(argc, argv, &cpr->cky_r)) < 0) { 8084235Smarkfen return (-1); 8094235Smarkfen } 8104235Smarkfen consumed += rtn; 8114235Smarkfen 8124235Smarkfen return (consumed); 8134235Smarkfen } 8144235Smarkfen 8154235Smarkfen /* 8164235Smarkfen * Preshared key field types...used for parsing preshared keys that 8174235Smarkfen * have been entered on the command line. The code to parse preshared 8184235Smarkfen * keys (parse_ps, parse_key, parse_psfldid, parse_ikmtype, ...) is 8194235Smarkfen * mostly duplicated from in.iked's readps.c. 8204235Smarkfen */ 8214235Smarkfen #define PSFLD_LOCID 1 8224235Smarkfen #define PSFLD_LOCIDTYPE 2 8234235Smarkfen #define PSFLD_REMID 3 8244235Smarkfen #define PSFLD_REMIDTYPE 4 8254235Smarkfen #define PSFLD_MODE 5 8264235Smarkfen #define PSFLD_KEY 6 8274235Smarkfen 8284235Smarkfen static keywdtab_t psfldtypes[] = { 8294235Smarkfen {PSFLD_LOCID, "localid"}, 8304235Smarkfen {PSFLD_LOCIDTYPE, "localidtype"}, 8314235Smarkfen {PSFLD_REMID, "remoteid"}, 8324235Smarkfen {PSFLD_REMIDTYPE, "remoteidtype"}, 8334235Smarkfen {PSFLD_MODE, "ike_mode"}, 8344235Smarkfen {PSFLD_KEY, "key"}, 8354235Smarkfen {NULL, 0} 8364235Smarkfen }; 8374235Smarkfen 8384235Smarkfen static int 8394235Smarkfen parse_psfldid(char *type, uint16_t *idnum) 8404235Smarkfen { 8414235Smarkfen keywdtab_t *pfp; 8424235Smarkfen 8434235Smarkfen if (type == NULL) 8444235Smarkfen return (-1); 8454235Smarkfen 8464235Smarkfen for (pfp = psfldtypes; pfp->kw_str != NULL; pfp++) { 8474235Smarkfen if (strcasecmp(pfp->kw_str, type) == 0) { 8484235Smarkfen if (idnum != NULL) 8494235Smarkfen *idnum = pfp->kw_tag; 8504235Smarkfen return (1); 8514235Smarkfen } 8524235Smarkfen } 8534235Smarkfen 8544235Smarkfen return (-1); 8554235Smarkfen } 8564235Smarkfen 8574235Smarkfen static keywdtab_t ikemodes[] = { 8584235Smarkfen {IKE_XCHG_IDENTITY_PROTECT, "main"}, 8594235Smarkfen {IKE_XCHG_AGGRESSIVE, "aggressive"}, 8604235Smarkfen {IKE_XCHG_IP_AND_AGGR, "both"}, 8614235Smarkfen {NULL, 0} 8624235Smarkfen }; 8634235Smarkfen 8644235Smarkfen static int 8654235Smarkfen parse_ikmtype(char *mode, uint16_t *modenum) 8664235Smarkfen { 8674235Smarkfen keywdtab_t *ikmp; 8684235Smarkfen 8694235Smarkfen if (mode == NULL) 8704235Smarkfen return (-1); 8714235Smarkfen 8724235Smarkfen for (ikmp = ikemodes; ikmp->kw_str != NULL; ikmp++) { 8734235Smarkfen if (strcasecmp(ikmp->kw_str, mode) == 0) { 8744235Smarkfen if (modenum != NULL) 8754235Smarkfen *modenum = ikmp->kw_tag; 8764235Smarkfen return (1); 8774235Smarkfen } 8784235Smarkfen } 8794235Smarkfen 8804235Smarkfen return (-1); 8814235Smarkfen } 8824235Smarkfen 8834235Smarkfen #define hd2num(hd) (((hd) >= '0' && (hd) <= '9') ? ((hd) - '0') : \ 8844235Smarkfen (((hd) >= 'a' && (hd) <= 'f') ? ((hd) - 'a' + 10) : ((hd) - 'A' + 10))) 8854235Smarkfen 8864235Smarkfen static uint8_t * 8874235Smarkfen parse_key(char *input, uint_t *keybuflen, uint_t *lbits) 8884235Smarkfen { 8894235Smarkfen uint8_t *keyp, *keybufp; 8904235Smarkfen uint_t i, hexlen = 0, bits, alloclen; 8914235Smarkfen 8924235Smarkfen for (i = 0; input[i] != '\0' && input[i] != '/'; i++) 8934235Smarkfen hexlen++; 8944235Smarkfen 8954235Smarkfen if (input[i] == '\0') { 8964235Smarkfen bits = 0; 8974235Smarkfen } else { 8984235Smarkfen /* Have /nn. */ 8994235Smarkfen input[i] = '\0'; 9004235Smarkfen if (sscanf((input + i + 1), "%u", &bits) != 1) 9014235Smarkfen return (NULL); 9024235Smarkfen 9034235Smarkfen /* hexlen is in nibbles */ 9044235Smarkfen if (((bits + 3) >> 2) > hexlen) 9054235Smarkfen return (NULL); 9064235Smarkfen 9074235Smarkfen /* 9084235Smarkfen * Adjust hexlen down if user gave us too small of a bit 9094235Smarkfen * count. 9104235Smarkfen */ 9114235Smarkfen if ((hexlen << 2) > bits + 3) { 9124235Smarkfen hexlen = (bits + 3) >> 2; 9134235Smarkfen input[hexlen] = '\0'; 9144235Smarkfen } 9154235Smarkfen } 9164235Smarkfen 9174235Smarkfen /* 9184235Smarkfen * Allocate. Remember, hexlen is in nibbles. 9194235Smarkfen */ 9204235Smarkfen 9214235Smarkfen alloclen = (hexlen/2 + (hexlen & 0x1)); 9224235Smarkfen keyp = malloc(alloclen); 9234235Smarkfen 9244235Smarkfen if (keyp == NULL) 9254235Smarkfen return (NULL); 9264235Smarkfen 9274235Smarkfen keybufp = keyp; 9284235Smarkfen *keybuflen = alloclen; 9294235Smarkfen if (bits == 0) 9304235Smarkfen *lbits = (hexlen + (hexlen & 0x1)) << 2; 9314235Smarkfen else 9324235Smarkfen *lbits = bits; 9334235Smarkfen 9344235Smarkfen /* 9354235Smarkfen * Read in nibbles. Read in odd-numbered as shifted high. 9364235Smarkfen * (e.g. 123 becomes 0x1230). 9374235Smarkfen */ 9384235Smarkfen for (i = 0; input[i] != '\0'; i += 2) { 9394235Smarkfen boolean_t second = (input[i + 1] != '\0'); 9404235Smarkfen 9414235Smarkfen if (!isxdigit(input[i]) || 9424235Smarkfen (!isxdigit(input[i + 1]) && second)) { 9434235Smarkfen free(keyp); 9444235Smarkfen return (NULL); 9454235Smarkfen } 9464235Smarkfen *keyp = (hd2num(input[i]) << 4); 9474235Smarkfen if (second) 9484235Smarkfen *keyp |= hd2num(input[i + 1]); 9494235Smarkfen else 9504235Smarkfen break; /* out of for loop. */ 9514235Smarkfen keyp++; 9524235Smarkfen } 9534235Smarkfen 9544235Smarkfen /* zero the remaining bits if we're a non-octet amount. */ 9554235Smarkfen if (bits & 0x7) 9564235Smarkfen *((input[i] == '\0') ? keyp - 1 : keyp) &= 9574235Smarkfen 0xff << (8 - (bits & 0x7)); 9584235Smarkfen return (keybufp); 9594235Smarkfen } 9604235Smarkfen 9614235Smarkfen /* 9624235Smarkfen * the ike_ps_t struct (plus trailing data) will be allocated here, 9634235Smarkfen * so it will need to be freed by the caller. 9644235Smarkfen */ 9654235Smarkfen static int 9664235Smarkfen parse_ps(int argc, char **argv, ike_ps_t **presharedpp, int *len) 9674235Smarkfen { 9684235Smarkfen uint_t c = 0, locidlen, remidlen, keylen, keybits; 9694235Smarkfen uint_t a_locidtotal = 0, a_remidtotal = 0; 9704235Smarkfen char *locid, *remid; 9714235Smarkfen uint8_t *keyp = NULL; 9724235Smarkfen uint16_t fldid, locidtype, remidtype, mtype; 9734235Smarkfen struct hostent *loche = NULL, *remhe = NULL; 9744235Smarkfen ike_ps_t *psp = NULL; 9754235Smarkfen sadb_ident_t *sidp; 9764235Smarkfen boolean_t whacked = B_FALSE; 9774235Smarkfen 9784235Smarkfen if ((argv[c] == NULL) || (argv[c][0] != '{')) 9794235Smarkfen return (-1); 9804235Smarkfen if (argv[c][1] != 0) { 9814235Smarkfen /* no space between '{' and first token */ 9824235Smarkfen argv[c]++; 9834235Smarkfen } else { 9844235Smarkfen c++; 9854235Smarkfen } 9864235Smarkfen if ((argv[argc - 1][strlen(argv[argc - 1]) - 1] == '}') && 9874235Smarkfen (argv[argc - 1][0] != '}')) { 9884235Smarkfen /* 9894235Smarkfen * whack '}' without a space before it or parsers break. 9904235Smarkfen * Remember this trailing character for later 9914235Smarkfen */ 9924235Smarkfen argv[argc - 1][strlen(argv[argc - 1]) - 1] = '\0'; 9934235Smarkfen whacked = B_TRUE; 9944235Smarkfen } 9954235Smarkfen 9964235Smarkfen while ((c < argc) && (argv[c] != NULL) && (argv[c][0] != '}')) { 9974235Smarkfen if ((argv[c + 1] == NULL) || (argv[c + 1][0] == '}')) 9984235Smarkfen goto bail; 9994235Smarkfen if (parse_psfldid(argv[c++], &fldid) < 0) 10004235Smarkfen goto bail; 10014235Smarkfen switch (fldid) { 10024235Smarkfen case PSFLD_LOCID: 10034235Smarkfen locid = argv[c++]; 10044235Smarkfen locidlen = strlen(locid) + 1; 10054235Smarkfen break; 10064235Smarkfen case PSFLD_LOCIDTYPE: 10074235Smarkfen if (parse_idtype(argv[c++], &locidtype) < 0) 10084235Smarkfen goto bail; 10094235Smarkfen break; 10104235Smarkfen case PSFLD_REMID: 10114235Smarkfen remid = argv[c++]; 10124235Smarkfen remidlen = strlen(remid) + 1; 10134235Smarkfen break; 10144235Smarkfen case PSFLD_REMIDTYPE: 10154235Smarkfen if (parse_idtype(argv[c++], &remidtype) < 0) 10164235Smarkfen goto bail; 10174235Smarkfen break; 10184235Smarkfen case PSFLD_MODE: 10194235Smarkfen if (parse_ikmtype(argv[c++], &mtype) < 0) 10204235Smarkfen goto bail; 10214235Smarkfen break; 10224235Smarkfen case PSFLD_KEY: 10234235Smarkfen keyp = parse_key(argv[c++], &keylen, &keybits); 10244235Smarkfen if (keyp == NULL) 10254235Smarkfen goto bail; 10264235Smarkfen break; 10274235Smarkfen } 10284235Smarkfen } 10294235Smarkfen 10304235Smarkfen /* Make sure the line was terminated with '}' */ 10314235Smarkfen if (argv[c] == NULL) { 10324235Smarkfen if (!whacked) 10334235Smarkfen goto bail; 10344235Smarkfen } else if (argv[c][0] != '}') { 10354235Smarkfen goto bail; 10364235Smarkfen } 10374235Smarkfen 10384235Smarkfen /* 10394235Smarkfen * make sure we got all the required fields. If no idtype, assume 10404235Smarkfen * ip addr; if that translation fails, we'll catch the error then. 10414235Smarkfen */ 10424235Smarkfen if (locid == NULL || remid == NULL || keyp == NULL || mtype == 0) 10434235Smarkfen goto bail; 10444235Smarkfen 10454235Smarkfen /* figure out the size buffer we need */ 10464235Smarkfen *len = sizeof (ike_ps_t); 10474235Smarkfen if (locidtype != SADB_IDENTTYPE_RESERVED) { 10484235Smarkfen a_locidtotal = IKEDOORROUNDUP(sizeof (sadb_ident_t) + locidlen); 10494235Smarkfen *len += a_locidtotal; 10504235Smarkfen } 10514235Smarkfen if (remidtype != SADB_IDENTTYPE_RESERVED) { 10524235Smarkfen a_remidtotal = IKEDOORROUNDUP(sizeof (sadb_ident_t) + remidlen); 10534235Smarkfen *len += a_remidtotal; 10544235Smarkfen } 10554235Smarkfen *len += keylen; 10564235Smarkfen 10574235Smarkfen psp = malloc(*len); 10584235Smarkfen if (psp == NULL) 10594235Smarkfen goto bail; 10604235Smarkfen (void) memset(psp, 0, *len); 10614235Smarkfen 10624235Smarkfen psp->ps_ike_mode = mtype; 10634235Smarkfen 10644235Smarkfen psp->ps_localid_off = sizeof (ike_ps_t); 10654235Smarkfen if (locidtype == SADB_IDENTTYPE_RESERVED) { 10664235Smarkfen /* 10674235Smarkfen * this is an ip address, store in the sockaddr field; 10684235Smarkfen * we won't use an sadb_ident_t. 10694235Smarkfen */ 10704235Smarkfen psp->ps_localid_len = 0; 10714235Smarkfen if (parse_addr(1, &locid, &loche) < 0) 10724235Smarkfen goto bail; 10734235Smarkfen if (loche->h_addr_list[1] != NULL) { 10744235Smarkfen message(gettext("preshared key identifier cannot " 10754235Smarkfen "match multiple IP addresses")); 10764235Smarkfen goto bail; 10774235Smarkfen } 10784235Smarkfen headdr2sa(loche->h_addr_list[0], &psp->ps_ipaddrs.loc_addr, 10794235Smarkfen loche->h_length); 10804235Smarkfen FREE_HE(loche); 10814235Smarkfen } else { 10824235Smarkfen psp->ps_localid_len = sizeof (sadb_ident_t) + locidlen; 10834235Smarkfen sidp = (sadb_ident_t *)((int)psp + psp->ps_localid_off); 10844235Smarkfen sidp->sadb_ident_len = psp->ps_localid_len; 10854235Smarkfen sidp->sadb_ident_type = locidtype; 10864235Smarkfen (void) strlcpy((char *)(sidp + 1), locid, a_locidtotal); 10874235Smarkfen } 10884235Smarkfen 10894235Smarkfen psp->ps_remoteid_off = psp->ps_localid_off + a_locidtotal; 10904235Smarkfen if (remidtype == SADB_IDENTTYPE_RESERVED) { 10914235Smarkfen /* 10924235Smarkfen * this is an ip address, store in the sockaddr field; 10934235Smarkfen * we won't use an sadb_ident_t. 10944235Smarkfen */ 10954235Smarkfen psp->ps_remoteid_len = 0; 10964235Smarkfen if (parse_addr(1, &remid, &remhe) < 0) 10974235Smarkfen goto bail; 10984235Smarkfen if (remhe->h_addr_list[1] != NULL) { 10994235Smarkfen message(gettext("preshared key identifier cannot " 11004235Smarkfen "match multiple IP addresses")); 11014235Smarkfen goto bail; 11024235Smarkfen } 11034235Smarkfen headdr2sa(remhe->h_addr_list[0], &psp->ps_ipaddrs.rem_addr, 11044235Smarkfen remhe->h_length); 11054235Smarkfen FREE_HE(remhe); 11064235Smarkfen } else { 11074235Smarkfen /* make sure we have at least 16-bit alignment */ 11084235Smarkfen if (remidlen & 0x1) 11094235Smarkfen remidlen++; 11104235Smarkfen psp->ps_remoteid_len = sizeof (sadb_ident_t) + remidlen; 11114235Smarkfen sidp = (sadb_ident_t *)((int)psp + psp->ps_remoteid_off); 11124235Smarkfen sidp->sadb_ident_len = psp->ps_remoteid_len; 11134235Smarkfen sidp->sadb_ident_type = remidtype; 11144235Smarkfen (void) strlcpy((char *)(sidp + 1), remid, a_remidtotal); 11154235Smarkfen } 11164235Smarkfen 11174235Smarkfen psp->ps_key_off = psp->ps_remoteid_off + a_remidtotal; 11184235Smarkfen psp->ps_key_len = keylen; 11194235Smarkfen psp->ps_key_bits = keybits; 11204235Smarkfen (void) memcpy((uint8_t *)((int)psp + psp->ps_key_off), keyp, keylen); 11214235Smarkfen 11224235Smarkfen *presharedpp = psp; 11234235Smarkfen 11244235Smarkfen return (c); 11254235Smarkfen 11264235Smarkfen bail: 11274235Smarkfen if (loche != NULL) 11284235Smarkfen FREE_HE(loche); 11294235Smarkfen if (remhe != NULL) 11304235Smarkfen FREE_HE(remhe); 11314235Smarkfen if (keyp != NULL) 11324235Smarkfen free(keyp); 11334235Smarkfen if (psp != NULL) 11344235Smarkfen free(psp); 11354235Smarkfen 11364235Smarkfen *presharedpp = NULL; 11374235Smarkfen 11384235Smarkfen return (-1); 11394235Smarkfen } 11404235Smarkfen 11414235Smarkfen /* stolen from libdhcputil (dhcp_inittab.c) */ 11424235Smarkfen static uint64_t 11434235Smarkfen ike_ntohll(uint64_t nll) 11444235Smarkfen { 11454235Smarkfen #ifdef _LITTLE_ENDIAN 11464235Smarkfen return ((uint64_t)ntohl(nll & 0xffffffff) << 32 | ntohl(nll >> 32)); 11474235Smarkfen #else 11484235Smarkfen return (nll); 11494235Smarkfen #endif 11504235Smarkfen } 11514235Smarkfen 11524235Smarkfen /* 11534235Smarkfen * Printing functions 11544235Smarkfen * 11554235Smarkfen * A potential point of confusion here is that the ikeadm-specific string- 11564235Smarkfen * producing functions do not match the ipsec_util.c versions in style: the 11574235Smarkfen * ikeadm-specific functions return a string (and are named foostr), while 11584235Smarkfen * the ipsec_util.c functions actually print the string to the file named 11594235Smarkfen * in the second arg to the function (and are named dump_foo). 11604235Smarkfen * 11614235Smarkfen * The reason for this is that in the context of the ikeadm output, it 11624235Smarkfen * seemed like the localization of the text would be more straightforward 11634235Smarkfen * (and could more easily accomodate non-english grammar!) if more complete 11644235Smarkfen * phrases were being translated, rather than a bit of a phrase followed by 11654235Smarkfen * a call to dump_foo() followed by more of the phrase. 11664235Smarkfen */ 11674235Smarkfen 11684235Smarkfen static char * 11694235Smarkfen errstr(int err) 11704235Smarkfen { 11714235Smarkfen static char rtn[MAXLINESIZE]; 11724235Smarkfen 11734235Smarkfen switch (err) { 11744235Smarkfen case IKE_ERR_NO_OBJ: 11754235Smarkfen return (gettext("No data returned")); 11764235Smarkfen case IKE_ERR_NO_DESC: 11774235Smarkfen return (gettext("No destination provided")); 11784235Smarkfen case IKE_ERR_ID_INVALID: 11794235Smarkfen return (gettext("Id info invalid")); 11804235Smarkfen case IKE_ERR_LOC_INVALID: 11814235Smarkfen return (gettext("Destination invalid")); 11824235Smarkfen case IKE_ERR_CMD_INVALID: 11834235Smarkfen return (gettext("Command invalid")); 11844235Smarkfen case IKE_ERR_DATA_INVALID: 11854235Smarkfen return (gettext("Supplied data invalid")); 11864235Smarkfen case IKE_ERR_CMD_NOTSUP: 11874235Smarkfen return (gettext("Unknown command")); 11884235Smarkfen case IKE_ERR_REQ_INVALID: 11894235Smarkfen return (gettext("Request invalid")); 11904235Smarkfen case IKE_ERR_NO_PRIV: 11914235Smarkfen return (gettext("Not allowed at current privilege level")); 11924235Smarkfen case IKE_ERR_SYS_ERR: 11934235Smarkfen return (gettext("System error")); 11944235Smarkfen case IKE_ERR_DUP_IGNORED: 11954235Smarkfen return (gettext("One or more duplicate entries ignored")); 11964235Smarkfen default: 11974235Smarkfen (void) snprintf(rtn, MAXLINESIZE, 11984235Smarkfen gettext("<unknown error %d>"), err); 11994235Smarkfen return (rtn); 12004235Smarkfen } 12014235Smarkfen } 12024235Smarkfen 12034235Smarkfen static char * 12044235Smarkfen dbgstr(int bit) 12054235Smarkfen { 12064235Smarkfen static char rtn[MAXLINESIZE]; 12074235Smarkfen 12084235Smarkfen switch (bit) { 12094235Smarkfen case D_CERT: 12104235Smarkfen return (gettext("Certificate management")); 12114235Smarkfen case D_KEY: 12124235Smarkfen return (gettext("Key management")); 12134235Smarkfen case D_OP: 12144235Smarkfen return (gettext("Operational")); 12154235Smarkfen case D_P1: 12164235Smarkfen return (gettext("Phase 1 SA creation")); 12174235Smarkfen case D_P2: 12184235Smarkfen return (gettext("Phase 2 SA creation")); 12194235Smarkfen case D_PFKEY: 12204235Smarkfen return (gettext("PF_KEY interface")); 12214235Smarkfen case D_POL: 12224235Smarkfen return (gettext("Policy management")); 12234235Smarkfen case D_PROP: 12244235Smarkfen return (gettext("Proposal construction")); 12254235Smarkfen case D_DOOR: 12264235Smarkfen return (gettext("Door interface")); 12274235Smarkfen case D_CONFIG: 12284235Smarkfen return (gettext("Config file processing")); 12294235Smarkfen default: 12304235Smarkfen (void) snprintf(rtn, MAXLINESIZE, 12314235Smarkfen gettext("<unknown flag 0x%x>"), bit); 12324235Smarkfen return (rtn); 12334235Smarkfen } 12344235Smarkfen } 12354235Smarkfen 12364235Smarkfen static char * 12374235Smarkfen privstr(int priv) 12384235Smarkfen { 12394235Smarkfen static char rtn[MAXLINESIZE]; 12404235Smarkfen 12414235Smarkfen switch (priv) { 12424235Smarkfen case IKE_PRIV_MINIMUM: 12434235Smarkfen return (gettext("base privileges")); 12444235Smarkfen case IKE_PRIV_MODKEYS: 12454235Smarkfen return (gettext("access to preshared key information")); 12464235Smarkfen case IKE_PRIV_KEYMAT: 12474235Smarkfen return (gettext("access to keying material")); 12484235Smarkfen default: 12494235Smarkfen (void) snprintf(rtn, MAXLINESIZE, 12504235Smarkfen gettext("<unknown level %d>"), priv); 12514235Smarkfen return (rtn); 12524235Smarkfen } 12534235Smarkfen } 12544235Smarkfen 12554235Smarkfen static char * 12564235Smarkfen xchgstr(int xchg) 12574235Smarkfen { 12584235Smarkfen static char rtn[MAXLINESIZE]; 12594235Smarkfen 12604235Smarkfen switch (xchg) { 12614235Smarkfen case IKE_XCHG_NONE: 12624235Smarkfen return (gettext("<unspecified>")); 12634235Smarkfen case IKE_XCHG_BASE: 12644235Smarkfen return (gettext("base")); 12654235Smarkfen case IKE_XCHG_IDENTITY_PROTECT: 12664235Smarkfen return (gettext("main mode (identity protect)")); 12674235Smarkfen case IKE_XCHG_AUTH_ONLY: 12684235Smarkfen return (gettext("authentication only")); 12694235Smarkfen case IKE_XCHG_AGGRESSIVE: 12704235Smarkfen return (gettext("aggressive mode")); 12714235Smarkfen case IKE_XCHG_IP_AND_AGGR: 12724235Smarkfen return (gettext("main and aggressive mode")); 12734235Smarkfen case IKE_XCHG_ANY: 12744235Smarkfen return (gettext("any mode")); 12754235Smarkfen default: 12764235Smarkfen (void) snprintf(rtn, MAXLINESIZE, 12774235Smarkfen gettext("<unknown %d>"), xchg); 12784235Smarkfen return (rtn); 12794235Smarkfen } 12804235Smarkfen } 12814235Smarkfen 12824235Smarkfen static char * 12834235Smarkfen statestr(int state) 12844235Smarkfen { 12854235Smarkfen static char rtn[MAXLINESIZE]; 12864235Smarkfen 12874235Smarkfen switch (state) { 12884235Smarkfen case IKE_SA_STATE_INIT: 12894235Smarkfen return (gettext("INITIALIZING")); 12904235Smarkfen case IKE_SA_STATE_SENT_SA: 12914235Smarkfen return (gettext("SENT FIRST MSG (SA)")); 12924235Smarkfen case IKE_SA_STATE_SENT_KE: 12934235Smarkfen return (gettext("SENT SECOND MSG (KE)")); 12944235Smarkfen case IKE_SA_STATE_SENT_LAST: 12954235Smarkfen return (gettext("SENT FINAL MSG")); 12964235Smarkfen case IKE_SA_STATE_DONE: 12974235Smarkfen return (gettext("ACTIVE")); 12984235Smarkfen case IKE_SA_STATE_DELETED: 12994235Smarkfen return (gettext("DELETED")); 13004235Smarkfen case IKE_SA_STATE_INVALID: 13014235Smarkfen return (gettext("<invalid>")); 13024235Smarkfen default: 13034235Smarkfen (void) snprintf(rtn, MAXLINESIZE, 13044235Smarkfen gettext("<unknown %d>"), state); 13054235Smarkfen return (rtn); 13064235Smarkfen } 13074235Smarkfen } 13084235Smarkfen 13094235Smarkfen static char * 13104235Smarkfen authmethstr(int meth) 13114235Smarkfen { 13124235Smarkfen static char rtn[MAXLINESIZE]; 13134235Smarkfen 13144235Smarkfen switch (meth) { 13154235Smarkfen case IKE_AUTH_METH_PRE_SHARED_KEY: 13164235Smarkfen return (gettext("pre-shared key")); 13174235Smarkfen case IKE_AUTH_METH_DSS_SIG: 13184235Smarkfen return (gettext("DSS signatures")); 13194235Smarkfen case IKE_AUTH_METH_RSA_SIG: 13204235Smarkfen return (gettext("RSA signatures")); 13214235Smarkfen case IKE_AUTH_METH_RSA_ENCR: 13224235Smarkfen return (gettext("RSA Encryption")); 13234235Smarkfen case IKE_AUTH_METH_RSA_ENCR_REVISED: 13244235Smarkfen return (gettext("Revised RSA Encryption")); 13254235Smarkfen default: 13264235Smarkfen (void) snprintf(rtn, MAXLINESIZE, 13274235Smarkfen gettext("<unknown %d>"), meth); 13284235Smarkfen return (rtn); 13294235Smarkfen } 13304235Smarkfen } 13314235Smarkfen 13324235Smarkfen static char * 13334235Smarkfen prfstr(int prf) 13344235Smarkfen { 13354235Smarkfen static char rtn[MAXLINESIZE]; 13364235Smarkfen 13374235Smarkfen switch (prf) { 13384235Smarkfen case IKE_PRF_NONE: 13394235Smarkfen return (gettext("<unknown>")); 13404235Smarkfen case IKE_PRF_HMAC_MD5: 13414235Smarkfen return ("HMAC MD5"); 13424235Smarkfen case IKE_PRF_HMAC_SHA1: 13434235Smarkfen return ("HMAC SHA1"); 1344*6126Sdanmcd case IKE_PRF_HMAC_SHA256: 1345*6126Sdanmcd return ("HMAC SHA256"); 1346*6126Sdanmcd case IKE_PRF_HMAC_SHA384: 1347*6126Sdanmcd return ("HMAC SHA384"); 1348*6126Sdanmcd case IKE_PRF_HMAC_SHA512: 1349*6126Sdanmcd return ("HMAC SHA512"); 13504235Smarkfen default: 13514235Smarkfen (void) snprintf(rtn, MAXLINESIZE, 13524235Smarkfen gettext("<unknown %d>"), prf); 13534235Smarkfen return (rtn); 13544235Smarkfen } 13554235Smarkfen } 13564235Smarkfen 13574235Smarkfen static char * 13584235Smarkfen dhstr(int grp) 13594235Smarkfen { 13604235Smarkfen static char rtn[MAXLINESIZE]; 13614235Smarkfen 13624235Smarkfen switch (grp) { 13634235Smarkfen case 0: 13644731Smarkfen return (gettext("<unavailable>")); 13654235Smarkfen case IKE_GRP_DESC_MODP_768: 13664731Smarkfen return (gettext("768-bit MODP (group 1)")); 13674235Smarkfen case IKE_GRP_DESC_MODP_1024: 13684731Smarkfen return (gettext("1024-bit MODP (group 2)")); 13694235Smarkfen case IKE_GRP_DESC_EC2N_155: 13704235Smarkfen return (gettext("EC2N group on GP[2^155]")); 13714235Smarkfen case IKE_GRP_DESC_EC2N_185: 13724235Smarkfen return (gettext("EC2N group on GP[2^185]")); 13734235Smarkfen case IKE_GRP_DESC_MODP_1536: 13744731Smarkfen return (gettext("1536-bit MODP (group 5)")); 13754731Smarkfen case IKE_GRP_DESC_MODP_2048: 13764731Smarkfen return (gettext("2048-bit MODP (group 14)")); 13774731Smarkfen case IKE_GRP_DESC_MODP_3072: 13784731Smarkfen return (gettext("3072-bit MODP (group 15)")); 13794731Smarkfen case IKE_GRP_DESC_MODP_4096: 13804731Smarkfen return (gettext("4096-bit MODP (group 16)")); 13814731Smarkfen case IKE_GRP_DESC_MODP_6144: 13824731Smarkfen return (gettext("6144-bit MODP (group 17)")); 13834731Smarkfen case IKE_GRP_DESC_MODP_8192: 13844731Smarkfen return (gettext("8192-bit MODP (group 18)")); 13854235Smarkfen default: 13864235Smarkfen (void) snprintf(rtn, MAXLINESIZE, gettext("<unknown %d>"), grp); 13874235Smarkfen return (rtn); 13884235Smarkfen } 13894235Smarkfen } 13904235Smarkfen 13914235Smarkfen static void 13924235Smarkfen print_hdr(char *prefix, ike_p1_hdr_t *hdrp) 13934235Smarkfen { 13944235Smarkfen (void) printf( 13954235Smarkfen gettext("%s Cookies: Initiator 0x%llx Responder 0x%llx\n"), 13964235Smarkfen prefix, ike_ntohll(hdrp->p1hdr_cookies.cky_i), 13974235Smarkfen ike_ntohll(hdrp->p1hdr_cookies.cky_r)); 13984235Smarkfen (void) printf(gettext("%s The local host is the %s.\n"), prefix, 13994235Smarkfen hdrp->p1hdr_isinit ? gettext("initiator") : gettext("responder")); 14004235Smarkfen (void) printf(gettext("%s ISAKMP version %d.%d; %s exchange\n"), prefix, 14014235Smarkfen hdrp->p1hdr_major, hdrp->p1hdr_minor, xchgstr(hdrp->p1hdr_xchg)); 14024235Smarkfen (void) printf(gettext("%s Current state is %s"), prefix, 14034235Smarkfen statestr(hdrp->p1hdr_state)); 14044235Smarkfen (void) printf("\n"); 14054235Smarkfen } 14064235Smarkfen 14074235Smarkfen static void 14084235Smarkfen print_lt_limits(char *prefix, ike_p1_xform_t *xfp) 14094235Smarkfen { 14104235Smarkfen (void) printf(gettext("%s Lifetime limits:\n"), prefix); 14114235Smarkfen (void) printf(gettext("%s %u seconds; %u kbytes protected; "), 14124235Smarkfen prefix, xfp->p1xf_max_secs, xfp->p1xf_max_kbytes); 14134235Smarkfen (void) printf(gettext("%u keymat provided.\n"), xfp->p1xf_max_keyuses); 14144235Smarkfen } 14154235Smarkfen 14164235Smarkfen #define LT_USAGE_LEN 16 /* 1 uint64 + 2 uint32s */ 14174235Smarkfen static void 14184235Smarkfen print_lt_usage(char *prefix, ike_p1_stats_t *sp) 14194235Smarkfen { 14204235Smarkfen time_t scratch; 14214235Smarkfen char tbuf[TBUF_SIZE]; 14224235Smarkfen 14234235Smarkfen (void) printf(gettext("%s Current usage:\n"), prefix); 14244235Smarkfen scratch = (time_t)sp->p1stat_start; 14254235Smarkfen if (strftime(tbuf, TBUF_SIZE, NULL, localtime(&scratch)) == 0) 14264235Smarkfen (void) strlcpy(tbuf, gettext("<time conversion failed>"), 14274235Smarkfen TBUF_SIZE); 14284235Smarkfen (void) printf(gettext("%s SA was created at %s\n"), prefix, tbuf); 14294235Smarkfen (void) printf(gettext("%s %u kbytes protected; %u keymat provided.\n"), 14304235Smarkfen prefix, sp->p1stat_kbytes, sp->p1stat_keyuses); 14314235Smarkfen } 14324235Smarkfen 14334235Smarkfen static void 14344235Smarkfen print_xform(char *prefix, ike_p1_xform_t *xfp, boolean_t print_lifetimes) 14354235Smarkfen { 14364235Smarkfen (void) printf(gettext("%s Authentication method: %s"), prefix, 14374235Smarkfen authmethstr(xfp->p1xf_auth_meth)); 14384235Smarkfen (void) printf(gettext("\n%s Encryption alg: "), prefix); 14394235Smarkfen (void) dump_ealg(xfp->p1xf_encr_alg, stdout); 14404235Smarkfen if (xfp->p1xf_encr_low_bits != 0) { 14414235Smarkfen (void) printf(gettext("(%d..%d)"), xfp->p1xf_encr_low_bits, 14424235Smarkfen xfp->p1xf_encr_high_bits); 14434235Smarkfen } 14444235Smarkfen (void) printf(gettext("; Authentication alg: ")); 14454235Smarkfen (void) dump_aalg(xfp->p1xf_auth_alg, stdout); 14464235Smarkfen (void) printf(gettext("\n%s PRF: %s"), prefix, prfstr(xfp->p1xf_prf)); 14474235Smarkfen (void) printf(gettext("; Oakley Group: %s\n"), 14484235Smarkfen dhstr(xfp->p1xf_dh_group)); 14494235Smarkfen if (xfp->p1xf_pfs == 0) { 14504235Smarkfen (void) printf(gettext("%s Phase 2 PFS is not used\n"), prefix); 14514235Smarkfen } else { 14524235Smarkfen (void) printf(gettext( 14534235Smarkfen "%s Phase 2 PFS is required (Oakley Group: %s)\n"), 14544235Smarkfen prefix, dhstr(xfp->p1xf_pfs)); 14554235Smarkfen } 14564235Smarkfen 14574235Smarkfen if (print_lifetimes) 14584235Smarkfen print_lt_limits(prefix, xfp); 14594235Smarkfen } 14604235Smarkfen 14614235Smarkfen static void 14624235Smarkfen print_lifetime(char *prefix, ike_p1_xform_t *xfp, ike_p1_stats_t *sp, 14634235Smarkfen int statlen) 14644235Smarkfen { 14654235Smarkfen time_t current, remain, exp; 14664235Smarkfen char tbuf[TBUF_SIZE]; 14674235Smarkfen 14684235Smarkfen current = time(NULL); 14694235Smarkfen 14704235Smarkfen print_lt_limits(prefix, xfp); 14714235Smarkfen 14724235Smarkfen /* 14734235Smarkfen * make sure the stats struct we've been passed is as big 14744235Smarkfen * as we expect it to be. The usage stats are at the end, 14754235Smarkfen * so anything less than the size we expect won't work. 14764235Smarkfen */ 14774235Smarkfen if (statlen >= sizeof (ike_p1_stats_t)) { 14784235Smarkfen print_lt_usage(prefix, sp); 14794235Smarkfen } else { 14804235Smarkfen return; 14814235Smarkfen } 14824235Smarkfen 14834235Smarkfen (void) printf(gettext("%s Expiration info:\n"), prefix); 14844235Smarkfen 14854235Smarkfen if (xfp->p1xf_max_kbytes != 0) 14864235Smarkfen (void) printf(gettext("%s %u more bytes can be protected.\n"), 14874235Smarkfen prefix, xfp->p1xf_max_kbytes - sp->p1stat_kbytes); 14884235Smarkfen 14894235Smarkfen if (xfp->p1xf_max_keyuses != 0) 14904235Smarkfen (void) printf(gettext("%s Keying material can be provided " 14914235Smarkfen "%u more times.\n"), prefix, 14924235Smarkfen xfp->p1xf_max_keyuses - sp->p1stat_keyuses); 14934235Smarkfen 14944235Smarkfen if (xfp->p1xf_max_secs != 0) { 14954235Smarkfen exp = (time_t)sp->p1stat_start + (time_t)xfp->p1xf_max_secs; 14964235Smarkfen remain = exp - current; 14974235Smarkfen if (strftime(tbuf, TBUF_SIZE, NULL, localtime(&exp)) == 0) 14984235Smarkfen (void) strlcpy(tbuf, 14994235Smarkfen gettext("<time conversion failed>"), TBUF_SIZE); 15004235Smarkfen /* 15014235Smarkfen * The SA may have expired but still exist because libike 15024235Smarkfen * has not freed it yet. 15034235Smarkfen */ 15044235Smarkfen if (remain > 0) 15054235Smarkfen (void) printf(gettext( 15064235Smarkfen "%s SA expires in %lu seconds, at %s\n"), 15074235Smarkfen prefix, remain, tbuf); 15084235Smarkfen else 15094235Smarkfen (void) printf(gettext("%s SA Expired at %s\n"), 15104235Smarkfen prefix, tbuf); 15114235Smarkfen } 15124235Smarkfen } 15134235Smarkfen 15144235Smarkfen /* used to verify structure lengths... */ 15154235Smarkfen #define COUNTER_32BIT 4 15164235Smarkfen #define COUNTER_PAIR 8 15174235Smarkfen 15184235Smarkfen static void 15194235Smarkfen print_p1stats(char *prefix, ike_p1_stats_t *sp, int statlen, 15204235Smarkfen boolean_t print_lifetimes) 15214235Smarkfen { 15224235Smarkfen if (statlen < COUNTER_PAIR) 15234235Smarkfen return; 15244235Smarkfen (void) printf(gettext("%s %u Quick Mode SAs created; "), prefix, 15254235Smarkfen sp->p1stat_new_qm_sas); 15264235Smarkfen (void) printf(gettext("%u Quick Mode SAs deleted\n"), 15274235Smarkfen sp->p1stat_del_qm_sas); 15284235Smarkfen statlen -= COUNTER_PAIR; 15294235Smarkfen 15304235Smarkfen if ((print_lifetimes) && (statlen >= LT_USAGE_LEN)) 15314235Smarkfen print_lt_usage(prefix, sp); 15324235Smarkfen } 15334235Smarkfen 15344235Smarkfen static void 15354235Smarkfen print_errs(char *prefix, ike_p1_errors_t *errp, int errlen) 15364235Smarkfen { 15374235Smarkfen /* 15384235Smarkfen * Don't try to break this one up; it's either all or nothing! 15394235Smarkfen */ 15404235Smarkfen if (errlen < sizeof (ike_p1_errors_t)) 15414235Smarkfen return; 15424235Smarkfen 15434235Smarkfen (void) printf(gettext("%s %u RX errors: "), prefix, 15444235Smarkfen errp->p1err_decrypt + errp->p1err_hash + errp->p1err_otherrx); 15454235Smarkfen (void) printf(gettext("%u decryption, %u hash, %u other\n"), 15464235Smarkfen errp->p1err_decrypt, errp->p1err_hash, errp->p1err_otherrx); 15474235Smarkfen (void) printf(gettext("%s %u TX errors\n"), prefix, errp->p1err_tx); 15484235Smarkfen } 15494235Smarkfen 15504235Smarkfen static void 15514235Smarkfen print_addr_range(char *prefix, ike_addr_pr_t *pr) 15524235Smarkfen { 15534235Smarkfen boolean_t range = B_TRUE; 15544235Smarkfen struct sockaddr_storage *beg, *end; 15554235Smarkfen struct sockaddr_in *bsin, *esin; 15564235Smarkfen struct sockaddr_in6 *bsin6, *esin6; 15574235Smarkfen 15584235Smarkfen beg = &pr->beg_iprange; 15594235Smarkfen end = &pr->end_iprange; 15604235Smarkfen 15614235Smarkfen if (beg->ss_family != end->ss_family) { 15624235Smarkfen (void) printf(gettext("%s invalid address range\n"), prefix); 15634235Smarkfen return; 15644235Smarkfen } 15654235Smarkfen 15664235Smarkfen switch (beg->ss_family) { 15674235Smarkfen case AF_INET: 15684235Smarkfen bsin = (struct sockaddr_in *)beg; 15694235Smarkfen esin = (struct sockaddr_in *)end; 15704235Smarkfen if ((uint32_t)bsin->sin_addr.s_addr == 15714235Smarkfen (uint32_t)esin->sin_addr.s_addr) 15724235Smarkfen range = B_FALSE; 15734235Smarkfen break; 15744235Smarkfen case AF_INET6: 15754235Smarkfen bsin6 = (struct sockaddr_in6 *)beg; 15764235Smarkfen esin6 = (struct sockaddr_in6 *)end; 15774235Smarkfen if (IN6_ARE_ADDR_EQUAL(&bsin6->sin6_addr, &esin6->sin6_addr)) 15784235Smarkfen range = B_FALSE; 15794235Smarkfen break; 15804235Smarkfen default: 15814235Smarkfen (void) printf(gettext("%s invalid address range\n"), prefix); 15824235Smarkfen return; 15834235Smarkfen } 15844235Smarkfen 15854235Smarkfen (void) printf("%s ", prefix); 15864867Spwernau (void) dump_sockaddr((struct sockaddr *)beg, 0, B_TRUE, stdout, nflag); 15874235Smarkfen if (range) { 15884235Smarkfen (void) printf(" - "); 15894867Spwernau (void) dump_sockaddr((struct sockaddr *)end, 0, B_TRUE, stdout, 15904867Spwernau nflag); 15914235Smarkfen } 15924235Smarkfen (void) printf("\n"); 15934235Smarkfen 15944235Smarkfen } 15954235Smarkfen 15964235Smarkfen /* 15974235Smarkfen * used to tell printing function if info should be identified 15984235Smarkfen * as belonging to initiator, responder, or neither 15994235Smarkfen */ 16004235Smarkfen #define IS_INITIATOR 1 16014235Smarkfen #define IS_RESPONDER 2 16024235Smarkfen #define DONT_PRINT_INIT 3 16034235Smarkfen 16044235Smarkfen static void 16054235Smarkfen print_addr(char *prefix, struct sockaddr_storage *sa, int init_instr) 16064235Smarkfen { 16074235Smarkfen (void) printf(gettext("%s Address"), prefix); 16084235Smarkfen 16094235Smarkfen if (init_instr != DONT_PRINT_INIT) 16104235Smarkfen (void) printf(" (%s):\n", (init_instr == IS_INITIATOR) ? 16114235Smarkfen gettext("Initiator") : gettext("Responder")); 16124235Smarkfen else 16134235Smarkfen (void) printf(":\n"); 16144235Smarkfen 16154235Smarkfen (void) printf("%s ", prefix); 16164867Spwernau (void) dump_sockaddr((struct sockaddr *)sa, 0, B_FALSE, stdout, nflag); 16174235Smarkfen } 16184235Smarkfen 16194235Smarkfen static void 16204235Smarkfen print_id(char *prefix, sadb_ident_t *idp, int init_instr) 16214235Smarkfen { 16224235Smarkfen boolean_t canprint; 16234235Smarkfen 16244235Smarkfen switch (init_instr) { 16254235Smarkfen case IS_INITIATOR: 16264235Smarkfen (void) printf(gettext("%s Initiator identity, "), prefix); 16274235Smarkfen break; 16284235Smarkfen case IS_RESPONDER: 16294235Smarkfen (void) printf(gettext("%s Responder identity, "), prefix); 16304235Smarkfen break; 16314235Smarkfen case DONT_PRINT_INIT: 16324235Smarkfen (void) printf(gettext("%s Identity, "), prefix); 16334235Smarkfen break; 16344235Smarkfen default: 16354235Smarkfen (void) printf(gettext("<invalid identity>\n")); 16364235Smarkfen return; 16374235Smarkfen } 16384235Smarkfen (void) printf(gettext("uid=%d, type "), idp->sadb_ident_id); 16394235Smarkfen canprint = dump_sadb_idtype(idp->sadb_ident_type, stdout, NULL); 16406119Spwernau if (canprint) { 16414235Smarkfen (void) printf("\n%s %s\n", prefix, (char *)(idp + 1)); 16426119Spwernau } else { 16436119Spwernau (void) printf(gettext("\n%s "), prefix); 16446119Spwernau print_asn1_name(stdout, 16456119Spwernau (const unsigned char *)(idp + 1), 16466119Spwernau SADB_64TO8(idp->sadb_ident_len) - sizeof (sadb_ident_t)); 16476119Spwernau } 16484235Smarkfen } 16494235Smarkfen 16504235Smarkfen static void 16514235Smarkfen print_idspec(char *prefix, char *idp, int icnt, int ecnt) 16524235Smarkfen { 16534235Smarkfen int i; 16544235Smarkfen 16554235Smarkfen (void) printf(gettext("%s Identity descriptors:\n"), prefix); 16564235Smarkfen 16574235Smarkfen for (i = 0; i < icnt; i++) { 16584235Smarkfen if (i == 0) 16594235Smarkfen (void) printf(gettext("%s Includes:\n"), prefix); 16604235Smarkfen (void) printf("%s %s\n", prefix, idp); 16614235Smarkfen idp += strlen(idp) + 1; 16624235Smarkfen } 16634235Smarkfen 16644235Smarkfen for (i = 0; i < ecnt; i++) { 16654235Smarkfen if (i == 0) 16664235Smarkfen (void) printf(gettext("%s Excludes:\n"), prefix); 16674235Smarkfen (void) printf("%s %s\n", prefix, idp); 16684235Smarkfen idp += strlen(idp) + 1; 16694235Smarkfen } 16704235Smarkfen } 16714235Smarkfen 16724235Smarkfen static void 16734235Smarkfen print_keys(char *prefix, ike_p1_key_t *keyp, int size) 16744235Smarkfen { 16754235Smarkfen uint32_t *curp; 16764235Smarkfen ike_p1_key_t *p; 16774235Smarkfen int ssize; 16784235Smarkfen 16794235Smarkfen curp = (uint32_t *)keyp; 16804235Smarkfen 16814235Smarkfen ssize = sizeof (ike_p1_key_t); 16824235Smarkfen 16834235Smarkfen while ((intptr_t)curp - (intptr_t)keyp < size) { 16844235Smarkfen size_t p1klen, len; 16854235Smarkfen 16864235Smarkfen p = (ike_p1_key_t *)curp; 16874235Smarkfen p1klen = p->p1key_len; 16884235Smarkfen len = p1klen - ssize; 16894235Smarkfen 16904235Smarkfen p1klen = roundup(p1klen, sizeof (ike_p1_key_t)); 16914235Smarkfen if (p1klen < ssize) { 16924235Smarkfen (void) printf(gettext("Short key\n")); 16934235Smarkfen break; 16944235Smarkfen } 16954235Smarkfen 16964235Smarkfen switch (p->p1key_type) { 16974235Smarkfen case IKE_KEY_PRESHARED: 16984235Smarkfen (void) printf(gettext("%s Pre-shared key (%d bytes): "), 16994235Smarkfen prefix, len); 17004235Smarkfen (void) dump_key((uint8_t *)(p + 1), SADB_8TO1(len), 17014235Smarkfen stdout); 17024235Smarkfen break; 17034235Smarkfen case IKE_KEY_SKEYID: 17044235Smarkfen (void) printf(gettext("%s SKEYID (%d bytes): "), 17054235Smarkfen prefix, len); 17064235Smarkfen (void) dump_key((uint8_t *)(p + 1), SADB_8TO1(len), 17074235Smarkfen stdout); 17084235Smarkfen break; 17094235Smarkfen case IKE_KEY_SKEYID_D: 17104235Smarkfen (void) printf(gettext("%s SKEYID_d (%d bytes): "), 17114235Smarkfen prefix, len); 17124235Smarkfen (void) dump_key((uint8_t *)(p + 1), SADB_8TO1(len), 17134235Smarkfen stdout); 17144235Smarkfen break; 17154235Smarkfen case IKE_KEY_SKEYID_A: 17164235Smarkfen (void) printf(gettext("%s SKEYID_a (%d bytes): "), 17174235Smarkfen prefix, len); 17184235Smarkfen (void) dump_key((uint8_t *)(p + 1), SADB_8TO1(len), 17194235Smarkfen stdout); 17204235Smarkfen break; 17214235Smarkfen case IKE_KEY_SKEYID_E: 17224235Smarkfen (void) printf(gettext("%s SKEYID_e (%d bytes): "), 17234235Smarkfen prefix, len); 17244235Smarkfen (void) dump_key((uint8_t *)(p + 1), SADB_8TO1(len), 17254235Smarkfen stdout); 17264235Smarkfen break; 17274235Smarkfen case IKE_KEY_ENCR: 17284235Smarkfen (void) printf(gettext("%s Encryption key (%d bytes): "), 17294235Smarkfen prefix, len); 17304235Smarkfen (void) dump_key((uint8_t *)(p + 1), SADB_8TO1(len), 17314235Smarkfen stdout); 17324235Smarkfen break; 17334235Smarkfen case IKE_KEY_IV: 17344235Smarkfen (void) printf( 17354235Smarkfen gettext("%s Initialization vector (%d bytes): "), 17364235Smarkfen prefix, len); 17374235Smarkfen (void) dump_key((uint8_t *)(p + 1), SADB_8TO1(len), 17384235Smarkfen stdout); 17394235Smarkfen break; 17404235Smarkfen default: 17414235Smarkfen (void) printf(gettext("%s Unidentified key info %p %d"), 17424235Smarkfen prefix, p, p1klen); 17434235Smarkfen } 17444235Smarkfen (void) printf("\n"); 17454235Smarkfen assert(IS_P2ALIGNED(p1klen, 8)); 17464235Smarkfen curp += (p1klen >> 2); 17474235Smarkfen } 17484235Smarkfen } 17494235Smarkfen 17504235Smarkfen static void 17514235Smarkfen print_p1(ike_p1_sa_t *p1) 17524235Smarkfen { 17534235Smarkfen ike_p1_stats_t *sp; 17544235Smarkfen ike_p1_errors_t *ep; 17554235Smarkfen ike_p1_key_t *kp; 17564235Smarkfen sadb_ident_t *lidp, *ridp; 17574235Smarkfen int lstat, rstat; 17584235Smarkfen 17594235Smarkfen (void) printf("\n"); 17604235Smarkfen print_hdr("IKESA:", &p1->p1sa_hdr); 17614235Smarkfen print_xform("XFORM:", &p1->p1sa_xform, B_FALSE); 17624235Smarkfen 17634235Smarkfen if (p1->p1sa_hdr.p1hdr_isinit) { 17644235Smarkfen lstat = IS_INITIATOR; 17654235Smarkfen rstat = IS_RESPONDER; 17664235Smarkfen } else { 17674235Smarkfen lstat = IS_RESPONDER; 17684235Smarkfen rstat = IS_INITIATOR; 17694235Smarkfen } 17704235Smarkfen print_addr("LOCIP:", &p1->p1sa_ipaddrs.loc_addr, lstat); 17714235Smarkfen print_addr("REMIP:", &p1->p1sa_ipaddrs.rem_addr, rstat); 17724235Smarkfen 17734235Smarkfen /* 17744235Smarkfen * the stat len might be 0; but still make the call 17754235Smarkfen * to print_lifetime() to pick up the xform info 17764235Smarkfen */ 17774235Smarkfen sp = (ike_p1_stats_t *)((int)(p1) + p1->p1sa_stat_off); 17784235Smarkfen print_lifetime("LIFTM:", &p1->p1sa_xform, sp, p1->p1sa_stat_len); 17794235Smarkfen 17804235Smarkfen if (p1->p1sa_stat_len > 0) { 17814235Smarkfen print_p1stats("STATS:", sp, p1->p1sa_stat_len, B_FALSE); 17824235Smarkfen } 17834235Smarkfen 17844235Smarkfen if (p1->p1sa_error_len > 0) { 17854235Smarkfen ep = (ike_p1_errors_t *)((int)(p1) + p1->p1sa_error_off); 17864235Smarkfen print_errs("ERRS: ", ep, p1->p1sa_error_len); 17874235Smarkfen } 17884235Smarkfen 17894235Smarkfen if (p1->p1sa_localid_len > 0) { 17904235Smarkfen lidp = (sadb_ident_t *)((int)(p1) + p1->p1sa_localid_off); 17914235Smarkfen print_id("LOCID:", lidp, lstat); 17924235Smarkfen } 17934235Smarkfen 17944235Smarkfen if (p1->p1sa_remoteid_len > 0) { 17954235Smarkfen ridp = (sadb_ident_t *)((int)(p1) + p1->p1sa_remoteid_off); 17964235Smarkfen print_id("REMID:", ridp, rstat); 17974235Smarkfen } 17984235Smarkfen 17994235Smarkfen if (p1->p1sa_key_len > 0) { 18004235Smarkfen kp = (ike_p1_key_t *)((int)(p1) + p1->p1sa_key_off); 18014235Smarkfen print_keys("KEY: ", kp, p1->p1sa_key_len); 18024235Smarkfen } 18034235Smarkfen } 18044235Smarkfen 18054235Smarkfen static void 18064235Smarkfen print_ps(ike_ps_t *ps) 18074235Smarkfen { 18084235Smarkfen sadb_ident_t *lidp, *ridp; 18094235Smarkfen uint8_t *keyp; 18104235Smarkfen 18114235Smarkfen (void) printf("\n"); 18124235Smarkfen 18134235Smarkfen (void) printf(gettext("PSKEY: For %s exchanges\n"), 18144235Smarkfen xchgstr(ps->ps_ike_mode)); 18154235Smarkfen 18164235Smarkfen if (ps->ps_key_len > 0) { 18174235Smarkfen keyp = (uint8_t *)((int)(ps) + ps->ps_key_off); 18184235Smarkfen (void) printf(gettext("PSKEY: Pre-shared key (%d bytes): "), 18194235Smarkfen ps->ps_key_len); 18204235Smarkfen (void) dump_key(keyp, ps->ps_key_bits, stdout); 18214235Smarkfen (void) printf("\n"); 18224235Smarkfen } 18234235Smarkfen 18244235Smarkfen /* 18254235Smarkfen * We get *either* and address or an ident, never both. So if 18264235Smarkfen * the ident is there, don't try printing an address. 18274235Smarkfen */ 18284235Smarkfen if (ps->ps_localid_len > 0) { 18294235Smarkfen lidp = (sadb_ident_t *) 18304235Smarkfen ((int)(ps) + ps->ps_localid_off); 18314235Smarkfen print_id("LOCID:", lidp, DONT_PRINT_INIT); 18324235Smarkfen } else { 18334235Smarkfen print_addr("LOCIP:", &ps->ps_ipaddrs.loc_addr, DONT_PRINT_INIT); 18344235Smarkfen } 18354235Smarkfen 18364235Smarkfen if (ps->ps_remoteid_len > 0) { 18374235Smarkfen ridp = (sadb_ident_t *) 18384235Smarkfen ((int)(ps) + ps->ps_remoteid_off); 18394235Smarkfen print_id("REMID:", ridp, DONT_PRINT_INIT); 18404235Smarkfen } else { 18414235Smarkfen print_addr("REMIP:", &ps->ps_ipaddrs.rem_addr, DONT_PRINT_INIT); 18424235Smarkfen } 18434235Smarkfen } 18444235Smarkfen 18454235Smarkfen #define PREFIXLEN 16 18464235Smarkfen 18474235Smarkfen static void 18484235Smarkfen print_rule(ike_rule_t *rp) 18494235Smarkfen { 18504235Smarkfen char prefix[PREFIXLEN]; 18514235Smarkfen int i; 18524235Smarkfen ike_p1_xform_t *xfp; 18534235Smarkfen ike_addr_pr_t *lipp, *ripp; 18544235Smarkfen char *lidp, *ridp; 18554235Smarkfen 18564235Smarkfen (void) printf("\n"); 18574235Smarkfen (void) printf(gettext("GLOBL: Label '%s', key manager cookie %u\n"), 18584235Smarkfen rp->rule_label, rp->rule_kmcookie); 18594235Smarkfen (void) printf(gettext("GLOBL: local_idtype=")); 18604235Smarkfen (void) dump_sadb_idtype(rp->rule_local_idtype, stdout, NULL); 18614235Smarkfen (void) printf(gettext(", ike_mode=%s\n"), xchgstr(rp->rule_ike_mode)); 18624235Smarkfen (void) printf(gettext( 18634235Smarkfen "GLOBL: p1_nonce_len=%u, p2_nonce_len=%u, p2_pfs=%s (group %u)\n"), 18644235Smarkfen rp->rule_p1_nonce_len, rp->rule_p2_nonce_len, 18654235Smarkfen (rp->rule_p2_pfs) ? gettext("true") : gettext("false"), 18664235Smarkfen rp->rule_p2_pfs); 18674235Smarkfen (void) printf( 18684235Smarkfen gettext("GLOBL: p2_lifetime=%u seconds, p2_softlife=%u seconds\n"), 18694235Smarkfen rp->rule_p2_lifetime_secs, rp->rule_p2_softlife_secs); 18704235Smarkfen (void) printf( 18714235Smarkfen gettext("GLOBL: p2_lifetime_kb=%u seconds," 18724235Smarkfen " p2_softlife_kb=%u seconds\n"), 18734235Smarkfen rp->rule_p2_lifetime_kb, rp->rule_p2_softlife_kb); 18744235Smarkfen 18754235Smarkfen if (rp->rule_locip_cnt > 0) { 18764235Smarkfen (void) printf(gettext("LOCIP: IP address range(s):\n")); 18774235Smarkfen lipp = (ike_addr_pr_t *)((int)rp + rp->rule_locip_off); 18784235Smarkfen for (i = 0; i < rp->rule_locip_cnt; i++, lipp++) { 18794235Smarkfen print_addr_range("LOCIP:", lipp); 18804235Smarkfen } 18814235Smarkfen } 18824235Smarkfen 18834235Smarkfen if (rp->rule_remip_cnt > 0) { 18844235Smarkfen (void) printf(gettext("REMIP: IP address range(s):\n")); 18854235Smarkfen ripp = (ike_addr_pr_t *)((int)rp + rp->rule_remip_off); 18864235Smarkfen for (i = 0; i < rp->rule_remip_cnt; i++, ripp++) { 18874235Smarkfen print_addr_range("REMIP:", ripp); 18884235Smarkfen } 18894235Smarkfen } 18904235Smarkfen 18914235Smarkfen if (rp->rule_locid_inclcnt + rp->rule_locid_exclcnt > 0) { 18924235Smarkfen lidp = (char *)((int)rp + rp->rule_locid_off); 18934235Smarkfen print_idspec("LOCID:", lidp, rp->rule_locid_inclcnt, 18944235Smarkfen rp->rule_locid_exclcnt); 18954235Smarkfen } 18964235Smarkfen 18974235Smarkfen if (rp->rule_remid_inclcnt + rp->rule_remid_exclcnt > 0) { 18984235Smarkfen ridp = (char *)((int)rp + rp->rule_remid_off); 18994235Smarkfen print_idspec("REMID:", ridp, rp->rule_remid_inclcnt, 19004235Smarkfen rp->rule_remid_exclcnt); 19014235Smarkfen } 19024235Smarkfen 19034235Smarkfen if (rp->rule_xform_cnt > 0) { 19044235Smarkfen (void) printf(gettext("XFRMS: Available Transforms:\n")); 19054235Smarkfen xfp = (ike_p1_xform_t *)((int)rp + rp->rule_xform_off); 19064235Smarkfen for (i = 0; i < rp->rule_xform_cnt; i++, xfp++) { 19074235Smarkfen (void) snprintf(prefix, PREFIXLEN, "XF %2u:", i); 19084235Smarkfen print_xform(prefix, xfp, B_TRUE); 19094235Smarkfen } 19104235Smarkfen } 19114235Smarkfen } 19124235Smarkfen 19134235Smarkfen #undef PREFIXLEN 19144235Smarkfen 19154235Smarkfen #define PRSACNTS(init, resp) \ 19164235Smarkfen (void) printf(gettext("initiator: %10u responder: %10u\n"), \ 19174235Smarkfen (init), (resp)) 19184235Smarkfen 19194235Smarkfen static void 19204235Smarkfen print_stats(ike_stats_t *sp, int len) 19214235Smarkfen { 19224235Smarkfen /* 19234235Smarkfen * before printing each line, make sure the structure we were 19244235Smarkfen * given is big enough to include the fields needed. 19254235Smarkfen */ 19264235Smarkfen if (len < COUNTER_PAIR) 19274235Smarkfen return; 19284235Smarkfen (void) printf(gettext("Phase 1 SA counts:\n")); 19294235Smarkfen (void) printf(gettext("Current: ")); 19304235Smarkfen PRSACNTS(sp->st_init_p1_current, sp->st_resp_p1_current); 19314235Smarkfen len -= COUNTER_PAIR; 19324235Smarkfen 19334235Smarkfen if (len < COUNTER_PAIR) 19344235Smarkfen return; 19354235Smarkfen (void) printf(gettext("Total: ")); 19364235Smarkfen PRSACNTS(sp->st_init_p1_total, sp->st_resp_p1_total); 19374235Smarkfen len -= COUNTER_PAIR; 19384235Smarkfen 19394235Smarkfen if (len < COUNTER_PAIR) 19404235Smarkfen return; 19414235Smarkfen (void) printf(gettext("Attempted: ")); 19424235Smarkfen PRSACNTS(sp->st_init_p1_attempts, sp->st_resp_p1_attempts); 19434235Smarkfen len -= COUNTER_PAIR; 19444235Smarkfen 19454235Smarkfen if (len < (COUNTER_PAIR + COUNTER_32BIT)) 19464235Smarkfen return; 19474235Smarkfen (void) printf(gettext("Failed: ")); 19484235Smarkfen PRSACNTS(sp->st_init_p1_noresp + sp->st_init_p1_respfail, 19494235Smarkfen sp->st_resp_p1_fail); 19504235Smarkfen (void) printf( 19514235Smarkfen gettext(" initiator fails include %u time-out(s)\n"), 19524235Smarkfen sp->st_init_p1_noresp); 19534235Smarkfen 19544235Smarkfen if (len < PATH_MAX) 19554235Smarkfen return; 19564235Smarkfen if (*(sp->st_pkcs11_libname) != '\0') 19574235Smarkfen (void) printf(gettext("PKCS#11 library linked in from %s\n"), 19584235Smarkfen sp->st_pkcs11_libname); 19594235Smarkfen } 19604235Smarkfen 19614235Smarkfen static void 19624235Smarkfen print_defaults(char *label, char *description, char *unit, boolean_t kbytes, 19634235Smarkfen uint_t current, uint_t def) 19644235Smarkfen { 19654235Smarkfen (void) printf("%-18s%-10s%14u%s%-10s%-26s\n", label, 19664235Smarkfen (current != def) ? gettext("config") : gettext("default"), 19674235Smarkfen (current != def) ? current : def, (kbytes) ? "K " : " ", 19684235Smarkfen unit, description); 19694235Smarkfen } 19704235Smarkfen 19714235Smarkfen /* 19724235Smarkfen * Print out defaults used by in.iked, the argument is a buffer containing 19734235Smarkfen * two ike_defaults_t's, the first contains the hard coded defaults, the second 19744235Smarkfen * contains the actual values used. If these differ, then the defaults have been 19754235Smarkfen * changed via a config file entry. Note that "-" indicates this default 19764235Smarkfen * is not tunable. 19774235Smarkfen */ 19784235Smarkfen static void 19794235Smarkfen do_print_defaults(ike_defaults_t *dp) 19804235Smarkfen { 19814235Smarkfen ike_defaults_t *ddp; 19824235Smarkfen ddp = (ike_defaults_t *)(dp + 1); 19834235Smarkfen 19844235Smarkfen (void) printf(gettext("\nGlobal defaults. Some values can be" 19854235Smarkfen " over-ridden on a per rule basis.\n\n")); 19864235Smarkfen 19874235Smarkfen (void) printf("%-18s%-10s%-16s%-10s%-26s\n\n", 19884235Smarkfen gettext("Token:"), gettext("Source:"), gettext("Value:"), 19894235Smarkfen gettext("Unit:"), gettext("Description:")); 19904235Smarkfen 19914235Smarkfen print_defaults("p1_lifetime_secs", gettext("phase 1 lifetime"), 19924235Smarkfen gettext("seconds"), B_FALSE, ddp->rule_p1_lifetime_secs, 19934235Smarkfen dp->rule_p1_lifetime_secs); 19944235Smarkfen 19954235Smarkfen print_defaults("-", gettext("minimum phase 1 lifetime"), 19964235Smarkfen gettext("seconds"), B_FALSE, ddp->rule_p1_minlife, 19974235Smarkfen dp->rule_p1_minlife); 19984235Smarkfen 19994235Smarkfen print_defaults("p1_nonce_len", gettext("phase 1 nonce length"), 20004235Smarkfen gettext("bytes"), B_FALSE, ddp->rule_p1_nonce_len, 20014235Smarkfen dp->rule_p1_nonce_len); 20024235Smarkfen 20034235Smarkfen print_defaults("p2_lifetime_secs", gettext("phase 2 lifetime"), 20044235Smarkfen gettext("seconds"), B_FALSE, ddp->rule_p2_lifetime_secs, 20054235Smarkfen dp->rule_p2_lifetime_secs); 20064235Smarkfen 20074235Smarkfen print_defaults("p2_softlife_secs", gettext("phase 2 soft lifetime"), 20084235Smarkfen gettext("seconds"), B_FALSE, ddp->rule_p2_softlife_secs, 20094235Smarkfen dp->rule_p2_softlife_secs); 20104235Smarkfen 20115213Smarkfen print_defaults("-", gettext("system phase 2 lifetime"), 20125213Smarkfen gettext("seconds"), B_FALSE, ddp->sys_p2_lifetime_secs, 20135213Smarkfen dp->sys_p2_lifetime_secs); 20145213Smarkfen 20155213Smarkfen print_defaults("-", gettext("system phase 2 soft lifetime"), 20165213Smarkfen gettext("seconds"), B_FALSE, ddp->sys_p2_softlife_secs, 20175213Smarkfen dp->sys_p2_softlife_secs); 20185213Smarkfen 20194235Smarkfen print_defaults("p2_lifetime_kb", gettext("phase 2 lifetime"), 20204235Smarkfen gettext("bytes"), B_TRUE, ddp->rule_p2_lifetime_kb, 20214235Smarkfen dp->rule_p2_lifetime_kb); 20224235Smarkfen 20234235Smarkfen print_defaults("p2_softlife_kb", gettext("phase 2 soft lifetime"), 20244235Smarkfen gettext("bytes"), B_TRUE, ddp->rule_p2_softlife_kb, 20254235Smarkfen dp->rule_p2_softlife_kb); 20264235Smarkfen 20275213Smarkfen print_defaults("-", gettext("system phase 2 lifetime"), 20285213Smarkfen gettext("bytes"), B_FALSE, ddp->sys_p2_lifetime_bytes, 20295213Smarkfen dp->sys_p2_lifetime_bytes); 20305213Smarkfen 20315213Smarkfen print_defaults("-", gettext("system phase 2 soft lifetime"), 20325213Smarkfen gettext("bytes"), B_FALSE, ddp->sys_p2_softlife_bytes, 20335213Smarkfen dp->sys_p2_softlife_bytes); 20345213Smarkfen 20354235Smarkfen print_defaults("-", gettext("minimum phase 2 lifetime"), 20364235Smarkfen gettext("seconds"), B_FALSE, ddp->rule_p2_minlife, 20374235Smarkfen dp->rule_p2_minlife); 20384235Smarkfen 20394235Smarkfen print_defaults("p2_nonce_len", gettext("phase 2 nonce length"), 20404235Smarkfen gettext("bytes"), B_FALSE, ddp->rule_p2_nonce_len, 20414235Smarkfen dp->rule_p2_nonce_len); 20424235Smarkfen 20434235Smarkfen print_defaults("-", gettext("default phase 2 lifetime"), 20444235Smarkfen gettext("seconds"), B_FALSE, ddp->rule_p2_def_minlife, 20454235Smarkfen dp->rule_p2_def_minlife); 20464235Smarkfen 20474235Smarkfen print_defaults("-", gettext("minimum phase 2 soft delta"), 20484235Smarkfen gettext("seconds"), B_FALSE, ddp->rule_p2_minsoft, 20494235Smarkfen dp->rule_p2_minsoft); 20504235Smarkfen 20514235Smarkfen print_defaults("p2_pfs", gettext("phase 2 PFS"), 20524235Smarkfen " ", B_FALSE, ddp->rule_p2_pfs, dp->rule_p2_pfs); 20534235Smarkfen 20544235Smarkfen print_defaults("max_certs", gettext("max certificates"), 20554235Smarkfen " ", B_FALSE, ddp->rule_max_certs, dp->rule_max_certs); 20564235Smarkfen 20574235Smarkfen print_defaults("-", gettext("IKE port number"), 20584235Smarkfen " ", B_FALSE, ddp->rule_ike_port, dp->rule_ike_port); 20594235Smarkfen 20604235Smarkfen print_defaults("-", gettext("NAT-T port number"), 20614235Smarkfen " ", B_FALSE, ddp->rule_natt_port, dp->rule_natt_port); 20624235Smarkfen } 20634235Smarkfen 20644235Smarkfen static void 20654235Smarkfen print_categories(int level) 20664235Smarkfen { 20674235Smarkfen int mask; 20684235Smarkfen 20694235Smarkfen if (level == 0) { 20704235Smarkfen (void) printf(gettext("No debug categories enabled.\n")); 20714235Smarkfen return; 20724235Smarkfen } 20734235Smarkfen 20744235Smarkfen (void) printf(gettext("Debug categories enabled:")); 20754235Smarkfen for (mask = 1; mask <= D_HIGHBIT; mask <<= 1) { 20764235Smarkfen if (level & mask) 20774235Smarkfen (void) printf("\n\t%s", dbgstr(mask)); 20784235Smarkfen } 20794235Smarkfen (void) printf("\n"); 20804235Smarkfen } 20814235Smarkfen 20824235Smarkfen /*PRINTFLIKE2*/ 20834235Smarkfen static void 20844235Smarkfen ikeadm_err_exit(ike_err_t *err, char *fmt, ...) 20854235Smarkfen { 20864235Smarkfen va_list ap; 20874235Smarkfen char bailbuf[BUFSIZ]; 20884235Smarkfen 20894235Smarkfen va_start(ap, fmt); 20904235Smarkfen (void) vsnprintf(bailbuf, BUFSIZ, fmt, ap); 20914235Smarkfen va_end(ap); 20924235Smarkfen if ((err != NULL) && (err->ike_err == IKE_ERR_SYS_ERR)) { 20934235Smarkfen bail_msg("%s: %s", bailbuf, (err->ike_err_unix == 0) ? 20944235Smarkfen gettext("<unknown error>") : strerror(err->ike_err_unix)); 20954235Smarkfen } else { 20964235Smarkfen bail_msg("%s: %s", bailbuf, (err == NULL) ? 20974235Smarkfen gettext("<unknown error>") : errstr(err->ike_err)); 20984235Smarkfen } 20994235Smarkfen } 21004235Smarkfen 21014235Smarkfen /*PRINTFLIKE2*/ 21024235Smarkfen static void 21034235Smarkfen ikeadm_err_msg(ike_err_t *err, char *fmt, ...) 21044235Smarkfen { 21054235Smarkfen va_list ap; 21064235Smarkfen char mbuf[BUFSIZ]; 21074235Smarkfen 21084235Smarkfen va_start(ap, fmt); 21094235Smarkfen (void) vsnprintf(mbuf, BUFSIZ, fmt, ap); 21104235Smarkfen va_end(ap); 21114235Smarkfen if ((err != NULL) && (err->ike_err == IKE_ERR_SYS_ERR)) { 21124235Smarkfen message("%s: %s", mbuf, (err->ike_err_unix == 0) ? 21134235Smarkfen gettext("<unknown error>") : 21144235Smarkfen ((err->ike_err_unix == EEXIST) ? 21154235Smarkfen gettext("Duplicate entry") : 21164235Smarkfen strerror(err->ike_err_unix))); 21174235Smarkfen } else { 21184235Smarkfen message("%s: %s", mbuf, (err == NULL) ? 21194235Smarkfen gettext("<unknown error>") : errstr(err->ike_err)); 21204235Smarkfen } 21214235Smarkfen } 21224235Smarkfen 21234235Smarkfen 21244235Smarkfen /* 21254235Smarkfen * Command functions 21264235Smarkfen */ 21274235Smarkfen 21284235Smarkfen /* 21294235Smarkfen * Exploit the fact that ike_dbg_t and ike_priv_t have identical 21304235Smarkfen * formats in the following two functions. 21314235Smarkfen */ 21324235Smarkfen static void 21334235Smarkfen do_getvar(int cmd) 21344235Smarkfen { 21354235Smarkfen ike_service_t req, *rtn; 21364235Smarkfen ike_dbg_t *dreq; 21374235Smarkfen char *varname; 21384235Smarkfen 21394235Smarkfen switch (cmd) { 21404235Smarkfen case IKE_SVC_GET_DBG: 21414235Smarkfen varname = gettext("debug"); 21424235Smarkfen break; 21434235Smarkfen case IKE_SVC_GET_PRIV: 21444235Smarkfen varname = gettext("privilege"); 21454235Smarkfen break; 21464235Smarkfen default: 21474235Smarkfen bail_msg(gettext("unrecognized get command (%d)"), cmd); 21484235Smarkfen } 21494235Smarkfen 21504235Smarkfen dreq = &req.svc_dbg; 21514235Smarkfen dreq->cmd = cmd; 21524235Smarkfen dreq->dbg_level = 0; 21534235Smarkfen 21544235Smarkfen rtn = ikedoor_call((char *)&req, sizeof (ike_dbg_t), NULL, 0); 21554235Smarkfen 21564235Smarkfen if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 21574235Smarkfen ikeadm_err_exit(&rtn->svc_err, 21584235Smarkfen gettext("error getting %s level"), varname); 21594235Smarkfen } 21604235Smarkfen dreq = &rtn->svc_dbg; 21614235Smarkfen (void) printf(gettext("Current %s level is 0x%x"), 21624235Smarkfen varname, dreq->dbg_level); 21634235Smarkfen 21644235Smarkfen if (cmd == IKE_SVC_GET_DBG) { 21654235Smarkfen (void) printf("\n"); 21664235Smarkfen print_categories(dreq->dbg_level); 21674235Smarkfen } else { 21684235Smarkfen (void) printf(gettext(", %s enabled\n"), 21694235Smarkfen privstr(dreq->dbg_level)); 21704235Smarkfen } 21714235Smarkfen } 21724235Smarkfen 21734235Smarkfen static void 21744235Smarkfen do_setvar(int cmd, int argc, char **argv) 21754235Smarkfen { 21764235Smarkfen ike_service_t req, *rtn; 21774235Smarkfen ike_dbg_t *dreq; 21784235Smarkfen door_desc_t *descp = NULL, desc; 21794235Smarkfen int fd, ndesc = 0; 21804235Smarkfen uint32_t reqlevel; 21814235Smarkfen char *varname; 21824235Smarkfen 21834235Smarkfen if (argc < 1) 21844235Smarkfen Bail("unspecified level"); 21854235Smarkfen reqlevel = strtoul(argv[0], NULL, 0); 21864235Smarkfen 21874235Smarkfen switch (cmd) { 21884235Smarkfen case IKE_SVC_SET_DBG: 21894235Smarkfen if (argc > 2) 21904235Smarkfen Bail("Too many arguments to \"set debug\""); 21914235Smarkfen varname = gettext("debug"); 21924235Smarkfen if (reqlevel == 0) { 21934235Smarkfen /* check for a string... */ 21944235Smarkfen reqlevel = parsedbgopts(argv[0]); 21954235Smarkfen } 21964235Smarkfen if (reqlevel == D_INVALID) 21974235Smarkfen bail_msg(gettext("Bad debug flag: %s"), argv[0]); 21984235Smarkfen break; 21994235Smarkfen case IKE_SVC_SET_PRIV: 22004235Smarkfen if (argc > 1) 22014235Smarkfen Bail("Too many arguments to \"set priv\""); 22024235Smarkfen 22034235Smarkfen varname = gettext("privilege"); 22044235Smarkfen if (reqlevel == 0) { 22054235Smarkfen /* check for a string... */ 22064235Smarkfen reqlevel = privstr2num(argv[0]); 22074235Smarkfen } 22084235Smarkfen if (reqlevel > IKE_PRIV_MAXIMUM) 22094235Smarkfen bail_msg(gettext("Bad privilege flag: %s"), argv[0]); 22104235Smarkfen break; 22114235Smarkfen default: 22124235Smarkfen bail_msg(gettext("unrecognized set command (%d)"), cmd); 22134235Smarkfen } 22144235Smarkfen 22154235Smarkfen dreq = &req.svc_dbg; 22164235Smarkfen dreq->cmd = cmd; 22174235Smarkfen dreq->dbg_level = reqlevel; 22184235Smarkfen 22194235Smarkfen if ((argc == 2) && (cmd == IKE_SVC_SET_DBG)) { 22204235Smarkfen fd = open(argv[1], O_RDWR | O_CREAT | O_APPEND, 22214235Smarkfen S_IRUSR | S_IWUSR); 22224235Smarkfen if (fd < 0) 22234235Smarkfen Bail("open debug file"); 22244235Smarkfen desc.d_data.d_desc.d_descriptor = fd; 22254235Smarkfen desc.d_attributes = DOOR_DESCRIPTOR; 22264235Smarkfen descp = &desc; 22274235Smarkfen ndesc = 1; 22284235Smarkfen } 22294235Smarkfen 22304235Smarkfen rtn = ikedoor_call((char *)&req, sizeof (ike_dbg_t), descp, ndesc); 22314235Smarkfen 22324235Smarkfen if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 22334235Smarkfen ikeadm_err_exit(&rtn->svc_err, 22344235Smarkfen gettext("error setting %s level"), varname); 22354235Smarkfen } 22364235Smarkfen dreq = &rtn->svc_dbg; 22374235Smarkfen (void) printf( 22384235Smarkfen gettext("Successfully changed %s level from 0x%x to 0x%x\n"), 22394235Smarkfen varname, dreq->dbg_level, reqlevel); 22404235Smarkfen 22414235Smarkfen if (cmd == IKE_SVC_SET_DBG) { 22424235Smarkfen print_categories(reqlevel); 22434235Smarkfen } else { 22444235Smarkfen (void) printf(gettext("New privilege level 0x%x enables %s\n"), 22454235Smarkfen reqlevel, privstr(reqlevel)); 22464235Smarkfen } 22474235Smarkfen } 22484235Smarkfen 22494235Smarkfen static void 22504235Smarkfen do_getstats(int cmd) 22514235Smarkfen { 22524235Smarkfen ike_service_t *rtn; 22534235Smarkfen ike_statreq_t sreq, *sreqp; 22544235Smarkfen ike_stats_t *sp; 22554235Smarkfen 22564235Smarkfen sreq.cmd = cmd; 22574235Smarkfen 22584235Smarkfen rtn = ikedoor_call((char *)&sreq, sizeof (ike_statreq_t), NULL, 0); 22594235Smarkfen if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 22604235Smarkfen ikeadm_err_exit(&rtn->svc_err, gettext("error getting stats")); 22614235Smarkfen } 22624235Smarkfen 22634235Smarkfen sreqp = &rtn->svc_stats; 22644235Smarkfen sp = (ike_stats_t *)(sreqp + 1); 22654235Smarkfen print_stats(sp, sreqp->stat_len); 22664235Smarkfen } 22674235Smarkfen 22684235Smarkfen static void 22694235Smarkfen do_getdefs(int cmd) 22704235Smarkfen { 22714235Smarkfen ike_service_t *rtn; 22724235Smarkfen ike_defreq_t dreq, *dreqp; 22734235Smarkfen ike_defaults_t *dp; 22744235Smarkfen 22754235Smarkfen dreq.cmd = cmd; 22764235Smarkfen 22774235Smarkfen rtn = ikedoor_call((char *)&dreq, sizeof (ike_defreq_t), NULL, 0); 22784235Smarkfen if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 22794235Smarkfen ikeadm_err_exit(&rtn->svc_err, 22804235Smarkfen gettext("error getting defaults")); 22814235Smarkfen } 22824235Smarkfen 22834235Smarkfen dreqp = &rtn->svc_defaults; 22844235Smarkfen dp = (ike_defaults_t *)(dreqp + 1); 22854235Smarkfen 22864235Smarkfen /* 22874235Smarkfen * Before printing each line, make sure the structure we were 22884235Smarkfen * given is big enough to include the fields needed. 22894235Smarkfen * Silently bail out of there is a version mismatch. 22904235Smarkfen */ 22914235Smarkfen if (dreqp->stat_len < ((2 * sizeof (ike_defaults_t)) 22924235Smarkfen + sizeof (ike_defreq_t)) || dreqp->version != DOORVER) { 22934235Smarkfen return; 22944235Smarkfen } 22954235Smarkfen do_print_defaults(dp); 22964235Smarkfen } 22974235Smarkfen 22984235Smarkfen static void 22994235Smarkfen do_dump(int cmd) 23004235Smarkfen { 23014235Smarkfen char *name; 23024235Smarkfen ike_service_t req, *rtn; 23034235Smarkfen ike_dump_t *dreq, *dump; 23044235Smarkfen 23054235Smarkfen switch (cmd) { 23064235Smarkfen case IKE_SVC_DUMP_P1S: 23074235Smarkfen name = gettext("phase 1 SA info"); 23084235Smarkfen break; 23094235Smarkfen case IKE_SVC_DUMP_RULES: 23104235Smarkfen name = gettext("policy rules"); 23114235Smarkfen break; 23124235Smarkfen case IKE_SVC_DUMP_PS: 23134235Smarkfen name = gettext("preshared keys"); 23144235Smarkfen break; 23154235Smarkfen default: 23164235Smarkfen bail_msg(gettext("unrecognized dump command (%d)"), cmd); 23174235Smarkfen } 23184235Smarkfen 23194235Smarkfen dreq = &req.svc_dump; 23204235Smarkfen dreq->cmd = cmd; 23214235Smarkfen dreq->dump_len = 0; 23224235Smarkfen dreq->dump_next = 0; 23234235Smarkfen do { 23244235Smarkfen rtn = ikedoor_call((char *)&req, sizeof (ike_dump_t), 23254235Smarkfen NULL, 0); 23264235Smarkfen if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 23274235Smarkfen if (rtn && (rtn->svc_err.ike_err == IKE_ERR_NO_OBJ)) { 23284235Smarkfen /* no entries to print */ 23294235Smarkfen break; 23304235Smarkfen } 23314235Smarkfen ikeadm_err_exit(&rtn->svc_err, 23324235Smarkfen gettext("error getting %s"), name); 23334235Smarkfen } 23344235Smarkfen dump = &rtn->svc_dump; 23354235Smarkfen 23364235Smarkfen switch (cmd) { 23374235Smarkfen case IKE_SVC_DUMP_P1S: 23384235Smarkfen print_p1((ike_p1_sa_t *)(dump + 1)); 23394235Smarkfen break; 23404235Smarkfen case IKE_SVC_DUMP_RULES: 23414235Smarkfen print_rule((ike_rule_t *)(dump + 1)); 23424235Smarkfen break; 23434235Smarkfen case IKE_SVC_DUMP_PS: 23444235Smarkfen print_ps((ike_ps_t *)(dump + 1)); 23454235Smarkfen break; 23464235Smarkfen } 23474235Smarkfen 23484235Smarkfen dreq->dump_next = dump->dump_next; 23494235Smarkfen 23504235Smarkfen (void) munmap((char *)rtn, dump->dump_len); 23514235Smarkfen 23524235Smarkfen } while (dreq->dump_next); 23534235Smarkfen 23544235Smarkfen (void) printf(gettext("\nCompleted dump of %s\n"), name); 23554235Smarkfen } 23564235Smarkfen 23574235Smarkfen static void 23584235Smarkfen do_getdel_doorcall(int cmd, int idlen, int idtype, char *idp, char *name) 23594235Smarkfen { 23604235Smarkfen int totallen; 23614235Smarkfen char *p; 23624235Smarkfen ike_service_t *reqp, *rtnp; 23634235Smarkfen ike_get_t *getp; 23644235Smarkfen boolean_t getcmd; 23654235Smarkfen 23664235Smarkfen getcmd = ((cmd == IKE_SVC_GET_P1) || (cmd == IKE_SVC_GET_RULE) || 23674235Smarkfen (cmd == IKE_SVC_GET_PS)); 23684235Smarkfen 23694235Smarkfen /* 23704235Smarkfen * WARNING: to avoid being redundant, this code takes advantage 23714235Smarkfen * of the fact that the ike_get_t and ike_del_t structures are 23724235Smarkfen * identical (only the field names differ, their function and 23734235Smarkfen * size are the same). If for some reason those structures 23744235Smarkfen * change, this code will need to be re-written to accomodate 23754235Smarkfen * that difference. 23764235Smarkfen */ 23774235Smarkfen totallen = sizeof (ike_get_t) + idlen; 23784235Smarkfen if ((reqp = (ike_service_t *)malloc(totallen)) == NULL) 23794235Smarkfen Bail("malloc(id)"); 23804235Smarkfen 23814235Smarkfen getp = &reqp->svc_get; 23824235Smarkfen getp->cmd = cmd; 23834235Smarkfen getp->get_len = totallen; 23844235Smarkfen getp->get_idtype = idtype; 23854235Smarkfen p = (char *)(getp + 1); 23864235Smarkfen 23874235Smarkfen (void) memcpy(p, idp, idlen); 23884235Smarkfen 23894235Smarkfen rtnp = ikedoor_call((char *)reqp, totallen, NULL, 0); 23904235Smarkfen if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) { 23914235Smarkfen if (rtnp && (rtnp->svc_err.ike_err == IKE_ERR_NO_OBJ)) { 23924235Smarkfen message(gettext("Could not find requested %s."), name); 23934235Smarkfen } else { 23944235Smarkfen ikeadm_err_msg(&rtnp->svc_err, gettext("error %s %s"), 23954235Smarkfen (getcmd) ? gettext("getting") : gettext("deleting"), 23964235Smarkfen name); 23974235Smarkfen } 23984235Smarkfen free(reqp); 23994235Smarkfen return; 24004235Smarkfen } 24014235Smarkfen getp = &rtnp->svc_get; 24024235Smarkfen 24034235Smarkfen if (getcmd) { 24044235Smarkfen switch (cmd) { 24054235Smarkfen case IKE_SVC_GET_P1: 24064235Smarkfen print_p1((ike_p1_sa_t *)(getp + 1)); 24074235Smarkfen break; 24084235Smarkfen case IKE_SVC_GET_PS: 24094235Smarkfen print_ps((ike_ps_t *)(getp + 1)); 24104235Smarkfen break; 24114235Smarkfen case IKE_SVC_GET_RULE: 24124235Smarkfen print_rule((ike_rule_t *)(getp + 1)); 24134235Smarkfen break; 24144235Smarkfen } 24154235Smarkfen } else { 24164235Smarkfen message(gettext("Successfully deleted selected %s."), name); 24174235Smarkfen } 24184235Smarkfen 24194235Smarkfen (void) munmap((char *)rtnp, getp->get_len); 24204235Smarkfen free(reqp); 24214235Smarkfen } 24224235Smarkfen 24234235Smarkfen static void 24244235Smarkfen do_getdel(int cmd, int argc, char **argv) 24254235Smarkfen { 24264235Smarkfen int idlen, idtype = 0, i, j; 24274235Smarkfen int bytelen1, bytelen2; 24284235Smarkfen char *name, *idp, *p, *p1, *p2; 24294235Smarkfen ike_addr_pr_t apr; 24304235Smarkfen ike_cky_pr_t cpr; 24314235Smarkfen sadb_ident_t *sid1p, *sid2p; 24324235Smarkfen struct hostent *he1p, *he2p; 24334235Smarkfen char label[MAX_LABEL_LEN]; 24344235Smarkfen 24354235Smarkfen if ((argc < 1) || (argv[0] == NULL)) { 24364235Smarkfen Bail("not enough identification info"); 24374235Smarkfen } 24384235Smarkfen 24394235Smarkfen switch (cmd) { 24404235Smarkfen case IKE_SVC_GET_P1: 24414235Smarkfen case IKE_SVC_DEL_P1: 24424235Smarkfen name = gettext("phase 1 SA"); 24434235Smarkfen /* 24444235Smarkfen * The first token must either be an address (or hostname) 24454235Smarkfen * or a cookie. We require cookies to be entered as hex 24464235Smarkfen * numbers, beginning with 0x; so if our token starts with 24474235Smarkfen * that, it's a cookie. 24484235Smarkfen */ 24494235Smarkfen if (strncmp(argv[0], "0x", 2) == 0) { 24504235Smarkfen if (parse_cky_pr(argc, argv, &cpr) >= 0) { 24514235Smarkfen idtype = IKE_ID_CKY_PAIR; 24524235Smarkfen idlen = sizeof (ike_cky_pr_t); 24534235Smarkfen idp = (char *)&cpr; 24544235Smarkfen } 24554235Smarkfen } else { 24564235Smarkfen if (parse_addr_pr(argc, argv, &he1p, &he2p) >= 0) { 24574235Smarkfen idtype = IKE_ID_ADDR_PAIR; 24584235Smarkfen idlen = sizeof (ike_addr_pr_t); 24594235Smarkfen } 24604235Smarkfen } 24614235Smarkfen break; 24624235Smarkfen 24634235Smarkfen case IKE_SVC_GET_RULE: 24644235Smarkfen case IKE_SVC_DEL_RULE: 24654235Smarkfen name = gettext("policy rule"); 24664235Smarkfen if (parse_label(argc, argv, label) >= 0) { 24674235Smarkfen idtype = IKE_ID_LABEL; 24684235Smarkfen idlen = MAX_LABEL_LEN; 24694235Smarkfen idp = label; 24704235Smarkfen } 24714235Smarkfen break; 24724235Smarkfen 24734235Smarkfen case IKE_SVC_GET_PS: 24744235Smarkfen case IKE_SVC_DEL_PS: 24754235Smarkfen name = gettext("preshared key"); 24764235Smarkfen /* 24774235Smarkfen * The first token must either be an address or an ident 24784235Smarkfen * type. Check for an ident type to determine which it is. 24794235Smarkfen */ 24804235Smarkfen if (parse_idtype(argv[0], NULL) >= 0) { 24814235Smarkfen if (parse_ident_pr(argc, argv, &sid1p, &sid2p) >= 0) { 24824235Smarkfen idtype = IKE_ID_IDENT_PAIR; 24834235Smarkfen idlen = SADB_64TO8(sid1p->sadb_ident_len) + 24844235Smarkfen SADB_64TO8(sid2p->sadb_ident_len); 24854235Smarkfen } 24864235Smarkfen } else { 24874235Smarkfen if (parse_addr_pr(argc, argv, &he1p, &he2p) >= 0) { 24884235Smarkfen idtype = IKE_ID_ADDR_PAIR; 24894235Smarkfen idlen = sizeof (ike_addr_pr_t); 24904235Smarkfen } 24914235Smarkfen } 24924235Smarkfen break; 24934235Smarkfen 24944235Smarkfen default: 24954235Smarkfen bail_msg(gettext("unrecognized get/del command (%d)"), cmd); 24964235Smarkfen } 24974235Smarkfen 24984235Smarkfen switch (idtype) { 24994235Smarkfen case IKE_ID_ADDR_PAIR: 25004235Smarkfen /* 25014235Smarkfen * we might have exploding addrs here; do every possible 25024235Smarkfen * combination. 25034235Smarkfen */ 25044235Smarkfen i = 0; 25054235Smarkfen j = 0; 25064235Smarkfen while ((p1 = he1p->h_addr_list[i++]) != NULL) { 25074235Smarkfen headdr2sa(p1, &apr.loc_addr, he1p->h_length); 25084235Smarkfen 25094235Smarkfen while ((p2 = he2p->h_addr_list[j++]) != NULL) { 25104235Smarkfen headdr2sa(p2, &apr.rem_addr, he2p->h_length); 25114235Smarkfen do_getdel_doorcall(cmd, idlen, idtype, 25124235Smarkfen (char *)&apr, name); 25134235Smarkfen } 25144235Smarkfen } 25154235Smarkfen FREE_HE(he1p); 25164235Smarkfen FREE_HE(he2p); 25174235Smarkfen break; 25184235Smarkfen 25194235Smarkfen case IKE_ID_IDENT_PAIR: 25204235Smarkfen bytelen1 = SADB_64TO8(sid1p->sadb_ident_len); 25214235Smarkfen bytelen2 = SADB_64TO8(sid2p->sadb_ident_len); 25224235Smarkfen if (idlen != bytelen1 + bytelen2) 25234235Smarkfen Bail("ident syntax error"); 25244235Smarkfen idp = p = (char *)malloc(idlen); 25254235Smarkfen if (p == NULL) 25264235Smarkfen Bail("malloc(id)"); 25274235Smarkfen (void) memcpy(p, (char *)sid1p, bytelen1); 25284235Smarkfen p += bytelen1; 25294235Smarkfen (void) memcpy(p, (char *)sid2p, bytelen2); 25304235Smarkfen do_getdel_doorcall(cmd, idlen, idtype, idp, name); 25314235Smarkfen free(idp); 25324235Smarkfen free(sid1p); 25334235Smarkfen free(sid2p); 25344235Smarkfen break; 25354235Smarkfen 25364235Smarkfen case IKE_ID_CKY_PAIR: 25374235Smarkfen case IKE_ID_LABEL: 25384235Smarkfen do_getdel_doorcall(cmd, idlen, idtype, idp, name); 25394235Smarkfen break; 25404235Smarkfen 25414235Smarkfen case 0: 25424235Smarkfen default: 25434235Smarkfen bail_msg(gettext("invalid %s identification\n"), name); 25444235Smarkfen } 25454235Smarkfen } 25464235Smarkfen 25474235Smarkfen /* 25484235Smarkfen * Copy source into target, inserting an escape character ('\') before 25494235Smarkfen * any quotes that appear. Return true on success, false on failure. 25504235Smarkfen */ 25514235Smarkfen static boolean_t 25524235Smarkfen escapequotes(char *target, char *source, int tlen) 25534235Smarkfen { 25544235Smarkfen int s, t, len = strlen(source) + 1; 25554235Smarkfen 25564235Smarkfen if (tlen < len) 25574235Smarkfen return (B_FALSE); 25584235Smarkfen 25594235Smarkfen for (s = 0, t = 0; s < len && t < tlen; s++) { 25604235Smarkfen if (source[s] == '\"') 25614235Smarkfen target[t++] = '\\'; 25624235Smarkfen target[t++] = source[s]; 25634235Smarkfen } 25644235Smarkfen 25654235Smarkfen if ((t == tlen) && (s < len)) 25664235Smarkfen return (B_FALSE); 25674235Smarkfen 25684235Smarkfen return (B_TRUE); 25694235Smarkfen } 25704235Smarkfen 25714235Smarkfen /* 25724235Smarkfen * Return true if the arg following the given keyword should 25734235Smarkfen * be in quotes (i.e. is a string), false if not. 25744235Smarkfen */ 25754235Smarkfen static boolean_t 25764235Smarkfen quotedfield(char *keywd) 25774235Smarkfen { 25784235Smarkfen if ((strncmp(keywd, "label", strlen("label") + 1) == 0) || 25794235Smarkfen (strncmp(keywd, "local_id", strlen("local_id") + 1) == 0) || 25804235Smarkfen (strncmp(keywd, "remote_id", strlen("remote_id") + 1) == 0)) 25814235Smarkfen return (B_TRUE); 25824235Smarkfen 25834235Smarkfen return (B_FALSE); 25844235Smarkfen } 25854235Smarkfen 25864235Smarkfen static void 25874235Smarkfen do_new(int cmd, int argc, char **argv) 25884235Smarkfen { 25894235Smarkfen ike_service_t *rtn; 25904235Smarkfen ike_new_t new, *newp = NULL; 25914235Smarkfen door_desc_t desc, *descp = NULL; 25924235Smarkfen int i, fd, ndesc = 0, buflen; 25934235Smarkfen char *name, tmpfilepath[32]; 25944235Smarkfen FILE *tmpfile; 25954235Smarkfen 25964235Smarkfen switch (cmd) { 25974235Smarkfen case IKE_SVC_NEW_PS: 25984235Smarkfen name = gettext("preshared key"); 25994235Smarkfen break; 26004235Smarkfen case IKE_SVC_NEW_RULE: 26014235Smarkfen name = gettext("policy rule"); 26024235Smarkfen break; 26034235Smarkfen default: 26044235Smarkfen bail_msg(gettext("unrecognized new command (%d)"), cmd); 26054235Smarkfen } 26064235Smarkfen 26074235Smarkfen if (argc == 1) { 26084235Smarkfen /* We've been given a file to read from */ 26094235Smarkfen fd = open(argv[0], O_RDONLY); 26104235Smarkfen if (fd < 0) 26114235Smarkfen Bail("open source file"); 26124235Smarkfen 26134235Smarkfen desc.d_data.d_desc.d_descriptor = fd; 26144235Smarkfen desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE; 26154235Smarkfen descp = &desc; 26164235Smarkfen ndesc = 1; 26174235Smarkfen 26184235Smarkfen new.cmd = cmd; 26194235Smarkfen new.new_len = 0; 26204235Smarkfen newp = &new; 26214235Smarkfen buflen = sizeof (ike_new_t); 26224235Smarkfen 26234235Smarkfen } else if ((argc > 1) && (cmd == IKE_SVC_NEW_PS)) { 26244235Smarkfen /* 26254235Smarkfen * This is an alternative to using the tmpfile method 26264235Smarkfen * for preshared keys. It means we're duplicating the 26274235Smarkfen * parsing effort that happens in readps.c; but it 26284235Smarkfen * does avoid having the key sitting in a file. 26294235Smarkfen */ 26304235Smarkfen ike_ps_t *psp; 26314235Smarkfen int pslen; 26324235Smarkfen 26334235Smarkfen /* 26344235Smarkfen * must be in interactive mode; don't want keys in 26354235Smarkfen * the process args. 26364235Smarkfen */ 26374235Smarkfen if (!interactive) 26384235Smarkfen Bail("Must be in interactive mode to add key info."); 26394235Smarkfen if (parse_ps(argc, argv, &psp, &pslen) < 0) { 26404235Smarkfen errno = 0; 26414235Smarkfen Bail("invalid preshared key definition"); 26424235Smarkfen } 26434235Smarkfen newp = malloc(sizeof (ike_new_t) + pslen); 26444235Smarkfen if (newp == NULL) 26454235Smarkfen Bail("alloc pskey"); 26464235Smarkfen newp->cmd = cmd; 26474235Smarkfen newp->new_len = sizeof (ike_new_t) + pslen; 26484235Smarkfen (void) memcpy((char *)(newp + 1), psp, pslen); 26494235Smarkfen buflen = newp->new_len; 26504235Smarkfen /* parse_ps allocated the ike_ps_t buffer; free it now */ 26514235Smarkfen free(psp); 26524235Smarkfen 26534235Smarkfen } else if ((argc > 1) && (cmd == IKE_SVC_NEW_RULE)) { 26544235Smarkfen /* 26554235Smarkfen * We've been given the item in argv. However, parsing 26564235Smarkfen * rules can get more than a little messy, and in.iked 26574235Smarkfen * already has a great parser for this stuff! So don't 26584235Smarkfen * fool around with trying to do the parsing here. Just 26594235Smarkfen * write it out to a tempfile, and send the fd to in.iked. 26604235Smarkfen * 26614235Smarkfen * We could conceivably do this for preshared keys, 26624235Smarkfen * rather than duplicating the parsing effort; but that 26634235Smarkfen * would mean the key would be written out to a file, 26644235Smarkfen * which isn't such a good idea. 26654235Smarkfen */ 26664235Smarkfen boolean_t doquotes = B_FALSE; 26674235Smarkfen int rtn; 26684235Smarkfen 26694235Smarkfen if ((argv[0][0] != '{') || 26704235Smarkfen (argv[argc - 1][strlen(argv[argc - 1]) - 1] != '}')) 26714235Smarkfen bail_msg(gettext("improperly formatted %s"), name); 26724235Smarkfen 26734235Smarkfen /* attempt to use a fairly unpredictable file name... */ 26744235Smarkfen (void) sprintf(tmpfilepath, "/var/run/%x", (int)gethrtime()); 26754235Smarkfen fd = open(tmpfilepath, O_RDWR | O_CREAT | O_EXCL, 26764235Smarkfen S_IRUSR | S_IWUSR); 26774235Smarkfen if (fd < 0) 26784235Smarkfen Bail("cannot open tmpfile"); 26794235Smarkfen 26804235Smarkfen /* and make it inaccessible asap */ 26814235Smarkfen if (unlink(tmpfilepath) < 0) { 26824235Smarkfen (void) close(fd); 26834235Smarkfen Bail("tmpfile error"); 26844235Smarkfen } 26854235Smarkfen 26864235Smarkfen tmpfile = fdopen(fd, "w"); 26874235Smarkfen if (tmpfile == NULL) { 26884235Smarkfen (void) close(fd); 26894235Smarkfen Bail("cannot write to tmpfile"); 26904235Smarkfen } 26914235Smarkfen 26924235Smarkfen for (i = 0; i < argc; i++) { 26934235Smarkfen /* 26944235Smarkfen * We have to do some gyrations with our string here, 26954235Smarkfen * to properly handle quotes. There are two issues: 26964235Smarkfen * - some of the fields of a rule may have embedded 26974235Smarkfen * whitespace, and thus must be quoted on the cmd 26984235Smarkfen * line. The shell removes the quotes, and gives 26994235Smarkfen * us a single argv string; but we need to put the 27004235Smarkfen * quotes back in when we write the string out to 27014235Smarkfen * file. The doquotes boolean is set when we 27024235Smarkfen * process a keyword which will be followed by a 27034235Smarkfen * string value (so the NEXT argv element will be 27044235Smarkfen * quoted). 27054235Smarkfen * - there might be a quote character in a field, 27064235Smarkfen * that was escaped on the cmdline. The shell 27074235Smarkfen * removes the escape char, and leaves the quote 27084235Smarkfen * in the string it gives us. We need to put the 27094235Smarkfen * escape char back in before writing to file. 27104235Smarkfen */ 27114235Smarkfen char field[MAXLINESIZE]; 27124235Smarkfen if (!escapequotes(field, argv[i], MAXLINESIZE)) 27134235Smarkfen Bail("write to tmpfile failed (arg too big)"); 27144235Smarkfen if (doquotes) { 27154235Smarkfen rtn = fprintf(tmpfile, "\"%s\"\n", field); 27164235Smarkfen doquotes = B_FALSE; 27174235Smarkfen } else { 27184235Smarkfen rtn = fprintf(tmpfile, "%s\n", field); 27194235Smarkfen } 27204235Smarkfen if (rtn < 0) 27214235Smarkfen Bail("write to tmpfile failed"); 27224235Smarkfen /* 27234235Smarkfen * check if this is a keyword identifying 27244235Smarkfen * a field that needs to be quoted. 27254235Smarkfen */ 27264235Smarkfen doquotes = quotedfield(argv[i]); 27274235Smarkfen } 27284235Smarkfen if (fflush(tmpfile) == EOF) 27294235Smarkfen Bail("write to tmpfile failed"); 27304235Smarkfen /* rewind so that the daemon will get the beginning */ 27314235Smarkfen rewind(tmpfile); 27324235Smarkfen 27334235Smarkfen desc.d_data.d_desc.d_descriptor = fd; 27344235Smarkfen desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE; 27354235Smarkfen descp = &desc; 27364235Smarkfen ndesc = 1; 27374235Smarkfen 27384235Smarkfen new.cmd = cmd; 27394235Smarkfen new.new_len = 0; 27404235Smarkfen newp = &new; 27414235Smarkfen buflen = sizeof (ike_new_t); 27424235Smarkfen 27434235Smarkfen } else { 27444235Smarkfen /* not enough information! */ 27454235Smarkfen bail_msg(gettext("missing %s description or file name"), name); 27464235Smarkfen } 27474235Smarkfen 27484235Smarkfen rtn = ikedoor_call((char *)newp, buflen, descp, ndesc); 27494235Smarkfen 27504235Smarkfen if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) { 27514235Smarkfen ikeadm_err_msg(&rtn->svc_err, 27524235Smarkfen gettext("error creating new %s"), name); 27534235Smarkfen } else { 27544235Smarkfen message(gettext("Successfully created new %s."), name); 27554235Smarkfen } 27564235Smarkfen } 27574235Smarkfen 27584235Smarkfen static void 27594235Smarkfen do_flush(int cmd) 27604235Smarkfen { 27614235Smarkfen ike_service_t *rtnp; 27624235Smarkfen ike_flush_t flush; 27634235Smarkfen 27644235Smarkfen if (cmd != IKE_SVC_FLUSH_P1S) { 27654235Smarkfen bail_msg(gettext("unrecognized flush command (%d)."), cmd); 27664235Smarkfen } 27674235Smarkfen 27684235Smarkfen flush.cmd = cmd; 27694235Smarkfen 27704235Smarkfen rtnp = ikedoor_call((char *)&flush, sizeof (ike_flush_t), NULL, 0); 27714235Smarkfen if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) { 27724235Smarkfen ikeadm_err_exit(&rtnp->svc_err, gettext("error doing flush")); 27734235Smarkfen } 27744235Smarkfen message(gettext("Successfully flushed P1 SAs.")); 27754235Smarkfen } 27764235Smarkfen 27774235Smarkfen static void 27784235Smarkfen do_rw(int cmd, int argc, char **argv) 27794235Smarkfen { 27804235Smarkfen ike_service_t *rtnp; 27814235Smarkfen ike_rw_t rw; 27824235Smarkfen door_desc_t desc, *descp = NULL; 27834235Smarkfen int oflag, omode, fd, ndesc = 0; 27844235Smarkfen char *op, *obj = NULL; 27854235Smarkfen boolean_t writing = B_FALSE; 27864235Smarkfen 27874235Smarkfen switch (cmd) { 27884235Smarkfen case IKE_SVC_READ_PS: 27894235Smarkfen obj = gettext("preshared key"); 27904235Smarkfen /* FALLTHRU */ 27914235Smarkfen case IKE_SVC_READ_RULES: 27924235Smarkfen if (obj == NULL) 27934235Smarkfen obj = gettext("policy rule"); 27944235Smarkfen op = gettext("read"); 27954235Smarkfen oflag = O_RDONLY; 27964235Smarkfen omode = 0; 27974235Smarkfen break; 27984235Smarkfen 27994235Smarkfen case IKE_SVC_WRITE_PS: 28004235Smarkfen obj = gettext("preshared key"); 28014235Smarkfen /* FALLTHRU */ 28024235Smarkfen case IKE_SVC_WRITE_RULES: 28034235Smarkfen if (obj == NULL) 28044235Smarkfen obj = gettext("policy rule"); 28054235Smarkfen op = gettext("write"); 28064235Smarkfen oflag = O_RDWR | O_CREAT | O_EXCL; 28074235Smarkfen omode = S_IRUSR | S_IWUSR; 28084235Smarkfen 28094235Smarkfen /* for write commands, dest location must be specified */ 28104235Smarkfen if (argc < 1) { 28114235Smarkfen bail_msg(gettext("destination location required " 28124235Smarkfen "to write %ss"), obj); 28134235Smarkfen } 28144235Smarkfen writing = B_TRUE; 28154235Smarkfen break; 28164235Smarkfen 28174235Smarkfen default: 28184235Smarkfen bail_msg(gettext("unrecognized read/write command (%d)."), cmd); 28194235Smarkfen } 28204235Smarkfen 28214235Smarkfen rw.cmd = cmd; 28224235Smarkfen 28234235Smarkfen if (argc >= 1) { 28244235Smarkfen rw.rw_loc = IKE_RW_LOC_USER_SPEC; 28254235Smarkfen fd = open(argv[0], oflag, omode); 28264235Smarkfen if (fd < 0) 28274235Smarkfen Bail("open user-specified file"); 28284235Smarkfen 28294235Smarkfen desc.d_data.d_desc.d_descriptor = fd; 28304235Smarkfen desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE; 28314235Smarkfen descp = &desc; 28324235Smarkfen ndesc = 1; 28334235Smarkfen } else { 28344235Smarkfen rw.rw_loc = IKE_RW_LOC_DEFAULT; 28354235Smarkfen } 28364235Smarkfen 28374235Smarkfen rtnp = ikedoor_call((char *)&rw, sizeof (ike_rw_t), descp, ndesc); 28384235Smarkfen if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) { 28394235Smarkfen /* 28404235Smarkfen * Need to remove the target file in the 28414235Smarkfen * case of a failed write command. 28424235Smarkfen */ 28434235Smarkfen if (writing) { 28444235Smarkfen /* 28454235Smarkfen * argv[0] must be valid if we're writing; we 28464235Smarkfen * exit before setting this boolean if not. 28474235Smarkfen */ 28484235Smarkfen (void) unlink(argv[0]); 28494235Smarkfen (void) close(fd); 28504235Smarkfen 28514235Smarkfen if ((rtnp != NULL) && 28524235Smarkfen (rtnp->svc_err.ike_err == IKE_ERR_NO_OBJ)) { 28534235Smarkfen message(gettext("No %s information to write."), 28544235Smarkfen obj); 28554235Smarkfen return; 28564235Smarkfen } 28574235Smarkfen } 28584235Smarkfen ikeadm_err_exit(&rtnp->svc_err, gettext("error doing %s"), op); 28594235Smarkfen } 28604235Smarkfen message(gettext("Completed %s of %s configuration information."), 28614235Smarkfen op, obj); 28624235Smarkfen } 28634235Smarkfen 28644235Smarkfen static void 28654235Smarkfen do_rbdump() 28664235Smarkfen { 28674235Smarkfen ike_cmd_t req; 28684235Smarkfen ike_service_t *rtnp; 28694235Smarkfen 28704235Smarkfen req.cmd = IKE_SVC_DBG_RBDUMP; 28714235Smarkfen 28724235Smarkfen rtnp = ikedoor_call((char *)&req, sizeof (ike_cmd_t), NULL, 0); 28734235Smarkfen if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) { 28744235Smarkfen ikeadm_err_exit(&rtnp->svc_err, gettext("error doing flush")); 28754235Smarkfen } 28764235Smarkfen message(gettext("Successfully dumped rulebase; check iked dbg")); 28774235Smarkfen } 28784235Smarkfen 28794235Smarkfen #define REQ_ARG_CNT 1 28804235Smarkfen 28814235Smarkfen /*ARGSUSED*/ 28824235Smarkfen static void 28834342Spwernau parseit(int argc, char **argv, char *notused, boolean_t notused_either) 28844235Smarkfen { 28854235Smarkfen int cmd, cmd_obj_args = 1; 28864235Smarkfen char *cmdstr, *objstr; 28874235Smarkfen 28884235Smarkfen if (interactive) { 28894235Smarkfen if (argc == 0) 28904235Smarkfen return; 28914235Smarkfen } 28924235Smarkfen 28934235Smarkfen if (argc < REQ_ARG_CNT) { 28944235Smarkfen usage(); 28954235Smarkfen } 28964235Smarkfen 28974235Smarkfen cmdstr = argv[0]; 28984235Smarkfen if (argc > REQ_ARG_CNT) { 28994235Smarkfen cmd_obj_args++; 29004235Smarkfen objstr = argv[1]; 29014235Smarkfen } else { 29024235Smarkfen objstr = NULL; 29034235Smarkfen } 29044235Smarkfen cmd = parsecmd(cmdstr, objstr); 29054235Smarkfen 29064235Smarkfen /* skip over args specifying command/object */ 29074235Smarkfen argc -= cmd_obj_args; 29084235Smarkfen argv += cmd_obj_args; 29094235Smarkfen 29104235Smarkfen switch (cmd) { 29114235Smarkfen case IKE_SVC_GET_DEFS: 29124235Smarkfen do_getdefs(cmd); 29134235Smarkfen break; 29144235Smarkfen case IKE_SVC_GET_DBG: 29154235Smarkfen case IKE_SVC_GET_PRIV: 29164235Smarkfen do_getvar(cmd); 29174235Smarkfen break; 29184235Smarkfen case IKE_SVC_GET_STATS: 29194235Smarkfen do_getstats(cmd); 29204235Smarkfen break; 29214235Smarkfen case IKE_SVC_SET_DBG: 29224235Smarkfen case IKE_SVC_SET_PRIV: 29234235Smarkfen do_setvar(cmd, argc, argv); 29244235Smarkfen break; 29254235Smarkfen case IKE_SVC_DUMP_P1S: 29264235Smarkfen case IKE_SVC_DUMP_RULES: 29274235Smarkfen case IKE_SVC_DUMP_PS: 29284235Smarkfen do_dump(cmd); 29294235Smarkfen break; 29304235Smarkfen case IKE_SVC_GET_P1: 29314235Smarkfen case IKE_SVC_GET_RULE: 29324235Smarkfen case IKE_SVC_GET_PS: 29334235Smarkfen case IKE_SVC_DEL_P1: 29344235Smarkfen case IKE_SVC_DEL_RULE: 29354235Smarkfen case IKE_SVC_DEL_PS: 29364235Smarkfen do_getdel(cmd, argc, argv); 29374235Smarkfen break; 29384235Smarkfen case IKE_SVC_NEW_RULE: 29394235Smarkfen case IKE_SVC_NEW_PS: 29404235Smarkfen do_new(cmd, argc, argv); 29414235Smarkfen break; 29424235Smarkfen case IKE_SVC_FLUSH_P1S: 29434235Smarkfen do_flush(cmd); 29444235Smarkfen break; 29454235Smarkfen case IKE_SVC_READ_RULES: 29464235Smarkfen case IKE_SVC_READ_PS: 29474235Smarkfen case IKE_SVC_WRITE_RULES: 29484235Smarkfen case IKE_SVC_WRITE_PS: 29494235Smarkfen do_rw(cmd, argc, argv); 29504235Smarkfen break; 29514235Smarkfen case IKEADM_HELP_GENERAL: 29524235Smarkfen print_help(); 29534235Smarkfen break; 29544235Smarkfen case IKEADM_HELP_GET: 29554235Smarkfen print_get_help(); 29564235Smarkfen break; 29574235Smarkfen case IKEADM_HELP_SET: 29584235Smarkfen print_set_help(); 29594235Smarkfen break; 29604235Smarkfen case IKEADM_HELP_ADD: 29614235Smarkfen print_add_help(); 29624235Smarkfen break; 29634235Smarkfen case IKEADM_HELP_DEL: 29644235Smarkfen print_del_help(); 29654235Smarkfen break; 29664235Smarkfen case IKEADM_HELP_DUMP: 29674235Smarkfen print_dump_help(); 29684235Smarkfen break; 29694235Smarkfen case IKEADM_HELP_FLUSH: 29704235Smarkfen print_flush_help(); 29714235Smarkfen break; 29724235Smarkfen case IKEADM_HELP_READ: 29734235Smarkfen print_read_help(); 29744235Smarkfen break; 29754235Smarkfen case IKEADM_HELP_WRITE: 29764235Smarkfen print_write_help(); 29774235Smarkfen break; 29784235Smarkfen case IKEADM_HELP_HELP: 29794235Smarkfen print_help_help(); 29804235Smarkfen break; 29814235Smarkfen case IKEADM_EXIT: 29824235Smarkfen if (interactive) 29834235Smarkfen exit(0); 29844235Smarkfen break; 29854235Smarkfen case IKE_SVC_DBG_RBDUMP: 29864235Smarkfen do_rbdump(); 29874235Smarkfen break; 29884235Smarkfen case IKE_SVC_ERROR: 29894235Smarkfen usage(); 29904235Smarkfen default: 29914235Smarkfen exit(0); 29924235Smarkfen } 29934235Smarkfen } 29944235Smarkfen 29954235Smarkfen int 29964235Smarkfen main(int argc, char **argv) 29974235Smarkfen { 29984235Smarkfen char ch; 29994235Smarkfen 30004235Smarkfen (void) setlocale(LC_ALL, ""); 30014235Smarkfen #if !defined(TEXT_DOMAIN) 30024235Smarkfen #define TEXT_DOMAIN "SYS_TEST" 30034235Smarkfen #endif 30044235Smarkfen (void) textdomain(TEXT_DOMAIN); 30054235Smarkfen 30064235Smarkfen while ((ch = getopt(argc, argv, "hpn")) != EOF) { 30074235Smarkfen switch (ch) { 30084235Smarkfen case 'h': 30094235Smarkfen print_help(); 30104235Smarkfen return (0); 30114235Smarkfen case 'p': 30124235Smarkfen pflag = B_TRUE; 30134235Smarkfen break; 30144235Smarkfen case 'n': 30154235Smarkfen nflag = B_TRUE; 30164235Smarkfen break; 30174235Smarkfen default: 30184235Smarkfen usage(); 30194235Smarkfen } 30204235Smarkfen } 30214235Smarkfen argc -= optind; 30224235Smarkfen argv += optind; 30234235Smarkfen 30244235Smarkfen if (open_door() < 0) { 30254235Smarkfen (void) fprintf(stderr, 30264235Smarkfen gettext("Unable to communicate with in.iked\n")); 30274235Smarkfen Bail("open_door failed"); 30284235Smarkfen } 30294235Smarkfen 30304235Smarkfen if (*argv == NULL) { 30314235Smarkfen /* no cmd-line args, do interactive mode */ 30324235Smarkfen do_interactive(stdin, NULL, "ikeadm> ", NULL, parseit); 30334235Smarkfen } 30344235Smarkfen 30354342Spwernau parseit(argc, argv, NULL, B_FALSE); 30364235Smarkfen 30374235Smarkfen return (0); 30384235Smarkfen } 3039