summaryrefslogtreecommitdiffstats
path: root/lib/libgssapi
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2007-06-30 07:47:45 +0000
committerdfr <dfr@FreeBSD.org>2007-06-30 07:47:45 +0000
commitc38fa0f103e8f34d337d3bf31003c1696179c54c (patch)
tree43e155259c3b6dda9ce39b2e454a8e8ef1282f3c /lib/libgssapi
parentb4cb24ec70dd01020b996accd7f33061c726299d (diff)
downloadFreeBSD-src-c38fa0f103e8f34d337d3bf31003c1696179c54c.zip
FreeBSD-src-c38fa0f103e8f34d337d3bf31003c1696179c54c.tar.gz
Merge fixes back from heimdal.
Approved by: re (kensmith)
Diffstat (limited to 'lib/libgssapi')
-rw-r--r--lib/libgssapi/gss_accept_sec_context.c8
-rw-r--r--lib/libgssapi/gss_display_status.c182
-rw-r--r--lib/libgssapi/gss_export_name.c3
-rw-r--r--lib/libgssapi/gss_indicate_mechs.c19
-rw-r--r--lib/libgssapi/gss_init_sec_context.c5
5 files changed, 154 insertions, 63 deletions
diff --git a/lib/libgssapi/gss_accept_sec_context.c b/lib/libgssapi/gss_accept_sec_context.c
index d9453cf..269a620 100644
--- a/lib/libgssapi/gss_accept_sec_context.c
+++ b/lib/libgssapi/gss_accept_sec_context.c
@@ -48,7 +48,7 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
OM_uint32 *time_rec,
gss_cred_id_t *delegated_cred_handle)
{
- OM_uint32 major_status;
+ OM_uint32 major_status, mech_ret_flags;
struct _gss_mech_switch *m;
struct _gss_context *ctx = (struct _gss_context *) *context_handle;
struct _gss_cred *cred = (struct _gss_cred *) acceptor_cred_handle;
@@ -165,7 +165,7 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
&src_mn,
mech_type,
output_token,
- ret_flags,
+ &mech_ret_flags,
time_rec,
&delegated_mc);
if (major_status != GSS_S_COMPLETE &&
@@ -187,7 +187,7 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
*src_name = (gss_name_t) name;
}
- if (*ret_flags & GSS_C_DELEG_FLAG) {
+ if (mech_ret_flags & GSS_C_DELEG_FLAG) {
if (!delegated_cred_handle) {
m->gm_release_cred(minor_status, &delegated_mc);
*ret_flags &= ~GSS_C_DELEG_FLAG;
@@ -217,6 +217,8 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
}
}
+ if (ret_flags)
+ *ret_flags = mech_ret_flags;
*context_handle = (gss_ctx_id_t) ctx;
return (major_status);
}
diff --git a/lib/libgssapi/gss_display_status.c b/lib/libgssapi/gss_display_status.c
index 04cf4c7..96f68609c5 100644
--- a/lib/libgssapi/gss_display_status.c
+++ b/lib/libgssapi/gss_display_status.c
@@ -25,44 +25,120 @@
*
* $FreeBSD$
*/
+/*
+ * Copyright (c) 1998 - 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
#include <gssapi/gssapi.h>
#include <string.h>
+#include <errno.h>
#include "mech_switch.h"
-struct _gss_status_desc {
- OM_uint32 gs_status;
- const char* gs_desc;
-};
-
-static struct _gss_status_desc _gss_status_descs[] = {
- GSS_S_BAD_MECH, "An unsupported mechanism was requested",
- GSS_S_BAD_NAME, "An invalid name was supplied",
- GSS_S_BAD_NAMETYPE, "A supplied name was of an unsupported type",
- GSS_S_BAD_BINDINGS, "Incorrect channel bindings were supplied",
- GSS_S_BAD_STATUS, "An invalid status code was supplied",
- GSS_S_BAD_MIC, "A token had an invalid MIC",
- GSS_S_NO_CRED, "No credentials were supplied, or the "
- "credentials were unavailable or inaccessible",
- GSS_S_NO_CONTEXT, "No context has been established",
- GSS_S_DEFECTIVE_TOKEN, "A token was invalid",
- GSS_S_DEFECTIVE_CREDENTIAL, "A credential was invalid",
- GSS_S_CREDENTIALS_EXPIRED, "The referenced credentials have expired",
- GSS_S_CONTEXT_EXPIRED, "The context has expired",
- GSS_S_FAILURE, "Miscellaneous failure",
- GSS_S_BAD_QOP, "The quality-of-protection requested could "
- "not be provided",
- GSS_S_UNAUTHORIZED, "The operation is forbidden by local security "
- "policy",
- GSS_S_UNAVAILABLE, "The operation or option is unavailable",
- GSS_S_DUPLICATE_ELEMENT, "The requested credential element already "
- "exists",
- GSS_S_NAME_NOT_MN, "The provided name was not a mechanism name"
-};
-#define _gss_status_desc_count \
- sizeof(_gss_status_descs) / sizeof(_gss_status_descs[0])
+static const char *
+calling_error(OM_uint32 v)
+{
+ static const char *msgs[] = {
+ NULL, /* 0 */
+ "A required input parameter could not be read.", /* */
+ "A required output parameter could not be written.", /* */
+ "A parameter was malformed"
+ };
+
+ v >>= GSS_C_CALLING_ERROR_OFFSET;
+
+ if (v == 0)
+ return "";
+ else if (v >= sizeof(msgs)/sizeof(*msgs))
+ return "unknown calling error";
+ else
+ return msgs[v];
+}
+
+static const char *
+routine_error(OM_uint32 v)
+{
+ static const char *msgs[] = {
+ NULL, /* 0 */
+ "An unsupported mechanism was requested",
+ "An invalid name was supplied",
+ "A supplied name was of an unsupported type",
+ "Incorrect channel bindings were supplied",
+ "An invalid status code was supplied",
+ "A token had an invalid MIC",
+ "No credentials were supplied, "
+ "or the credentials were unavailable or inaccessible.",
+ "No context has been established",
+ "A token was invalid",
+ "A credential was invalid",
+ "The referenced credentials have expired",
+ "The context has expired",
+ "Miscellaneous failure (see text)",
+ "The quality-of-protection requested could not be provide",
+ "The operation is forbidden by local security policy",
+ "The operation or option is not available",
+ "The requested credential element already exists",
+ "The provided name was not a mechanism name.",
+ };
+
+ v >>= GSS_C_ROUTINE_ERROR_OFFSET;
+ if (v == 0)
+ return "";
+ else if (v >= sizeof(msgs)/sizeof(*msgs))
+ return "unknown routine error";
+ else
+ return msgs[v];
+}
+
+static const char *
+supplementary_error(OM_uint32 v)
+{
+ static const char *msgs[] = {
+ "normal completion",
+ "continuation call to routine required",
+ "duplicate per-message token detected",
+ "timed-out per-message token detected",
+ "reordered (early) per-message token detected",
+ "skipped predecessor token(s) detected"
+ };
+
+ v >>= GSS_C_SUPPLEMENTARY_OFFSET;
+
+ if (v >= sizeof(msgs)/sizeof(*msgs))
+ return "unknown routine error";
+ else
+ return msgs[v];
+}
OM_uint32
gss_display_status(OM_uint32 *minor_status,
@@ -73,31 +149,29 @@ gss_display_status(OM_uint32 *minor_status,
gss_buffer_t status_string)
{
OM_uint32 major_status;
- struct _gss_mech_switch *m;
- int i;
- const char *message;
*minor_status = 0;
switch (status_type) {
- case GSS_C_GSS_CODE:
- for (i = 0; i < _gss_status_desc_count; i++) {
- if (_gss_status_descs[i].gs_status == status_value) {
- message = _gss_status_descs[i].gs_desc;
- status_string->length = strlen(message);
- status_string->value = strdup(message);
- return (GSS_S_COMPLETE);
- }
- }
+ case GSS_C_GSS_CODE: {
+ char *buf;
+
+ if (GSS_SUPPLEMENTARY_INFO(status_value))
+ asprintf(&buf, "%s", supplementary_error(
+ GSS_SUPPLEMENTARY_INFO(status_value)));
+ else
+ asprintf (&buf, "%s %s",
+ calling_error(GSS_CALLING_ERROR(status_value)),
+ routine_error(GSS_ROUTINE_ERROR(status_value)));
+
+ status_string->length = strlen(buf);
+ status_string->value = buf;
- /*
- * Fall through to attempt to get some underlying
- * implementation to describe the value.
- */
- case GSS_C_MECH_CODE:
- SLIST_FOREACH(m, &_gss_mechs, gm_link) {
- if (mech_type &&
- !_gss_oid_equal(&m->gm_mech_oid, mech_type))
- continue;
+ return GSS_S_COMPLETE;
+ }
+ case GSS_C_MECH_CODE: {
+ struct _gss_mech_switch *m;
+ m = _gss_find_mech_switch(mech_type);
+ if (m) {
major_status = m->gm_display_status(minor_status,
status_value, status_type, mech_type,
message_content, status_string);
@@ -105,6 +179,8 @@ gss_display_status(OM_uint32 *minor_status,
return (GSS_S_COMPLETE);
}
}
-
+ }
+ status_string->value = NULL;
+ status_string->length = 0;
return (GSS_S_BAD_STATUS);
}
diff --git a/lib/libgssapi/gss_export_name.c b/lib/libgssapi/gss_export_name.c
index f504333..6cba2f8 100644
--- a/lib/libgssapi/gss_export_name.c
+++ b/lib/libgssapi/gss_export_name.c
@@ -39,6 +39,9 @@ gss_export_name(OM_uint32 *minor_status,
struct _gss_name *name = (struct _gss_name *) input_name;
struct _gss_mechanism_name *mn;
+ exported_name->value = NULL;
+ exported_name->length = 0;
+
/*
* If this name already has any attached MNs, export the first
* one, otherwise export based on the first mechanism in our
diff --git a/lib/libgssapi/gss_indicate_mechs.c b/lib/libgssapi/gss_indicate_mechs.c
index 7abab20..87a34f4 100644
--- a/lib/libgssapi/gss_indicate_mechs.c
+++ b/lib/libgssapi/gss_indicate_mechs.c
@@ -46,13 +46,18 @@ gss_indicate_mechs(OM_uint32 *minor_status,
return (major_status);
SLIST_FOREACH(m, &_gss_mechs, gm_link) {
- major_status = m->gm_indicate_mechs(minor_status, &set);
- if (major_status)
- continue;
- for (i = 0; i < set->count; i++)
- major_status = gss_add_oid_set_member(minor_status,
- &set->elements[i], mech_set);
- gss_release_oid_set(minor_status, &set);
+ if (m->gm_indicate_mechs) {
+ major_status = m->gm_indicate_mechs(minor_status, &set);
+ if (major_status)
+ continue;
+ for (i = 0; i < set->count; i++)
+ major_status = gss_add_oid_set_member(minor_status,
+ &set->elements[i], mech_set);
+ gss_release_oid_set(minor_status, &set);
+ } else {
+ major_status = gss_add_oid_set_member(
+ minor_status, &m->gm_mech_oid, mech_set);
+ }
}
*minor_status = 0;
diff --git a/lib/libgssapi/gss_init_sec_context.c b/lib/libgssapi/gss_init_sec_context.c
index b9325fe..8b596f3 100644
--- a/lib/libgssapi/gss_init_sec_context.c
+++ b/lib/libgssapi/gss_init_sec_context.c
@@ -98,6 +98,11 @@ gss_init_sec_context(OM_uint32 * minor_status,
* Find the MN for this mechanism.
*/
mn = _gss_find_mn(name, mech_type);
+ if (mn == NULL) {
+ if (allocated_ctx)
+ free(ctx);
+ return GSS_S_BAD_NAME;
+ }
/*
* If we have a cred, find the cred for this mechanism.
OpenPOWER on IntegriCloud