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;
50 gssEapAttrProvidersInitInternal(void)
52 OM_uint32 major, minor;
54 assert(gssEapAttrProvidersInitStatus == GSS_S_UNAVAILABLE);
56 major = gssEapRadiusAttrProviderInit(&minor);
61 major = gssEapSamlAttrProvidersInit(&minor);
66 #ifdef HAVE_SHIBRESOLVER
67 /* Allow Shibboleth initialization failure to be non-fatal */
68 gssEapLocalAttrProviderInit(&minor);
73 assert(major == GSS_S_COMPLETE);
76 gssEapAttrProvidersInitStatus = major;
80 gssEapAttrProvidersInit(OM_uint32 *minor)
82 GSSEAP_ONCE(&gssEapAttrProvidersInitOnce, gssEapAttrProvidersInitInternal);
84 if (GSS_ERROR(gssEapAttrProvidersInitStatus))
85 *minor = GSSEAP_NO_ATTR_PROVIDERS;
87 return gssEapAttrProvidersInitStatus;
91 gssEapAttrProvidersFinalize(OM_uint32 *minor)
93 if (gssEapAttrProvidersInitStatus == GSS_S_COMPLETE) {
94 #ifdef HAVE_SHIBRESOLVER
95 gssEapLocalAttrProviderFinalize(minor);
98 gssEapSamlAttrProvidersFinalize(minor);
100 gssEapRadiusAttrProviderFinalize(minor);
102 gssEapAttrProvidersInitStatus = GSS_S_UNAVAILABLE;
105 return GSS_S_COMPLETE;
108 static gss_eap_attr_create_provider gssEapAttrFactories[ATTR_TYPE_MAX + 1];
111 * Register a provider for a particular type and prefix
114 gss_eap_attr_ctx::registerProvider(unsigned int type,
115 gss_eap_attr_create_provider factory)
117 assert(type <= ATTR_TYPE_MAX);
119 assert(gssEapAttrFactories[type] == NULL);
121 gssEapAttrFactories[type] = factory;
125 * Unregister a provider
128 gss_eap_attr_ctx::unregisterProvider(unsigned int type)
130 assert(type <= ATTR_TYPE_MAX);
132 gssEapAttrFactories[type] = NULL;
136 * Create an attribute context, that manages instances of providers
138 gss_eap_attr_ctx::gss_eap_attr_ctx(void)
142 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
143 gss_eap_attr_provider *provider;
145 if (gssEapAttrFactories[i] != NULL) {
146 provider = (gssEapAttrFactories[i])();
151 m_providers[i] = provider;
156 * Convert an attribute prefix to a type
159 gss_eap_attr_ctx::attributePrefixToType(const gss_buffer_t prefix) const
163 for (i = ATTR_TYPE_MIN; i < ATTR_TYPE_MAX; i++) {
166 if (!providerEnabled(i))
169 pprefix = m_providers[i]->prefix();
173 if (strlen(pprefix) == prefix->length &&
174 memcmp(pprefix, prefix->value, prefix->length) == 0)
178 return ATTR_TYPE_LOCAL;
182 * Convert a type to an attribute prefix
185 gss_eap_attr_ctx::attributeTypeToPrefix(unsigned int type) const
187 gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER;
189 if (type < ATTR_TYPE_MIN || type >= ATTR_TYPE_MAX)
192 if (!providerEnabled(type))
195 prefix.value = (void *)m_providers[type]->prefix();
196 if (prefix.value != NULL)
197 prefix.length = strlen((char *)prefix.value);
203 gss_eap_attr_ctx::providerEnabled(unsigned int type) const
205 if (type == ATTR_TYPE_LOCAL &&
206 (m_flags & ATTR_FLAG_DISABLE_LOCAL))
209 if (m_providers[type] == NULL)
216 gss_eap_attr_ctx::releaseProvider(unsigned int type)
218 delete m_providers[type];
219 m_providers[type] = NULL;
223 * Initialize a context from an existing context.
226 gss_eap_attr_ctx::initWithExistingContext(const gss_eap_attr_ctx *manager)
230 m_flags = manager->m_flags;
232 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
233 gss_eap_attr_provider *provider;
235 if (!providerEnabled(i)) {
240 provider = m_providers[i];
242 ret = provider->initWithExistingContext(this,
243 manager->m_providers[i]);
254 * Initialize a context from a GSS credential and context.
257 gss_eap_attr_ctx::initWithGssContext(const gss_cred_id_t cred,
258 const gss_ctx_id_t ctx)
262 if (cred != GSS_C_NO_CREDENTIAL &&
263 (cred->flags & GSS_EAP_DISABLE_LOCAL_ATTRS_FLAG)) {
264 m_flags |= ATTR_FLAG_DISABLE_LOCAL;
267 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
268 gss_eap_attr_provider *provider;
270 if (!providerEnabled(i)) {
275 provider = m_providers[i];
277 ret = provider->initWithGssContext(this, cred, ctx);
288 gss_eap_attr_ctx::initWithJsonObject(JSONObject &obj)
291 bool foundSource[ATTR_TYPE_MAX + 1];
294 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++)
295 foundSource[type] = false;
297 if (obj["version"].integer() != 1)
300 m_flags = obj["flags"].integer();
302 JSONObject sources = obj["sources"];
304 /* Initialize providers from serialized state */
305 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
306 gss_eap_attr_provider *provider;
309 if (!providerEnabled(type)) {
310 releaseProvider(type);
314 provider = m_providers[type];
315 key = provider->name();
319 JSONObject source = sources.get(key);
320 if (!source.isNull() &&
321 !provider->initWithJsonObject(this, source)) {
322 releaseProvider(type);
326 foundSource[type] = true;
329 /* Initialize remaining providers from initialized providers */
330 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
331 gss_eap_attr_provider *provider;
333 if (foundSource[type] || !providerEnabled(type))
336 provider = m_providers[type];
338 ret = provider->initWithGssContext(this,
342 releaseProvider(type);
351 gss_eap_attr_ctx::jsonRepresentation(void) const
353 JSONObject obj, sources;
356 obj.set("version", 1);
357 obj.set("flags", m_flags);
359 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
360 gss_eap_attr_provider *provider;
363 provider = m_providers[i];
364 if (provider == NULL)
365 continue; /* provider not initialised */
367 key = provider->name();
369 continue; /* provider does not have state */
371 JSONObject source = provider->jsonRepresentation();
372 sources.set(key, source);
375 obj.set("sources", sources);
381 * Initialize a context from an exported context or name token
384 gss_eap_attr_ctx::initWithBuffer(const gss_buffer_t buffer)
386 OM_uint32 major, minor;
391 major = bufferToString(&minor, buffer, &s);
392 if (GSS_ERROR(major))
395 JSONObject obj = JSONObject::load(s, 0, &error);
397 ret = initWithJsonObject(obj);
406 gss_eap_attr_ctx::~gss_eap_attr_ctx(void)
408 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++)
409 delete m_providers[i];
413 * Locate provider for a given type
415 gss_eap_attr_provider *
416 gss_eap_attr_ctx::getProvider(unsigned int type) const
418 assert(type >= ATTR_TYPE_MIN && type <= ATTR_TYPE_MAX);
419 return m_providers[type];
423 * Get primary provider. Only the primary provider is serialised when
424 * gss_export_sec_context() or gss_export_name_composite() is called.
426 gss_eap_attr_provider *
427 gss_eap_attr_ctx::getPrimaryProvider(void) const
429 return m_providers[ATTR_TYPE_MIN];
436 gss_eap_attr_ctx::setAttribute(int complete,
437 const gss_buffer_t attr,
438 const gss_buffer_t value)
440 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
442 gss_eap_attr_provider *provider;
445 decomposeAttributeName(attr, &type, &suffix);
447 provider = m_providers[type];
448 if (provider != NULL) {
449 ret = provider->setAttribute(complete,
450 (type == ATTR_TYPE_LOCAL) ? attr : &suffix,
458 * Delete an attrbiute
461 gss_eap_attr_ctx::deleteAttribute(const gss_buffer_t attr)
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->deleteAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix);
479 * Enumerate attribute types with callback
482 gss_eap_attr_ctx::getAttributeTypes(gss_eap_attr_enumeration_cb cb, void *data) const
487 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
488 gss_eap_attr_provider *provider = m_providers[i];
490 if (provider == NULL)
493 ret = provider->getAttributeTypes(cb, data);
501 struct eap_gss_get_attr_types_args {
503 gss_buffer_set_t attrs;
507 addAttribute(const gss_eap_attr_ctx *manager,
508 const gss_eap_attr_provider *provider GSSEAP_UNUSED,
509 const gss_buffer_t attribute,
512 eap_gss_get_attr_types_args *args = (eap_gss_get_attr_types_args *)data;
513 gss_buffer_desc qualified;
514 OM_uint32 major, minor;
516 if (args->type != ATTR_TYPE_LOCAL) {
517 manager->composeAttributeName(args->type, attribute, &qualified);
518 major = gss_add_buffer_set_member(&minor, &qualified, &args->attrs);
519 gss_release_buffer(&minor, &qualified);
521 major = gss_add_buffer_set_member(&minor, attribute, &args->attrs);
524 return GSS_ERROR(major) == false;
528 * Enumerate attribute types, output is buffer set
531 gss_eap_attr_ctx::getAttributeTypes(gss_buffer_set_t *attrs)
533 eap_gss_get_attr_types_args args;
534 OM_uint32 major, minor;
538 major = gss_create_empty_buffer_set(&minor, attrs);
539 if (GSS_ERROR(major))
540 throw std::bad_alloc();
544 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
545 gss_eap_attr_provider *provider = m_providers[i];
549 if (provider == NULL)
552 ret = provider->getAttributeTypes(addAttribute, (void *)&args);
558 gss_release_buffer_set(&minor, attrs);
564 * Get attribute with given name
567 gss_eap_attr_ctx::getAttribute(const gss_buffer_t attr,
571 gss_buffer_t display_value,
574 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
576 gss_eap_attr_provider *provider;
579 decomposeAttributeName(attr, &type, &suffix);
581 provider = m_providers[type];
582 if (provider == NULL)
585 ret = provider->getAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix,
586 authenticated, complete,
587 value, display_value, more);
593 * Map attribute context to C++ object
596 gss_eap_attr_ctx::mapToAny(int authenticated,
597 gss_buffer_t type_id) const
600 gss_eap_attr_provider *provider;
601 gss_buffer_desc suffix;
603 decomposeAttributeName(type_id, &type, &suffix);
605 provider = m_providers[type];
606 if (provider == NULL)
607 return (gss_any_t)NULL;
609 return provider->mapToAny(authenticated, &suffix);
613 * Release mapped context
616 gss_eap_attr_ctx::releaseAnyNameMapping(gss_buffer_t type_id,
617 gss_any_t input) const
620 gss_eap_attr_provider *provider;
621 gss_buffer_desc suffix;
623 decomposeAttributeName(type_id, &type, &suffix);
625 provider = m_providers[type];
626 if (provider != NULL)
627 provider->releaseAnyNameMapping(&suffix, input);
631 * Export attribute context to buffer
634 gss_eap_attr_ctx::exportToBuffer(gss_buffer_t buffer) const
639 JSONObject obj = jsonRepresentation();
645 s = obj.dump(JSON_COMPACT);
647 if (GSS_ERROR(makeStringBuffer(&minor, s, buffer)))
648 throw std::bad_alloc();
652 * Return soonest expiry time of providers
655 gss_eap_attr_ctx::getExpiryTime(void) const
658 time_t expiryTime = 0;
660 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
661 gss_eap_attr_provider *provider = m_providers[i];
662 time_t providerExpiryTime;
664 if (provider == NULL)
667 providerExpiryTime = provider->getExpiryTime();
668 if (providerExpiryTime == 0)
671 if (expiryTime == 0 || providerExpiryTime < expiryTime)
672 expiryTime = providerExpiryTime;
679 gss_eap_attr_ctx::mapException(OM_uint32 *minor, std::exception &e) const
684 /* Errors we handle ourselves */
685 if (typeid(e) == typeid(std::bad_alloc)) {
686 major = GSS_S_FAILURE;
689 } else if (typeid(e) == typeid(JSONException)) {
690 major = GSS_S_BAD_NAME;
691 *minor = GSSEAP_BAD_ATTR_TOKEN;
692 gssEapSaveStatusInfo(*minor, "%s", e.what());
696 /* Errors we delegate to providers */
697 major = GSS_S_CONTINUE_NEEDED;
699 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
700 gss_eap_attr_provider *provider = m_providers[i];
702 if (provider == NULL)
705 major = provider->mapException(minor, e);
706 if (major != GSS_S_CONTINUE_NEEDED)
710 if (major == GSS_S_CONTINUE_NEEDED) {
711 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
712 major = GSS_S_FAILURE;
716 assert(GSS_ERROR(major));
722 * Decompose attribute name into prefix and suffix
725 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
732 for (i = 0; i < attribute->length; i++) {
733 if (((char *)attribute->value)[i] == ' ') {
734 p = (char *)attribute->value + i + 1;
739 prefix->value = attribute->value;
742 if (p != NULL && *p != '\0') {
743 suffix->length = attribute->length - 1 - prefix->length;
747 suffix->value = NULL;
752 * Decompose attribute name into type and suffix
755 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
757 gss_buffer_t suffix) const
759 gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER;
761 decomposeAttributeName(attribute, &prefix, suffix);
762 *type = attributePrefixToType(&prefix);
766 * Compose attribute name from prefix, suffix; returns C++ string
769 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
770 const gss_buffer_t suffix)
774 if (prefix == GSS_C_NO_BUFFER || prefix->length == 0)
777 str.append((const char *)prefix->value, prefix->length);
779 if (suffix != GSS_C_NO_BUFFER) {
781 str.append((const char *)suffix->value, suffix->length);
788 * Compose attribute name from type, suffix; returns C++ string
791 gss_eap_attr_ctx::composeAttributeName(unsigned int type,
792 const gss_buffer_t suffix)
794 gss_buffer_desc prefix = attributeTypeToPrefix(type);
796 return composeAttributeName(&prefix, suffix);
800 * Compose attribute name from prefix, suffix; returns GSS buffer
803 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
804 const gss_buffer_t suffix,
805 gss_buffer_t attribute)
807 std::string str = composeAttributeName(prefix, suffix);
809 if (str.length() != 0) {
810 return duplicateBuffer(str, attribute);
812 attribute->length = 0;
813 attribute->value = NULL;
818 * Compose attribute name from type, suffix; returns GSS buffer
821 gss_eap_attr_ctx::composeAttributeName(unsigned int type,
822 const gss_buffer_t suffix,
823 gss_buffer_t attribute) const
825 gss_buffer_desc prefix = attributeTypeToPrefix(type);
827 return composeAttributeName(&prefix, suffix, attribute);
834 gssEapInquireName(OM_uint32 *minor,
838 gss_buffer_set_t *attrs)
842 if (name_is_MN != NULL)
843 *name_is_MN = (name->mechanismUsed != GSS_C_NULL_OID);
845 if (MN_mech != NULL) {
846 major = gssEapCanonicalizeOid(minor, name->mechanismUsed,
847 OID_FLAG_NULL_VALID, MN_mech);
848 if (GSS_ERROR(major))
852 if (name->attrCtx == NULL) {
853 *minor = GSSEAP_NO_ATTR_CONTEXT;
854 return GSS_S_UNAVAILABLE;
857 if (GSS_ERROR(gssEapAttrProvidersInit(minor))) {
858 return GSS_S_UNAVAILABLE;
862 if (!name->attrCtx->getAttributeTypes(attrs)) {
863 *minor = GSSEAP_NO_ATTR_CONTEXT;
864 return GSS_S_UNAVAILABLE;
866 } catch (std::exception &e) {
867 return name->attrCtx->mapException(minor, e);
870 return GSS_S_COMPLETE;
874 gssEapGetNameAttribute(OM_uint32 *minor,
880 gss_buffer_t display_value,
883 if (authenticated != NULL)
885 if (complete != NULL)
893 if (display_value != NULL) {
894 display_value->length = 0;
895 display_value->value = NULL;
898 if (name->attrCtx == NULL) {
899 *minor = GSSEAP_NO_ATTR_CONTEXT;
900 return GSS_S_UNAVAILABLE;
903 if (GSS_ERROR(gssEapAttrProvidersInit(minor))) {
904 return GSS_S_UNAVAILABLE;
908 if (!name->attrCtx->getAttribute(attr, authenticated, complete,
909 value, display_value, more)) {
910 *minor = GSSEAP_NO_SUCH_ATTR;
911 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
912 (int)attr->length, (char *)attr->value);
913 return GSS_S_UNAVAILABLE;
915 } catch (std::exception &e) {
916 return name->attrCtx->mapException(minor, e);
919 return GSS_S_COMPLETE;
923 gssEapDeleteNameAttribute(OM_uint32 *minor,
927 if (name->attrCtx == NULL) {
928 *minor = GSSEAP_NO_ATTR_CONTEXT;
929 return GSS_S_UNAVAILABLE;
932 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
933 return GSS_S_UNAVAILABLE;
936 if (!name->attrCtx->deleteAttribute(attr)) {
937 *minor = GSSEAP_NO_SUCH_ATTR;
938 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
939 (int)attr->length, (char *)attr->value);
940 return GSS_S_UNAVAILABLE;
942 } catch (std::exception &e) {
943 return name->attrCtx->mapException(minor, e);
946 return GSS_S_COMPLETE;
950 gssEapSetNameAttribute(OM_uint32 *minor,
956 if (name->attrCtx == NULL) {
957 *minor = GSSEAP_NO_ATTR_CONTEXT;
958 return GSS_S_UNAVAILABLE;
961 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
962 return GSS_S_UNAVAILABLE;
965 if (!name->attrCtx->setAttribute(complete, attr, value)) {
966 *minor = GSSEAP_NO_SUCH_ATTR;
967 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
968 (int)attr->length, (char *)attr->value);
969 return GSS_S_UNAVAILABLE;
971 } catch (std::exception &e) {
972 return name->attrCtx->mapException(minor, e);
975 return GSS_S_COMPLETE;
979 gssEapExportAttrContext(OM_uint32 *minor,
983 if (name->attrCtx == NULL) {
985 buffer->value = NULL;
987 return GSS_S_COMPLETE;
990 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
991 return GSS_S_UNAVAILABLE;
994 name->attrCtx->exportToBuffer(buffer);
995 } catch (std::exception &e) {
996 return name->attrCtx->mapException(minor, e);
999 return GSS_S_COMPLETE;
1003 gssEapImportAttrContext(OM_uint32 *minor,
1004 gss_buffer_t buffer,
1007 gss_eap_attr_ctx *ctx = NULL;
1008 OM_uint32 major = GSS_S_FAILURE;
1010 assert(name->attrCtx == NULL);
1012 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1013 return GSS_S_UNAVAILABLE;
1015 if (buffer->length == 0)
1016 return GSS_S_COMPLETE;
1019 ctx = new gss_eap_attr_ctx();
1021 if (ctx->initWithBuffer(buffer)) {
1022 name->attrCtx = ctx;
1023 major = GSS_S_COMPLETE;
1026 major = GSS_S_BAD_NAME;
1027 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1029 } catch (std::exception &e) {
1031 major = ctx->mapException(minor, e);
1034 assert(major == GSS_S_COMPLETE || name->attrCtx == NULL);
1036 if (GSS_ERROR(major))
1043 gssEapDuplicateAttrContext(OM_uint32 *minor,
1047 gss_eap_attr_ctx *ctx = NULL;
1048 OM_uint32 major = GSS_S_FAILURE;
1050 assert(out->attrCtx == NULL);
1052 if (in->attrCtx == NULL) {
1054 return GSS_S_COMPLETE;
1057 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1058 return GSS_S_UNAVAILABLE;
1061 ctx = new gss_eap_attr_ctx();
1063 if (ctx->initWithExistingContext(in->attrCtx)) {
1065 major = GSS_S_COMPLETE;
1068 major = GSS_S_FAILURE;
1069 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1071 } catch (std::exception &e) {
1072 major = in->attrCtx->mapException(minor, e);
1075 assert(major == GSS_S_COMPLETE || out->attrCtx == NULL);
1077 if (GSS_ERROR(major))
1080 return GSS_S_COMPLETE;
1084 gssEapMapNameToAny(OM_uint32 *minor,
1087 gss_buffer_t type_id,
1090 if (name->attrCtx == NULL) {
1091 *minor = GSSEAP_NO_ATTR_CONTEXT;
1092 return GSS_S_UNAVAILABLE;
1095 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1096 return GSS_S_UNAVAILABLE;
1099 *output = name->attrCtx->mapToAny(authenticated, type_id);
1100 } catch (std::exception &e) {
1101 return name->attrCtx->mapException(minor, e);
1104 return GSS_S_COMPLETE;
1108 gssEapReleaseAnyNameMapping(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;
1123 name->attrCtx->releaseAnyNameMapping(type_id, *input);
1125 } catch (std::exception &e) {
1126 return name->attrCtx->mapException(minor, e);
1129 return GSS_S_COMPLETE;
1133 gssEapReleaseAttrContext(OM_uint32 *minor,
1136 if (name->attrCtx != NULL)
1137 delete name->attrCtx;
1140 return GSS_S_COMPLETE;
1144 * Public accessor for initialisng a context from a GSS context. Also
1145 * sets expiry time on GSS context as a side-effect.
1148 gssEapCreateAttrContext(OM_uint32 *minor,
1149 gss_cred_id_t gssCred,
1150 gss_ctx_id_t gssCtx,
1151 struct gss_eap_attr_ctx **pAttrContext,
1152 time_t *pExpiryTime)
1154 gss_eap_attr_ctx *ctx = NULL;
1157 assert(gssCtx != GSS_C_NO_CONTEXT);
1159 *pAttrContext = NULL;
1161 major = gssEapAttrProvidersInit(minor);
1162 if (GSS_ERROR(major))
1166 /* Set *pAttrContext here to for reentrancy */
1167 *pAttrContext = ctx = new gss_eap_attr_ctx();
1169 if (ctx->initWithGssContext(gssCred, gssCtx)) {
1170 *pExpiryTime = ctx->getExpiryTime();
1171 major = GSS_S_COMPLETE;
1174 major = GSS_S_FAILURE;
1175 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1177 } catch (std::exception &e) {
1179 major = ctx->mapException(minor, e);
1182 if (GSS_ERROR(major)) {
1184 *pAttrContext = NULL;