Print this page
6414175 kcf.conf's supportedlist not providing much usefulness

*** 30,49 **** #include <strings.h> #include <time.h> #include <unistd.h> #include <locale.h> #include <sys/types.h> #include <sys/stat.h> #include "cryptoadm.h" static int err; /* To store errno which may be overwritten by gettext() */ static int build_entrylist(entry_t *, entrylist_t **); static entry_t *dup_entry(entry_t *); static mechlist_t *dup_mechlist(mechlist_t *); static entry_t *getent(char *, entrylist_t *); static int interpret(char *, entry_t **); ! static int parse_dislist(char *, entry_t *); /* * Duplicate the mechanism list. A null pointer is returned if the storage * space available is insufficient or the input argument is NULL. --- 30,50 ---- #include <strings.h> #include <time.h> #include <unistd.h> #include <locale.h> #include <sys/types.h> + #include <zone.h> #include <sys/stat.h> #include "cryptoadm.h" static int err; /* To store errno which may be overwritten by gettext() */ static int build_entrylist(entry_t *, entrylist_t **); static entry_t *dup_entry(entry_t *); static mechlist_t *dup_mechlist(mechlist_t *); static entry_t *getent(char *, entrylist_t *); static int interpret(char *, entry_t **); ! static int parse_sup_dis_list(char *, entry_t *); /* * Duplicate the mechanism list. A null pointer is returned if the storage * space available is insufficient or the input argument is NULL.
*** 93,106 **** plist = plist->next; } return (count); } /* ! * Duplicate an entry. A null pointer is returned if the storage space ! * available is insufficient or the input argument is NULL. */ static entry_t * dup_entry(entry_t *pent1) { entry_t *pent2 = NULL; --- 94,136 ---- plist = plist->next; } return (count); } + /* + * Create one item of type entry_t with the provider name. + * Return NULL if there's not enough memory or provname is NULL. + */ + entry_t * + create_entry(char *provname) + { + entry_t *pent = NULL; + if (provname == NULL) { + return (NULL); + } + + pent = calloc(1, sizeof (entry_t)); + if (pent == NULL) { + cryptodebug("out of memory."); + return (NULL); + } + + (void) strlcpy(pent->name, provname, MAXNAMELEN); + pent->suplist = NULL; + pent->sup_count = 0; + pent->dislist = NULL; + pent->dis_count = 0; + pent->load = B_TRUE; + + return (pent); + } + /* ! * Duplicate an entry for a provider from kcf.conf. ! * Return NULL if memory is insufficient or the input argument is NULL. ! * Called by getent(). */ static entry_t * dup_entry(entry_t *pent1) { entry_t *pent2 = NULL;
*** 107,126 **** if (pent1 == NULL) { return (NULL); } ! if ((pent2 = malloc(sizeof (entry_t))) == NULL) { cryptodebug("out of memory."); return (NULL); } - (void) strlcpy(pent2->name, pent1->name, sizeof (pent2->name)); pent2->sup_count = pent1->sup_count; pent2->dis_count = pent1->dis_count; ! pent2->suplist = NULL; ! pent2->dislist = NULL; if (pent1->suplist != NULL) { pent2->suplist = dup_mechlist(pent1->suplist); if (pent2->suplist == NULL) { free_entry(pent2); return (NULL); --- 137,154 ---- if (pent1 == NULL) { return (NULL); } ! if ((pent2 = create_entry(pent1->name)) == NULL) { cryptodebug("out of memory."); return (NULL); } pent2->sup_count = pent1->sup_count; pent2->dis_count = pent1->dis_count; ! pent2->load = pent1->load; if (pent1->suplist != NULL) { pent2->suplist = dup_mechlist(pent1->suplist); if (pent2->suplist == NULL) { free_entry(pent2); return (NULL);
*** 148,161 **** * pent: the entry for the disabledlist. This is an IN/OUT argument. * * Return value: SUCCESS or FAILURE. */ static int ! parse_dislist(char *buf, entry_t *pent) { ! mechlist_t *pmech; ! mechlist_t *phead; char *next_token; char *value; int count; int supflag = B_FALSE; int disflag = B_FALSE; --- 176,189 ---- * pent: the entry for the disabledlist. This is an IN/OUT argument. * * Return value: SUCCESS or FAILURE. */ static int ! parse_sup_dis_list(char *buf, entry_t *pent) { ! mechlist_t *pmech = NULL; ! mechlist_t *phead = NULL; char *next_token; char *value; int count; int supflag = B_FALSE; int disflag = B_FALSE;
*** 217,269 **** return (rc); } - /* ! * This routine converts a char string into an entry_t structure */ static int interpret(char *buf, entry_t **ppent) { ! entry_t *pent; char *token1; char *token2; char *token3; int rc; if ((token1 = strtok(buf, SEP_COLON)) == NULL) { /* buf is NULL */ return (FAILURE); }; ! pent = malloc(sizeof (entry_t)); if (pent == NULL) { cryptodebug("out of memory."); return (FAILURE); } - (void) strlcpy(pent->name, token1, sizeof (pent->name)); - pent->suplist = NULL; - pent->dislist = NULL; - pent->sup_count = 0; - pent->dis_count = 0; if ((token2 = strtok(NULL, SEP_SEMICOLON)) == NULL) { /* The entry contains a provider name only */ free_entry(pent); return (FAILURE); } /* need to get token3 first to satisfy nested strtok invocations */ ! token3 = strtok(NULL, SEP_SEMICOLON); ! if (token2 && ((rc = parse_dislist(token2, pent)) != SUCCESS)) { free_entry(pent); return (rc); } ! if (token3 && ((rc = parse_dislist(token3, pent)) != SUCCESS)) { free_entry(pent); return (rc); } *ppent = pent; --- 245,309 ---- return (rc); } /* ! * Convert a char string containing a line about a provider ! * from kcf.conf into an entry_t structure. ! * ! * See ent2str(), the reverse of this function, for the format of ! * kcf.conf lines. */ static int interpret(char *buf, entry_t **ppent) { ! entry_t *pent = NULL; char *token1; char *token2; char *token3; int rc; + /* Get provider name */ if ((token1 = strtok(buf, SEP_COLON)) == NULL) { /* buf is NULL */ return (FAILURE); }; ! pent = create_entry(token1); if (pent == NULL) { cryptodebug("out of memory."); return (FAILURE); } if ((token2 = strtok(NULL, SEP_SEMICOLON)) == NULL) { /* The entry contains a provider name only */ free_entry(pent); return (FAILURE); } + if (strncmp(token2, EF_UNLOAD, strlen(EF_UNLOAD)) == 0) { + pent->load = B_FALSE; /* cryptoadm unload */ + if ((token2 = strtok(NULL, SEP_SEMICOLON)) == NULL) { + /* The entry contains a provider name:unload only */ + free_entry(pent); + return (FAILURE); + } + } + /* need to get token3 first to satisfy nested strtok invocations */ ! token3 = strtok(NULL, SEP_SEMICOLON); /* optional */ ! /* parse supportedlist (or disabledlist if no supportedlist) */ ! if ((token2 != NULL) && ((rc = parse_sup_dis_list(token2, pent)) != ! SUCCESS)) { free_entry(pent); return (rc); } ! /* parse disabledlist (if there's a supportedlist) */ ! if ((token3 != NULL) && ((rc = parse_sup_dis_list(token3, pent)) != ! SUCCESS)) { free_entry(pent); return (rc); } *ppent = pent;
*** 270,287 **** return (SUCCESS); } /* ! * Add an entry to the end of an entry list. If the entry list is NULL, will ! * create an entry list with the pent. */ static int build_entrylist(entry_t *pent, entrylist_t **pplist) { entrylist_t *pentlist; ! entrylist_t *pcur; pentlist = malloc(sizeof (entrylist_t)); if (pentlist == NULL) { cryptodebug("out of memory."); return (FAILURE); --- 310,328 ---- return (SUCCESS); } /* ! * Add an entry about a provider from kcf.conf to the end of an entry list. ! * If the entry list pplist is NULL, create the linked list with pent as the ! * first element. */ static int build_entrylist(entry_t *pent, entrylist_t **pplist) { entrylist_t *pentlist; ! entrylist_t *pcur = NULL; pentlist = malloc(sizeof (entrylist_t)); if (pentlist == NULL) { cryptodebug("out of memory."); return (FAILURE);
*** 303,313 **** /* * Find the entry with the "provname" name from the entry list and duplicate ! * it. */ static entry_t * getent(char *provname, entrylist_t *entrylist) { boolean_t found = B_FALSE; --- 344,354 ---- /* * Find the entry with the "provname" name from the entry list and duplicate ! * it. Called by getent_kef(). */ static entry_t * getent(char *provname, entrylist_t *entrylist) { boolean_t found = B_FALSE;
*** 333,343 **** /* duplicate the entry to be returned */ return (dup_entry(pent1)); } ! void free_entry(entry_t *pent) { if (pent == NULL) { return; --- 374,388 ---- /* duplicate the entry to be returned */ return (dup_entry(pent1)); } ! /* ! * Free memory in entry_t. ! * That is, the supported and disabled lists for a provider ! * from kcf.conf. ! */ void free_entry(entry_t *pent) { if (pent == NULL) { return;
*** 347,356 **** --- 392,405 ---- free(pent); } } + /* + * Free elements in a entrylist_t linked list, + * which lists providers in kcf.conf. + */ void free_entrylist(entrylist_t *entrylist) { entrylist_t *pnext;
*** 362,386 **** } /* * Convert an entry to a string. This routine builds a string for the entry ! * to be inserted in the config file. Based on the content of each entry, ! * the result string can be one of the 4 forms: ! * - name * - name:supportedlist=m1,m2,...,mj * - name:disabledlist=m1,m2,...,mj * - name:supportedlist=m1,...,mj;disabledlist=m1,m2,...,mk * ! * Note that the caller is responsible for freeing the returned string. */ char * ent2str(entry_t *pent) { char *buf; ! mechlist_t *phead; ! boolean_t supflag = B_FALSE; if (pent == NULL) { return (NULL); } --- 411,441 ---- } /* * Convert an entry to a string. This routine builds a string for the entry ! * to be inserted in the kcf.conf file. Based on the content of each entry, ! * the result string can be one of these 6 forms: * - name:supportedlist=m1,m2,...,mj * - name:disabledlist=m1,m2,...,mj * - name:supportedlist=m1,...,mj;disabledlist=m1,m2,...,mk * ! * - name:unload;supportedlist=m1,m2,...,mj ! * - name:unload;disabledlist=m1,m2,...,mj ! * - name:unload;supportedlist=m1,...,mj;disabledlist=m1,m2,...,mk ! * ! * Note that the caller is responsible for freeing the returned string ! * (with free_entry()). ! * See interpret() for the reverse of this function: converting a string ! * to an entry_t. */ char * ent2str(entry_t *pent) { char *buf; ! mechlist_t *pcur = NULL; ! boolean_t semicolon_separator = B_FALSE; if (pent == NULL) { return (NULL); }
*** 393,464 **** if (strlcpy(buf, pent->name, BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); } ! /* convert the supported list if any */ ! phead = pent->suplist; ! if (phead != NULL) { ! supflag = B_TRUE; ! if (strlcat(buf, SEP_COLON, BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); } if (strlcat(buf, EF_SUPPORTED, BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); } ! while (phead != NULL) { ! if (strlcat(buf, phead->name, BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); } ! phead = phead->next; ! if (phead != NULL) { if (strlcat(buf, SEP_COMMA, BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); } } } } /* convert the disabled list if any */ ! phead = pent->dislist; ! if (phead != NULL) { ! if (supflag) { ! if (strlcat(buf, ";disabledlist=", BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); } ! } else { ! if (strlcat(buf, ":disabledlist=", BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); } - } ! while (phead != NULL) { ! if (strlcat(buf, phead->name, BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); } ! phead = phead->next; ! if (phead != NULL) { if (strlcat(buf, SEP_COMMA, BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); } } } } if (strlcat(buf, "\n", BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); --- 448,535 ---- if (strlcpy(buf, pent->name, BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); } ! if (!pent->load) { /* add "unload" keyword */ if (strlcat(buf, SEP_COLON, BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); } + if (strlcat(buf, EF_UNLOAD, BUFSIZ) >= BUFSIZ) { + free(buf); + return (NULL); + } + + semicolon_separator = B_TRUE; + } + + /* convert the supported list if any */ + pcur = pent->suplist; + if (pcur != NULL) { + if (strlcat(buf, + semicolon_separator ? SEP_SEMICOLON : SEP_COLON, + BUFSIZ) >= BUFSIZ) { + free(buf); + return (NULL); + } + if (strlcat(buf, EF_SUPPORTED, BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); } ! while (pcur != NULL) { ! if (strlcat(buf, pcur->name, BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); } ! pcur = pcur->next; ! if (pcur != NULL) { if (strlcat(buf, SEP_COMMA, BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); } } } + semicolon_separator = B_TRUE; } /* convert the disabled list if any */ ! pcur = pent->dislist; ! if (pcur != NULL) { ! if (strlcat(buf, ! semicolon_separator ? SEP_SEMICOLON : SEP_COLON, ! BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); } ! ! if (strlcat(buf, EF_DISABLED, BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); } ! while (pcur != NULL) { ! if (strlcat(buf, pcur->name, BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); } ! pcur = pcur->next; ! if (pcur != NULL) { if (strlcat(buf, SEP_COMMA, BUFSIZ) >= BUFSIZ) { free(buf); return (NULL); } } } + semicolon_separator = B_TRUE; } if (strlcat(buf, "\n", BUFSIZ) >= BUFSIZ) { free(buf); return (NULL);
*** 476,487 **** int enable_mechs(entry_t **ppent, boolean_t allflag, mechlist_t *mlist) { entry_t *pent; mechlist_t *phead; /* the current and resulting disabled list */ ! mechlist_t *ptr; ! mechlist_t *pcur; boolean_t found; pent = *ppent; if (pent == NULL) { return (FAILURE); --- 547,558 ---- int enable_mechs(entry_t **ppent, boolean_t allflag, mechlist_t *mlist) { entry_t *pent; mechlist_t *phead; /* the current and resulting disabled list */ ! mechlist_t *ptr = NULL; ! mechlist_t *pcur = NULL; boolean_t found; pent = *ppent; if (pent == NULL) { return (FAILURE);
*** 538,547 **** --- 609,623 ---- return (SUCCESS); } + /* + * Determine if the kernel provider name, path, is a device + * (that is, it contains a slash character (e.g., "mca/0"). + * If so, it is a hardware provider; otherwise it is a software provider. + */ boolean_t is_device(char *path) { if (strchr(path, SEP_SLASH) != NULL) { return (B_TRUE);
*** 550,560 **** } } /* * Split a hardware provider name with the "name/inst_num" format into ! * a name and a number. */ int split_hw_provname(char *provname, char *pname, int *inst_num) { char name[MAXNAMELEN]; --- 626,636 ---- } } /* * Split a hardware provider name with the "name/inst_num" format into ! * a name and a number (e.g., split "mca/0" into "mca" instance 0). */ int split_hw_provname(char *provname, char *pname, int *inst_num) { char name[MAXNAMELEN];
*** 579,595 **** return (SUCCESS); } /* ! * Retrieve information from kcf.conf and build a device entry list and ! * a software entry list */ int get_kcfconf_info(entrylist_t **ppdevlist, entrylist_t **ppsoftlist) { ! FILE *pfile; char buffer[BUFSIZ]; int len; entry_t *pent = NULL; int rc = SUCCESS; --- 655,677 ---- return (SUCCESS); } /* ! * Retrieve information from kcf.conf and build a hardware device entry list ! * and a software entry list of kernel crypto providers. ! * ! * This list is usually incomplete, as kernel crypto providers only have to ! * be listed in kcf.conf if a mechanism is disabled (by cryptoadm) or ! * if the kernel provider module is not one of the default kernel providers. ! * ! * The kcf.conf file is available only in the global zone. */ int get_kcfconf_info(entrylist_t **ppdevlist, entrylist_t **ppsoftlist) { ! FILE *pfile = NULL; char buffer[BUFSIZ]; int len; entry_t *pent = NULL; int rc = SUCCESS;
*** 605,615 **** buffer[0] == '\n'|| buffer[0] == '\t') { continue; /* ignore comment lines */ } len = strlen(buffer); ! if (buffer[len-1] == '\n') { /* get rid of trailing '\n' */ len--; } buffer[len] = '\0'; if ((rc = interpret(buffer, &pent)) == SUCCESS) { --- 687,697 ---- buffer[0] == '\n'|| buffer[0] == '\t') { continue; /* ignore comment lines */ } len = strlen(buffer); ! if (buffer[len - 1] == '\n') { /* get rid of trailing '\n' */ len--; } buffer[len] = '\0'; if ((rc = interpret(buffer, &pent)) == SUCCESS) {
*** 635,645 **** return (rc); } /* * Retrieve information from admin device and build a device entry list and ! * a software entry list. This is used where there is no kcf.conf, e.g. * non-global zone. */ int get_admindev_info(entrylist_t **ppdevlist, entrylist_t **ppsoftlist) { --- 717,727 ---- return (rc); } /* * Retrieve information from admin device and build a device entry list and ! * a software entry list. This is used where there is no kcf.conf, e.g., the * non-global zone. */ int get_admindev_info(entrylist_t **ppdevlist, entrylist_t **ppsoftlist) {
*** 646,662 **** crypto_get_dev_list_t *pdevlist_kernel = NULL; crypto_get_soft_list_t *psoftlist_kernel = NULL; char *devname; int inst_num; int mcount; ! mechlist_t *pmech; ! entry_t *pent = NULL; int i; char *psoftname; entrylist_t *tmp_pdev = NULL; entrylist_t *tmp_psoft = NULL; if (get_dev_list(&pdevlist_kernel) != SUCCESS) { cryptodebug("failed to get hardware provider list from kernel"); return (FAILURE); } --- 728,748 ---- crypto_get_dev_list_t *pdevlist_kernel = NULL; crypto_get_soft_list_t *psoftlist_kernel = NULL; char *devname; int inst_num; int mcount; ! mechlist_t *pmech = NULL; ! entry_t *pent_dev = NULL, *pent_soft = NULL; int i; char *psoftname; entrylist_t *tmp_pdev = NULL; entrylist_t *tmp_psoft = NULL; + entrylist_t *phardlist = NULL, *psoftlist = NULL; + /* + * Get hardware providers + */ if (get_dev_list(&pdevlist_kernel) != SUCCESS) { cryptodebug("failed to get hardware provider list from kernel"); return (FAILURE); }
*** 672,733 **** "failed to retrieve the mechanism list for %s/%d.", devname, inst_num); goto fail_out; } ! if ((pent = malloc(sizeof (entry_t))) == NULL) { cryptodebug("out of memory."); free_mechlist(pmech); goto fail_out; } ! (void) strlcpy(pent->name, devname, MAXNAMELEN); ! pent->suplist = pmech; ! pent->sup_count = mcount; ! pent->dislist = NULL; ! pent->dis_count = 0; ! ! if (build_entrylist(pent, &tmp_pdev) != SUCCESS) { goto fail_out; } - - /* because incorporated in tmp_pdev */ - pent = NULL; } free(pdevlist_kernel); pdevlist_kernel = NULL; if (get_soft_list(&psoftlist_kernel) != SUCCESS) { cryptodebug("failed to get software provider list from kernel"); goto fail_out; } for (i = 0, psoftname = psoftlist_kernel->sl_soft_names; i < psoftlist_kernel->sl_soft_count; i++, psoftname = psoftname + strlen(psoftname) + 1) { pmech = NULL; ! if (get_soft_info(psoftname, &pmech) != SUCCESS) { cryptodebug( "failed to retrieve the mechanism list for %s.", psoftname); goto fail_out; } ! if ((pent = malloc(sizeof (entry_t))) == NULL) { cryptodebug("out of memory."); free_mechlist(pmech); goto fail_out; } ! (void) strlcpy(pent->name, psoftname, MAXNAMELEN); ! pent->suplist = pmech; ! pent->sup_count = get_mech_count(pmech); ! pent->dislist = NULL; ! pent->dis_count = 0; ! ! if (build_entrylist(pent, &tmp_psoft) != SUCCESS) { goto fail_out; } } free(psoftlist_kernel); --- 758,818 ---- "failed to retrieve the mechanism list for %s/%d.", devname, inst_num); goto fail_out; } ! if ((pent_dev = create_entry(devname)) == NULL) { cryptodebug("out of memory."); free_mechlist(pmech); goto fail_out; } + pent_dev->suplist = pmech; + pent_dev->sup_count = mcount; ! if (build_entrylist(pent_dev, &tmp_pdev) != SUCCESS) { goto fail_out; } } free(pdevlist_kernel); pdevlist_kernel = NULL; + /* + * Get software providers + */ + if (getzoneid() == GLOBAL_ZONEID) { + if (get_kcfconf_info(&phardlist, &psoftlist) != SUCCESS) { + goto fail_out; + } + } + if (get_soft_list(&psoftlist_kernel) != SUCCESS) { cryptodebug("failed to get software provider list from kernel"); goto fail_out; } for (i = 0, psoftname = psoftlist_kernel->sl_soft_names; i < psoftlist_kernel->sl_soft_count; i++, psoftname = psoftname + strlen(psoftname) + 1) { pmech = NULL; ! if (get_soft_info(psoftname, &pmech, phardlist, psoftlist) != ! SUCCESS) { cryptodebug( "failed to retrieve the mechanism list for %s.", psoftname); goto fail_out; } ! if ((pent_soft = create_entry(psoftname)) == NULL) { cryptodebug("out of memory."); free_mechlist(pmech); goto fail_out; } + pent_soft->suplist = pmech; + pent_soft->sup_count = get_mech_count(pmech); ! if (build_entrylist(pent_soft, &tmp_psoft) != SUCCESS) { goto fail_out; } } free(psoftlist_kernel);
*** 737,748 **** *ppsoftlist = tmp_psoft; return (SUCCESS); fail_out: ! if (pent != NULL) ! free_entry(pent); free_entrylist(tmp_pdev); free_entrylist(tmp_psoft); if (pdevlist_kernel != NULL) --- 822,835 ---- *ppsoftlist = tmp_psoft; return (SUCCESS); fail_out: ! if (pent_dev != NULL) ! free_entry(pent_dev); ! if (pent_soft != NULL) ! free_entry(pent_soft); free_entrylist(tmp_pdev); free_entrylist(tmp_psoft); if (pdevlist_kernel != NULL)
*** 752,783 **** return (FAILURE); } /* ! * Find the entry in the "kcf.conf" file with "provname" as the provider name. ! * Return the entry if found, otherwise return NULL. */ entry_t * ! getent_kef(char *provname) { - entrylist_t *pdevlist = NULL; - entrylist_t *psoftlist = NULL; entry_t *pent = NULL; ! if (get_kcfconf_info(&pdevlist, &psoftlist) != SUCCESS) { return (NULL); } if (is_device(provname)) { ! pent = getent(provname, pdevlist); } else { pent = getent(provname, psoftlist); } ! free_entrylist(pdevlist); free_entrylist(psoftlist); return (pent); } /* --- 839,878 ---- return (FAILURE); } /* ! * Return configuration information for a kernel provider from kcf.conf. ! * For kernel software providers return a enabled list and disabled list. ! * For kernel hardware providers return just a disabled list. ! * ! * Parameters phardlist and psoftlist are supplied by get_kcfconf_info(). ! * If NULL, this function calls get_kcfconf_info() internally. */ entry_t * ! getent_kef(char *provname, entrylist_t *phardlist, entrylist_t *psoftlist) { entry_t *pent = NULL; + boolean_t memory_allocated = B_FALSE; ! if ((phardlist == NULL) || (psoftlist == NULL)) { ! if (get_kcfconf_info(&phardlist, &psoftlist) != SUCCESS) { return (NULL); } + memory_allocated = B_TRUE; + } if (is_device(provname)) { ! pent = getent(provname, phardlist); } else { pent = getent(provname, psoftlist); } ! if (memory_allocated) { ! free_entrylist(phardlist); free_entrylist(psoftlist); + } return (pent); } /*
*** 784,794 **** * Print out the provider name and the mechanism list. */ void print_mechlist(char *provname, mechlist_t *pmechlist) { ! mechlist_t *ptr; if (provname == NULL) { return; } --- 879,889 ---- * Print out the provider name and the mechanism list. */ void print_mechlist(char *provname, mechlist_t *pmechlist) { ! mechlist_t *ptr = NULL; if (provname == NULL) { return; }
*** 810,872 **** } } /* ! * Update the kcf.conf file based on the specified entry and the update mode. ! * - If update_mode is MODIFY_MODE or DELETE_MODE, the entry with the same ! * provider name will be modified or deleted. ! * - If update_mode is ADD_MODE, this must be a hardware provider without ! * an entry in the kcf.conf file yet. Need to locate its driver package ! * bracket and insert an entry into the bracket. */ int update_kcfconf(entry_t *pent, int update_mode) { boolean_t add_it = B_FALSE; boolean_t delete_it = B_FALSE; - boolean_t found_package = B_FALSE; boolean_t found_entry = B_FALSE; ! FILE *pfile; ! FILE *pfile_tmp; char buffer[BUFSIZ]; char buffer2[BUFSIZ]; - char devname[MAXNAMELEN]; char tmpfile_name[MAXPATHLEN]; char *name; - char *str; char *new_str = NULL; - int inst_num; int rc = SUCCESS; - if (pent == NULL) { cryptoerror(LOG_STDERR, gettext("internal error.")); return (FAILURE); } /* Check the update_mode */ ! if (update_mode == ADD_MODE) { add_it = B_TRUE; ! /* Get the hardware provider name first */ ! if (split_hw_provname(pent->name, devname, &inst_num) == ! FAILURE) { ! return (FAILURE); ! } ! ! /* Convert the entry to be a string */ if ((new_str = ent2str(pent)) == NULL) { return (FAILURE); } ! } else if (update_mode == DELETE_MODE) { delete_it = B_TRUE; ! } else if (update_mode != MODIFY_MODE) { cryptoerror(LOG_STDERR, gettext("internal error.")); return (FAILURE); } - /* Open the kcf.conf file */ if ((pfile = fopen(_PATH_KCF_CONF, "r+")) == NULL) { err = errno; cryptoerror(LOG_STDERR, gettext("failed to update the configuration - %s"), --- 905,959 ---- } } /* ! * Update the kcf.conf file based on the update mode: ! * - If update_mode is MODIFY_MODE, modify the entry with the same name. ! * If not found, append a new entry to the kcf.conf file. ! * - If update_mode is DELETE_MODE, delete the entry with the same name. ! * - If update_mode is ADD_MODE, append a new entry to the kcf.conf file. */ int update_kcfconf(entry_t *pent, int update_mode) { boolean_t add_it = B_FALSE; boolean_t delete_it = B_FALSE; boolean_t found_entry = B_FALSE; ! FILE *pfile = NULL; ! FILE *pfile_tmp = NULL; char buffer[BUFSIZ]; char buffer2[BUFSIZ]; char tmpfile_name[MAXPATHLEN]; char *name; char *new_str = NULL; int rc = SUCCESS; if (pent == NULL) { cryptoerror(LOG_STDERR, gettext("internal error.")); return (FAILURE); } /* Check the update_mode */ ! switch (update_mode) { ! case ADD_MODE: add_it = B_TRUE; ! /* FALLTHROUGH */ ! case MODIFY_MODE: ! /* Convert the entry a string to add to kcf.conf */ if ((new_str = ent2str(pent)) == NULL) { return (FAILURE); } ! break; ! case DELETE_MODE: delete_it = B_TRUE; ! break; ! default: cryptoerror(LOG_STDERR, gettext("internal error.")); return (FAILURE); } /* Open the kcf.conf file */ if ((pfile = fopen(_PATH_KCF_CONF, "r+")) == NULL) { err = errno; cryptoerror(LOG_STDERR, gettext("failed to update the configuration - %s"),
*** 911,950 **** * Loop thru the entire kcf.conf file, insert, modify or delete * an entry. */ while (fgets(buffer, BUFSIZ, pfile) != NULL) { if (add_it) { - /* always keep the current line */ if (fputs(buffer, pfile_tmp) == EOF) { err = errno; cryptoerror(LOG_STDERR, gettext( "failed to write to a temp file: %s."), strerror(err)); rc = FAILURE; break; } - /* - * If the current position is the beginning of a driver - * package and if the driver name matches the hardware - * provider name, then we want to insert the entry - * here. - */ - if ((strstr(buffer, HW_DRIVER_STRING) != NULL) && - (strstr(buffer, devname) != NULL)) { - found_package = B_TRUE; - if (fputs(new_str, pfile_tmp) == EOF) { - err = errno; - cryptoerror(LOG_STDERR, gettext( - "failed to write to a temp file: " - "%s."), strerror(err)); - rc = FAILURE; - break; - } - } } else { /* modify or delete */ found_entry = B_FALSE; if (!(buffer[0] == '#' || buffer[0] == ' ' || buffer[0] == '\n'|| buffer[0] == '\t')) { /* * Get the provider name from this line and * check if this is the entry to be updated --- 998,1019 ---- * Loop thru the entire kcf.conf file, insert, modify or delete * an entry. */ while (fgets(buffer, BUFSIZ, pfile) != NULL) { if (add_it) { if (fputs(buffer, pfile_tmp) == EOF) { err = errno; cryptoerror(LOG_STDERR, gettext( "failed to write to a temp file: %s."), strerror(err)); rc = FAILURE; break; } } else { /* modify or delete */ found_entry = B_FALSE; + if (!(buffer[0] == '#' || buffer[0] == ' ' || buffer[0] == '\n'|| buffer[0] == '\t')) { /* * Get the provider name from this line and * check if this is the entry to be updated
*** 967,984 **** if (found_entry && !delete_it) { /* * This is the entry to be updated; get the * updated string and place into buffer. */ ! if ((str = ent2str(pent)) == NULL) { ! rc = FAILURE; ! break; ! } else { ! (void) strlcpy(buffer, str, BUFSIZ); ! free(str); } - } if (!(found_entry && delete_it)) { /* This is the entry to be updated/reserved */ if (fputs(buffer, pfile_tmp) == EOF) { err = errno; --- 1036,1048 ---- if (found_entry && !delete_it) { /* * This is the entry to be updated; get the * updated string and place into buffer. */ ! (void) strlcpy(buffer, new_str, BUFSIZ); ! free(new_str); } if (!(found_entry && delete_it)) { /* This is the entry to be updated/reserved */ if (fputs(buffer, pfile_tmp) == EOF) { err = errno;
*** 990,1020 **** } } } } ! if (add_it) { ! free(new_str); ! } ! ! if ((add_it && !found_package) || (rc == FAILURE)) { ! if (add_it && !found_package) { ! cryptoerror(LOG_STDERR, ! gettext("failed to update configuration - no " ! "driver package information.")); ! } ! ! (void) fclose(pfile); ! (void) fclose(pfile_tmp); ! if (unlink(tmpfile_name) != 0) { err = errno; cryptoerror(LOG_STDERR, gettext( ! "(Warning) failed to remove %s: %s"), ! tmpfile_name, strerror(err)); } ! return (FAILURE); } (void) fclose(pfile); if (fclose(pfile_tmp) != 0) { err = errno; cryptoerror(LOG_STDERR, --- 1054,1076 ---- } } } } ! if ((!delete_it) && (rc != FAILURE)) { ! if (add_it || !found_entry) { ! /* append new entry to end of file */ ! if (fputs(new_str, pfile_tmp) == EOF) { err = errno; cryptoerror(LOG_STDERR, gettext( ! "failed to write to a temp file: %s."), ! strerror(err)); ! rc = FAILURE; } ! free(new_str); } + } (void) fclose(pfile); if (fclose(pfile_tmp) != 0) { err = errno; cryptoerror(LOG_STDERR,
*** 1065,1077 **** int disable_mechs(entry_t **ppent, mechlist_t *infolist, boolean_t allflag, mechlist_t *dislist) { entry_t *pent; ! mechlist_t *plist; ! mechlist_t *phead; ! mechlist_t *pmech; int rc = SUCCESS; pent = *ppent; if (pent == NULL) { return (FAILURE); --- 1121,1133 ---- int disable_mechs(entry_t **ppent, mechlist_t *infolist, boolean_t allflag, mechlist_t *dislist) { entry_t *pent; ! mechlist_t *plist = NULL; ! mechlist_t *phead = NULL; ! mechlist_t *pmech = NULL; int rc = SUCCESS; pent = *ppent; if (pent == NULL) { return (FAILURE);
*** 1170,1194 **** * in the kcf.conf file. * * The flag has_random is set to B_TRUE if the provider does random * numbers. The flag has_mechs is set by the caller to B_TRUE if the provider * has some mechanisms. */ void ! print_kef_policy(entry_t *pent, boolean_t has_random, boolean_t has_mechs) { ! mechlist_t *ptr; boolean_t rnd_disabled = B_FALSE; ! if (pent == NULL) { ! return; ! } ! rnd_disabled = filter_mechlist(&pent->dislist, RANDOM); ptr = pent->dislist; ! (void) printf("%s:", pent->name); if (has_mechs == B_TRUE) { /* * TRANSLATION_NOTE * This code block may need to be modified a bit to avoid --- 1226,1251 ---- * in the kcf.conf file. * * The flag has_random is set to B_TRUE if the provider does random * numbers. The flag has_mechs is set by the caller to B_TRUE if the provider * has some mechanisms. + * + * If pent is NULL, the provider doesn't have a kcf.conf entry. */ void ! print_kef_policy(char *provname, entry_t *pent, boolean_t has_random, ! boolean_t has_mechs) { ! mechlist_t *ptr = NULL; boolean_t rnd_disabled = B_FALSE; ! if (pent != NULL) { rnd_disabled = filter_mechlist(&pent->dislist, RANDOM); ptr = pent->dislist; + } ! (void) printf("%s:", provname); if (has_mechs == B_TRUE) { /* * TRANSLATION_NOTE * This code block may need to be modified a bit to avoid
*** 1216,1271 **** else if (has_random) (void) printf(gettext(" %s is enabled."), "random"); (void) printf("\n"); } /* * Check if a kernel software provider is in the kernel. */ int ! check_active_for_soft(char *provname, boolean_t *is_active) { - crypto_get_soft_list_t *psoftlist_kernel = NULL; char *ptr; int i; if (provname == NULL) { cryptoerror(LOG_STDERR, gettext("internal error.")); return (FAILURE); } if (get_soft_list(&psoftlist_kernel) == FAILURE) { ! cryptodebug("failed to get the software provider list from" ! "kernel."); return (FAILURE); } ! *is_active = B_FALSE; ptr = psoftlist_kernel->sl_soft_names; for (i = 0; i < psoftlist_kernel->sl_soft_count; i++) { if (strcmp(provname, ptr) == 0) { ! *is_active = B_TRUE; break; } ptr = ptr + strlen(ptr) + 1; } free(psoftlist_kernel); return (SUCCESS); } /* * Check if a kernel hardware provider is in the kernel. */ int ! check_active_for_hard(char *provname, boolean_t *is_active) { - crypto_get_dev_list_t *pdevlist = NULL; char devname[MAXNAMELEN]; int inst_num; int i; if (provname == NULL) { cryptoerror(LOG_STDERR, gettext("internal error.")); return (FAILURE); } --- 1273,1348 ---- else if (has_random) (void) printf(gettext(" %s is enabled."), "random"); (void) printf("\n"); } + /* * Check if a kernel software provider is in the kernel. + * + * Parameters: + * provname Provider name + * psoftlist_kernel Optional software provider list. If NULL, it will be + * obtained from get_soft_list(). + * in_kernel Set to B_TRUE if device is in the kernel, else B_FALSE */ int ! check_kernel_for_soft(char *provname, crypto_get_soft_list_t *psoftlist_kernel, ! boolean_t *in_kernel) { char *ptr; int i; + boolean_t psoftlist_allocated = B_FALSE; if (provname == NULL) { cryptoerror(LOG_STDERR, gettext("internal error.")); return (FAILURE); } + if (psoftlist_kernel == NULL) { if (get_soft_list(&psoftlist_kernel) == FAILURE) { ! cryptodebug("failed to get the software provider list" ! " from kernel."); return (FAILURE); } + psoftlist_allocated = B_TRUE; + } ! *in_kernel = B_FALSE; ptr = psoftlist_kernel->sl_soft_names; for (i = 0; i < psoftlist_kernel->sl_soft_count; i++) { if (strcmp(provname, ptr) == 0) { ! *in_kernel = B_TRUE; break; } ptr = ptr + strlen(ptr) + 1; } + + if (psoftlist_allocated) free(psoftlist_kernel); return (SUCCESS); } /* * Check if a kernel hardware provider is in the kernel. + * + * Parameters: + * provname Provider name + * pdevlist Optional Hardware Crypto Device List. If NULL, it will be + * obtained from get_dev_list(). + * in_kernel Set to B_TRUE if device is in the kernel, otherwise B_FALSE */ int ! check_kernel_for_hard(char *provname, ! crypto_get_dev_list_t *pdevlist, boolean_t *in_kernel) { char devname[MAXNAMELEN]; int inst_num; int i; + boolean_t dev_list_allocated = B_FALSE; if (provname == NULL) { cryptoerror(LOG_STDERR, gettext("internal error.")); return (FAILURE); }
*** 1272,1293 **** if (split_hw_provname(provname, devname, &inst_num) == FAILURE) { return (FAILURE); } if (get_dev_list(&pdevlist) == FAILURE) { cryptoerror(LOG_STDERR, gettext("internal error.")); return (FAILURE); } ! *is_active = B_FALSE; for (i = 0; i < pdevlist->dl_dev_count; i++) { if ((strcmp(pdevlist->dl_devs[i].le_dev_name, devname) == 0) && (pdevlist->dl_devs[i].le_dev_instance == inst_num)) { ! *is_active = B_TRUE; break; } } free(pdevlist); return (SUCCESS); } --- 1349,1375 ---- if (split_hw_provname(provname, devname, &inst_num) == FAILURE) { return (FAILURE); } + if (pdevlist == NULL) { if (get_dev_list(&pdevlist) == FAILURE) { cryptoerror(LOG_STDERR, gettext("internal error.")); return (FAILURE); } + dev_list_allocated = B_TRUE; + } ! *in_kernel = B_FALSE; for (i = 0; i < pdevlist->dl_dev_count; i++) { if ((strcmp(pdevlist->dl_devs[i].le_dev_name, devname) == 0) && (pdevlist->dl_devs[i].le_dev_instance == inst_num)) { ! *in_kernel = B_TRUE; break; } } + + if (dev_list_allocated) free(pdevlist); return (SUCCESS); }