diff options
Diffstat (limited to 'src/lib/gssapi/mechglue/g_utils.c')
-rw-r--r-- | src/lib/gssapi/mechglue/g_utils.c | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/src/lib/gssapi/mechglue/g_utils.c b/src/lib/gssapi/mechglue/g_utils.c new file mode 100644 index 0000000..82fe70d --- /dev/null +++ b/src/lib/gssapi/mechglue/g_utils.c @@ -0,0 +1,281 @@ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* #pragma ident "@(#)g_utils.c 1.8 04/02/23 SMI" */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <ctype.h> +#include <errno.h> +#include <gssapi/gssapi.h> + +#define Q_DEFAULT "default" +#define BUFLEN 256 + +#if 0 +static int qop_num_pair_cnt; +static const char QOP_NUM_FILE[] = "/etc/gss/qop"; +static qop_num qop_num_pairs[MAX_QOP_NUM_PAIRS+1]; +static mutex_t qopfile_lock = DEFAULTMUTEX; + +static OM_uint32 gssint_read_qop_file(void); + +/* + * This routine fetches qop and num from "/etc/gss/qop". + * There is a memory leak associated with rereading this file, + * because we can't free the qop_num_pairs array when we reread + * the file (some callers may have been given these pointers). + * In general, this memory leak should be a small one, because + * we don't expect the qop file to be changed and reread often. + */ +static OM_uint32 +gssint_read_qop_file(void) +{ + char buf[BUFLEN]; /* one line from the file */ + char *name, *next; + char *qopname, *num_str; + char *line; + FILE *fp; + static int last = 0; + struct stat stbuf; + OM_uint32 major = GSS_S_COMPLETE; + + (void) mutex_lock(&qopfile_lock); + if (stat(QOP_NUM_FILE, &stbuf) != 0 || stbuf.st_mtime < last) { + if (!qop_num_pairs[0].qop) { + major = GSS_S_FAILURE; + } + goto done; + } + last = stbuf.st_mtime; + + fp = fopen(QOP_NUM_FILE, "r"); + if (fp == (FILE *)0) { + major = GSS_S_FAILURE; + goto done; + } + + /* + * For each line in the file parse it appropriately. + * File format : qopname num(int) + * Note that we silently ignore corrupt entries. + */ + qop_num_pair_cnt = 0; + while (!feof(fp)) { + line = fgets(buf, BUFLEN, fp); + if (line == NULL) + break; + + /* Skip comments and blank lines */ + if ((*line == '#') || (*line == '\n')) + continue; + + /* Skip trailing comments */ + next = strchr(line, '#'); + if (next) + *next = '\0'; + + name = &(buf[0]); + while (isspace(*name)) + name++; + if (*name == '\0') /* blank line */ + continue; + + qopname = name; /* will contain qop name */ + while (!isspace(*qopname)) + qopname++; + if (*qopname == '\0') { + continue; + } + next = qopname+1; + *qopname = '\0'; /* null terminate qopname */ + qop_num_pairs[qop_num_pair_cnt].qop = strdup(name); + if (qop_num_pairs[qop_num_pair_cnt].qop == NULL) + continue; + + name = next; + while (isspace(*name)) + name++; + if (*name == '\0') { /* end of line, no num */ + free(qop_num_pairs[qop_num_pair_cnt].qop); + continue; + } + num_str = name; /* will contain num (n) */ + while (!isspace(*num_str)) + num_str++; + next = num_str+1; + *num_str++ = '\0'; /* null terminate num_str */ + + qop_num_pairs[qop_num_pair_cnt].num = (OM_uint32)atoi(name); + name = next; + while (isspace(*name)) + name++; + if (*name == '\0') { /* end of line, no mechanism */ + free(qop_num_pairs[qop_num_pair_cnt].qop); + continue; + } + num_str = name; /* will contain mech */ + while (!isspace(*num_str)) + num_str++; + *num_str = '\0'; + + qop_num_pairs[qop_num_pair_cnt].mech = strdup(name); + if (qop_num_pairs[qop_num_pair_cnt].mech == NULL) { + free(qop_num_pairs[qop_num_pair_cnt].qop); + continue; + } + + if (qop_num_pair_cnt++ >= MAX_QOP_NUM_PAIRS) + break; + } + (void) fclose(fp); +done: + (void) mutex_unlock(&qopfile_lock); + return (major); +} + +OM_uint32 +gssint_qop_to_num( + char *qop, + char *mech, + OM_uint32 *num +) +{ + int i; + OM_uint32 major = GSS_S_FAILURE; + + if (!num) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + + if (qop == NULL || strlen(qop) == 0 || + strcasecmp(qop, Q_DEFAULT) == 0) { + *num = GSS_C_QOP_DEFAULT; + return (GSS_S_COMPLETE); + } + + if ((major = gssint_read_qop_file()) != GSS_S_COMPLETE) + return (major); + + for (i = 0; i < qop_num_pair_cnt; i++) { + if ((strcasecmp(mech, qop_num_pairs[i].mech) == 0) && + (strcasecmp(qop, qop_num_pairs[i].qop) == 0)) { + *num = qop_num_pairs[i].num; + return (GSS_S_COMPLETE); + } + } + + return (GSS_S_FAILURE); +} + +OM_uint32 +gssint_num_to_qop( + char *mech, + OM_uint32 num, + char **qop +) +{ + int i; + OM_uint32 major; + + if (!qop) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + *qop = NULL; + + if (num == GSS_C_QOP_DEFAULT) { + *qop = Q_DEFAULT; + return (GSS_S_COMPLETE); + } + + if (mech == NULL) + return (GSS_S_CALL_INACCESSIBLE_READ); + + if ((major = gssint_read_qop_file()) != GSS_S_COMPLETE) + return (major); + + for (i = 0; i < qop_num_pair_cnt; i++) { + if ((strcasecmp(mech, qop_num_pairs[i].mech) == 0) && + (num == qop_num_pairs[i].num)) { + *qop = qop_num_pairs[i].qop; + return (GSS_S_COMPLETE); + } + } + return (GSS_S_FAILURE); +} + +/* + * For a given mechanism pass back qop information about it in a buffer + * of size MAX_QOPS_PER_MECH+1. + */ +OM_uint32 +gssint_get_mech_info( + char *mech, + char **qops +) +{ + int i, cnt = 0; + OM_uint32 major = GSS_S_COMPLETE; + + if (!qops) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + *qops = NULL; + + if (!mech) + return (GSS_S_CALL_INACCESSIBLE_READ); + + if ((major = gssint_read_qop_file()) != GSS_S_COMPLETE) + return (major); + + for (i = 0; i < qop_num_pair_cnt; i++) { + if (strcmp(mech, qop_num_pairs[i].mech) == 0) { + if (cnt >= MAX_QOPS_PER_MECH) { + return (GSS_S_FAILURE); + } + qops[cnt++] = qop_num_pairs[i].qop; + } + } + qops[cnt] = NULL; + return (GSS_S_COMPLETE); +} + +/* + * Copy the qop values and names for the mechanism back in a qop_num + * buffer of size MAX_QOPS_PER_MECH provided by the caller. + */ +OM_uint32 +gssint_mech_qops( + char *mech, + qop_num *mechqops, + int *numqop +) +{ + int i; + OM_uint32 major; + int cnt = 0; + + if (!mechqops || !numqop) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + *numqop = 0; + + if (!mech) + return (GSS_S_CALL_INACCESSIBLE_READ); + + if ((major = gssint_read_qop_file()) != GSS_S_COMPLETE) + return (major); + + for (i = 0; i < qop_num_pair_cnt; i++) { + if (strcasecmp(mech, qop_num_pairs[i].mech) == 0) { + if (cnt >= MAX_QOPS_PER_MECH) { + return (GSS_S_FAILURE); + } + mechqops[cnt++] = qop_num_pairs[i]; + } + } + *numqop = cnt; + return (GSS_S_COMPLETE); +} +#endif |