10ba2cbe9Sxc151355 /*
20ba2cbe9Sxc151355 * CDDL HEADER START
30ba2cbe9Sxc151355 *
40ba2cbe9Sxc151355 * The contents of this file are subject to the terms of the
50ba2cbe9Sxc151355 * Common Development and Distribution License (the "License").
60ba2cbe9Sxc151355 * You may not use this file except in compliance with the License.
70ba2cbe9Sxc151355 *
80ba2cbe9Sxc151355 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90ba2cbe9Sxc151355 * or http://www.opensolaris.org/os/licensing.
100ba2cbe9Sxc151355 * See the License for the specific language governing permissions
110ba2cbe9Sxc151355 * and limitations under the License.
120ba2cbe9Sxc151355 *
130ba2cbe9Sxc151355 * When distributing Covered Code, include this CDDL HEADER in each
140ba2cbe9Sxc151355 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150ba2cbe9Sxc151355 * If applicable, add the following below this CDDL HEADER, with the
160ba2cbe9Sxc151355 * fields enclosed by brackets "[]" replaced with your own identifying
170ba2cbe9Sxc151355 * information: Portions Copyright [yyyy] [name of copyright owner]
180ba2cbe9Sxc151355 *
190ba2cbe9Sxc151355 * CDDL HEADER END
200ba2cbe9Sxc151355 */
210ba2cbe9Sxc151355 /*
22*6ba597c5SAnurag S. Maskey * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
230ba2cbe9Sxc151355 * Use is subject to license terms.
240ba2cbe9Sxc151355 */
250ba2cbe9Sxc151355
260ba2cbe9Sxc151355 #include <unistd.h>
270ba2cbe9Sxc151355 #include <stdlib.h>
280ba2cbe9Sxc151355 #include <strings.h>
290ba2cbe9Sxc151355 #include <errno.h>
300ba2cbe9Sxc151355 #include <ctype.h>
310ba2cbe9Sxc151355 #include <fcntl.h>
320ba2cbe9Sxc151355 #include <sys/stat.h>
330ba2cbe9Sxc151355 #include <sys/dld.h>
3482a2fc47SJames Carlson #include <sys/dld_ioc.h>
350ba2cbe9Sxc151355 #include <libinetutil.h>
36f595a68aSyz147064 #include <libdllink.h>
370ba2cbe9Sxc151355 #include <libdladm_impl.h>
380ba2cbe9Sxc151355
394ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_set_secobj_db(dladm_handle_t, const char *,
400ba2cbe9Sxc151355 dladm_secobj_class_t, uint8_t *, uint_t);
414ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_get_secobj_db(dladm_handle_t, const char *,
420ba2cbe9Sxc151355 dladm_secobj_class_t *, uint8_t *, uint_t *);
434ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_unset_secobj_db(dladm_handle_t, const char *);
444ac67f02SAnurag S. Maskey static dladm_status_t i_dladm_walk_secobj_db(dladm_handle_t, void *,
454ac67f02SAnurag S. Maskey boolean_t (*)(dladm_handle_t, void *,
464ac67f02SAnurag S. Maskey const char *));
470ba2cbe9Sxc151355
480ba2cbe9Sxc151355 typedef struct secobj_class_info {
490ba2cbe9Sxc151355 const char *sc_name;
500ba2cbe9Sxc151355 dld_secobj_class_t sc_dldclass;
510ba2cbe9Sxc151355 } secobj_class_info_t;
520ba2cbe9Sxc151355
530ba2cbe9Sxc151355 static secobj_class_info_t secobj_class_table[] = {
54a399b765Szf162725 {"wep", DLD_SECOBJ_CLASS_WEP},
55a399b765Szf162725 {"wpa", DLD_SECOBJ_CLASS_WPA}
560ba2cbe9Sxc151355 };
570ba2cbe9Sxc151355
58eae72b5bSSebastien Roy #define SECOBJ_MAXBUFSZ 65536
590ba2cbe9Sxc151355 #define NSECOBJCLASS \
600ba2cbe9Sxc151355 (sizeof (secobj_class_table) / sizeof (secobj_class_info_t))
610ba2cbe9Sxc151355
620ba2cbe9Sxc151355 static boolean_t
dladm_check_secobjclass(dladm_secobj_class_t class)630ba2cbe9Sxc151355 dladm_check_secobjclass(dladm_secobj_class_t class)
640ba2cbe9Sxc151355 {
650ba2cbe9Sxc151355 return (class >= 0 && class < NSECOBJCLASS);
660ba2cbe9Sxc151355 }
670ba2cbe9Sxc151355
680ba2cbe9Sxc151355 dladm_status_t
dladm_str2secobjclass(const char * str,dladm_secobj_class_t * class)690ba2cbe9Sxc151355 dladm_str2secobjclass(const char *str, dladm_secobj_class_t *class)
700ba2cbe9Sxc151355 {
710ba2cbe9Sxc151355 int i;
720ba2cbe9Sxc151355 secobj_class_info_t *sp;
730ba2cbe9Sxc151355
740ba2cbe9Sxc151355 for (i = 0; i < NSECOBJCLASS; i++) {
750ba2cbe9Sxc151355 sp = &secobj_class_table[i];
760ba2cbe9Sxc151355 if (strcasecmp(str, sp->sc_name) == 0) {
770ba2cbe9Sxc151355 *class = i;
780ba2cbe9Sxc151355 return (DLADM_STATUS_OK);
790ba2cbe9Sxc151355 }
800ba2cbe9Sxc151355 }
810ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG);
820ba2cbe9Sxc151355 }
830ba2cbe9Sxc151355
840ba2cbe9Sxc151355 const char *
dladm_secobjclass2str(dladm_secobj_class_t class,char * buf)850ba2cbe9Sxc151355 dladm_secobjclass2str(dladm_secobj_class_t class, char *buf)
860ba2cbe9Sxc151355 {
870ba2cbe9Sxc151355 const char *s;
880ba2cbe9Sxc151355
890ba2cbe9Sxc151355 if (!dladm_check_secobjclass(class))
900ba2cbe9Sxc151355 s = "";
910ba2cbe9Sxc151355 else
920ba2cbe9Sxc151355 s = secobj_class_table[class].sc_name;
930ba2cbe9Sxc151355
940ba2cbe9Sxc151355 (void) snprintf(buf, DLADM_STRSIZE, "%s", s);
950ba2cbe9Sxc151355 return (buf);
960ba2cbe9Sxc151355 }
970ba2cbe9Sxc151355
980ba2cbe9Sxc151355 static boolean_t
dladm_convert_secobjclass(dladm_secobj_class_t class,dld_secobj_class_t * dldclass)990ba2cbe9Sxc151355 dladm_convert_secobjclass(dladm_secobj_class_t class,
1000ba2cbe9Sxc151355 dld_secobj_class_t *dldclass)
1010ba2cbe9Sxc151355 {
1020ba2cbe9Sxc151355 if (!dladm_check_secobjclass(class))
1030ba2cbe9Sxc151355 return (B_FALSE);
1040ba2cbe9Sxc151355
1050ba2cbe9Sxc151355 *dldclass = secobj_class_table[class].sc_dldclass;
1060ba2cbe9Sxc151355 return (B_TRUE);
1070ba2cbe9Sxc151355 }
1080ba2cbe9Sxc151355
1090ba2cbe9Sxc151355 static boolean_t
dladm_convert_dldsecobjclass(dld_secobj_class_t dldclass,dladm_secobj_class_t * class)1100ba2cbe9Sxc151355 dladm_convert_dldsecobjclass(dld_secobj_class_t dldclass,
1110ba2cbe9Sxc151355 dladm_secobj_class_t *class)
1120ba2cbe9Sxc151355 {
1130ba2cbe9Sxc151355 int i;
1140ba2cbe9Sxc151355 secobj_class_info_t *sp;
1150ba2cbe9Sxc151355
1160ba2cbe9Sxc151355 for (i = 0; i < NSECOBJCLASS; i++) {
1170ba2cbe9Sxc151355 sp = &secobj_class_table[i];
1180ba2cbe9Sxc151355 if (dldclass == sp->sc_dldclass) {
1190ba2cbe9Sxc151355 *class = i;
1200ba2cbe9Sxc151355 return (B_TRUE);
1210ba2cbe9Sxc151355 }
1220ba2cbe9Sxc151355 }
1230ba2cbe9Sxc151355 return (B_FALSE);
1240ba2cbe9Sxc151355 }
1250ba2cbe9Sxc151355
1260ba2cbe9Sxc151355 dladm_status_t
dladm_set_secobj(dladm_handle_t handle,const char * obj_name,dladm_secobj_class_t class,uint8_t * obj_val,uint_t obj_len,uint_t flags)1274ac67f02SAnurag S. Maskey dladm_set_secobj(dladm_handle_t handle, const char *obj_name,
1284ac67f02SAnurag S. Maskey dladm_secobj_class_t class, uint8_t *obj_val, uint_t obj_len, uint_t flags)
1290ba2cbe9Sxc151355 {
1300ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK;
1310ba2cbe9Sxc151355 dld_ioc_secobj_set_t secobj_set;
1320ba2cbe9Sxc151355 dld_secobj_t *objp;
1330ba2cbe9Sxc151355
134a9489f61SAnurag S. Maskey if (!dladm_valid_secobj_name(obj_name))
135a9489f61SAnurag S. Maskey return (DLADM_STATUS_BADARG);
136a9489f61SAnurag S. Maskey
1370ba2cbe9Sxc151355 if (!dladm_check_secobjclass(class) || flags == 0 ||
1380ba2cbe9Sxc151355 obj_name == NULL || strlen(obj_name) > DLD_SECOBJ_NAME_MAX ||
1390ba2cbe9Sxc151355 obj_val == NULL || obj_len == 0 || obj_len > DLD_SECOBJ_VAL_MAX)
1400ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG);
1410ba2cbe9Sxc151355
142d62bc4baSyz147064 if ((flags & DLADM_OPT_ACTIVE) == 0)
1430ba2cbe9Sxc151355 goto persist;
1440ba2cbe9Sxc151355
1450ba2cbe9Sxc151355 bzero(&secobj_set, sizeof (secobj_set));
1460ba2cbe9Sxc151355 objp = &secobj_set.ss_obj;
1470ba2cbe9Sxc151355 if (!dladm_convert_secobjclass(class, &objp->so_class))
1480ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG);
1490ba2cbe9Sxc151355
1500ba2cbe9Sxc151355 (void) strlcpy(objp->so_name, obj_name, DLD_SECOBJ_NAME_MAX);
1510ba2cbe9Sxc151355 bcopy(obj_val, objp->so_val, obj_len);
1520ba2cbe9Sxc151355 objp->so_len = obj_len;
1530ba2cbe9Sxc151355
1540ba2cbe9Sxc151355 if ((flags & DLADM_OPT_CREATE) != 0)
1550ba2cbe9Sxc151355 secobj_set.ss_flags = DLD_SECOBJ_OPT_CREATE;
1560ba2cbe9Sxc151355
1574ac67f02SAnurag S. Maskey if (ioctl(dladm_dld_fd(handle), DLDIOC_SECOBJ_SET, &secobj_set) < 0)
1580ba2cbe9Sxc151355 status = dladm_errno2status(errno);
1590ba2cbe9Sxc151355
1600ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK)
1610ba2cbe9Sxc151355 return (status);
1620ba2cbe9Sxc151355
1630ba2cbe9Sxc151355 persist:
1640ba2cbe9Sxc151355 if ((flags & DLADM_OPT_PERSIST) != 0) {
1654ac67f02SAnurag S. Maskey status = i_dladm_set_secobj_db(handle, obj_name, class,
1660ba2cbe9Sxc151355 obj_val, obj_len);
1670ba2cbe9Sxc151355 }
1680ba2cbe9Sxc151355 return (status);
1690ba2cbe9Sxc151355 }
1700ba2cbe9Sxc151355
1710ba2cbe9Sxc151355 dladm_status_t
dladm_get_secobj(dladm_handle_t handle,const char * obj_name,dladm_secobj_class_t * classp,uint8_t * obj_val,uint_t * obj_lenp,uint_t flags)1724ac67f02SAnurag S. Maskey dladm_get_secobj(dladm_handle_t handle, const char *obj_name,
1734ac67f02SAnurag S. Maskey dladm_secobj_class_t *classp, uint8_t *obj_val, uint_t *obj_lenp,
1744ac67f02SAnurag S. Maskey uint_t flags)
1750ba2cbe9Sxc151355 {
1760ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK;
1770ba2cbe9Sxc151355 dld_ioc_secobj_get_t secobj_get;
1780ba2cbe9Sxc151355 dld_secobj_t *objp;
1790ba2cbe9Sxc151355
1800ba2cbe9Sxc151355 if (obj_name == NULL || strlen(obj_name) > DLD_SECOBJ_NAME_MAX ||
1810ba2cbe9Sxc151355 obj_val == NULL || obj_lenp == NULL || *obj_lenp == 0 ||
1820ba2cbe9Sxc151355 *obj_lenp > DLD_SECOBJ_VAL_MAX)
1830ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG);
1840ba2cbe9Sxc151355
1850ba2cbe9Sxc151355 if ((flags & DLADM_OPT_PERSIST) != 0) {
1864ac67f02SAnurag S. Maskey return (i_dladm_get_secobj_db(handle, obj_name, classp,
1870ba2cbe9Sxc151355 obj_val, obj_lenp));
1880ba2cbe9Sxc151355 }
1890ba2cbe9Sxc151355
1900ba2cbe9Sxc151355 bzero(&secobj_get, sizeof (secobj_get));
1910ba2cbe9Sxc151355 objp = &secobj_get.sg_obj;
1920ba2cbe9Sxc151355 (void) strlcpy(objp->so_name, obj_name, DLD_SECOBJ_NAME_MAX);
1930ba2cbe9Sxc151355
194eae72b5bSSebastien Roy secobj_get.sg_size = sizeof (secobj_get);
1954ac67f02SAnurag S. Maskey if (ioctl(dladm_dld_fd(handle), DLDIOC_SECOBJ_GET, &secobj_get) < 0)
1960ba2cbe9Sxc151355 status = dladm_errno2status(errno);
1970ba2cbe9Sxc151355
1980ba2cbe9Sxc151355 if (objp->so_len > *obj_lenp)
1990ba2cbe9Sxc151355 return (DLADM_STATUS_TOOSMALL);
2000ba2cbe9Sxc151355
2010ba2cbe9Sxc151355 if (!dladm_convert_dldsecobjclass(objp->so_class, classp))
2020ba2cbe9Sxc151355 return (DLADM_STATUS_FAILED);
2030ba2cbe9Sxc151355
2040ba2cbe9Sxc151355 *obj_lenp = objp->so_len;
2050ba2cbe9Sxc151355 bcopy(objp->so_val, obj_val, *obj_lenp);
2060ba2cbe9Sxc151355 return (status);
2070ba2cbe9Sxc151355 }
2080ba2cbe9Sxc151355
2090ba2cbe9Sxc151355 dladm_status_t
dladm_unset_secobj(dladm_handle_t handle,const char * obj_name,uint_t flags)2104ac67f02SAnurag S. Maskey dladm_unset_secobj(dladm_handle_t handle, const char *obj_name, uint_t flags)
2110ba2cbe9Sxc151355 {
2120ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK;
2130ba2cbe9Sxc151355 dld_ioc_secobj_unset_t secobj_unset;
2140ba2cbe9Sxc151355
2150ba2cbe9Sxc151355 if (obj_name == NULL || strlen(obj_name) > DLD_SECOBJ_NAME_MAX ||
2160ba2cbe9Sxc151355 flags == 0)
2170ba2cbe9Sxc151355 return (DLADM_STATUS_BADARG);
2180ba2cbe9Sxc151355
219d62bc4baSyz147064 if ((flags & DLADM_OPT_ACTIVE) == 0)
2200ba2cbe9Sxc151355 goto persist;
2210ba2cbe9Sxc151355
2220ba2cbe9Sxc151355 bzero(&secobj_unset, sizeof (secobj_unset));
2230ba2cbe9Sxc151355 (void) strlcpy(secobj_unset.su_name, obj_name, DLD_SECOBJ_NAME_MAX);
2240ba2cbe9Sxc151355
2254ac67f02SAnurag S. Maskey if (ioctl(dladm_dld_fd(handle), DLDIOC_SECOBJ_UNSET, &secobj_unset) < 0)
2260ba2cbe9Sxc151355 status = dladm_errno2status(errno);
2270ba2cbe9Sxc151355
2280ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK)
2290ba2cbe9Sxc151355 return (status);
2300ba2cbe9Sxc151355
2310ba2cbe9Sxc151355 persist:
2320ba2cbe9Sxc151355 if ((flags & DLADM_OPT_PERSIST) != 0)
2334ac67f02SAnurag S. Maskey status = i_dladm_unset_secobj_db(handle, obj_name);
2340ba2cbe9Sxc151355
2350ba2cbe9Sxc151355 return (status);
2360ba2cbe9Sxc151355 }
2370ba2cbe9Sxc151355
2380ba2cbe9Sxc151355 dladm_status_t
dladm_walk_secobj(dladm_handle_t handle,void * arg,boolean_t (* func)(dladm_handle_t,void *,const char *),uint_t flags)2394ac67f02SAnurag S. Maskey dladm_walk_secobj(dladm_handle_t handle, void *arg,
2404ac67f02SAnurag S. Maskey boolean_t (*func)(dladm_handle_t, void *, const char *), uint_t flags)
2410ba2cbe9Sxc151355 {
2420ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK;
2430ba2cbe9Sxc151355 dld_ioc_secobj_get_t *secobj_getp;
2440ba2cbe9Sxc151355 dld_secobj_t *objp;
245eae72b5bSSebastien Roy size_t secobj_bufsz;
2460ba2cbe9Sxc151355
2470ba2cbe9Sxc151355 if ((flags & DLADM_OPT_PERSIST) != 0)
2484ac67f02SAnurag S. Maskey return (i_dladm_walk_secobj_db(handle, arg, func));
2490ba2cbe9Sxc151355
250eae72b5bSSebastien Roy /* Start with enough room for 10 objects, increase if necessary. */
251eae72b5bSSebastien Roy secobj_bufsz = sizeof (*secobj_getp) + (10 * sizeof (*objp));
252eae72b5bSSebastien Roy secobj_getp = calloc(1, secobj_bufsz);
253eae72b5bSSebastien Roy if (secobj_getp == NULL) {
2540ba2cbe9Sxc151355 status = dladm_errno2status(errno);
2550ba2cbe9Sxc151355 goto done;
2560ba2cbe9Sxc151355 }
257eae72b5bSSebastien Roy
258eae72b5bSSebastien Roy tryagain:
259eae72b5bSSebastien Roy secobj_getp->sg_size = secobj_bufsz;
2604ac67f02SAnurag S. Maskey if (ioctl(dladm_dld_fd(handle), DLDIOC_SECOBJ_GET, secobj_getp) < 0) {
261eae72b5bSSebastien Roy if (errno == ENOSPC) {
262eae72b5bSSebastien Roy /* Increase the buffer size and try again. */
263eae72b5bSSebastien Roy secobj_bufsz *= 2;
264eae72b5bSSebastien Roy if (secobj_bufsz > SECOBJ_MAXBUFSZ) {
265eae72b5bSSebastien Roy status = dladm_errno2status(errno);
266eae72b5bSSebastien Roy goto done;
267eae72b5bSSebastien Roy }
268eae72b5bSSebastien Roy secobj_getp = realloc(secobj_getp, secobj_bufsz);
269eae72b5bSSebastien Roy if (secobj_getp == NULL) {
270eae72b5bSSebastien Roy status = dladm_errno2status(errno);
271eae72b5bSSebastien Roy goto done;
272eae72b5bSSebastien Roy }
273eae72b5bSSebastien Roy bzero(secobj_getp, secobj_bufsz);
274eae72b5bSSebastien Roy goto tryagain;
275eae72b5bSSebastien Roy }
2760ba2cbe9Sxc151355 status = dladm_errno2status(errno);
2770ba2cbe9Sxc151355 goto done;
2780ba2cbe9Sxc151355 }
2790ba2cbe9Sxc151355
2800ba2cbe9Sxc151355 objp = (dld_secobj_t *)(secobj_getp + 1);
2810ba2cbe9Sxc151355 while (secobj_getp->sg_count > 0) {
2824ac67f02SAnurag S. Maskey if (!func(handle, arg, objp->so_name))
2830ba2cbe9Sxc151355 goto done;
2840ba2cbe9Sxc151355 secobj_getp->sg_count--;
2850ba2cbe9Sxc151355 objp++;
2860ba2cbe9Sxc151355 }
2870ba2cbe9Sxc151355 done:
2880ba2cbe9Sxc151355 free(secobj_getp);
2890ba2cbe9Sxc151355 return (status);
2900ba2cbe9Sxc151355 }
2910ba2cbe9Sxc151355
2920ba2cbe9Sxc151355 /*
2930ba2cbe9Sxc151355 * Data structures used for implementing persistent secure objects
2940ba2cbe9Sxc151355 */
2950ba2cbe9Sxc151355 typedef struct secobj_info {
2960ba2cbe9Sxc151355 const char *si_name;
2970ba2cbe9Sxc151355 dladm_secobj_class_t *si_classp;
2980ba2cbe9Sxc151355 uint8_t *si_val;
2990ba2cbe9Sxc151355 uint_t *si_lenp;
3000ba2cbe9Sxc151355 } secobj_info_t;
3010ba2cbe9Sxc151355
3020ba2cbe9Sxc151355 typedef struct secobj_name {
3030ba2cbe9Sxc151355 char *sn_name;
3040ba2cbe9Sxc151355 struct secobj_name *sn_next;
3050ba2cbe9Sxc151355 } secobj_name_t;
3060ba2cbe9Sxc151355
3070ba2cbe9Sxc151355 typedef struct secobj_db_state secobj_db_state_t;
3080ba2cbe9Sxc151355
3094ac67f02SAnurag S. Maskey typedef boolean_t (*secobj_db_op_t)(dladm_handle_t, struct secobj_db_state *,
3104ac67f02SAnurag S. Maskey char *, secobj_info_t *, dladm_status_t *);
3110ba2cbe9Sxc151355
3120ba2cbe9Sxc151355 struct secobj_db_state {
3130ba2cbe9Sxc151355 secobj_db_op_t ss_op;
3140ba2cbe9Sxc151355 secobj_info_t ss_info;
3150ba2cbe9Sxc151355 secobj_name_t **ss_namelist;
3160ba2cbe9Sxc151355 };
3170ba2cbe9Sxc151355
3180ba2cbe9Sxc151355 /*
3190ba2cbe9Sxc151355 * Update or generate a secobj entry using the info in ssp->ss_info.
3200ba2cbe9Sxc151355 */
3210ba2cbe9Sxc151355 /* ARGSUSED */
3220ba2cbe9Sxc151355 static boolean_t
process_secobj_set(dladm_handle_t handle,secobj_db_state_t * ssp,char * buf,secobj_info_t * sip,dladm_status_t * statusp)3234ac67f02SAnurag S. Maskey process_secobj_set(dladm_handle_t handle, secobj_db_state_t *ssp, char *buf,
3244ac67f02SAnurag S. Maskey secobj_info_t *sip, dladm_status_t *statusp)
3250ba2cbe9Sxc151355 {
3260ba2cbe9Sxc151355 char tmpbuf[MAXLINELEN];
3270ba2cbe9Sxc151355 char classbuf[DLADM_STRSIZE];
3280ba2cbe9Sxc151355 char *ptr = tmpbuf, *lim = tmpbuf + MAXLINELEN;
3290ba2cbe9Sxc151355 int i;
3300ba2cbe9Sxc151355
3310ba2cbe9Sxc151355 sip = &ssp->ss_info;
3320ba2cbe9Sxc151355
3330ba2cbe9Sxc151355 ptr += snprintf(ptr, BUFLEN(lim, ptr), "%s\t", sip->si_name);
3340ba2cbe9Sxc151355 ptr += snprintf(ptr, BUFLEN(lim, ptr), "%s\t",
3350ba2cbe9Sxc151355 dladm_secobjclass2str(*sip->si_classp, classbuf));
3360ba2cbe9Sxc151355
3370ba2cbe9Sxc151355 ptr += snprintf(ptr, BUFLEN(lim, ptr), "0x");
3380ba2cbe9Sxc151355 for (i = 0; i < *sip->si_lenp; i++) {
3390ba2cbe9Sxc151355 ptr += snprintf(ptr, BUFLEN(lim, ptr), "%02x",
3400ba2cbe9Sxc151355 sip->si_val[i] & 0xff);
3410ba2cbe9Sxc151355 }
3420ba2cbe9Sxc151355 if (ptr > lim) {
3430ba2cbe9Sxc151355 *statusp = DLADM_STATUS_TOOSMALL;
3440ba2cbe9Sxc151355 return (B_FALSE);
3450ba2cbe9Sxc151355 }
3460ba2cbe9Sxc151355 (void) snprintf(buf, MAXLINELEN, "%s\n", tmpbuf);
3470ba2cbe9Sxc151355 return (B_FALSE);
3480ba2cbe9Sxc151355 }
3490ba2cbe9Sxc151355
3500ba2cbe9Sxc151355 /* ARGSUSED */
3510ba2cbe9Sxc151355 static boolean_t
process_secobj_get(dladm_handle_t handle,secobj_db_state_t * ssp,char * buf,secobj_info_t * sip,dladm_status_t * statusp)3524ac67f02SAnurag S. Maskey process_secobj_get(dladm_handle_t handle, secobj_db_state_t *ssp, char *buf,
3534ac67f02SAnurag S. Maskey secobj_info_t *sip, dladm_status_t *statusp)
3540ba2cbe9Sxc151355 {
3550ba2cbe9Sxc151355 if (*sip->si_lenp > *ssp->ss_info.si_lenp) {
3560ba2cbe9Sxc151355 *statusp = DLADM_STATUS_TOOSMALL;
3570ba2cbe9Sxc151355 return (B_FALSE);
3580ba2cbe9Sxc151355 }
3590ba2cbe9Sxc151355 bcopy(sip->si_val, ssp->ss_info.si_val, *sip->si_lenp);
3600ba2cbe9Sxc151355 *ssp->ss_info.si_lenp = *sip->si_lenp;
3610ba2cbe9Sxc151355 *ssp->ss_info.si_classp = *sip->si_classp;
3620ba2cbe9Sxc151355 return (B_FALSE);
3630ba2cbe9Sxc151355 }
3640ba2cbe9Sxc151355
3650ba2cbe9Sxc151355 /* ARGSUSED */
3660ba2cbe9Sxc151355 static boolean_t
process_secobj_unset(dladm_handle_t handle,secobj_db_state_t * ssp,char * buf,secobj_info_t * sip,dladm_status_t * statusp)3674ac67f02SAnurag S. Maskey process_secobj_unset(dladm_handle_t handle, secobj_db_state_t *ssp, char *buf,
3684ac67f02SAnurag S. Maskey secobj_info_t *sip, dladm_status_t *statusp)
3690ba2cbe9Sxc151355 {
3700ba2cbe9Sxc151355 /*
3710ba2cbe9Sxc151355 * Delete line.
3720ba2cbe9Sxc151355 */
3730ba2cbe9Sxc151355 buf[0] = '\0';
3740ba2cbe9Sxc151355 return (B_FALSE);
3750ba2cbe9Sxc151355 }
3760ba2cbe9Sxc151355
3770ba2cbe9Sxc151355 /* ARGSUSED */
3780ba2cbe9Sxc151355 static boolean_t
process_secobj_walk(dladm_handle_t handle,secobj_db_state_t * ssp,char * buf,secobj_info_t * sip,dladm_status_t * statusp)3794ac67f02SAnurag S. Maskey process_secobj_walk(dladm_handle_t handle, secobj_db_state_t *ssp, char *buf,
3804ac67f02SAnurag S. Maskey secobj_info_t *sip, dladm_status_t *statusp)
3810ba2cbe9Sxc151355 {
3820ba2cbe9Sxc151355 secobj_name_t *snp;
3830ba2cbe9Sxc151355
3840ba2cbe9Sxc151355 if ((snp = malloc(sizeof (*snp))) == NULL)
3850ba2cbe9Sxc151355 return (B_TRUE);
3860ba2cbe9Sxc151355
3870ba2cbe9Sxc151355 if ((snp->sn_name = strdup(sip->si_name)) == NULL) {
3880ba2cbe9Sxc151355 free(snp);
3890ba2cbe9Sxc151355 return (B_TRUE);
3900ba2cbe9Sxc151355 }
3910ba2cbe9Sxc151355
3920ba2cbe9Sxc151355 snp->sn_next = NULL;
3930ba2cbe9Sxc151355 *ssp->ss_namelist = snp;
3940ba2cbe9Sxc151355 ssp->ss_namelist = &snp->sn_next;
3950ba2cbe9Sxc151355 return (B_TRUE);
3960ba2cbe9Sxc151355 }
3970ba2cbe9Sxc151355
3980ba2cbe9Sxc151355 /* ARGSUSED */
3990ba2cbe9Sxc151355 static boolean_t
process_secobj_init(dladm_handle_t handle,secobj_db_state_t * ssp,char * buf,secobj_info_t * sip,dladm_status_t * statusp)4004ac67f02SAnurag S. Maskey process_secobj_init(dladm_handle_t handle, secobj_db_state_t *ssp, char *buf,
4014ac67f02SAnurag S. Maskey secobj_info_t *sip, dladm_status_t *statusp)
4020ba2cbe9Sxc151355 {
4034ac67f02SAnurag S. Maskey *statusp = dladm_set_secobj(handle, sip->si_name, *sip->si_classp,
4044ac67f02SAnurag S. Maskey sip->si_val, *sip->si_lenp,
4054ac67f02SAnurag S. Maskey DLADM_OPT_ACTIVE | DLADM_OPT_CREATE);
4060ba2cbe9Sxc151355 return (B_TRUE);
4070ba2cbe9Sxc151355 }
4080ba2cbe9Sxc151355
4090ba2cbe9Sxc151355 static int
parse_secobj_val(char * buf,secobj_info_t * sip)4100ba2cbe9Sxc151355 parse_secobj_val(char *buf, secobj_info_t *sip)
4110ba2cbe9Sxc151355 {
4120ba2cbe9Sxc151355 if (strncmp(buf, "0x", 2) != 0)
4130ba2cbe9Sxc151355 return (EINVAL);
4140ba2cbe9Sxc151355
4150ba2cbe9Sxc151355 return (hexascii_to_octet(buf + 2, strlen(buf) - 2,
4160ba2cbe9Sxc151355 sip->si_val, sip->si_lenp));
4170ba2cbe9Sxc151355 }
4180ba2cbe9Sxc151355
4190ba2cbe9Sxc151355 static boolean_t
process_secobj_line(dladm_handle_t handle,secobj_db_state_t * ssp,char * buf,dladm_status_t * statusp)4204ac67f02SAnurag S. Maskey process_secobj_line(dladm_handle_t handle, secobj_db_state_t *ssp, char *buf,
4210ba2cbe9Sxc151355 dladm_status_t *statusp)
4220ba2cbe9Sxc151355 {
4230ba2cbe9Sxc151355 secobj_info_t sinfo;
4240ba2cbe9Sxc151355 dladm_secobj_class_t class;
4250ba2cbe9Sxc151355 uint8_t val[DLADM_SECOBJ_VAL_MAX];
4260ba2cbe9Sxc151355 uint_t vlen;
4270ba2cbe9Sxc151355 int i, len, nlen;
4280ba2cbe9Sxc151355 char *str, *lasts;
4290ba2cbe9Sxc151355
4300ba2cbe9Sxc151355 /*
4310ba2cbe9Sxc151355 * Skip leading spaces, blank lines, and comments.
4320ba2cbe9Sxc151355 */
4330ba2cbe9Sxc151355 len = strlen(buf);
4340ba2cbe9Sxc151355 for (i = 0; i < len; i++) {
4350ba2cbe9Sxc151355 if (!isspace(buf[i]))
4360ba2cbe9Sxc151355 break;
4370ba2cbe9Sxc151355 }
4380ba2cbe9Sxc151355 if (i == len || buf[i] == '#')
4390ba2cbe9Sxc151355 return (B_TRUE);
4400ba2cbe9Sxc151355
4410ba2cbe9Sxc151355 str = buf + i;
4420ba2cbe9Sxc151355 if (ssp->ss_info.si_name != NULL) {
4430ba2cbe9Sxc151355 /*
4440ba2cbe9Sxc151355 * Skip objects we're not interested in.
4450ba2cbe9Sxc151355 */
4460ba2cbe9Sxc151355 nlen = strlen(ssp->ss_info.si_name);
4470ba2cbe9Sxc151355 if (strncmp(str, ssp->ss_info.si_name, nlen) != 0 ||
4480ba2cbe9Sxc151355 !isspace(str[nlen]))
4490ba2cbe9Sxc151355 return (B_TRUE);
4500ba2cbe9Sxc151355
4510ba2cbe9Sxc151355 sinfo.si_name = ssp->ss_info.si_name;
4520ba2cbe9Sxc151355 } else {
4530ba2cbe9Sxc151355 /*
4540ba2cbe9Sxc151355 * If an object is not specified, find the object name
4550ba2cbe9Sxc151355 * and assign it to sinfo.si_name.
4560ba2cbe9Sxc151355 */
4570ba2cbe9Sxc151355 if (strtok_r(str, " \n\t", &lasts) == NULL)
4580ba2cbe9Sxc151355 goto fail;
4590ba2cbe9Sxc151355
4600ba2cbe9Sxc151355 nlen = strlen(str);
4610ba2cbe9Sxc151355 sinfo.si_name = str;
4620ba2cbe9Sxc151355 }
4630ba2cbe9Sxc151355 str += nlen + 1;
4640ba2cbe9Sxc151355 if (str >= buf + len)
4650ba2cbe9Sxc151355 goto fail;
4660ba2cbe9Sxc151355
4670ba2cbe9Sxc151355 /*
4680ba2cbe9Sxc151355 * Find the class name.
4690ba2cbe9Sxc151355 */
4700ba2cbe9Sxc151355 if ((str = strtok_r(str, " \n\t", &lasts)) == NULL)
4710ba2cbe9Sxc151355 goto fail;
4720ba2cbe9Sxc151355
4730ba2cbe9Sxc151355 *statusp = dladm_str2secobjclass(str, &class);
4740ba2cbe9Sxc151355 if (*statusp != DLADM_STATUS_OK)
4750ba2cbe9Sxc151355 goto fail;
4760ba2cbe9Sxc151355
4770ba2cbe9Sxc151355 /*
4780ba2cbe9Sxc151355 * Find the object value.
4790ba2cbe9Sxc151355 */
4800ba2cbe9Sxc151355 if ((str = strtok_r(NULL, " \n\t", &lasts)) == NULL)
4810ba2cbe9Sxc151355 goto fail;
4820ba2cbe9Sxc151355
4830ba2cbe9Sxc151355 vlen = DLADM_SECOBJ_VAL_MAX;
4840ba2cbe9Sxc151355 sinfo.si_classp = &class;
4850ba2cbe9Sxc151355 sinfo.si_val = val;
4860ba2cbe9Sxc151355 sinfo.si_lenp = &vlen;
4870ba2cbe9Sxc151355 if (parse_secobj_val(str, &sinfo) != 0)
4880ba2cbe9Sxc151355 goto fail;
4890ba2cbe9Sxc151355
4904ac67f02SAnurag S. Maskey return ((*ssp->ss_op)(handle, ssp, buf, &sinfo, statusp));
4910ba2cbe9Sxc151355
4920ba2cbe9Sxc151355 fail:
4930ba2cbe9Sxc151355 /*
4940ba2cbe9Sxc151355 * Delete corrupted line.
4950ba2cbe9Sxc151355 */
4960ba2cbe9Sxc151355 buf[0] = '\0';
4970ba2cbe9Sxc151355 return (B_TRUE);
4980ba2cbe9Sxc151355 }
4990ba2cbe9Sxc151355
5000ba2cbe9Sxc151355 static dladm_status_t
process_secobj_db(dladm_handle_t handle,void * arg,FILE * fp,FILE * nfp)5014ac67f02SAnurag S. Maskey process_secobj_db(dladm_handle_t handle, void *arg, FILE *fp, FILE *nfp)
5020ba2cbe9Sxc151355 {
5030ba2cbe9Sxc151355 secobj_db_state_t *ssp = arg;
5040ba2cbe9Sxc151355 dladm_status_t status = DLADM_STATUS_OK;
5050ba2cbe9Sxc151355 char buf[MAXLINELEN];
5060ba2cbe9Sxc151355 boolean_t cont = B_TRUE;
5070ba2cbe9Sxc151355
5080ba2cbe9Sxc151355 /*
5090ba2cbe9Sxc151355 * This loop processes each line of the configuration file.
5100ba2cbe9Sxc151355 * buf can potentially be modified by process_secobj_line().
5110ba2cbe9Sxc151355 * If this is a write operation and buf is not truncated, buf will
5120ba2cbe9Sxc151355 * be written to disk. process_secobj_line() will no longer be
5130ba2cbe9Sxc151355 * called after it returns B_FALSE; at which point the remainder
5140ba2cbe9Sxc151355 * of the file will continue to be read and, if necessary, written
5150ba2cbe9Sxc151355 * to disk as well.
5160ba2cbe9Sxc151355 */
5170ba2cbe9Sxc151355 while (fgets(buf, MAXLINELEN, fp) != NULL) {
5180ba2cbe9Sxc151355 if (cont)
5194ac67f02SAnurag S. Maskey cont = process_secobj_line(handle, ssp, buf, &status);
5200ba2cbe9Sxc151355
5210ba2cbe9Sxc151355 if (nfp != NULL && buf[0] != '\0' && fputs(buf, nfp) == EOF) {
5220ba2cbe9Sxc151355 status = dladm_errno2status(errno);
5230ba2cbe9Sxc151355 break;
5240ba2cbe9Sxc151355 }
5250ba2cbe9Sxc151355 }
5260ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK || !cont)
5270ba2cbe9Sxc151355 return (status);
5280ba2cbe9Sxc151355
5290ba2cbe9Sxc151355 if (ssp->ss_op == process_secobj_set) {
5300ba2cbe9Sxc151355 /*
5310ba2cbe9Sxc151355 * If the specified object is not found above, we add the
5320ba2cbe9Sxc151355 * object to the configuration file.
5330ba2cbe9Sxc151355 */
5344ac67f02SAnurag S. Maskey (void) (*ssp->ss_op)(handle, ssp, buf, NULL, &status);
5350ba2cbe9Sxc151355 if (status == DLADM_STATUS_OK && fputs(buf, nfp) == EOF)
5360ba2cbe9Sxc151355 status = dladm_errno2status(errno);
5370ba2cbe9Sxc151355 }
5380ba2cbe9Sxc151355
5390ba2cbe9Sxc151355 if (ssp->ss_op == process_secobj_unset ||
5400ba2cbe9Sxc151355 ssp->ss_op == process_secobj_get)
5410ba2cbe9Sxc151355 status = DLADM_STATUS_NOTFOUND;
5420ba2cbe9Sxc151355
5430ba2cbe9Sxc151355 return (status);
5440ba2cbe9Sxc151355 }
5450ba2cbe9Sxc151355
5464ac67f02SAnurag S. Maskey #define SECOBJ_RW_DB(handle, statep, writeop) \
547*6ba597c5SAnurag S. Maskey (i_dladm_rw_db(handle, "/etc/dladm/secobj.conf", \
548*6ba597c5SAnurag S. Maskey S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, \
5490ba2cbe9Sxc151355 process_secobj_db, (statep), (writeop)))
5500ba2cbe9Sxc151355
5510ba2cbe9Sxc151355 static dladm_status_t
i_dladm_set_secobj_db(dladm_handle_t handle,const char * obj_name,dladm_secobj_class_t class,uint8_t * obj_val,uint_t obj_len)5524ac67f02SAnurag S. Maskey i_dladm_set_secobj_db(dladm_handle_t handle, const char *obj_name,
5534ac67f02SAnurag S. Maskey dladm_secobj_class_t class, uint8_t *obj_val, uint_t obj_len)
5540ba2cbe9Sxc151355 {
5550ba2cbe9Sxc151355 secobj_db_state_t state;
5560ba2cbe9Sxc151355
5570ba2cbe9Sxc151355 state.ss_op = process_secobj_set;
5580ba2cbe9Sxc151355 state.ss_info.si_name = obj_name;
5590ba2cbe9Sxc151355 state.ss_info.si_classp = &class;
5600ba2cbe9Sxc151355 state.ss_info.si_val = obj_val;
5610ba2cbe9Sxc151355 state.ss_info.si_lenp = &obj_len;
5620ba2cbe9Sxc151355 state.ss_namelist = NULL;
5630ba2cbe9Sxc151355
5644ac67f02SAnurag S. Maskey return (SECOBJ_RW_DB(handle, &state, B_TRUE));
5650ba2cbe9Sxc151355 }
5660ba2cbe9Sxc151355
5670ba2cbe9Sxc151355 static dladm_status_t
i_dladm_get_secobj_db(dladm_handle_t handle,const char * obj_name,dladm_secobj_class_t * classp,uint8_t * obj_val,uint_t * obj_lenp)5684ac67f02SAnurag S. Maskey i_dladm_get_secobj_db(dladm_handle_t handle, const char *obj_name,
5694ac67f02SAnurag S. Maskey dladm_secobj_class_t *classp, uint8_t *obj_val, uint_t *obj_lenp)
5700ba2cbe9Sxc151355 {
5710ba2cbe9Sxc151355 secobj_db_state_t state;
5720ba2cbe9Sxc151355
5730ba2cbe9Sxc151355 state.ss_op = process_secobj_get;
5740ba2cbe9Sxc151355 state.ss_info.si_name = obj_name;
5750ba2cbe9Sxc151355 state.ss_info.si_classp = classp;
5760ba2cbe9Sxc151355 state.ss_info.si_val = obj_val;
5770ba2cbe9Sxc151355 state.ss_info.si_lenp = obj_lenp;
5780ba2cbe9Sxc151355 state.ss_namelist = NULL;
5790ba2cbe9Sxc151355
5804ac67f02SAnurag S. Maskey return (SECOBJ_RW_DB(handle, &state, B_FALSE));
5810ba2cbe9Sxc151355 }
5820ba2cbe9Sxc151355
5830ba2cbe9Sxc151355 static dladm_status_t
i_dladm_unset_secobj_db(dladm_handle_t handle,const char * obj_name)5844ac67f02SAnurag S. Maskey i_dladm_unset_secobj_db(dladm_handle_t handle, const char *obj_name)
5850ba2cbe9Sxc151355 {
5860ba2cbe9Sxc151355 secobj_db_state_t state;
5870ba2cbe9Sxc151355
5880ba2cbe9Sxc151355 state.ss_op = process_secobj_unset;
5890ba2cbe9Sxc151355 state.ss_info.si_name = obj_name;
5900ba2cbe9Sxc151355 state.ss_info.si_classp = NULL;
5910ba2cbe9Sxc151355 state.ss_info.si_val = NULL;
5920ba2cbe9Sxc151355 state.ss_info.si_lenp = NULL;
5930ba2cbe9Sxc151355 state.ss_namelist = NULL;
5940ba2cbe9Sxc151355
5954ac67f02SAnurag S. Maskey return (SECOBJ_RW_DB(handle, &state, B_TRUE));
5960ba2cbe9Sxc151355 }
5970ba2cbe9Sxc151355
5980ba2cbe9Sxc151355 static dladm_status_t
i_dladm_walk_secobj_db(dladm_handle_t handle,void * arg,boolean_t (* func)(dladm_handle_t,void *,const char *))5994ac67f02SAnurag S. Maskey i_dladm_walk_secobj_db(dladm_handle_t handle, void *arg,
6004ac67f02SAnurag S. Maskey boolean_t (*func)(dladm_handle_t, void *, const char *))
6010ba2cbe9Sxc151355 {
6020ba2cbe9Sxc151355 secobj_db_state_t state;
6030ba2cbe9Sxc151355 secobj_name_t *snp = NULL, *fsnp;
6040ba2cbe9Sxc151355 dladm_status_t status;
6050ba2cbe9Sxc151355 boolean_t cont = B_TRUE;
6060ba2cbe9Sxc151355
6070ba2cbe9Sxc151355 state.ss_op = process_secobj_walk;
6080ba2cbe9Sxc151355 state.ss_info.si_name = NULL;
6090ba2cbe9Sxc151355 state.ss_info.si_classp = NULL;
6100ba2cbe9Sxc151355 state.ss_info.si_val = NULL;
6110ba2cbe9Sxc151355 state.ss_info.si_lenp = NULL;
6120ba2cbe9Sxc151355 state.ss_namelist = &snp;
6130ba2cbe9Sxc151355
6144ac67f02SAnurag S. Maskey status = SECOBJ_RW_DB(handle, &state, B_FALSE);
6150ba2cbe9Sxc151355 if (status != DLADM_STATUS_OK)
6160ba2cbe9Sxc151355 return (status);
6170ba2cbe9Sxc151355
6180ba2cbe9Sxc151355 while (snp != NULL) {
6190ba2cbe9Sxc151355 fsnp = snp;
6200ba2cbe9Sxc151355 snp = snp->sn_next;
6210ba2cbe9Sxc151355 if (cont)
6224ac67f02SAnurag S. Maskey cont = func(handle, arg, fsnp->sn_name);
6230ba2cbe9Sxc151355 free(fsnp->sn_name);
6240ba2cbe9Sxc151355 free(fsnp);
6250ba2cbe9Sxc151355 }
6260ba2cbe9Sxc151355 return (status);
6270ba2cbe9Sxc151355 }
6280ba2cbe9Sxc151355
6290ba2cbe9Sxc151355 dladm_status_t
dladm_init_secobj(dladm_handle_t handle)6304ac67f02SAnurag S. Maskey dladm_init_secobj(dladm_handle_t handle)
6310ba2cbe9Sxc151355 {
6320ba2cbe9Sxc151355 secobj_db_state_t state;
6330ba2cbe9Sxc151355
6340ba2cbe9Sxc151355 state.ss_op = process_secobj_init;
6350ba2cbe9Sxc151355 state.ss_info.si_name = NULL;
6360ba2cbe9Sxc151355 state.ss_info.si_classp = NULL;
6370ba2cbe9Sxc151355 state.ss_info.si_val = NULL;
6380ba2cbe9Sxc151355 state.ss_info.si_lenp = NULL;
6390ba2cbe9Sxc151355 state.ss_namelist = NULL;
6400ba2cbe9Sxc151355
6414ac67f02SAnurag S. Maskey return (SECOBJ_RW_DB(handle, &state, B_FALSE));
6420ba2cbe9Sxc151355 }
643a9489f61SAnurag S. Maskey
644a9489f61SAnurag S. Maskey boolean_t
dladm_valid_secobj_name(const char * secobj_name)645a9489f61SAnurag S. Maskey dladm_valid_secobj_name(const char *secobj_name)
646a9489f61SAnurag S. Maskey {
647a9489f61SAnurag S. Maskey size_t len = strlen(secobj_name);
648a9489f61SAnurag S. Maskey const char *cp;
649a9489f61SAnurag S. Maskey
650a9489f61SAnurag S. Maskey if (len + 1 > DLADM_SECOBJ_NAME_MAX)
651a9489f61SAnurag S. Maskey return (B_FALSE);
652a9489f61SAnurag S. Maskey
653a9489f61SAnurag S. Maskey /*
654a9489f61SAnurag S. Maskey * The legal characters in a secobj name are:
655a9489f61SAnurag S. Maskey * alphanumeric (a-z, A-Z, 0-9), '.', '_', '-'.
656a9489f61SAnurag S. Maskey */
657a9489f61SAnurag S. Maskey for (cp = secobj_name; *cp != '\0'; cp++) {
658a9489f61SAnurag S. Maskey if (!isalnum(*cp) &&
659a9489f61SAnurag S. Maskey (*cp != '.') && (*cp != '_') && (*cp != '-'))
660a9489f61SAnurag S. Maskey return (B_FALSE);
661a9489f61SAnurag S. Maskey }
662a9489f61SAnurag S. Maskey
663a9489f61SAnurag S. Maskey return (B_TRUE);
664a9489f61SAnurag S. Maskey }
665