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);
}