aboutsummaryrefslogtreecommitdiff
path: root/src/lib/gssapi/mechglue/g_utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/gssapi/mechglue/g_utils.c')
-rw-r--r--src/lib/gssapi/mechglue/g_utils.c281
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