2 * Copyright (c) 2011, JANET(UK)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of JANET(UK) nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * Attribute provider mechanism.
37 #include "gssapiP_eap.h"
45 /* lazy initialisation */
47 static volatile OM_uint32 gssEapAttrProvidersInitStatus = GSS_S_UNAVAILABLE;
49 static GSSEAP_THREAD_ONCE gssEapAttrProvidersInitOnce = GSSEAP_ONCE_INITIALIZER;
50 static OM_uint32 gssEapAttrProvidersInitStatus = GSS_S_UNAVAILABLE;
53 GSSEAP_ONCE_CALLBACK(gssEapAttrProvidersInitInternal)
55 OM_uint32 major, minor;
57 GSSEAP_ASSERT(gssEapAttrProvidersInitStatus == GSS_S_UNAVAILABLE);
59 json_set_alloc_funcs(GSSEAP_MALLOC, GSSEAP_FREE);
61 major = gssEapRadiusAttrProviderInit(&minor);
66 major = gssEapSamlAttrProvidersInit(&minor);
71 #ifdef HAVE_SHIBRESOLVER
72 /* Allow Shibboleth initialization failure to be non-fatal */
73 gssEapLocalAttrProviderInit(&minor);
78 GSSEAP_ASSERT(major == GSS_S_COMPLETE);
82 InterlockedCompareExchangeRelease(&gssEapAttrProvidersInitStatus,
83 major, GSS_S_UNAVAILABLE);
85 gssEapAttrProvidersInitStatus = major;
92 gssEapAttrProvidersInit(OM_uint32 *minor)
95 if (gssEapAttrProvidersInitStatus == GSS_S_UNAVAILABLE)
96 gssEapAttrProvidersInitInternal();
98 GSSEAP_ONCE(&gssEapAttrProvidersInitOnce, gssEapAttrProvidersInitInternal);
101 if (GSS_ERROR(gssEapAttrProvidersInitStatus))
102 *minor = GSSEAP_NO_ATTR_PROVIDERS;
104 return gssEapAttrProvidersInitStatus;
108 gssEapAttrProvidersFinalize(OM_uint32 *minor)
110 if (gssEapAttrProvidersInitStatus == GSS_S_COMPLETE) {
111 #ifdef HAVE_SHIBRESOLVER
112 gssEapLocalAttrProviderFinalize(minor);
115 gssEapSamlAttrProvidersFinalize(minor);
117 gssEapRadiusAttrProviderFinalize(minor);
119 gssEapAttrProvidersInitStatus = GSS_S_UNAVAILABLE;
122 return GSS_S_COMPLETE;
125 static gss_eap_attr_create_provider gssEapAttrFactories[ATTR_TYPE_MAX + 1];
128 * Register a provider for a particular type and prefix
131 gss_eap_attr_ctx::registerProvider(unsigned int type,
132 gss_eap_attr_create_provider factory)
134 GSSEAP_ASSERT(type <= ATTR_TYPE_MAX);
136 GSSEAP_ASSERT(gssEapAttrFactories[type] == NULL);
138 gssEapAttrFactories[type] = factory;
142 * Unregister a provider
145 gss_eap_attr_ctx::unregisterProvider(unsigned int type)
147 GSSEAP_ASSERT(type <= ATTR_TYPE_MAX);
149 gssEapAttrFactories[type] = NULL;
153 * Create an attribute context, that manages instances of providers
155 gss_eap_attr_ctx::gss_eap_attr_ctx(void)
159 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
160 gss_eap_attr_provider *provider;
162 if (gssEapAttrFactories[i] != NULL) {
163 provider = (gssEapAttrFactories[i])();
168 m_providers[i] = provider;
173 * Convert an attribute prefix to a type
176 gss_eap_attr_ctx::attributePrefixToType(const gss_buffer_t prefix) const
180 for (i = ATTR_TYPE_MIN; i < ATTR_TYPE_MAX; i++) {
183 if (!providerEnabled(i))
186 pprefix = m_providers[i]->prefix();
190 if (strlen(pprefix) == prefix->length &&
191 memcmp(pprefix, prefix->value, prefix->length) == 0)
195 return ATTR_TYPE_LOCAL;
199 * Convert a type to an attribute prefix
202 gss_eap_attr_ctx::attributeTypeToPrefix(unsigned int type) const
204 gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER;
206 if (type < ATTR_TYPE_MIN || type >= ATTR_TYPE_MAX)
209 if (!providerEnabled(type))
212 prefix.value = (void *)m_providers[type]->prefix();
213 if (prefix.value != NULL)
214 prefix.length = strlen((char *)prefix.value);
220 gss_eap_attr_ctx::providerEnabled(unsigned int type) const
222 if (type == ATTR_TYPE_LOCAL &&
223 (m_flags & ATTR_FLAG_DISABLE_LOCAL))
226 if (m_providers[type] == NULL)
233 gss_eap_attr_ctx::releaseProvider(unsigned int type)
235 delete m_providers[type];
236 m_providers[type] = NULL;
240 * Initialize a context from an existing context.
243 gss_eap_attr_ctx::initWithExistingContext(const gss_eap_attr_ctx *manager)
247 m_flags = manager->m_flags;
249 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
250 gss_eap_attr_provider *provider;
252 if (!providerEnabled(i)) {
257 provider = m_providers[i];
259 ret = provider->initWithExistingContext(this,
260 manager->m_providers[i]);
271 * Initialize a context from a GSS credential and context.
274 gss_eap_attr_ctx::initWithGssContext(const gss_cred_id_t cred,
275 const gss_ctx_id_t ctx)
279 if (cred != GSS_C_NO_CREDENTIAL &&
280 (cred->flags & GSS_EAP_DISABLE_LOCAL_ATTRS_FLAG)) {
281 m_flags |= ATTR_FLAG_DISABLE_LOCAL;
284 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
285 gss_eap_attr_provider *provider;
287 if (!providerEnabled(i)) {
292 provider = m_providers[i];
294 ret = provider->initWithGssContext(this, cred, ctx);
305 gss_eap_attr_ctx::initWithJsonObject(JSONObject &obj)
308 bool foundSource[ATTR_TYPE_MAX + 1];
311 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++)
312 foundSource[type] = false;
314 if (obj["version"].integer() != 1)
317 m_flags = obj["flags"].integer();
319 JSONObject sources = obj["sources"];
321 /* Initialize providers from serialized state */
322 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
323 gss_eap_attr_provider *provider;
326 if (!providerEnabled(type)) {
327 releaseProvider(type);
331 provider = m_providers[type];
332 key = provider->name();
336 JSONObject source = sources.get(key);
337 if (!source.isNull() &&
338 !provider->initWithJsonObject(this, source)) {
339 releaseProvider(type);
343 foundSource[type] = true;
346 /* Initialize remaining providers from initialized providers */
347 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
348 gss_eap_attr_provider *provider;
350 if (foundSource[type] || !providerEnabled(type))
353 provider = m_providers[type];
355 ret = provider->initWithGssContext(this,
359 releaseProvider(type);
368 gss_eap_attr_ctx::jsonRepresentation(void) const
370 JSONObject obj, sources;
373 obj.set("version", 1);
374 obj.set("flags", m_flags);
376 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
377 gss_eap_attr_provider *provider;
380 provider = m_providers[i];
381 if (provider == NULL)
382 continue; /* provider not initialised */
384 key = provider->name();
386 continue; /* provider does not have state */
388 JSONObject source = provider->jsonRepresentation();
389 sources.set(key, source);
392 obj.set("sources", sources);
398 * Initialize a context from an exported context or name token
401 gss_eap_attr_ctx::initWithBuffer(const gss_buffer_t buffer)
403 OM_uint32 major, minor;
408 major = bufferToString(&minor, buffer, &s);
409 if (GSS_ERROR(major))
412 JSONObject obj = JSONObject::load(s, 0, &error);
414 ret = initWithJsonObject(obj);
423 gss_eap_attr_ctx::~gss_eap_attr_ctx(void)
425 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++)
426 delete m_providers[i];
430 * Locate provider for a given type
432 gss_eap_attr_provider *
433 gss_eap_attr_ctx::getProvider(unsigned int type) const
435 GSSEAP_ASSERT(type >= ATTR_TYPE_MIN && type <= ATTR_TYPE_MAX);
436 return m_providers[type];
440 * Get primary provider. Only the primary provider is serialised when
441 * gss_export_sec_context() or gss_export_name_composite() is called.
443 gss_eap_attr_provider *
444 gss_eap_attr_ctx::getPrimaryProvider(void) const
446 return m_providers[ATTR_TYPE_MIN];
453 gss_eap_attr_ctx::setAttribute(int complete,
454 const gss_buffer_t attr,
455 const gss_buffer_t value)
457 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
459 gss_eap_attr_provider *provider;
462 decomposeAttributeName(attr, &type, &suffix);
464 provider = m_providers[type];
465 if (provider != NULL) {
466 ret = provider->setAttribute(complete,
467 (type == ATTR_TYPE_LOCAL) ? attr : &suffix,
475 * Delete an attrbiute
478 gss_eap_attr_ctx::deleteAttribute(const gss_buffer_t attr)
480 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
482 gss_eap_attr_provider *provider;
485 decomposeAttributeName(attr, &type, &suffix);
487 provider = m_providers[type];
488 if (provider != NULL) {
489 ret = provider->deleteAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix);
496 * Enumerate attribute types with callback
499 gss_eap_attr_ctx::getAttributeTypes(gss_eap_attr_enumeration_cb cb, void *data) const
504 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
505 gss_eap_attr_provider *provider = m_providers[i];
507 if (provider == NULL)
510 ret = provider->getAttributeTypes(cb, data);
518 struct eap_gss_get_attr_types_args {
520 gss_buffer_set_t attrs;
524 addAttribute(const gss_eap_attr_ctx *manager,
525 const gss_eap_attr_provider *provider GSSEAP_UNUSED,
526 const gss_buffer_t attribute,
529 eap_gss_get_attr_types_args *args = (eap_gss_get_attr_types_args *)data;
530 gss_buffer_desc qualified;
531 OM_uint32 major, minor;
533 if (args->type != ATTR_TYPE_LOCAL) {
534 manager->composeAttributeName(args->type, attribute, &qualified);
535 major = gss_add_buffer_set_member(&minor, &qualified, &args->attrs);
536 gss_release_buffer(&minor, &qualified);
538 major = gss_add_buffer_set_member(&minor, attribute, &args->attrs);
541 return GSS_ERROR(major) == false;
545 * Enumerate attribute types, output is buffer set
548 gss_eap_attr_ctx::getAttributeTypes(gss_buffer_set_t *attrs)
550 eap_gss_get_attr_types_args args;
551 OM_uint32 major, minor;
555 major = gss_create_empty_buffer_set(&minor, attrs);
556 if (GSS_ERROR(major))
557 throw std::bad_alloc();
561 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
562 gss_eap_attr_provider *provider = m_providers[i];
566 if (provider == NULL)
569 ret = provider->getAttributeTypes(addAttribute, (void *)&args);
575 gss_release_buffer_set(&minor, attrs);
581 * Get attribute with given name
584 gss_eap_attr_ctx::getAttribute(const gss_buffer_t attr,
588 gss_buffer_t display_value,
591 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
593 gss_eap_attr_provider *provider;
596 decomposeAttributeName(attr, &type, &suffix);
598 provider = m_providers[type];
599 if (provider == NULL)
602 ret = provider->getAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix,
603 authenticated, complete,
604 value, display_value, more);
610 * Map attribute context to C++ object
613 gss_eap_attr_ctx::mapToAny(int authenticated,
614 gss_buffer_t type_id) const
617 gss_eap_attr_provider *provider;
618 gss_buffer_desc suffix;
620 decomposeAttributeName(type_id, &type, &suffix);
622 provider = m_providers[type];
623 if (provider == NULL)
624 return (gss_any_t)NULL;
626 return provider->mapToAny(authenticated, &suffix);
630 * Release mapped context
633 gss_eap_attr_ctx::releaseAnyNameMapping(gss_buffer_t type_id,
634 gss_any_t input) const
637 gss_eap_attr_provider *provider;
638 gss_buffer_desc suffix;
640 decomposeAttributeName(type_id, &type, &suffix);
642 provider = m_providers[type];
643 if (provider != NULL)
644 provider->releaseAnyNameMapping(&suffix, input);
648 * Export attribute context to buffer
651 gss_eap_attr_ctx::exportToBuffer(gss_buffer_t buffer) const
656 JSONObject obj = jsonRepresentation();
662 s = obj.dump(JSON_COMPACT);
664 if (GSS_ERROR(makeStringBuffer(&minor, s, buffer)))
665 throw std::bad_alloc();
669 * Return soonest expiry time of providers
672 gss_eap_attr_ctx::getExpiryTime(void) const
675 time_t expiryTime = 0;
677 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
678 gss_eap_attr_provider *provider = m_providers[i];
679 time_t providerExpiryTime;
681 if (provider == NULL)
684 providerExpiryTime = provider->getExpiryTime();
685 if (providerExpiryTime == 0)
688 if (expiryTime == 0 || providerExpiryTime < expiryTime)
689 expiryTime = providerExpiryTime;
696 gss_eap_attr_ctx::mapException(OM_uint32 *minor, std::exception &e) const
701 /* Errors we handle ourselves */
702 if (typeid(e) == typeid(std::bad_alloc)) {
703 major = GSS_S_FAILURE;
706 } else if (typeid(e) == typeid(JSONException)) {
707 major = GSS_S_BAD_NAME;
708 *minor = GSSEAP_BAD_ATTR_TOKEN;
709 gssEapSaveStatusInfo(*minor, "%s", e.what());
713 /* Errors we delegate to providers */
714 major = GSS_S_CONTINUE_NEEDED;
716 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
717 gss_eap_attr_provider *provider = m_providers[i];
719 if (provider == NULL)
722 major = provider->mapException(minor, e);
723 if (major != GSS_S_CONTINUE_NEEDED)
727 if (major == GSS_S_CONTINUE_NEEDED) {
728 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
729 major = GSS_S_FAILURE;
733 GSSEAP_ASSERT(GSS_ERROR(major));
739 * Decompose attribute name into prefix and suffix
742 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
749 for (i = 0; i < attribute->length; i++) {
750 if (((char *)attribute->value)[i] == ' ') {
751 p = (char *)attribute->value + i + 1;
756 prefix->value = attribute->value;
759 if (p != NULL && *p != '\0') {
760 suffix->length = attribute->length - 1 - prefix->length;
764 suffix->value = NULL;
769 * Decompose attribute name into type and suffix
772 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
774 gss_buffer_t suffix) const
776 gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER;
778 decomposeAttributeName(attribute, &prefix, suffix);
779 *type = attributePrefixToType(&prefix);
783 * Compose attribute name from prefix, suffix; returns C++ string
786 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
787 const gss_buffer_t suffix)
791 if (prefix == GSS_C_NO_BUFFER || prefix->length == 0)
794 str.append((const char *)prefix->value, prefix->length);
796 if (suffix != GSS_C_NO_BUFFER) {
798 str.append((const char *)suffix->value, suffix->length);
805 * Compose attribute name from type, suffix; returns C++ string
808 gss_eap_attr_ctx::composeAttributeName(unsigned int type,
809 const gss_buffer_t suffix)
811 gss_buffer_desc prefix = attributeTypeToPrefix(type);
813 return composeAttributeName(&prefix, suffix);
817 * Compose attribute name from prefix, suffix; returns GSS buffer
820 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
821 const gss_buffer_t suffix,
822 gss_buffer_t attribute)
824 std::string str = composeAttributeName(prefix, suffix);
826 if (str.length() != 0) {
827 return duplicateBuffer(str, attribute);
829 attribute->length = 0;
830 attribute->value = NULL;
835 * Compose attribute name from type, suffix; returns GSS buffer
838 gss_eap_attr_ctx::composeAttributeName(unsigned int type,
839 const gss_buffer_t suffix,
840 gss_buffer_t attribute) const
842 gss_buffer_desc prefix = attributeTypeToPrefix(type);
844 return composeAttributeName(&prefix, suffix, attribute);
851 gssEapInquireName(OM_uint32 *minor,
855 gss_buffer_set_t *attrs)
859 if (name_is_MN != NULL)
860 *name_is_MN = (name->mechanismUsed != GSS_C_NULL_OID);
862 if (MN_mech != NULL) {
863 major = gssEapCanonicalizeOid(minor, name->mechanismUsed,
864 OID_FLAG_NULL_VALID, MN_mech);
865 if (GSS_ERROR(major))
869 if (name->attrCtx == NULL) {
870 *minor = GSSEAP_NO_ATTR_CONTEXT;
871 return GSS_S_UNAVAILABLE;
874 if (GSS_ERROR(gssEapAttrProvidersInit(minor))) {
875 return GSS_S_UNAVAILABLE;
879 if (!name->attrCtx->getAttributeTypes(attrs)) {
880 *minor = GSSEAP_NO_ATTR_CONTEXT;
881 return GSS_S_UNAVAILABLE;
883 } catch (std::exception &e) {
884 return name->attrCtx->mapException(minor, e);
887 return GSS_S_COMPLETE;
891 gssEapGetNameAttribute(OM_uint32 *minor,
897 gss_buffer_t display_value,
900 if (authenticated != NULL)
902 if (complete != NULL)
910 if (display_value != NULL) {
911 display_value->length = 0;
912 display_value->value = NULL;
915 if (name->attrCtx == NULL) {
916 *minor = GSSEAP_NO_ATTR_CONTEXT;
917 return GSS_S_UNAVAILABLE;
920 if (GSS_ERROR(gssEapAttrProvidersInit(minor))) {
921 return GSS_S_UNAVAILABLE;
925 if (!name->attrCtx->getAttribute(attr, authenticated, complete,
926 value, display_value, more)) {
927 *minor = GSSEAP_NO_SUCH_ATTR;
928 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
929 (int)attr->length, (char *)attr->value);
930 return GSS_S_UNAVAILABLE;
932 } catch (std::exception &e) {
933 return name->attrCtx->mapException(minor, e);
936 return GSS_S_COMPLETE;
940 gssEapDeleteNameAttribute(OM_uint32 *minor,
944 if (name->attrCtx == NULL) {
945 *minor = GSSEAP_NO_ATTR_CONTEXT;
946 return GSS_S_UNAVAILABLE;
949 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
950 return GSS_S_UNAVAILABLE;
953 if (!name->attrCtx->deleteAttribute(attr)) {
954 *minor = GSSEAP_NO_SUCH_ATTR;
955 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
956 (int)attr->length, (char *)attr->value);
957 return GSS_S_UNAVAILABLE;
959 } catch (std::exception &e) {
960 return name->attrCtx->mapException(minor, e);
963 return GSS_S_COMPLETE;
967 gssEapSetNameAttribute(OM_uint32 *minor,
973 if (name->attrCtx == NULL) {
974 *minor = GSSEAP_NO_ATTR_CONTEXT;
975 return GSS_S_UNAVAILABLE;
978 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
979 return GSS_S_UNAVAILABLE;
982 if (!name->attrCtx->setAttribute(complete, attr, value)) {
983 *minor = GSSEAP_NO_SUCH_ATTR;
984 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
985 (int)attr->length, (char *)attr->value);
986 return GSS_S_UNAVAILABLE;
988 } catch (std::exception &e) {
989 return name->attrCtx->mapException(minor, e);
992 return GSS_S_COMPLETE;
996 gssEapExportAttrContext(OM_uint32 *minor,
1000 if (name->attrCtx == NULL) {
1002 buffer->value = NULL;
1004 return GSS_S_COMPLETE;
1007 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1008 return GSS_S_UNAVAILABLE;
1011 name->attrCtx->exportToBuffer(buffer);
1012 } catch (std::exception &e) {
1013 return name->attrCtx->mapException(minor, e);
1016 return GSS_S_COMPLETE;
1020 gssEapImportAttrContext(OM_uint32 *minor,
1021 gss_buffer_t buffer,
1024 gss_eap_attr_ctx *ctx = NULL;
1025 OM_uint32 major = GSS_S_FAILURE;
1027 GSSEAP_ASSERT(name->attrCtx == NULL);
1029 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1030 return GSS_S_UNAVAILABLE;
1032 if (buffer->length == 0)
1033 return GSS_S_COMPLETE;
1036 ctx = new gss_eap_attr_ctx();
1038 if (ctx->initWithBuffer(buffer)) {
1039 name->attrCtx = ctx;
1040 major = GSS_S_COMPLETE;
1043 major = GSS_S_BAD_NAME;
1044 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1046 } catch (std::exception &e) {
1048 major = ctx->mapException(minor, e);
1051 GSSEAP_ASSERT(major == GSS_S_COMPLETE || name->attrCtx == NULL);
1053 if (GSS_ERROR(major))
1060 gssEapDuplicateAttrContext(OM_uint32 *minor,
1064 gss_eap_attr_ctx *ctx = NULL;
1065 OM_uint32 major = GSS_S_FAILURE;
1067 GSSEAP_ASSERT(out->attrCtx == NULL);
1069 if (in->attrCtx == NULL) {
1071 return GSS_S_COMPLETE;
1074 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1075 return GSS_S_UNAVAILABLE;
1078 ctx = new gss_eap_attr_ctx();
1080 if (ctx->initWithExistingContext(in->attrCtx)) {
1082 major = GSS_S_COMPLETE;
1085 major = GSS_S_FAILURE;
1086 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1088 } catch (std::exception &e) {
1089 major = in->attrCtx->mapException(minor, e);
1092 GSSEAP_ASSERT(major == GSS_S_COMPLETE || out->attrCtx == NULL);
1094 if (GSS_ERROR(major))
1097 return GSS_S_COMPLETE;
1101 gssEapMapNameToAny(OM_uint32 *minor,
1104 gss_buffer_t type_id,
1107 if (name->attrCtx == NULL) {
1108 *minor = GSSEAP_NO_ATTR_CONTEXT;
1109 return GSS_S_UNAVAILABLE;
1112 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1113 return GSS_S_UNAVAILABLE;
1116 *output = name->attrCtx->mapToAny(authenticated, type_id);
1117 } catch (std::exception &e) {
1118 return name->attrCtx->mapException(minor, e);
1121 return GSS_S_COMPLETE;
1125 gssEapReleaseAnyNameMapping(OM_uint32 *minor,
1127 gss_buffer_t type_id,
1130 if (name->attrCtx == NULL) {
1131 *minor = GSSEAP_NO_ATTR_CONTEXT;
1132 return GSS_S_UNAVAILABLE;
1135 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1136 return GSS_S_UNAVAILABLE;
1140 name->attrCtx->releaseAnyNameMapping(type_id, *input);
1142 } catch (std::exception &e) {
1143 return name->attrCtx->mapException(minor, e);
1146 return GSS_S_COMPLETE;
1150 gssEapReleaseAttrContext(OM_uint32 *minor,
1153 if (name->attrCtx != NULL)
1154 delete name->attrCtx;
1157 return GSS_S_COMPLETE;
1161 * Public accessor for initialisng a context from a GSS context. Also
1162 * sets expiry time on GSS context as a side-effect.
1165 gssEapCreateAttrContext(OM_uint32 *minor,
1166 gss_cred_id_t gssCred,
1167 gss_ctx_id_t gssCtx,
1168 struct gss_eap_attr_ctx **pAttrContext,
1169 time_t *pExpiryTime)
1171 gss_eap_attr_ctx *ctx = NULL;
1174 GSSEAP_ASSERT(gssCtx != GSS_C_NO_CONTEXT);
1176 *pAttrContext = NULL;
1178 major = gssEapAttrProvidersInit(minor);
1179 if (GSS_ERROR(major))
1183 /* Set *pAttrContext here to for reentrancy */
1184 *pAttrContext = ctx = new gss_eap_attr_ctx();
1186 if (ctx->initWithGssContext(gssCred, gssCtx)) {
1187 *pExpiryTime = ctx->getExpiryTime();
1188 major = GSS_S_COMPLETE;
1191 major = GSS_S_FAILURE;
1192 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1194 } catch (std::exception &e) {
1196 major = ctx->mapException(minor, e);
1199 if (GSS_ERROR(major)) {
1201 *pAttrContext = NULL;