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 */
46 static GSSEAP_THREAD_ONCE gssEapAttrProvidersInitOnce = GSSEAP_ONCE_INITIALIZER;
47 static OM_uint32 gssEapAttrProvidersInitStatus = GSS_S_UNAVAILABLE;
49 GSSEAP_ONCE_CALLBACK(gssEapAttrProvidersInitInternal)
51 OM_uint32 major, minor;
53 GSSEAP_ASSERT(gssEapAttrProvidersInitStatus == GSS_S_UNAVAILABLE);
55 json_set_alloc_funcs(GSSEAP_MALLOC, GSSEAP_FREE);
57 major = gssEapRadiusAttrProviderInit(&minor);
62 #ifdef HAVE_SHIBRESOLVER
63 /* Allow Shibboleth initialization failure to be non-fatal */
64 gssEapLocalAttrProviderInit(&minor);
67 wpa_printf(MSG_INFO, "### gssEapAttrProvidersInitInternal(): Calling gssEapSamlAttrProvidersInit()");
68 major = gssEapSamlAttrProvidersInit(&minor);
69 if (GSS_ERROR(major)) {
70 wpa_printf(MSG_ERROR, "### gssEapAttrProvidersInitInternal(): Error returned from gssEapSamlAttrProvidersInit; major code is %08X; minor is %08X", major, minor);
74 wpa_printf(MSG_INFO, "### gssEapAttrProvidersInitInternal(): Don't have OpenSAML; not calling gssEapSamlAttrProvidersInit()");
79 GSSEAP_ASSERT(major == GSS_S_COMPLETE);
82 wpa_printf(MSG_INFO, "### gssEapAttrProvidersInitInternal(): Setting gssEapAttrProvidersInitStatus to %08X", major);
83 gssEapAttrProvidersInitStatus = major;
89 gssEapAttrProvidersInit(OM_uint32 *minor)
91 GSSEAP_ONCE(&gssEapAttrProvidersInitOnce, gssEapAttrProvidersInitInternal);
93 if (GSS_ERROR(gssEapAttrProvidersInitStatus))
94 *minor = GSSEAP_NO_ATTR_PROVIDERS;
96 return gssEapAttrProvidersInitStatus;
102 class finalize_class {
106 wpa_printf(MSG_INFO, "### finalize_class::finalize_class(): Constructing");
113 wpa_printf(MSG_INFO, "### ~finalize_class::~finalize_class() : initStatus=%08x", gssEapAttrProvidersInitStatus);
115 if (gssEapAttrProvidersInitStatus == GSS_S_COMPLETE) {
116 wpa_printf(MSG_INFO, "### ~finalize_class::~finalize_class() : really finalizing");
119 gssEapSamlAttrProvidersFinalize(&minor);
121 gssEapRadiusAttrProviderFinalize(&minor);
123 gssEapAttrProvidersInitStatus = GSS_S_UNAVAILABLE;
131 static gss_eap_attr_create_provider gssEapAttrFactories[ATTR_TYPE_MAX + 1];
134 * Register a provider for a particular type and prefix
137 gss_eap_attr_ctx::registerProvider(unsigned int type,
138 gss_eap_attr_create_provider factory)
140 GSSEAP_ASSERT(type <= ATTR_TYPE_MAX);
142 GSSEAP_ASSERT(gssEapAttrFactories[type] == NULL);
144 gssEapAttrFactories[type] = factory;
148 * Unregister a provider
151 gss_eap_attr_ctx::unregisterProvider(unsigned int type)
153 GSSEAP_ASSERT(type <= ATTR_TYPE_MAX);
155 gssEapAttrFactories[type] = NULL;
159 * Create an attribute context, that manages instances of providers
161 gss_eap_attr_ctx::gss_eap_attr_ctx(void)
165 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
166 gss_eap_attr_provider *provider;
168 if (gssEapAttrFactories[i] != NULL) {
169 provider = (gssEapAttrFactories[i])();
174 m_providers[i] = provider;
179 * Convert an attribute prefix to a type
182 gss_eap_attr_ctx::attributePrefixToType(const gss_buffer_t prefix) const
186 for (i = ATTR_TYPE_MIN; i < ATTR_TYPE_MAX; i++) {
189 if (!providerEnabled(i))
192 pprefix = m_providers[i]->prefix();
196 if (strlen(pprefix) == prefix->length &&
197 memcmp(pprefix, prefix->value, prefix->length) == 0)
201 return ATTR_TYPE_LOCAL;
205 * Convert a type to an attribute prefix
208 gss_eap_attr_ctx::attributeTypeToPrefix(unsigned int type) const
210 gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER;
212 if (type < ATTR_TYPE_MIN || type >= ATTR_TYPE_MAX)
215 if (!providerEnabled(type))
218 prefix.value = (void *)m_providers[type]->prefix();
219 if (prefix.value != NULL)
220 prefix.length = strlen((char *)prefix.value);
226 gss_eap_attr_ctx::providerEnabled(unsigned int type) const
228 if (type == ATTR_TYPE_LOCAL &&
229 (m_flags & ATTR_FLAG_DISABLE_LOCAL))
232 if (m_providers[type] == NULL)
239 gss_eap_attr_ctx::releaseProvider(unsigned int type)
241 delete m_providers[type];
242 m_providers[type] = NULL;
246 * Initialize a context from an existing context.
249 gss_eap_attr_ctx::initWithExistingContext(const gss_eap_attr_ctx *manager)
253 m_flags = manager->m_flags;
255 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
256 gss_eap_attr_provider *provider;
258 if (!providerEnabled(i)) {
263 provider = m_providers[i];
265 ret = provider->initWithExistingContext(this,
266 manager->m_providers[i]);
277 * Initialize a context from a GSS credential and context.
280 gss_eap_attr_ctx::initWithGssContext(const gss_cred_id_t cred,
281 const gss_ctx_id_t ctx)
285 if (cred != GSS_C_NO_CREDENTIAL &&
286 (cred->flags & GSS_EAP_DISABLE_LOCAL_ATTRS_FLAG)) {
287 m_flags |= ATTR_FLAG_DISABLE_LOCAL;
290 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
291 gss_eap_attr_provider *provider;
293 if (!providerEnabled(i)) {
298 provider = m_providers[i];
300 ret = provider->initWithGssContext(this, cred, ctx);
311 gss_eap_attr_ctx::initWithJsonObject(JSONObject &obj)
314 bool foundSource[ATTR_TYPE_MAX + 1];
317 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++)
318 foundSource[type] = false;
320 if (obj["version"].integer() != 1)
323 m_flags = obj["flags"].integer();
325 JSONObject sources = obj["sources"];
327 /* Initialize providers from serialized state */
328 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
329 gss_eap_attr_provider *provider;
332 if (!providerEnabled(type)) {
333 releaseProvider(type);
337 provider = m_providers[type];
338 key = provider->name();
342 JSONObject source = sources.get(key);
343 if (!source.isNull() &&
344 !provider->initWithJsonObject(this, source)) {
345 releaseProvider(type);
349 foundSource[type] = true;
352 /* Initialize remaining providers from initialized providers */
353 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
354 gss_eap_attr_provider *provider;
356 if (foundSource[type] || !providerEnabled(type))
359 provider = m_providers[type];
361 ret = provider->initWithGssContext(this,
365 releaseProvider(type);
374 gss_eap_attr_ctx::jsonRepresentation(void) const
376 JSONObject obj, sources;
379 obj.set("version", 1);
380 obj.set("flags", m_flags);
382 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
383 gss_eap_attr_provider *provider;
386 provider = m_providers[i];
387 if (provider == NULL)
388 continue; /* provider not initialised */
390 key = provider->name();
392 continue; /* provider does not have state */
394 JSONObject source = provider->jsonRepresentation();
395 sources.set(key, source);
398 obj.set("sources", sources);
404 * Initialize a context from an exported context or name token
407 gss_eap_attr_ctx::initWithBuffer(const gss_buffer_t buffer)
409 OM_uint32 major, minor;
414 major = bufferToString(&minor, buffer, &s);
415 if (GSS_ERROR(major))
418 JSONObject obj = JSONObject::load(s, 0, &error);
420 ret = initWithJsonObject(obj);
429 gss_eap_attr_ctx::~gss_eap_attr_ctx(void)
431 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++)
432 delete m_providers[i];
436 * Locate provider for a given type
438 gss_eap_attr_provider *
439 gss_eap_attr_ctx::getProvider(unsigned int type) const
441 GSSEAP_ASSERT(type >= ATTR_TYPE_MIN && type <= ATTR_TYPE_MAX);
442 return m_providers[type];
446 * Get primary provider. Only the primary provider is serialised when
447 * gss_export_sec_context() or gss_export_name_composite() is called.
449 gss_eap_attr_provider *
450 gss_eap_attr_ctx::getPrimaryProvider(void) const
452 return m_providers[ATTR_TYPE_MIN];
459 gss_eap_attr_ctx::setAttribute(int complete,
460 const gss_buffer_t attr,
461 const gss_buffer_t value)
463 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
465 gss_eap_attr_provider *provider;
468 decomposeAttributeName(attr, &type, &suffix);
470 provider = m_providers[type];
471 if (provider != NULL) {
472 ret = provider->setAttribute(complete,
473 (type == ATTR_TYPE_LOCAL) ? attr : &suffix,
481 * Delete an attrbiute
484 gss_eap_attr_ctx::deleteAttribute(const gss_buffer_t attr)
486 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
488 gss_eap_attr_provider *provider;
491 decomposeAttributeName(attr, &type, &suffix);
493 provider = m_providers[type];
494 if (provider != NULL) {
495 ret = provider->deleteAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix);
502 * Enumerate attribute types with callback
505 gss_eap_attr_ctx::getAttributeTypes(gss_eap_attr_enumeration_cb cb, void *data) const
510 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
511 gss_eap_attr_provider *provider = m_providers[i];
513 if (provider == NULL)
516 ret = provider->getAttributeTypes(cb, data);
524 struct eap_gss_get_attr_types_args {
526 gss_buffer_set_t attrs;
530 addAttribute(const gss_eap_attr_ctx *manager,
531 const gss_eap_attr_provider *provider GSSEAP_UNUSED,
532 const gss_buffer_t attribute,
535 eap_gss_get_attr_types_args *args = (eap_gss_get_attr_types_args *)data;
536 gss_buffer_desc qualified;
537 OM_uint32 major, minor;
539 if (args->type != ATTR_TYPE_LOCAL) {
540 manager->composeAttributeName(args->type, attribute, &qualified);
541 major = gss_add_buffer_set_member(&minor, &qualified, &args->attrs);
542 gss_release_buffer(&minor, &qualified);
544 major = gss_add_buffer_set_member(&minor, attribute, &args->attrs);
547 return GSS_ERROR(major) == false;
551 * Enumerate attribute types, output is buffer set
554 gss_eap_attr_ctx::getAttributeTypes(gss_buffer_set_t *attrs)
556 eap_gss_get_attr_types_args args;
557 OM_uint32 major, minor;
561 major = gss_create_empty_buffer_set(&minor, attrs);
562 if (GSS_ERROR(major))
563 throw std::bad_alloc();
567 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
568 gss_eap_attr_provider *provider = m_providers[i];
572 if (provider == NULL)
575 ret = provider->getAttributeTypes(addAttribute, (void *)&args);
581 gss_release_buffer_set(&minor, attrs);
587 * Get attribute with given name
590 gss_eap_attr_ctx::getAttribute(const gss_buffer_t attr,
594 gss_buffer_t display_value,
597 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
599 gss_eap_attr_provider *provider;
602 decomposeAttributeName(attr, &type, &suffix);
604 provider = m_providers[type];
605 if (provider == NULL)
608 ret = provider->getAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix,
609 authenticated, complete,
610 value, display_value, more);
616 * Map attribute context to C++ object
619 gss_eap_attr_ctx::mapToAny(int authenticated,
620 gss_buffer_t type_id) const
623 gss_eap_attr_provider *provider;
624 gss_buffer_desc suffix;
626 decomposeAttributeName(type_id, &type, &suffix);
628 provider = m_providers[type];
629 if (provider == NULL)
630 return (gss_any_t)NULL;
632 return provider->mapToAny(authenticated, &suffix);
636 * Release mapped context
639 gss_eap_attr_ctx::releaseAnyNameMapping(gss_buffer_t type_id,
640 gss_any_t input) const
643 gss_eap_attr_provider *provider;
644 gss_buffer_desc suffix;
646 decomposeAttributeName(type_id, &type, &suffix);
648 provider = m_providers[type];
649 if (provider != NULL)
650 provider->releaseAnyNameMapping(&suffix, input);
654 * Export attribute context to buffer
657 gss_eap_attr_ctx::exportToBuffer(gss_buffer_t buffer) const
662 JSONObject obj = jsonRepresentation();
668 s = obj.dump(JSON_COMPACT);
670 if (GSS_ERROR(makeStringBuffer(&minor, s, buffer)))
671 throw std::bad_alloc();
675 * Return soonest expiry time of providers
678 gss_eap_attr_ctx::getExpiryTime(void) const
681 time_t expiryTime = 0;
683 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
684 gss_eap_attr_provider *provider = m_providers[i];
685 time_t providerExpiryTime;
687 if (provider == NULL)
690 providerExpiryTime = provider->getExpiryTime();
691 if (providerExpiryTime == 0)
694 if (expiryTime == 0 || providerExpiryTime < expiryTime)
695 expiryTime = providerExpiryTime;
702 gss_eap_attr_ctx::mapException(OM_uint32 *minor, std::exception &e) const
707 /* Errors we handle ourselves */
708 if (typeid(e) == typeid(std::bad_alloc)) {
709 major = GSS_S_FAILURE;
712 } else if (typeid(e) == typeid(JSONException)) {
713 major = GSS_S_BAD_NAME;
714 *minor = GSSEAP_BAD_ATTR_TOKEN;
715 gssEapSaveStatusInfo(*minor, "%s", e.what());
719 /* Errors we delegate to providers */
720 major = GSS_S_CONTINUE_NEEDED;
722 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
723 gss_eap_attr_provider *provider = m_providers[i];
725 if (provider == NULL)
728 major = provider->mapException(minor, e);
729 if (major != GSS_S_CONTINUE_NEEDED)
733 if (major == GSS_S_CONTINUE_NEEDED) {
734 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
735 major = GSS_S_FAILURE;
739 GSSEAP_ASSERT(GSS_ERROR(major));
745 * Decompose attribute name into prefix and suffix
748 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
755 for (i = 0; i < attribute->length; i++) {
756 if (((char *)attribute->value)[i] == ' ') {
757 p = (char *)attribute->value + i + 1;
762 prefix->value = attribute->value;
765 if (p != NULL && *p != '\0') {
766 suffix->length = attribute->length - 1 - prefix->length;
770 suffix->value = NULL;
775 * Decompose attribute name into type and suffix
778 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
780 gss_buffer_t suffix) const
782 gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER;
784 decomposeAttributeName(attribute, &prefix, suffix);
785 *type = attributePrefixToType(&prefix);
789 * Compose attribute name from prefix, suffix; returns C++ string
792 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
793 const gss_buffer_t suffix)
797 if (prefix == GSS_C_NO_BUFFER || prefix->length == 0)
800 str.append((const char *)prefix->value, prefix->length);
802 if (suffix != GSS_C_NO_BUFFER) {
804 str.append((const char *)suffix->value, suffix->length);
811 * Compose attribute name from type, suffix; returns C++ string
814 gss_eap_attr_ctx::composeAttributeName(unsigned int type,
815 const gss_buffer_t suffix)
817 gss_buffer_desc prefix = attributeTypeToPrefix(type);
819 return composeAttributeName(&prefix, suffix);
823 * Compose attribute name from prefix, suffix; returns GSS buffer
826 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
827 const gss_buffer_t suffix,
828 gss_buffer_t attribute)
830 std::string str = composeAttributeName(prefix, suffix);
832 if (str.length() != 0) {
833 return duplicateBuffer(str, attribute);
835 attribute->length = 0;
836 attribute->value = NULL;
841 * Compose attribute name from type, suffix; returns GSS buffer
844 gss_eap_attr_ctx::composeAttributeName(unsigned int type,
845 const gss_buffer_t suffix,
846 gss_buffer_t attribute) const
848 gss_buffer_desc prefix = attributeTypeToPrefix(type);
850 return composeAttributeName(&prefix, suffix, attribute);
857 gssEapInquireName(OM_uint32 *minor,
861 gss_buffer_set_t *attrs)
865 if (name_is_MN != NULL)
866 *name_is_MN = (name->mechanismUsed != GSS_C_NULL_OID);
868 if (MN_mech != NULL) {
869 major = gssEapCanonicalizeOid(minor, name->mechanismUsed,
870 OID_FLAG_NULL_VALID, MN_mech);
871 if (GSS_ERROR(major))
875 if (name->attrCtx == NULL) {
876 *minor = GSSEAP_NO_ATTR_CONTEXT;
877 return GSS_S_UNAVAILABLE;
880 if (GSS_ERROR(gssEapAttrProvidersInit(minor))) {
881 return GSS_S_UNAVAILABLE;
885 if (!name->attrCtx->getAttributeTypes(attrs)) {
886 *minor = GSSEAP_NO_ATTR_CONTEXT;
887 return GSS_S_UNAVAILABLE;
889 } catch (std::exception &e) {
890 return name->attrCtx->mapException(minor, e);
893 return GSS_S_COMPLETE;
897 gssEapGetNameAttribute(OM_uint32 *minor,
903 gss_buffer_t display_value,
906 if (authenticated != NULL)
908 if (complete != NULL)
916 if (display_value != NULL) {
917 display_value->length = 0;
918 display_value->value = NULL;
921 if (name->attrCtx == NULL) {
922 *minor = GSSEAP_NO_ATTR_CONTEXT;
923 return GSS_S_UNAVAILABLE;
926 if (GSS_ERROR(gssEapAttrProvidersInit(minor))) {
927 return GSS_S_UNAVAILABLE;
931 if (!name->attrCtx->getAttribute(attr, authenticated, complete,
932 value, display_value, more)) {
933 *minor = GSSEAP_NO_SUCH_ATTR;
934 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
935 (int)attr->length, (char *)attr->value);
936 return GSS_S_UNAVAILABLE;
938 } catch (std::exception &e) {
939 return name->attrCtx->mapException(minor, e);
942 return GSS_S_COMPLETE;
946 gssEapDeleteNameAttribute(OM_uint32 *minor,
950 if (name->attrCtx == NULL) {
951 *minor = GSSEAP_NO_ATTR_CONTEXT;
952 return GSS_S_UNAVAILABLE;
955 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
956 return GSS_S_UNAVAILABLE;
959 if (!name->attrCtx->deleteAttribute(attr)) {
960 *minor = GSSEAP_NO_SUCH_ATTR;
961 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
962 (int)attr->length, (char *)attr->value);
963 return GSS_S_UNAVAILABLE;
965 } catch (std::exception &e) {
966 return name->attrCtx->mapException(minor, e);
969 return GSS_S_COMPLETE;
973 gssEapSetNameAttribute(OM_uint32 *minor,
979 if (name->attrCtx == NULL) {
980 *minor = GSSEAP_NO_ATTR_CONTEXT;
981 return GSS_S_UNAVAILABLE;
984 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
985 return GSS_S_UNAVAILABLE;
988 if (!name->attrCtx->setAttribute(complete, attr, value)) {
989 *minor = GSSEAP_NO_SUCH_ATTR;
990 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
991 (int)attr->length, (char *)attr->value);
992 return GSS_S_UNAVAILABLE;
994 } catch (std::exception &e) {
995 return name->attrCtx->mapException(minor, e);
998 return GSS_S_COMPLETE;
1002 gssEapExportAttrContext(OM_uint32 *minor,
1003 gss_const_name_t name,
1004 gss_buffer_t buffer)
1006 if (name->attrCtx == NULL) {
1008 buffer->value = NULL;
1010 return GSS_S_COMPLETE;
1013 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1014 return GSS_S_UNAVAILABLE;
1017 name->attrCtx->exportToBuffer(buffer);
1018 } catch (std::exception &e) {
1019 return name->attrCtx->mapException(minor, e);
1022 return GSS_S_COMPLETE;
1026 gssEapImportAttrContext(OM_uint32 *minor,
1027 gss_buffer_t buffer,
1030 gss_eap_attr_ctx *ctx = NULL;
1031 OM_uint32 major = GSS_S_FAILURE;
1033 GSSEAP_ASSERT(name->attrCtx == NULL);
1035 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1036 return GSS_S_UNAVAILABLE;
1038 if (buffer->length == 0)
1039 return GSS_S_COMPLETE;
1042 ctx = new gss_eap_attr_ctx();
1044 if (ctx->initWithBuffer(buffer)) {
1045 name->attrCtx = ctx;
1046 major = GSS_S_COMPLETE;
1049 major = GSS_S_BAD_NAME;
1050 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1052 } catch (std::exception &e) {
1054 major = ctx->mapException(minor, e);
1057 GSSEAP_ASSERT(major == GSS_S_COMPLETE || name->attrCtx == NULL);
1059 if (GSS_ERROR(major))
1066 gssEapDuplicateAttrContext(OM_uint32 *minor,
1067 gss_const_name_t in,
1070 gss_eap_attr_ctx *ctx = NULL;
1071 OM_uint32 major = GSS_S_FAILURE;
1073 GSSEAP_ASSERT(out->attrCtx == NULL);
1075 if (in->attrCtx == NULL) {
1077 return GSS_S_COMPLETE;
1080 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1081 return GSS_S_UNAVAILABLE;
1084 ctx = new gss_eap_attr_ctx();
1086 if (ctx->initWithExistingContext(in->attrCtx)) {
1088 major = GSS_S_COMPLETE;
1091 major = GSS_S_FAILURE;
1092 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1094 } catch (std::exception &e) {
1095 major = in->attrCtx->mapException(minor, e);
1098 GSSEAP_ASSERT(major == GSS_S_COMPLETE || out->attrCtx == NULL);
1100 if (GSS_ERROR(major))
1103 return GSS_S_COMPLETE;
1107 gssEapMapNameToAny(OM_uint32 *minor,
1110 gss_buffer_t type_id,
1113 if (name->attrCtx == NULL) {
1114 *minor = GSSEAP_NO_ATTR_CONTEXT;
1115 return GSS_S_UNAVAILABLE;
1118 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1119 return GSS_S_UNAVAILABLE;
1122 *output = name->attrCtx->mapToAny(authenticated, type_id);
1123 } catch (std::exception &e) {
1124 return name->attrCtx->mapException(minor, e);
1127 return GSS_S_COMPLETE;
1131 gssEapReleaseAnyNameMapping(OM_uint32 *minor,
1133 gss_buffer_t type_id,
1136 if (name->attrCtx == NULL) {
1137 *minor = GSSEAP_NO_ATTR_CONTEXT;
1138 return GSS_S_UNAVAILABLE;
1141 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1142 return GSS_S_UNAVAILABLE;
1146 name->attrCtx->releaseAnyNameMapping(type_id, *input);
1148 } catch (std::exception &e) {
1149 return name->attrCtx->mapException(minor, e);
1152 return GSS_S_COMPLETE;
1156 gssEapReleaseAttrContext(OM_uint32 *minor,
1159 if (name->attrCtx != NULL)
1160 delete name->attrCtx;
1163 return GSS_S_COMPLETE;
1167 * Public accessor for initialisng a context from a GSS context. Also
1168 * sets expiry time on GSS context as a side-effect.
1171 gssEapCreateAttrContext(OM_uint32 *minor,
1172 gss_cred_id_t gssCred,
1173 gss_ctx_id_t gssCtx,
1174 struct gss_eap_attr_ctx **pAttrContext,
1175 time_t *pExpiryTime)
1177 gss_eap_attr_ctx *ctx = NULL;
1180 GSSEAP_ASSERT(gssCtx != GSS_C_NO_CONTEXT);
1182 *pAttrContext = NULL;
1184 major = gssEapAttrProvidersInit(minor);
1185 if (GSS_ERROR(major))
1189 /* Set *pAttrContext here to for reentrancy */
1190 *pAttrContext = ctx = new gss_eap_attr_ctx();
1192 if (ctx->initWithGssContext(gssCred, gssCtx)) {
1193 *pExpiryTime = ctx->getExpiryTime();
1194 major = GSS_S_COMPLETE;
1197 major = GSS_S_FAILURE;
1198 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1200 } catch (std::exception &e) {
1202 major = ctx->mapException(minor, e);
1205 if (GSS_ERROR(major)) {
1207 *pAttrContext = NULL;