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 major = gssEapSamlAttrProvidersInit(&minor);
74 GSSEAP_ASSERT(major == GSS_S_COMPLETE);
77 gssEapAttrProvidersInitStatus = major;
83 gssEapAttrProvidersInit(OM_uint32 *minor)
85 GSSEAP_ONCE(&gssEapAttrProvidersInitOnce, gssEapAttrProvidersInitInternal);
87 if (GSS_ERROR(gssEapAttrProvidersInitStatus))
88 *minor = GSSEAP_NO_ATTR_PROVIDERS;
90 return gssEapAttrProvidersInitStatus;
94 class finalize_class {
99 if (gssEapAttrProvidersInitStatus == GSS_S_COMPLETE) {
100 #ifdef HAVE_SHIBRESOLVER
101 gssEapLocalAttrProviderFinalize(&minor);
104 gssEapSamlAttrProvidersFinalize(&minor);
106 gssEapRadiusAttrProviderFinalize(&minor);
108 gssEapAttrProvidersInitStatus = GSS_S_UNAVAILABLE;
116 static gss_eap_attr_create_provider gssEapAttrFactories[ATTR_TYPE_MAX + 1];
119 * Register a provider for a particular type and prefix
122 gss_eap_attr_ctx::registerProvider(unsigned int type,
123 gss_eap_attr_create_provider factory)
125 GSSEAP_ASSERT(type <= ATTR_TYPE_MAX);
127 GSSEAP_ASSERT(gssEapAttrFactories[type] == NULL);
129 gssEapAttrFactories[type] = factory;
133 * Unregister a provider
136 gss_eap_attr_ctx::unregisterProvider(unsigned int type)
138 GSSEAP_ASSERT(type <= ATTR_TYPE_MAX);
140 gssEapAttrFactories[type] = NULL;
144 * Create an attribute context, that manages instances of providers
146 gss_eap_attr_ctx::gss_eap_attr_ctx(void)
150 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
151 gss_eap_attr_provider *provider;
153 if (gssEapAttrFactories[i] != NULL) {
154 provider = (gssEapAttrFactories[i])();
159 m_providers[i] = provider;
164 * Convert an attribute prefix to a type
167 gss_eap_attr_ctx::attributePrefixToType(const gss_buffer_t prefix) const
171 for (i = ATTR_TYPE_MIN; i < ATTR_TYPE_MAX; i++) {
174 if (!providerEnabled(i))
177 pprefix = m_providers[i]->prefix();
181 if (strlen(pprefix) == prefix->length &&
182 memcmp(pprefix, prefix->value, prefix->length) == 0)
186 return ATTR_TYPE_LOCAL;
190 * Convert a type to an attribute prefix
193 gss_eap_attr_ctx::attributeTypeToPrefix(unsigned int type) const
195 gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER;
197 if (type < ATTR_TYPE_MIN || type >= ATTR_TYPE_MAX)
200 if (!providerEnabled(type))
203 prefix.value = (void *)m_providers[type]->prefix();
204 if (prefix.value != NULL)
205 prefix.length = strlen((char *)prefix.value);
211 gss_eap_attr_ctx::providerEnabled(unsigned int type) const
213 if (type == ATTR_TYPE_LOCAL &&
214 (m_flags & ATTR_FLAG_DISABLE_LOCAL))
217 if (m_providers[type] == NULL)
224 gss_eap_attr_ctx::releaseProvider(unsigned int type)
226 delete m_providers[type];
227 m_providers[type] = NULL;
231 * Initialize a context from an existing context.
234 gss_eap_attr_ctx::initWithExistingContext(const gss_eap_attr_ctx *manager)
238 m_flags = manager->m_flags;
240 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
241 gss_eap_attr_provider *provider;
243 if (!providerEnabled(i)) {
248 provider = m_providers[i];
250 ret = provider->initWithExistingContext(this,
251 manager->m_providers[i]);
262 * Initialize a context from a GSS credential and context.
265 gss_eap_attr_ctx::initWithGssContext(const gss_cred_id_t cred,
266 const gss_ctx_id_t ctx)
270 if (cred != GSS_C_NO_CREDENTIAL &&
271 (cred->flags & GSS_EAP_DISABLE_LOCAL_ATTRS_FLAG)) {
272 m_flags |= ATTR_FLAG_DISABLE_LOCAL;
275 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
276 gss_eap_attr_provider *provider;
278 if (!providerEnabled(i)) {
283 provider = m_providers[i];
285 ret = provider->initWithGssContext(this, cred, ctx);
296 gss_eap_attr_ctx::initWithJsonObject(JSONObject &obj)
299 bool foundSource[ATTR_TYPE_MAX + 1];
302 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++)
303 foundSource[type] = false;
305 if (obj["version"].integer() != 1)
308 m_flags = obj["flags"].integer();
310 JSONObject sources = obj["sources"];
312 /* Initialize providers from serialized state */
313 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
314 gss_eap_attr_provider *provider;
317 if (!providerEnabled(type)) {
318 releaseProvider(type);
322 provider = m_providers[type];
323 key = provider->name();
327 JSONObject source = sources.get(key);
328 if (!source.isNull() &&
329 !provider->initWithJsonObject(this, source)) {
330 releaseProvider(type);
334 foundSource[type] = true;
337 /* Initialize remaining providers from initialized providers */
338 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
339 gss_eap_attr_provider *provider;
341 if (foundSource[type] || !providerEnabled(type))
344 provider = m_providers[type];
346 ret = provider->initWithGssContext(this,
350 releaseProvider(type);
359 gss_eap_attr_ctx::jsonRepresentation(void) const
361 JSONObject obj, sources;
364 obj.set("version", 1);
365 obj.set("flags", m_flags);
367 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
368 gss_eap_attr_provider *provider;
371 provider = m_providers[i];
372 if (provider == NULL)
373 continue; /* provider not initialised */
375 key = provider->name();
377 continue; /* provider does not have state */
379 JSONObject source = provider->jsonRepresentation();
380 sources.set(key, source);
383 obj.set("sources", sources);
389 * Initialize a context from an exported context or name token
392 gss_eap_attr_ctx::initWithBuffer(const gss_buffer_t buffer)
394 OM_uint32 major, minor;
399 major = bufferToString(&minor, buffer, &s);
400 if (GSS_ERROR(major))
403 JSONObject obj = JSONObject::load(s, 0, &error);
405 ret = initWithJsonObject(obj);
414 gss_eap_attr_ctx::~gss_eap_attr_ctx(void)
416 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++)
417 delete m_providers[i];
421 * Locate provider for a given type
423 gss_eap_attr_provider *
424 gss_eap_attr_ctx::getProvider(unsigned int type) const
426 GSSEAP_ASSERT(type >= ATTR_TYPE_MIN && type <= ATTR_TYPE_MAX);
427 return m_providers[type];
431 * Get primary provider. Only the primary provider is serialised when
432 * gss_export_sec_context() or gss_export_name_composite() is called.
434 gss_eap_attr_provider *
435 gss_eap_attr_ctx::getPrimaryProvider(void) const
437 return m_providers[ATTR_TYPE_MIN];
444 gss_eap_attr_ctx::setAttribute(int complete,
445 const gss_buffer_t attr,
446 const gss_buffer_t value)
448 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
450 gss_eap_attr_provider *provider;
453 decomposeAttributeName(attr, &type, &suffix);
455 provider = m_providers[type];
456 if (provider != NULL) {
457 ret = provider->setAttribute(complete,
458 (type == ATTR_TYPE_LOCAL) ? attr : &suffix,
466 * Delete an attrbiute
469 gss_eap_attr_ctx::deleteAttribute(const gss_buffer_t attr)
471 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
473 gss_eap_attr_provider *provider;
476 decomposeAttributeName(attr, &type, &suffix);
478 provider = m_providers[type];
479 if (provider != NULL) {
480 ret = provider->deleteAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix);
487 * Enumerate attribute types with callback
490 gss_eap_attr_ctx::getAttributeTypes(gss_eap_attr_enumeration_cb cb, void *data) const
495 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
496 gss_eap_attr_provider *provider = m_providers[i];
498 if (provider == NULL)
501 ret = provider->getAttributeTypes(cb, data);
509 struct eap_gss_get_attr_types_args {
511 gss_buffer_set_t attrs;
515 addAttribute(const gss_eap_attr_ctx *manager,
516 const gss_eap_attr_provider *provider GSSEAP_UNUSED,
517 const gss_buffer_t attribute,
520 eap_gss_get_attr_types_args *args = (eap_gss_get_attr_types_args *)data;
521 gss_buffer_desc qualified;
522 OM_uint32 major, minor;
524 if (args->type != ATTR_TYPE_LOCAL) {
525 manager->composeAttributeName(args->type, attribute, &qualified);
526 major = gss_add_buffer_set_member(&minor, &qualified, &args->attrs);
527 gss_release_buffer(&minor, &qualified);
529 major = gss_add_buffer_set_member(&minor, attribute, &args->attrs);
532 return GSS_ERROR(major) == false;
536 * Enumerate attribute types, output is buffer set
539 gss_eap_attr_ctx::getAttributeTypes(gss_buffer_set_t *attrs)
541 eap_gss_get_attr_types_args args;
542 OM_uint32 major, minor;
546 major = gss_create_empty_buffer_set(&minor, attrs);
547 if (GSS_ERROR(major))
548 throw std::bad_alloc();
552 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
553 gss_eap_attr_provider *provider = m_providers[i];
557 if (provider == NULL)
560 ret = provider->getAttributeTypes(addAttribute, (void *)&args);
566 gss_release_buffer_set(&minor, attrs);
572 * Get attribute with given name
575 gss_eap_attr_ctx::getAttribute(const gss_buffer_t attr,
579 gss_buffer_t display_value,
582 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
584 gss_eap_attr_provider *provider;
587 decomposeAttributeName(attr, &type, &suffix);
589 provider = m_providers[type];
590 if (provider == NULL)
593 ret = provider->getAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix,
594 authenticated, complete,
595 value, display_value, more);
601 * Map attribute context to C++ object
604 gss_eap_attr_ctx::mapToAny(int authenticated,
605 gss_buffer_t type_id) const
608 gss_eap_attr_provider *provider;
609 gss_buffer_desc suffix;
611 decomposeAttributeName(type_id, &type, &suffix);
613 provider = m_providers[type];
614 if (provider == NULL)
615 return (gss_any_t)NULL;
617 return provider->mapToAny(authenticated, &suffix);
621 * Release mapped context
624 gss_eap_attr_ctx::releaseAnyNameMapping(gss_buffer_t type_id,
625 gss_any_t input) const
628 gss_eap_attr_provider *provider;
629 gss_buffer_desc suffix;
631 decomposeAttributeName(type_id, &type, &suffix);
633 provider = m_providers[type];
634 if (provider != NULL)
635 provider->releaseAnyNameMapping(&suffix, input);
639 * Export attribute context to buffer
642 gss_eap_attr_ctx::exportToBuffer(gss_buffer_t buffer) const
647 JSONObject obj = jsonRepresentation();
653 s = obj.dump(JSON_COMPACT);
655 if (GSS_ERROR(makeStringBuffer(&minor, s, buffer)))
656 throw std::bad_alloc();
660 * Return soonest expiry time of providers
663 gss_eap_attr_ctx::getExpiryTime(void) const
666 time_t expiryTime = 0;
668 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
669 gss_eap_attr_provider *provider = m_providers[i];
670 time_t providerExpiryTime;
672 if (provider == NULL)
675 providerExpiryTime = provider->getExpiryTime();
676 if (providerExpiryTime == 0)
679 if (expiryTime == 0 || providerExpiryTime < expiryTime)
680 expiryTime = providerExpiryTime;
687 gss_eap_attr_ctx::mapException(OM_uint32 *minor, std::exception &e) const
692 /* Errors we handle ourselves */
693 if (typeid(e) == typeid(std::bad_alloc)) {
694 major = GSS_S_FAILURE;
697 } else if (typeid(e) == typeid(JSONException)) {
698 major = GSS_S_BAD_NAME;
699 *minor = GSSEAP_BAD_ATTR_TOKEN;
700 gssEapSaveStatusInfo(*minor, "%s", e.what());
704 /* Errors we delegate to providers */
705 major = GSS_S_CONTINUE_NEEDED;
707 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
708 gss_eap_attr_provider *provider = m_providers[i];
710 if (provider == NULL)
713 major = provider->mapException(minor, e);
714 if (major != GSS_S_CONTINUE_NEEDED)
718 if (major == GSS_S_CONTINUE_NEEDED) {
719 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
720 major = GSS_S_FAILURE;
724 GSSEAP_ASSERT(GSS_ERROR(major));
730 * Decompose attribute name into prefix and suffix
733 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
740 for (i = 0; i < attribute->length; i++) {
741 if (((char *)attribute->value)[i] == ' ') {
742 p = (char *)attribute->value + i + 1;
747 prefix->value = attribute->value;
750 if (p != NULL && *p != '\0') {
751 suffix->length = attribute->length - 1 - prefix->length;
755 suffix->value = NULL;
760 * Decompose attribute name into type and suffix
763 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
765 gss_buffer_t suffix) const
767 gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER;
769 decomposeAttributeName(attribute, &prefix, suffix);
770 *type = attributePrefixToType(&prefix);
774 * Compose attribute name from prefix, suffix; returns C++ string
777 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
778 const gss_buffer_t suffix)
782 if (prefix == GSS_C_NO_BUFFER || prefix->length == 0)
785 str.append((const char *)prefix->value, prefix->length);
787 if (suffix != GSS_C_NO_BUFFER) {
789 str.append((const char *)suffix->value, suffix->length);
796 * Compose attribute name from type, suffix; returns C++ string
799 gss_eap_attr_ctx::composeAttributeName(unsigned int type,
800 const gss_buffer_t suffix)
802 gss_buffer_desc prefix = attributeTypeToPrefix(type);
804 return composeAttributeName(&prefix, suffix);
808 * Compose attribute name from prefix, suffix; returns GSS buffer
811 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
812 const gss_buffer_t suffix,
813 gss_buffer_t attribute)
815 std::string str = composeAttributeName(prefix, suffix);
817 if (str.length() != 0) {
818 return duplicateBuffer(str, attribute);
820 attribute->length = 0;
821 attribute->value = NULL;
826 * Compose attribute name from type, suffix; returns GSS buffer
829 gss_eap_attr_ctx::composeAttributeName(unsigned int type,
830 const gss_buffer_t suffix,
831 gss_buffer_t attribute) const
833 gss_buffer_desc prefix = attributeTypeToPrefix(type);
835 return composeAttributeName(&prefix, suffix, attribute);
842 gssEapInquireName(OM_uint32 *minor,
846 gss_buffer_set_t *attrs)
850 if (name_is_MN != NULL)
851 *name_is_MN = (name->mechanismUsed != GSS_C_NULL_OID);
853 if (MN_mech != NULL) {
854 major = gssEapCanonicalizeOid(minor, name->mechanismUsed,
855 OID_FLAG_NULL_VALID, MN_mech);
856 if (GSS_ERROR(major))
860 if (name->attrCtx == NULL) {
861 *minor = GSSEAP_NO_ATTR_CONTEXT;
862 return GSS_S_UNAVAILABLE;
865 if (GSS_ERROR(gssEapAttrProvidersInit(minor))) {
866 return GSS_S_UNAVAILABLE;
870 if (!name->attrCtx->getAttributeTypes(attrs)) {
871 *minor = GSSEAP_NO_ATTR_CONTEXT;
872 return GSS_S_UNAVAILABLE;
874 } catch (std::exception &e) {
875 return name->attrCtx->mapException(minor, e);
878 return GSS_S_COMPLETE;
882 gssEapGetNameAttribute(OM_uint32 *minor,
888 gss_buffer_t display_value,
891 if (authenticated != NULL)
893 if (complete != NULL)
901 if (display_value != NULL) {
902 display_value->length = 0;
903 display_value->value = NULL;
906 if (name->attrCtx == NULL) {
907 *minor = GSSEAP_NO_ATTR_CONTEXT;
908 return GSS_S_UNAVAILABLE;
911 if (GSS_ERROR(gssEapAttrProvidersInit(minor))) {
912 return GSS_S_UNAVAILABLE;
916 if (!name->attrCtx->getAttribute(attr, authenticated, complete,
917 value, display_value, more)) {
918 *minor = GSSEAP_NO_SUCH_ATTR;
919 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
920 (int)attr->length, (char *)attr->value);
921 return GSS_S_UNAVAILABLE;
923 } catch (std::exception &e) {
924 return name->attrCtx->mapException(minor, e);
927 return GSS_S_COMPLETE;
931 gssEapDeleteNameAttribute(OM_uint32 *minor,
935 if (name->attrCtx == NULL) {
936 *minor = GSSEAP_NO_ATTR_CONTEXT;
937 return GSS_S_UNAVAILABLE;
940 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
941 return GSS_S_UNAVAILABLE;
944 if (!name->attrCtx->deleteAttribute(attr)) {
945 *minor = GSSEAP_NO_SUCH_ATTR;
946 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
947 (int)attr->length, (char *)attr->value);
948 return GSS_S_UNAVAILABLE;
950 } catch (std::exception &e) {
951 return name->attrCtx->mapException(minor, e);
954 return GSS_S_COMPLETE;
958 gssEapSetNameAttribute(OM_uint32 *minor,
964 if (name->attrCtx == NULL) {
965 *minor = GSSEAP_NO_ATTR_CONTEXT;
966 return GSS_S_UNAVAILABLE;
969 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
970 return GSS_S_UNAVAILABLE;
973 if (!name->attrCtx->setAttribute(complete, attr, value)) {
974 *minor = GSSEAP_NO_SUCH_ATTR;
975 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
976 (int)attr->length, (char *)attr->value);
977 return GSS_S_UNAVAILABLE;
979 } catch (std::exception &e) {
980 return name->attrCtx->mapException(minor, e);
983 return GSS_S_COMPLETE;
987 gssEapExportAttrContext(OM_uint32 *minor,
991 if (name->attrCtx == NULL) {
993 buffer->value = NULL;
995 return GSS_S_COMPLETE;
998 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
999 return GSS_S_UNAVAILABLE;
1002 name->attrCtx->exportToBuffer(buffer);
1003 } catch (std::exception &e) {
1004 return name->attrCtx->mapException(minor, e);
1007 return GSS_S_COMPLETE;
1011 gssEapImportAttrContext(OM_uint32 *minor,
1012 gss_buffer_t buffer,
1015 gss_eap_attr_ctx *ctx = NULL;
1016 OM_uint32 major = GSS_S_FAILURE;
1018 GSSEAP_ASSERT(name->attrCtx == NULL);
1020 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1021 return GSS_S_UNAVAILABLE;
1023 if (buffer->length == 0)
1024 return GSS_S_COMPLETE;
1027 ctx = new gss_eap_attr_ctx();
1029 if (ctx->initWithBuffer(buffer)) {
1030 name->attrCtx = ctx;
1031 major = GSS_S_COMPLETE;
1034 major = GSS_S_BAD_NAME;
1035 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1037 } catch (std::exception &e) {
1039 major = ctx->mapException(minor, e);
1042 GSSEAP_ASSERT(major == GSS_S_COMPLETE || name->attrCtx == NULL);
1044 if (GSS_ERROR(major))
1051 gssEapDuplicateAttrContext(OM_uint32 *minor,
1055 gss_eap_attr_ctx *ctx = NULL;
1056 OM_uint32 major = GSS_S_FAILURE;
1058 GSSEAP_ASSERT(out->attrCtx == NULL);
1060 if (in->attrCtx == NULL) {
1062 return GSS_S_COMPLETE;
1065 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1066 return GSS_S_UNAVAILABLE;
1069 ctx = new gss_eap_attr_ctx();
1071 if (ctx->initWithExistingContext(in->attrCtx)) {
1073 major = GSS_S_COMPLETE;
1076 major = GSS_S_FAILURE;
1077 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1079 } catch (std::exception &e) {
1080 major = in->attrCtx->mapException(minor, e);
1083 GSSEAP_ASSERT(major == GSS_S_COMPLETE || out->attrCtx == NULL);
1085 if (GSS_ERROR(major))
1088 return GSS_S_COMPLETE;
1092 gssEapMapNameToAny(OM_uint32 *minor,
1095 gss_buffer_t type_id,
1098 if (name->attrCtx == NULL) {
1099 *minor = GSSEAP_NO_ATTR_CONTEXT;
1100 return GSS_S_UNAVAILABLE;
1103 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1104 return GSS_S_UNAVAILABLE;
1107 *output = name->attrCtx->mapToAny(authenticated, type_id);
1108 } catch (std::exception &e) {
1109 return name->attrCtx->mapException(minor, e);
1112 return GSS_S_COMPLETE;
1116 gssEapReleaseAnyNameMapping(OM_uint32 *minor,
1118 gss_buffer_t type_id,
1121 if (name->attrCtx == NULL) {
1122 *minor = GSSEAP_NO_ATTR_CONTEXT;
1123 return GSS_S_UNAVAILABLE;
1126 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1127 return GSS_S_UNAVAILABLE;
1131 name->attrCtx->releaseAnyNameMapping(type_id, *input);
1133 } catch (std::exception &e) {
1134 return name->attrCtx->mapException(minor, e);
1137 return GSS_S_COMPLETE;
1141 gssEapReleaseAttrContext(OM_uint32 *minor,
1144 if (name->attrCtx != NULL)
1145 delete name->attrCtx;
1148 return GSS_S_COMPLETE;
1152 * Public accessor for initialisng a context from a GSS context. Also
1153 * sets expiry time on GSS context as a side-effect.
1156 gssEapCreateAttrContext(OM_uint32 *minor,
1157 gss_cred_id_t gssCred,
1158 gss_ctx_id_t gssCtx,
1159 struct gss_eap_attr_ctx **pAttrContext,
1160 time_t *pExpiryTime)
1162 gss_eap_attr_ctx *ctx = NULL;
1165 GSSEAP_ASSERT(gssCtx != GSS_C_NO_CONTEXT);
1167 *pAttrContext = NULL;
1169 major = gssEapAttrProvidersInit(minor);
1170 if (GSS_ERROR(major))
1174 /* Set *pAttrContext here to for reentrancy */
1175 *pAttrContext = ctx = new gss_eap_attr_ctx();
1177 if (ctx->initWithGssContext(gssCred, gssCtx)) {
1178 *pExpiryTime = ctx->getExpiryTime();
1179 major = GSS_S_COMPLETE;
1182 major = GSS_S_FAILURE;
1183 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1185 } catch (std::exception &e) {
1187 major = ctx->mapException(minor, e);
1190 if (GSS_ERROR(major)) {
1192 *pAttrContext = NULL;