4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
25 #include <arpa/inet.h> /* inet_addr() */
28 #include <netdb.h> /* hostent */
29 #include <netinet/in.h> /* ip_addr_t */
36 #include <sys/varargs.h>
43 * ksslcfg manages smf(5) instances for the Kernel SSL proxy module.
44 * It makes use of kssladm(1M) which does the grunt work.
48 * This version number is rather meaningless. In any case,
49 * version 2.0 adds support for IPv6 addresses.
51 #define KSSLCFG_VERSION "Version 2.0"
53 boolean_t verbose
= B_FALSE
;
54 const char *SERVICE_NAME
= "network/ssl/proxy";
57 KSSL_DEBUG(const char *format
, ...)
63 (void) vprintf(format
, ap
);
69 * Convert string to port number and check for errors. Return 0 on error,
73 get_portnum(const char *s
, ushort_t
*rport
)
79 tmp_port
= strtoll(s
, &ep
, 10);
80 if (s
== ep
|| *ep
!= '\0' || errno
!= 0)
82 if (tmp_port
< 1 || tmp_port
> 65535)
86 *rport
= (ushort_t
)tmp_port
;
91 #define ANY_ADDR "INADDR_ANY"
94 * An instance name is formed using either the host name in the fully
95 * qualified domain name form (FQDN) which should map to a specific IP address
96 * or using INADDR_ANY which means all IP addresses.
98 * We do a lookup or reverse lookup to get the host name. It is assumed that
99 * the returned name is in the FQDN form. i.e. DNS is used.
102 create_instance_name(const char *arg
, char **inaddr_any_name
,
109 const char *prefix
= "kssl-";
112 first_space
= strchr(arg
, ' ');
113 if (first_space
== NULL
) { /* No host name. Use INADDR_ANY. */
114 if (get_portnum(arg
, &port
) == 0) {
115 (void) fprintf(stderr
,
116 gettext("Error: Invalid port value -- %s\n"),
120 KSSL_DEBUG("port=%d\n", port
);
121 if ((cname
= strdup(ANY_ADDR
)) == NULL
)
132 if (get_portnum(first_space
+ 1, &port
) == 0) {
133 (void) fprintf(stderr
,
134 gettext("Error: Invalid port value -- %s\n"),
138 KSSL_DEBUG("port=%d\n", port
);
140 if ((temp_str
= strdup(arg
)) == NULL
)
142 *(strchr(temp_str
, ' ')) = '\0';
144 if (inet_pton(AF_INET6
, temp_str
, &v6addr
) == 1) {
145 /* Do a reverse lookup for the IPv6 address */
146 hp
= getipnodebyaddr(&v6addr
, sizeof (v6addr
),
147 AF_INET6
, &error_num
);
148 } else if (inet_pton(AF_INET
, temp_str
, &v4addr
) == 1) {
149 /* Do a reverse lookup for the IPv4 address */
150 hp
= getipnodebyaddr(&v4addr
, sizeof (v4addr
),
151 AF_INET
, &error_num
);
153 /* Do a lookup for the host name */
154 hp
= getipnodebyname(temp_str
, AF_INET6
, AI_DEFAULT
,
159 (void) fprintf(stderr
,
160 gettext("Error: Unknown host -- %s\n"), temp_str
);
165 if ((ptr
= cname
= strdup(hp
->h_name
)) == NULL
) {
175 while ((ptr
= strchr(ptr
, '.')) != NULL
) {
182 if (do_warn
&& is_create
) {
183 (void) fprintf(stderr
,
184 gettext("Warning: %s does not appear to have a"
185 " registered DNS name.\n"), temp_str
);
191 KSSL_DEBUG("Cannonical host name =%s\n", cname
);
193 len
= strlen(prefix
) + strlen(cname
) + 10;
194 if ((instance_name
= malloc(len
)) == NULL
) {
195 (void) fprintf(stderr
,
196 gettext("Error: memory allocation failure.\n"));
199 (void) snprintf(instance_name
, len
, "%s%s-%d", prefix
, cname
, port
);
202 len
= strlen(prefix
) + strlen(ANY_ADDR
) + 10;
203 if ((*inaddr_any_name
= malloc(len
)) == NULL
) {
204 (void) fprintf(stderr
,
205 gettext("Error: memory allocation failure.\n"));
211 (void) snprintf(*inaddr_any_name
, len
,
212 "%s%s-%d", prefix
, ANY_ADDR
, port
);
216 KSSL_DEBUG("instance_name=%s\n", instance_name
);
217 return (instance_name
);
223 (void) fprintf(stderr
, gettext("Usage:\n"));
224 usage_create(B_FALSE
);
225 usage_delete(B_FALSE
);
226 (void) fprintf(stderr
, "ksslcfg -V\n");
227 (void) fprintf(stderr
, "ksslcfg -?\n");
232 main(int argc
, char **argv
)
236 (void) setlocale(LC_ALL
, "");
237 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
238 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
240 (void) textdomain(TEXT_DOMAIN
);
242 /* Running from within a non-global zone is not supported yet. */
243 if (getzoneid() != GLOBAL_ZONEID
) {
244 (void) fprintf(stderr
,
245 gettext("Error: Configuring KSSL from within a non-global "
246 "zone is not supported.\nPlease run the command from "
247 "the global zone.\n"));
248 return (ERROR_USAGE
);
253 return (ERROR_USAGE
);
256 if (strcmp(argv
[1], "create") == 0) {
257 rv
= do_create(argc
, argv
);
258 } else if (strcmp(argv
[1], "delete") == 0) {
259 rv
= do_delete(argc
, argv
);
260 } else if (strcmp(argv
[1], "-V") == 0) {
261 (void) printf("%s\n", KSSLCFG_VERSION
);
262 } else if (strcmp(argv
[1], "-?") == 0) {
265 (void) fprintf(stderr
,
266 gettext("Error: Unknown subcommand -- %s\n"), argv
[1]);