17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50f2065ccSmarkfen * Common Development and Distribution License (the "License").
60f2065ccSmarkfen * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate *
215d01c172SVladimir Kotal * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
227c478bd9Sstevel@tonic-gate */
237c478bd9Sstevel@tonic-gate
247c478bd9Sstevel@tonic-gate #include <unistd.h>
257c478bd9Sstevel@tonic-gate #include <stdio.h>
267c478bd9Sstevel@tonic-gate #include <stdarg.h>
277c478bd9Sstevel@tonic-gate #include <stdlib.h>
287c478bd9Sstevel@tonic-gate #include <sys/sysconf.h>
297c478bd9Sstevel@tonic-gate #include <string.h>
307c478bd9Sstevel@tonic-gate #include <strings.h>
317c478bd9Sstevel@tonic-gate #include <libintl.h>
327c478bd9Sstevel@tonic-gate #include <locale.h>
337c478bd9Sstevel@tonic-gate #include <ctype.h>
347c478bd9Sstevel@tonic-gate #include <time.h>
357c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
367c478bd9Sstevel@tonic-gate #include <sys/stat.h>
377c478bd9Sstevel@tonic-gate #include <sys/mman.h>
387c478bd9Sstevel@tonic-gate #include <fcntl.h>
397c478bd9Sstevel@tonic-gate #include <sys/socket.h>
407c478bd9Sstevel@tonic-gate #include <netdb.h>
417c478bd9Sstevel@tonic-gate #include <errno.h>
427c478bd9Sstevel@tonic-gate #include <assert.h>
437c478bd9Sstevel@tonic-gate #include <netinet/in.h>
447c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
457c478bd9Sstevel@tonic-gate #include <door.h>
467c478bd9Sstevel@tonic-gate #include <setjmp.h>
477c478bd9Sstevel@tonic-gate
487c478bd9Sstevel@tonic-gate #include <ipsec_util.h>
497c478bd9Sstevel@tonic-gate #include <ikedoor.h>
507c478bd9Sstevel@tonic-gate
517c478bd9Sstevel@tonic-gate static int doorfd = -1;
527c478bd9Sstevel@tonic-gate
537c478bd9Sstevel@tonic-gate /*
547c478bd9Sstevel@tonic-gate * These are additional return values for the command line parsing
557c478bd9Sstevel@tonic-gate * function (parsecmd()). They are specific to this utility, but
567c478bd9Sstevel@tonic-gate * need to share the same space as the IKE_SVC_* defs, without conflicts.
577c478bd9Sstevel@tonic-gate * So they're defined relative to the end of that range.
587c478bd9Sstevel@tonic-gate */
597c478bd9Sstevel@tonic-gate #define IKEADM_HELP_GENERAL IKE_SVC_MAX + 1
607c478bd9Sstevel@tonic-gate #define IKEADM_HELP_GET IKE_SVC_MAX + 2
617c478bd9Sstevel@tonic-gate #define IKEADM_HELP_SET IKE_SVC_MAX + 3
627c478bd9Sstevel@tonic-gate #define IKEADM_HELP_ADD IKE_SVC_MAX + 4
637c478bd9Sstevel@tonic-gate #define IKEADM_HELP_DEL IKE_SVC_MAX + 5
647c478bd9Sstevel@tonic-gate #define IKEADM_HELP_DUMP IKE_SVC_MAX + 6
657c478bd9Sstevel@tonic-gate #define IKEADM_HELP_FLUSH IKE_SVC_MAX + 7
667c478bd9Sstevel@tonic-gate #define IKEADM_HELP_READ IKE_SVC_MAX + 8
677c478bd9Sstevel@tonic-gate #define IKEADM_HELP_WRITE IKE_SVC_MAX + 9
68c7777ac8SPaul Wernau #define IKEADM_HELP_TOKEN IKE_SVC_MAX + 10
69c7777ac8SPaul Wernau #define IKEADM_HELP_HELP IKE_SVC_MAX + 11
70c7777ac8SPaul Wernau #define IKEADM_EXIT IKE_SVC_MAX + 12
717c478bd9Sstevel@tonic-gate
72bfe6f8f5SVladimir Kotal /*
73bfe6f8f5SVladimir Kotal * Disable default TAB completion for now (until some brave soul tackles it).
74bfe6f8f5SVladimir Kotal */
75bfe6f8f5SVladimir Kotal /* ARGSUSED */
76bfe6f8f5SVladimir Kotal static
CPL_MATCH_FN(no_match)77bfe6f8f5SVladimir Kotal CPL_MATCH_FN(no_match)
78bfe6f8f5SVladimir Kotal {
79bfe6f8f5SVladimir Kotal return (0);
80bfe6f8f5SVladimir Kotal }
81bfe6f8f5SVladimir Kotal
820fddcadbSToomas Soome static void command_complete(int s) __NORETURN;
830fddcadbSToomas Soome static void usage(void) __NORETURN;
840fddcadbSToomas Soome
857c478bd9Sstevel@tonic-gate static void
command_complete(int s)867c478bd9Sstevel@tonic-gate command_complete(int s)
877c478bd9Sstevel@tonic-gate {
887c478bd9Sstevel@tonic-gate if (interactive) {
897c478bd9Sstevel@tonic-gate longjmp(env, 1);
907c478bd9Sstevel@tonic-gate } else {
917c478bd9Sstevel@tonic-gate exit(s);
927c478bd9Sstevel@tonic-gate }
937c478bd9Sstevel@tonic-gate }
947c478bd9Sstevel@tonic-gate
957c478bd9Sstevel@tonic-gate static void
usage(void)960fddcadbSToomas Soome usage(void)
977c478bd9Sstevel@tonic-gate {
987c478bd9Sstevel@tonic-gate if (!interactive) {
997c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Usage:\t"
1007c478bd9Sstevel@tonic-gate "ikeadm [ -hnp ] cmd obj [cmd-specific options]\n"));
1017c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(" \tikeadm help\n"));
102bfe6f8f5SVladimir Kotal } else {
103bfe6f8f5SVladimir Kotal (void) fprintf(stderr,
104bfe6f8f5SVladimir Kotal gettext("\nType help for usage info\n"));
1057c478bd9Sstevel@tonic-gate }
1067c478bd9Sstevel@tonic-gate
1077c478bd9Sstevel@tonic-gate command_complete(1);
1087c478bd9Sstevel@tonic-gate }
1097c478bd9Sstevel@tonic-gate
1107c478bd9Sstevel@tonic-gate static void
print_help()1117c478bd9Sstevel@tonic-gate print_help()
1127c478bd9Sstevel@tonic-gate {
1137c478bd9Sstevel@tonic-gate (void) printf(gettext("Valid commands and objects:\n"));
1140f2065ccSmarkfen (void) printf(
1150f2065ccSmarkfen "\tget debug|priv|stats|p1|rule|preshared|defaults [%s]\n",
1167c478bd9Sstevel@tonic-gate gettext("identifier"));
1177c478bd9Sstevel@tonic-gate (void) printf("\tset priv %s\n", gettext("level"));
1187c478bd9Sstevel@tonic-gate (void) printf("\tset debug %s [%s]\n",
1197c478bd9Sstevel@tonic-gate gettext("level"), gettext("filename"));
1207c478bd9Sstevel@tonic-gate (void) printf("\tadd rule|preshared {%s}|%s\n",
1217c478bd9Sstevel@tonic-gate gettext("definition"), gettext("filename"));
1227c478bd9Sstevel@tonic-gate (void) printf("\tdel p1|rule|preshared %s\n", gettext("identifier"));
1235d01c172SVladimir Kotal (void) printf("\tdump p1|rule|preshared|certcache|groups|"
1245d01c172SVladimir Kotal "encralgs|authalgs\n");
125c7777ac8SPaul Wernau (void) printf("\tflush p1|certcache\n");
1267c478bd9Sstevel@tonic-gate (void) printf("\tread rule|preshared [%s]\n", gettext("filename"));
1277c478bd9Sstevel@tonic-gate (void) printf("\twrite rule|preshared %s\n", gettext("filename"));
128c7777ac8SPaul Wernau (void) printf("\ttoken <login|logout> %s\n",
129c7777ac8SPaul Wernau gettext("<PKCS#11 Token Object>"));
1307c478bd9Sstevel@tonic-gate (void) printf(
131c7777ac8SPaul Wernau "\thelp [get|set|add|del|dump|flush|read|write|token|help]\n");
1327c478bd9Sstevel@tonic-gate (void) printf("\texit %s\n", gettext("exit the program"));
1337c478bd9Sstevel@tonic-gate (void) printf("\tquit %s\n", gettext("exit the program"));
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate command_complete(0);
1367c478bd9Sstevel@tonic-gate }
1377c478bd9Sstevel@tonic-gate
1387c478bd9Sstevel@tonic-gate static void
print_get_help()1397c478bd9Sstevel@tonic-gate print_get_help()
1407c478bd9Sstevel@tonic-gate {
1417c478bd9Sstevel@tonic-gate (void) printf(
1427c478bd9Sstevel@tonic-gate gettext("This command gets information from in.iked.\n\n"));
1437c478bd9Sstevel@tonic-gate (void) printf(gettext("Objects that may be retrieved include:\n"));
1447c478bd9Sstevel@tonic-gate (void) printf("\tdebug\t\t");
1457c478bd9Sstevel@tonic-gate (void) printf(gettext("the current debug level\n"));
1467c478bd9Sstevel@tonic-gate (void) printf("\tpriv\t\t");
1477c478bd9Sstevel@tonic-gate (void) printf(gettext("the current privilege level\n"));
1487c478bd9Sstevel@tonic-gate (void) printf("\tstats\t\t");
1497c478bd9Sstevel@tonic-gate (void) printf(gettext("current usage statistics\n"));
1507c478bd9Sstevel@tonic-gate (void) printf("\tp1\t\t");
1517c478bd9Sstevel@tonic-gate (void) printf(gettext("a phase 1 SA, identified by\n"));
1527c478bd9Sstevel@tonic-gate (void) printf(gettext("\t\t\t local_ip remote_ip OR\n"));
1537c478bd9Sstevel@tonic-gate (void) printf(gettext("\t\t\t init_cookie resp_cookie\n"));
1547c478bd9Sstevel@tonic-gate (void) printf("\trule\t\t");
1557c478bd9Sstevel@tonic-gate (void) printf(gettext("a phase 1 rule, identified by its label\n"));
1567c478bd9Sstevel@tonic-gate (void) printf("\tpreshared\t");
1577c478bd9Sstevel@tonic-gate (void) printf(gettext("a preshared key, identified by\n"));
1587c478bd9Sstevel@tonic-gate (void) printf(gettext("\t\t\t local_ip remote_ip OR\n"));
1597c478bd9Sstevel@tonic-gate (void) printf(gettext("\t\t\t local_id remote_id\n"));
1607c478bd9Sstevel@tonic-gate (void) printf("\n");
1617c478bd9Sstevel@tonic-gate
1627c478bd9Sstevel@tonic-gate command_complete(0);
1637c478bd9Sstevel@tonic-gate }
1647c478bd9Sstevel@tonic-gate
1657c478bd9Sstevel@tonic-gate static void
print_set_help()1667c478bd9Sstevel@tonic-gate print_set_help()
1677c478bd9Sstevel@tonic-gate {
1687c478bd9Sstevel@tonic-gate (void) printf(gettext("This command sets values in in.iked.\n\n"));
1697c478bd9Sstevel@tonic-gate (void) printf(gettext("Objects that may be set include:\n"));
1707c478bd9Sstevel@tonic-gate (void) printf("\tdebug\t\t");
1717c478bd9Sstevel@tonic-gate (void) printf(gettext("change the debug level\n"));
1727c478bd9Sstevel@tonic-gate (void) printf("\tpriv\t\t");
1737c478bd9Sstevel@tonic-gate (void) printf(
1747c478bd9Sstevel@tonic-gate gettext("change the privilege level (may only be lowered)\n"));
1757c478bd9Sstevel@tonic-gate (void) printf("\n");
1767c478bd9Sstevel@tonic-gate
1777c478bd9Sstevel@tonic-gate command_complete(0);
1787c478bd9Sstevel@tonic-gate }
1797c478bd9Sstevel@tonic-gate
1807c478bd9Sstevel@tonic-gate static void
print_add_help()1817c478bd9Sstevel@tonic-gate print_add_help()
1827c478bd9Sstevel@tonic-gate {
1837c478bd9Sstevel@tonic-gate (void) printf(
1847c478bd9Sstevel@tonic-gate gettext("This command adds items to in.iked's tables.\n\n"));
1857c478bd9Sstevel@tonic-gate (void) printf(gettext("Objects that may be set include:\n"));
1867c478bd9Sstevel@tonic-gate (void) printf("\trule\t\t");
1877c478bd9Sstevel@tonic-gate (void) printf(gettext("a phase 1 policy rule\n"));
1887c478bd9Sstevel@tonic-gate (void) printf("\tpreshared\t");
1897c478bd9Sstevel@tonic-gate (void) printf(gettext("a preshared key\n"));
1907c478bd9Sstevel@tonic-gate (void) printf(
1917c478bd9Sstevel@tonic-gate gettext("\nObjects may be entered on the command-line, as a\n"));
1927c478bd9Sstevel@tonic-gate (void) printf(
1937c478bd9Sstevel@tonic-gate gettext("series of keywords and tokens contained in curly\n"));
1947c478bd9Sstevel@tonic-gate (void) printf(
1957c478bd9Sstevel@tonic-gate gettext("braces ('{', '}'); or the name of a file containing\n"));
1967c478bd9Sstevel@tonic-gate (void) printf(gettext("the object definition may be provided.\n\n"));
1977c478bd9Sstevel@tonic-gate (void) printf(
1987c478bd9Sstevel@tonic-gate gettext("For security purposes, preshared keys may only be\n"));
1997c478bd9Sstevel@tonic-gate (void) printf(
2007c478bd9Sstevel@tonic-gate gettext("entered on the command-line if ikeadm is running in\n"));
2017c478bd9Sstevel@tonic-gate (void) printf(gettext("interactive mode.\n"));
2027c478bd9Sstevel@tonic-gate (void) printf("\n");
2037c478bd9Sstevel@tonic-gate
2047c478bd9Sstevel@tonic-gate command_complete(0);
2057c478bd9Sstevel@tonic-gate }
2067c478bd9Sstevel@tonic-gate
2077c478bd9Sstevel@tonic-gate static void
print_del_help()2087c478bd9Sstevel@tonic-gate print_del_help()
2097c478bd9Sstevel@tonic-gate {
2107c478bd9Sstevel@tonic-gate (void) printf(
2117c478bd9Sstevel@tonic-gate gettext("This command deletes an item from in.iked's tables.\n\n"));
2127c478bd9Sstevel@tonic-gate (void) printf(gettext("Objects that may be deleted include:\n"));
2137c478bd9Sstevel@tonic-gate (void) printf("\tp1\t\t");
2147c478bd9Sstevel@tonic-gate (void) printf(gettext("a phase 1 SA, identified by\n"));
2157c478bd9Sstevel@tonic-gate (void) printf(gettext("\t\t\t local_ip remote_ip OR\n"));
2167c478bd9Sstevel@tonic-gate (void) printf(gettext("\t\t\t init_cookie resp_cookie\n"));
2177c478bd9Sstevel@tonic-gate (void) printf("\trule\t\t");
2187c478bd9Sstevel@tonic-gate (void) printf(gettext("a phase 1 rule, identified by its label\n"));
2197c478bd9Sstevel@tonic-gate (void) printf("\tpreshared\t");
2207c478bd9Sstevel@tonic-gate (void) printf(gettext("a preshared key, identified by\n"));
2217c478bd9Sstevel@tonic-gate (void) printf(gettext("\t\t\t local_ip remote_ip OR\n"));
2227c478bd9Sstevel@tonic-gate (void) printf(gettext("\t\t\t local_id remote_id\n"));
2237c478bd9Sstevel@tonic-gate (void) printf("\n");
2247c478bd9Sstevel@tonic-gate
2257c478bd9Sstevel@tonic-gate command_complete(0);
2267c478bd9Sstevel@tonic-gate }
2277c478bd9Sstevel@tonic-gate
2287c478bd9Sstevel@tonic-gate static void
print_dump_help()2297c478bd9Sstevel@tonic-gate print_dump_help()
2307c478bd9Sstevel@tonic-gate {
2317c478bd9Sstevel@tonic-gate (void) printf(
2327c478bd9Sstevel@tonic-gate gettext("This command dumps one of in.iked's tables.\n\n"));
2337c478bd9Sstevel@tonic-gate (void) printf(gettext("Tables that may be dumped include:\n"));
2347c478bd9Sstevel@tonic-gate (void) printf("\tp1\t\t");
2357c478bd9Sstevel@tonic-gate (void) printf(gettext("all phase 1 SAs\n"));
2367c478bd9Sstevel@tonic-gate (void) printf("\trule\t\t");
2377c478bd9Sstevel@tonic-gate (void) printf(gettext("all phase 1 rules\n"));
2387c478bd9Sstevel@tonic-gate (void) printf("\tpreshared\t");
2397c478bd9Sstevel@tonic-gate (void) printf(gettext("all preshared keys\n"));
240c7777ac8SPaul Wernau (void) printf("\tcertcache\t");
241c7777ac8SPaul Wernau (void) printf(gettext("all cached certificates\n"));
2425d01c172SVladimir Kotal (void) printf("\tgroups\t\t");
2435d01c172SVladimir Kotal (void) printf(gettext("all implemented Diffie-Hellman groups\n"));
2445d01c172SVladimir Kotal (void) printf("\tencralgs\t");
2455d01c172SVladimir Kotal (void) printf(gettext("all encryption algorithms for IKE\n"));
2465d01c172SVladimir Kotal (void) printf("\tauthalgs\t");
2475d01c172SVladimir Kotal (void) printf(gettext("all authentication algorithms IKE\n"));
2487c478bd9Sstevel@tonic-gate (void) printf("\n");
2497c478bd9Sstevel@tonic-gate
2507c478bd9Sstevel@tonic-gate command_complete(0);
2517c478bd9Sstevel@tonic-gate }
2527c478bd9Sstevel@tonic-gate
2537c478bd9Sstevel@tonic-gate static void
print_flush_help()2547c478bd9Sstevel@tonic-gate print_flush_help()
2557c478bd9Sstevel@tonic-gate {
2567c478bd9Sstevel@tonic-gate (void) printf(
2577c478bd9Sstevel@tonic-gate gettext("This command clears one of in.iked's tables.\n\n"));
2587c478bd9Sstevel@tonic-gate (void) printf(gettext("Tables that may be flushed include:\n"));
2597c478bd9Sstevel@tonic-gate (void) printf("\tp1\t\t");
2607c478bd9Sstevel@tonic-gate (void) printf(gettext("all phase 1 SAs\n"));
261c7777ac8SPaul Wernau (void) printf("\tcertcache\t");
262c7777ac8SPaul Wernau (void) printf(gettext("all cached certificates\n"));
2637c478bd9Sstevel@tonic-gate (void) printf("\n");
2647c478bd9Sstevel@tonic-gate
2657c478bd9Sstevel@tonic-gate command_complete(0);
2667c478bd9Sstevel@tonic-gate }
2677c478bd9Sstevel@tonic-gate
2687c478bd9Sstevel@tonic-gate static void
print_read_help()2697c478bd9Sstevel@tonic-gate print_read_help()
2707c478bd9Sstevel@tonic-gate {
2717c478bd9Sstevel@tonic-gate (void) printf(
2727c478bd9Sstevel@tonic-gate gettext("This command reads a new configuration file into\n"));
2737c478bd9Sstevel@tonic-gate (void) printf(
2747c478bd9Sstevel@tonic-gate gettext("in.iked, discarding the old configuration info.\n\n"));
2757c478bd9Sstevel@tonic-gate (void) printf(gettext("Sets of data that may be read include:\n"));
2767c478bd9Sstevel@tonic-gate (void) printf("\trule\t\t");
2777c478bd9Sstevel@tonic-gate (void) printf(gettext("all phase 1 rules\n"));
2787c478bd9Sstevel@tonic-gate (void) printf("\tpreshared\t");
2797c478bd9Sstevel@tonic-gate (void) printf(gettext("all preshared keys\n\n"));
2807c478bd9Sstevel@tonic-gate (void) printf(
2817c478bd9Sstevel@tonic-gate gettext("A filename may be provided to specify a source file\n"));
2827c478bd9Sstevel@tonic-gate (void) printf(gettext("other than the default.\n"));
2837c478bd9Sstevel@tonic-gate (void) printf("\n");
2847c478bd9Sstevel@tonic-gate
2857c478bd9Sstevel@tonic-gate command_complete(0);
2867c478bd9Sstevel@tonic-gate }
2877c478bd9Sstevel@tonic-gate
2887c478bd9Sstevel@tonic-gate static void
print_write_help()2897c478bd9Sstevel@tonic-gate print_write_help()
2907c478bd9Sstevel@tonic-gate {
2917c478bd9Sstevel@tonic-gate (void) printf(
2927c478bd9Sstevel@tonic-gate gettext("This command writes in.iked's current configuration\n"));
2937c478bd9Sstevel@tonic-gate (void) printf(gettext("out to a config file.\n\n"));
2947c478bd9Sstevel@tonic-gate (void) printf(gettext("Sets of data that may be written include:\n"));
2957c478bd9Sstevel@tonic-gate (void) printf("\trule\t\t");
2967c478bd9Sstevel@tonic-gate (void) printf(gettext("all phase 1 rules\n"));
2977c478bd9Sstevel@tonic-gate (void) printf("\tpreshared\t");
2987c478bd9Sstevel@tonic-gate (void) printf(gettext("all preshared keys\n\n"));
2997c478bd9Sstevel@tonic-gate (void) printf(
3007c478bd9Sstevel@tonic-gate gettext("A filename must be provided to specify the file to\n"));
3017c478bd9Sstevel@tonic-gate (void) printf(gettext("which the information should be written.\n"));
3027c478bd9Sstevel@tonic-gate (void) printf("\n");
3037c478bd9Sstevel@tonic-gate
3047c478bd9Sstevel@tonic-gate command_complete(0);
3057c478bd9Sstevel@tonic-gate }
3067c478bd9Sstevel@tonic-gate
307c7777ac8SPaul Wernau static void
print_token_help()308c7777ac8SPaul Wernau print_token_help()
309c7777ac8SPaul Wernau {
310c7777ac8SPaul Wernau (void) printf(gettext(
311c7777ac8SPaul Wernau "This command logs IKE into and out of PKCS#11 tokens.\n\n"));
312c7777ac8SPaul Wernau (void) printf(gettext("Commands include:\n"));
313c7777ac8SPaul Wernau (void) printf("\tlogin <PKCS#11 Token Object>\t");
314c7777ac8SPaul Wernau (void) printf(gettext("log into token\n"));
315c7777ac8SPaul Wernau (void) printf("\tlogout <PKCS#11 Token Object>\t");
316c7777ac8SPaul Wernau (void) printf(gettext("log out of token\n\n"));
317c7777ac8SPaul Wernau (void) printf(
318c7777ac8SPaul Wernau gettext("The PKCS#11 Token Object name must be "
319c7777ac8SPaul Wernau "enclosed in quotation marks.\n"));
320c7777ac8SPaul Wernau (void) printf("\n");
321c7777ac8SPaul Wernau
322c7777ac8SPaul Wernau command_complete(0);
323c7777ac8SPaul Wernau }
324c7777ac8SPaul Wernau
3257c478bd9Sstevel@tonic-gate static void
print_help_help()3267c478bd9Sstevel@tonic-gate print_help_help()
3277c478bd9Sstevel@tonic-gate {
3287c478bd9Sstevel@tonic-gate (void) printf(
3297c478bd9Sstevel@tonic-gate gettext("This command provides information about commands.\n\n"));
3307c478bd9Sstevel@tonic-gate (void) printf(
3317c478bd9Sstevel@tonic-gate gettext("The 'help' command alone provides a list of valid\n"));
3327c478bd9Sstevel@tonic-gate (void) printf(
3337c478bd9Sstevel@tonic-gate gettext("commands, along with the valid objects for each.\n"));
3347c478bd9Sstevel@tonic-gate (void) printf(
3357c478bd9Sstevel@tonic-gate gettext("'help' followed by a valid command name provides\n"));
3367c478bd9Sstevel@tonic-gate (void) printf(gettext("further information about that command.\n"));
3377c478bd9Sstevel@tonic-gate (void) printf("\n");
3387c478bd9Sstevel@tonic-gate
3397c478bd9Sstevel@tonic-gate command_complete(0);
3407c478bd9Sstevel@tonic-gate }
3417c478bd9Sstevel@tonic-gate
3427c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/
3437c478bd9Sstevel@tonic-gate static void
message(char * fmt,...)3447c478bd9Sstevel@tonic-gate message(char *fmt, ...)
3457c478bd9Sstevel@tonic-gate {
3467c478bd9Sstevel@tonic-gate va_list ap;
3477c478bd9Sstevel@tonic-gate char msgbuf[BUFSIZ];
3487c478bd9Sstevel@tonic-gate
3497c478bd9Sstevel@tonic-gate va_start(ap, fmt);
3507c478bd9Sstevel@tonic-gate (void) vsnprintf(msgbuf, BUFSIZ, fmt, ap);
3517c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("ikeadm: %s\n"), msgbuf);
3527c478bd9Sstevel@tonic-gate va_end(ap);
3537c478bd9Sstevel@tonic-gate }
3547c478bd9Sstevel@tonic-gate
3557c478bd9Sstevel@tonic-gate static int
open_door(void)3567c478bd9Sstevel@tonic-gate open_door(void)
3577c478bd9Sstevel@tonic-gate {
3587c478bd9Sstevel@tonic-gate if (doorfd >= 0)
3597c478bd9Sstevel@tonic-gate (void) close(doorfd);
360c7777ac8SPaul Wernau doorfd = open(DOORNM, O_RDONLY);
3617c478bd9Sstevel@tonic-gate return (doorfd);
3627c478bd9Sstevel@tonic-gate }
3637c478bd9Sstevel@tonic-gate
3647c478bd9Sstevel@tonic-gate static ike_service_t *
ikedoor_call(char * reqp,int size,door_desc_t * descp,int ndesc)3657c478bd9Sstevel@tonic-gate ikedoor_call(char *reqp, int size, door_desc_t *descp, int ndesc)
3667c478bd9Sstevel@tonic-gate {
3677c478bd9Sstevel@tonic-gate door_arg_t arg;
3687c478bd9Sstevel@tonic-gate int retries = 0;
3697c478bd9Sstevel@tonic-gate
3707c478bd9Sstevel@tonic-gate arg.data_ptr = reqp;
3717c478bd9Sstevel@tonic-gate arg.data_size = size;
3727c478bd9Sstevel@tonic-gate arg.desc_ptr = descp;
3737c478bd9Sstevel@tonic-gate arg.desc_num = ndesc;
3747c478bd9Sstevel@tonic-gate arg.rbuf = (char *)NULL;
3757c478bd9Sstevel@tonic-gate arg.rsize = 0;
3767c478bd9Sstevel@tonic-gate
3777c478bd9Sstevel@tonic-gate retry:
3787c478bd9Sstevel@tonic-gate if (door_call(doorfd, &arg) < 0) {
3797c478bd9Sstevel@tonic-gate if ((errno == EBADF) && ((++retries < 2) &&
3807c478bd9Sstevel@tonic-gate (open_door() >= 0)))
3817c478bd9Sstevel@tonic-gate goto retry;
382c8393ed7Smarkfen (void) fprintf(stderr,
383c8393ed7Smarkfen gettext("Unable to communicate with in.iked\n"));
3847c478bd9Sstevel@tonic-gate Bail("door_call failed");
3857c478bd9Sstevel@tonic-gate }
3867c478bd9Sstevel@tonic-gate
3877c478bd9Sstevel@tonic-gate if ((ndesc > 0) && (descp->d_attributes & DOOR_RELEASE) &&
3887c478bd9Sstevel@tonic-gate ((errno == EBADF) || (errno == EFAULT))) {
3897c478bd9Sstevel@tonic-gate /* callers assume passed fds will be closed no matter what */
3907c478bd9Sstevel@tonic-gate (void) close(descp->d_data.d_desc.d_descriptor);
3917c478bd9Sstevel@tonic-gate }
3927c478bd9Sstevel@tonic-gate
3937c478bd9Sstevel@tonic-gate /* LINTED E_BAD_PTR_CAST_ALIGN */
3947c478bd9Sstevel@tonic-gate return ((ike_service_t *)arg.rbuf);
3957c478bd9Sstevel@tonic-gate }
3967c478bd9Sstevel@tonic-gate
3977c478bd9Sstevel@tonic-gate /*
3987c478bd9Sstevel@tonic-gate * Parsing functions
3997c478bd9Sstevel@tonic-gate */
4007c478bd9Sstevel@tonic-gate
4017c478bd9Sstevel@tonic-gate /* stolen from ipseckey.c, with a second tier added */
4027c478bd9Sstevel@tonic-gate static int
parsecmd(char * cmdstr,char * objstr)4037c478bd9Sstevel@tonic-gate parsecmd(char *cmdstr, char *objstr)
4047c478bd9Sstevel@tonic-gate {
405c7777ac8SPaul Wernau #define MAXOBJS 11
406c8393ed7Smarkfen struct objtbl {
4077c478bd9Sstevel@tonic-gate char *obj;
4087c478bd9Sstevel@tonic-gate int token;
4097c478bd9Sstevel@tonic-gate };
4107c478bd9Sstevel@tonic-gate static struct cmdtbl {
4117c478bd9Sstevel@tonic-gate char *cmd;
4127c478bd9Sstevel@tonic-gate int null_obj_token;
4137c478bd9Sstevel@tonic-gate struct objtbl objt[MAXOBJS];
4147c478bd9Sstevel@tonic-gate } table[] = {
4157c478bd9Sstevel@tonic-gate {"get", IKE_SVC_ERROR, {
4167c478bd9Sstevel@tonic-gate {"debug", IKE_SVC_GET_DBG},
4177c478bd9Sstevel@tonic-gate {"priv", IKE_SVC_GET_PRIV},
4187c478bd9Sstevel@tonic-gate {"stats", IKE_SVC_GET_STATS},
4197c478bd9Sstevel@tonic-gate {"p1", IKE_SVC_GET_P1},
4207c478bd9Sstevel@tonic-gate {"rule", IKE_SVC_GET_RULE},
4217c478bd9Sstevel@tonic-gate {"preshared", IKE_SVC_GET_PS},
4220f2065ccSmarkfen {"defaults", IKE_SVC_GET_DEFS},
4234b56a003SDaniel Anderson {NULL, IKE_SVC_ERROR}
4247c478bd9Sstevel@tonic-gate }
4257c478bd9Sstevel@tonic-gate },
4267c478bd9Sstevel@tonic-gate {"set", IKE_SVC_ERROR, {
4277c478bd9Sstevel@tonic-gate {"debug", IKE_SVC_SET_DBG},
4287c478bd9Sstevel@tonic-gate {"priv", IKE_SVC_SET_PRIV},
4294b56a003SDaniel Anderson {NULL, IKE_SVC_ERROR}
4307c478bd9Sstevel@tonic-gate }
4317c478bd9Sstevel@tonic-gate },
432c7777ac8SPaul Wernau {"token", IKE_SVC_ERROR, {
433c7777ac8SPaul Wernau {"login", IKE_SVC_SET_PIN},
434c7777ac8SPaul Wernau {"logout", IKE_SVC_DEL_PIN},
435c7777ac8SPaul Wernau {NULL, IKE_SVC_ERROR},
436c7777ac8SPaul Wernau }
437c7777ac8SPaul Wernau },
4387c478bd9Sstevel@tonic-gate {"add", IKE_SVC_ERROR, {
4397c478bd9Sstevel@tonic-gate {"rule", IKE_SVC_NEW_RULE},
4407c478bd9Sstevel@tonic-gate {"preshared", IKE_SVC_NEW_PS},
4414b56a003SDaniel Anderson {NULL, IKE_SVC_ERROR}
4427c478bd9Sstevel@tonic-gate }
4437c478bd9Sstevel@tonic-gate },
4447c478bd9Sstevel@tonic-gate {"del", IKE_SVC_ERROR, {
4457c478bd9Sstevel@tonic-gate {"p1", IKE_SVC_DEL_P1},
4467c478bd9Sstevel@tonic-gate {"rule", IKE_SVC_DEL_RULE},
4477c478bd9Sstevel@tonic-gate {"preshared", IKE_SVC_DEL_PS},
4484b56a003SDaniel Anderson {NULL, IKE_SVC_ERROR}
4497c478bd9Sstevel@tonic-gate }
4507c478bd9Sstevel@tonic-gate },
4517c478bd9Sstevel@tonic-gate {"dump", IKE_SVC_ERROR, {
4527c478bd9Sstevel@tonic-gate {"p1", IKE_SVC_DUMP_P1S},
4537c478bd9Sstevel@tonic-gate {"rule", IKE_SVC_DUMP_RULES},
4547c478bd9Sstevel@tonic-gate {"preshared", IKE_SVC_DUMP_PS},
455c7777ac8SPaul Wernau {"certcache", IKE_SVC_DUMP_CERTCACHE},
4565d01c172SVladimir Kotal {"groups", IKE_SVC_DUMP_GROUPS},
4575d01c172SVladimir Kotal {"encralgs", IKE_SVC_DUMP_ENCRALGS},
4585d01c172SVladimir Kotal {"authalgs", IKE_SVC_DUMP_AUTHALGS},
4594b56a003SDaniel Anderson {NULL, IKE_SVC_ERROR}
4607c478bd9Sstevel@tonic-gate }
4617c478bd9Sstevel@tonic-gate },
4627c478bd9Sstevel@tonic-gate {"flush", IKE_SVC_ERROR, {
4637c478bd9Sstevel@tonic-gate {"p1", IKE_SVC_FLUSH_P1S},
464c7777ac8SPaul Wernau {"certcache", IKE_SVC_FLUSH_CERTCACHE},
4654b56a003SDaniel Anderson {NULL, IKE_SVC_ERROR}
4667c478bd9Sstevel@tonic-gate }
4677c478bd9Sstevel@tonic-gate },
4687c478bd9Sstevel@tonic-gate {"read", IKE_SVC_ERROR, {
4697c478bd9Sstevel@tonic-gate {"rule", IKE_SVC_READ_RULES},
4707c478bd9Sstevel@tonic-gate {"preshared", IKE_SVC_READ_PS},
4714b56a003SDaniel Anderson {NULL, IKE_SVC_ERROR}
4727c478bd9Sstevel@tonic-gate }
4737c478bd9Sstevel@tonic-gate },
4747c478bd9Sstevel@tonic-gate {"write", IKE_SVC_ERROR, {
4757c478bd9Sstevel@tonic-gate {"rule", IKE_SVC_WRITE_RULES},
4767c478bd9Sstevel@tonic-gate {"preshared", IKE_SVC_WRITE_PS},
4774b56a003SDaniel Anderson {NULL, IKE_SVC_ERROR}
4787c478bd9Sstevel@tonic-gate }
4797c478bd9Sstevel@tonic-gate },
4807c478bd9Sstevel@tonic-gate {"help", IKEADM_HELP_GENERAL, {
4817c478bd9Sstevel@tonic-gate {"get", IKEADM_HELP_GET},
4827c478bd9Sstevel@tonic-gate {"set", IKEADM_HELP_SET},
4837c478bd9Sstevel@tonic-gate {"add", IKEADM_HELP_ADD},
4847c478bd9Sstevel@tonic-gate {"del", IKEADM_HELP_DEL},
4857c478bd9Sstevel@tonic-gate {"dump", IKEADM_HELP_DUMP},
4867c478bd9Sstevel@tonic-gate {"flush", IKEADM_HELP_FLUSH},
4877c478bd9Sstevel@tonic-gate {"read", IKEADM_HELP_READ},
4887c478bd9Sstevel@tonic-gate {"write", IKEADM_HELP_WRITE},
489c7777ac8SPaul Wernau {"token", IKEADM_HELP_TOKEN},
4907c478bd9Sstevel@tonic-gate {"help", IKEADM_HELP_HELP},
4914b56a003SDaniel Anderson {NULL, IKE_SVC_ERROR}
4927c478bd9Sstevel@tonic-gate }
4937c478bd9Sstevel@tonic-gate },
4947c478bd9Sstevel@tonic-gate {"exit", IKEADM_EXIT, {
4954b56a003SDaniel Anderson {NULL, IKE_SVC_ERROR}
4967c478bd9Sstevel@tonic-gate }
4977c478bd9Sstevel@tonic-gate },
4987c478bd9Sstevel@tonic-gate {"quit", IKEADM_EXIT, {
4994b56a003SDaniel Anderson {NULL, IKE_SVC_ERROR}
5007c478bd9Sstevel@tonic-gate }
5017c478bd9Sstevel@tonic-gate },
5027c478bd9Sstevel@tonic-gate {"dbg", IKE_SVC_ERROR, {
5037c478bd9Sstevel@tonic-gate {"rbdump", IKE_SVC_DBG_RBDUMP},
5044b56a003SDaniel Anderson {NULL, IKE_SVC_ERROR}
5057c478bd9Sstevel@tonic-gate }
5067c478bd9Sstevel@tonic-gate },
5077c478bd9Sstevel@tonic-gate {NULL, IKE_SVC_ERROR, {
5084b56a003SDaniel Anderson {NULL, IKE_SVC_ERROR}
5097c478bd9Sstevel@tonic-gate }
5104b56a003SDaniel Anderson }
5117c478bd9Sstevel@tonic-gate };
5127c478bd9Sstevel@tonic-gate struct cmdtbl *ct = table;
5137c478bd9Sstevel@tonic-gate struct objtbl *ot;
5147c478bd9Sstevel@tonic-gate
5157c478bd9Sstevel@tonic-gate if (cmdstr == NULL) {
5167c478bd9Sstevel@tonic-gate return (IKE_SVC_ERROR);
5177c478bd9Sstevel@tonic-gate }
5187c478bd9Sstevel@tonic-gate
5197c478bd9Sstevel@tonic-gate while (ct->cmd != NULL && strcmp(ct->cmd, cmdstr) != 0)
5207c478bd9Sstevel@tonic-gate ct++;
5217c478bd9Sstevel@tonic-gate ot = ct->objt;
5227c478bd9Sstevel@tonic-gate
5237c478bd9Sstevel@tonic-gate if (ct->cmd == NULL) {
5247c478bd9Sstevel@tonic-gate message(gettext("Unrecognized command '%s'"), cmdstr);
5257c478bd9Sstevel@tonic-gate return (ot->token);
5267c478bd9Sstevel@tonic-gate }
5277c478bd9Sstevel@tonic-gate
5287c478bd9Sstevel@tonic-gate if (objstr == NULL) {
5297c478bd9Sstevel@tonic-gate return (ct->null_obj_token);
5307c478bd9Sstevel@tonic-gate }
5317c478bd9Sstevel@tonic-gate
5327c478bd9Sstevel@tonic-gate while (ot->obj != NULL && strcmp(ot->obj, objstr) != 0)
5337c478bd9Sstevel@tonic-gate ot++;
5347c478bd9Sstevel@tonic-gate
5357c478bd9Sstevel@tonic-gate if (ot->obj == NULL)
5367c478bd9Sstevel@tonic-gate message(gettext("Unrecognized object '%s'"), objstr);
5377c478bd9Sstevel@tonic-gate
5387c478bd9Sstevel@tonic-gate return (ot->token);
5397c478bd9Sstevel@tonic-gate }
5407c478bd9Sstevel@tonic-gate
5417c478bd9Sstevel@tonic-gate /*
5427c478bd9Sstevel@tonic-gate * Parsing functions:
5437c478bd9Sstevel@tonic-gate * Parse command-line identification info. All return -1 on failure,
5447c478bd9Sstevel@tonic-gate * or the number of cmd-line args "consumed" on success (though argc
5457c478bd9Sstevel@tonic-gate * and argv params are not actually modified).
5467c478bd9Sstevel@tonic-gate */
5477c478bd9Sstevel@tonic-gate
5487c478bd9Sstevel@tonic-gate static int
parse_label(int argc,char ** argv,char * label)5497c478bd9Sstevel@tonic-gate parse_label(int argc, char **argv, char *label)
5507c478bd9Sstevel@tonic-gate {
5517c478bd9Sstevel@tonic-gate if ((argc < 1) || (argv == NULL))
5527c478bd9Sstevel@tonic-gate return (-1);
5537c478bd9Sstevel@tonic-gate
5547c478bd9Sstevel@tonic-gate if (strlcpy(label, argv[0], MAX_LABEL_LEN) >= MAX_LABEL_LEN)
5557c478bd9Sstevel@tonic-gate return (-1);
5567c478bd9Sstevel@tonic-gate
5577c478bd9Sstevel@tonic-gate return (1);
5587c478bd9Sstevel@tonic-gate }
5597c478bd9Sstevel@tonic-gate
560c7777ac8SPaul Wernau /*
561c7777ac8SPaul Wernau * Parse a PKCS#11 token get the label.
562c7777ac8SPaul Wernau */
563c7777ac8SPaul Wernau static int
parse_token(int argc,char ** argv,char * token_label)564c7777ac8SPaul Wernau parse_token(int argc, char **argv, char *token_label)
565c7777ac8SPaul Wernau {
566c7777ac8SPaul Wernau if ((argc < 1) || (argv == NULL))
567c7777ac8SPaul Wernau return (-1);
568c7777ac8SPaul Wernau
569c7777ac8SPaul Wernau if (strlcpy(token_label, argv[0], PKCS11_TOKSIZE) >= PKCS11_TOKSIZE)
570c7777ac8SPaul Wernau return (-1);
571c7777ac8SPaul Wernau
572c7777ac8SPaul Wernau return (0);
573c7777ac8SPaul Wernau }
574c7777ac8SPaul Wernau
5757c478bd9Sstevel@tonic-gate /*
5767c478bd9Sstevel@tonic-gate * Parse an address off the command line. In the hpp param, either
5777c478bd9Sstevel@tonic-gate * return a hostent pointer (caller frees) or a pointer to a dummy_he_t
5787c478bd9Sstevel@tonic-gate * (must also be freed by the caller; both cases are handled by the
5797c478bd9Sstevel@tonic-gate * macro FREE_HE). The new getipnodebyname() call does the Right Thing
5807c478bd9Sstevel@tonic-gate * (TM), even with raw addresses (colon-separated IPv6 or dotted decimal
5817c478bd9Sstevel@tonic-gate * IPv4).
5827c478bd9Sstevel@tonic-gate * (mostly stolen from ipseckey.c, though some tweaks were made
5837c478bd9Sstevel@tonic-gate * to better serve our purposes here.)
5847c478bd9Sstevel@tonic-gate */
5857c478bd9Sstevel@tonic-gate
5867c478bd9Sstevel@tonic-gate typedef struct {
5877c478bd9Sstevel@tonic-gate struct hostent he;
5887c478bd9Sstevel@tonic-gate char *addtl[2];
5897c478bd9Sstevel@tonic-gate } dummy_he_t;
5907c478bd9Sstevel@tonic-gate
5917c478bd9Sstevel@tonic-gate static int
parse_addr(int argc,char ** argv,struct hostent ** hpp)5927c478bd9Sstevel@tonic-gate parse_addr(int argc, char **argv, struct hostent **hpp)
5937c478bd9Sstevel@tonic-gate {
5947c478bd9Sstevel@tonic-gate int hp_errno;
5957c478bd9Sstevel@tonic-gate struct hostent *hp = NULL;
5967c478bd9Sstevel@tonic-gate dummy_he_t *dhp;
5977c478bd9Sstevel@tonic-gate char *addr1;
5987c478bd9Sstevel@tonic-gate
5997c478bd9Sstevel@tonic-gate if ((argc < 1) || (argv == NULL) || (argv[0] == NULL))
6007c478bd9Sstevel@tonic-gate return (-1);
6017c478bd9Sstevel@tonic-gate
6027c478bd9Sstevel@tonic-gate if (!nflag) {
6037c478bd9Sstevel@tonic-gate /*
6047c478bd9Sstevel@tonic-gate * Try name->address first. Assume AF_INET6, and
6057c478bd9Sstevel@tonic-gate * get IPV4s, plus IPv6s iff IPv6 is configured.
6067c478bd9Sstevel@tonic-gate */
6077c478bd9Sstevel@tonic-gate hp = getipnodebyname(argv[0], AF_INET6, AI_DEFAULT | AI_ALL,
6087c478bd9Sstevel@tonic-gate &hp_errno);
6097c478bd9Sstevel@tonic-gate } else {
6107c478bd9Sstevel@tonic-gate /*
6117c478bd9Sstevel@tonic-gate * Try a normal address conversion only. malloc a
6127c478bd9Sstevel@tonic-gate * dummy_he_t to construct a fake hostent. Caller
6137c478bd9Sstevel@tonic-gate * will know to free this one using free_he().
6147c478bd9Sstevel@tonic-gate */
6157c478bd9Sstevel@tonic-gate dhp = (dummy_he_t *)malloc(sizeof (dummy_he_t));
6167c478bd9Sstevel@tonic-gate addr1 = (char *)malloc(sizeof (struct in6_addr));
6177c478bd9Sstevel@tonic-gate if (inet_pton(AF_INET6, argv[0], addr1) == 1) {
6187c478bd9Sstevel@tonic-gate dhp->he.h_addr_list = dhp->addtl;
6197c478bd9Sstevel@tonic-gate dhp->addtl[0] = addr1;
6207c478bd9Sstevel@tonic-gate dhp->addtl[1] = NULL;
6217c478bd9Sstevel@tonic-gate hp = &dhp->he;
6227c478bd9Sstevel@tonic-gate dhp->he.h_addrtype = AF_INET6;
6237c478bd9Sstevel@tonic-gate dhp->he.h_length = sizeof (struct in6_addr);
6247c478bd9Sstevel@tonic-gate } else if (inet_pton(AF_INET, argv[0], addr1) == 1) {
6257c478bd9Sstevel@tonic-gate dhp->he.h_addr_list = dhp->addtl;
6267c478bd9Sstevel@tonic-gate dhp->addtl[0] = addr1;
6277c478bd9Sstevel@tonic-gate dhp->addtl[1] = NULL;
6287c478bd9Sstevel@tonic-gate hp = &dhp->he;
6297c478bd9Sstevel@tonic-gate dhp->he.h_addrtype = AF_INET;
6307c478bd9Sstevel@tonic-gate dhp->he.h_length = sizeof (struct in_addr);
6317c478bd9Sstevel@tonic-gate } else {
6327c478bd9Sstevel@tonic-gate hp = NULL;
6337c478bd9Sstevel@tonic-gate }
6347c478bd9Sstevel@tonic-gate }
6357c478bd9Sstevel@tonic-gate
6367c478bd9Sstevel@tonic-gate *hpp = hp;
6377c478bd9Sstevel@tonic-gate
6387c478bd9Sstevel@tonic-gate if (hp == NULL) {
6397c478bd9Sstevel@tonic-gate message(gettext("Unknown address %s."), argv[0]);
6407c478bd9Sstevel@tonic-gate return (-1);
6417c478bd9Sstevel@tonic-gate }
6427c478bd9Sstevel@tonic-gate
6437c478bd9Sstevel@tonic-gate return (1);
6447c478bd9Sstevel@tonic-gate }
6457c478bd9Sstevel@tonic-gate
6467c478bd9Sstevel@tonic-gate /*
6477c478bd9Sstevel@tonic-gate * Free a dummy_he_t structure that was malloc'd in parse_addr().
6487c478bd9Sstevel@tonic-gate * Unfortunately, callers of parse_addr don't want to know about
6497c478bd9Sstevel@tonic-gate * dummy_he_t structs, so all they have is a pointer to the struct
6507c478bd9Sstevel@tonic-gate * hostent; so that's what's passed in. To manage this, we make
6517c478bd9Sstevel@tonic-gate * the assumption that the struct hostent is the first field in
6527c478bd9Sstevel@tonic-gate * the dummy_he_t, and therefore a pointer to it is a pointer to
6537c478bd9Sstevel@tonic-gate * the dummy_he_t.
6547c478bd9Sstevel@tonic-gate */
6557c478bd9Sstevel@tonic-gate static void
free_he(struct hostent * hep)6567c478bd9Sstevel@tonic-gate free_he(struct hostent *hep)
6577c478bd9Sstevel@tonic-gate {
6587c478bd9Sstevel@tonic-gate dummy_he_t *p = (dummy_he_t *)hep;
6597c478bd9Sstevel@tonic-gate
6607c478bd9Sstevel@tonic-gate assert(p != NULL);
6617c478bd9Sstevel@tonic-gate
6627c478bd9Sstevel@tonic-gate if (p->addtl[0])
6637c478bd9Sstevel@tonic-gate free(p->addtl[0]);
6647c478bd9Sstevel@tonic-gate if (p->addtl[1])
6657c478bd9Sstevel@tonic-gate free(p->addtl[1]);
6667c478bd9Sstevel@tonic-gate
6677c478bd9Sstevel@tonic-gate free(p);
6687c478bd9Sstevel@tonic-gate }
6697c478bd9Sstevel@tonic-gate
6707c478bd9Sstevel@tonic-gate #define FREE_HE(x) \
6717c478bd9Sstevel@tonic-gate if (nflag) \
6727c478bd9Sstevel@tonic-gate free_he(x); \
6737c478bd9Sstevel@tonic-gate else \
6747c478bd9Sstevel@tonic-gate freehostent(x)
6757c478bd9Sstevel@tonic-gate
6767c478bd9Sstevel@tonic-gate static void
headdr2sa(char * hea,struct sockaddr_storage * sa,int len)6777c478bd9Sstevel@tonic-gate headdr2sa(char *hea, struct sockaddr_storage *sa, int len)
6787c478bd9Sstevel@tonic-gate {
6797c478bd9Sstevel@tonic-gate struct sockaddr_in *sin;
6807c478bd9Sstevel@tonic-gate struct sockaddr_in6 *sin6;
6817c478bd9Sstevel@tonic-gate
6827c478bd9Sstevel@tonic-gate if (len == sizeof (struct in6_addr)) {
6837c478bd9Sstevel@tonic-gate /* LINTED E_BAD_PTR_CAST_ALIGN */
6847c478bd9Sstevel@tonic-gate if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)hea)) {
6857c478bd9Sstevel@tonic-gate sin = (struct sockaddr_in *)sa;
6867c478bd9Sstevel@tonic-gate (void) memset(sin, 0, sizeof (*sin));
6877c478bd9Sstevel@tonic-gate /* LINTED E_BAD_PTR_CAST_ALIGN */
6887c478bd9Sstevel@tonic-gate IN6_V4MAPPED_TO_INADDR((struct in6_addr *)hea,
6897c478bd9Sstevel@tonic-gate &sin->sin_addr);
6907c478bd9Sstevel@tonic-gate sin->sin_family = AF_INET;
6917c478bd9Sstevel@tonic-gate } else {
6927c478bd9Sstevel@tonic-gate sin6 = (struct sockaddr_in6 *)sa;
6937c478bd9Sstevel@tonic-gate (void) memset(sin6, 0, sizeof (*sin6));
6947c478bd9Sstevel@tonic-gate (void) memcpy(&sin6->sin6_addr, hea,
6957c478bd9Sstevel@tonic-gate sizeof (struct in6_addr));
6967c478bd9Sstevel@tonic-gate sin6->sin6_family = AF_INET6;
6977c478bd9Sstevel@tonic-gate }
6987c478bd9Sstevel@tonic-gate } else {
6997c478bd9Sstevel@tonic-gate sin = (struct sockaddr_in *)sa;
7007c478bd9Sstevel@tonic-gate (void) memset(sin, 0, sizeof (*sin));
7017c478bd9Sstevel@tonic-gate (void) memcpy(&sin->sin_addr, hea, sizeof (struct in_addr));
7027c478bd9Sstevel@tonic-gate sin->sin_family = AF_INET;
7037c478bd9Sstevel@tonic-gate }
7047c478bd9Sstevel@tonic-gate }
7057c478bd9Sstevel@tonic-gate
7067c478bd9Sstevel@tonic-gate /*
7077c478bd9Sstevel@tonic-gate * The possible ident-type keywords that might be used on the command
7087c478bd9Sstevel@tonic-gate * line. This is a superset of the ones supported by ipseckey, those
7097c478bd9Sstevel@tonic-gate * in the ike config file, and those in ike.preshared.
7107c478bd9Sstevel@tonic-gate */
7117c478bd9Sstevel@tonic-gate static keywdtab_t idtypes[] = {
7127c478bd9Sstevel@tonic-gate /* ip, ipv4, and ipv6 are valid for preshared keys... */
7137c478bd9Sstevel@tonic-gate {SADB_IDENTTYPE_RESERVED, "ip"},
7147c478bd9Sstevel@tonic-gate {SADB_IDENTTYPE_RESERVED, "ipv4"},
7157c478bd9Sstevel@tonic-gate {SADB_IDENTTYPE_RESERVED, "ipv6"},
7167c478bd9Sstevel@tonic-gate {SADB_IDENTTYPE_PREFIX, "prefix"},
7177c478bd9Sstevel@tonic-gate {SADB_IDENTTYPE_PREFIX, "ipv4-prefix"},
7187c478bd9Sstevel@tonic-gate {SADB_IDENTTYPE_PREFIX, "ipv6-prefix"},
7197c478bd9Sstevel@tonic-gate {SADB_IDENTTYPE_PREFIX, "subnet"},
7207c478bd9Sstevel@tonic-gate {SADB_IDENTTYPE_PREFIX, "subnetv4"},
7217c478bd9Sstevel@tonic-gate {SADB_IDENTTYPE_PREFIX, "subnetv6"},
7227c478bd9Sstevel@tonic-gate {SADB_IDENTTYPE_FQDN, "fqdn"},
7237c478bd9Sstevel@tonic-gate {SADB_IDENTTYPE_FQDN, "dns"},
7247c478bd9Sstevel@tonic-gate {SADB_IDENTTYPE_FQDN, "domain"},
7257c478bd9Sstevel@tonic-gate {SADB_IDENTTYPE_FQDN, "domainname"},
7267c478bd9Sstevel@tonic-gate {SADB_IDENTTYPE_USER_FQDN, "user_fqdn"},
7277c478bd9Sstevel@tonic-gate {SADB_IDENTTYPE_USER_FQDN, "mbox"},
7287c478bd9Sstevel@tonic-gate {SADB_IDENTTYPE_USER_FQDN, "mailbox"},
7297c478bd9Sstevel@tonic-gate {SADB_X_IDENTTYPE_DN, "dn"},
7307c478bd9Sstevel@tonic-gate {SADB_X_IDENTTYPE_DN, "asn1dn"},
7317c478bd9Sstevel@tonic-gate {SADB_X_IDENTTYPE_GN, "gn"},
7327c478bd9Sstevel@tonic-gate {SADB_X_IDENTTYPE_GN, "asn1gn"},
7337c478bd9Sstevel@tonic-gate {SADB_X_IDENTTYPE_ADDR_RANGE, "ipv4-range"},
7347c478bd9Sstevel@tonic-gate {SADB_X_IDENTTYPE_ADDR_RANGE, "ipv6-range"},
7357c478bd9Sstevel@tonic-gate {SADB_X_IDENTTYPE_ADDR_RANGE, "rangev4"},
7367c478bd9Sstevel@tonic-gate {SADB_X_IDENTTYPE_ADDR_RANGE, "rangev6"},
7377c478bd9Sstevel@tonic-gate {SADB_X_IDENTTYPE_KEY_ID, "keyid"},
73895c74518SToomas Soome {0, NULL}
7397c478bd9Sstevel@tonic-gate };
7407c478bd9Sstevel@tonic-gate
7417c478bd9Sstevel@tonic-gate static int
parse_idtype(char * type,uint16_t * idnum)7427c478bd9Sstevel@tonic-gate parse_idtype(char *type, uint16_t *idnum)
7437c478bd9Sstevel@tonic-gate {
7447c478bd9Sstevel@tonic-gate keywdtab_t *idp;
7457c478bd9Sstevel@tonic-gate
7467c478bd9Sstevel@tonic-gate if (type == NULL)
7477c478bd9Sstevel@tonic-gate return (-1);
7487c478bd9Sstevel@tonic-gate
7497c478bd9Sstevel@tonic-gate for (idp = idtypes; idp->kw_str != NULL; idp++) {
7507c478bd9Sstevel@tonic-gate if (strcasecmp(idp->kw_str, type) == 0) {
7517c478bd9Sstevel@tonic-gate if (idnum != NULL)
7527c478bd9Sstevel@tonic-gate *idnum = idp->kw_tag;
7537c478bd9Sstevel@tonic-gate return (1);
7547c478bd9Sstevel@tonic-gate }
7557c478bd9Sstevel@tonic-gate }
7567c478bd9Sstevel@tonic-gate
7577c478bd9Sstevel@tonic-gate return (-1);
7587c478bd9Sstevel@tonic-gate }
7597c478bd9Sstevel@tonic-gate
7607c478bd9Sstevel@tonic-gate /*
7617c478bd9Sstevel@tonic-gate * The sadb_ident_t is malloc'd, since its length varies;
7627c478bd9Sstevel@tonic-gate * so the caller must free() it when done with the data.
7637c478bd9Sstevel@tonic-gate */
7647c478bd9Sstevel@tonic-gate static int
parse_ident(int argc,char ** argv,sadb_ident_t ** idpp)7657c478bd9Sstevel@tonic-gate parse_ident(int argc, char **argv, sadb_ident_t **idpp)
7667c478bd9Sstevel@tonic-gate {
7677c478bd9Sstevel@tonic-gate int alloclen, consumed;
7687c478bd9Sstevel@tonic-gate sadb_ident_t *idp;
7697c478bd9Sstevel@tonic-gate if ((argc < 2) || (argv == NULL) || (argv[0] == NULL) ||
7707c478bd9Sstevel@tonic-gate (argv[1] == NULL))
7717c478bd9Sstevel@tonic-gate return (-1);
7727c478bd9Sstevel@tonic-gate
7737c478bd9Sstevel@tonic-gate alloclen = sizeof (sadb_ident_t) + IKEDOORROUNDUP(strlen(argv[1]) + 1);
7747c478bd9Sstevel@tonic-gate *idpp = idp = (sadb_ident_t *)malloc(alloclen);
7757c478bd9Sstevel@tonic-gate if (idp == NULL)
7767c478bd9Sstevel@tonic-gate Bail("parsing identity");
7777c478bd9Sstevel@tonic-gate
7787c478bd9Sstevel@tonic-gate if ((consumed = parse_idtype(argv[0], &idp->sadb_ident_type)) < 0) {
7797c478bd9Sstevel@tonic-gate message(gettext("unknown identity type %s."), argv[0]);
7807c478bd9Sstevel@tonic-gate return (-1);
7817c478bd9Sstevel@tonic-gate }
7827c478bd9Sstevel@tonic-gate
7837c478bd9Sstevel@tonic-gate idp->sadb_ident_len = SADB_8TO64(alloclen);
7847c478bd9Sstevel@tonic-gate idp->sadb_ident_reserved = 0;
7857c478bd9Sstevel@tonic-gate idp->sadb_ident_id = 0;
7867c478bd9Sstevel@tonic-gate
7877c478bd9Sstevel@tonic-gate /* now copy in identity param */
788e3320f40Smarkfen (void) strlcpy((char *)(idp + 1), argv[1],
789e3320f40Smarkfen alloclen - (sizeof (sadb_ident_t)));
7907c478bd9Sstevel@tonic-gate
7917c478bd9Sstevel@tonic-gate return (++consumed);
7927c478bd9Sstevel@tonic-gate }
7937c478bd9Sstevel@tonic-gate
7947c478bd9Sstevel@tonic-gate static int
parse_cky(int argc,char ** argv,uint64_t * ckyp)7957c478bd9Sstevel@tonic-gate parse_cky(int argc, char **argv, uint64_t *ckyp)
7967c478bd9Sstevel@tonic-gate {
7977c478bd9Sstevel@tonic-gate u_longlong_t arg;
7987c478bd9Sstevel@tonic-gate
7997c478bd9Sstevel@tonic-gate if ((argc < 1) || (argv[0] == NULL))
8007c478bd9Sstevel@tonic-gate return (-1);
8017c478bd9Sstevel@tonic-gate
8027c478bd9Sstevel@tonic-gate errno = 0;
8037c478bd9Sstevel@tonic-gate arg = strtoull(argv[0], NULL, 0);
8047c478bd9Sstevel@tonic-gate if (errno != 0) {
8057c478bd9Sstevel@tonic-gate message(gettext("failed to parse cookie %s."), argv[0]);
8067c478bd9Sstevel@tonic-gate return (-1);
8077c478bd9Sstevel@tonic-gate }
8087c478bd9Sstevel@tonic-gate
8097c478bd9Sstevel@tonic-gate *ckyp = (uint64_t)arg;
8107c478bd9Sstevel@tonic-gate
8117c478bd9Sstevel@tonic-gate return (1);
8127c478bd9Sstevel@tonic-gate }
8137c478bd9Sstevel@tonic-gate
8147c478bd9Sstevel@tonic-gate static int
parse_addr_pr(int argc,char ** argv,struct hostent ** h1pp,struct hostent ** h2pp)8157c478bd9Sstevel@tonic-gate parse_addr_pr(int argc, char **argv, struct hostent **h1pp,
8160fddcadbSToomas Soome struct hostent **h2pp)
8177c478bd9Sstevel@tonic-gate {
8187c478bd9Sstevel@tonic-gate int rtn, consumed = 0;
8197c478bd9Sstevel@tonic-gate
8207c478bd9Sstevel@tonic-gate if ((rtn = parse_addr(argc, argv, h1pp)) < 0) {
8217c478bd9Sstevel@tonic-gate return (-1);
8227c478bd9Sstevel@tonic-gate }
8237c478bd9Sstevel@tonic-gate consumed = rtn;
8247c478bd9Sstevel@tonic-gate argc -= rtn;
8257c478bd9Sstevel@tonic-gate argv += rtn;
8267c478bd9Sstevel@tonic-gate
8277c478bd9Sstevel@tonic-gate if ((rtn = parse_addr(argc, argv, h2pp)) < 0) {
8287c478bd9Sstevel@tonic-gate FREE_HE(*h1pp);
8297c478bd9Sstevel@tonic-gate return (-1);
8307c478bd9Sstevel@tonic-gate }
8317c478bd9Sstevel@tonic-gate consumed += rtn;
8327c478bd9Sstevel@tonic-gate
8337c478bd9Sstevel@tonic-gate return (consumed);
8347c478bd9Sstevel@tonic-gate }
8357c478bd9Sstevel@tonic-gate
8367c478bd9Sstevel@tonic-gate /*
8377c478bd9Sstevel@tonic-gate * The sadb_ident_ts are malloc'd, since their length varies;
8387c478bd9Sstevel@tonic-gate * so the caller must free() them when done with the data.
8397c478bd9Sstevel@tonic-gate */
8407c478bd9Sstevel@tonic-gate static int
parse_ident_pr(int argc,char ** argv,sadb_ident_t ** id1pp,sadb_ident_t ** id2pp)8417c478bd9Sstevel@tonic-gate parse_ident_pr(int argc, char **argv, sadb_ident_t **id1pp,
8427c478bd9Sstevel@tonic-gate sadb_ident_t **id2pp)
8437c478bd9Sstevel@tonic-gate {
8447c478bd9Sstevel@tonic-gate int rtn, consumed = 0;
8457c478bd9Sstevel@tonic-gate
8467c478bd9Sstevel@tonic-gate if ((rtn = parse_ident(argc, argv, id1pp)) < 0) {
8477c478bd9Sstevel@tonic-gate return (-1);
8487c478bd9Sstevel@tonic-gate }
8497c478bd9Sstevel@tonic-gate consumed = rtn;
8507c478bd9Sstevel@tonic-gate argc -= rtn;
8517c478bd9Sstevel@tonic-gate argv += rtn;
8527c478bd9Sstevel@tonic-gate
8537c478bd9Sstevel@tonic-gate (*id1pp)->sadb_ident_exttype = SADB_EXT_IDENTITY_SRC;
8547c478bd9Sstevel@tonic-gate
8557c478bd9Sstevel@tonic-gate if ((rtn = parse_ident(argc, argv, id2pp)) < 0) {
8567c478bd9Sstevel@tonic-gate free(*id1pp);
8577c478bd9Sstevel@tonic-gate return (-1);
8587c478bd9Sstevel@tonic-gate }
8597c478bd9Sstevel@tonic-gate consumed += rtn;
8607c478bd9Sstevel@tonic-gate
8617c478bd9Sstevel@tonic-gate (*id2pp)->sadb_ident_exttype = SADB_EXT_IDENTITY_DST;
8627c478bd9Sstevel@tonic-gate
8637c478bd9Sstevel@tonic-gate return (consumed);
8647c478bd9Sstevel@tonic-gate }
8657c478bd9Sstevel@tonic-gate
8667c478bd9Sstevel@tonic-gate static int
parse_cky_pr(int argc,char ** argv,ike_cky_pr_t * cpr)8677c478bd9Sstevel@tonic-gate parse_cky_pr(int argc, char **argv, ike_cky_pr_t *cpr)
8687c478bd9Sstevel@tonic-gate {
8697c478bd9Sstevel@tonic-gate int rtn, consumed = 0;
8707c478bd9Sstevel@tonic-gate
8717c478bd9Sstevel@tonic-gate if ((rtn = parse_cky(argc, argv, &cpr->cky_i)) < 0) {
8727c478bd9Sstevel@tonic-gate return (-1);
8737c478bd9Sstevel@tonic-gate }
8747c478bd9Sstevel@tonic-gate consumed = rtn;
8757c478bd9Sstevel@tonic-gate argc -= rtn;
8767c478bd9Sstevel@tonic-gate argv += rtn;
8777c478bd9Sstevel@tonic-gate
8787c478bd9Sstevel@tonic-gate if ((rtn = parse_cky(argc, argv, &cpr->cky_r)) < 0) {
8797c478bd9Sstevel@tonic-gate return (-1);
8807c478bd9Sstevel@tonic-gate }
8817c478bd9Sstevel@tonic-gate consumed += rtn;
8827c478bd9Sstevel@tonic-gate
8837c478bd9Sstevel@tonic-gate return (consumed);
8847c478bd9Sstevel@tonic-gate }
8857c478bd9Sstevel@tonic-gate
8867c478bd9Sstevel@tonic-gate /*
8877c478bd9Sstevel@tonic-gate * Preshared key field types...used for parsing preshared keys that
8887c478bd9Sstevel@tonic-gate * have been entered on the command line. The code to parse preshared
8897c478bd9Sstevel@tonic-gate * keys (parse_ps, parse_key, parse_psfldid, parse_ikmtype, ...) is
8907c478bd9Sstevel@tonic-gate * mostly duplicated from in.iked's readps.c.
8917c478bd9Sstevel@tonic-gate */
8927c478bd9Sstevel@tonic-gate #define PSFLD_LOCID 1
8937c478bd9Sstevel@tonic-gate #define PSFLD_LOCIDTYPE 2
8947c478bd9Sstevel@tonic-gate #define PSFLD_REMID 3
8957c478bd9Sstevel@tonic-gate #define PSFLD_REMIDTYPE 4
8967c478bd9Sstevel@tonic-gate #define PSFLD_MODE 5
8977c478bd9Sstevel@tonic-gate #define PSFLD_KEY 6
8987c478bd9Sstevel@tonic-gate
8997c478bd9Sstevel@tonic-gate static keywdtab_t psfldtypes[] = {
9007c478bd9Sstevel@tonic-gate {PSFLD_LOCID, "localid"},
9017c478bd9Sstevel@tonic-gate {PSFLD_LOCIDTYPE, "localidtype"},
9027c478bd9Sstevel@tonic-gate {PSFLD_REMID, "remoteid"},
9037c478bd9Sstevel@tonic-gate {PSFLD_REMIDTYPE, "remoteidtype"},
9047c478bd9Sstevel@tonic-gate {PSFLD_MODE, "ike_mode"},
9057c478bd9Sstevel@tonic-gate {PSFLD_KEY, "key"},
90695c74518SToomas Soome {0, NULL}
9077c478bd9Sstevel@tonic-gate };
9087c478bd9Sstevel@tonic-gate
9097c478bd9Sstevel@tonic-gate static int
parse_psfldid(char * type,uint16_t * idnum)9107c478bd9Sstevel@tonic-gate parse_psfldid(char *type, uint16_t *idnum)
9117c478bd9Sstevel@tonic-gate {
9127c478bd9Sstevel@tonic-gate keywdtab_t *pfp;
9137c478bd9Sstevel@tonic-gate
9147c478bd9Sstevel@tonic-gate if (type == NULL)
9157c478bd9Sstevel@tonic-gate return (-1);
9167c478bd9Sstevel@tonic-gate
9177c478bd9Sstevel@tonic-gate for (pfp = psfldtypes; pfp->kw_str != NULL; pfp++) {
9187c478bd9Sstevel@tonic-gate if (strcasecmp(pfp->kw_str, type) == 0) {
9197c478bd9Sstevel@tonic-gate if (idnum != NULL)
9207c478bd9Sstevel@tonic-gate *idnum = pfp->kw_tag;
9217c478bd9Sstevel@tonic-gate return (1);
9227c478bd9Sstevel@tonic-gate }
9237c478bd9Sstevel@tonic-gate }
9247c478bd9Sstevel@tonic-gate
9257c478bd9Sstevel@tonic-gate return (-1);
9267c478bd9Sstevel@tonic-gate }
9277c478bd9Sstevel@tonic-gate
9287c478bd9Sstevel@tonic-gate static keywdtab_t ikemodes[] = {
9297c478bd9Sstevel@tonic-gate {IKE_XCHG_IDENTITY_PROTECT, "main"},
9307c478bd9Sstevel@tonic-gate {IKE_XCHG_AGGRESSIVE, "aggressive"},
9317c478bd9Sstevel@tonic-gate {IKE_XCHG_IP_AND_AGGR, "both"},
93295c74518SToomas Soome {0, NULL}
9337c478bd9Sstevel@tonic-gate };
9347c478bd9Sstevel@tonic-gate
9357c478bd9Sstevel@tonic-gate static int
parse_ikmtype(char * mode,uint16_t * modenum)9367c478bd9Sstevel@tonic-gate parse_ikmtype(char *mode, uint16_t *modenum)
9377c478bd9Sstevel@tonic-gate {
9387c478bd9Sstevel@tonic-gate keywdtab_t *ikmp;
9397c478bd9Sstevel@tonic-gate
9407c478bd9Sstevel@tonic-gate if (mode == NULL)
9417c478bd9Sstevel@tonic-gate return (-1);
9427c478bd9Sstevel@tonic-gate
9437c478bd9Sstevel@tonic-gate for (ikmp = ikemodes; ikmp->kw_str != NULL; ikmp++) {
9447c478bd9Sstevel@tonic-gate if (strcasecmp(ikmp->kw_str, mode) == 0) {
9457c478bd9Sstevel@tonic-gate if (modenum != NULL)
9467c478bd9Sstevel@tonic-gate *modenum = ikmp->kw_tag;
9477c478bd9Sstevel@tonic-gate return (1);
9487c478bd9Sstevel@tonic-gate }
9497c478bd9Sstevel@tonic-gate }
9507c478bd9Sstevel@tonic-gate
9517c478bd9Sstevel@tonic-gate return (-1);
9527c478bd9Sstevel@tonic-gate }
9537c478bd9Sstevel@tonic-gate
9547c478bd9Sstevel@tonic-gate #define hd2num(hd) (((hd) >= '0' && (hd) <= '9') ? ((hd) - '0') : \
9557c478bd9Sstevel@tonic-gate (((hd) >= 'a' && (hd) <= 'f') ? ((hd) - 'a' + 10) : ((hd) - 'A' + 10)))
9567c478bd9Sstevel@tonic-gate
9577c478bd9Sstevel@tonic-gate static uint8_t *
parse_key(char * input,uint_t * keybuflen,uint_t * lbits)9587c478bd9Sstevel@tonic-gate parse_key(char *input, uint_t *keybuflen, uint_t *lbits)
9597c478bd9Sstevel@tonic-gate {
9607c478bd9Sstevel@tonic-gate uint8_t *keyp, *keybufp;
9617c478bd9Sstevel@tonic-gate uint_t i, hexlen = 0, bits, alloclen;
9627c478bd9Sstevel@tonic-gate
9637c478bd9Sstevel@tonic-gate for (i = 0; input[i] != '\0' && input[i] != '/'; i++)
9647c478bd9Sstevel@tonic-gate hexlen++;
9657c478bd9Sstevel@tonic-gate
9667c478bd9Sstevel@tonic-gate if (input[i] == '\0') {
9677c478bd9Sstevel@tonic-gate bits = 0;
9687c478bd9Sstevel@tonic-gate } else {
9697c478bd9Sstevel@tonic-gate /* Have /nn. */
9707c478bd9Sstevel@tonic-gate input[i] = '\0';
9717c478bd9Sstevel@tonic-gate if (sscanf((input + i + 1), "%u", &bits) != 1)
9727c478bd9Sstevel@tonic-gate return (NULL);
9737c478bd9Sstevel@tonic-gate
9747c478bd9Sstevel@tonic-gate /* hexlen is in nibbles */
9757c478bd9Sstevel@tonic-gate if (((bits + 3) >> 2) > hexlen)
9767c478bd9Sstevel@tonic-gate return (NULL);
9777c478bd9Sstevel@tonic-gate
9787c478bd9Sstevel@tonic-gate /*
9797c478bd9Sstevel@tonic-gate * Adjust hexlen down if user gave us too small of a bit
9807c478bd9Sstevel@tonic-gate * count.
9817c478bd9Sstevel@tonic-gate */
9827c478bd9Sstevel@tonic-gate if ((hexlen << 2) > bits + 3) {
9837c478bd9Sstevel@tonic-gate hexlen = (bits + 3) >> 2;
9847c478bd9Sstevel@tonic-gate input[hexlen] = '\0';
9857c478bd9Sstevel@tonic-gate }
9867c478bd9Sstevel@tonic-gate }
9877c478bd9Sstevel@tonic-gate
9887c478bd9Sstevel@tonic-gate /*
9897c478bd9Sstevel@tonic-gate * Allocate. Remember, hexlen is in nibbles.
9907c478bd9Sstevel@tonic-gate */
9917c478bd9Sstevel@tonic-gate
9927c478bd9Sstevel@tonic-gate alloclen = (hexlen/2 + (hexlen & 0x1));
9937c478bd9Sstevel@tonic-gate keyp = malloc(alloclen);
9947c478bd9Sstevel@tonic-gate
9957c478bd9Sstevel@tonic-gate if (keyp == NULL)
9967c478bd9Sstevel@tonic-gate return (NULL);
9977c478bd9Sstevel@tonic-gate
9987c478bd9Sstevel@tonic-gate keybufp = keyp;
9997c478bd9Sstevel@tonic-gate *keybuflen = alloclen;
10007c478bd9Sstevel@tonic-gate if (bits == 0)
10017c478bd9Sstevel@tonic-gate *lbits = (hexlen + (hexlen & 0x1)) << 2;
10027c478bd9Sstevel@tonic-gate else
10037c478bd9Sstevel@tonic-gate *lbits = bits;
10047c478bd9Sstevel@tonic-gate
10057c478bd9Sstevel@tonic-gate /*
10067c478bd9Sstevel@tonic-gate * Read in nibbles. Read in odd-numbered as shifted high.
10077c478bd9Sstevel@tonic-gate * (e.g. 123 becomes 0x1230).
10087c478bd9Sstevel@tonic-gate */
10097c478bd9Sstevel@tonic-gate for (i = 0; input[i] != '\0'; i += 2) {
10107c478bd9Sstevel@tonic-gate boolean_t second = (input[i + 1] != '\0');
10117c478bd9Sstevel@tonic-gate
10127c478bd9Sstevel@tonic-gate if (!isxdigit(input[i]) ||
10137c478bd9Sstevel@tonic-gate (!isxdigit(input[i + 1]) && second)) {
10147c478bd9Sstevel@tonic-gate free(keyp);
10157c478bd9Sstevel@tonic-gate return (NULL);
10167c478bd9Sstevel@tonic-gate }
10177c478bd9Sstevel@tonic-gate *keyp = (hd2num(input[i]) << 4);
10187c478bd9Sstevel@tonic-gate if (second)
10197c478bd9Sstevel@tonic-gate *keyp |= hd2num(input[i + 1]);
10207c478bd9Sstevel@tonic-gate else
10217c478bd9Sstevel@tonic-gate break; /* out of for loop. */
10227c478bd9Sstevel@tonic-gate keyp++;
10237c478bd9Sstevel@tonic-gate }
10247c478bd9Sstevel@tonic-gate
10257c478bd9Sstevel@tonic-gate /* zero the remaining bits if we're a non-octet amount. */
10267c478bd9Sstevel@tonic-gate if (bits & 0x7)
10277c478bd9Sstevel@tonic-gate *((input[i] == '\0') ? keyp - 1 : keyp) &=
10287c478bd9Sstevel@tonic-gate 0xff << (8 - (bits & 0x7));
10297c478bd9Sstevel@tonic-gate return (keybufp);
10307c478bd9Sstevel@tonic-gate }
10317c478bd9Sstevel@tonic-gate
10327c478bd9Sstevel@tonic-gate /*
10337c478bd9Sstevel@tonic-gate * the ike_ps_t struct (plus trailing data) will be allocated here,
10347c478bd9Sstevel@tonic-gate * so it will need to be freed by the caller.
10357c478bd9Sstevel@tonic-gate */
10367c478bd9Sstevel@tonic-gate static int
parse_ps(int argc,char ** argv,ike_ps_t ** presharedpp,int * len)10377c478bd9Sstevel@tonic-gate parse_ps(int argc, char **argv, ike_ps_t **presharedpp, int *len)
10387c478bd9Sstevel@tonic-gate {
10397c478bd9Sstevel@tonic-gate uint_t c = 0, locidlen, remidlen, keylen, keybits;
10407c478bd9Sstevel@tonic-gate uint_t a_locidtotal = 0, a_remidtotal = 0;
104141c215c2SPaul Wernau char *locid, *remid, *locpfx = NULL, *rempfx = NULL;
10427c478bd9Sstevel@tonic-gate uint8_t *keyp = NULL;
10437c478bd9Sstevel@tonic-gate uint16_t fldid, locidtype, remidtype, mtype;
10447c478bd9Sstevel@tonic-gate struct hostent *loche = NULL, *remhe = NULL;
10457c478bd9Sstevel@tonic-gate ike_ps_t *psp = NULL;
10467c478bd9Sstevel@tonic-gate sadb_ident_t *sidp;
104715b07f80Spwernau boolean_t whacked = B_FALSE;
104841c215c2SPaul Wernau int pfxlen = 0;
10497c478bd9Sstevel@tonic-gate
10507c478bd9Sstevel@tonic-gate if ((argv[c] == NULL) || (argv[c][0] != '{'))
10517c478bd9Sstevel@tonic-gate return (-1);
10527c478bd9Sstevel@tonic-gate if (argv[c][1] != 0) {
10537c478bd9Sstevel@tonic-gate /* no space between '{' and first token */
10547c478bd9Sstevel@tonic-gate argv[c]++;
10557c478bd9Sstevel@tonic-gate } else {
10567c478bd9Sstevel@tonic-gate c++;
10577c478bd9Sstevel@tonic-gate }
105815b07f80Spwernau if ((argv[argc - 1][strlen(argv[argc - 1]) - 1] == '}') &&
105915b07f80Spwernau (argv[argc - 1][0] != '}')) {
106015b07f80Spwernau /*
106115b07f80Spwernau * whack '}' without a space before it or parsers break.
106215b07f80Spwernau * Remember this trailing character for later
106315b07f80Spwernau */
106415b07f80Spwernau argv[argc - 1][strlen(argv[argc - 1]) - 1] = '\0';
106515b07f80Spwernau whacked = B_TRUE;
106615b07f80Spwernau }
10677c478bd9Sstevel@tonic-gate
106841c215c2SPaul Wernau /* Default to type IP */
106941c215c2SPaul Wernau locidtype = remidtype = SADB_IDENTTYPE_RESERVED;
107041c215c2SPaul Wernau /* Default to base exchanges */
107141c215c2SPaul Wernau mtype = IKE_XCHG_BASE;
107241c215c2SPaul Wernau
10737c478bd9Sstevel@tonic-gate while ((c < argc) && (argv[c] != NULL) && (argv[c][0] != '}')) {
107415b07f80Spwernau if ((argv[c + 1] == NULL) || (argv[c + 1][0] == '}'))
107515b07f80Spwernau goto bail;
10767c478bd9Sstevel@tonic-gate if (parse_psfldid(argv[c++], &fldid) < 0)
10777c478bd9Sstevel@tonic-gate goto bail;
10787c478bd9Sstevel@tonic-gate switch (fldid) {
10797c478bd9Sstevel@tonic-gate case PSFLD_LOCID:
10807c478bd9Sstevel@tonic-gate locid = argv[c++];
10817c478bd9Sstevel@tonic-gate locidlen = strlen(locid) + 1;
10827c478bd9Sstevel@tonic-gate break;
10837c478bd9Sstevel@tonic-gate case PSFLD_LOCIDTYPE:
10847c478bd9Sstevel@tonic-gate if (parse_idtype(argv[c++], &locidtype) < 0)
10857c478bd9Sstevel@tonic-gate goto bail;
10867c478bd9Sstevel@tonic-gate break;
10877c478bd9Sstevel@tonic-gate case PSFLD_REMID:
10887c478bd9Sstevel@tonic-gate remid = argv[c++];
10897c478bd9Sstevel@tonic-gate remidlen = strlen(remid) + 1;
10907c478bd9Sstevel@tonic-gate break;
10917c478bd9Sstevel@tonic-gate case PSFLD_REMIDTYPE:
10927c478bd9Sstevel@tonic-gate if (parse_idtype(argv[c++], &remidtype) < 0)
10937c478bd9Sstevel@tonic-gate goto bail;
10947c478bd9Sstevel@tonic-gate break;
10957c478bd9Sstevel@tonic-gate case PSFLD_MODE:
10967c478bd9Sstevel@tonic-gate if (parse_ikmtype(argv[c++], &mtype) < 0)
10977c478bd9Sstevel@tonic-gate goto bail;
10987c478bd9Sstevel@tonic-gate break;
10997c478bd9Sstevel@tonic-gate case PSFLD_KEY:
11007c478bd9Sstevel@tonic-gate keyp = parse_key(argv[c++], &keylen, &keybits);
11017c478bd9Sstevel@tonic-gate if (keyp == NULL)
11027c478bd9Sstevel@tonic-gate goto bail;
11037c478bd9Sstevel@tonic-gate break;
11047c478bd9Sstevel@tonic-gate }
11057c478bd9Sstevel@tonic-gate }
110615b07f80Spwernau
110715b07f80Spwernau /* Make sure the line was terminated with '}' */
110815b07f80Spwernau if (argv[c] == NULL) {
110915b07f80Spwernau if (!whacked)
111015b07f80Spwernau goto bail;
111115b07f80Spwernau } else if (argv[c][0] != '}') {
111215b07f80Spwernau goto bail;
111315b07f80Spwernau }
111415b07f80Spwernau
11157c478bd9Sstevel@tonic-gate /*
11167c478bd9Sstevel@tonic-gate * make sure we got all the required fields. If no idtype, assume
11177c478bd9Sstevel@tonic-gate * ip addr; if that translation fails, we'll catch the error then.
11187c478bd9Sstevel@tonic-gate */
11197c478bd9Sstevel@tonic-gate if (locid == NULL || remid == NULL || keyp == NULL || mtype == 0)
11207c478bd9Sstevel@tonic-gate goto bail;
11217c478bd9Sstevel@tonic-gate
11227c478bd9Sstevel@tonic-gate /* figure out the size buffer we need */
11237c478bd9Sstevel@tonic-gate *len = sizeof (ike_ps_t);
11247c478bd9Sstevel@tonic-gate if (locidtype != SADB_IDENTTYPE_RESERVED) {
11257c478bd9Sstevel@tonic-gate a_locidtotal = IKEDOORROUNDUP(sizeof (sadb_ident_t) + locidlen);
11267c478bd9Sstevel@tonic-gate *len += a_locidtotal;
11277c478bd9Sstevel@tonic-gate }
11287c478bd9Sstevel@tonic-gate if (remidtype != SADB_IDENTTYPE_RESERVED) {
11297c478bd9Sstevel@tonic-gate a_remidtotal = IKEDOORROUNDUP(sizeof (sadb_ident_t) + remidlen);
11307c478bd9Sstevel@tonic-gate *len += a_remidtotal;
11317c478bd9Sstevel@tonic-gate }
11327c478bd9Sstevel@tonic-gate *len += keylen;
11337c478bd9Sstevel@tonic-gate
11347c478bd9Sstevel@tonic-gate psp = malloc(*len);
11357c478bd9Sstevel@tonic-gate if (psp == NULL)
11367c478bd9Sstevel@tonic-gate goto bail;
11377c478bd9Sstevel@tonic-gate (void) memset(psp, 0, *len);
11387c478bd9Sstevel@tonic-gate
11397c478bd9Sstevel@tonic-gate psp->ps_ike_mode = mtype;
11407c478bd9Sstevel@tonic-gate
11417c478bd9Sstevel@tonic-gate psp->ps_localid_off = sizeof (ike_ps_t);
11427c478bd9Sstevel@tonic-gate if (locidtype == SADB_IDENTTYPE_RESERVED) {
114341c215c2SPaul Wernau locpfx = strchr(locid, '/');
114441c215c2SPaul Wernau if (locpfx != NULL) {
114541c215c2SPaul Wernau *locpfx = '\0';
114641c215c2SPaul Wernau locpfx++;
114741c215c2SPaul Wernau }
114841c215c2SPaul Wernau
11497c478bd9Sstevel@tonic-gate /*
11507c478bd9Sstevel@tonic-gate * this is an ip address, store in the sockaddr field;
11517c478bd9Sstevel@tonic-gate * we won't use an sadb_ident_t.
11527c478bd9Sstevel@tonic-gate */
11537c478bd9Sstevel@tonic-gate psp->ps_localid_len = 0;
11547c478bd9Sstevel@tonic-gate if (parse_addr(1, &locid, &loche) < 0)
11557c478bd9Sstevel@tonic-gate goto bail;
11567c478bd9Sstevel@tonic-gate if (loche->h_addr_list[1] != NULL) {
11577c478bd9Sstevel@tonic-gate message(gettext("preshared key identifier cannot "
11587c478bd9Sstevel@tonic-gate "match multiple IP addresses"));
11597c478bd9Sstevel@tonic-gate goto bail;
11607c478bd9Sstevel@tonic-gate }
11617c478bd9Sstevel@tonic-gate headdr2sa(loche->h_addr_list[0], &psp->ps_ipaddrs.loc_addr,
11627c478bd9Sstevel@tonic-gate loche->h_length);
11637c478bd9Sstevel@tonic-gate FREE_HE(loche);
11647c478bd9Sstevel@tonic-gate } else {
11657c478bd9Sstevel@tonic-gate psp->ps_localid_len = sizeof (sadb_ident_t) + locidlen;
11667c478bd9Sstevel@tonic-gate sidp = (sadb_ident_t *)((int)psp + psp->ps_localid_off);
11677c478bd9Sstevel@tonic-gate sidp->sadb_ident_len = psp->ps_localid_len;
11687c478bd9Sstevel@tonic-gate sidp->sadb_ident_type = locidtype;
1169e3320f40Smarkfen (void) strlcpy((char *)(sidp + 1), locid, a_locidtotal);
11707c478bd9Sstevel@tonic-gate }
11717c478bd9Sstevel@tonic-gate
11727c478bd9Sstevel@tonic-gate psp->ps_remoteid_off = psp->ps_localid_off + a_locidtotal;
11737c478bd9Sstevel@tonic-gate if (remidtype == SADB_IDENTTYPE_RESERVED) {
117441c215c2SPaul Wernau rempfx = strchr(remid, '/');
117541c215c2SPaul Wernau if (rempfx != NULL) {
117641c215c2SPaul Wernau *rempfx = '\0';
117741c215c2SPaul Wernau rempfx++;
117841c215c2SPaul Wernau }
117941c215c2SPaul Wernau
11807c478bd9Sstevel@tonic-gate /*
11817c478bd9Sstevel@tonic-gate * this is an ip address, store in the sockaddr field;
11827c478bd9Sstevel@tonic-gate * we won't use an sadb_ident_t.
11837c478bd9Sstevel@tonic-gate */
11847c478bd9Sstevel@tonic-gate psp->ps_remoteid_len = 0;
11857c478bd9Sstevel@tonic-gate if (parse_addr(1, &remid, &remhe) < 0)
11867c478bd9Sstevel@tonic-gate goto bail;
11877c478bd9Sstevel@tonic-gate if (remhe->h_addr_list[1] != NULL) {
11887c478bd9Sstevel@tonic-gate message(gettext("preshared key identifier cannot "
11897c478bd9Sstevel@tonic-gate "match multiple IP addresses"));
11907c478bd9Sstevel@tonic-gate goto bail;
11917c478bd9Sstevel@tonic-gate }
11927c478bd9Sstevel@tonic-gate headdr2sa(remhe->h_addr_list[0], &psp->ps_ipaddrs.rem_addr,
11937c478bd9Sstevel@tonic-gate remhe->h_length);
11947c478bd9Sstevel@tonic-gate FREE_HE(remhe);
11957c478bd9Sstevel@tonic-gate } else {
11967c478bd9Sstevel@tonic-gate /* make sure we have at least 16-bit alignment */
11977c478bd9Sstevel@tonic-gate if (remidlen & 0x1)
11987c478bd9Sstevel@tonic-gate remidlen++;
11997c478bd9Sstevel@tonic-gate psp->ps_remoteid_len = sizeof (sadb_ident_t) + remidlen;
12007c478bd9Sstevel@tonic-gate sidp = (sadb_ident_t *)((int)psp + psp->ps_remoteid_off);
12017c478bd9Sstevel@tonic-gate sidp->sadb_ident_len = psp->ps_remoteid_len;
12027c478bd9Sstevel@tonic-gate sidp->sadb_ident_type = remidtype;
1203e3320f40Smarkfen (void) strlcpy((char *)(sidp + 1), remid, a_remidtotal);
12047c478bd9Sstevel@tonic-gate }
12057c478bd9Sstevel@tonic-gate
12067c478bd9Sstevel@tonic-gate psp->ps_key_off = psp->ps_remoteid_off + a_remidtotal;
12077c478bd9Sstevel@tonic-gate psp->ps_key_len = keylen;
12087c478bd9Sstevel@tonic-gate psp->ps_key_bits = keybits;
12097c478bd9Sstevel@tonic-gate (void) memcpy((uint8_t *)((int)psp + psp->ps_key_off), keyp, keylen);
121041c215c2SPaul Wernau if (locpfx != NULL && ((pfxlen = atoi(locpfx)) > 0))
121141c215c2SPaul Wernau psp->ps_localid_plen = pfxlen;
121241c215c2SPaul Wernau if (rempfx != NULL && ((pfxlen = atoi(rempfx)) > 0))
121341c215c2SPaul Wernau psp->ps_remoteid_plen = pfxlen;
12147c478bd9Sstevel@tonic-gate
12157c478bd9Sstevel@tonic-gate *presharedpp = psp;
12167c478bd9Sstevel@tonic-gate
12177c478bd9Sstevel@tonic-gate return (c);
12187c478bd9Sstevel@tonic-gate
12197c478bd9Sstevel@tonic-gate bail:
12207c478bd9Sstevel@tonic-gate if (loche != NULL)
12217c478bd9Sstevel@tonic-gate FREE_HE(loche);
12227c478bd9Sstevel@tonic-gate if (remhe != NULL)
12237c478bd9Sstevel@tonic-gate FREE_HE(remhe);
12247c478bd9Sstevel@tonic-gate if (keyp != NULL)
12257c478bd9Sstevel@tonic-gate free(keyp);
12267c478bd9Sstevel@tonic-gate if (psp != NULL)
12277c478bd9Sstevel@tonic-gate free(psp);
12287c478bd9Sstevel@tonic-gate
12297c478bd9Sstevel@tonic-gate *presharedpp = NULL;
12307c478bd9Sstevel@tonic-gate
12317c478bd9Sstevel@tonic-gate return (-1);
12327c478bd9Sstevel@tonic-gate }
12337c478bd9Sstevel@tonic-gate
12347c478bd9Sstevel@tonic-gate /*
12357c478bd9Sstevel@tonic-gate * Printing functions
12367c478bd9Sstevel@tonic-gate *
12377c478bd9Sstevel@tonic-gate * A potential point of confusion here is that the ikeadm-specific string-
12387c478bd9Sstevel@tonic-gate * producing functions do not match the ipsec_util.c versions in style: the
12397c478bd9Sstevel@tonic-gate * ikeadm-specific functions return a string (and are named foostr), while
12407c478bd9Sstevel@tonic-gate * the ipsec_util.c functions actually print the string to the file named
12417c478bd9Sstevel@tonic-gate * in the second arg to the function (and are named dump_foo).
12427c478bd9Sstevel@tonic-gate *
12434b56a003SDaniel Anderson * Localization for ikeadm seems more straightforward when complete
12444b56a003SDaniel Anderson * phrases are translated rather than: a part of a phrase, a call to
12454b56a003SDaniel Anderson * dump_foo(), and more of the phrase. It could also accommodate
12464b56a003SDaniel Anderson * non-English grammar more easily.
12477c478bd9Sstevel@tonic-gate */
12487c478bd9Sstevel@tonic-gate
12497c478bd9Sstevel@tonic-gate static char *
errstr(int err)12507c478bd9Sstevel@tonic-gate errstr(int err)
12517c478bd9Sstevel@tonic-gate {
12527c478bd9Sstevel@tonic-gate static char rtn[MAXLINESIZE];
12537c478bd9Sstevel@tonic-gate
12547c478bd9Sstevel@tonic-gate switch (err) {
12557c478bd9Sstevel@tonic-gate case IKE_ERR_NO_OBJ:
12567c478bd9Sstevel@tonic-gate return (gettext("No data returned"));
12577c478bd9Sstevel@tonic-gate case IKE_ERR_NO_DESC:
12587c478bd9Sstevel@tonic-gate return (gettext("No destination provided"));
12597c478bd9Sstevel@tonic-gate case IKE_ERR_ID_INVALID:
12607c478bd9Sstevel@tonic-gate return (gettext("Id info invalid"));
12617c478bd9Sstevel@tonic-gate case IKE_ERR_LOC_INVALID:
12627c478bd9Sstevel@tonic-gate return (gettext("Destination invalid"));
12637c478bd9Sstevel@tonic-gate case IKE_ERR_CMD_INVALID:
12647c478bd9Sstevel@tonic-gate return (gettext("Command invalid"));
12657c478bd9Sstevel@tonic-gate case IKE_ERR_DATA_INVALID:
12667c478bd9Sstevel@tonic-gate return (gettext("Supplied data invalid"));
12677c478bd9Sstevel@tonic-gate case IKE_ERR_CMD_NOTSUP:
12687c478bd9Sstevel@tonic-gate return (gettext("Unknown command"));
12697c478bd9Sstevel@tonic-gate case IKE_ERR_REQ_INVALID:
12707c478bd9Sstevel@tonic-gate return (gettext("Request invalid"));
12717c478bd9Sstevel@tonic-gate case IKE_ERR_NO_PRIV:
12727c478bd9Sstevel@tonic-gate return (gettext("Not allowed at current privilege level"));
1273c7777ac8SPaul Wernau case IKE_ERR_NO_AUTH:
1274c7777ac8SPaul Wernau return (gettext("User not authorized"));
12757c478bd9Sstevel@tonic-gate case IKE_ERR_SYS_ERR:
12767c478bd9Sstevel@tonic-gate return (gettext("System error"));
127715b07f80Spwernau case IKE_ERR_DUP_IGNORED:
127815b07f80Spwernau return (gettext("One or more duplicate entries ignored"));
1279c7777ac8SPaul Wernau case IKE_ERR_NO_TOKEN:
1280c7777ac8SPaul Wernau return (gettext(
1281c7777ac8SPaul Wernau "token login failed or no objects on device"));
1282c7777ac8SPaul Wernau case IKE_ERR_IN_PROGRESS:
1283c7777ac8SPaul Wernau return (gettext(
1284c7777ac8SPaul Wernau "Duplicate operation already in progress"));
1285c7777ac8SPaul Wernau case IKE_ERR_NO_MEM:
1286c7777ac8SPaul Wernau return (gettext(
1287c7777ac8SPaul Wernau "Insufficient memory"));
12887c478bd9Sstevel@tonic-gate default:
12897c478bd9Sstevel@tonic-gate (void) snprintf(rtn, MAXLINESIZE,
12907c478bd9Sstevel@tonic-gate gettext("<unknown error %d>"), err);
12917c478bd9Sstevel@tonic-gate return (rtn);
12927c478bd9Sstevel@tonic-gate }
12937c478bd9Sstevel@tonic-gate }
12947c478bd9Sstevel@tonic-gate
12957c478bd9Sstevel@tonic-gate static char *
dbgstr(int bit)12967c478bd9Sstevel@tonic-gate dbgstr(int bit)
12977c478bd9Sstevel@tonic-gate {
12987c478bd9Sstevel@tonic-gate static char rtn[MAXLINESIZE];
12997c478bd9Sstevel@tonic-gate
13007c478bd9Sstevel@tonic-gate switch (bit) {
13017c478bd9Sstevel@tonic-gate case D_CERT:
13027c478bd9Sstevel@tonic-gate return (gettext("Certificate management"));
13037c478bd9Sstevel@tonic-gate case D_KEY:
13047c478bd9Sstevel@tonic-gate return (gettext("Key management"));
13057c478bd9Sstevel@tonic-gate case D_OP:
13067c478bd9Sstevel@tonic-gate return (gettext("Operational"));
13077c478bd9Sstevel@tonic-gate case D_P1:
13087c478bd9Sstevel@tonic-gate return (gettext("Phase 1 SA creation"));
13097c478bd9Sstevel@tonic-gate case D_P2:
13107c478bd9Sstevel@tonic-gate return (gettext("Phase 2 SA creation"));
13117c478bd9Sstevel@tonic-gate case D_PFKEY:
13127c478bd9Sstevel@tonic-gate return (gettext("PF_KEY interface"));
13137c478bd9Sstevel@tonic-gate case D_POL:
13147c478bd9Sstevel@tonic-gate return (gettext("Policy management"));
13157c478bd9Sstevel@tonic-gate case D_PROP:
13167c478bd9Sstevel@tonic-gate return (gettext("Proposal construction"));
13177c478bd9Sstevel@tonic-gate case D_DOOR:
13187c478bd9Sstevel@tonic-gate return (gettext("Door interface"));
13197c478bd9Sstevel@tonic-gate case D_CONFIG:
13207c478bd9Sstevel@tonic-gate return (gettext("Config file processing"));
13215d3b8cb7SBill Sommerfeld case D_LABEL:
13225d3b8cb7SBill Sommerfeld return (gettext("MAC label processing"));
13237c478bd9Sstevel@tonic-gate default:
13247c478bd9Sstevel@tonic-gate (void) snprintf(rtn, MAXLINESIZE,
13257c478bd9Sstevel@tonic-gate gettext("<unknown flag 0x%x>"), bit);
13267c478bd9Sstevel@tonic-gate return (rtn);
13277c478bd9Sstevel@tonic-gate }
13287c478bd9Sstevel@tonic-gate }
13297c478bd9Sstevel@tonic-gate
13307c478bd9Sstevel@tonic-gate static char *
privstr(int priv)13317c478bd9Sstevel@tonic-gate privstr(int priv)
13327c478bd9Sstevel@tonic-gate {
13337c478bd9Sstevel@tonic-gate static char rtn[MAXLINESIZE];
13347c478bd9Sstevel@tonic-gate
13357c478bd9Sstevel@tonic-gate switch (priv) {
13367c478bd9Sstevel@tonic-gate case IKE_PRIV_MINIMUM:
13377c478bd9Sstevel@tonic-gate return (gettext("base privileges"));
13387c478bd9Sstevel@tonic-gate case IKE_PRIV_MODKEYS:
13397c478bd9Sstevel@tonic-gate return (gettext("access to preshared key information"));
13407c478bd9Sstevel@tonic-gate case IKE_PRIV_KEYMAT:
13417c478bd9Sstevel@tonic-gate return (gettext("access to keying material"));
13427c478bd9Sstevel@tonic-gate default:
13437c478bd9Sstevel@tonic-gate (void) snprintf(rtn, MAXLINESIZE,
13447c478bd9Sstevel@tonic-gate gettext("<unknown level %d>"), priv);
13457c478bd9Sstevel@tonic-gate return (rtn);
13467c478bd9Sstevel@tonic-gate }
13477c478bd9Sstevel@tonic-gate }
13487c478bd9Sstevel@tonic-gate
13497c478bd9Sstevel@tonic-gate static char *
xchgstr(int xchg)13507c478bd9Sstevel@tonic-gate xchgstr(int xchg)
13517c478bd9Sstevel@tonic-gate {
13527c478bd9Sstevel@tonic-gate static char rtn[MAXLINESIZE];
13537c478bd9Sstevel@tonic-gate
13547c478bd9Sstevel@tonic-gate switch (xchg) {
13557c478bd9Sstevel@tonic-gate case IKE_XCHG_NONE:
13567c478bd9Sstevel@tonic-gate return (gettext("<unspecified>"));
13577c478bd9Sstevel@tonic-gate case IKE_XCHG_BASE:
13587c478bd9Sstevel@tonic-gate return (gettext("base"));
13597c478bd9Sstevel@tonic-gate case IKE_XCHG_IDENTITY_PROTECT:
13607c478bd9Sstevel@tonic-gate return (gettext("main mode (identity protect)"));
13617c478bd9Sstevel@tonic-gate case IKE_XCHG_AUTH_ONLY:
13627c478bd9Sstevel@tonic-gate return (gettext("authentication only"));
13637c478bd9Sstevel@tonic-gate case IKE_XCHG_AGGRESSIVE:
13647c478bd9Sstevel@tonic-gate return (gettext("aggressive mode"));
13657c478bd9Sstevel@tonic-gate case IKE_XCHG_IP_AND_AGGR:
13667c478bd9Sstevel@tonic-gate return (gettext("main and aggressive mode"));
13677c478bd9Sstevel@tonic-gate case IKE_XCHG_ANY:
13687c478bd9Sstevel@tonic-gate return (gettext("any mode"));
13697c478bd9Sstevel@tonic-gate default:
13707c478bd9Sstevel@tonic-gate (void) snprintf(rtn, MAXLINESIZE,
13717c478bd9Sstevel@tonic-gate gettext("<unknown %d>"), xchg);
13727c478bd9Sstevel@tonic-gate return (rtn);
13737c478bd9Sstevel@tonic-gate }
13747c478bd9Sstevel@tonic-gate }
13757c478bd9Sstevel@tonic-gate
13767c478bd9Sstevel@tonic-gate static char *
statestr(int state)13777c478bd9Sstevel@tonic-gate statestr(int state)
13787c478bd9Sstevel@tonic-gate {
13797c478bd9Sstevel@tonic-gate static char rtn[MAXLINESIZE];
13807c478bd9Sstevel@tonic-gate
13817c478bd9Sstevel@tonic-gate switch (state) {
13827c478bd9Sstevel@tonic-gate case IKE_SA_STATE_INIT:
13837c478bd9Sstevel@tonic-gate return (gettext("INITIALIZING"));
13847c478bd9Sstevel@tonic-gate case IKE_SA_STATE_SENT_SA:
13857c478bd9Sstevel@tonic-gate return (gettext("SENT FIRST MSG (SA)"));
13867c478bd9Sstevel@tonic-gate case IKE_SA_STATE_SENT_KE:
13877c478bd9Sstevel@tonic-gate return (gettext("SENT SECOND MSG (KE)"));
13887c478bd9Sstevel@tonic-gate case IKE_SA_STATE_SENT_LAST:
13897c478bd9Sstevel@tonic-gate return (gettext("SENT FINAL MSG"));
13907c478bd9Sstevel@tonic-gate case IKE_SA_STATE_DONE:
13917c478bd9Sstevel@tonic-gate return (gettext("ACTIVE"));
13927c478bd9Sstevel@tonic-gate case IKE_SA_STATE_DELETED:
13937c478bd9Sstevel@tonic-gate return (gettext("DELETED"));
13947c478bd9Sstevel@tonic-gate case IKE_SA_STATE_INVALID:
13957c478bd9Sstevel@tonic-gate return (gettext("<invalid>"));
13967c478bd9Sstevel@tonic-gate default:
13977c478bd9Sstevel@tonic-gate (void) snprintf(rtn, MAXLINESIZE,
13987c478bd9Sstevel@tonic-gate gettext("<unknown %d>"), state);
13997c478bd9Sstevel@tonic-gate return (rtn);
14007c478bd9Sstevel@tonic-gate }
14017c478bd9Sstevel@tonic-gate }
14027c478bd9Sstevel@tonic-gate
14037c478bd9Sstevel@tonic-gate static char *
authmethstr(int meth)14047c478bd9Sstevel@tonic-gate authmethstr(int meth)
14057c478bd9Sstevel@tonic-gate {
14067c478bd9Sstevel@tonic-gate static char rtn[MAXLINESIZE];
14077c478bd9Sstevel@tonic-gate
14087c478bd9Sstevel@tonic-gate switch (meth) {
14097c478bd9Sstevel@tonic-gate case IKE_AUTH_METH_PRE_SHARED_KEY:
14107c478bd9Sstevel@tonic-gate return (gettext("pre-shared key"));
14117c478bd9Sstevel@tonic-gate case IKE_AUTH_METH_DSS_SIG:
14127c478bd9Sstevel@tonic-gate return (gettext("DSS signatures"));
14137c478bd9Sstevel@tonic-gate case IKE_AUTH_METH_RSA_SIG:
14147c478bd9Sstevel@tonic-gate return (gettext("RSA signatures"));
14157c478bd9Sstevel@tonic-gate case IKE_AUTH_METH_RSA_ENCR:
14167c478bd9Sstevel@tonic-gate return (gettext("RSA Encryption"));
14177c478bd9Sstevel@tonic-gate case IKE_AUTH_METH_RSA_ENCR_REVISED:
14187c478bd9Sstevel@tonic-gate return (gettext("Revised RSA Encryption"));
14197c478bd9Sstevel@tonic-gate default:
14207c478bd9Sstevel@tonic-gate (void) snprintf(rtn, MAXLINESIZE,
14217c478bd9Sstevel@tonic-gate gettext("<unknown %d>"), meth);
14227c478bd9Sstevel@tonic-gate return (rtn);
14237c478bd9Sstevel@tonic-gate }
14247c478bd9Sstevel@tonic-gate }
14257c478bd9Sstevel@tonic-gate
14267c478bd9Sstevel@tonic-gate static char *
prfstr(int prf)14277c478bd9Sstevel@tonic-gate prfstr(int prf)
14287c478bd9Sstevel@tonic-gate {
14297c478bd9Sstevel@tonic-gate static char rtn[MAXLINESIZE];
14307c478bd9Sstevel@tonic-gate
14317c478bd9Sstevel@tonic-gate switch (prf) {
14327c478bd9Sstevel@tonic-gate case IKE_PRF_NONE:
1433349233acSpwernau return (gettext("<none/unavailable>"));
14347c478bd9Sstevel@tonic-gate case IKE_PRF_HMAC_MD5:
14357c478bd9Sstevel@tonic-gate return ("HMAC MD5");
14367c478bd9Sstevel@tonic-gate case IKE_PRF_HMAC_SHA1:
14377c478bd9Sstevel@tonic-gate return ("HMAC SHA1");
14380358d3a6Sdanmcd case IKE_PRF_HMAC_SHA256:
14390358d3a6Sdanmcd return ("HMAC SHA256");
14400358d3a6Sdanmcd case IKE_PRF_HMAC_SHA384:
14410358d3a6Sdanmcd return ("HMAC SHA384");
14420358d3a6Sdanmcd case IKE_PRF_HMAC_SHA512:
14430358d3a6Sdanmcd return ("HMAC SHA512");
14447c478bd9Sstevel@tonic-gate default:
14457c478bd9Sstevel@tonic-gate (void) snprintf(rtn, MAXLINESIZE,
14467c478bd9Sstevel@tonic-gate gettext("<unknown %d>"), prf);
14477c478bd9Sstevel@tonic-gate return (rtn);
14487c478bd9Sstevel@tonic-gate }
14497c478bd9Sstevel@tonic-gate }
14507c478bd9Sstevel@tonic-gate
14517c478bd9Sstevel@tonic-gate static char *
dhstr(int grp)14527c478bd9Sstevel@tonic-gate dhstr(int grp)
14537c478bd9Sstevel@tonic-gate {
14547c478bd9Sstevel@tonic-gate static char rtn[MAXLINESIZE];
14557c478bd9Sstevel@tonic-gate
14567c478bd9Sstevel@tonic-gate switch (grp) {
14577c478bd9Sstevel@tonic-gate case 0:
1458020bf065Smarkfen return (gettext("<unavailable>"));
14597c478bd9Sstevel@tonic-gate case IKE_GRP_DESC_MODP_768:
1460020bf065Smarkfen return (gettext("768-bit MODP (group 1)"));
14617c478bd9Sstevel@tonic-gate case IKE_GRP_DESC_MODP_1024:
1462020bf065Smarkfen return (gettext("1024-bit MODP (group 2)"));
14637c478bd9Sstevel@tonic-gate case IKE_GRP_DESC_EC2N_155:
14647c478bd9Sstevel@tonic-gate return (gettext("EC2N group on GP[2^155]"));
14657c478bd9Sstevel@tonic-gate case IKE_GRP_DESC_EC2N_185:
14667c478bd9Sstevel@tonic-gate return (gettext("EC2N group on GP[2^185]"));
14677c478bd9Sstevel@tonic-gate case IKE_GRP_DESC_MODP_1536:
1468020bf065Smarkfen return (gettext("1536-bit MODP (group 5)"));
1469020bf065Smarkfen case IKE_GRP_DESC_MODP_2048:
1470020bf065Smarkfen return (gettext("2048-bit MODP (group 14)"));
1471020bf065Smarkfen case IKE_GRP_DESC_MODP_3072:
1472020bf065Smarkfen return (gettext("3072-bit MODP (group 15)"));
1473020bf065Smarkfen case IKE_GRP_DESC_MODP_4096:
1474020bf065Smarkfen return (gettext("4096-bit MODP (group 16)"));
1475020bf065Smarkfen case IKE_GRP_DESC_MODP_6144:
1476020bf065Smarkfen return (gettext("6144-bit MODP (group 17)"));
1477020bf065Smarkfen case IKE_GRP_DESC_MODP_8192:
1478020bf065Smarkfen return (gettext("8192-bit MODP (group 18)"));
147946c08a97SBill Sommerfeld case IKE_GRP_DESC_ECP_256:
148046c08a97SBill Sommerfeld return (gettext("256-bit ECP (group 19)"));
148146c08a97SBill Sommerfeld case IKE_GRP_DESC_ECP_384:
148246c08a97SBill Sommerfeld return (gettext("384-bit ECP (group 20)"));
148346c08a97SBill Sommerfeld case IKE_GRP_DESC_ECP_521:
148446c08a97SBill Sommerfeld return (gettext("521-bit ECP (group 21)"));
148546c08a97SBill Sommerfeld case IKE_GRP_DESC_MODP_1024_160:
148646c08a97SBill Sommerfeld return (
148746c08a97SBill Sommerfeld gettext("1024-bit MODP with 160-bit subprime (group 22)"));
148846c08a97SBill Sommerfeld case IKE_GRP_DESC_MODP_2048_224:
148946c08a97SBill Sommerfeld return (
149046c08a97SBill Sommerfeld gettext("2048-bit MODP with 224-bit subprime (group 23)"));
149146c08a97SBill Sommerfeld case IKE_GRP_DESC_MODP_2048_256:
149246c08a97SBill Sommerfeld return (
149346c08a97SBill Sommerfeld gettext("2048-bit MODP with 256-bit subprime (group 24)"));
149446c08a97SBill Sommerfeld case IKE_GRP_DESC_ECP_192:
149546c08a97SBill Sommerfeld return (gettext("192-bit ECP (group 25)"));
149646c08a97SBill Sommerfeld case IKE_GRP_DESC_ECP_224:
149746c08a97SBill Sommerfeld return (gettext("224-bit ECP (group 26)"));
14987c478bd9Sstevel@tonic-gate default:
14997c478bd9Sstevel@tonic-gate (void) snprintf(rtn, MAXLINESIZE, gettext("<unknown %d>"), grp);
15007c478bd9Sstevel@tonic-gate return (rtn);
15017c478bd9Sstevel@tonic-gate }
15027c478bd9Sstevel@tonic-gate }
15037c478bd9Sstevel@tonic-gate
15047c478bd9Sstevel@tonic-gate static void
print_hdr(char * prefix,ike_p1_hdr_t * hdrp)15057c478bd9Sstevel@tonic-gate print_hdr(char *prefix, ike_p1_hdr_t *hdrp)
15067c478bd9Sstevel@tonic-gate {
15079c2c14abSThejaswini Singarajipura char sbuf[TBUF_SIZE];
15089c2c14abSThejaswini Singarajipura char tbuf[TBUF_SIZE];
1509dc739cedSDan McDonald time_t ltime = (time_t)hdrp->p1hdr_dpd_time;
15109c2c14abSThejaswini Singarajipura
15117c478bd9Sstevel@tonic-gate (void) printf(
15127c478bd9Sstevel@tonic-gate gettext("%s Cookies: Initiator 0x%llx Responder 0x%llx\n"),
15134b56a003SDaniel Anderson prefix, ntohll(hdrp->p1hdr_cookies.cky_i),
15144b56a003SDaniel Anderson ntohll(hdrp->p1hdr_cookies.cky_r));
15157c478bd9Sstevel@tonic-gate (void) printf(gettext("%s The local host is the %s.\n"), prefix,
15167c478bd9Sstevel@tonic-gate hdrp->p1hdr_isinit ? gettext("initiator") : gettext("responder"));
15177c478bd9Sstevel@tonic-gate (void) printf(gettext("%s ISAKMP version %d.%d; %s exchange\n"), prefix,
15187c478bd9Sstevel@tonic-gate hdrp->p1hdr_major, hdrp->p1hdr_minor, xchgstr(hdrp->p1hdr_xchg));
15199c2c14abSThejaswini Singarajipura (void) printf(gettext("%s Current state is %s\n"), prefix,
15207c478bd9Sstevel@tonic-gate statestr(hdrp->p1hdr_state));
15219c2c14abSThejaswini Singarajipura if (hdrp->p1hdr_support_dpd == B_FALSE) {
15229c2c14abSThejaswini Singarajipura return;
15239c2c14abSThejaswini Singarajipura }
15249c2c14abSThejaswini Singarajipura (void) printf(gettext("%s Dead Peer Detection (RFC 3706)"
15259c2c14abSThejaswini Singarajipura " enabled"), prefix);
15269c2c14abSThejaswini Singarajipura if (hdrp->p1hdr_dpd_state < DPD_IN_PROGRESS) {
15279c2c14abSThejaswini Singarajipura (void) printf("\n");
15289c2c14abSThejaswini Singarajipura return;
15299c2c14abSThejaswini Singarajipura }
15309c2c14abSThejaswini Singarajipura if (strftime(tbuf, TBUF_SIZE, NULL,
1531dc739cedSDan McDonald localtime(<ime)) == 0) {
15329c2c14abSThejaswini Singarajipura (void) strlcpy(tbuf, gettext("<time conversion failed>"),
15339c2c14abSThejaswini Singarajipura TBUF_SIZE);
15349c2c14abSThejaswini Singarajipura }
15359c2c14abSThejaswini Singarajipura (void) printf(gettext("\n%s Dead Peer Detection handshake "), prefix);
15369c2c14abSThejaswini Singarajipura switch (hdrp->p1hdr_dpd_state) {
15379c2c14abSThejaswini Singarajipura case DPD_SUCCESSFUL:
15389c2c14abSThejaswini Singarajipura (void) strlcpy(sbuf, gettext("was successful at "), TBUF_SIZE);
15399c2c14abSThejaswini Singarajipura break;
15409c2c14abSThejaswini Singarajipura case DPD_FAILURE:
15419c2c14abSThejaswini Singarajipura (void) strlcpy(sbuf, gettext("failed at "), TBUF_SIZE);
15429c2c14abSThejaswini Singarajipura break;
15439c2c14abSThejaswini Singarajipura case DPD_IN_PROGRESS:
15449c2c14abSThejaswini Singarajipura (void) strlcpy(sbuf, gettext("is in progress."), TBUF_SIZE);
15459c2c14abSThejaswini Singarajipura break;
15469c2c14abSThejaswini Singarajipura }
1547a14de6c8SDan McDonald (void) printf("%s %s", sbuf,
1548a14de6c8SDan McDonald (hdrp->p1hdr_dpd_state == DPD_IN_PROGRESS) ? "" : tbuf);
15497c478bd9Sstevel@tonic-gate (void) printf("\n");
15507c478bd9Sstevel@tonic-gate }
15517c478bd9Sstevel@tonic-gate
15527c478bd9Sstevel@tonic-gate static void
print_lt_limits(char * prefix,ike_p1_xform_t * xfp)15537c478bd9Sstevel@tonic-gate print_lt_limits(char *prefix, ike_p1_xform_t *xfp)
15547c478bd9Sstevel@tonic-gate {
1555510c3f91SVladimir Kotal char byte_str[BYTE_STR_SIZE]; /* byte lifetime string representation */
1556510c3f91SVladimir Kotal char secs_str[SECS_STR_SIZE]; /* lifetime string representation */
1557510c3f91SVladimir Kotal
15587c478bd9Sstevel@tonic-gate (void) printf(gettext("%s Lifetime limits:\n"), prefix);
1559510c3f91SVladimir Kotal (void) printf(gettext("%s %u seconds%s; %u kbytes %sprotected\n"),
1560510c3f91SVladimir Kotal prefix, xfp->p1xf_max_secs, secs2out(xfp->p1xf_max_secs,
1561510c3f91SVladimir Kotal secs_str, sizeof (secs_str), SPC_BEGIN), xfp->p1xf_max_kbytes,
1562510c3f91SVladimir Kotal bytecnt2out((uint64_t)xfp->p1xf_max_kbytes << 10, byte_str,
1563510c3f91SVladimir Kotal sizeof (byte_str), SPC_END));
1564510c3f91SVladimir Kotal (void) printf(gettext("%s keying material for IPsec SAs can be "
1565510c3f91SVladimir Kotal "provided %u times%s\n"), prefix, xfp->p1xf_max_keyuses,
1566510c3f91SVladimir Kotal xfp->p1xf_max_keyuses == 0 ? " (no limit)" : "");
15677c478bd9Sstevel@tonic-gate }
15687c478bd9Sstevel@tonic-gate
15697c478bd9Sstevel@tonic-gate #define LT_USAGE_LEN 16 /* 1 uint64 + 2 uint32s */
15707c478bd9Sstevel@tonic-gate static void
print_lt_usage(char * prefix,ike_p1_stats_t * sp)15717c478bd9Sstevel@tonic-gate print_lt_usage(char *prefix, ike_p1_stats_t *sp)
15727c478bd9Sstevel@tonic-gate {
15737c478bd9Sstevel@tonic-gate time_t scratch;
15747c478bd9Sstevel@tonic-gate char tbuf[TBUF_SIZE];
1575510c3f91SVladimir Kotal char bytestr[BYTE_STR_SIZE]; /* byte lifetime representation */
15767c478bd9Sstevel@tonic-gate
15777c478bd9Sstevel@tonic-gate (void) printf(gettext("%s Current usage:\n"), prefix);
15787c478bd9Sstevel@tonic-gate scratch = (time_t)sp->p1stat_start;
15797c478bd9Sstevel@tonic-gate if (strftime(tbuf, TBUF_SIZE, NULL, localtime(&scratch)) == 0)
15807c478bd9Sstevel@tonic-gate (void) strlcpy(tbuf, gettext("<time conversion failed>"),
15817c478bd9Sstevel@tonic-gate TBUF_SIZE);
15827c478bd9Sstevel@tonic-gate (void) printf(gettext("%s SA was created at %s\n"), prefix, tbuf);
1583510c3f91SVladimir Kotal (void) printf(gettext("%s %u kbytes %sprotected\n"),
1584510c3f91SVladimir Kotal prefix, sp->p1stat_kbytes,
1585510c3f91SVladimir Kotal bytecnt2out((uint64_t)sp->p1stat_kbytes << 10, bytestr,
1586510c3f91SVladimir Kotal sizeof (bytestr), SPC_END));
1587510c3f91SVladimir Kotal (void) printf(gettext("%s keying material for IPsec SAs provided "
1588510c3f91SVladimir Kotal "%u times\n"), prefix, sp->p1stat_keyuses);
15897c478bd9Sstevel@tonic-gate }
15907c478bd9Sstevel@tonic-gate
15917c478bd9Sstevel@tonic-gate static void
print_xform(char * prefix,ike_p1_xform_t * xfp,boolean_t print_lifetimes)15927c478bd9Sstevel@tonic-gate print_xform(char *prefix, ike_p1_xform_t *xfp, boolean_t print_lifetimes)
15937c478bd9Sstevel@tonic-gate {
15947c478bd9Sstevel@tonic-gate (void) printf(gettext("%s Authentication method: %s"), prefix,
15957c478bd9Sstevel@tonic-gate authmethstr(xfp->p1xf_auth_meth));
15967c478bd9Sstevel@tonic-gate (void) printf(gettext("\n%s Encryption alg: "), prefix);
15977c478bd9Sstevel@tonic-gate (void) dump_ealg(xfp->p1xf_encr_alg, stdout);
159820dc9b2eSvk if (xfp->p1xf_encr_low_bits != 0) {
159920dc9b2eSvk (void) printf(gettext("(%d..%d)"), xfp->p1xf_encr_low_bits,
160020dc9b2eSvk xfp->p1xf_encr_high_bits);
1601349233acSpwernau } else if ((xfp->p1xf_encr_low_bits == 0) &&
1602349233acSpwernau (xfp->p1xf_encr_high_bits != 0)) {
1603349233acSpwernau /*
1604349233acSpwernau * High bits is a placeholder for
1605349233acSpwernau * negotiated algorithm strength
1606349233acSpwernau */
1607349233acSpwernau (void) printf(gettext("(%d)"), xfp->p1xf_encr_high_bits);
160820dc9b2eSvk }
16097c478bd9Sstevel@tonic-gate (void) printf(gettext("; Authentication alg: "));
16107c478bd9Sstevel@tonic-gate (void) dump_aalg(xfp->p1xf_auth_alg, stdout);
1611349233acSpwernau (void) printf("\n%s ", prefix);
1612349233acSpwernau if (xfp->p1xf_prf != 0)
1613349233acSpwernau (void) printf(gettext("PRF: %s ; "), prfstr(xfp->p1xf_prf));
1614349233acSpwernau (void) printf(gettext("Oakley Group: %s\n"),
16157c478bd9Sstevel@tonic-gate dhstr(xfp->p1xf_dh_group));
16167c478bd9Sstevel@tonic-gate if (xfp->p1xf_pfs == 0) {
16177c478bd9Sstevel@tonic-gate (void) printf(gettext("%s Phase 2 PFS is not used\n"), prefix);
16187c478bd9Sstevel@tonic-gate } else {
16197c478bd9Sstevel@tonic-gate (void) printf(gettext(
16207c478bd9Sstevel@tonic-gate "%s Phase 2 PFS is required (Oakley Group: %s)\n"),
16217c478bd9Sstevel@tonic-gate prefix, dhstr(xfp->p1xf_pfs));
16227c478bd9Sstevel@tonic-gate }
16237c478bd9Sstevel@tonic-gate
16247c478bd9Sstevel@tonic-gate if (print_lifetimes)
16257c478bd9Sstevel@tonic-gate print_lt_limits(prefix, xfp);
16267c478bd9Sstevel@tonic-gate }
16277c478bd9Sstevel@tonic-gate
16287c478bd9Sstevel@tonic-gate static void
print_lifetime(char * prefix,ike_p1_xform_t * xfp,ike_p1_stats_t * sp,int statlen)16297c478bd9Sstevel@tonic-gate print_lifetime(char *prefix, ike_p1_xform_t *xfp, ike_p1_stats_t *sp,
16307c478bd9Sstevel@tonic-gate int statlen)
16317c478bd9Sstevel@tonic-gate {
16327c478bd9Sstevel@tonic-gate time_t current, remain, exp;
16337c478bd9Sstevel@tonic-gate char tbuf[TBUF_SIZE];
1634510c3f91SVladimir Kotal char byte_str[BYTE_STR_SIZE]; /* byte lifetime representation */
1635510c3f91SVladimir Kotal char secs_str[SECS_STR_SIZE]; /* seconds lifetime representation */
16367c478bd9Sstevel@tonic-gate
16377c478bd9Sstevel@tonic-gate current = time(NULL);
16387c478bd9Sstevel@tonic-gate
16397c478bd9Sstevel@tonic-gate print_lt_limits(prefix, xfp);
16407c478bd9Sstevel@tonic-gate
16417c478bd9Sstevel@tonic-gate /*
16427c478bd9Sstevel@tonic-gate * make sure the stats struct we've been passed is as big
16437c478bd9Sstevel@tonic-gate * as we expect it to be. The usage stats are at the end,
16447c478bd9Sstevel@tonic-gate * so anything less than the size we expect won't work.
16457c478bd9Sstevel@tonic-gate */
16467c478bd9Sstevel@tonic-gate if (statlen >= sizeof (ike_p1_stats_t)) {
16477c478bd9Sstevel@tonic-gate print_lt_usage(prefix, sp);
16487c478bd9Sstevel@tonic-gate } else {
16497c478bd9Sstevel@tonic-gate return;
16507c478bd9Sstevel@tonic-gate }
16517c478bd9Sstevel@tonic-gate
16527c478bd9Sstevel@tonic-gate (void) printf(gettext("%s Expiration info:\n"), prefix);
16537c478bd9Sstevel@tonic-gate
16547c478bd9Sstevel@tonic-gate if (xfp->p1xf_max_kbytes != 0)
1655510c3f91SVladimir Kotal (void) printf(gettext("%s %u more bytes %scan be "
1656510c3f91SVladimir Kotal "protected.\n"),
1657510c3f91SVladimir Kotal prefix, xfp->p1xf_max_kbytes - sp->p1stat_kbytes,
1658510c3f91SVladimir Kotal bytecnt2out((uint64_t)(xfp->p1xf_max_kbytes -
1659510c3f91SVladimir Kotal sp->p1stat_kbytes) << 10, byte_str, sizeof (byte_str),
1660510c3f91SVladimir Kotal SPC_END));
16617c478bd9Sstevel@tonic-gate
16627c478bd9Sstevel@tonic-gate if (xfp->p1xf_max_keyuses != 0)
16637c478bd9Sstevel@tonic-gate (void) printf(gettext("%s Keying material can be provided "
16647c478bd9Sstevel@tonic-gate "%u more times.\n"), prefix,
16657c478bd9Sstevel@tonic-gate xfp->p1xf_max_keyuses - sp->p1stat_keyuses);
16667c478bd9Sstevel@tonic-gate
16677c478bd9Sstevel@tonic-gate if (xfp->p1xf_max_secs != 0) {
16687c478bd9Sstevel@tonic-gate exp = (time_t)sp->p1stat_start + (time_t)xfp->p1xf_max_secs;
16697c478bd9Sstevel@tonic-gate remain = exp - current;
16707c478bd9Sstevel@tonic-gate if (strftime(tbuf, TBUF_SIZE, NULL, localtime(&exp)) == 0)
16717c478bd9Sstevel@tonic-gate (void) strlcpy(tbuf,
16727c478bd9Sstevel@tonic-gate gettext("<time conversion failed>"), TBUF_SIZE);
1673c8393ed7Smarkfen /*
1674c8393ed7Smarkfen * The SA may have expired but still exist because libike
1675c8393ed7Smarkfen * has not freed it yet.
1676c8393ed7Smarkfen */
1677510c3f91SVladimir Kotal if (remain > 0) {
1678c8393ed7Smarkfen (void) printf(gettext(
1679510c3f91SVladimir Kotal "%s SA expires in %lu seconds%s\n"),
1680510c3f91SVladimir Kotal prefix, remain, secs2out(remain, secs_str,
1681510c3f91SVladimir Kotal sizeof (secs_str), SPC_BEGIN));
1682510c3f91SVladimir Kotal (void) printf(gettext("%s Time of expiration: %s\n"),
1683510c3f91SVladimir Kotal prefix, tbuf);
1684510c3f91SVladimir Kotal } else {
1685c8393ed7Smarkfen (void) printf(gettext("%s SA Expired at %s\n"),
1686c8393ed7Smarkfen prefix, tbuf);
1687510c3f91SVladimir Kotal }
16887c478bd9Sstevel@tonic-gate }
16897c478bd9Sstevel@tonic-gate }
16907c478bd9Sstevel@tonic-gate
16917c478bd9Sstevel@tonic-gate /* used to verify structure lengths... */
16927c478bd9Sstevel@tonic-gate #define COUNTER_32BIT 4
16937c478bd9Sstevel@tonic-gate #define COUNTER_PAIR 8
16947c478bd9Sstevel@tonic-gate
16957c478bd9Sstevel@tonic-gate static void
print_p1stats(char * prefix,ike_p1_stats_t * sp,int statlen,boolean_t print_lifetimes)16967c478bd9Sstevel@tonic-gate print_p1stats(char *prefix, ike_p1_stats_t *sp, int statlen,
16977c478bd9Sstevel@tonic-gate boolean_t print_lifetimes)
16987c478bd9Sstevel@tonic-gate {
16997c478bd9Sstevel@tonic-gate if (statlen < COUNTER_PAIR)
17007c478bd9Sstevel@tonic-gate return;
17017c478bd9Sstevel@tonic-gate (void) printf(gettext("%s %u Quick Mode SAs created; "), prefix,
17027c478bd9Sstevel@tonic-gate sp->p1stat_new_qm_sas);
17037c478bd9Sstevel@tonic-gate (void) printf(gettext("%u Quick Mode SAs deleted\n"),
17047c478bd9Sstevel@tonic-gate sp->p1stat_del_qm_sas);
17057c478bd9Sstevel@tonic-gate statlen -= COUNTER_PAIR;
17067c478bd9Sstevel@tonic-gate
17077c478bd9Sstevel@tonic-gate if ((print_lifetimes) && (statlen >= LT_USAGE_LEN))
17087c478bd9Sstevel@tonic-gate print_lt_usage(prefix, sp);
17097c478bd9Sstevel@tonic-gate }
17107c478bd9Sstevel@tonic-gate
17117c478bd9Sstevel@tonic-gate static void
print_errs(char * prefix,ike_p1_errors_t * errp,int errlen)17127c478bd9Sstevel@tonic-gate print_errs(char *prefix, ike_p1_errors_t *errp, int errlen)
17137c478bd9Sstevel@tonic-gate {
17147c478bd9Sstevel@tonic-gate /*
17157c478bd9Sstevel@tonic-gate * Don't try to break this one up; it's either all or nothing!
17167c478bd9Sstevel@tonic-gate */
17177c478bd9Sstevel@tonic-gate if (errlen < sizeof (ike_p1_errors_t))
17187c478bd9Sstevel@tonic-gate return;
17197c478bd9Sstevel@tonic-gate
17207c478bd9Sstevel@tonic-gate (void) printf(gettext("%s %u RX errors: "), prefix,
17217c478bd9Sstevel@tonic-gate errp->p1err_decrypt + errp->p1err_hash + errp->p1err_otherrx);
17227c478bd9Sstevel@tonic-gate (void) printf(gettext("%u decryption, %u hash, %u other\n"),
17237c478bd9Sstevel@tonic-gate errp->p1err_decrypt, errp->p1err_hash, errp->p1err_otherrx);
17247c478bd9Sstevel@tonic-gate (void) printf(gettext("%s %u TX errors\n"), prefix, errp->p1err_tx);
17257c478bd9Sstevel@tonic-gate }
17267c478bd9Sstevel@tonic-gate
17277c478bd9Sstevel@tonic-gate static void
print_addr_range(char * prefix,ike_addr_pr_t * pr)17287c478bd9Sstevel@tonic-gate print_addr_range(char *prefix, ike_addr_pr_t *pr)
17297c478bd9Sstevel@tonic-gate {
17307c478bd9Sstevel@tonic-gate boolean_t range = B_TRUE;
17317c478bd9Sstevel@tonic-gate struct sockaddr_storage *beg, *end;
17327c478bd9Sstevel@tonic-gate struct sockaddr_in *bsin, *esin;
17337c478bd9Sstevel@tonic-gate struct sockaddr_in6 *bsin6, *esin6;
17347c478bd9Sstevel@tonic-gate
17357c478bd9Sstevel@tonic-gate beg = &pr->beg_iprange;
17367c478bd9Sstevel@tonic-gate end = &pr->end_iprange;
17377c478bd9Sstevel@tonic-gate
17387c478bd9Sstevel@tonic-gate if (beg->ss_family != end->ss_family) {
17397c478bd9Sstevel@tonic-gate (void) printf(gettext("%s invalid address range\n"), prefix);
17407c478bd9Sstevel@tonic-gate return;
17417c478bd9Sstevel@tonic-gate }
17427c478bd9Sstevel@tonic-gate
17437c478bd9Sstevel@tonic-gate switch (beg->ss_family) {
17447c478bd9Sstevel@tonic-gate case AF_INET:
17457c478bd9Sstevel@tonic-gate bsin = (struct sockaddr_in *)beg;
17467c478bd9Sstevel@tonic-gate esin = (struct sockaddr_in *)end;
17477c478bd9Sstevel@tonic-gate if ((uint32_t)bsin->sin_addr.s_addr ==
17487c478bd9Sstevel@tonic-gate (uint32_t)esin->sin_addr.s_addr)
17497c478bd9Sstevel@tonic-gate range = B_FALSE;
17507c478bd9Sstevel@tonic-gate break;
17517c478bd9Sstevel@tonic-gate case AF_INET6:
17527c478bd9Sstevel@tonic-gate bsin6 = (struct sockaddr_in6 *)beg;
17537c478bd9Sstevel@tonic-gate esin6 = (struct sockaddr_in6 *)end;
17547c478bd9Sstevel@tonic-gate if (IN6_ARE_ADDR_EQUAL(&bsin6->sin6_addr, &esin6->sin6_addr))
17557c478bd9Sstevel@tonic-gate range = B_FALSE;
17567c478bd9Sstevel@tonic-gate break;
17577c478bd9Sstevel@tonic-gate default:
17587c478bd9Sstevel@tonic-gate (void) printf(gettext("%s invalid address range\n"), prefix);
17597c478bd9Sstevel@tonic-gate return;
17607c478bd9Sstevel@tonic-gate }
17617c478bd9Sstevel@tonic-gate
17627c478bd9Sstevel@tonic-gate (void) printf("%s ", prefix);
1763bb3ed8dfSpwernau (void) dump_sockaddr((struct sockaddr *)beg, 0, B_TRUE, stdout, nflag);
17647c478bd9Sstevel@tonic-gate if (range) {
17657c478bd9Sstevel@tonic-gate (void) printf(" - ");
1766bb3ed8dfSpwernau (void) dump_sockaddr((struct sockaddr *)end, 0, B_TRUE, stdout,
1767bb3ed8dfSpwernau nflag);
17687c478bd9Sstevel@tonic-gate }
17697c478bd9Sstevel@tonic-gate (void) printf("\n");
17707c478bd9Sstevel@tonic-gate
17717c478bd9Sstevel@tonic-gate }
17727c478bd9Sstevel@tonic-gate
17737c478bd9Sstevel@tonic-gate /*
17747c478bd9Sstevel@tonic-gate * used to tell printing function if info should be identified
17757c478bd9Sstevel@tonic-gate * as belonging to initiator, responder, or neither
17767c478bd9Sstevel@tonic-gate */
17777c478bd9Sstevel@tonic-gate #define IS_INITIATOR 1
17787c478bd9Sstevel@tonic-gate #define IS_RESPONDER 2
17797c478bd9Sstevel@tonic-gate #define DONT_PRINT_INIT 3
17807c478bd9Sstevel@tonic-gate
17817c478bd9Sstevel@tonic-gate static void
print_addr(char * prefix,struct sockaddr_storage * sa,int init_instr,int mask)178241c215c2SPaul Wernau print_addr(char *prefix, struct sockaddr_storage *sa, int init_instr,
178341c215c2SPaul Wernau int mask)
17847c478bd9Sstevel@tonic-gate {
17857c478bd9Sstevel@tonic-gate (void) printf(gettext("%s Address"), prefix);
17867c478bd9Sstevel@tonic-gate
17877c478bd9Sstevel@tonic-gate if (init_instr != DONT_PRINT_INIT)
17887c478bd9Sstevel@tonic-gate (void) printf(" (%s):\n", (init_instr == IS_INITIATOR) ?
17897c478bd9Sstevel@tonic-gate gettext("Initiator") : gettext("Responder"));
17907c478bd9Sstevel@tonic-gate else
17917c478bd9Sstevel@tonic-gate (void) printf(":\n");
17927c478bd9Sstevel@tonic-gate
17937c478bd9Sstevel@tonic-gate (void) printf("%s ", prefix);
179441c215c2SPaul Wernau (void) dump_sockaddr((struct sockaddr *)sa, mask, B_FALSE, stdout,
179541c215c2SPaul Wernau nflag);
17967c478bd9Sstevel@tonic-gate }
17977c478bd9Sstevel@tonic-gate
17987c478bd9Sstevel@tonic-gate static void
print_id(char * prefix,sadb_ident_t * idp,int init_instr)17997c478bd9Sstevel@tonic-gate print_id(char *prefix, sadb_ident_t *idp, int init_instr)
18007c478bd9Sstevel@tonic-gate {
18017c478bd9Sstevel@tonic-gate boolean_t canprint;
18027c478bd9Sstevel@tonic-gate
18037c478bd9Sstevel@tonic-gate switch (init_instr) {
18047c478bd9Sstevel@tonic-gate case IS_INITIATOR:
18057c478bd9Sstevel@tonic-gate (void) printf(gettext("%s Initiator identity, "), prefix);
18067c478bd9Sstevel@tonic-gate break;
18077c478bd9Sstevel@tonic-gate case IS_RESPONDER:
18087c478bd9Sstevel@tonic-gate (void) printf(gettext("%s Responder identity, "), prefix);
18097c478bd9Sstevel@tonic-gate break;
18107c478bd9Sstevel@tonic-gate case DONT_PRINT_INIT:
18117c478bd9Sstevel@tonic-gate (void) printf(gettext("%s Identity, "), prefix);
18127c478bd9Sstevel@tonic-gate break;
18137c478bd9Sstevel@tonic-gate default:
18147c478bd9Sstevel@tonic-gate (void) printf(gettext("<invalid identity>\n"));
18157c478bd9Sstevel@tonic-gate return;
18167c478bd9Sstevel@tonic-gate }
18177c478bd9Sstevel@tonic-gate (void) printf(gettext("uid=%d, type "), idp->sadb_ident_id);
18187c478bd9Sstevel@tonic-gate canprint = dump_sadb_idtype(idp->sadb_ident_type, stdout, NULL);
1819a12f8217Spwernau if (canprint) {
18207c478bd9Sstevel@tonic-gate (void) printf("\n%s %s\n", prefix, (char *)(idp + 1));
1821a12f8217Spwernau } else {
1822a12f8217Spwernau (void) printf(gettext("\n%s "), prefix);
1823a12f8217Spwernau print_asn1_name(stdout,
1824a12f8217Spwernau (const unsigned char *)(idp + 1),
1825a12f8217Spwernau SADB_64TO8(idp->sadb_ident_len) - sizeof (sadb_ident_t));
1826a12f8217Spwernau }
18277c478bd9Sstevel@tonic-gate }
18287c478bd9Sstevel@tonic-gate
18297c478bd9Sstevel@tonic-gate static void
print_idspec(char * prefix,char * idp,int icnt,int ecnt)18307c478bd9Sstevel@tonic-gate print_idspec(char *prefix, char *idp, int icnt, int ecnt)
18317c478bd9Sstevel@tonic-gate {
18327c478bd9Sstevel@tonic-gate int i;
18337c478bd9Sstevel@tonic-gate
18347c478bd9Sstevel@tonic-gate (void) printf(gettext("%s Identity descriptors:\n"), prefix);
18357c478bd9Sstevel@tonic-gate
18367c478bd9Sstevel@tonic-gate for (i = 0; i < icnt; i++) {
18377c478bd9Sstevel@tonic-gate if (i == 0)
18387c478bd9Sstevel@tonic-gate (void) printf(gettext("%s Includes:\n"), prefix);
18397c478bd9Sstevel@tonic-gate (void) printf("%s %s\n", prefix, idp);
18407c478bd9Sstevel@tonic-gate idp += strlen(idp) + 1;
18417c478bd9Sstevel@tonic-gate }
18427c478bd9Sstevel@tonic-gate
18437c478bd9Sstevel@tonic-gate for (i = 0; i < ecnt; i++) {
18447c478bd9Sstevel@tonic-gate if (i == 0)
18457c478bd9Sstevel@tonic-gate (void) printf(gettext("%s Excludes:\n"), prefix);
18467c478bd9Sstevel@tonic-gate (void) printf("%s %s\n", prefix, idp);
18477c478bd9Sstevel@tonic-gate idp += strlen(idp) + 1;
18487c478bd9Sstevel@tonic-gate }
18497c478bd9Sstevel@tonic-gate }
18507c478bd9Sstevel@tonic-gate
18517c478bd9Sstevel@tonic-gate static void
print_keys(char * prefix,ike_p1_key_t * keyp,int size)18527c478bd9Sstevel@tonic-gate print_keys(char *prefix, ike_p1_key_t *keyp, int size)
18537c478bd9Sstevel@tonic-gate {
18547c478bd9Sstevel@tonic-gate uint32_t *curp;
18557c478bd9Sstevel@tonic-gate ike_p1_key_t *p;
18567c478bd9Sstevel@tonic-gate int ssize;
18577c478bd9Sstevel@tonic-gate
18587c478bd9Sstevel@tonic-gate curp = (uint32_t *)keyp;
18597c478bd9Sstevel@tonic-gate
18607c478bd9Sstevel@tonic-gate ssize = sizeof (ike_p1_key_t);
18617c478bd9Sstevel@tonic-gate
18627c478bd9Sstevel@tonic-gate while ((intptr_t)curp - (intptr_t)keyp < size) {
18637c478bd9Sstevel@tonic-gate size_t p1klen, len;
18647c478bd9Sstevel@tonic-gate
18657c478bd9Sstevel@tonic-gate p = (ike_p1_key_t *)curp;
18667c478bd9Sstevel@tonic-gate p1klen = p->p1key_len;
18677c478bd9Sstevel@tonic-gate len = p1klen - ssize;
18687c478bd9Sstevel@tonic-gate
18697c478bd9Sstevel@tonic-gate p1klen = roundup(p1klen, sizeof (ike_p1_key_t));
18707c478bd9Sstevel@tonic-gate if (p1klen < ssize) {
18717c478bd9Sstevel@tonic-gate (void) printf(gettext("Short key\n"));
18727c478bd9Sstevel@tonic-gate break;
18737c478bd9Sstevel@tonic-gate }
18747c478bd9Sstevel@tonic-gate
18757c478bd9Sstevel@tonic-gate switch (p->p1key_type) {
18767c478bd9Sstevel@tonic-gate case IKE_KEY_PRESHARED:
18777c478bd9Sstevel@tonic-gate (void) printf(gettext("%s Pre-shared key (%d bytes): "),
18787c478bd9Sstevel@tonic-gate prefix, len);
18797c478bd9Sstevel@tonic-gate break;
18807c478bd9Sstevel@tonic-gate case IKE_KEY_SKEYID:
18817c478bd9Sstevel@tonic-gate (void) printf(gettext("%s SKEYID (%d bytes): "),
18827c478bd9Sstevel@tonic-gate prefix, len);
18837c478bd9Sstevel@tonic-gate break;
18847c478bd9Sstevel@tonic-gate case IKE_KEY_SKEYID_D:
18857c478bd9Sstevel@tonic-gate (void) printf(gettext("%s SKEYID_d (%d bytes): "),
18867c478bd9Sstevel@tonic-gate prefix, len);
18877c478bd9Sstevel@tonic-gate break;
18887c478bd9Sstevel@tonic-gate case IKE_KEY_SKEYID_A:
18897c478bd9Sstevel@tonic-gate (void) printf(gettext("%s SKEYID_a (%d bytes): "),
18907c478bd9Sstevel@tonic-gate prefix, len);
18917c478bd9Sstevel@tonic-gate break;
18927c478bd9Sstevel@tonic-gate case IKE_KEY_SKEYID_E:
18937c478bd9Sstevel@tonic-gate (void) printf(gettext("%s SKEYID_e (%d bytes): "),
18947c478bd9Sstevel@tonic-gate prefix, len);
18957c478bd9Sstevel@tonic-gate break;
18967c478bd9Sstevel@tonic-gate case IKE_KEY_ENCR:
18977c478bd9Sstevel@tonic-gate (void) printf(gettext("%s Encryption key (%d bytes): "),
18987c478bd9Sstevel@tonic-gate prefix, len);
18997c478bd9Sstevel@tonic-gate break;
19007c478bd9Sstevel@tonic-gate case IKE_KEY_IV:
19017c478bd9Sstevel@tonic-gate (void) printf(
19027c478bd9Sstevel@tonic-gate gettext("%s Initialization vector (%d bytes): "),
19037c478bd9Sstevel@tonic-gate prefix, len);
19047c478bd9Sstevel@tonic-gate break;
19057c478bd9Sstevel@tonic-gate default:
19067c478bd9Sstevel@tonic-gate (void) printf(gettext("%s Unidentified key info %p %d"),
19077c478bd9Sstevel@tonic-gate prefix, p, p1klen);
1908d0115d88SMark Fenwick goto badkey;
19097c478bd9Sstevel@tonic-gate }
1910d0115d88SMark Fenwick (void) dump_key((uint8_t *)(p + 1), SADB_8TO1(len), 0,
1911d0115d88SMark Fenwick stdout, B_FALSE);
1912d0115d88SMark Fenwick badkey:
19137c478bd9Sstevel@tonic-gate (void) printf("\n");
19147c478bd9Sstevel@tonic-gate assert(IS_P2ALIGNED(p1klen, 8));
19157c478bd9Sstevel@tonic-gate curp += (p1klen >> 2);
19167c478bd9Sstevel@tonic-gate }
19177c478bd9Sstevel@tonic-gate }
19187c478bd9Sstevel@tonic-gate
19195d01c172SVladimir Kotal static void
print_group_header(void)19205d01c172SVladimir Kotal print_group_header(void)
19215d01c172SVladimir Kotal {
19225d01c172SVladimir Kotal (void) printf(gettext("\nList of Diffie-Hellman groups for setting "
19235d01c172SVladimir Kotal "up IKE SAs"));
19245d01c172SVladimir Kotal (void) printf(gettext("\nThe values match the IPsec attribute "
19255d01c172SVladimir Kotal "assigned numbers published by IANA\n\n"));
19265d01c172SVladimir Kotal (void) printf("%-6s%-9s%-50s\n",
19275d01c172SVladimir Kotal gettext("Value"), gettext("Strength"), gettext("Description"));
19285d01c172SVladimir Kotal }
19295d01c172SVladimir Kotal
19305d01c172SVladimir Kotal static void
print_group(ike_group_t * gp)19315d01c172SVladimir Kotal print_group(ike_group_t *gp)
19325d01c172SVladimir Kotal {
19335d01c172SVladimir Kotal (void) printf("%-6u%-9u%-50s\n",
19345d01c172SVladimir Kotal gp->group_number, gp->group_bits, gp->group_label);
19355d01c172SVladimir Kotal }
19365d01c172SVladimir Kotal
19375d01c172SVladimir Kotal static void
print_encralg_header(void)19385d01c172SVladimir Kotal print_encralg_header(void)
19395d01c172SVladimir Kotal {
19405d01c172SVladimir Kotal (void) printf(gettext("\nList of encryption algorithms for IKE"));
19415d01c172SVladimir Kotal (void) printf(gettext("\nThe values match the IPsec attribute "
19425d01c172SVladimir Kotal "assigned numbers published by IANA\n\n"));
19435d01c172SVladimir Kotal (void) printf("%-6s%-20s%-15s\n", gettext("Value"),
19445d01c172SVladimir Kotal gettext("Name"), gettext("Keylen range"));
19455d01c172SVladimir Kotal }
19465d01c172SVladimir Kotal
19475d01c172SVladimir Kotal static void
print_encralg(ike_encralg_t * ep)19485d01c172SVladimir Kotal print_encralg(ike_encralg_t *ep)
19495d01c172SVladimir Kotal {
19505d01c172SVladimir Kotal char keylen_str[16];
19515d01c172SVladimir Kotal
19525d01c172SVladimir Kotal (void) strlcpy(keylen_str, "N/A", sizeof (keylen_str));
19535d01c172SVladimir Kotal if (ep->encr_keylen_min != 0 || ep->encr_keylen_max != 0)
19545d01c172SVladimir Kotal (void) snprintf(keylen_str, sizeof (keylen_str), "%d-%d",
19555d01c172SVladimir Kotal ep->encr_keylen_min, ep->encr_keylen_max);
19565d01c172SVladimir Kotal (void) printf("%-6u%-20s%-15s\n",
19575d01c172SVladimir Kotal ep->encr_value, ep->encr_name, keylen_str);
19585d01c172SVladimir Kotal }
19595d01c172SVladimir Kotal
19605d01c172SVladimir Kotal static void
print_authalg_header(void)19615d01c172SVladimir Kotal print_authalg_header(void)
19625d01c172SVladimir Kotal {
19635d01c172SVladimir Kotal (void) printf(gettext("\nList of authentication algorithms for IKE"));
19645d01c172SVladimir Kotal (void) printf(gettext("\nThe values match the IPsec attribute "
19655d01c172SVladimir Kotal "assigned numbers published by IANA\n\n"));
19665d01c172SVladimir Kotal (void) printf("%-6s%-20s\n", gettext("Value"), gettext("Name"));
19675d01c172SVladimir Kotal }
19685d01c172SVladimir Kotal
19695d01c172SVladimir Kotal static void
print_authalg(ike_authalg_t * ap)19705d01c172SVladimir Kotal print_authalg(ike_authalg_t *ap)
19715d01c172SVladimir Kotal {
19725d01c172SVladimir Kotal (void) printf("%-6u%-20s\n",
19735d01c172SVladimir Kotal ap->auth_value, ap->auth_name);
19745d01c172SVladimir Kotal }
19755d01c172SVladimir Kotal
19767c478bd9Sstevel@tonic-gate static void
print_p1(ike_p1_sa_t * p1)19777c478bd9Sstevel@tonic-gate print_p1(ike_p1_sa_t *p1)
19787c478bd9Sstevel@tonic-gate {
19797c478bd9Sstevel@tonic-gate ike_p1_stats_t *sp;
19807c478bd9Sstevel@tonic-gate ike_p1_errors_t *ep;
19817c478bd9Sstevel@tonic-gate ike_p1_key_t *kp;
19827c478bd9Sstevel@tonic-gate sadb_ident_t *lidp, *ridp;
19837c478bd9Sstevel@tonic-gate int lstat, rstat;
19847c478bd9Sstevel@tonic-gate
19857c478bd9Sstevel@tonic-gate (void) printf("\n");
19867c478bd9Sstevel@tonic-gate print_hdr("IKESA:", &p1->p1sa_hdr);
19877c478bd9Sstevel@tonic-gate print_xform("XFORM:", &p1->p1sa_xform, B_FALSE);
19887c478bd9Sstevel@tonic-gate
19897c478bd9Sstevel@tonic-gate if (p1->p1sa_hdr.p1hdr_isinit) {
19907c478bd9Sstevel@tonic-gate lstat = IS_INITIATOR;
19917c478bd9Sstevel@tonic-gate rstat = IS_RESPONDER;
19927c478bd9Sstevel@tonic-gate } else {
19937c478bd9Sstevel@tonic-gate lstat = IS_RESPONDER;
19947c478bd9Sstevel@tonic-gate rstat = IS_INITIATOR;
19957c478bd9Sstevel@tonic-gate }
199641c215c2SPaul Wernau print_addr("LOCIP:", &p1->p1sa_ipaddrs.loc_addr, lstat, 0);
199741c215c2SPaul Wernau print_addr("REMIP:", &p1->p1sa_ipaddrs.rem_addr, rstat, 0);
19987c478bd9Sstevel@tonic-gate
19997c478bd9Sstevel@tonic-gate /*
20007c478bd9Sstevel@tonic-gate * the stat len might be 0; but still make the call
20017c478bd9Sstevel@tonic-gate * to print_lifetime() to pick up the xform info
20027c478bd9Sstevel@tonic-gate */
20037c478bd9Sstevel@tonic-gate sp = (ike_p1_stats_t *)((int)(p1) + p1->p1sa_stat_off);
20047c478bd9Sstevel@tonic-gate print_lifetime("LIFTM:", &p1->p1sa_xform, sp, p1->p1sa_stat_len);
20057c478bd9Sstevel@tonic-gate
20067c478bd9Sstevel@tonic-gate if (p1->p1sa_stat_len > 0) {
20077c478bd9Sstevel@tonic-gate print_p1stats("STATS:", sp, p1->p1sa_stat_len, B_FALSE);
20087c478bd9Sstevel@tonic-gate }
20097c478bd9Sstevel@tonic-gate
20107c478bd9Sstevel@tonic-gate if (p1->p1sa_error_len > 0) {
20117c478bd9Sstevel@tonic-gate ep = (ike_p1_errors_t *)((int)(p1) + p1->p1sa_error_off);
20127c478bd9Sstevel@tonic-gate print_errs("ERRS: ", ep, p1->p1sa_error_len);
20137c478bd9Sstevel@tonic-gate }
20147c478bd9Sstevel@tonic-gate
20157c478bd9Sstevel@tonic-gate if (p1->p1sa_localid_len > 0) {
20167c478bd9Sstevel@tonic-gate lidp = (sadb_ident_t *)((int)(p1) + p1->p1sa_localid_off);
20177c478bd9Sstevel@tonic-gate print_id("LOCID:", lidp, lstat);
20187c478bd9Sstevel@tonic-gate }
20197c478bd9Sstevel@tonic-gate
20207c478bd9Sstevel@tonic-gate if (p1->p1sa_remoteid_len > 0) {
20217c478bd9Sstevel@tonic-gate ridp = (sadb_ident_t *)((int)(p1) + p1->p1sa_remoteid_off);
20227c478bd9Sstevel@tonic-gate print_id("REMID:", ridp, rstat);
20237c478bd9Sstevel@tonic-gate }
20247c478bd9Sstevel@tonic-gate
20257c478bd9Sstevel@tonic-gate if (p1->p1sa_key_len > 0) {
20267c478bd9Sstevel@tonic-gate kp = (ike_p1_key_t *)((int)(p1) + p1->p1sa_key_off);
20277c478bd9Sstevel@tonic-gate print_keys("KEY: ", kp, p1->p1sa_key_len);
20287c478bd9Sstevel@tonic-gate }
20297c478bd9Sstevel@tonic-gate }
20307c478bd9Sstevel@tonic-gate
2031c7777ac8SPaul Wernau static void
print_certcache(ike_certcache_t * c)2032c7777ac8SPaul Wernau print_certcache(ike_certcache_t *c)
2033c7777ac8SPaul Wernau {
2034c7777ac8SPaul Wernau (void) printf("\n");
2035c7777ac8SPaul Wernau
2036c7777ac8SPaul Wernau (void) printf(gettext("CERTIFICATE CACHE ID: %d\n"), c->cache_id);
2037c7777ac8SPaul Wernau (void) printf(gettext("\tSubject Name: <%s>\n"),
203878af48deSToomas Soome (*c->subject != '\0') ? c->subject : gettext("Name unavailable"));
2039c7777ac8SPaul Wernau (void) printf(gettext("\t Issuer Name: <%s>\n"),
204078af48deSToomas Soome (*c->issuer != '\0') ? c->issuer : gettext("Name unavailable"));
2041510c3f91SVladimir Kotal if ((int)c->certclass == -1)
2042c7777ac8SPaul Wernau (void) printf(gettext("\t\t[trusted certificate]\n"));
2043c7777ac8SPaul Wernau switch (c->linkage) {
2044c7777ac8SPaul Wernau case CERT_OFF_WIRE:
2045c7777ac8SPaul Wernau (void) printf(gettext("\t\t[Public certificate only]\n"));
2046c7777ac8SPaul Wernau (void) printf(gettext(
2047c7777ac8SPaul Wernau "\t\t[Obtained via certificate payload]\n"));
2048c7777ac8SPaul Wernau break;
2049c7777ac8SPaul Wernau case CERT_NO_PRIVKEY:
2050c7777ac8SPaul Wernau (void) printf(gettext("\t\t[Public certificate only]\n"));
2051c7777ac8SPaul Wernau break;
2052c7777ac8SPaul Wernau case CERT_PRIVKEY_LOCKED:
2053c7777ac8SPaul Wernau (void) printf(gettext(
2054c7777ac8SPaul Wernau "\t\t[Private key linked but locked]\n"));
2055c7777ac8SPaul Wernau break;
2056c7777ac8SPaul Wernau case CERT_PRIVKEY_AVAIL:
2057c7777ac8SPaul Wernau (void) printf(gettext("\t\t[Private key available]\n"));
2058c7777ac8SPaul Wernau break;
2059c7777ac8SPaul Wernau }
2060c7777ac8SPaul Wernau }
2061c7777ac8SPaul Wernau
20627c478bd9Sstevel@tonic-gate static void
print_ps(ike_ps_t * ps)20637c478bd9Sstevel@tonic-gate print_ps(ike_ps_t *ps)
20647c478bd9Sstevel@tonic-gate {
20657c478bd9Sstevel@tonic-gate sadb_ident_t *lidp, *ridp;
20667c478bd9Sstevel@tonic-gate uint8_t *keyp;
20677c478bd9Sstevel@tonic-gate
20687c478bd9Sstevel@tonic-gate (void) printf("\n");
20697c478bd9Sstevel@tonic-gate
20707c478bd9Sstevel@tonic-gate (void) printf(gettext("PSKEY: For %s exchanges\n"),
20717c478bd9Sstevel@tonic-gate xchgstr(ps->ps_ike_mode));
20727c478bd9Sstevel@tonic-gate
20737c478bd9Sstevel@tonic-gate if (ps->ps_key_len > 0) {
20747c478bd9Sstevel@tonic-gate keyp = (uint8_t *)((int)(ps) + ps->ps_key_off);
20757c478bd9Sstevel@tonic-gate (void) printf(gettext("PSKEY: Pre-shared key (%d bytes): "),
20767c478bd9Sstevel@tonic-gate ps->ps_key_len);
2077628b0c67SMark Fenwick (void) dump_key(keyp, ps->ps_key_bits, 0, stdout, B_FALSE);
20787c478bd9Sstevel@tonic-gate (void) printf("\n");
20797c478bd9Sstevel@tonic-gate }
20807c478bd9Sstevel@tonic-gate
20817c478bd9Sstevel@tonic-gate /*
20827c478bd9Sstevel@tonic-gate * We get *either* and address or an ident, never both. So if
20837c478bd9Sstevel@tonic-gate * the ident is there, don't try printing an address.
20847c478bd9Sstevel@tonic-gate */
20857c478bd9Sstevel@tonic-gate if (ps->ps_localid_len > 0) {
20867c478bd9Sstevel@tonic-gate lidp = (sadb_ident_t *)
20877c478bd9Sstevel@tonic-gate ((int)(ps) + ps->ps_localid_off);
20887c478bd9Sstevel@tonic-gate print_id("LOCID:", lidp, DONT_PRINT_INIT);
20897c478bd9Sstevel@tonic-gate } else {
209041c215c2SPaul Wernau print_addr("LOCIP:", &ps->ps_ipaddrs.loc_addr, DONT_PRINT_INIT,
209141c215c2SPaul Wernau ps->ps_localid_plen > 0 ? ps->ps_localid_plen : 0);
20927c478bd9Sstevel@tonic-gate }
20937c478bd9Sstevel@tonic-gate
20947c478bd9Sstevel@tonic-gate if (ps->ps_remoteid_len > 0) {
20957c478bd9Sstevel@tonic-gate ridp = (sadb_ident_t *)
20967c478bd9Sstevel@tonic-gate ((int)(ps) + ps->ps_remoteid_off);
20977c478bd9Sstevel@tonic-gate print_id("REMID:", ridp, DONT_PRINT_INIT);
20987c478bd9Sstevel@tonic-gate } else {
209941c215c2SPaul Wernau print_addr("REMIP:", &ps->ps_ipaddrs.rem_addr, DONT_PRINT_INIT,
210041c215c2SPaul Wernau ps->ps_remoteid_plen > 0 ? ps->ps_remoteid_plen : 0);
21017c478bd9Sstevel@tonic-gate }
21027c478bd9Sstevel@tonic-gate }
21037c478bd9Sstevel@tonic-gate
21047c478bd9Sstevel@tonic-gate #define PREFIXLEN 16
21057c478bd9Sstevel@tonic-gate
21067c478bd9Sstevel@tonic-gate static void
print_rule(ike_rule_t * rp)21077c478bd9Sstevel@tonic-gate print_rule(ike_rule_t *rp)
21087c478bd9Sstevel@tonic-gate {
21097c478bd9Sstevel@tonic-gate char prefix[PREFIXLEN];
21107c478bd9Sstevel@tonic-gate int i;
21117c478bd9Sstevel@tonic-gate ike_p1_xform_t *xfp;
21127c478bd9Sstevel@tonic-gate ike_addr_pr_t *lipp, *ripp;
21137c478bd9Sstevel@tonic-gate char *lidp, *ridp;
2114510c3f91SVladimir Kotal char byte_str[BYTE_STR_SIZE]; /* kbyte string representation */
2115510c3f91SVladimir Kotal char secs_str[SECS_STR_SIZE]; /* seconds string representation */
21167c478bd9Sstevel@tonic-gate
21177c478bd9Sstevel@tonic-gate (void) printf("\n");
21187c478bd9Sstevel@tonic-gate (void) printf(gettext("GLOBL: Label '%s', key manager cookie %u\n"),
21197c478bd9Sstevel@tonic-gate rp->rule_label, rp->rule_kmcookie);
21207c478bd9Sstevel@tonic-gate (void) printf(gettext("GLOBL: local_idtype="));
21217c478bd9Sstevel@tonic-gate (void) dump_sadb_idtype(rp->rule_local_idtype, stdout, NULL);
21227c478bd9Sstevel@tonic-gate (void) printf(gettext(", ike_mode=%s\n"), xchgstr(rp->rule_ike_mode));
21230f2065ccSmarkfen (void) printf(gettext(
21240f2065ccSmarkfen "GLOBL: p1_nonce_len=%u, p2_nonce_len=%u, p2_pfs=%s (group %u)\n"),
21250f2065ccSmarkfen rp->rule_p1_nonce_len, rp->rule_p2_nonce_len,
21267c478bd9Sstevel@tonic-gate (rp->rule_p2_pfs) ? gettext("true") : gettext("false"),
21270f2065ccSmarkfen rp->rule_p2_pfs);
21280f2065ccSmarkfen (void) printf(
2129510c3f91SVladimir Kotal gettext("GLOBL: p2_lifetime=%u seconds%s\n"),
2130510c3f91SVladimir Kotal rp->rule_p2_lifetime_secs, secs2out(rp->rule_p2_lifetime_secs,
2131510c3f91SVladimir Kotal secs_str, sizeof (secs_str), SPC_BEGIN));
2132510c3f91SVladimir Kotal (void) printf(
2133510c3f91SVladimir Kotal gettext("GLOBL: p2_softlife=%u seconds%s\n"),
2134510c3f91SVladimir Kotal rp->rule_p2_softlife_secs, secs2out(rp->rule_p2_softlife_secs,
2135510c3f91SVladimir Kotal secs_str, sizeof (secs_str), SPC_BEGIN));
2136510c3f91SVladimir Kotal (void) printf(
2137510c3f91SVladimir Kotal gettext("GLOBL: p2_idletime=%u seconds%s\n"),
2138510c3f91SVladimir Kotal rp->rule_p2_idletime_secs, secs2out(rp->rule_p2_idletime_secs,
2139510c3f91SVladimir Kotal secs_str, sizeof (secs_str), SPC_BEGIN));
2140510c3f91SVladimir Kotal /*
2141510c3f91SVladimir Kotal * Perform explicit conversion before passing to bytecnt2out()
2142510c3f91SVladimir Kotal * to avoid integer overflow.
2143510c3f91SVladimir Kotal */
21449c2c14abSThejaswini Singarajipura (void) printf(
2145510c3f91SVladimir Kotal gettext("GLOBL: p2_lifetime_kb=%u kilobytes%s\n"),
2146510c3f91SVladimir Kotal rp->rule_p2_lifetime_kb,
2147510c3f91SVladimir Kotal bytecnt2out((uint64_t)(rp->rule_p2_lifetime_kb) << 10,
2148510c3f91SVladimir Kotal byte_str, sizeof (byte_str), SPC_BEGIN));
21490f2065ccSmarkfen (void) printf(
2150510c3f91SVladimir Kotal gettext("GLOBL: p2_softlife_kb=%u kilobytes%s\n"),
2151510c3f91SVladimir Kotal rp->rule_p2_softlife_kb,
2152510c3f91SVladimir Kotal bytecnt2out(((uint64_t)(rp->rule_p2_softlife_kb)) << 10,
2153510c3f91SVladimir Kotal byte_str, sizeof (byte_str), SPC_BEGIN));
21547c478bd9Sstevel@tonic-gate
21557c478bd9Sstevel@tonic-gate if (rp->rule_locip_cnt > 0) {
21567c478bd9Sstevel@tonic-gate (void) printf(gettext("LOCIP: IP address range(s):\n"));
21577c478bd9Sstevel@tonic-gate lipp = (ike_addr_pr_t *)((int)rp + rp->rule_locip_off);
21587c478bd9Sstevel@tonic-gate for (i = 0; i < rp->rule_locip_cnt; i++, lipp++) {
21597c478bd9Sstevel@tonic-gate print_addr_range("LOCIP:", lipp);
21607c478bd9Sstevel@tonic-gate }
21617c478bd9Sstevel@tonic-gate }
21627c478bd9Sstevel@tonic-gate
21637c478bd9Sstevel@tonic-gate if (rp->rule_remip_cnt > 0) {
21647c478bd9Sstevel@tonic-gate (void) printf(gettext("REMIP: IP address range(s):\n"));
21657c478bd9Sstevel@tonic-gate ripp = (ike_addr_pr_t *)((int)rp + rp->rule_remip_off);
21667c478bd9Sstevel@tonic-gate for (i = 0; i < rp->rule_remip_cnt; i++, ripp++) {
21677c478bd9Sstevel@tonic-gate print_addr_range("REMIP:", ripp);
21687c478bd9Sstevel@tonic-gate }
21697c478bd9Sstevel@tonic-gate }
21707c478bd9Sstevel@tonic-gate
21717c478bd9Sstevel@tonic-gate if (rp->rule_locid_inclcnt + rp->rule_locid_exclcnt > 0) {
21727c478bd9Sstevel@tonic-gate lidp = (char *)((int)rp + rp->rule_locid_off);
21737c478bd9Sstevel@tonic-gate print_idspec("LOCID:", lidp, rp->rule_locid_inclcnt,
21747c478bd9Sstevel@tonic-gate rp->rule_locid_exclcnt);
21757c478bd9Sstevel@tonic-gate }
21767c478bd9Sstevel@tonic-gate
21777c478bd9Sstevel@tonic-gate if (rp->rule_remid_inclcnt + rp->rule_remid_exclcnt > 0) {
21787c478bd9Sstevel@tonic-gate ridp = (char *)((int)rp + rp->rule_remid_off);
21797c478bd9Sstevel@tonic-gate print_idspec("REMID:", ridp, rp->rule_remid_inclcnt,
21807c478bd9Sstevel@tonic-gate rp->rule_remid_exclcnt);
21817c478bd9Sstevel@tonic-gate }
21827c478bd9Sstevel@tonic-gate
21837c478bd9Sstevel@tonic-gate if (rp->rule_xform_cnt > 0) {
21847c478bd9Sstevel@tonic-gate (void) printf(gettext("XFRMS: Available Transforms:\n"));
21857c478bd9Sstevel@tonic-gate xfp = (ike_p1_xform_t *)((int)rp + rp->rule_xform_off);
21867c478bd9Sstevel@tonic-gate for (i = 0; i < rp->rule_xform_cnt; i++, xfp++) {
21877c478bd9Sstevel@tonic-gate (void) snprintf(prefix, PREFIXLEN, "XF %2u:", i);
21887c478bd9Sstevel@tonic-gate print_xform(prefix, xfp, B_TRUE);
21897c478bd9Sstevel@tonic-gate }
21907c478bd9Sstevel@tonic-gate }
21917c478bd9Sstevel@tonic-gate }
21927c478bd9Sstevel@tonic-gate
21937c478bd9Sstevel@tonic-gate #undef PREFIXLEN
21947c478bd9Sstevel@tonic-gate
21957c478bd9Sstevel@tonic-gate #define PRSACNTS(init, resp) \
21967c478bd9Sstevel@tonic-gate (void) printf(gettext("initiator: %10u responder: %10u\n"), \
21977c478bd9Sstevel@tonic-gate (init), (resp))
21987c478bd9Sstevel@tonic-gate
21997c478bd9Sstevel@tonic-gate static void
print_stats(ike_stats_t * sp,int len)22007c478bd9Sstevel@tonic-gate print_stats(ike_stats_t *sp, int len)
22017c478bd9Sstevel@tonic-gate {
22027c478bd9Sstevel@tonic-gate /*
22037c478bd9Sstevel@tonic-gate * before printing each line, make sure the structure we were
22047c478bd9Sstevel@tonic-gate * given is big enough to include the fields needed.
22057c478bd9Sstevel@tonic-gate */
22067c478bd9Sstevel@tonic-gate if (len < COUNTER_PAIR)
22077c478bd9Sstevel@tonic-gate return;
22087c478bd9Sstevel@tonic-gate (void) printf(gettext("Phase 1 SA counts:\n"));
22097c478bd9Sstevel@tonic-gate (void) printf(gettext("Current: "));
22107c478bd9Sstevel@tonic-gate PRSACNTS(sp->st_init_p1_current, sp->st_resp_p1_current);
22117c478bd9Sstevel@tonic-gate len -= COUNTER_PAIR;
22127c478bd9Sstevel@tonic-gate
22137c478bd9Sstevel@tonic-gate if (len < COUNTER_PAIR)
22147c478bd9Sstevel@tonic-gate return;
22157c478bd9Sstevel@tonic-gate (void) printf(gettext("Total: "));
22167c478bd9Sstevel@tonic-gate PRSACNTS(sp->st_init_p1_total, sp->st_resp_p1_total);
22177c478bd9Sstevel@tonic-gate len -= COUNTER_PAIR;
22187c478bd9Sstevel@tonic-gate
22197c478bd9Sstevel@tonic-gate if (len < COUNTER_PAIR)
22207c478bd9Sstevel@tonic-gate return;
22217c478bd9Sstevel@tonic-gate (void) printf(gettext("Attempted: "));
22227c478bd9Sstevel@tonic-gate PRSACNTS(sp->st_init_p1_attempts, sp->st_resp_p1_attempts);
22237c478bd9Sstevel@tonic-gate len -= COUNTER_PAIR;
22247c478bd9Sstevel@tonic-gate
22257c478bd9Sstevel@tonic-gate if (len < (COUNTER_PAIR + COUNTER_32BIT))
22267c478bd9Sstevel@tonic-gate return;
22277c478bd9Sstevel@tonic-gate (void) printf(gettext("Failed: "));
22287c478bd9Sstevel@tonic-gate PRSACNTS(sp->st_init_p1_noresp + sp->st_init_p1_respfail,
22297c478bd9Sstevel@tonic-gate sp->st_resp_p1_fail);
22307c478bd9Sstevel@tonic-gate (void) printf(
22317c478bd9Sstevel@tonic-gate gettext(" initiator fails include %u time-out(s)\n"),
22327c478bd9Sstevel@tonic-gate sp->st_init_p1_noresp);
22337c478bd9Sstevel@tonic-gate
22347c478bd9Sstevel@tonic-gate if (len < PATH_MAX)
22357c478bd9Sstevel@tonic-gate return;
22367c478bd9Sstevel@tonic-gate if (*(sp->st_pkcs11_libname) != '\0')
22377c478bd9Sstevel@tonic-gate (void) printf(gettext("PKCS#11 library linked in from %s\n"),
22387c478bd9Sstevel@tonic-gate sp->st_pkcs11_libname);
22397c478bd9Sstevel@tonic-gate }
22407c478bd9Sstevel@tonic-gate
2241510c3f91SVladimir Kotal /* Print one line of 'get defaults' output (i.e. single value). */
22420f2065ccSmarkfen static void
print_defaults(char * label,char * description,char * unit,uint_t current,uint_t def)2243510c3f91SVladimir Kotal print_defaults(char *label, char *description, char *unit,
22440f2065ccSmarkfen uint_t current, uint_t def)
22450f2065ccSmarkfen {
2246510c3f91SVladimir Kotal (void) printf("%-18s%-10s%11u %-10s%-26s\n", label,
22470f2065ccSmarkfen (current != def) ? gettext("config") : gettext("default"),
2248510c3f91SVladimir Kotal current, unit, description);
22490f2065ccSmarkfen }
22500f2065ccSmarkfen
22510f2065ccSmarkfen /*
22520f2065ccSmarkfen * Print out defaults used by in.iked, the argument is a buffer containing
22530f2065ccSmarkfen * two ike_defaults_t's, the first contains the hard coded defaults, the second
22540f2065ccSmarkfen * contains the actual values used. If these differ, then the defaults have been
22550f2065ccSmarkfen * changed via a config file entry. Note that "-" indicates this default
2256bbf21555SRichard Lowe * is not tunable via ike.config(5) or is system wide tunable.
22570f2065ccSmarkfen */
22580f2065ccSmarkfen static void
do_print_defaults(ike_defaults_t * dp)22590f2065ccSmarkfen do_print_defaults(ike_defaults_t *dp)
22600f2065ccSmarkfen {
22610f2065ccSmarkfen ike_defaults_t *ddp;
22620f2065ccSmarkfen ddp = (ike_defaults_t *)(dp + 1);
22630f2065ccSmarkfen
22640f2065ccSmarkfen (void) printf(gettext("\nGlobal defaults. Some values can be"
2265510c3f91SVladimir Kotal " over-ridden on a per rule basis.\n"));
2266510c3f91SVladimir Kotal (void) printf(gettext("\nSystem defaults are time delayed.\n\n"));
22670f2065ccSmarkfen
2268510c3f91SVladimir Kotal (void) printf("%-18s%-10s%-12s%-10s%-26s\n\n",
22690f2065ccSmarkfen gettext("Token:"), gettext("Source:"), gettext("Value:"),
22700f2065ccSmarkfen gettext("Unit:"), gettext("Description:"));
22710f2065ccSmarkfen
2272510c3f91SVladimir Kotal /* iked tunables */
22730f2065ccSmarkfen print_defaults("p1_lifetime_secs", gettext("phase 1 lifetime"),
2274510c3f91SVladimir Kotal gettext("seconds"), ddp->rule_p1_lifetime_secs,
22750f2065ccSmarkfen dp->rule_p1_lifetime_secs);
22760f2065ccSmarkfen
22770f2065ccSmarkfen print_defaults("-", gettext("minimum phase 1 lifetime"),
2278510c3f91SVladimir Kotal gettext("seconds"), ddp->rule_p1_minlife,
22790f2065ccSmarkfen dp->rule_p1_minlife);
22800f2065ccSmarkfen
22810f2065ccSmarkfen print_defaults("p1_nonce_len", gettext("phase 1 nonce length"),
2282510c3f91SVladimir Kotal gettext("bytes"), ddp->rule_p1_nonce_len,
22830f2065ccSmarkfen dp->rule_p1_nonce_len);
22840f2065ccSmarkfen
22850f2065ccSmarkfen print_defaults("p2_lifetime_secs", gettext("phase 2 lifetime"),
2286510c3f91SVladimir Kotal gettext("seconds"), ddp->rule_p2_lifetime_secs,
22870f2065ccSmarkfen dp->rule_p2_lifetime_secs);
22880f2065ccSmarkfen
22890f2065ccSmarkfen print_defaults("p2_softlife_secs", gettext("phase 2 soft lifetime"),
2290510c3f91SVladimir Kotal gettext("seconds"), ddp->rule_p2_softlife_secs,
22910f2065ccSmarkfen dp->rule_p2_softlife_secs);
22920f2065ccSmarkfen
22939c2c14abSThejaswini Singarajipura print_defaults("p2_idletime_secs", gettext("phase 2 idle time"),
2294510c3f91SVladimir Kotal gettext("seconds"), ddp->rule_p2_idletime_secs,
22959c2c14abSThejaswini Singarajipura dp->rule_p2_idletime_secs);
22969c2c14abSThejaswini Singarajipura
2297510c3f91SVladimir Kotal print_defaults("p2_lifetime_kb", gettext("phase 2 lifetime"),
2298510c3f91SVladimir Kotal gettext("kilobytes"), ddp->rule_p2_lifetime_kb,
2299510c3f91SVladimir Kotal dp->rule_p2_lifetime_kb);
2300510c3f91SVladimir Kotal
2301510c3f91SVladimir Kotal print_defaults("p2_softlife_kb", gettext("phase 2 soft lifetime"),
2302510c3f91SVladimir Kotal gettext("kilobytes"), ddp->rule_p2_softlife_kb,
2303510c3f91SVladimir Kotal dp->rule_p2_softlife_kb);
2304510c3f91SVladimir Kotal
2305510c3f91SVladimir Kotal /* system wide tunables */
23061a6921e0Smarkfen print_defaults("-", gettext("system phase 2 lifetime"),
2307510c3f91SVladimir Kotal gettext("seconds"), ddp->sys_p2_lifetime_secs,
23081a6921e0Smarkfen dp->sys_p2_lifetime_secs);
23091a6921e0Smarkfen
23101a6921e0Smarkfen print_defaults("-", gettext("system phase 2 soft lifetime"),
2311510c3f91SVladimir Kotal gettext("seconds"), ddp->sys_p2_softlife_secs,
23121a6921e0Smarkfen dp->sys_p2_softlife_secs);
23131a6921e0Smarkfen
23149c2c14abSThejaswini Singarajipura print_defaults("-", gettext("system phase 2 idle time"),
2315510c3f91SVladimir Kotal gettext("seconds"), ddp->sys_p2_idletime_secs,
23169c2c14abSThejaswini Singarajipura dp->sys_p2_idletime_secs);
23179c2c14abSThejaswini Singarajipura
23181a6921e0Smarkfen print_defaults("-", gettext("system phase 2 lifetime"),
2319510c3f91SVladimir Kotal gettext("bytes"), ddp->sys_p2_lifetime_bytes,
23201a6921e0Smarkfen dp->sys_p2_lifetime_bytes);
23211a6921e0Smarkfen
23221a6921e0Smarkfen print_defaults("-", gettext("system phase 2 soft lifetime"),
2323510c3f91SVladimir Kotal gettext("bytes"), ddp->sys_p2_softlife_bytes,
23241a6921e0Smarkfen dp->sys_p2_softlife_bytes);
23251a6921e0Smarkfen
2326510c3f91SVladimir Kotal /* minimum and maximum values */
2327510c3f91SVladimir Kotal print_defaults("-", gettext("minimum phase 2 hard lifetime"),
2328510c3f91SVladimir Kotal gettext("seconds"), ddp->rule_p2_minlife_hard_secs,
2329510c3f91SVladimir Kotal dp->rule_p2_minlife_hard_secs);
23300f2065ccSmarkfen
2331510c3f91SVladimir Kotal print_defaults("-", gettext("minimum phase 2 soft lifetime"),
2332510c3f91SVladimir Kotal gettext("seconds"), ddp->rule_p2_minlife_soft_secs,
2333510c3f91SVladimir Kotal dp->rule_p2_minlife_soft_secs);
2334510c3f91SVladimir Kotal
2335510c3f91SVladimir Kotal print_defaults("-", gettext("minimum phase 2 idle lifetime"),
2336510c3f91SVladimir Kotal gettext("seconds"), ddp->rule_p2_minlife_idle_secs,
2337510c3f91SVladimir Kotal dp->rule_p2_minlife_idle_secs);
23380f2065ccSmarkfen
2339510c3f91SVladimir Kotal print_defaults("-", gettext("minimum phase 2 hard lifetime"),
2340510c3f91SVladimir Kotal gettext("kilobytes"), ddp->rule_p2_minlife_hard_kb,
2341510c3f91SVladimir Kotal dp->rule_p2_minlife_hard_kb);
23420f2065ccSmarkfen
2343510c3f91SVladimir Kotal print_defaults("-", gettext("minimum phase 2 soft lifetime"),
2344510c3f91SVladimir Kotal gettext("kilobytes"), ddp->rule_p2_minlife_soft_kb,
2345510c3f91SVladimir Kotal dp->rule_p2_minlife_soft_kb);
2346510c3f91SVladimir Kotal
2347510c3f91SVladimir Kotal print_defaults("-", gettext("minimum phase 2 delta"),
2348510c3f91SVladimir Kotal gettext("seconds"), ddp->rule_p2_mindiff_secs,
2349510c3f91SVladimir Kotal dp->rule_p2_mindiff_secs);
2350510c3f91SVladimir Kotal
2351510c3f91SVladimir Kotal print_defaults("-", gettext("minimum phase 2 delta"),
2352510c3f91SVladimir Kotal gettext("kilobytes"), ddp->rule_p2_mindiff_kb,
2353510c3f91SVladimir Kotal dp->rule_p2_mindiff_kb);
2354510c3f91SVladimir Kotal
2355510c3f91SVladimir Kotal print_defaults("-", gettext("maximum phase 2 lifetime"),
2356510c3f91SVladimir Kotal gettext("seconds"), ddp->rule_p2_maxlife_secs,
2357510c3f91SVladimir Kotal dp->rule_p2_maxlife_secs);
2358510c3f91SVladimir Kotal
2359510c3f91SVladimir Kotal print_defaults("-", gettext("conversion factor"),
2360510c3f91SVladimir Kotal gettext("kbytes/s"), ddp->conversion_factor,
2361510c3f91SVladimir Kotal dp->conversion_factor);
2362510c3f91SVladimir Kotal
2363510c3f91SVladimir Kotal print_defaults("-", gettext("maximum phase 2 lifetime"),
2364510c3f91SVladimir Kotal gettext("kilobytes"), ddp->rule_p2_maxlife_kb,
2365510c3f91SVladimir Kotal dp->rule_p2_maxlife_kb);
2366510c3f91SVladimir Kotal
2367510c3f91SVladimir Kotal /* other values */
2368510c3f91SVladimir Kotal print_defaults("p2_nonce_len", gettext("phase 2 nonce length"),
2369510c3f91SVladimir Kotal gettext("bytes"), ddp->rule_p2_nonce_len,
2370510c3f91SVladimir Kotal dp->rule_p2_nonce_len);
23710f2065ccSmarkfen
23720f2065ccSmarkfen print_defaults("p2_pfs", gettext("phase 2 PFS"),
2373510c3f91SVladimir Kotal " ", ddp->rule_p2_pfs, dp->rule_p2_pfs);
23740f2065ccSmarkfen
23750f2065ccSmarkfen print_defaults("max_certs", gettext("max certificates"),
2376510c3f91SVladimir Kotal " ", ddp->rule_max_certs, dp->rule_max_certs);
23770f2065ccSmarkfen
23780f2065ccSmarkfen print_defaults("-", gettext("IKE port number"),
2379510c3f91SVladimir Kotal " ", ddp->rule_ike_port, dp->rule_ike_port);
23800f2065ccSmarkfen
23810f2065ccSmarkfen print_defaults("-", gettext("NAT-T port number"),
2382510c3f91SVladimir Kotal " ", ddp->rule_natt_port, dp->rule_natt_port);
23830f2065ccSmarkfen }
23840f2065ccSmarkfen
23857c478bd9Sstevel@tonic-gate static void
print_categories(int level)23867c478bd9Sstevel@tonic-gate print_categories(int level)
23877c478bd9Sstevel@tonic-gate {
23887c478bd9Sstevel@tonic-gate int mask;
23897c478bd9Sstevel@tonic-gate
23907c478bd9Sstevel@tonic-gate if (level == 0) {
23917c478bd9Sstevel@tonic-gate (void) printf(gettext("No debug categories enabled.\n"));
23927c478bd9Sstevel@tonic-gate return;
23937c478bd9Sstevel@tonic-gate }
23947c478bd9Sstevel@tonic-gate
23957c478bd9Sstevel@tonic-gate (void) printf(gettext("Debug categories enabled:"));
23967c478bd9Sstevel@tonic-gate for (mask = 1; mask <= D_HIGHBIT; mask <<= 1) {
23977c478bd9Sstevel@tonic-gate if (level & mask)
23987c478bd9Sstevel@tonic-gate (void) printf("\n\t%s", dbgstr(mask));
23997c478bd9Sstevel@tonic-gate }
24007c478bd9Sstevel@tonic-gate (void) printf("\n");
24017c478bd9Sstevel@tonic-gate }
24027c478bd9Sstevel@tonic-gate
24037c478bd9Sstevel@tonic-gate /*PRINTFLIKE2*/
24047c478bd9Sstevel@tonic-gate static void
ikeadm_err_exit(ike_err_t * err,char * fmt,...)24057c478bd9Sstevel@tonic-gate ikeadm_err_exit(ike_err_t *err, char *fmt, ...)
24067c478bd9Sstevel@tonic-gate {
24077c478bd9Sstevel@tonic-gate va_list ap;
24087c478bd9Sstevel@tonic-gate char bailbuf[BUFSIZ];
24097c478bd9Sstevel@tonic-gate
24107c478bd9Sstevel@tonic-gate va_start(ap, fmt);
24117c478bd9Sstevel@tonic-gate (void) vsnprintf(bailbuf, BUFSIZ, fmt, ap);
24127c478bd9Sstevel@tonic-gate va_end(ap);
24137c478bd9Sstevel@tonic-gate if ((err != NULL) && (err->ike_err == IKE_ERR_SYS_ERR)) {
24147c478bd9Sstevel@tonic-gate bail_msg("%s: %s", bailbuf, (err->ike_err_unix == 0) ?
24157c478bd9Sstevel@tonic-gate gettext("<unknown error>") : strerror(err->ike_err_unix));
24167c478bd9Sstevel@tonic-gate } else {
24177c478bd9Sstevel@tonic-gate bail_msg("%s: %s", bailbuf, (err == NULL) ?
24187c478bd9Sstevel@tonic-gate gettext("<unknown error>") : errstr(err->ike_err));
24197c478bd9Sstevel@tonic-gate }
24207c478bd9Sstevel@tonic-gate }
24217c478bd9Sstevel@tonic-gate
24227c478bd9Sstevel@tonic-gate /*PRINTFLIKE2*/
24237c478bd9Sstevel@tonic-gate static void
ikeadm_err_msg(ike_err_t * err,char * fmt,...)24247c478bd9Sstevel@tonic-gate ikeadm_err_msg(ike_err_t *err, char *fmt, ...)
24257c478bd9Sstevel@tonic-gate {
24267c478bd9Sstevel@tonic-gate va_list ap;
24277c478bd9Sstevel@tonic-gate char mbuf[BUFSIZ];
24287c478bd9Sstevel@tonic-gate
24297c478bd9Sstevel@tonic-gate va_start(ap, fmt);
24307c478bd9Sstevel@tonic-gate (void) vsnprintf(mbuf, BUFSIZ, fmt, ap);
24317c478bd9Sstevel@tonic-gate va_end(ap);
24327c478bd9Sstevel@tonic-gate if ((err != NULL) && (err->ike_err == IKE_ERR_SYS_ERR)) {
24337c478bd9Sstevel@tonic-gate message("%s: %s", mbuf, (err->ike_err_unix == 0) ?
243415b07f80Spwernau gettext("<unknown error>") :
243515b07f80Spwernau ((err->ike_err_unix == EEXIST) ?
243615b07f80Spwernau gettext("Duplicate entry") :
243715b07f80Spwernau strerror(err->ike_err_unix)));
24387c478bd9Sstevel@tonic-gate } else {
24397c478bd9Sstevel@tonic-gate message("%s: %s", mbuf, (err == NULL) ?
24407c478bd9Sstevel@tonic-gate gettext("<unknown error>") : errstr(err->ike_err));
24417c478bd9Sstevel@tonic-gate }
24427c478bd9Sstevel@tonic-gate }
24437c478bd9Sstevel@tonic-gate
24447c478bd9Sstevel@tonic-gate
24457c478bd9Sstevel@tonic-gate /*
24467c478bd9Sstevel@tonic-gate * Command functions
24477c478bd9Sstevel@tonic-gate */
24487c478bd9Sstevel@tonic-gate
24497c478bd9Sstevel@tonic-gate /*
24507c478bd9Sstevel@tonic-gate * Exploit the fact that ike_dbg_t and ike_priv_t have identical
24517c478bd9Sstevel@tonic-gate * formats in the following two functions.
24527c478bd9Sstevel@tonic-gate */
24537c478bd9Sstevel@tonic-gate static void
do_getvar(int cmd)24547c478bd9Sstevel@tonic-gate do_getvar(int cmd)
24557c478bd9Sstevel@tonic-gate {
24567c478bd9Sstevel@tonic-gate ike_service_t req, *rtn;
24577c478bd9Sstevel@tonic-gate ike_dbg_t *dreq;
24587c478bd9Sstevel@tonic-gate char *varname;
24597c478bd9Sstevel@tonic-gate
24607c478bd9Sstevel@tonic-gate switch (cmd) {
24617c478bd9Sstevel@tonic-gate case IKE_SVC_GET_DBG:
24627c478bd9Sstevel@tonic-gate varname = gettext("debug");
24637c478bd9Sstevel@tonic-gate break;
24647c478bd9Sstevel@tonic-gate case IKE_SVC_GET_PRIV:
24657c478bd9Sstevel@tonic-gate varname = gettext("privilege");
24667c478bd9Sstevel@tonic-gate break;
24677c478bd9Sstevel@tonic-gate default:
24687c478bd9Sstevel@tonic-gate bail_msg(gettext("unrecognized get command (%d)"), cmd);
24697c478bd9Sstevel@tonic-gate }
24707c478bd9Sstevel@tonic-gate
24717c478bd9Sstevel@tonic-gate dreq = &req.svc_dbg;
24727c478bd9Sstevel@tonic-gate dreq->cmd = cmd;
24737c478bd9Sstevel@tonic-gate dreq->dbg_level = 0;
24747c478bd9Sstevel@tonic-gate
24757c478bd9Sstevel@tonic-gate rtn = ikedoor_call((char *)&req, sizeof (ike_dbg_t), NULL, 0);
24767c478bd9Sstevel@tonic-gate
24777c478bd9Sstevel@tonic-gate if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) {
24787c478bd9Sstevel@tonic-gate ikeadm_err_exit(&rtn->svc_err,
24797c478bd9Sstevel@tonic-gate gettext("error getting %s level"), varname);
24807c478bd9Sstevel@tonic-gate }
24817c478bd9Sstevel@tonic-gate dreq = &rtn->svc_dbg;
24827c478bd9Sstevel@tonic-gate (void) printf(gettext("Current %s level is 0x%x"),
24837c478bd9Sstevel@tonic-gate varname, dreq->dbg_level);
24847c478bd9Sstevel@tonic-gate
24857c478bd9Sstevel@tonic-gate if (cmd == IKE_SVC_GET_DBG) {
24867c478bd9Sstevel@tonic-gate (void) printf("\n");
24877c478bd9Sstevel@tonic-gate print_categories(dreq->dbg_level);
24887c478bd9Sstevel@tonic-gate } else {
24897c478bd9Sstevel@tonic-gate (void) printf(gettext(", %s enabled\n"),
24907c478bd9Sstevel@tonic-gate privstr(dreq->dbg_level));
24917c478bd9Sstevel@tonic-gate }
24927c478bd9Sstevel@tonic-gate }
24937c478bd9Sstevel@tonic-gate
2494c7777ac8SPaul Wernau /*
2495c7777ac8SPaul Wernau * Log into a token and unlock all objects
2496c7777ac8SPaul Wernau * referenced by PKCS#11 hint files.
2497c7777ac8SPaul Wernau */
2498c7777ac8SPaul Wernau static void
do_setdel_pin(int cmd,int argc,char ** argv)2499c7777ac8SPaul Wernau do_setdel_pin(int cmd, int argc, char **argv)
2500c7777ac8SPaul Wernau {
2501c7777ac8SPaul Wernau ike_service_t req, *rtn;
2502c7777ac8SPaul Wernau ike_pin_t *preq;
2503c7777ac8SPaul Wernau char token_label[PKCS11_TOKSIZE];
2504c7777ac8SPaul Wernau char *token_pin;
2505c7777ac8SPaul Wernau char prompt[80];
2506c7777ac8SPaul Wernau
2507c7777ac8SPaul Wernau if (argc < 1)
2508c7777ac8SPaul Wernau Bail(gettext("Must specify PKCS#11 token object."));
2509c7777ac8SPaul Wernau
2510c7777ac8SPaul Wernau preq = &req.svc_pin;
2511c7777ac8SPaul Wernau preq->cmd = cmd;
2512c7777ac8SPaul Wernau
2513c7777ac8SPaul Wernau switch (cmd) {
2514c7777ac8SPaul Wernau case IKE_SVC_SET_PIN:
2515c7777ac8SPaul Wernau if (parse_token(argc, argv, token_label) != 0)
2516c7777ac8SPaul Wernau Bail("Invalid syntax for \"token login\"");
2517c7777ac8SPaul Wernau (void) snprintf(prompt, sizeof (prompt),
2518c7777ac8SPaul Wernau "Enter PIN for PKCS#11 token \'%s\': ", token_label);
2519c7777ac8SPaul Wernau token_pin =
2520c7777ac8SPaul Wernau getpassphrase(prompt);
2521c7777ac8SPaul Wernau (void) strlcpy((char *)preq->token_pin, token_pin, MAX_PIN_LEN);
2522c7777ac8SPaul Wernau bzero(token_pin, strlen(token_pin));
2523c7777ac8SPaul Wernau break;
2524c7777ac8SPaul Wernau case IKE_SVC_DEL_PIN:
2525c7777ac8SPaul Wernau if (parse_token(argc, argv, token_label) != 0)
2526c7777ac8SPaul Wernau Bail("Invalid syntax for \"token logout\"");
2527c7777ac8SPaul Wernau break;
2528c7777ac8SPaul Wernau default:
2529c7777ac8SPaul Wernau bail_msg(gettext("unrecognized token command (%d)"), cmd);
2530c7777ac8SPaul Wernau }
2531c7777ac8SPaul Wernau
2532c7777ac8SPaul Wernau (void) strlcpy(preq->pkcs11_token, token_label, PKCS11_TOKSIZE);
2533c7777ac8SPaul Wernau
2534c7777ac8SPaul Wernau rtn = ikedoor_call((char *)&req, sizeof (ike_pin_t), NULL, 0);
2535c7777ac8SPaul Wernau if (cmd == IKE_SVC_SET_PIN)
2536c7777ac8SPaul Wernau bzero(preq->token_pin, sizeof (preq->token_pin));
2537c7777ac8SPaul Wernau
2538c7777ac8SPaul Wernau if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) {
2539c7777ac8SPaul Wernau ikeadm_err_exit(&rtn->svc_err,
2540c7777ac8SPaul Wernau gettext("PKCS#11 operation"));
2541c7777ac8SPaul Wernau }
2542c7777ac8SPaul Wernau preq = &rtn->svc_pin;
2543c7777ac8SPaul Wernau message(gettext("PKCS#11 operation successful"));
2544c7777ac8SPaul Wernau }
2545c7777ac8SPaul Wernau
25467c478bd9Sstevel@tonic-gate static void
do_setvar(int cmd,int argc,char ** argv)25477c478bd9Sstevel@tonic-gate do_setvar(int cmd, int argc, char **argv)
25487c478bd9Sstevel@tonic-gate {
25497c478bd9Sstevel@tonic-gate ike_service_t req, *rtn;
25507c478bd9Sstevel@tonic-gate ike_dbg_t *dreq;
25517c478bd9Sstevel@tonic-gate door_desc_t *descp = NULL, desc;
25527c478bd9Sstevel@tonic-gate int fd, ndesc = 0;
25537c478bd9Sstevel@tonic-gate uint32_t reqlevel;
25547c478bd9Sstevel@tonic-gate char *varname;
25557c478bd9Sstevel@tonic-gate
25567c478bd9Sstevel@tonic-gate if (argc < 1)
25577c478bd9Sstevel@tonic-gate Bail("unspecified level");
25587c478bd9Sstevel@tonic-gate reqlevel = strtoul(argv[0], NULL, 0);
25597c478bd9Sstevel@tonic-gate
25607c478bd9Sstevel@tonic-gate switch (cmd) {
25617c478bd9Sstevel@tonic-gate case IKE_SVC_SET_DBG:
25627c478bd9Sstevel@tonic-gate if (argc > 2)
25637c478bd9Sstevel@tonic-gate Bail("Too many arguments to \"set debug\"");
25647c478bd9Sstevel@tonic-gate varname = gettext("debug");
25657c478bd9Sstevel@tonic-gate if (reqlevel == 0) {
25667c478bd9Sstevel@tonic-gate /* check for a string... */
25677c478bd9Sstevel@tonic-gate reqlevel = parsedbgopts(argv[0]);
25687c478bd9Sstevel@tonic-gate }
25697c478bd9Sstevel@tonic-gate if (reqlevel == D_INVALID)
25707c478bd9Sstevel@tonic-gate bail_msg(gettext("Bad debug flag: %s"), argv[0]);
25717c478bd9Sstevel@tonic-gate break;
25727c478bd9Sstevel@tonic-gate case IKE_SVC_SET_PRIV:
25737c478bd9Sstevel@tonic-gate if (argc > 1)
25747c478bd9Sstevel@tonic-gate Bail("Too many arguments to \"set priv\"");
25757c478bd9Sstevel@tonic-gate
25767c478bd9Sstevel@tonic-gate varname = gettext("privilege");
25777c478bd9Sstevel@tonic-gate if (reqlevel == 0) {
25787c478bd9Sstevel@tonic-gate /* check for a string... */
25797c478bd9Sstevel@tonic-gate reqlevel = privstr2num(argv[0]);
25807c478bd9Sstevel@tonic-gate }
25817c478bd9Sstevel@tonic-gate if (reqlevel > IKE_PRIV_MAXIMUM)
25827c478bd9Sstevel@tonic-gate bail_msg(gettext("Bad privilege flag: %s"), argv[0]);
25837c478bd9Sstevel@tonic-gate break;
25847c478bd9Sstevel@tonic-gate default:
25857c478bd9Sstevel@tonic-gate bail_msg(gettext("unrecognized set command (%d)"), cmd);
25867c478bd9Sstevel@tonic-gate }
25877c478bd9Sstevel@tonic-gate
25887c478bd9Sstevel@tonic-gate dreq = &req.svc_dbg;
25897c478bd9Sstevel@tonic-gate dreq->cmd = cmd;
25907c478bd9Sstevel@tonic-gate dreq->dbg_level = reqlevel;
25917c478bd9Sstevel@tonic-gate
25927c478bd9Sstevel@tonic-gate if ((argc == 2) && (cmd == IKE_SVC_SET_DBG)) {
25937c478bd9Sstevel@tonic-gate fd = open(argv[1], O_RDWR | O_CREAT | O_APPEND,
25947c478bd9Sstevel@tonic-gate S_IRUSR | S_IWUSR);
25957c478bd9Sstevel@tonic-gate if (fd < 0)
25967c478bd9Sstevel@tonic-gate Bail("open debug file");
25977c478bd9Sstevel@tonic-gate desc.d_data.d_desc.d_descriptor = fd;
25987c478bd9Sstevel@tonic-gate desc.d_attributes = DOOR_DESCRIPTOR;
25997c478bd9Sstevel@tonic-gate descp = &desc;
26007c478bd9Sstevel@tonic-gate ndesc = 1;
26017c478bd9Sstevel@tonic-gate }
26027c478bd9Sstevel@tonic-gate
26037c478bd9Sstevel@tonic-gate rtn = ikedoor_call((char *)&req, sizeof (ike_dbg_t), descp, ndesc);
26047c478bd9Sstevel@tonic-gate
26057c478bd9Sstevel@tonic-gate if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) {
26067c478bd9Sstevel@tonic-gate ikeadm_err_exit(&rtn->svc_err,
26077c478bd9Sstevel@tonic-gate gettext("error setting %s level"), varname);
26087c478bd9Sstevel@tonic-gate }
26097c478bd9Sstevel@tonic-gate dreq = &rtn->svc_dbg;
26107c478bd9Sstevel@tonic-gate (void) printf(
26117c478bd9Sstevel@tonic-gate gettext("Successfully changed %s level from 0x%x to 0x%x\n"),
26127c478bd9Sstevel@tonic-gate varname, dreq->dbg_level, reqlevel);
26137c478bd9Sstevel@tonic-gate
26147c478bd9Sstevel@tonic-gate if (cmd == IKE_SVC_SET_DBG) {
26157c478bd9Sstevel@tonic-gate print_categories(reqlevel);
26167c478bd9Sstevel@tonic-gate } else {
26177c478bd9Sstevel@tonic-gate (void) printf(gettext("New privilege level 0x%x enables %s\n"),
26187c478bd9Sstevel@tonic-gate reqlevel, privstr(reqlevel));
26197c478bd9Sstevel@tonic-gate }
26207c478bd9Sstevel@tonic-gate }
26217c478bd9Sstevel@tonic-gate
26227c478bd9Sstevel@tonic-gate static void
do_getstats(int cmd)26237c478bd9Sstevel@tonic-gate do_getstats(int cmd)
26247c478bd9Sstevel@tonic-gate {
26257c478bd9Sstevel@tonic-gate ike_service_t *rtn;
26267c478bd9Sstevel@tonic-gate ike_statreq_t sreq, *sreqp;
26277c478bd9Sstevel@tonic-gate ike_stats_t *sp;
26287c478bd9Sstevel@tonic-gate
26297c478bd9Sstevel@tonic-gate sreq.cmd = cmd;
26307c478bd9Sstevel@tonic-gate
26317c478bd9Sstevel@tonic-gate rtn = ikedoor_call((char *)&sreq, sizeof (ike_statreq_t), NULL, 0);
26327c478bd9Sstevel@tonic-gate if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) {
26337c478bd9Sstevel@tonic-gate ikeadm_err_exit(&rtn->svc_err, gettext("error getting stats"));
26347c478bd9Sstevel@tonic-gate }
26357c478bd9Sstevel@tonic-gate
26367c478bd9Sstevel@tonic-gate sreqp = &rtn->svc_stats;
26377c478bd9Sstevel@tonic-gate sp = (ike_stats_t *)(sreqp + 1);
26387c478bd9Sstevel@tonic-gate print_stats(sp, sreqp->stat_len);
26397c478bd9Sstevel@tonic-gate }
26407c478bd9Sstevel@tonic-gate
26410f2065ccSmarkfen static void
do_getdefs(int cmd)26420f2065ccSmarkfen do_getdefs(int cmd)
26430f2065ccSmarkfen {
26440f2065ccSmarkfen ike_service_t *rtn;
26450f2065ccSmarkfen ike_defreq_t dreq, *dreqp;
26460f2065ccSmarkfen ike_defaults_t *dp;
26470f2065ccSmarkfen
26480f2065ccSmarkfen dreq.cmd = cmd;
26490f2065ccSmarkfen
26500f2065ccSmarkfen rtn = ikedoor_call((char *)&dreq, sizeof (ike_defreq_t), NULL, 0);
26510f2065ccSmarkfen if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) {
26520f2065ccSmarkfen ikeadm_err_exit(&rtn->svc_err,
26530f2065ccSmarkfen gettext("error getting defaults"));
26540f2065ccSmarkfen }
26550f2065ccSmarkfen
26560f2065ccSmarkfen dreqp = &rtn->svc_defaults;
26570f2065ccSmarkfen dp = (ike_defaults_t *)(dreqp + 1);
26580f2065ccSmarkfen
26590f2065ccSmarkfen /*
26600f2065ccSmarkfen * Before printing each line, make sure the structure we were
26610f2065ccSmarkfen * given is big enough to include the fields needed.
26620f2065ccSmarkfen * Silently bail out of there is a version mismatch.
26630f2065ccSmarkfen */
26640f2065ccSmarkfen if (dreqp->stat_len < ((2 * sizeof (ike_defaults_t))
26650f2065ccSmarkfen + sizeof (ike_defreq_t)) || dreqp->version != DOORVER) {
26660f2065ccSmarkfen return;
26670f2065ccSmarkfen }
26680f2065ccSmarkfen do_print_defaults(dp);
26690f2065ccSmarkfen }
26700f2065ccSmarkfen
26717c478bd9Sstevel@tonic-gate static void
do_dump(int cmd)26727c478bd9Sstevel@tonic-gate do_dump(int cmd)
26737c478bd9Sstevel@tonic-gate {
26747c478bd9Sstevel@tonic-gate char *name;
26757c478bd9Sstevel@tonic-gate ike_service_t req, *rtn;
26767c478bd9Sstevel@tonic-gate ike_dump_t *dreq, *dump;
26777c478bd9Sstevel@tonic-gate
26787c478bd9Sstevel@tonic-gate switch (cmd) {
26797c478bd9Sstevel@tonic-gate case IKE_SVC_DUMP_P1S:
26807c478bd9Sstevel@tonic-gate name = gettext("phase 1 SA info");
26817c478bd9Sstevel@tonic-gate break;
26827c478bd9Sstevel@tonic-gate case IKE_SVC_DUMP_RULES:
26837c478bd9Sstevel@tonic-gate name = gettext("policy rules");
26847c478bd9Sstevel@tonic-gate break;
26857c478bd9Sstevel@tonic-gate case IKE_SVC_DUMP_PS:
26867c478bd9Sstevel@tonic-gate name = gettext("preshared keys");
26877c478bd9Sstevel@tonic-gate break;
2688c7777ac8SPaul Wernau case IKE_SVC_DUMP_CERTCACHE:
2689c7777ac8SPaul Wernau name = gettext("certcache");
2690c7777ac8SPaul Wernau break;
26915d01c172SVladimir Kotal case IKE_SVC_DUMP_GROUPS:
26925d01c172SVladimir Kotal name = gettext("groups");
26935d01c172SVladimir Kotal print_group_header();
26945d01c172SVladimir Kotal break;
26955d01c172SVladimir Kotal case IKE_SVC_DUMP_ENCRALGS:
26965d01c172SVladimir Kotal name = gettext("encralgs");
26975d01c172SVladimir Kotal print_encralg_header();
26985d01c172SVladimir Kotal break;
26995d01c172SVladimir Kotal case IKE_SVC_DUMP_AUTHALGS:
27005d01c172SVladimir Kotal name = gettext("authalgs");
27015d01c172SVladimir Kotal print_authalg_header();
27025d01c172SVladimir Kotal break;
27037c478bd9Sstevel@tonic-gate default:
27047c478bd9Sstevel@tonic-gate bail_msg(gettext("unrecognized dump command (%d)"), cmd);
27057c478bd9Sstevel@tonic-gate }
27067c478bd9Sstevel@tonic-gate
27077c478bd9Sstevel@tonic-gate dreq = &req.svc_dump;
27087c478bd9Sstevel@tonic-gate dreq->cmd = cmd;
27097c478bd9Sstevel@tonic-gate dreq->dump_len = 0;
27107c478bd9Sstevel@tonic-gate dreq->dump_next = 0;
27117c478bd9Sstevel@tonic-gate do {
27127c478bd9Sstevel@tonic-gate rtn = ikedoor_call((char *)&req, sizeof (ike_dump_t),
27137c478bd9Sstevel@tonic-gate NULL, 0);
27147c478bd9Sstevel@tonic-gate if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) {
27157c478bd9Sstevel@tonic-gate if (rtn && (rtn->svc_err.ike_err == IKE_ERR_NO_OBJ)) {
27167c478bd9Sstevel@tonic-gate /* no entries to print */
27177c478bd9Sstevel@tonic-gate break;
27187c478bd9Sstevel@tonic-gate }
27197c478bd9Sstevel@tonic-gate ikeadm_err_exit(&rtn->svc_err,
27207c478bd9Sstevel@tonic-gate gettext("error getting %s"), name);
27217c478bd9Sstevel@tonic-gate }
27227c478bd9Sstevel@tonic-gate dump = &rtn->svc_dump;
27237c478bd9Sstevel@tonic-gate
27247c478bd9Sstevel@tonic-gate switch (cmd) {
27257c478bd9Sstevel@tonic-gate case IKE_SVC_DUMP_P1S:
27267c478bd9Sstevel@tonic-gate print_p1((ike_p1_sa_t *)(dump + 1));
27277c478bd9Sstevel@tonic-gate break;
27287c478bd9Sstevel@tonic-gate case IKE_SVC_DUMP_RULES:
27297c478bd9Sstevel@tonic-gate print_rule((ike_rule_t *)(dump + 1));
27307c478bd9Sstevel@tonic-gate break;
27317c478bd9Sstevel@tonic-gate case IKE_SVC_DUMP_PS:
27327c478bd9Sstevel@tonic-gate print_ps((ike_ps_t *)(dump + 1));
27337c478bd9Sstevel@tonic-gate break;
2734c7777ac8SPaul Wernau case IKE_SVC_DUMP_CERTCACHE:
2735c7777ac8SPaul Wernau print_certcache((ike_certcache_t *)(dump + 1));
2736c7777ac8SPaul Wernau break;
27375d01c172SVladimir Kotal case IKE_SVC_DUMP_GROUPS:
27385d01c172SVladimir Kotal print_group((ike_group_t *)(dump + 1));
27395d01c172SVladimir Kotal break;
27405d01c172SVladimir Kotal case IKE_SVC_DUMP_ENCRALGS:
27415d01c172SVladimir Kotal print_encralg((ike_encralg_t *)(dump + 1));
27425d01c172SVladimir Kotal break;
27435d01c172SVladimir Kotal case IKE_SVC_DUMP_AUTHALGS:
27445d01c172SVladimir Kotal print_authalg((ike_authalg_t *)(dump + 1));
27455d01c172SVladimir Kotal break;
27467c478bd9Sstevel@tonic-gate }
27477c478bd9Sstevel@tonic-gate
27487c478bd9Sstevel@tonic-gate dreq->dump_next = dump->dump_next;
27497c478bd9Sstevel@tonic-gate
27507c478bd9Sstevel@tonic-gate (void) munmap((char *)rtn, dump->dump_len);
27517c478bd9Sstevel@tonic-gate
27527c478bd9Sstevel@tonic-gate } while (dreq->dump_next);
27537c478bd9Sstevel@tonic-gate
27547c478bd9Sstevel@tonic-gate (void) printf(gettext("\nCompleted dump of %s\n"), name);
27557c478bd9Sstevel@tonic-gate }
27567c478bd9Sstevel@tonic-gate
27577c478bd9Sstevel@tonic-gate static void
do_getdel_doorcall(int cmd,int idlen,int idtype,char * idp,char * name)27587c478bd9Sstevel@tonic-gate do_getdel_doorcall(int cmd, int idlen, int idtype, char *idp, char *name)
27597c478bd9Sstevel@tonic-gate {
27607c478bd9Sstevel@tonic-gate int totallen;
27617c478bd9Sstevel@tonic-gate char *p;
27627c478bd9Sstevel@tonic-gate ike_service_t *reqp, *rtnp;
27637c478bd9Sstevel@tonic-gate ike_get_t *getp;
27647c478bd9Sstevel@tonic-gate boolean_t getcmd;
27657c478bd9Sstevel@tonic-gate
27667c478bd9Sstevel@tonic-gate getcmd = ((cmd == IKE_SVC_GET_P1) || (cmd == IKE_SVC_GET_RULE) ||
27677c478bd9Sstevel@tonic-gate (cmd == IKE_SVC_GET_PS));
27687c478bd9Sstevel@tonic-gate
27697c478bd9Sstevel@tonic-gate /*
27707c478bd9Sstevel@tonic-gate * WARNING: to avoid being redundant, this code takes advantage
27717c478bd9Sstevel@tonic-gate * of the fact that the ike_get_t and ike_del_t structures are
27727c478bd9Sstevel@tonic-gate * identical (only the field names differ, their function and
27737c478bd9Sstevel@tonic-gate * size are the same). If for some reason those structures
27747c478bd9Sstevel@tonic-gate * change, this code will need to be re-written to accomodate
27757c478bd9Sstevel@tonic-gate * that difference.
27767c478bd9Sstevel@tonic-gate */
27777c478bd9Sstevel@tonic-gate totallen = sizeof (ike_get_t) + idlen;
27787c478bd9Sstevel@tonic-gate if ((reqp = (ike_service_t *)malloc(totallen)) == NULL)
27797c478bd9Sstevel@tonic-gate Bail("malloc(id)");
27807c478bd9Sstevel@tonic-gate
27817c478bd9Sstevel@tonic-gate getp = &reqp->svc_get;
27827c478bd9Sstevel@tonic-gate getp->cmd = cmd;
27837c478bd9Sstevel@tonic-gate getp->get_len = totallen;
27847c478bd9Sstevel@tonic-gate getp->get_idtype = idtype;
27857c478bd9Sstevel@tonic-gate p = (char *)(getp + 1);
27867c478bd9Sstevel@tonic-gate
27877c478bd9Sstevel@tonic-gate (void) memcpy(p, idp, idlen);
27887c478bd9Sstevel@tonic-gate
27897c478bd9Sstevel@tonic-gate rtnp = ikedoor_call((char *)reqp, totallen, NULL, 0);
27907c478bd9Sstevel@tonic-gate if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) {
27917c478bd9Sstevel@tonic-gate if (rtnp && (rtnp->svc_err.ike_err == IKE_ERR_NO_OBJ)) {
27927c478bd9Sstevel@tonic-gate message(gettext("Could not find requested %s."), name);
27937c478bd9Sstevel@tonic-gate } else {
27947c478bd9Sstevel@tonic-gate ikeadm_err_msg(&rtnp->svc_err, gettext("error %s %s"),
27957c478bd9Sstevel@tonic-gate (getcmd) ? gettext("getting") : gettext("deleting"),
27967c478bd9Sstevel@tonic-gate name);
27977c478bd9Sstevel@tonic-gate }
27987c478bd9Sstevel@tonic-gate free(reqp);
27997c478bd9Sstevel@tonic-gate return;
28007c478bd9Sstevel@tonic-gate }
28017c478bd9Sstevel@tonic-gate getp = &rtnp->svc_get;
28027c478bd9Sstevel@tonic-gate
28037c478bd9Sstevel@tonic-gate if (getcmd) {
28047c478bd9Sstevel@tonic-gate switch (cmd) {
28057c478bd9Sstevel@tonic-gate case IKE_SVC_GET_P1:
28067c478bd9Sstevel@tonic-gate print_p1((ike_p1_sa_t *)(getp + 1));
28077c478bd9Sstevel@tonic-gate break;
28087c478bd9Sstevel@tonic-gate case IKE_SVC_GET_PS:
28097c478bd9Sstevel@tonic-gate print_ps((ike_ps_t *)(getp + 1));
28107c478bd9Sstevel@tonic-gate break;
28117c478bd9Sstevel@tonic-gate case IKE_SVC_GET_RULE:
28127c478bd9Sstevel@tonic-gate print_rule((ike_rule_t *)(getp + 1));
28137c478bd9Sstevel@tonic-gate break;
28147c478bd9Sstevel@tonic-gate }
28157c478bd9Sstevel@tonic-gate } else {
28167c478bd9Sstevel@tonic-gate message(gettext("Successfully deleted selected %s."), name);
28177c478bd9Sstevel@tonic-gate }
28187c478bd9Sstevel@tonic-gate
28197c478bd9Sstevel@tonic-gate (void) munmap((char *)rtnp, getp->get_len);
28207c478bd9Sstevel@tonic-gate free(reqp);
28217c478bd9Sstevel@tonic-gate }
28227c478bd9Sstevel@tonic-gate
28237c478bd9Sstevel@tonic-gate static void
do_getdel(int cmd,int argc,char ** argv)28247c478bd9Sstevel@tonic-gate do_getdel(int cmd, int argc, char **argv)
28257c478bd9Sstevel@tonic-gate {
28267c478bd9Sstevel@tonic-gate int idlen, idtype = 0, i, j;
28277c478bd9Sstevel@tonic-gate int bytelen1, bytelen2;
28287c478bd9Sstevel@tonic-gate char *name, *idp, *p, *p1, *p2;
28297c478bd9Sstevel@tonic-gate ike_addr_pr_t apr;
28307c478bd9Sstevel@tonic-gate ike_cky_pr_t cpr;
28317c478bd9Sstevel@tonic-gate sadb_ident_t *sid1p, *sid2p;
28327c478bd9Sstevel@tonic-gate struct hostent *he1p, *he2p;
28337c478bd9Sstevel@tonic-gate char label[MAX_LABEL_LEN];
28347c478bd9Sstevel@tonic-gate
28357c478bd9Sstevel@tonic-gate if ((argc < 1) || (argv[0] == NULL)) {
28367c478bd9Sstevel@tonic-gate Bail("not enough identification info");
28377c478bd9Sstevel@tonic-gate }
28387c478bd9Sstevel@tonic-gate
28397c478bd9Sstevel@tonic-gate switch (cmd) {
28407c478bd9Sstevel@tonic-gate case IKE_SVC_GET_P1:
28417c478bd9Sstevel@tonic-gate case IKE_SVC_DEL_P1:
28427c478bd9Sstevel@tonic-gate name = gettext("phase 1 SA");
28437c478bd9Sstevel@tonic-gate /*
28447c478bd9Sstevel@tonic-gate * The first token must either be an address (or hostname)
28457c478bd9Sstevel@tonic-gate * or a cookie. We require cookies to be entered as hex
28467c478bd9Sstevel@tonic-gate * numbers, beginning with 0x; so if our token starts with
28477c478bd9Sstevel@tonic-gate * that, it's a cookie.
28487c478bd9Sstevel@tonic-gate */
28497c478bd9Sstevel@tonic-gate if (strncmp(argv[0], "0x", 2) == 0) {
28507c478bd9Sstevel@tonic-gate if (parse_cky_pr(argc, argv, &cpr) >= 0) {
28517c478bd9Sstevel@tonic-gate idtype = IKE_ID_CKY_PAIR;
28527c478bd9Sstevel@tonic-gate idlen = sizeof (ike_cky_pr_t);
28537c478bd9Sstevel@tonic-gate idp = (char *)&cpr;
28547c478bd9Sstevel@tonic-gate }
28557c478bd9Sstevel@tonic-gate } else {
28567c478bd9Sstevel@tonic-gate if (parse_addr_pr(argc, argv, &he1p, &he2p) >= 0) {
28577c478bd9Sstevel@tonic-gate idtype = IKE_ID_ADDR_PAIR;
28587c478bd9Sstevel@tonic-gate idlen = sizeof (ike_addr_pr_t);
28597c478bd9Sstevel@tonic-gate }
28607c478bd9Sstevel@tonic-gate }
28617c478bd9Sstevel@tonic-gate break;
28627c478bd9Sstevel@tonic-gate
28637c478bd9Sstevel@tonic-gate case IKE_SVC_GET_RULE:
28647c478bd9Sstevel@tonic-gate case IKE_SVC_DEL_RULE:
28657c478bd9Sstevel@tonic-gate name = gettext("policy rule");
28667c478bd9Sstevel@tonic-gate if (parse_label(argc, argv, label) >= 0) {
28677c478bd9Sstevel@tonic-gate idtype = IKE_ID_LABEL;
28687c478bd9Sstevel@tonic-gate idlen = MAX_LABEL_LEN;
28697c478bd9Sstevel@tonic-gate idp = label;
28707c478bd9Sstevel@tonic-gate }
28717c478bd9Sstevel@tonic-gate break;
28727c478bd9Sstevel@tonic-gate
28737c478bd9Sstevel@tonic-gate case IKE_SVC_GET_PS:
28747c478bd9Sstevel@tonic-gate case IKE_SVC_DEL_PS:
28757c478bd9Sstevel@tonic-gate name = gettext("preshared key");
28767c478bd9Sstevel@tonic-gate /*
28777c478bd9Sstevel@tonic-gate * The first token must either be an address or an ident
28787c478bd9Sstevel@tonic-gate * type. Check for an ident type to determine which it is.
28797c478bd9Sstevel@tonic-gate */
28807c478bd9Sstevel@tonic-gate if (parse_idtype(argv[0], NULL) >= 0) {
28817c478bd9Sstevel@tonic-gate if (parse_ident_pr(argc, argv, &sid1p, &sid2p) >= 0) {
28827c478bd9Sstevel@tonic-gate idtype = IKE_ID_IDENT_PAIR;
28837c478bd9Sstevel@tonic-gate idlen = SADB_64TO8(sid1p->sadb_ident_len) +
28847c478bd9Sstevel@tonic-gate SADB_64TO8(sid2p->sadb_ident_len);
28857c478bd9Sstevel@tonic-gate }
28867c478bd9Sstevel@tonic-gate } else {
28877c478bd9Sstevel@tonic-gate if (parse_addr_pr(argc, argv, &he1p, &he2p) >= 0) {
28887c478bd9Sstevel@tonic-gate idtype = IKE_ID_ADDR_PAIR;
28897c478bd9Sstevel@tonic-gate idlen = sizeof (ike_addr_pr_t);
28907c478bd9Sstevel@tonic-gate }
28917c478bd9Sstevel@tonic-gate }
28927c478bd9Sstevel@tonic-gate break;
28937c478bd9Sstevel@tonic-gate
28947c478bd9Sstevel@tonic-gate default:
28957c478bd9Sstevel@tonic-gate bail_msg(gettext("unrecognized get/del command (%d)"), cmd);
28967c478bd9Sstevel@tonic-gate }
28977c478bd9Sstevel@tonic-gate
28987c478bd9Sstevel@tonic-gate switch (idtype) {
28997c478bd9Sstevel@tonic-gate case IKE_ID_ADDR_PAIR:
29007c478bd9Sstevel@tonic-gate /*
29017c478bd9Sstevel@tonic-gate * we might have exploding addrs here; do every possible
29027c478bd9Sstevel@tonic-gate * combination.
29037c478bd9Sstevel@tonic-gate */
29047c478bd9Sstevel@tonic-gate i = 0;
29057c478bd9Sstevel@tonic-gate j = 0;
29067c478bd9Sstevel@tonic-gate while ((p1 = he1p->h_addr_list[i++]) != NULL) {
29077c478bd9Sstevel@tonic-gate headdr2sa(p1, &apr.loc_addr, he1p->h_length);
29087c478bd9Sstevel@tonic-gate
29097c478bd9Sstevel@tonic-gate while ((p2 = he2p->h_addr_list[j++]) != NULL) {
29107c478bd9Sstevel@tonic-gate headdr2sa(p2, &apr.rem_addr, he2p->h_length);
29117c478bd9Sstevel@tonic-gate do_getdel_doorcall(cmd, idlen, idtype,
29127c478bd9Sstevel@tonic-gate (char *)&apr, name);
29137c478bd9Sstevel@tonic-gate }
29147c478bd9Sstevel@tonic-gate }
29157c478bd9Sstevel@tonic-gate FREE_HE(he1p);
29167c478bd9Sstevel@tonic-gate FREE_HE(he2p);
29177c478bd9Sstevel@tonic-gate break;
29187c478bd9Sstevel@tonic-gate
29197c478bd9Sstevel@tonic-gate case IKE_ID_IDENT_PAIR:
29207c478bd9Sstevel@tonic-gate bytelen1 = SADB_64TO8(sid1p->sadb_ident_len);
29217c478bd9Sstevel@tonic-gate bytelen2 = SADB_64TO8(sid2p->sadb_ident_len);
29227c478bd9Sstevel@tonic-gate if (idlen != bytelen1 + bytelen2)
29237c478bd9Sstevel@tonic-gate Bail("ident syntax error");
29247c478bd9Sstevel@tonic-gate idp = p = (char *)malloc(idlen);
29257c478bd9Sstevel@tonic-gate if (p == NULL)
29267c478bd9Sstevel@tonic-gate Bail("malloc(id)");
29277c478bd9Sstevel@tonic-gate (void) memcpy(p, (char *)sid1p, bytelen1);
29287c478bd9Sstevel@tonic-gate p += bytelen1;
29297c478bd9Sstevel@tonic-gate (void) memcpy(p, (char *)sid2p, bytelen2);
29307c478bd9Sstevel@tonic-gate do_getdel_doorcall(cmd, idlen, idtype, idp, name);
29317c478bd9Sstevel@tonic-gate free(idp);
29327c478bd9Sstevel@tonic-gate free(sid1p);
29337c478bd9Sstevel@tonic-gate free(sid2p);
29347c478bd9Sstevel@tonic-gate break;
29357c478bd9Sstevel@tonic-gate
29367c478bd9Sstevel@tonic-gate case IKE_ID_CKY_PAIR:
29377c478bd9Sstevel@tonic-gate case IKE_ID_LABEL:
29387c478bd9Sstevel@tonic-gate do_getdel_doorcall(cmd, idlen, idtype, idp, name);
29397c478bd9Sstevel@tonic-gate break;
29407c478bd9Sstevel@tonic-gate
29417c478bd9Sstevel@tonic-gate case 0:
29427c478bd9Sstevel@tonic-gate default:
29437c478bd9Sstevel@tonic-gate bail_msg(gettext("invalid %s identification\n"), name);
29447c478bd9Sstevel@tonic-gate }
29457c478bd9Sstevel@tonic-gate }
29467c478bd9Sstevel@tonic-gate
29477c478bd9Sstevel@tonic-gate /*
29487c478bd9Sstevel@tonic-gate * Copy source into target, inserting an escape character ('\') before
29497c478bd9Sstevel@tonic-gate * any quotes that appear. Return true on success, false on failure.
29507c478bd9Sstevel@tonic-gate */
29517c478bd9Sstevel@tonic-gate static boolean_t
escapequotes(char * target,char * source,int tlen)29527c478bd9Sstevel@tonic-gate escapequotes(char *target, char *source, int tlen)
29537c478bd9Sstevel@tonic-gate {
29547c478bd9Sstevel@tonic-gate int s, t, len = strlen(source) + 1;
29557c478bd9Sstevel@tonic-gate
29567c478bd9Sstevel@tonic-gate if (tlen < len)
29577c478bd9Sstevel@tonic-gate return (B_FALSE);
29587c478bd9Sstevel@tonic-gate
29597c478bd9Sstevel@tonic-gate for (s = 0, t = 0; s < len && t < tlen; s++) {
29607c478bd9Sstevel@tonic-gate if (source[s] == '\"')
29617c478bd9Sstevel@tonic-gate target[t++] = '\\';
29627c478bd9Sstevel@tonic-gate target[t++] = source[s];
29637c478bd9Sstevel@tonic-gate }
29647c478bd9Sstevel@tonic-gate
29657c478bd9Sstevel@tonic-gate if ((t == tlen) && (s < len))
29667c478bd9Sstevel@tonic-gate return (B_FALSE);
29677c478bd9Sstevel@tonic-gate
29687c478bd9Sstevel@tonic-gate return (B_TRUE);
29697c478bd9Sstevel@tonic-gate }
29707c478bd9Sstevel@tonic-gate
29717c478bd9Sstevel@tonic-gate /*
29727c478bd9Sstevel@tonic-gate * Return true if the arg following the given keyword should
29737c478bd9Sstevel@tonic-gate * be in quotes (i.e. is a string), false if not.
29747c478bd9Sstevel@tonic-gate */
29757c478bd9Sstevel@tonic-gate static boolean_t
quotedfield(char * keywd)29767c478bd9Sstevel@tonic-gate quotedfield(char *keywd)
29777c478bd9Sstevel@tonic-gate {
29787c478bd9Sstevel@tonic-gate if ((strncmp(keywd, "label", strlen("label") + 1) == 0) ||
29797c478bd9Sstevel@tonic-gate (strncmp(keywd, "local_id", strlen("local_id") + 1) == 0) ||
29807c478bd9Sstevel@tonic-gate (strncmp(keywd, "remote_id", strlen("remote_id") + 1) == 0))
29817c478bd9Sstevel@tonic-gate return (B_TRUE);
29827c478bd9Sstevel@tonic-gate
29837c478bd9Sstevel@tonic-gate return (B_FALSE);
29847c478bd9Sstevel@tonic-gate }
29857c478bd9Sstevel@tonic-gate
29867c478bd9Sstevel@tonic-gate static void
do_new(int cmd,int argc,char ** argv)29877c478bd9Sstevel@tonic-gate do_new(int cmd, int argc, char **argv)
29887c478bd9Sstevel@tonic-gate {
29897c478bd9Sstevel@tonic-gate ike_service_t *rtn;
29907c478bd9Sstevel@tonic-gate ike_new_t new, *newp = NULL;
29917c478bd9Sstevel@tonic-gate door_desc_t desc, *descp = NULL;
29927c478bd9Sstevel@tonic-gate int i, fd, ndesc = 0, buflen;
29937c478bd9Sstevel@tonic-gate char *name, tmpfilepath[32];
29947c478bd9Sstevel@tonic-gate FILE *tmpfile;
29957c478bd9Sstevel@tonic-gate
29967c478bd9Sstevel@tonic-gate switch (cmd) {
29977c478bd9Sstevel@tonic-gate case IKE_SVC_NEW_PS:
29987c478bd9Sstevel@tonic-gate name = gettext("preshared key");
29997c478bd9Sstevel@tonic-gate break;
30007c478bd9Sstevel@tonic-gate case IKE_SVC_NEW_RULE:
30017c478bd9Sstevel@tonic-gate name = gettext("policy rule");
30027c478bd9Sstevel@tonic-gate break;
30037c478bd9Sstevel@tonic-gate default:
30047c478bd9Sstevel@tonic-gate bail_msg(gettext("unrecognized new command (%d)"), cmd);
30057c478bd9Sstevel@tonic-gate }
30067c478bd9Sstevel@tonic-gate
30077c478bd9Sstevel@tonic-gate if (argc == 1) {
30087c478bd9Sstevel@tonic-gate /* We've been given a file to read from */
30097c478bd9Sstevel@tonic-gate fd = open(argv[0], O_RDONLY);
30107c478bd9Sstevel@tonic-gate if (fd < 0)
30117c478bd9Sstevel@tonic-gate Bail("open source file");
30127c478bd9Sstevel@tonic-gate
30137c478bd9Sstevel@tonic-gate desc.d_data.d_desc.d_descriptor = fd;
30147c478bd9Sstevel@tonic-gate desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE;
30157c478bd9Sstevel@tonic-gate descp = &desc;
30167c478bd9Sstevel@tonic-gate ndesc = 1;
30177c478bd9Sstevel@tonic-gate
30187c478bd9Sstevel@tonic-gate new.cmd = cmd;
30197c478bd9Sstevel@tonic-gate new.new_len = 0;
30207c478bd9Sstevel@tonic-gate newp = &new;
30217c478bd9Sstevel@tonic-gate buflen = sizeof (ike_new_t);
30227c478bd9Sstevel@tonic-gate
30237c478bd9Sstevel@tonic-gate } else if ((argc > 1) && (cmd == IKE_SVC_NEW_PS)) {
30247c478bd9Sstevel@tonic-gate /*
30257c478bd9Sstevel@tonic-gate * This is an alternative to using the tmpfile method
30267c478bd9Sstevel@tonic-gate * for preshared keys. It means we're duplicating the
30277c478bd9Sstevel@tonic-gate * parsing effort that happens in readps.c; but it
30287c478bd9Sstevel@tonic-gate * does avoid having the key sitting in a file.
30297c478bd9Sstevel@tonic-gate */
30307c478bd9Sstevel@tonic-gate ike_ps_t *psp;
30317c478bd9Sstevel@tonic-gate int pslen;
30327c478bd9Sstevel@tonic-gate
30337c478bd9Sstevel@tonic-gate /*
30347c478bd9Sstevel@tonic-gate * must be in interactive mode; don't want keys in
30357c478bd9Sstevel@tonic-gate * the process args.
30367c478bd9Sstevel@tonic-gate */
30377c478bd9Sstevel@tonic-gate if (!interactive)
30387c478bd9Sstevel@tonic-gate Bail("Must be in interactive mode to add key info.");
30397c478bd9Sstevel@tonic-gate if (parse_ps(argc, argv, &psp, &pslen) < 0) {
30407c478bd9Sstevel@tonic-gate errno = 0;
30417c478bd9Sstevel@tonic-gate Bail("invalid preshared key definition");
30427c478bd9Sstevel@tonic-gate }
30437c478bd9Sstevel@tonic-gate newp = malloc(sizeof (ike_new_t) + pslen);
30447c478bd9Sstevel@tonic-gate if (newp == NULL)
30457c478bd9Sstevel@tonic-gate Bail("alloc pskey");
30467c478bd9Sstevel@tonic-gate newp->cmd = cmd;
30477c478bd9Sstevel@tonic-gate newp->new_len = sizeof (ike_new_t) + pslen;
30487c478bd9Sstevel@tonic-gate (void) memcpy((char *)(newp + 1), psp, pslen);
30497c478bd9Sstevel@tonic-gate buflen = newp->new_len;
30507c478bd9Sstevel@tonic-gate /* parse_ps allocated the ike_ps_t buffer; free it now */
30517c478bd9Sstevel@tonic-gate free(psp);
30527c478bd9Sstevel@tonic-gate
30537c478bd9Sstevel@tonic-gate } else if ((argc > 1) && (cmd == IKE_SVC_NEW_RULE)) {
30547c478bd9Sstevel@tonic-gate /*
30557c478bd9Sstevel@tonic-gate * We've been given the item in argv. However, parsing
30567c478bd9Sstevel@tonic-gate * rules can get more than a little messy, and in.iked
30577c478bd9Sstevel@tonic-gate * already has a great parser for this stuff! So don't
30587c478bd9Sstevel@tonic-gate * fool around with trying to do the parsing here. Just
30597c478bd9Sstevel@tonic-gate * write it out to a tempfile, and send the fd to in.iked.
30607c478bd9Sstevel@tonic-gate *
30617c478bd9Sstevel@tonic-gate * We could conceivably do this for preshared keys,
30627c478bd9Sstevel@tonic-gate * rather than duplicating the parsing effort; but that
30637c478bd9Sstevel@tonic-gate * would mean the key would be written out to a file,
30647c478bd9Sstevel@tonic-gate * which isn't such a good idea.
30657c478bd9Sstevel@tonic-gate */
30667c478bd9Sstevel@tonic-gate boolean_t doquotes = B_FALSE;
30677c478bd9Sstevel@tonic-gate int rtn;
30687c478bd9Sstevel@tonic-gate
30697c478bd9Sstevel@tonic-gate if ((argv[0][0] != '{') ||
30707c478bd9Sstevel@tonic-gate (argv[argc - 1][strlen(argv[argc - 1]) - 1] != '}'))
30717c478bd9Sstevel@tonic-gate bail_msg(gettext("improperly formatted %s"), name);
30727c478bd9Sstevel@tonic-gate
30737c478bd9Sstevel@tonic-gate /* attempt to use a fairly unpredictable file name... */
30747c478bd9Sstevel@tonic-gate (void) sprintf(tmpfilepath, "/var/run/%x", (int)gethrtime());
30757c478bd9Sstevel@tonic-gate fd = open(tmpfilepath, O_RDWR | O_CREAT | O_EXCL,
30767c478bd9Sstevel@tonic-gate S_IRUSR | S_IWUSR);
30777c478bd9Sstevel@tonic-gate if (fd < 0)
30787c478bd9Sstevel@tonic-gate Bail("cannot open tmpfile");
30797c478bd9Sstevel@tonic-gate
30807c478bd9Sstevel@tonic-gate /* and make it inaccessible asap */
30817c478bd9Sstevel@tonic-gate if (unlink(tmpfilepath) < 0) {
30827c478bd9Sstevel@tonic-gate (void) close(fd);
30837c478bd9Sstevel@tonic-gate Bail("tmpfile error");
30847c478bd9Sstevel@tonic-gate }
30857c478bd9Sstevel@tonic-gate
30867c478bd9Sstevel@tonic-gate tmpfile = fdopen(fd, "w");
30877c478bd9Sstevel@tonic-gate if (tmpfile == NULL) {
30887c478bd9Sstevel@tonic-gate (void) close(fd);
30897c478bd9Sstevel@tonic-gate Bail("cannot write to tmpfile");
30907c478bd9Sstevel@tonic-gate }
30917c478bd9Sstevel@tonic-gate
30927c478bd9Sstevel@tonic-gate for (i = 0; i < argc; i++) {
30937c478bd9Sstevel@tonic-gate /*
30947c478bd9Sstevel@tonic-gate * We have to do some gyrations with our string here,
30957c478bd9Sstevel@tonic-gate * to properly handle quotes. There are two issues:
30967c478bd9Sstevel@tonic-gate * - some of the fields of a rule may have embedded
30977c478bd9Sstevel@tonic-gate * whitespace, and thus must be quoted on the cmd
30987c478bd9Sstevel@tonic-gate * line. The shell removes the quotes, and gives
30997c478bd9Sstevel@tonic-gate * us a single argv string; but we need to put the
31007c478bd9Sstevel@tonic-gate * quotes back in when we write the string out to
31017c478bd9Sstevel@tonic-gate * file. The doquotes boolean is set when we
31027c478bd9Sstevel@tonic-gate * process a keyword which will be followed by a
31037c478bd9Sstevel@tonic-gate * string value (so the NEXT argv element will be
31047c478bd9Sstevel@tonic-gate * quoted).
31057c478bd9Sstevel@tonic-gate * - there might be a quote character in a field,
31067c478bd9Sstevel@tonic-gate * that was escaped on the cmdline. The shell
31077c478bd9Sstevel@tonic-gate * removes the escape char, and leaves the quote
31087c478bd9Sstevel@tonic-gate * in the string it gives us. We need to put the
31097c478bd9Sstevel@tonic-gate * escape char back in before writing to file.
31107c478bd9Sstevel@tonic-gate */
31117c478bd9Sstevel@tonic-gate char field[MAXLINESIZE];
31127c478bd9Sstevel@tonic-gate if (!escapequotes(field, argv[i], MAXLINESIZE))
31137c478bd9Sstevel@tonic-gate Bail("write to tmpfile failed (arg too big)");
31147c478bd9Sstevel@tonic-gate if (doquotes) {
31157c478bd9Sstevel@tonic-gate rtn = fprintf(tmpfile, "\"%s\"\n", field);
31167c478bd9Sstevel@tonic-gate doquotes = B_FALSE;
31177c478bd9Sstevel@tonic-gate } else {
31187c478bd9Sstevel@tonic-gate rtn = fprintf(tmpfile, "%s\n", field);
31197c478bd9Sstevel@tonic-gate }
31207c478bd9Sstevel@tonic-gate if (rtn < 0)
31217c478bd9Sstevel@tonic-gate Bail("write to tmpfile failed");
31227c478bd9Sstevel@tonic-gate /*
31237c478bd9Sstevel@tonic-gate * check if this is a keyword identifying
31247c478bd9Sstevel@tonic-gate * a field that needs to be quoted.
31257c478bd9Sstevel@tonic-gate */
31267c478bd9Sstevel@tonic-gate doquotes = quotedfield(argv[i]);
31277c478bd9Sstevel@tonic-gate }
31287c478bd9Sstevel@tonic-gate if (fflush(tmpfile) == EOF)
31297c478bd9Sstevel@tonic-gate Bail("write to tmpfile failed");
31307c478bd9Sstevel@tonic-gate /* rewind so that the daemon will get the beginning */
31317c478bd9Sstevel@tonic-gate rewind(tmpfile);
31327c478bd9Sstevel@tonic-gate
31337c478bd9Sstevel@tonic-gate desc.d_data.d_desc.d_descriptor = fd;
31347c478bd9Sstevel@tonic-gate desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE;
31357c478bd9Sstevel@tonic-gate descp = &desc;
31367c478bd9Sstevel@tonic-gate ndesc = 1;
31377c478bd9Sstevel@tonic-gate
31387c478bd9Sstevel@tonic-gate new.cmd = cmd;
31397c478bd9Sstevel@tonic-gate new.new_len = 0;
31407c478bd9Sstevel@tonic-gate newp = &new;
31417c478bd9Sstevel@tonic-gate buflen = sizeof (ike_new_t);
31427c478bd9Sstevel@tonic-gate
31437c478bd9Sstevel@tonic-gate } else {
31447c478bd9Sstevel@tonic-gate /* not enough information! */
31457c478bd9Sstevel@tonic-gate bail_msg(gettext("missing %s description or file name"), name);
31467c478bd9Sstevel@tonic-gate }
31477c478bd9Sstevel@tonic-gate
31487c478bd9Sstevel@tonic-gate rtn = ikedoor_call((char *)newp, buflen, descp, ndesc);
31497c478bd9Sstevel@tonic-gate
31507c478bd9Sstevel@tonic-gate if ((rtn == NULL) || (rtn->svc_err.cmd == IKE_SVC_ERROR)) {
31517c478bd9Sstevel@tonic-gate ikeadm_err_msg(&rtn->svc_err,
31527c478bd9Sstevel@tonic-gate gettext("error creating new %s"), name);
31537c478bd9Sstevel@tonic-gate } else {
31547c478bd9Sstevel@tonic-gate message(gettext("Successfully created new %s."), name);
31557c478bd9Sstevel@tonic-gate }
31567c478bd9Sstevel@tonic-gate }
31577c478bd9Sstevel@tonic-gate
31587c478bd9Sstevel@tonic-gate static void
do_flush(int cmd)31597c478bd9Sstevel@tonic-gate do_flush(int cmd)
31607c478bd9Sstevel@tonic-gate {
31617c478bd9Sstevel@tonic-gate ike_service_t *rtnp;
31627c478bd9Sstevel@tonic-gate ike_flush_t flush;
31637c478bd9Sstevel@tonic-gate
3164c7777ac8SPaul Wernau if (cmd != IKE_SVC_FLUSH_P1S && cmd != IKE_SVC_FLUSH_CERTCACHE) {
31657c478bd9Sstevel@tonic-gate bail_msg(gettext("unrecognized flush command (%d)."), cmd);
31667c478bd9Sstevel@tonic-gate }
31677c478bd9Sstevel@tonic-gate
31687c478bd9Sstevel@tonic-gate flush.cmd = cmd;
31697c478bd9Sstevel@tonic-gate
31707c478bd9Sstevel@tonic-gate rtnp = ikedoor_call((char *)&flush, sizeof (ike_flush_t), NULL, 0);
31717c478bd9Sstevel@tonic-gate if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) {
31727c478bd9Sstevel@tonic-gate ikeadm_err_exit(&rtnp->svc_err, gettext("error doing flush"));
31737c478bd9Sstevel@tonic-gate }
3174c7777ac8SPaul Wernau if (cmd == IKE_SVC_FLUSH_P1S)
3175c7777ac8SPaul Wernau message(gettext("Successfully flushed P1 SAs."));
3176c7777ac8SPaul Wernau else
3177c7777ac8SPaul Wernau message(gettext("Successfully flushed cert cache."));
31787c478bd9Sstevel@tonic-gate }
31797c478bd9Sstevel@tonic-gate
31807c478bd9Sstevel@tonic-gate static void
do_rw(int cmd,int argc,char ** argv)31817c478bd9Sstevel@tonic-gate do_rw(int cmd, int argc, char **argv)
31827c478bd9Sstevel@tonic-gate {
31837c478bd9Sstevel@tonic-gate ike_service_t *rtnp;
31847c478bd9Sstevel@tonic-gate ike_rw_t rw;
31857c478bd9Sstevel@tonic-gate door_desc_t desc, *descp = NULL;
31867c478bd9Sstevel@tonic-gate int oflag, omode, fd, ndesc = 0;
31877c478bd9Sstevel@tonic-gate char *op, *obj = NULL;
31887c478bd9Sstevel@tonic-gate boolean_t writing = B_FALSE;
31897c478bd9Sstevel@tonic-gate
31907c478bd9Sstevel@tonic-gate switch (cmd) {
31917c478bd9Sstevel@tonic-gate case IKE_SVC_READ_PS:
31927c478bd9Sstevel@tonic-gate obj = gettext("preshared key");
31937c478bd9Sstevel@tonic-gate /* FALLTHRU */
31947c478bd9Sstevel@tonic-gate case IKE_SVC_READ_RULES:
31957c478bd9Sstevel@tonic-gate if (obj == NULL)
31967c478bd9Sstevel@tonic-gate obj = gettext("policy rule");
31977c478bd9Sstevel@tonic-gate op = gettext("read");
31987c478bd9Sstevel@tonic-gate oflag = O_RDONLY;
31997c478bd9Sstevel@tonic-gate omode = 0;
32007c478bd9Sstevel@tonic-gate break;
32017c478bd9Sstevel@tonic-gate
32027c478bd9Sstevel@tonic-gate case IKE_SVC_WRITE_PS:
32037c478bd9Sstevel@tonic-gate obj = gettext("preshared key");
32047c478bd9Sstevel@tonic-gate /* FALLTHRU */
32057c478bd9Sstevel@tonic-gate case IKE_SVC_WRITE_RULES:
32067c478bd9Sstevel@tonic-gate if (obj == NULL)
32077c478bd9Sstevel@tonic-gate obj = gettext("policy rule");
32087c478bd9Sstevel@tonic-gate op = gettext("write");
32097c478bd9Sstevel@tonic-gate oflag = O_RDWR | O_CREAT | O_EXCL;
32107c478bd9Sstevel@tonic-gate omode = S_IRUSR | S_IWUSR;
32117c478bd9Sstevel@tonic-gate
32127c478bd9Sstevel@tonic-gate /* for write commands, dest location must be specified */
32137c478bd9Sstevel@tonic-gate if (argc < 1) {
32147c478bd9Sstevel@tonic-gate bail_msg(gettext("destination location required "
32157c478bd9Sstevel@tonic-gate "to write %ss"), obj);
32167c478bd9Sstevel@tonic-gate }
32177c478bd9Sstevel@tonic-gate writing = B_TRUE;
32187c478bd9Sstevel@tonic-gate break;
32197c478bd9Sstevel@tonic-gate
32207c478bd9Sstevel@tonic-gate default:
32217c478bd9Sstevel@tonic-gate bail_msg(gettext("unrecognized read/write command (%d)."), cmd);
32227c478bd9Sstevel@tonic-gate }
32237c478bd9Sstevel@tonic-gate
32247c478bd9Sstevel@tonic-gate rw.cmd = cmd;
32257c478bd9Sstevel@tonic-gate
32267c478bd9Sstevel@tonic-gate if (argc >= 1) {
32277c478bd9Sstevel@tonic-gate rw.rw_loc = IKE_RW_LOC_USER_SPEC;
32287c478bd9Sstevel@tonic-gate fd = open(argv[0], oflag, omode);
32297c478bd9Sstevel@tonic-gate if (fd < 0)
32307c478bd9Sstevel@tonic-gate Bail("open user-specified file");
32317c478bd9Sstevel@tonic-gate
32327c478bd9Sstevel@tonic-gate desc.d_data.d_desc.d_descriptor = fd;
32337c478bd9Sstevel@tonic-gate desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE;
32347c478bd9Sstevel@tonic-gate descp = &desc;
32357c478bd9Sstevel@tonic-gate ndesc = 1;
32367c478bd9Sstevel@tonic-gate } else {
32377c478bd9Sstevel@tonic-gate rw.rw_loc = IKE_RW_LOC_DEFAULT;
32387c478bd9Sstevel@tonic-gate }
32397c478bd9Sstevel@tonic-gate
32407c478bd9Sstevel@tonic-gate rtnp = ikedoor_call((char *)&rw, sizeof (ike_rw_t), descp, ndesc);
32417c478bd9Sstevel@tonic-gate if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) {
32427c478bd9Sstevel@tonic-gate /*
32437c478bd9Sstevel@tonic-gate * Need to remove the target file in the
32447c478bd9Sstevel@tonic-gate * case of a failed write command.
32457c478bd9Sstevel@tonic-gate */
32467c478bd9Sstevel@tonic-gate if (writing) {
32477c478bd9Sstevel@tonic-gate /*
32487c478bd9Sstevel@tonic-gate * argv[0] must be valid if we're writing; we
32497c478bd9Sstevel@tonic-gate * exit before setting this boolean if not.
32507c478bd9Sstevel@tonic-gate */
32517c478bd9Sstevel@tonic-gate (void) unlink(argv[0]);
32527c478bd9Sstevel@tonic-gate (void) close(fd);
32537c478bd9Sstevel@tonic-gate
32547c478bd9Sstevel@tonic-gate if ((rtnp != NULL) &&
32557c478bd9Sstevel@tonic-gate (rtnp->svc_err.ike_err == IKE_ERR_NO_OBJ)) {
32567c478bd9Sstevel@tonic-gate message(gettext("No %s information to write."),
32577c478bd9Sstevel@tonic-gate obj);
32587c478bd9Sstevel@tonic-gate return;
32597c478bd9Sstevel@tonic-gate }
32607c478bd9Sstevel@tonic-gate }
32617c478bd9Sstevel@tonic-gate ikeadm_err_exit(&rtnp->svc_err, gettext("error doing %s"), op);
32627c478bd9Sstevel@tonic-gate }
32637c478bd9Sstevel@tonic-gate message(gettext("Completed %s of %s configuration information."),
32647c478bd9Sstevel@tonic-gate op, obj);
32657c478bd9Sstevel@tonic-gate }
32667c478bd9Sstevel@tonic-gate
32677c478bd9Sstevel@tonic-gate static void
do_rbdump()32687c478bd9Sstevel@tonic-gate do_rbdump()
32697c478bd9Sstevel@tonic-gate {
32707c478bd9Sstevel@tonic-gate ike_cmd_t req;
32717c478bd9Sstevel@tonic-gate ike_service_t *rtnp;
32727c478bd9Sstevel@tonic-gate
32737c478bd9Sstevel@tonic-gate req.cmd = IKE_SVC_DBG_RBDUMP;
32747c478bd9Sstevel@tonic-gate
32757c478bd9Sstevel@tonic-gate rtnp = ikedoor_call((char *)&req, sizeof (ike_cmd_t), NULL, 0);
32767c478bd9Sstevel@tonic-gate if ((rtnp == NULL) || (rtnp->svc_err.cmd == IKE_SVC_ERROR)) {
32777c478bd9Sstevel@tonic-gate ikeadm_err_exit(&rtnp->svc_err, gettext("error doing flush"));
32787c478bd9Sstevel@tonic-gate }
32797c478bd9Sstevel@tonic-gate message(gettext("Successfully dumped rulebase; check iked dbg"));
32807c478bd9Sstevel@tonic-gate }
32817c478bd9Sstevel@tonic-gate
32827c478bd9Sstevel@tonic-gate #define REQ_ARG_CNT 1
32837c478bd9Sstevel@tonic-gate
3284e3320f40Smarkfen /*ARGSUSED*/
32857c478bd9Sstevel@tonic-gate static void
parseit(int argc,char ** argv,char * notused,boolean_t notused_either)328625e435e0Spwernau parseit(int argc, char **argv, char *notused, boolean_t notused_either)
32877c478bd9Sstevel@tonic-gate {
32887c478bd9Sstevel@tonic-gate int cmd, cmd_obj_args = 1;
32897c478bd9Sstevel@tonic-gate char *cmdstr, *objstr;
32907c478bd9Sstevel@tonic-gate
32917c478bd9Sstevel@tonic-gate if (interactive) {
32927c478bd9Sstevel@tonic-gate if (argc == 0)
32937c478bd9Sstevel@tonic-gate return;
32947c478bd9Sstevel@tonic-gate }
32957c478bd9Sstevel@tonic-gate
32967c478bd9Sstevel@tonic-gate if (argc < REQ_ARG_CNT) {
32977c478bd9Sstevel@tonic-gate usage();
32987c478bd9Sstevel@tonic-gate }
32997c478bd9Sstevel@tonic-gate
33007c478bd9Sstevel@tonic-gate cmdstr = argv[0];
33017c478bd9Sstevel@tonic-gate if (argc > REQ_ARG_CNT) {
33027c478bd9Sstevel@tonic-gate cmd_obj_args++;
33037c478bd9Sstevel@tonic-gate objstr = argv[1];
33047c478bd9Sstevel@tonic-gate } else {
33057c478bd9Sstevel@tonic-gate objstr = NULL;
33067c478bd9Sstevel@tonic-gate }
33077c478bd9Sstevel@tonic-gate cmd = parsecmd(cmdstr, objstr);
33087c478bd9Sstevel@tonic-gate
33097c478bd9Sstevel@tonic-gate /* skip over args specifying command/object */
33107c478bd9Sstevel@tonic-gate argc -= cmd_obj_args;
33117c478bd9Sstevel@tonic-gate argv += cmd_obj_args;
33127c478bd9Sstevel@tonic-gate
33137c478bd9Sstevel@tonic-gate switch (cmd) {
33140f2065ccSmarkfen case IKE_SVC_GET_DEFS:
3315bfe6f8f5SVladimir Kotal if (argc != 0) {
3316bfe6f8f5SVladimir Kotal print_get_help();
3317bfe6f8f5SVladimir Kotal break;
3318bfe6f8f5SVladimir Kotal }
33190f2065ccSmarkfen do_getdefs(cmd);
33200f2065ccSmarkfen break;
33217c478bd9Sstevel@tonic-gate case IKE_SVC_GET_DBG:
33227c478bd9Sstevel@tonic-gate case IKE_SVC_GET_PRIV:
3323bfe6f8f5SVladimir Kotal if (argc != 0) {
3324bfe6f8f5SVladimir Kotal print_get_help();
3325bfe6f8f5SVladimir Kotal break;
3326bfe6f8f5SVladimir Kotal }
33277c478bd9Sstevel@tonic-gate do_getvar(cmd);
33287c478bd9Sstevel@tonic-gate break;
33297c478bd9Sstevel@tonic-gate case IKE_SVC_GET_STATS:
3330bfe6f8f5SVladimir Kotal if (argc != 0) {
3331bfe6f8f5SVladimir Kotal print_get_help();
3332bfe6f8f5SVladimir Kotal break;
3333bfe6f8f5SVladimir Kotal }
33347c478bd9Sstevel@tonic-gate do_getstats(cmd);
33357c478bd9Sstevel@tonic-gate break;
33367c478bd9Sstevel@tonic-gate case IKE_SVC_SET_DBG:
33377c478bd9Sstevel@tonic-gate case IKE_SVC_SET_PRIV:
33387c478bd9Sstevel@tonic-gate do_setvar(cmd, argc, argv);
33397c478bd9Sstevel@tonic-gate break;
3340c7777ac8SPaul Wernau case IKE_SVC_SET_PIN:
3341c7777ac8SPaul Wernau case IKE_SVC_DEL_PIN:
3342c7777ac8SPaul Wernau do_setdel_pin(cmd, argc, argv);
3343c7777ac8SPaul Wernau break;
33447c478bd9Sstevel@tonic-gate case IKE_SVC_DUMP_P1S:
33457c478bd9Sstevel@tonic-gate case IKE_SVC_DUMP_RULES:
33465d01c172SVladimir Kotal case IKE_SVC_DUMP_GROUPS:
33475d01c172SVladimir Kotal case IKE_SVC_DUMP_ENCRALGS:
33485d01c172SVladimir Kotal case IKE_SVC_DUMP_AUTHALGS:
33497c478bd9Sstevel@tonic-gate case IKE_SVC_DUMP_PS:
3350c7777ac8SPaul Wernau case IKE_SVC_DUMP_CERTCACHE:
335195c74518SToomas Soome if (argc != 0) {
3352bfe6f8f5SVladimir Kotal print_dump_help();
3353bfe6f8f5SVladimir Kotal break;
3354bfe6f8f5SVladimir Kotal }
33557c478bd9Sstevel@tonic-gate do_dump(cmd);
33567c478bd9Sstevel@tonic-gate break;
33577c478bd9Sstevel@tonic-gate case IKE_SVC_GET_P1:
33587c478bd9Sstevel@tonic-gate case IKE_SVC_GET_RULE:
33597c478bd9Sstevel@tonic-gate case IKE_SVC_GET_PS:
33607c478bd9Sstevel@tonic-gate case IKE_SVC_DEL_P1:
33617c478bd9Sstevel@tonic-gate case IKE_SVC_DEL_RULE:
33627c478bd9Sstevel@tonic-gate case IKE_SVC_DEL_PS:
33637c478bd9Sstevel@tonic-gate do_getdel(cmd, argc, argv);
33647c478bd9Sstevel@tonic-gate break;
33657c478bd9Sstevel@tonic-gate case IKE_SVC_NEW_RULE:
33667c478bd9Sstevel@tonic-gate case IKE_SVC_NEW_PS:
33677c478bd9Sstevel@tonic-gate do_new(cmd, argc, argv);
33687c478bd9Sstevel@tonic-gate break;
33697c478bd9Sstevel@tonic-gate case IKE_SVC_FLUSH_P1S:
3370c7777ac8SPaul Wernau case IKE_SVC_FLUSH_CERTCACHE:
3371bfe6f8f5SVladimir Kotal if (argc != 0) {
3372bfe6f8f5SVladimir Kotal print_flush_help();
3373bfe6f8f5SVladimir Kotal break;
3374bfe6f8f5SVladimir Kotal }
33757c478bd9Sstevel@tonic-gate do_flush(cmd);
33767c478bd9Sstevel@tonic-gate break;
33777c478bd9Sstevel@tonic-gate case IKE_SVC_READ_RULES:
33787c478bd9Sstevel@tonic-gate case IKE_SVC_READ_PS:
33797c478bd9Sstevel@tonic-gate case IKE_SVC_WRITE_RULES:
33807c478bd9Sstevel@tonic-gate case IKE_SVC_WRITE_PS:
33817c478bd9Sstevel@tonic-gate do_rw(cmd, argc, argv);
33827c478bd9Sstevel@tonic-gate break;
33837c478bd9Sstevel@tonic-gate case IKEADM_HELP_GENERAL:
33847c478bd9Sstevel@tonic-gate print_help();
33857c478bd9Sstevel@tonic-gate break;
33867c478bd9Sstevel@tonic-gate case IKEADM_HELP_GET:
33877c478bd9Sstevel@tonic-gate print_get_help();
33887c478bd9Sstevel@tonic-gate break;
33897c478bd9Sstevel@tonic-gate case IKEADM_HELP_SET:
33907c478bd9Sstevel@tonic-gate print_set_help();
33917c478bd9Sstevel@tonic-gate break;
33927c478bd9Sstevel@tonic-gate case IKEADM_HELP_ADD:
33937c478bd9Sstevel@tonic-gate print_add_help();
33947c478bd9Sstevel@tonic-gate break;
33957c478bd9Sstevel@tonic-gate case IKEADM_HELP_DEL:
33967c478bd9Sstevel@tonic-gate print_del_help();
33977c478bd9Sstevel@tonic-gate break;
33987c478bd9Sstevel@tonic-gate case IKEADM_HELP_DUMP:
33997c478bd9Sstevel@tonic-gate print_dump_help();
34007c478bd9Sstevel@tonic-gate break;
34017c478bd9Sstevel@tonic-gate case IKEADM_HELP_FLUSH:
34027c478bd9Sstevel@tonic-gate print_flush_help();
34037c478bd9Sstevel@tonic-gate break;
34047c478bd9Sstevel@tonic-gate case IKEADM_HELP_READ:
34057c478bd9Sstevel@tonic-gate print_read_help();
34067c478bd9Sstevel@tonic-gate break;
34077c478bd9Sstevel@tonic-gate case IKEADM_HELP_WRITE:
34087c478bd9Sstevel@tonic-gate print_write_help();
34097c478bd9Sstevel@tonic-gate break;
3410c7777ac8SPaul Wernau case IKEADM_HELP_TOKEN:
3411c7777ac8SPaul Wernau print_token_help();
3412c7777ac8SPaul Wernau break;
34137c478bd9Sstevel@tonic-gate case IKEADM_HELP_HELP:
34147c478bd9Sstevel@tonic-gate print_help_help();
34157c478bd9Sstevel@tonic-gate break;
34167c478bd9Sstevel@tonic-gate case IKEADM_EXIT:
34177c478bd9Sstevel@tonic-gate if (interactive)
34187c478bd9Sstevel@tonic-gate exit(0);
34197c478bd9Sstevel@tonic-gate break;
34207c478bd9Sstevel@tonic-gate case IKE_SVC_DBG_RBDUMP:
34217c478bd9Sstevel@tonic-gate do_rbdump();
34227c478bd9Sstevel@tonic-gate break;
34237c478bd9Sstevel@tonic-gate case IKE_SVC_ERROR:
34247c478bd9Sstevel@tonic-gate usage();
34257c478bd9Sstevel@tonic-gate default:
34267c478bd9Sstevel@tonic-gate exit(0);
34277c478bd9Sstevel@tonic-gate }
34287c478bd9Sstevel@tonic-gate }
34297c478bd9Sstevel@tonic-gate
34307c478bd9Sstevel@tonic-gate int
main(int argc,char ** argv)34317c478bd9Sstevel@tonic-gate main(int argc, char **argv)
34327c478bd9Sstevel@tonic-gate {
3433*ef150c2bSRichard Lowe int ch;
34347c478bd9Sstevel@tonic-gate
34357c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
34367c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
34377c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST"
34387c478bd9Sstevel@tonic-gate #endif
34397c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
34407c478bd9Sstevel@tonic-gate
34417c478bd9Sstevel@tonic-gate while ((ch = getopt(argc, argv, "hpn")) != EOF) {
34427c478bd9Sstevel@tonic-gate switch (ch) {
34437c478bd9Sstevel@tonic-gate case 'h':
34447c478bd9Sstevel@tonic-gate print_help();
34457c478bd9Sstevel@tonic-gate return (0);
34467c478bd9Sstevel@tonic-gate case 'p':
34477c478bd9Sstevel@tonic-gate pflag = B_TRUE;
34487c478bd9Sstevel@tonic-gate break;
34497c478bd9Sstevel@tonic-gate case 'n':
34507c478bd9Sstevel@tonic-gate nflag = B_TRUE;
34517c478bd9Sstevel@tonic-gate break;
34527c478bd9Sstevel@tonic-gate default:
34537c478bd9Sstevel@tonic-gate usage();
34547c478bd9Sstevel@tonic-gate }
34557c478bd9Sstevel@tonic-gate }
34567c478bd9Sstevel@tonic-gate argc -= optind;
34577c478bd9Sstevel@tonic-gate argv += optind;
34587c478bd9Sstevel@tonic-gate
3459c8393ed7Smarkfen if (open_door() < 0) {
3460c8393ed7Smarkfen (void) fprintf(stderr,
3461c8393ed7Smarkfen gettext("Unable to communicate with in.iked\n"));
3462c8393ed7Smarkfen Bail("open_door failed");
3463c8393ed7Smarkfen }
34647c478bd9Sstevel@tonic-gate
34657c478bd9Sstevel@tonic-gate if (*argv == NULL) {
34667c478bd9Sstevel@tonic-gate /* no cmd-line args, do interactive mode */
3467bfe6f8f5SVladimir Kotal do_interactive(stdin, NULL, "ikeadm> ", NULL, parseit,
3468bfe6f8f5SVladimir Kotal no_match);
34697c478bd9Sstevel@tonic-gate }
34707c478bd9Sstevel@tonic-gate
347125e435e0Spwernau parseit(argc, argv, NULL, B_FALSE);
34727c478bd9Sstevel@tonic-gate
34737c478bd9Sstevel@tonic-gate return (0);
34747c478bd9Sstevel@tonic-gate }
3475