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 major = gssEapRadiusAttrProviderInit(&minor);
60 major = gssEapSamlAttrProvidersInit(&minor);
65 #ifdef HAVE_SHIBRESOLVER
66 /* Allow Shibboleth initialization failure to be non-fatal */
67 gssEapLocalAttrProviderInit(&minor);
72 GSSEAP_ASSERT(major == GSS_S_COMPLETE);
75 gssEapAttrProvidersInitStatus = major;
81 gssEapAttrProvidersInit(OM_uint32 *minor)
83 GSSEAP_ONCE(&gssEapAttrProvidersInitOnce, gssEapAttrProvidersInitInternal);
85 if (GSS_ERROR(gssEapAttrProvidersInitStatus))
86 *minor = GSSEAP_NO_ATTR_PROVIDERS;
88 return gssEapAttrProvidersInitStatus;
92 gssEapAttrProvidersFinalize(OM_uint32 *minor)
94 if (gssEapAttrProvidersInitStatus == GSS_S_COMPLETE) {
95 #ifdef HAVE_SHIBRESOLVER
96 gssEapLocalAttrProviderFinalize(minor);
99 gssEapSamlAttrProvidersFinalize(minor);
101 gssEapRadiusAttrProviderFinalize(minor);
103 gssEapAttrProvidersInitStatus = GSS_S_UNAVAILABLE;
106 return GSS_S_COMPLETE;
109 static gss_eap_attr_create_provider gssEapAttrFactories[ATTR_TYPE_MAX + 1];
112 * Register a provider for a particular type and prefix
115 gss_eap_attr_ctx::registerProvider(unsigned int type,
116 gss_eap_attr_create_provider factory)
118 GSSEAP_ASSERT(type <= ATTR_TYPE_MAX);
120 GSSEAP_ASSERT(gssEapAttrFactories[type] == NULL);
122 gssEapAttrFactories[type] = factory;
126 * Unregister a provider
129 gss_eap_attr_ctx::unregisterProvider(unsigned int type)
131 GSSEAP_ASSERT(type <= ATTR_TYPE_MAX);
133 gssEapAttrFactories[type] = NULL;
137 * Create an attribute context, that manages instances of providers
139 gss_eap_attr_ctx::gss_eap_attr_ctx(void)
143 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
144 gss_eap_attr_provider *provider;
146 if (gssEapAttrFactories[i] != NULL) {
147 provider = (gssEapAttrFactories[i])();
152 m_providers[i] = provider;
157 * Convert an attribute prefix to a type
160 gss_eap_attr_ctx::attributePrefixToType(const gss_buffer_t prefix) const
164 for (i = ATTR_TYPE_MIN; i < ATTR_TYPE_MAX; i++) {
167 if (!providerEnabled(i))
170 pprefix = m_providers[i]->prefix();
174 if (strlen(pprefix) == prefix->length &&
175 memcmp(pprefix, prefix->value, prefix->length) == 0)
179 return ATTR_TYPE_LOCAL;
183 * Convert a type to an attribute prefix
186 gss_eap_attr_ctx::attributeTypeToPrefix(unsigned int type) const
188 gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER;
190 if (type < ATTR_TYPE_MIN || type >= ATTR_TYPE_MAX)
193 if (!providerEnabled(type))
196 prefix.value = (void *)m_providers[type]->prefix();
197 if (prefix.value != NULL)
198 prefix.length = strlen((char *)prefix.value);
204 gss_eap_attr_ctx::providerEnabled(unsigned int type) const
206 if (type == ATTR_TYPE_LOCAL &&
207 (m_flags & ATTR_FLAG_DISABLE_LOCAL))
210 if (m_providers[type] == NULL)
217 gss_eap_attr_ctx::releaseProvider(unsigned int type)
219 delete m_providers[type];
220 m_providers[type] = NULL;
224 * Initialize a context from an existing context.
227 gss_eap_attr_ctx::initWithExistingContext(const gss_eap_attr_ctx *manager)
231 m_flags = manager->m_flags;
233 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
234 gss_eap_attr_provider *provider;
236 if (!providerEnabled(i)) {
241 provider = m_providers[i];
243 ret = provider->initWithExistingContext(this,
244 manager->m_providers[i]);
255 * Initialize a context from a GSS credential and context.
258 gss_eap_attr_ctx::initWithGssContext(const gss_cred_id_t cred,
259 const gss_ctx_id_t ctx)
263 if (cred != GSS_C_NO_CREDENTIAL &&
264 (cred->flags & GSS_EAP_DISABLE_LOCAL_ATTRS_FLAG)) {
265 m_flags |= ATTR_FLAG_DISABLE_LOCAL;
268 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
269 gss_eap_attr_provider *provider;
271 if (!providerEnabled(i)) {
276 provider = m_providers[i];
278 ret = provider->initWithGssContext(this, cred, ctx);
289 gss_eap_attr_ctx::initWithJsonObject(JSONObject &obj)
292 bool foundSource[ATTR_TYPE_MAX + 1];
295 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++)
296 foundSource[type] = false;
298 if (obj["version"].integer() != 1)
301 m_flags = obj["flags"].integer();
303 JSONObject sources = obj["sources"];
305 /* Initialize providers from serialized state */
306 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
307 gss_eap_attr_provider *provider;
310 if (!providerEnabled(type)) {
311 releaseProvider(type);
315 provider = m_providers[type];
316 key = provider->name();
320 JSONObject source = sources.get(key);
321 if (!source.isNull() &&
322 !provider->initWithJsonObject(this, source)) {
323 releaseProvider(type);
327 foundSource[type] = true;
330 /* Initialize remaining providers from initialized providers */
331 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
332 gss_eap_attr_provider *provider;
334 if (foundSource[type] || !providerEnabled(type))
337 provider = m_providers[type];
339 ret = provider->initWithGssContext(this,
343 releaseProvider(type);
352 gss_eap_attr_ctx::jsonRepresentation(void) const
354 JSONObject obj, sources;
357 obj.set("version", 1);
358 obj.set("flags", m_flags);
360 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
361 gss_eap_attr_provider *provider;
364 provider = m_providers[i];
365 if (provider == NULL)
366 continue; /* provider not initialised */
368 key = provider->name();
370 continue; /* provider does not have state */
372 JSONObject source = provider->jsonRepresentation();
373 sources.set(key, source);
376 obj.set("sources", sources);
382 * Initialize a context from an exported context or name token
385 gss_eap_attr_ctx::initWithBuffer(const gss_buffer_t buffer)
387 OM_uint32 major, minor;
392 major = bufferToString(&minor, buffer, &s);
393 if (GSS_ERROR(major))
396 JSONObject obj = JSONObject::load(s, 0, &error);
398 ret = initWithJsonObject(obj);
407 gss_eap_attr_ctx::~gss_eap_attr_ctx(void)
409 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++)
410 delete m_providers[i];
414 * Locate provider for a given type
416 gss_eap_attr_provider *
417 gss_eap_attr_ctx::getProvider(unsigned int type) const
419 GSSEAP_ASSERT(type >= ATTR_TYPE_MIN && type <= ATTR_TYPE_MAX);
420 return m_providers[type];
424 * Get primary provider. Only the primary provider is serialised when
425 * gss_export_sec_context() or gss_export_name_composite() is called.
427 gss_eap_attr_provider *
428 gss_eap_attr_ctx::getPrimaryProvider(void) const
430 return m_providers[ATTR_TYPE_MIN];
437 gss_eap_attr_ctx::setAttribute(int complete,
438 const gss_buffer_t attr,
439 const gss_buffer_t value)
441 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
443 gss_eap_attr_provider *provider;
446 decomposeAttributeName(attr, &type, &suffix);
448 provider = m_providers[type];
449 if (provider != NULL) {
450 ret = provider->setAttribute(complete,
451 (type == ATTR_TYPE_LOCAL) ? attr : &suffix,
459 * Delete an attrbiute
462 gss_eap_attr_ctx::deleteAttribute(const gss_buffer_t attr)
464 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
466 gss_eap_attr_provider *provider;
469 decomposeAttributeName(attr, &type, &suffix);
471 provider = m_providers[type];
472 if (provider != NULL) {
473 ret = provider->deleteAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix);
480 * Enumerate attribute types with callback
483 gss_eap_attr_ctx::getAttributeTypes(gss_eap_attr_enumeration_cb cb, void *data) const
488 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
489 gss_eap_attr_provider *provider = m_providers[i];
491 if (provider == NULL)
494 ret = provider->getAttributeTypes(cb, data);
502 struct eap_gss_get_attr_types_args {
504 gss_buffer_set_t attrs;
508 addAttribute(const gss_eap_attr_ctx *manager,
509 const gss_eap_attr_provider *provider GSSEAP_UNUSED,
510 const gss_buffer_t attribute,
513 eap_gss_get_attr_types_args *args = (eap_gss_get_attr_types_args *)data;
514 gss_buffer_desc qualified;
515 OM_uint32 major, minor;
517 if (args->type != ATTR_TYPE_LOCAL) {
518 manager->composeAttributeName(args->type, attribute, &qualified);
519 major = gss_add_buffer_set_member(&minor, &qualified, &args->attrs);
520 gss_release_buffer(&minor, &qualified);
522 major = gss_add_buffer_set_member(&minor, attribute, &args->attrs);
525 return GSS_ERROR(major) == false;
529 * Enumerate attribute types, output is buffer set
532 gss_eap_attr_ctx::getAttributeTypes(gss_buffer_set_t *attrs)
534 eap_gss_get_attr_types_args args;
535 OM_uint32 major, minor;
539 major = gss_create_empty_buffer_set(&minor, attrs);
540 if (GSS_ERROR(major))
541 throw std::bad_alloc();
545 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
546 gss_eap_attr_provider *provider = m_providers[i];
550 if (provider == NULL)
553 ret = provider->getAttributeTypes(addAttribute, (void *)&args);
559 gss_release_buffer_set(&minor, attrs);
565 * Get attribute with given name
568 gss_eap_attr_ctx::getAttribute(const gss_buffer_t attr,
572 gss_buffer_t display_value,
575 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
577 gss_eap_attr_provider *provider;
580 decomposeAttributeName(attr, &type, &suffix);
582 provider = m_providers[type];
583 if (provider == NULL)
586 ret = provider->getAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix,
587 authenticated, complete,
588 value, display_value, more);
594 * Map attribute context to C++ object
597 gss_eap_attr_ctx::mapToAny(int authenticated,
598 gss_buffer_t type_id) const
601 gss_eap_attr_provider *provider;
602 gss_buffer_desc suffix;
604 decomposeAttributeName(type_id, &type, &suffix);
606 provider = m_providers[type];
607 if (provider == NULL)
608 return (gss_any_t)NULL;
610 return provider->mapToAny(authenticated, &suffix);
614 * Release mapped context
617 gss_eap_attr_ctx::releaseAnyNameMapping(gss_buffer_t type_id,
618 gss_any_t input) const
621 gss_eap_attr_provider *provider;
622 gss_buffer_desc suffix;
624 decomposeAttributeName(type_id, &type, &suffix);
626 provider = m_providers[type];
627 if (provider != NULL)
628 provider->releaseAnyNameMapping(&suffix, input);
632 * Export attribute context to buffer
635 gss_eap_attr_ctx::exportToBuffer(gss_buffer_t buffer) const
640 JSONObject obj = jsonRepresentation();
646 s = obj.dump(JSON_COMPACT);
648 if (GSS_ERROR(makeStringBuffer(&minor, s, buffer)))
649 throw std::bad_alloc();
653 * Return soonest expiry time of providers
656 gss_eap_attr_ctx::getExpiryTime(void) const
659 time_t expiryTime = 0;
661 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
662 gss_eap_attr_provider *provider = m_providers[i];
663 time_t providerExpiryTime;
665 if (provider == NULL)
668 providerExpiryTime = provider->getExpiryTime();
669 if (providerExpiryTime == 0)
672 if (expiryTime == 0 || providerExpiryTime < expiryTime)
673 expiryTime = providerExpiryTime;
680 gss_eap_attr_ctx::mapException(OM_uint32 *minor, std::exception &e) const
685 /* Errors we handle ourselves */
686 if (typeid(e) == typeid(std::bad_alloc)) {
687 major = GSS_S_FAILURE;
690 } else if (typeid(e) == typeid(JSONException)) {
691 major = GSS_S_BAD_NAME;
692 *minor = GSSEAP_BAD_ATTR_TOKEN;
693 gssEapSaveStatusInfo(*minor, "%s", e.what());
697 /* Errors we delegate to providers */
698 major = GSS_S_CONTINUE_NEEDED;
700 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
701 gss_eap_attr_provider *provider = m_providers[i];
703 if (provider == NULL)
706 major = provider->mapException(minor, e);
707 if (major != GSS_S_CONTINUE_NEEDED)
711 if (major == GSS_S_CONTINUE_NEEDED) {
712 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
713 major = GSS_S_FAILURE;
717 GSSEAP_ASSERT(GSS_ERROR(major));
723 * Decompose attribute name into prefix and suffix
726 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
733 for (i = 0; i < attribute->length; i++) {
734 if (((char *)attribute->value)[i] == ' ') {
735 p = (char *)attribute->value + i + 1;
740 prefix->value = attribute->value;
743 if (p != NULL && *p != '\0') {
744 suffix->length = attribute->length - 1 - prefix->length;
748 suffix->value = NULL;
753 * Decompose attribute name into type and suffix
756 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
758 gss_buffer_t suffix) const
760 gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER;
762 decomposeAttributeName(attribute, &prefix, suffix);
763 *type = attributePrefixToType(&prefix);
767 * Compose attribute name from prefix, suffix; returns C++ string
770 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
771 const gss_buffer_t suffix)
775 if (prefix == GSS_C_NO_BUFFER || prefix->length == 0)
778 str.append((const char *)prefix->value, prefix->length);
780 if (suffix != GSS_C_NO_BUFFER) {
782 str.append((const char *)suffix->value, suffix->length);
789 * Compose attribute name from type, suffix; returns C++ string
792 gss_eap_attr_ctx::composeAttributeName(unsigned int type,
793 const gss_buffer_t suffix)
795 gss_buffer_desc prefix = attributeTypeToPrefix(type);
797 return composeAttributeName(&prefix, suffix);
801 * Compose attribute name from prefix, suffix; returns GSS buffer
804 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
805 const gss_buffer_t suffix,
806 gss_buffer_t attribute)
808 std::string str = composeAttributeName(prefix, suffix);
810 if (str.length() != 0) {
811 return duplicateBuffer(str, attribute);
813 attribute->length = 0;
814 attribute->value = NULL;
819 * Compose attribute name from type, suffix; returns GSS buffer
822 gss_eap_attr_ctx::composeAttributeName(unsigned int type,
823 const gss_buffer_t suffix,
824 gss_buffer_t attribute) const
826 gss_buffer_desc prefix = attributeTypeToPrefix(type);
828 return composeAttributeName(&prefix, suffix, attribute);
835 gssEapInquireName(OM_uint32 *minor,
839 gss_buffer_set_t *attrs)
843 if (name_is_MN != NULL)
844 *name_is_MN = (name->mechanismUsed != GSS_C_NULL_OID);
846 if (MN_mech != NULL) {
847 major = gssEapCanonicalizeOid(minor, name->mechanismUsed,
848 OID_FLAG_NULL_VALID, MN_mech);
849 if (GSS_ERROR(major))
853 if (name->attrCtx == NULL) {
854 *minor = GSSEAP_NO_ATTR_CONTEXT;
855 return GSS_S_UNAVAILABLE;
858 if (GSS_ERROR(gssEapAttrProvidersInit(minor))) {
859 return GSS_S_UNAVAILABLE;
863 if (!name->attrCtx->getAttributeTypes(attrs)) {
864 *minor = GSSEAP_NO_ATTR_CONTEXT;
865 return GSS_S_UNAVAILABLE;
867 } catch (std::exception &e) {
868 return name->attrCtx->mapException(minor, e);
871 return GSS_S_COMPLETE;
875 gssEapGetNameAttribute(OM_uint32 *minor,
881 gss_buffer_t display_value,
884 if (authenticated != NULL)
886 if (complete != NULL)
894 if (display_value != NULL) {
895 display_value->length = 0;
896 display_value->value = NULL;
899 if (name->attrCtx == NULL) {
900 *minor = GSSEAP_NO_ATTR_CONTEXT;
901 return GSS_S_UNAVAILABLE;
904 if (GSS_ERROR(gssEapAttrProvidersInit(minor))) {
905 return GSS_S_UNAVAILABLE;
909 if (!name->attrCtx->getAttribute(attr, authenticated, complete,
910 value, display_value, more)) {
911 *minor = GSSEAP_NO_SUCH_ATTR;
912 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
913 (int)attr->length, (char *)attr->value);
914 return GSS_S_UNAVAILABLE;
916 } catch (std::exception &e) {
917 return name->attrCtx->mapException(minor, e);
920 return GSS_S_COMPLETE;
924 gssEapDeleteNameAttribute(OM_uint32 *minor,
928 if (name->attrCtx == NULL) {
929 *minor = GSSEAP_NO_ATTR_CONTEXT;
930 return GSS_S_UNAVAILABLE;
933 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
934 return GSS_S_UNAVAILABLE;
937 if (!name->attrCtx->deleteAttribute(attr)) {
938 *minor = GSSEAP_NO_SUCH_ATTR;
939 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
940 (int)attr->length, (char *)attr->value);
941 return GSS_S_UNAVAILABLE;
943 } catch (std::exception &e) {
944 return name->attrCtx->mapException(minor, e);
947 return GSS_S_COMPLETE;
951 gssEapSetNameAttribute(OM_uint32 *minor,
957 if (name->attrCtx == NULL) {
958 *minor = GSSEAP_NO_ATTR_CONTEXT;
959 return GSS_S_UNAVAILABLE;
962 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
963 return GSS_S_UNAVAILABLE;
966 if (!name->attrCtx->setAttribute(complete, attr, value)) {
967 *minor = GSSEAP_NO_SUCH_ATTR;
968 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
969 (int)attr->length, (char *)attr->value);
970 return GSS_S_UNAVAILABLE;
972 } catch (std::exception &e) {
973 return name->attrCtx->mapException(minor, e);
976 return GSS_S_COMPLETE;
980 gssEapExportAttrContext(OM_uint32 *minor,
984 if (name->attrCtx == NULL) {
986 buffer->value = NULL;
988 return GSS_S_COMPLETE;
991 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
992 return GSS_S_UNAVAILABLE;
995 name->attrCtx->exportToBuffer(buffer);
996 } catch (std::exception &e) {
997 return name->attrCtx->mapException(minor, e);
1000 return GSS_S_COMPLETE;
1004 gssEapImportAttrContext(OM_uint32 *minor,
1005 gss_buffer_t buffer,
1008 gss_eap_attr_ctx *ctx = NULL;
1009 OM_uint32 major = GSS_S_FAILURE;
1011 GSSEAP_ASSERT(name->attrCtx == NULL);
1013 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1014 return GSS_S_UNAVAILABLE;
1016 if (buffer->length == 0)
1017 return GSS_S_COMPLETE;
1020 ctx = new gss_eap_attr_ctx();
1022 if (ctx->initWithBuffer(buffer)) {
1023 name->attrCtx = ctx;
1024 major = GSS_S_COMPLETE;
1027 major = GSS_S_BAD_NAME;
1028 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1030 } catch (std::exception &e) {
1032 major = ctx->mapException(minor, e);
1035 GSSEAP_ASSERT(major == GSS_S_COMPLETE || name->attrCtx == NULL);
1037 if (GSS_ERROR(major))
1044 gssEapDuplicateAttrContext(OM_uint32 *minor,
1048 gss_eap_attr_ctx *ctx = NULL;
1049 OM_uint32 major = GSS_S_FAILURE;
1051 GSSEAP_ASSERT(out->attrCtx == NULL);
1053 if (in->attrCtx == NULL) {
1055 return GSS_S_COMPLETE;
1058 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1059 return GSS_S_UNAVAILABLE;
1062 ctx = new gss_eap_attr_ctx();
1064 if (ctx->initWithExistingContext(in->attrCtx)) {
1066 major = GSS_S_COMPLETE;
1069 major = GSS_S_FAILURE;
1070 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1072 } catch (std::exception &e) {
1073 major = in->attrCtx->mapException(minor, e);
1076 GSSEAP_ASSERT(major == GSS_S_COMPLETE || out->attrCtx == NULL);
1078 if (GSS_ERROR(major))
1081 return GSS_S_COMPLETE;
1085 gssEapMapNameToAny(OM_uint32 *minor,
1088 gss_buffer_t type_id,
1091 if (name->attrCtx == NULL) {
1092 *minor = GSSEAP_NO_ATTR_CONTEXT;
1093 return GSS_S_UNAVAILABLE;
1096 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1097 return GSS_S_UNAVAILABLE;
1100 *output = name->attrCtx->mapToAny(authenticated, type_id);
1101 } catch (std::exception &e) {
1102 return name->attrCtx->mapException(minor, e);
1105 return GSS_S_COMPLETE;
1109 gssEapReleaseAnyNameMapping(OM_uint32 *minor,
1111 gss_buffer_t type_id,
1114 if (name->attrCtx == NULL) {
1115 *minor = GSSEAP_NO_ATTR_CONTEXT;
1116 return GSS_S_UNAVAILABLE;
1119 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1120 return GSS_S_UNAVAILABLE;
1124 name->attrCtx->releaseAnyNameMapping(type_id, *input);
1126 } catch (std::exception &e) {
1127 return name->attrCtx->mapException(minor, e);
1130 return GSS_S_COMPLETE;
1134 gssEapReleaseAttrContext(OM_uint32 *minor,
1137 if (name->attrCtx != NULL)
1138 delete name->attrCtx;
1141 return GSS_S_COMPLETE;
1145 * Public accessor for initialisng a context from a GSS context. Also
1146 * sets expiry time on GSS context as a side-effect.
1149 gssEapCreateAttrContext(OM_uint32 *minor,
1150 gss_cred_id_t gssCred,
1151 gss_ctx_id_t gssCtx,
1152 struct gss_eap_attr_ctx **pAttrContext,
1153 time_t *pExpiryTime)
1155 gss_eap_attr_ctx *ctx = NULL;
1158 GSSEAP_ASSERT(gssCtx != GSS_C_NO_CONTEXT);
1160 *pAttrContext = NULL;
1162 major = gssEapAttrProvidersInit(minor);
1163 if (GSS_ERROR(major))
1167 /* Set *pAttrContext here to for reentrancy */
1168 *pAttrContext = ctx = new gss_eap_attr_ctx();
1170 if (ctx->initWithGssContext(gssCred, gssCtx)) {
1171 *pExpiryTime = ctx->getExpiryTime();
1172 major = GSS_S_COMPLETE;
1175 major = GSS_S_FAILURE;
1176 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1178 } catch (std::exception &e) {
1180 major = ctx->mapException(minor, e);
1183 if (GSS_ERROR(major)) {
1185 *pAttrContext = NULL;