1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate #include <errno.h> 30*0Sstevel@tonic-gate #include <fcntl.h> 31*0Sstevel@tonic-gate #include <stdio.h> 32*0Sstevel@tonic-gate #include <stdlib.h> 33*0Sstevel@tonic-gate #include <strings.h> 34*0Sstevel@tonic-gate #include <time.h> 35*0Sstevel@tonic-gate #include <unistd.h> 36*0Sstevel@tonic-gate #include <locale.h> 37*0Sstevel@tonic-gate #include <sys/types.h> 38*0Sstevel@tonic-gate #include <sys/stat.h> 39*0Sstevel@tonic-gate #include "cryptoadm.h" 40*0Sstevel@tonic-gate 41*0Sstevel@tonic-gate static int err; /* To store errno which may be overwritten by gettext() */ 42*0Sstevel@tonic-gate static int build_entrylist(entry_t *, entrylist_t **); 43*0Sstevel@tonic-gate static entry_t *dup_entry(entry_t *); 44*0Sstevel@tonic-gate static mechlist_t *dup_mechlist(mechlist_t *); 45*0Sstevel@tonic-gate static entry_t *getent(char *, entrylist_t *); 46*0Sstevel@tonic-gate static int interpret(char *, entry_t **); 47*0Sstevel@tonic-gate static int parse_dislist(char *, entry_t *); 48*0Sstevel@tonic-gate 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate /* 51*0Sstevel@tonic-gate * Duplicate the mechanism list. A null pointer is returned if the storage 52*0Sstevel@tonic-gate * space available is insufficient or the input argument is NULL. 53*0Sstevel@tonic-gate */ 54*0Sstevel@tonic-gate static mechlist_t * 55*0Sstevel@tonic-gate dup_mechlist(mechlist_t *plist) 56*0Sstevel@tonic-gate { 57*0Sstevel@tonic-gate mechlist_t *pres = NULL; 58*0Sstevel@tonic-gate mechlist_t *pcur; 59*0Sstevel@tonic-gate mechlist_t *ptmp; 60*0Sstevel@tonic-gate int rc = SUCCESS; 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gate while (plist != NULL) { 63*0Sstevel@tonic-gate if (!(ptmp = create_mech(plist->name))) { 64*0Sstevel@tonic-gate rc = FAILURE; 65*0Sstevel@tonic-gate break; 66*0Sstevel@tonic-gate } 67*0Sstevel@tonic-gate 68*0Sstevel@tonic-gate if (pres == NULL) { 69*0Sstevel@tonic-gate pres = pcur = ptmp; 70*0Sstevel@tonic-gate } else { 71*0Sstevel@tonic-gate pcur->next = ptmp; 72*0Sstevel@tonic-gate pcur = pcur->next; 73*0Sstevel@tonic-gate } 74*0Sstevel@tonic-gate plist = plist->next; 75*0Sstevel@tonic-gate } 76*0Sstevel@tonic-gate 77*0Sstevel@tonic-gate if (rc != SUCCESS) { 78*0Sstevel@tonic-gate free_mechlist(pres); 79*0Sstevel@tonic-gate return (NULL); 80*0Sstevel@tonic-gate } 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate return (pres); 83*0Sstevel@tonic-gate } 84*0Sstevel@tonic-gate 85*0Sstevel@tonic-gate 86*0Sstevel@tonic-gate /* 87*0Sstevel@tonic-gate * Get the number of mechanisms in the mechanism list. 88*0Sstevel@tonic-gate */ 89*0Sstevel@tonic-gate int 90*0Sstevel@tonic-gate get_mech_count(mechlist_t *plist) 91*0Sstevel@tonic-gate { 92*0Sstevel@tonic-gate int count = 0; 93*0Sstevel@tonic-gate 94*0Sstevel@tonic-gate while (plist != NULL) { 95*0Sstevel@tonic-gate count++; 96*0Sstevel@tonic-gate plist = plist->next; 97*0Sstevel@tonic-gate } 98*0Sstevel@tonic-gate return (count); 99*0Sstevel@tonic-gate } 100*0Sstevel@tonic-gate 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate /* 103*0Sstevel@tonic-gate * Duplicate an entry. A null pointer is returned if the storage space 104*0Sstevel@tonic-gate * available is insufficient or the input argument is NULL. 105*0Sstevel@tonic-gate */ 106*0Sstevel@tonic-gate static entry_t * 107*0Sstevel@tonic-gate dup_entry(entry_t *pent1) 108*0Sstevel@tonic-gate { 109*0Sstevel@tonic-gate entry_t *pent2 = NULL; 110*0Sstevel@tonic-gate 111*0Sstevel@tonic-gate if (pent1 == NULL) { 112*0Sstevel@tonic-gate return (NULL); 113*0Sstevel@tonic-gate } 114*0Sstevel@tonic-gate 115*0Sstevel@tonic-gate if ((pent2 = malloc(sizeof (entry_t))) == NULL) { 116*0Sstevel@tonic-gate cryptodebug("out of memory."); 117*0Sstevel@tonic-gate return (NULL); 118*0Sstevel@tonic-gate } 119*0Sstevel@tonic-gate 120*0Sstevel@tonic-gate (void) strlcpy(pent2->name, pent1->name, sizeof (pent2->name)); 121*0Sstevel@tonic-gate pent2->sup_count = pent1->sup_count; 122*0Sstevel@tonic-gate pent2->dis_count = pent1->dis_count; 123*0Sstevel@tonic-gate pent2->suplist = NULL; 124*0Sstevel@tonic-gate pent2->dislist = NULL; 125*0Sstevel@tonic-gate if (pent1->suplist != NULL) { 126*0Sstevel@tonic-gate pent2->suplist = dup_mechlist(pent1->suplist); 127*0Sstevel@tonic-gate if (pent2->suplist == NULL) { 128*0Sstevel@tonic-gate free_entry(pent2); 129*0Sstevel@tonic-gate return (NULL); 130*0Sstevel@tonic-gate } 131*0Sstevel@tonic-gate } 132*0Sstevel@tonic-gate if (pent1->dislist != NULL) { 133*0Sstevel@tonic-gate pent2->dislist = dup_mechlist(pent1->dislist); 134*0Sstevel@tonic-gate if (pent2->dislist == NULL) { 135*0Sstevel@tonic-gate free_entry(pent2); 136*0Sstevel@tonic-gate return (NULL); 137*0Sstevel@tonic-gate } 138*0Sstevel@tonic-gate } 139*0Sstevel@tonic-gate 140*0Sstevel@tonic-gate return (pent2); 141*0Sstevel@tonic-gate } 142*0Sstevel@tonic-gate 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gate /* 145*0Sstevel@tonic-gate * This routine parses the disabledlist or the supportedlist of an entry 146*0Sstevel@tonic-gate * in the kcf.conf configuration file. 147*0Sstevel@tonic-gate * 148*0Sstevel@tonic-gate * Arguments: 149*0Sstevel@tonic-gate * buf: an input argument which is a char string with the format of 150*0Sstevel@tonic-gate * "disabledlist=m1,m2,..." or "supportedlist=m1,m2,..." 151*0Sstevel@tonic-gate * pent: the entry for the disabledlist. This is an IN/OUT argument. 152*0Sstevel@tonic-gate * 153*0Sstevel@tonic-gate * Return value: SUCCESS or FAILURE. 154*0Sstevel@tonic-gate */ 155*0Sstevel@tonic-gate static int 156*0Sstevel@tonic-gate parse_dislist(char *buf, entry_t *pent) 157*0Sstevel@tonic-gate { 158*0Sstevel@tonic-gate mechlist_t *pmech; 159*0Sstevel@tonic-gate mechlist_t *phead; 160*0Sstevel@tonic-gate char *next_token; 161*0Sstevel@tonic-gate char *value; 162*0Sstevel@tonic-gate int count; 163*0Sstevel@tonic-gate int supflag = B_FALSE; 164*0Sstevel@tonic-gate int disflag = B_FALSE; 165*0Sstevel@tonic-gate int rc = SUCCESS; 166*0Sstevel@tonic-gate 167*0Sstevel@tonic-gate if (strncmp(buf, EF_SUPPORTED, strlen(EF_SUPPORTED)) == 0) { 168*0Sstevel@tonic-gate supflag = B_TRUE; 169*0Sstevel@tonic-gate } else if (strncmp(buf, EF_DISABLED, strlen(EF_DISABLED)) == 0) { 170*0Sstevel@tonic-gate disflag = B_TRUE; 171*0Sstevel@tonic-gate } else { 172*0Sstevel@tonic-gate /* should not come here */ 173*0Sstevel@tonic-gate return (FAILURE); 174*0Sstevel@tonic-gate } 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate if (value = strpbrk(buf, SEP_EQUAL)) { 177*0Sstevel@tonic-gate value++; /* get rid of = */ 178*0Sstevel@tonic-gate } else { 179*0Sstevel@tonic-gate cryptodebug("failed to parse the kcf.conf file."); 180*0Sstevel@tonic-gate return (FAILURE); 181*0Sstevel@tonic-gate } 182*0Sstevel@tonic-gate 183*0Sstevel@tonic-gate if ((next_token = strtok(value, SEP_COMMA)) == NULL) { 184*0Sstevel@tonic-gate cryptodebug("failed to parse the kcf.conf file."); 185*0Sstevel@tonic-gate return (FAILURE); 186*0Sstevel@tonic-gate } 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate if ((pmech = create_mech(next_token)) == NULL) { 189*0Sstevel@tonic-gate return (FAILURE); 190*0Sstevel@tonic-gate } 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate if (supflag) { 193*0Sstevel@tonic-gate pent->suplist = phead = pmech; 194*0Sstevel@tonic-gate } else if (disflag) { 195*0Sstevel@tonic-gate pent->dislist = phead = pmech; 196*0Sstevel@tonic-gate } 197*0Sstevel@tonic-gate 198*0Sstevel@tonic-gate count = 1; 199*0Sstevel@tonic-gate while (next_token) { 200*0Sstevel@tonic-gate if (next_token = strtok(NULL, SEP_COMMA)) { 201*0Sstevel@tonic-gate if ((pmech = create_mech(next_token)) == NULL) { 202*0Sstevel@tonic-gate rc = FAILURE; 203*0Sstevel@tonic-gate break; 204*0Sstevel@tonic-gate } 205*0Sstevel@tonic-gate count++; 206*0Sstevel@tonic-gate phead->next = pmech; 207*0Sstevel@tonic-gate phead = phead->next; 208*0Sstevel@tonic-gate } 209*0Sstevel@tonic-gate } 210*0Sstevel@tonic-gate 211*0Sstevel@tonic-gate if (rc == SUCCESS) { 212*0Sstevel@tonic-gate if (supflag) { 213*0Sstevel@tonic-gate pent->sup_count = count; 214*0Sstevel@tonic-gate } else if (disflag) { 215*0Sstevel@tonic-gate pent->dis_count = count; 216*0Sstevel@tonic-gate } 217*0Sstevel@tonic-gate } else { 218*0Sstevel@tonic-gate free_mechlist(phead); 219*0Sstevel@tonic-gate } 220*0Sstevel@tonic-gate 221*0Sstevel@tonic-gate return (rc); 222*0Sstevel@tonic-gate } 223*0Sstevel@tonic-gate 224*0Sstevel@tonic-gate 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gate /* 227*0Sstevel@tonic-gate * This routine converts a char string into an entry_t structure 228*0Sstevel@tonic-gate */ 229*0Sstevel@tonic-gate static int 230*0Sstevel@tonic-gate interpret(char *buf, entry_t **ppent) 231*0Sstevel@tonic-gate { 232*0Sstevel@tonic-gate entry_t *pent; 233*0Sstevel@tonic-gate char *token1; 234*0Sstevel@tonic-gate char *token2; 235*0Sstevel@tonic-gate char *token3; 236*0Sstevel@tonic-gate int rc; 237*0Sstevel@tonic-gate 238*0Sstevel@tonic-gate if ((token1 = strtok(buf, SEP_COLON)) == NULL) { /* buf is NULL */ 239*0Sstevel@tonic-gate return (FAILURE); 240*0Sstevel@tonic-gate }; 241*0Sstevel@tonic-gate 242*0Sstevel@tonic-gate pent = malloc(sizeof (entry_t)); 243*0Sstevel@tonic-gate if (pent == NULL) { 244*0Sstevel@tonic-gate cryptodebug("out of memory."); 245*0Sstevel@tonic-gate return (FAILURE); 246*0Sstevel@tonic-gate } 247*0Sstevel@tonic-gate (void) strlcpy(pent->name, token1, sizeof (pent->name)); 248*0Sstevel@tonic-gate pent->suplist = NULL; 249*0Sstevel@tonic-gate pent->dislist = NULL; 250*0Sstevel@tonic-gate pent->sup_count = 0; 251*0Sstevel@tonic-gate pent->dis_count = 0; 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gate if ((token2 = strtok(NULL, SEP_SEMICOLON)) == NULL) { 254*0Sstevel@tonic-gate /* The entry contains a provider name only */ 255*0Sstevel@tonic-gate free_entry(pent); 256*0Sstevel@tonic-gate return (FAILURE); 257*0Sstevel@tonic-gate } 258*0Sstevel@tonic-gate 259*0Sstevel@tonic-gate /* need to get token3 first to satisfy nested strtok invocations */ 260*0Sstevel@tonic-gate token3 = strtok(NULL, SEP_SEMICOLON); 261*0Sstevel@tonic-gate 262*0Sstevel@tonic-gate if (token2 && ((rc = parse_dislist(token2, pent)) != SUCCESS)) { 263*0Sstevel@tonic-gate free_entry(pent); 264*0Sstevel@tonic-gate return (rc); 265*0Sstevel@tonic-gate } 266*0Sstevel@tonic-gate 267*0Sstevel@tonic-gate if (token3 && ((rc = parse_dislist(token3, pent)) != SUCCESS)) { 268*0Sstevel@tonic-gate free_entry(pent); 269*0Sstevel@tonic-gate return (rc); 270*0Sstevel@tonic-gate } 271*0Sstevel@tonic-gate 272*0Sstevel@tonic-gate *ppent = pent; 273*0Sstevel@tonic-gate return (SUCCESS); 274*0Sstevel@tonic-gate } 275*0Sstevel@tonic-gate 276*0Sstevel@tonic-gate 277*0Sstevel@tonic-gate /* 278*0Sstevel@tonic-gate * Add an entry to the end of an entry list. If the entry list is NULL, will 279*0Sstevel@tonic-gate * create an entry list with the pent. 280*0Sstevel@tonic-gate */ 281*0Sstevel@tonic-gate static int 282*0Sstevel@tonic-gate build_entrylist(entry_t *pent, entrylist_t **pplist) 283*0Sstevel@tonic-gate { 284*0Sstevel@tonic-gate entrylist_t *pentlist; 285*0Sstevel@tonic-gate entrylist_t *pcur; 286*0Sstevel@tonic-gate 287*0Sstevel@tonic-gate pentlist = malloc(sizeof (entrylist_t)); 288*0Sstevel@tonic-gate if (pentlist == NULL) { 289*0Sstevel@tonic-gate cryptodebug("out of memory."); 290*0Sstevel@tonic-gate return (FAILURE); 291*0Sstevel@tonic-gate } 292*0Sstevel@tonic-gate pentlist->pent = pent; 293*0Sstevel@tonic-gate pentlist->next = NULL; 294*0Sstevel@tonic-gate 295*0Sstevel@tonic-gate if (*pplist) { 296*0Sstevel@tonic-gate pcur = *pplist; 297*0Sstevel@tonic-gate while (pcur->next != NULL) 298*0Sstevel@tonic-gate pcur = pcur->next; 299*0Sstevel@tonic-gate pcur->next = pentlist; 300*0Sstevel@tonic-gate } else { /* empty list */ 301*0Sstevel@tonic-gate *pplist = pentlist; 302*0Sstevel@tonic-gate } 303*0Sstevel@tonic-gate 304*0Sstevel@tonic-gate return (SUCCESS); 305*0Sstevel@tonic-gate } 306*0Sstevel@tonic-gate 307*0Sstevel@tonic-gate 308*0Sstevel@tonic-gate 309*0Sstevel@tonic-gate /* 310*0Sstevel@tonic-gate * Find the entry with the "provname" name from the entry list and duplicate 311*0Sstevel@tonic-gate * it. 312*0Sstevel@tonic-gate */ 313*0Sstevel@tonic-gate static entry_t * 314*0Sstevel@tonic-gate getent(char *provname, entrylist_t *entrylist) 315*0Sstevel@tonic-gate { 316*0Sstevel@tonic-gate boolean_t found = B_FALSE; 317*0Sstevel@tonic-gate entry_t *pent1 = NULL; 318*0Sstevel@tonic-gate 319*0Sstevel@tonic-gate if ((provname == NULL) || (entrylist == NULL)) { 320*0Sstevel@tonic-gate return (NULL); 321*0Sstevel@tonic-gate } 322*0Sstevel@tonic-gate 323*0Sstevel@tonic-gate while (!found && entrylist) { 324*0Sstevel@tonic-gate if (strcmp(entrylist->pent->name, provname) == 0) { 325*0Sstevel@tonic-gate found = B_TRUE; 326*0Sstevel@tonic-gate pent1 = entrylist->pent; 327*0Sstevel@tonic-gate } else { 328*0Sstevel@tonic-gate entrylist = entrylist->next; 329*0Sstevel@tonic-gate } 330*0Sstevel@tonic-gate } 331*0Sstevel@tonic-gate 332*0Sstevel@tonic-gate if (!found) { 333*0Sstevel@tonic-gate return (NULL); 334*0Sstevel@tonic-gate } 335*0Sstevel@tonic-gate 336*0Sstevel@tonic-gate /* duplicate the entry to be returned */ 337*0Sstevel@tonic-gate return (dup_entry(pent1)); 338*0Sstevel@tonic-gate } 339*0Sstevel@tonic-gate 340*0Sstevel@tonic-gate 341*0Sstevel@tonic-gate 342*0Sstevel@tonic-gate void 343*0Sstevel@tonic-gate free_entry(entry_t *pent) 344*0Sstevel@tonic-gate { 345*0Sstevel@tonic-gate if (pent == NULL) { 346*0Sstevel@tonic-gate return; 347*0Sstevel@tonic-gate } else { 348*0Sstevel@tonic-gate free_mechlist(pent->suplist); 349*0Sstevel@tonic-gate free_mechlist(pent->dislist); 350*0Sstevel@tonic-gate free(pent); 351*0Sstevel@tonic-gate } 352*0Sstevel@tonic-gate } 353*0Sstevel@tonic-gate 354*0Sstevel@tonic-gate 355*0Sstevel@tonic-gate void 356*0Sstevel@tonic-gate free_entrylist(entrylist_t *entrylist) 357*0Sstevel@tonic-gate { 358*0Sstevel@tonic-gate entrylist_t *pnext; 359*0Sstevel@tonic-gate 360*0Sstevel@tonic-gate while (entrylist != NULL) { 361*0Sstevel@tonic-gate pnext = entrylist->next; 362*0Sstevel@tonic-gate free_entry(entrylist->pent); 363*0Sstevel@tonic-gate entrylist = pnext; 364*0Sstevel@tonic-gate } 365*0Sstevel@tonic-gate } 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gate 368*0Sstevel@tonic-gate /* 369*0Sstevel@tonic-gate * Convert an entry to a string. This routine builds a string for the entry 370*0Sstevel@tonic-gate * to be inserted in the config file. Based on the content of each entry, 371*0Sstevel@tonic-gate * the result string can be one of the 4 forms: 372*0Sstevel@tonic-gate * - name 373*0Sstevel@tonic-gate * - name:supportedlist=m1,m2,...,mj 374*0Sstevel@tonic-gate * - name:disabledlist=m1,m2,...,mj 375*0Sstevel@tonic-gate * - name:supportedlist=m1,...,mj;disabledlist=m1,m2,...,mk 376*0Sstevel@tonic-gate * 377*0Sstevel@tonic-gate * Note that the caller is responsible for freeing the returned string. 378*0Sstevel@tonic-gate */ 379*0Sstevel@tonic-gate char * 380*0Sstevel@tonic-gate ent2str(entry_t *pent) 381*0Sstevel@tonic-gate { 382*0Sstevel@tonic-gate char *buf; 383*0Sstevel@tonic-gate mechlist_t *phead; 384*0Sstevel@tonic-gate boolean_t supflag = B_FALSE; 385*0Sstevel@tonic-gate 386*0Sstevel@tonic-gate 387*0Sstevel@tonic-gate if (pent == NULL) { 388*0Sstevel@tonic-gate return (NULL); 389*0Sstevel@tonic-gate } 390*0Sstevel@tonic-gate 391*0Sstevel@tonic-gate if ((buf = malloc(BUFSIZ)) == NULL) { 392*0Sstevel@tonic-gate return (NULL); 393*0Sstevel@tonic-gate } 394*0Sstevel@tonic-gate 395*0Sstevel@tonic-gate /* convert the provider name */ 396*0Sstevel@tonic-gate if (strlcpy(buf, pent->name, BUFSIZ) >= BUFSIZ) { 397*0Sstevel@tonic-gate free(buf); 398*0Sstevel@tonic-gate return (NULL); 399*0Sstevel@tonic-gate } 400*0Sstevel@tonic-gate 401*0Sstevel@tonic-gate /* convert the supported list if any */ 402*0Sstevel@tonic-gate phead = pent->suplist; 403*0Sstevel@tonic-gate if (phead != NULL) { 404*0Sstevel@tonic-gate supflag = B_TRUE; 405*0Sstevel@tonic-gate 406*0Sstevel@tonic-gate if (strlcat(buf, SEP_COLON, BUFSIZ) >= BUFSIZ) { 407*0Sstevel@tonic-gate free(buf); 408*0Sstevel@tonic-gate return (NULL); 409*0Sstevel@tonic-gate } 410*0Sstevel@tonic-gate 411*0Sstevel@tonic-gate if (strlcat(buf, EF_SUPPORTED, BUFSIZ) >= BUFSIZ) { 412*0Sstevel@tonic-gate free(buf); 413*0Sstevel@tonic-gate return (NULL); 414*0Sstevel@tonic-gate } 415*0Sstevel@tonic-gate 416*0Sstevel@tonic-gate while (phead != NULL) { 417*0Sstevel@tonic-gate if (strlcat(buf, phead->name, BUFSIZ) >= BUFSIZ) { 418*0Sstevel@tonic-gate free(buf); 419*0Sstevel@tonic-gate return (NULL); 420*0Sstevel@tonic-gate } 421*0Sstevel@tonic-gate 422*0Sstevel@tonic-gate phead = phead->next; 423*0Sstevel@tonic-gate if (phead != NULL) { 424*0Sstevel@tonic-gate if (strlcat(buf, SEP_COMMA, BUFSIZ) 425*0Sstevel@tonic-gate >= BUFSIZ) { 426*0Sstevel@tonic-gate free(buf); 427*0Sstevel@tonic-gate return (NULL); 428*0Sstevel@tonic-gate } 429*0Sstevel@tonic-gate } 430*0Sstevel@tonic-gate } 431*0Sstevel@tonic-gate } 432*0Sstevel@tonic-gate 433*0Sstevel@tonic-gate /* convert the disabled list if any */ 434*0Sstevel@tonic-gate phead = pent->dislist; 435*0Sstevel@tonic-gate if (phead != NULL) { 436*0Sstevel@tonic-gate if (supflag) { 437*0Sstevel@tonic-gate if (strlcat(buf, ";disabledlist=", BUFSIZ) >= BUFSIZ) { 438*0Sstevel@tonic-gate free(buf); 439*0Sstevel@tonic-gate return (NULL); 440*0Sstevel@tonic-gate } 441*0Sstevel@tonic-gate } else { 442*0Sstevel@tonic-gate if (strlcat(buf, ":disabledlist=", BUFSIZ) >= BUFSIZ) { 443*0Sstevel@tonic-gate free(buf); 444*0Sstevel@tonic-gate return (NULL); 445*0Sstevel@tonic-gate } 446*0Sstevel@tonic-gate } 447*0Sstevel@tonic-gate 448*0Sstevel@tonic-gate while (phead != NULL) { 449*0Sstevel@tonic-gate if (strlcat(buf, phead->name, BUFSIZ) >= BUFSIZ) { 450*0Sstevel@tonic-gate free(buf); 451*0Sstevel@tonic-gate return (NULL); 452*0Sstevel@tonic-gate } 453*0Sstevel@tonic-gate 454*0Sstevel@tonic-gate phead = phead->next; 455*0Sstevel@tonic-gate if (phead != NULL) { 456*0Sstevel@tonic-gate if (strlcat(buf, SEP_COMMA, BUFSIZ) 457*0Sstevel@tonic-gate >= BUFSIZ) { 458*0Sstevel@tonic-gate free(buf); 459*0Sstevel@tonic-gate return (NULL); 460*0Sstevel@tonic-gate } 461*0Sstevel@tonic-gate } 462*0Sstevel@tonic-gate } 463*0Sstevel@tonic-gate } 464*0Sstevel@tonic-gate 465*0Sstevel@tonic-gate if (strlcat(buf, "\n", BUFSIZ) >= BUFSIZ) { 466*0Sstevel@tonic-gate free(buf); 467*0Sstevel@tonic-gate return (NULL); 468*0Sstevel@tonic-gate } 469*0Sstevel@tonic-gate 470*0Sstevel@tonic-gate return (buf); 471*0Sstevel@tonic-gate } 472*0Sstevel@tonic-gate 473*0Sstevel@tonic-gate 474*0Sstevel@tonic-gate /* 475*0Sstevel@tonic-gate * Enable the mechanisms for the provider pointed by *ppent. If allflag is 476*0Sstevel@tonic-gate * TRUE, enable all. Otherwise, enable the mechanisms specified in the 3rd 477*0Sstevel@tonic-gate * argument "mlist". The result will be stored in ppent also. 478*0Sstevel@tonic-gate */ 479*0Sstevel@tonic-gate int 480*0Sstevel@tonic-gate enable_mechs(entry_t **ppent, boolean_t allflag, mechlist_t *mlist) 481*0Sstevel@tonic-gate { 482*0Sstevel@tonic-gate entry_t *pent; 483*0Sstevel@tonic-gate mechlist_t *phead; /* the current and resulting disabled list */ 484*0Sstevel@tonic-gate mechlist_t *ptr; 485*0Sstevel@tonic-gate mechlist_t *pcur; 486*0Sstevel@tonic-gate boolean_t found; 487*0Sstevel@tonic-gate 488*0Sstevel@tonic-gate pent = *ppent; 489*0Sstevel@tonic-gate if (pent == NULL) { 490*0Sstevel@tonic-gate return (FAILURE); 491*0Sstevel@tonic-gate } 492*0Sstevel@tonic-gate 493*0Sstevel@tonic-gate if (allflag) { 494*0Sstevel@tonic-gate free_mechlist(pent->dislist); 495*0Sstevel@tonic-gate pent->dis_count = 0; 496*0Sstevel@tonic-gate pent->dislist = NULL; 497*0Sstevel@tonic-gate return (SUCCESS); 498*0Sstevel@tonic-gate } 499*0Sstevel@tonic-gate 500*0Sstevel@tonic-gate /* 501*0Sstevel@tonic-gate * for each mechanism in the to-be-enabled mechanism list, 502*0Sstevel@tonic-gate * - check if it is in the current disabled list 503*0Sstevel@tonic-gate * - if found, delete it from the disabled list 504*0Sstevel@tonic-gate * otherwise, give a warning. 505*0Sstevel@tonic-gate */ 506*0Sstevel@tonic-gate ptr = mlist; 507*0Sstevel@tonic-gate while (ptr != NULL) { 508*0Sstevel@tonic-gate found = B_FALSE; 509*0Sstevel@tonic-gate phead = pcur = pent->dislist; 510*0Sstevel@tonic-gate while (!found && pcur) { 511*0Sstevel@tonic-gate if (strcmp(pcur->name, ptr->name) == 0) { 512*0Sstevel@tonic-gate found = B_TRUE; 513*0Sstevel@tonic-gate } else { 514*0Sstevel@tonic-gate phead = pcur; 515*0Sstevel@tonic-gate pcur = pcur->next; 516*0Sstevel@tonic-gate } 517*0Sstevel@tonic-gate } 518*0Sstevel@tonic-gate 519*0Sstevel@tonic-gate if (found) { 520*0Sstevel@tonic-gate if (phead == pcur) { 521*0Sstevel@tonic-gate pent->dislist = pent->dislist->next; 522*0Sstevel@tonic-gate free(pcur); 523*0Sstevel@tonic-gate } else { 524*0Sstevel@tonic-gate phead->next = pcur->next; 525*0Sstevel@tonic-gate free(pcur); 526*0Sstevel@tonic-gate } 527*0Sstevel@tonic-gate pent->dis_count--; 528*0Sstevel@tonic-gate } else { 529*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 530*0Sstevel@tonic-gate "(Warning) %1$s is either enabled already or not " 531*0Sstevel@tonic-gate "a valid mechanism for %2$s"), ptr->name, 532*0Sstevel@tonic-gate pent->name); 533*0Sstevel@tonic-gate } 534*0Sstevel@tonic-gate ptr = ptr->next; 535*0Sstevel@tonic-gate } 536*0Sstevel@tonic-gate 537*0Sstevel@tonic-gate if (pent->dis_count == 0) { 538*0Sstevel@tonic-gate pent->dislist = NULL; 539*0Sstevel@tonic-gate } 540*0Sstevel@tonic-gate 541*0Sstevel@tonic-gate return (SUCCESS); 542*0Sstevel@tonic-gate 543*0Sstevel@tonic-gate } 544*0Sstevel@tonic-gate 545*0Sstevel@tonic-gate 546*0Sstevel@tonic-gate boolean_t 547*0Sstevel@tonic-gate is_device(char *path) 548*0Sstevel@tonic-gate { 549*0Sstevel@tonic-gate if (strchr(path, SEP_SLASH) != NULL) { 550*0Sstevel@tonic-gate return (B_TRUE); 551*0Sstevel@tonic-gate } else { 552*0Sstevel@tonic-gate return (B_FALSE); 553*0Sstevel@tonic-gate } 554*0Sstevel@tonic-gate } 555*0Sstevel@tonic-gate 556*0Sstevel@tonic-gate /* 557*0Sstevel@tonic-gate * Split a hardware provider name with the "name/inst_num" format into 558*0Sstevel@tonic-gate * a name and a number. 559*0Sstevel@tonic-gate */ 560*0Sstevel@tonic-gate int 561*0Sstevel@tonic-gate split_hw_provname(char *provname, char *pname, int *inst_num) 562*0Sstevel@tonic-gate { 563*0Sstevel@tonic-gate char name[MAXNAMELEN]; 564*0Sstevel@tonic-gate char *inst_str; 565*0Sstevel@tonic-gate 566*0Sstevel@tonic-gate if (provname == NULL) { 567*0Sstevel@tonic-gate return (FAILURE); 568*0Sstevel@tonic-gate } 569*0Sstevel@tonic-gate 570*0Sstevel@tonic-gate (void) strlcpy(name, provname, MAXNAMELEN); 571*0Sstevel@tonic-gate if (strtok(name, "/") == NULL) { 572*0Sstevel@tonic-gate return (FAILURE); 573*0Sstevel@tonic-gate } 574*0Sstevel@tonic-gate 575*0Sstevel@tonic-gate if ((inst_str = strtok(NULL, "/")) == NULL) { 576*0Sstevel@tonic-gate return (FAILURE); 577*0Sstevel@tonic-gate } 578*0Sstevel@tonic-gate 579*0Sstevel@tonic-gate (void) strlcpy(pname, name, MAXNAMELEN); 580*0Sstevel@tonic-gate *inst_num = atoi(inst_str); 581*0Sstevel@tonic-gate 582*0Sstevel@tonic-gate return (SUCCESS); 583*0Sstevel@tonic-gate } 584*0Sstevel@tonic-gate 585*0Sstevel@tonic-gate 586*0Sstevel@tonic-gate /* 587*0Sstevel@tonic-gate * Retrieve information from kcf.conf and build a device entry list and 588*0Sstevel@tonic-gate * a software entry list 589*0Sstevel@tonic-gate */ 590*0Sstevel@tonic-gate int 591*0Sstevel@tonic-gate get_kcfconf_info(entrylist_t **ppdevlist, entrylist_t **ppsoftlist) 592*0Sstevel@tonic-gate { 593*0Sstevel@tonic-gate FILE *pfile; 594*0Sstevel@tonic-gate char buffer[BUFSIZ]; 595*0Sstevel@tonic-gate int len; 596*0Sstevel@tonic-gate entry_t *pent = NULL; 597*0Sstevel@tonic-gate int rc = SUCCESS; 598*0Sstevel@tonic-gate 599*0Sstevel@tonic-gate if ((pfile = fopen(_PATH_KCF_CONF, "r")) == NULL) { 600*0Sstevel@tonic-gate cryptodebug("failed to open the kcf.conf file for read only"); 601*0Sstevel@tonic-gate return (FAILURE); 602*0Sstevel@tonic-gate } 603*0Sstevel@tonic-gate 604*0Sstevel@tonic-gate *ppdevlist = NULL; 605*0Sstevel@tonic-gate *ppsoftlist = NULL; 606*0Sstevel@tonic-gate while (fgets(buffer, BUFSIZ, pfile) != NULL) { 607*0Sstevel@tonic-gate if (buffer[0] == '#' || buffer[0] == ' ' || 608*0Sstevel@tonic-gate buffer[0] == '\n'|| buffer[0] == '\t') { 609*0Sstevel@tonic-gate continue; /* ignore comment lines */ 610*0Sstevel@tonic-gate } 611*0Sstevel@tonic-gate 612*0Sstevel@tonic-gate len = strlen(buffer); 613*0Sstevel@tonic-gate if (buffer[len-1] == '\n') { /* get rid of trailing '\n' */ 614*0Sstevel@tonic-gate len--; 615*0Sstevel@tonic-gate } 616*0Sstevel@tonic-gate buffer[len] = '\0'; 617*0Sstevel@tonic-gate 618*0Sstevel@tonic-gate if ((rc = interpret(buffer, &pent)) == SUCCESS) { 619*0Sstevel@tonic-gate if (is_device(pent->name)) { 620*0Sstevel@tonic-gate rc = build_entrylist(pent, ppdevlist); 621*0Sstevel@tonic-gate } else { 622*0Sstevel@tonic-gate rc = build_entrylist(pent, ppsoftlist); 623*0Sstevel@tonic-gate } 624*0Sstevel@tonic-gate } else { 625*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 626*0Sstevel@tonic-gate "failed to parse configuration.")); 627*0Sstevel@tonic-gate } 628*0Sstevel@tonic-gate 629*0Sstevel@tonic-gate if (rc != SUCCESS) { 630*0Sstevel@tonic-gate free_entrylist(*ppdevlist); 631*0Sstevel@tonic-gate free_entrylist(*ppsoftlist); 632*0Sstevel@tonic-gate free_entry(pent); 633*0Sstevel@tonic-gate break; 634*0Sstevel@tonic-gate } 635*0Sstevel@tonic-gate } 636*0Sstevel@tonic-gate 637*0Sstevel@tonic-gate (void) fclose(pfile); 638*0Sstevel@tonic-gate return (rc); 639*0Sstevel@tonic-gate } 640*0Sstevel@tonic-gate 641*0Sstevel@tonic-gate /* 642*0Sstevel@tonic-gate * Retrieve information from admin device and build a device entry list and 643*0Sstevel@tonic-gate * a software entry list. This is used where there is no kcf.conf, e.g. 644*0Sstevel@tonic-gate * non-global zone. 645*0Sstevel@tonic-gate */ 646*0Sstevel@tonic-gate int 647*0Sstevel@tonic-gate get_admindev_info(entrylist_t **ppdevlist, entrylist_t **ppsoftlist) 648*0Sstevel@tonic-gate { 649*0Sstevel@tonic-gate crypto_get_dev_list_t *pdevlist_kernel = NULL; 650*0Sstevel@tonic-gate crypto_get_soft_list_t *psoftlist_kernel = NULL; 651*0Sstevel@tonic-gate char *devname; 652*0Sstevel@tonic-gate int inst_num; 653*0Sstevel@tonic-gate int mcount; 654*0Sstevel@tonic-gate mechlist_t *pmech; 655*0Sstevel@tonic-gate entry_t *pent = NULL; 656*0Sstevel@tonic-gate int i; 657*0Sstevel@tonic-gate char *psoftname; 658*0Sstevel@tonic-gate entrylist_t *tmp_pdev = NULL; 659*0Sstevel@tonic-gate entrylist_t *tmp_psoft = NULL; 660*0Sstevel@tonic-gate 661*0Sstevel@tonic-gate if (get_dev_list(&pdevlist_kernel) != SUCCESS) { 662*0Sstevel@tonic-gate cryptodebug("failed to get hardware provider list from kernel"); 663*0Sstevel@tonic-gate return (FAILURE); 664*0Sstevel@tonic-gate } 665*0Sstevel@tonic-gate 666*0Sstevel@tonic-gate for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) { 667*0Sstevel@tonic-gate devname = pdevlist_kernel->dl_devs[i].le_dev_name; 668*0Sstevel@tonic-gate inst_num = pdevlist_kernel->dl_devs[i].le_dev_instance; 669*0Sstevel@tonic-gate mcount = pdevlist_kernel->dl_devs[i].le_mechanism_count; 670*0Sstevel@tonic-gate 671*0Sstevel@tonic-gate pmech = NULL; 672*0Sstevel@tonic-gate if (get_dev_info(devname, inst_num, mcount, &pmech) != 673*0Sstevel@tonic-gate SUCCESS) { 674*0Sstevel@tonic-gate cryptodebug( 675*0Sstevel@tonic-gate "failed to retrieve the mechanism list for %s/%d.", 676*0Sstevel@tonic-gate devname, inst_num); 677*0Sstevel@tonic-gate goto fail_out; 678*0Sstevel@tonic-gate } 679*0Sstevel@tonic-gate 680*0Sstevel@tonic-gate if ((pent = malloc(sizeof (entry_t))) == NULL) { 681*0Sstevel@tonic-gate cryptodebug("out of memory."); 682*0Sstevel@tonic-gate free_mechlist(pmech); 683*0Sstevel@tonic-gate goto fail_out; 684*0Sstevel@tonic-gate } 685*0Sstevel@tonic-gate 686*0Sstevel@tonic-gate (void) strlcpy(pent->name, devname, MAXNAMELEN); 687*0Sstevel@tonic-gate pent->suplist = pmech; 688*0Sstevel@tonic-gate pent->sup_count = mcount; 689*0Sstevel@tonic-gate pent->dislist = NULL; 690*0Sstevel@tonic-gate pent->dis_count = 0; 691*0Sstevel@tonic-gate 692*0Sstevel@tonic-gate if (build_entrylist(pent, &tmp_pdev) != SUCCESS) { 693*0Sstevel@tonic-gate goto fail_out; 694*0Sstevel@tonic-gate } 695*0Sstevel@tonic-gate 696*0Sstevel@tonic-gate /* because incorporated in tmp_pdev */ 697*0Sstevel@tonic-gate pent = NULL; 698*0Sstevel@tonic-gate } 699*0Sstevel@tonic-gate 700*0Sstevel@tonic-gate free(pdevlist_kernel); 701*0Sstevel@tonic-gate pdevlist_kernel = NULL; 702*0Sstevel@tonic-gate 703*0Sstevel@tonic-gate if (get_soft_list(&psoftlist_kernel) != SUCCESS) { 704*0Sstevel@tonic-gate cryptodebug("failed to get software provider list from kernel"); 705*0Sstevel@tonic-gate goto fail_out; 706*0Sstevel@tonic-gate } 707*0Sstevel@tonic-gate 708*0Sstevel@tonic-gate for (i = 0, psoftname = psoftlist_kernel->sl_soft_names; 709*0Sstevel@tonic-gate i < psoftlist_kernel->sl_soft_count; 710*0Sstevel@tonic-gate i++, psoftname = psoftname + strlen(psoftname) + 1) { 711*0Sstevel@tonic-gate pmech = NULL; 712*0Sstevel@tonic-gate if (get_soft_info(psoftname, &pmech) != SUCCESS) { 713*0Sstevel@tonic-gate cryptodebug( 714*0Sstevel@tonic-gate "failed to retrieve the mechanism list for %s.", 715*0Sstevel@tonic-gate psoftname); 716*0Sstevel@tonic-gate goto fail_out; 717*0Sstevel@tonic-gate } 718*0Sstevel@tonic-gate 719*0Sstevel@tonic-gate if ((pent = malloc(sizeof (entry_t))) == NULL) { 720*0Sstevel@tonic-gate cryptodebug("out of memory."); 721*0Sstevel@tonic-gate free_mechlist(pmech); 722*0Sstevel@tonic-gate goto fail_out; 723*0Sstevel@tonic-gate } 724*0Sstevel@tonic-gate 725*0Sstevel@tonic-gate (void) strlcpy(pent->name, psoftname, MAXNAMELEN); 726*0Sstevel@tonic-gate pent->suplist = pmech; 727*0Sstevel@tonic-gate pent->sup_count = get_mech_count(pmech); 728*0Sstevel@tonic-gate pent->dislist = NULL; 729*0Sstevel@tonic-gate pent->dis_count = 0; 730*0Sstevel@tonic-gate 731*0Sstevel@tonic-gate if (build_entrylist(pent, &tmp_psoft) != SUCCESS) { 732*0Sstevel@tonic-gate goto fail_out; 733*0Sstevel@tonic-gate } 734*0Sstevel@tonic-gate } 735*0Sstevel@tonic-gate 736*0Sstevel@tonic-gate free(psoftlist_kernel); 737*0Sstevel@tonic-gate psoftlist_kernel = NULL; 738*0Sstevel@tonic-gate 739*0Sstevel@tonic-gate *ppdevlist = tmp_pdev; 740*0Sstevel@tonic-gate *ppsoftlist = tmp_psoft; 741*0Sstevel@tonic-gate 742*0Sstevel@tonic-gate return (SUCCESS); 743*0Sstevel@tonic-gate 744*0Sstevel@tonic-gate fail_out: 745*0Sstevel@tonic-gate if (pent != NULL) 746*0Sstevel@tonic-gate free_entry(pent); 747*0Sstevel@tonic-gate 748*0Sstevel@tonic-gate free_entrylist(tmp_pdev); 749*0Sstevel@tonic-gate free_entrylist(tmp_psoft); 750*0Sstevel@tonic-gate 751*0Sstevel@tonic-gate if (pdevlist_kernel != NULL) 752*0Sstevel@tonic-gate free(pdevlist_kernel); 753*0Sstevel@tonic-gate if (psoftlist_kernel != NULL) 754*0Sstevel@tonic-gate free(psoftlist_kernel); 755*0Sstevel@tonic-gate 756*0Sstevel@tonic-gate return (FAILURE); 757*0Sstevel@tonic-gate } 758*0Sstevel@tonic-gate 759*0Sstevel@tonic-gate /* 760*0Sstevel@tonic-gate * Find the entry in the "kcf.conf" file with "provname" as the provider name. 761*0Sstevel@tonic-gate * Return the entry if found, otherwise return NULL. 762*0Sstevel@tonic-gate */ 763*0Sstevel@tonic-gate entry_t * 764*0Sstevel@tonic-gate getent_kef(char *provname) 765*0Sstevel@tonic-gate { 766*0Sstevel@tonic-gate entrylist_t *pdevlist = NULL; 767*0Sstevel@tonic-gate entrylist_t *psoftlist = NULL; 768*0Sstevel@tonic-gate entry_t *pent = NULL; 769*0Sstevel@tonic-gate 770*0Sstevel@tonic-gate if (get_kcfconf_info(&pdevlist, &psoftlist) != SUCCESS) { 771*0Sstevel@tonic-gate return (NULL); 772*0Sstevel@tonic-gate } 773*0Sstevel@tonic-gate 774*0Sstevel@tonic-gate if (is_device(provname)) { 775*0Sstevel@tonic-gate pent = getent(provname, pdevlist); 776*0Sstevel@tonic-gate } else { 777*0Sstevel@tonic-gate pent = getent(provname, psoftlist); 778*0Sstevel@tonic-gate } 779*0Sstevel@tonic-gate 780*0Sstevel@tonic-gate free_entrylist(pdevlist); 781*0Sstevel@tonic-gate free_entrylist(psoftlist); 782*0Sstevel@tonic-gate 783*0Sstevel@tonic-gate return (pent); 784*0Sstevel@tonic-gate } 785*0Sstevel@tonic-gate 786*0Sstevel@tonic-gate /* 787*0Sstevel@tonic-gate * Print out the provider name and the mechanism list. 788*0Sstevel@tonic-gate */ 789*0Sstevel@tonic-gate void 790*0Sstevel@tonic-gate print_mechlist(char *provname, mechlist_t *pmechlist) 791*0Sstevel@tonic-gate { 792*0Sstevel@tonic-gate mechlist_t *ptr; 793*0Sstevel@tonic-gate 794*0Sstevel@tonic-gate if (provname == NULL) { 795*0Sstevel@tonic-gate return; 796*0Sstevel@tonic-gate } 797*0Sstevel@tonic-gate 798*0Sstevel@tonic-gate (void) printf("%s: ", provname); 799*0Sstevel@tonic-gate if (pmechlist == NULL) { 800*0Sstevel@tonic-gate (void) printf(gettext("No mechanisms presented.\n")); 801*0Sstevel@tonic-gate return; 802*0Sstevel@tonic-gate } 803*0Sstevel@tonic-gate 804*0Sstevel@tonic-gate ptr = pmechlist; 805*0Sstevel@tonic-gate while (ptr != NULL) { 806*0Sstevel@tonic-gate (void) printf("%s", ptr->name); 807*0Sstevel@tonic-gate ptr = ptr->next; 808*0Sstevel@tonic-gate if (ptr == NULL) { 809*0Sstevel@tonic-gate (void) printf("\n"); 810*0Sstevel@tonic-gate } else { 811*0Sstevel@tonic-gate (void) printf(","); 812*0Sstevel@tonic-gate } 813*0Sstevel@tonic-gate } 814*0Sstevel@tonic-gate } 815*0Sstevel@tonic-gate 816*0Sstevel@tonic-gate 817*0Sstevel@tonic-gate /* 818*0Sstevel@tonic-gate * Update the kcf.conf file based on the specified entry and the update mode. 819*0Sstevel@tonic-gate * - If update_mode is MODIFY_MODE or DELETE_MODE, the entry with the same 820*0Sstevel@tonic-gate * provider name will be modified or deleted. 821*0Sstevel@tonic-gate * - If update_mode is ADD_MODE, this must be a hardware provider without 822*0Sstevel@tonic-gate * an entry in the kcf.conf file yet. Need to locate its driver package 823*0Sstevel@tonic-gate * bracket and insert an entry into the bracket. 824*0Sstevel@tonic-gate */ 825*0Sstevel@tonic-gate int 826*0Sstevel@tonic-gate update_kcfconf(entry_t *pent, int update_mode) 827*0Sstevel@tonic-gate { 828*0Sstevel@tonic-gate boolean_t add_it = B_FALSE; 829*0Sstevel@tonic-gate boolean_t delete_it = B_FALSE; 830*0Sstevel@tonic-gate boolean_t found_package = B_FALSE; 831*0Sstevel@tonic-gate boolean_t found_entry = B_FALSE; 832*0Sstevel@tonic-gate FILE *pfile; 833*0Sstevel@tonic-gate FILE *pfile_tmp; 834*0Sstevel@tonic-gate char buffer[BUFSIZ]; 835*0Sstevel@tonic-gate char buffer2[BUFSIZ]; 836*0Sstevel@tonic-gate char devname[MAXNAMELEN]; 837*0Sstevel@tonic-gate char tmpfile_name[MAXPATHLEN]; 838*0Sstevel@tonic-gate char *name; 839*0Sstevel@tonic-gate char *str; 840*0Sstevel@tonic-gate char *new_str = NULL; 841*0Sstevel@tonic-gate int inst_num; 842*0Sstevel@tonic-gate int rc = SUCCESS; 843*0Sstevel@tonic-gate 844*0Sstevel@tonic-gate 845*0Sstevel@tonic-gate if (pent == NULL) { 846*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("internal error.")); 847*0Sstevel@tonic-gate return (FAILURE); 848*0Sstevel@tonic-gate } 849*0Sstevel@tonic-gate 850*0Sstevel@tonic-gate /* Check the update_mode */ 851*0Sstevel@tonic-gate if (update_mode == ADD_MODE) { 852*0Sstevel@tonic-gate add_it = B_TRUE; 853*0Sstevel@tonic-gate /* Get the hardware provider name first */ 854*0Sstevel@tonic-gate if (split_hw_provname(pent->name, devname, &inst_num) == 855*0Sstevel@tonic-gate FAILURE) { 856*0Sstevel@tonic-gate return (FAILURE); 857*0Sstevel@tonic-gate } 858*0Sstevel@tonic-gate 859*0Sstevel@tonic-gate /* Convert the entry to be a string */ 860*0Sstevel@tonic-gate if ((new_str = ent2str(pent)) == NULL) { 861*0Sstevel@tonic-gate return (FAILURE); 862*0Sstevel@tonic-gate } 863*0Sstevel@tonic-gate } else if (update_mode == DELETE_MODE) { 864*0Sstevel@tonic-gate delete_it = B_TRUE; 865*0Sstevel@tonic-gate } else if (update_mode != MODIFY_MODE) { 866*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("internal error.")); 867*0Sstevel@tonic-gate return (FAILURE); 868*0Sstevel@tonic-gate } 869*0Sstevel@tonic-gate 870*0Sstevel@tonic-gate 871*0Sstevel@tonic-gate /* Open the kcf.conf file */ 872*0Sstevel@tonic-gate if ((pfile = fopen(_PATH_KCF_CONF, "r+")) == NULL) { 873*0Sstevel@tonic-gate err = errno; 874*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, 875*0Sstevel@tonic-gate gettext("failed to update the configuration - %s"), 876*0Sstevel@tonic-gate strerror(err)); 877*0Sstevel@tonic-gate cryptodebug("failed to open %s for write.", _PATH_KCF_CONF); 878*0Sstevel@tonic-gate return (FAILURE); 879*0Sstevel@tonic-gate } 880*0Sstevel@tonic-gate 881*0Sstevel@tonic-gate /* Lock the kcf.conf file */ 882*0Sstevel@tonic-gate if (lockf(fileno(pfile), F_TLOCK, 0) == -1) { 883*0Sstevel@tonic-gate err = errno; 884*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, 885*0Sstevel@tonic-gate gettext("failed to update the configuration - %s"), 886*0Sstevel@tonic-gate strerror(err)); 887*0Sstevel@tonic-gate (void) fclose(pfile); 888*0Sstevel@tonic-gate return (FAILURE); 889*0Sstevel@tonic-gate } 890*0Sstevel@tonic-gate 891*0Sstevel@tonic-gate /* 892*0Sstevel@tonic-gate * Create a temporary file in the /etc/crypto directory to save 893*0Sstevel@tonic-gate * updated configuration file first. 894*0Sstevel@tonic-gate */ 895*0Sstevel@tonic-gate (void) strlcpy(tmpfile_name, TMPFILE_TEMPLATE, sizeof (tmpfile_name)); 896*0Sstevel@tonic-gate if (mkstemp(tmpfile_name) == -1) { 897*0Sstevel@tonic-gate err = errno; 898*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, 899*0Sstevel@tonic-gate gettext("failed to create a temporary file - %s"), 900*0Sstevel@tonic-gate strerror(err)); 901*0Sstevel@tonic-gate (void) fclose(pfile); 902*0Sstevel@tonic-gate return (FAILURE); 903*0Sstevel@tonic-gate } 904*0Sstevel@tonic-gate 905*0Sstevel@tonic-gate if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) { 906*0Sstevel@tonic-gate err = errno; 907*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("failed to open %s - %s"), 908*0Sstevel@tonic-gate tmpfile_name, strerror(err)); 909*0Sstevel@tonic-gate (void) fclose(pfile); 910*0Sstevel@tonic-gate return (FAILURE); 911*0Sstevel@tonic-gate } 912*0Sstevel@tonic-gate 913*0Sstevel@tonic-gate /* 914*0Sstevel@tonic-gate * Loop thru the entire kcf.conf file, insert, modify or delete 915*0Sstevel@tonic-gate * an entry. 916*0Sstevel@tonic-gate */ 917*0Sstevel@tonic-gate while (fgets(buffer, BUFSIZ, pfile) != NULL) { 918*0Sstevel@tonic-gate if (add_it) { 919*0Sstevel@tonic-gate /* always keep the current line */ 920*0Sstevel@tonic-gate if (fputs(buffer, pfile_tmp) == EOF) { 921*0Sstevel@tonic-gate err = errno; 922*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 923*0Sstevel@tonic-gate "failed to write to a temp file: %s."), 924*0Sstevel@tonic-gate strerror(err)); 925*0Sstevel@tonic-gate rc = FAILURE; 926*0Sstevel@tonic-gate break; 927*0Sstevel@tonic-gate } 928*0Sstevel@tonic-gate 929*0Sstevel@tonic-gate /* 930*0Sstevel@tonic-gate * If the current position is the beginning of a driver 931*0Sstevel@tonic-gate * package and if the driver name matches the hardware 932*0Sstevel@tonic-gate * provider name, then we want to insert the entry 933*0Sstevel@tonic-gate * here. 934*0Sstevel@tonic-gate */ 935*0Sstevel@tonic-gate if ((strstr(buffer, HW_DRIVER_STRING) != NULL) && 936*0Sstevel@tonic-gate (strstr(buffer, devname) != NULL)) { 937*0Sstevel@tonic-gate found_package = B_TRUE; 938*0Sstevel@tonic-gate if (fputs(new_str, pfile_tmp) == EOF) { 939*0Sstevel@tonic-gate err = errno; 940*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 941*0Sstevel@tonic-gate "failed to write to a temp file: " 942*0Sstevel@tonic-gate "%s."), strerror(err)); 943*0Sstevel@tonic-gate rc = FAILURE; 944*0Sstevel@tonic-gate break; 945*0Sstevel@tonic-gate } 946*0Sstevel@tonic-gate } 947*0Sstevel@tonic-gate } else { /* modify or delete */ 948*0Sstevel@tonic-gate found_entry = B_FALSE; 949*0Sstevel@tonic-gate if (!(buffer[0] == '#' || buffer[0] == ' ' || 950*0Sstevel@tonic-gate buffer[0] == '\n'|| buffer[0] == '\t')) { 951*0Sstevel@tonic-gate /* 952*0Sstevel@tonic-gate * Get the provider name from this line and 953*0Sstevel@tonic-gate * check if this is the entry to be updated 954*0Sstevel@tonic-gate * or deleted. Note: can not use "buffer" 955*0Sstevel@tonic-gate * directly because strtok will change its 956*0Sstevel@tonic-gate * value. 957*0Sstevel@tonic-gate */ 958*0Sstevel@tonic-gate (void) strlcpy(buffer2, buffer, BUFSIZ); 959*0Sstevel@tonic-gate if ((name = strtok(buffer2, SEP_COLON)) == 960*0Sstevel@tonic-gate NULL) { 961*0Sstevel@tonic-gate rc = FAILURE; 962*0Sstevel@tonic-gate break; 963*0Sstevel@tonic-gate } 964*0Sstevel@tonic-gate 965*0Sstevel@tonic-gate if (strcmp(pent->name, name) == 0) { 966*0Sstevel@tonic-gate found_entry = B_TRUE; 967*0Sstevel@tonic-gate } 968*0Sstevel@tonic-gate } 969*0Sstevel@tonic-gate 970*0Sstevel@tonic-gate if (found_entry && !delete_it) { 971*0Sstevel@tonic-gate /* 972*0Sstevel@tonic-gate * This is the entry to be updated; get the 973*0Sstevel@tonic-gate * updated string and place into buffer. 974*0Sstevel@tonic-gate */ 975*0Sstevel@tonic-gate if ((str = ent2str(pent)) == NULL) { 976*0Sstevel@tonic-gate rc = FAILURE; 977*0Sstevel@tonic-gate break; 978*0Sstevel@tonic-gate } else { 979*0Sstevel@tonic-gate (void) strlcpy(buffer, str, BUFSIZ); 980*0Sstevel@tonic-gate free(str); 981*0Sstevel@tonic-gate } 982*0Sstevel@tonic-gate } 983*0Sstevel@tonic-gate 984*0Sstevel@tonic-gate if (!(found_entry && delete_it)) { 985*0Sstevel@tonic-gate /* This is the entry to be updated/reserved */ 986*0Sstevel@tonic-gate if (fputs(buffer, pfile_tmp) == EOF) { 987*0Sstevel@tonic-gate err = errno; 988*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 989*0Sstevel@tonic-gate "failed to write to a temp file: " 990*0Sstevel@tonic-gate "%s."), strerror(err)); 991*0Sstevel@tonic-gate rc = FAILURE; 992*0Sstevel@tonic-gate break; 993*0Sstevel@tonic-gate } 994*0Sstevel@tonic-gate } 995*0Sstevel@tonic-gate } 996*0Sstevel@tonic-gate } 997*0Sstevel@tonic-gate 998*0Sstevel@tonic-gate if (add_it) { 999*0Sstevel@tonic-gate free(new_str); 1000*0Sstevel@tonic-gate } 1001*0Sstevel@tonic-gate 1002*0Sstevel@tonic-gate if ((add_it && !found_package) || (rc == FAILURE)) { 1003*0Sstevel@tonic-gate if (add_it && !found_package) { 1004*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, 1005*0Sstevel@tonic-gate gettext("failed to update configuration - no " 1006*0Sstevel@tonic-gate "driver package information.")); 1007*0Sstevel@tonic-gate } 1008*0Sstevel@tonic-gate 1009*0Sstevel@tonic-gate (void) fclose(pfile); 1010*0Sstevel@tonic-gate (void) fclose(pfile_tmp); 1011*0Sstevel@tonic-gate if (unlink(tmpfile_name) != 0) { 1012*0Sstevel@tonic-gate err = errno; 1013*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 1014*0Sstevel@tonic-gate "(Warning) failed to remove %s: %s"), 1015*0Sstevel@tonic-gate tmpfile_name, strerror(err)); 1016*0Sstevel@tonic-gate } 1017*0Sstevel@tonic-gate return (FAILURE); 1018*0Sstevel@tonic-gate } 1019*0Sstevel@tonic-gate 1020*0Sstevel@tonic-gate (void) fclose(pfile); 1021*0Sstevel@tonic-gate if (fclose(pfile_tmp) != 0) { 1022*0Sstevel@tonic-gate err = errno; 1023*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, 1024*0Sstevel@tonic-gate gettext("failed to close %s: %s"), tmpfile_name, 1025*0Sstevel@tonic-gate strerror(err)); 1026*0Sstevel@tonic-gate return (FAILURE); 1027*0Sstevel@tonic-gate } 1028*0Sstevel@tonic-gate 1029*0Sstevel@tonic-gate /* Copy the temporary file to the kcf.conf file */ 1030*0Sstevel@tonic-gate if (rename(tmpfile_name, _PATH_KCF_CONF) == -1) { 1031*0Sstevel@tonic-gate err = errno; 1032*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, 1033*0Sstevel@tonic-gate gettext("failed to update the configuration - %s"), 1034*0Sstevel@tonic-gate strerror(err)); 1035*0Sstevel@tonic-gate cryptodebug("failed to rename %s to %s: %s", tmpfile, 1036*0Sstevel@tonic-gate _PATH_KCF_CONF, strerror(err)); 1037*0Sstevel@tonic-gate rc = FAILURE; 1038*0Sstevel@tonic-gate } else if (chmod(_PATH_KCF_CONF, 1039*0Sstevel@tonic-gate S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) { 1040*0Sstevel@tonic-gate err = errno; 1041*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, 1042*0Sstevel@tonic-gate gettext("failed to update the configuration - %s"), 1043*0Sstevel@tonic-gate strerror(err)); 1044*0Sstevel@tonic-gate cryptodebug("failed to chmod to %s: %s", _PATH_KCF_CONF, 1045*0Sstevel@tonic-gate strerror(err)); 1046*0Sstevel@tonic-gate rc = FAILURE; 1047*0Sstevel@tonic-gate } else { 1048*0Sstevel@tonic-gate rc = SUCCESS; 1049*0Sstevel@tonic-gate } 1050*0Sstevel@tonic-gate 1051*0Sstevel@tonic-gate if ((rc == FAILURE) && (unlink(tmpfile_name) != 0)) { 1052*0Sstevel@tonic-gate err = errno; 1053*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext( 1054*0Sstevel@tonic-gate "(Warning) failed to remove %s: %s"), 1055*0Sstevel@tonic-gate tmpfile_name, strerror(err)); 1056*0Sstevel@tonic-gate } 1057*0Sstevel@tonic-gate 1058*0Sstevel@tonic-gate return (rc); 1059*0Sstevel@tonic-gate } 1060*0Sstevel@tonic-gate 1061*0Sstevel@tonic-gate 1062*0Sstevel@tonic-gate /* 1063*0Sstevel@tonic-gate * Disable the mechanisms for the provider pointed by *ppent. If allflag is 1064*0Sstevel@tonic-gate * TRUE, disable all. Otherwise, disable the mechanisms specified in the 1065*0Sstevel@tonic-gate * dislist argument. The "infolist" argument contains the mechanism list 1066*0Sstevel@tonic-gate * supported by this provider. 1067*0Sstevel@tonic-gate */ 1068*0Sstevel@tonic-gate int 1069*0Sstevel@tonic-gate disable_mechs(entry_t **ppent, mechlist_t *infolist, boolean_t allflag, 1070*0Sstevel@tonic-gate mechlist_t *dislist) 1071*0Sstevel@tonic-gate { 1072*0Sstevel@tonic-gate entry_t *pent; 1073*0Sstevel@tonic-gate mechlist_t *plist; 1074*0Sstevel@tonic-gate mechlist_t *phead; 1075*0Sstevel@tonic-gate mechlist_t *pmech; 1076*0Sstevel@tonic-gate int rc = SUCCESS; 1077*0Sstevel@tonic-gate 1078*0Sstevel@tonic-gate pent = *ppent; 1079*0Sstevel@tonic-gate if (pent == NULL) { 1080*0Sstevel@tonic-gate return (FAILURE); 1081*0Sstevel@tonic-gate } 1082*0Sstevel@tonic-gate 1083*0Sstevel@tonic-gate if (allflag) { 1084*0Sstevel@tonic-gate free_mechlist(pent->dislist); 1085*0Sstevel@tonic-gate pent->dis_count = get_mech_count(infolist); 1086*0Sstevel@tonic-gate if (!(pent->dislist = dup_mechlist(infolist))) { 1087*0Sstevel@tonic-gate return (FAILURE); 1088*0Sstevel@tonic-gate } else { 1089*0Sstevel@tonic-gate return (SUCCESS); 1090*0Sstevel@tonic-gate } 1091*0Sstevel@tonic-gate } 1092*0Sstevel@tonic-gate 1093*0Sstevel@tonic-gate /* 1094*0Sstevel@tonic-gate * Not disable all. Now loop thru the mechanisms specified in the 1095*0Sstevel@tonic-gate * dislist. If the mechanism is not supported by the provider, 1096*0Sstevel@tonic-gate * ignore it with a warning. If the mechanism is disabled already, 1097*0Sstevel@tonic-gate * do nothing. Otherwise, prepend it to the beginning of the disabled 1098*0Sstevel@tonic-gate * list of the provider. 1099*0Sstevel@tonic-gate */ 1100*0Sstevel@tonic-gate plist = dislist; 1101*0Sstevel@tonic-gate while (plist != NULL) { 1102*0Sstevel@tonic-gate if (!is_in_list(plist->name, infolist)) { 1103*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("(Warning) " 1104*0Sstevel@tonic-gate "%1$s is not a valid mechanism for %2$s."), 1105*0Sstevel@tonic-gate plist->name, pent->name); 1106*0Sstevel@tonic-gate } else if (!is_in_list(plist->name, pent->dislist)) { 1107*0Sstevel@tonic-gate /* Add this mechanism into the disabled list */ 1108*0Sstevel@tonic-gate if ((pmech = create_mech(plist->name)) == NULL) { 1109*0Sstevel@tonic-gate rc = FAILURE; 1110*0Sstevel@tonic-gate break; 1111*0Sstevel@tonic-gate } 1112*0Sstevel@tonic-gate 1113*0Sstevel@tonic-gate if (pent->dislist == NULL) { 1114*0Sstevel@tonic-gate pent->dislist = pmech; 1115*0Sstevel@tonic-gate } else { 1116*0Sstevel@tonic-gate phead = pent->dislist; 1117*0Sstevel@tonic-gate pent->dislist = pmech; 1118*0Sstevel@tonic-gate pmech->next = phead; 1119*0Sstevel@tonic-gate } 1120*0Sstevel@tonic-gate pent->dis_count++; 1121*0Sstevel@tonic-gate } 1122*0Sstevel@tonic-gate plist = plist->next; 1123*0Sstevel@tonic-gate } 1124*0Sstevel@tonic-gate 1125*0Sstevel@tonic-gate return (rc); 1126*0Sstevel@tonic-gate } 1127*0Sstevel@tonic-gate 1128*0Sstevel@tonic-gate /* 1129*0Sstevel@tonic-gate * Remove the mechanism passed, specified by mech, from the list of 1130*0Sstevel@tonic-gate * mechanisms, if present in the list. Else, do nothing. 1131*0Sstevel@tonic-gate * 1132*0Sstevel@tonic-gate * Returns B_TRUE if mechanism is present in the list. 1133*0Sstevel@tonic-gate */ 1134*0Sstevel@tonic-gate boolean_t 1135*0Sstevel@tonic-gate filter_mechlist(mechlist_t **pmechlist, const char *mech) 1136*0Sstevel@tonic-gate { 1137*0Sstevel@tonic-gate int cnt = 0; 1138*0Sstevel@tonic-gate mechlist_t *ptr, *pptr; 1139*0Sstevel@tonic-gate boolean_t mech_present = B_FALSE; 1140*0Sstevel@tonic-gate 1141*0Sstevel@tonic-gate ptr = pptr = *pmechlist; 1142*0Sstevel@tonic-gate 1143*0Sstevel@tonic-gate while (ptr != NULL) { 1144*0Sstevel@tonic-gate if (strncmp(ptr->name, mech, sizeof (mech_name_t)) == 0) { 1145*0Sstevel@tonic-gate mech_present = B_TRUE; 1146*0Sstevel@tonic-gate if (ptr == *pmechlist) { 1147*0Sstevel@tonic-gate pptr = *pmechlist = ptr->next; 1148*0Sstevel@tonic-gate free(ptr); 1149*0Sstevel@tonic-gate ptr = pptr; 1150*0Sstevel@tonic-gate } else { 1151*0Sstevel@tonic-gate pptr->next = ptr->next; 1152*0Sstevel@tonic-gate free(ptr); 1153*0Sstevel@tonic-gate ptr = pptr->next; 1154*0Sstevel@tonic-gate } 1155*0Sstevel@tonic-gate } else { 1156*0Sstevel@tonic-gate pptr = ptr; 1157*0Sstevel@tonic-gate ptr = ptr->next; 1158*0Sstevel@tonic-gate cnt++; 1159*0Sstevel@tonic-gate } 1160*0Sstevel@tonic-gate } 1161*0Sstevel@tonic-gate 1162*0Sstevel@tonic-gate /* Only one entry is present */ 1163*0Sstevel@tonic-gate if (cnt == 0) 1164*0Sstevel@tonic-gate *pmechlist = NULL; 1165*0Sstevel@tonic-gate 1166*0Sstevel@tonic-gate return (mech_present); 1167*0Sstevel@tonic-gate } 1168*0Sstevel@tonic-gate 1169*0Sstevel@tonic-gate 1170*0Sstevel@tonic-gate 1171*0Sstevel@tonic-gate /* 1172*0Sstevel@tonic-gate * Print out the mechanism policy for a kernel provider that has an entry 1173*0Sstevel@tonic-gate * in the kcf.conf file. 1174*0Sstevel@tonic-gate * 1175*0Sstevel@tonic-gate * The flag has_random is set to B_TRUE if the provider does random 1176*0Sstevel@tonic-gate * numbers. The flag has_mechs is set by the caller to B_TRUE if the provider 1177*0Sstevel@tonic-gate * has some mechanisms. 1178*0Sstevel@tonic-gate */ 1179*0Sstevel@tonic-gate void 1180*0Sstevel@tonic-gate print_kef_policy(entry_t *pent, boolean_t has_random, boolean_t has_mechs) 1181*0Sstevel@tonic-gate { 1182*0Sstevel@tonic-gate mechlist_t *ptr; 1183*0Sstevel@tonic-gate boolean_t rnd_disabled = B_FALSE; 1184*0Sstevel@tonic-gate 1185*0Sstevel@tonic-gate if (pent == NULL) { 1186*0Sstevel@tonic-gate return; 1187*0Sstevel@tonic-gate } 1188*0Sstevel@tonic-gate 1189*0Sstevel@tonic-gate rnd_disabled = filter_mechlist(&pent->dislist, RANDOM); 1190*0Sstevel@tonic-gate ptr = pent->dislist; 1191*0Sstevel@tonic-gate 1192*0Sstevel@tonic-gate (void) printf("%s:", pent->name); 1193*0Sstevel@tonic-gate 1194*0Sstevel@tonic-gate if (has_mechs == B_TRUE) { 1195*0Sstevel@tonic-gate /* 1196*0Sstevel@tonic-gate * TRANSLATION_NOTE: 1197*0Sstevel@tonic-gate * This code block may need to be modified a bit to avoid 1198*0Sstevel@tonic-gate * constructing the text message on the fly. 1199*0Sstevel@tonic-gate */ 1200*0Sstevel@tonic-gate (void) printf(gettext(" all mechanisms are enabled")); 1201*0Sstevel@tonic-gate if (ptr != NULL) 1202*0Sstevel@tonic-gate (void) printf(gettext(", except ")); 1203*0Sstevel@tonic-gate while (ptr != NULL) { 1204*0Sstevel@tonic-gate (void) printf("%s", ptr->name); 1205*0Sstevel@tonic-gate ptr = ptr->next; 1206*0Sstevel@tonic-gate if (ptr != NULL) 1207*0Sstevel@tonic-gate (void) printf(","); 1208*0Sstevel@tonic-gate } 1209*0Sstevel@tonic-gate if (ptr == NULL) 1210*0Sstevel@tonic-gate (void) printf("."); 1211*0Sstevel@tonic-gate } 1212*0Sstevel@tonic-gate 1213*0Sstevel@tonic-gate /* 1214*0Sstevel@tonic-gate * TRANSLATION_NOTE: 1215*0Sstevel@tonic-gate * "random" is a keyword and not to be translated. 1216*0Sstevel@tonic-gate */ 1217*0Sstevel@tonic-gate if (rnd_disabled) 1218*0Sstevel@tonic-gate (void) printf(gettext(" %s is disabled."), "random"); 1219*0Sstevel@tonic-gate else if (has_random) 1220*0Sstevel@tonic-gate (void) printf(gettext(" %s is enabled."), "random"); 1221*0Sstevel@tonic-gate (void) printf("\n"); 1222*0Sstevel@tonic-gate } 1223*0Sstevel@tonic-gate 1224*0Sstevel@tonic-gate /* 1225*0Sstevel@tonic-gate * Check if a kernel software provider is in the kernel. 1226*0Sstevel@tonic-gate */ 1227*0Sstevel@tonic-gate int 1228*0Sstevel@tonic-gate check_active_for_soft(char *provname, boolean_t *is_active) 1229*0Sstevel@tonic-gate { 1230*0Sstevel@tonic-gate crypto_get_soft_list_t *psoftlist_kernel = NULL; 1231*0Sstevel@tonic-gate char *ptr; 1232*0Sstevel@tonic-gate int i; 1233*0Sstevel@tonic-gate 1234*0Sstevel@tonic-gate if (provname == NULL) { 1235*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("internal error.")); 1236*0Sstevel@tonic-gate return (FAILURE); 1237*0Sstevel@tonic-gate } 1238*0Sstevel@tonic-gate 1239*0Sstevel@tonic-gate if (get_soft_list(&psoftlist_kernel) == FAILURE) { 1240*0Sstevel@tonic-gate cryptodebug("failed to get the software provider list from" 1241*0Sstevel@tonic-gate "kernel."); 1242*0Sstevel@tonic-gate return (FAILURE); 1243*0Sstevel@tonic-gate } 1244*0Sstevel@tonic-gate 1245*0Sstevel@tonic-gate *is_active = B_FALSE; 1246*0Sstevel@tonic-gate ptr = psoftlist_kernel->sl_soft_names; 1247*0Sstevel@tonic-gate for (i = 0; i < psoftlist_kernel->sl_soft_count; i++) { 1248*0Sstevel@tonic-gate if (strcmp(provname, ptr) == 0) { 1249*0Sstevel@tonic-gate *is_active = B_TRUE; 1250*0Sstevel@tonic-gate break; 1251*0Sstevel@tonic-gate } 1252*0Sstevel@tonic-gate ptr = ptr + strlen(ptr) + 1; 1253*0Sstevel@tonic-gate } 1254*0Sstevel@tonic-gate free(psoftlist_kernel); 1255*0Sstevel@tonic-gate 1256*0Sstevel@tonic-gate return (SUCCESS); 1257*0Sstevel@tonic-gate } 1258*0Sstevel@tonic-gate 1259*0Sstevel@tonic-gate 1260*0Sstevel@tonic-gate /* 1261*0Sstevel@tonic-gate * Check if a kernel hardware provider is in the kernel. 1262*0Sstevel@tonic-gate */ 1263*0Sstevel@tonic-gate int 1264*0Sstevel@tonic-gate check_active_for_hard(char *provname, boolean_t *is_active) 1265*0Sstevel@tonic-gate { 1266*0Sstevel@tonic-gate crypto_get_dev_list_t *pdevlist = NULL; 1267*0Sstevel@tonic-gate char devname[MAXNAMELEN]; 1268*0Sstevel@tonic-gate int inst_num; 1269*0Sstevel@tonic-gate int i; 1270*0Sstevel@tonic-gate 1271*0Sstevel@tonic-gate if (provname == NULL) { 1272*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("internal error.")); 1273*0Sstevel@tonic-gate return (FAILURE); 1274*0Sstevel@tonic-gate } 1275*0Sstevel@tonic-gate 1276*0Sstevel@tonic-gate if (split_hw_provname(provname, devname, &inst_num) == FAILURE) { 1277*0Sstevel@tonic-gate return (FAILURE); 1278*0Sstevel@tonic-gate } 1279*0Sstevel@tonic-gate 1280*0Sstevel@tonic-gate if (get_dev_list(&pdevlist) == FAILURE) { 1281*0Sstevel@tonic-gate cryptoerror(LOG_STDERR, gettext("internal error.")); 1282*0Sstevel@tonic-gate return (FAILURE); 1283*0Sstevel@tonic-gate } 1284*0Sstevel@tonic-gate 1285*0Sstevel@tonic-gate *is_active = B_FALSE; 1286*0Sstevel@tonic-gate for (i = 0; i < pdevlist->dl_dev_count; i++) { 1287*0Sstevel@tonic-gate if ((strcmp(pdevlist->dl_devs[i].le_dev_name, devname) == 0) && 1288*0Sstevel@tonic-gate (pdevlist->dl_devs[i].le_dev_instance == inst_num)) { 1289*0Sstevel@tonic-gate *is_active = B_TRUE; 1290*0Sstevel@tonic-gate break; 1291*0Sstevel@tonic-gate } 1292*0Sstevel@tonic-gate } 1293*0Sstevel@tonic-gate free(pdevlist); 1294*0Sstevel@tonic-gate 1295*0Sstevel@tonic-gate return (SUCCESS); 1296*0Sstevel@tonic-gate } 1297