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 gssEapAttrProvidersFinalize(OM_uint32 *minor)
96 if (gssEapAttrProvidersInitStatus == GSS_S_COMPLETE) {
97 #ifdef HAVE_SHIBRESOLVER
98 gssEapLocalAttrProviderFinalize(minor);
101 gssEapSamlAttrProvidersFinalize(minor);
103 gssEapRadiusAttrProviderFinalize(minor);
105 gssEapAttrProvidersInitStatus = GSS_S_UNAVAILABLE;
108 return GSS_S_COMPLETE;
111 static gss_eap_attr_create_provider gssEapAttrFactories[ATTR_TYPE_MAX + 1];
114 * Register a provider for a particular type and prefix
117 gss_eap_attr_ctx::registerProvider(unsigned int type,
118 gss_eap_attr_create_provider factory)
120 GSSEAP_ASSERT(type <= ATTR_TYPE_MAX);
122 GSSEAP_ASSERT(gssEapAttrFactories[type] == NULL);
124 gssEapAttrFactories[type] = factory;
128 * Unregister a provider
131 gss_eap_attr_ctx::unregisterProvider(unsigned int type)
133 GSSEAP_ASSERT(type <= ATTR_TYPE_MAX);
135 gssEapAttrFactories[type] = NULL;
139 * Create an attribute context, that manages instances of providers
141 gss_eap_attr_ctx::gss_eap_attr_ctx(void)
145 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
146 gss_eap_attr_provider *provider;
148 if (gssEapAttrFactories[i] != NULL) {
149 provider = (gssEapAttrFactories[i])();
154 m_providers[i] = provider;
159 * Convert an attribute prefix to a type
162 gss_eap_attr_ctx::attributePrefixToType(const gss_buffer_t prefix) const
166 for (i = ATTR_TYPE_MIN; i < ATTR_TYPE_MAX; i++) {
169 if (!providerEnabled(i))
172 pprefix = m_providers[i]->prefix();
176 if (strlen(pprefix) == prefix->length &&
177 memcmp(pprefix, prefix->value, prefix->length) == 0)
181 return ATTR_TYPE_LOCAL;
185 * Convert a type to an attribute prefix
188 gss_eap_attr_ctx::attributeTypeToPrefix(unsigned int type) const
190 gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER;
192 if (type < ATTR_TYPE_MIN || type >= ATTR_TYPE_MAX)
195 if (!providerEnabled(type))
198 prefix.value = (void *)m_providers[type]->prefix();
199 if (prefix.value != NULL)
200 prefix.length = strlen((char *)prefix.value);
206 gss_eap_attr_ctx::providerEnabled(unsigned int type) const
208 if (type == ATTR_TYPE_LOCAL &&
209 (m_flags & ATTR_FLAG_DISABLE_LOCAL))
212 if (m_providers[type] == NULL)
219 gss_eap_attr_ctx::releaseProvider(unsigned int type)
221 delete m_providers[type];
222 m_providers[type] = NULL;
226 * Initialize a context from an existing context.
229 gss_eap_attr_ctx::initWithExistingContext(const gss_eap_attr_ctx *manager)
233 m_flags = manager->m_flags;
235 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
236 gss_eap_attr_provider *provider;
238 if (!providerEnabled(i)) {
243 provider = m_providers[i];
245 ret = provider->initWithExistingContext(this,
246 manager->m_providers[i]);
257 * Initialize a context from a GSS credential and context.
260 gss_eap_attr_ctx::initWithGssContext(const gss_cred_id_t cred,
261 const gss_ctx_id_t ctx)
265 if (cred != GSS_C_NO_CREDENTIAL &&
266 (cred->flags & GSS_EAP_DISABLE_LOCAL_ATTRS_FLAG)) {
267 m_flags |= ATTR_FLAG_DISABLE_LOCAL;
270 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
271 gss_eap_attr_provider *provider;
273 if (!providerEnabled(i)) {
278 provider = m_providers[i];
280 ret = provider->initWithGssContext(this, cred, ctx);
291 gss_eap_attr_ctx::initWithJsonObject(JSONObject &obj)
294 bool foundSource[ATTR_TYPE_MAX + 1];
297 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++)
298 foundSource[type] = false;
300 if (obj["version"].integer() != 1)
303 m_flags = obj["flags"].integer();
305 JSONObject sources = obj["sources"];
307 /* Initialize providers from serialized state */
308 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
309 gss_eap_attr_provider *provider;
312 if (!providerEnabled(type)) {
313 releaseProvider(type);
317 provider = m_providers[type];
318 key = provider->name();
322 JSONObject source = sources.get(key);
323 if (!source.isNull() &&
324 !provider->initWithJsonObject(this, source)) {
325 releaseProvider(type);
329 foundSource[type] = true;
332 /* Initialize remaining providers from initialized providers */
333 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
334 gss_eap_attr_provider *provider;
336 if (foundSource[type] || !providerEnabled(type))
339 provider = m_providers[type];
341 ret = provider->initWithGssContext(this,
345 releaseProvider(type);
354 gss_eap_attr_ctx::jsonRepresentation(void) const
356 JSONObject obj, sources;
359 obj.set("version", 1);
360 obj.set("flags", m_flags);
362 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
363 gss_eap_attr_provider *provider;
366 provider = m_providers[i];
367 if (provider == NULL)
368 continue; /* provider not initialised */
370 key = provider->name();
372 continue; /* provider does not have state */
374 JSONObject source = provider->jsonRepresentation();
375 sources.set(key, source);
378 obj.set("sources", sources);
384 * Initialize a context from an exported context or name token
387 gss_eap_attr_ctx::initWithBuffer(const gss_buffer_t buffer)
389 OM_uint32 major, minor;
394 major = bufferToString(&minor, buffer, &s);
395 if (GSS_ERROR(major))
398 JSONObject obj = JSONObject::load(s, 0, &error);
400 ret = initWithJsonObject(obj);
409 gss_eap_attr_ctx::~gss_eap_attr_ctx(void)
411 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++)
412 delete m_providers[i];
416 * Locate provider for a given type
418 gss_eap_attr_provider *
419 gss_eap_attr_ctx::getProvider(unsigned int type) const
421 GSSEAP_ASSERT(type >= ATTR_TYPE_MIN && type <= ATTR_TYPE_MAX);
422 return m_providers[type];
426 * Get primary provider. Only the primary provider is serialised when
427 * gss_export_sec_context() or gss_export_name_composite() is called.
429 gss_eap_attr_provider *
430 gss_eap_attr_ctx::getPrimaryProvider(void) const
432 return m_providers[ATTR_TYPE_MIN];
439 gss_eap_attr_ctx::setAttribute(int complete,
440 const gss_buffer_t attr,
441 const gss_buffer_t value)
443 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
445 gss_eap_attr_provider *provider;
448 decomposeAttributeName(attr, &type, &suffix);
450 provider = m_providers[type];
451 if (provider != NULL) {
452 ret = provider->setAttribute(complete,
453 (type == ATTR_TYPE_LOCAL) ? attr : &suffix,
461 * Delete an attrbiute
464 gss_eap_attr_ctx::deleteAttribute(const gss_buffer_t attr)
466 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
468 gss_eap_attr_provider *provider;
471 decomposeAttributeName(attr, &type, &suffix);
473 provider = m_providers[type];
474 if (provider != NULL) {
475 ret = provider->deleteAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix);
482 * Enumerate attribute types with callback
485 gss_eap_attr_ctx::getAttributeTypes(gss_eap_attr_enumeration_cb cb, void *data) const
490 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
491 gss_eap_attr_provider *provider = m_providers[i];
493 if (provider == NULL)
496 ret = provider->getAttributeTypes(cb, data);
504 struct eap_gss_get_attr_types_args {
506 gss_buffer_set_t attrs;
510 addAttribute(const gss_eap_attr_ctx *manager,
511 const gss_eap_attr_provider *provider GSSEAP_UNUSED,
512 const gss_buffer_t attribute,
515 eap_gss_get_attr_types_args *args = (eap_gss_get_attr_types_args *)data;
516 gss_buffer_desc qualified;
517 OM_uint32 major, minor;
519 if (args->type != ATTR_TYPE_LOCAL) {
520 manager->composeAttributeName(args->type, attribute, &qualified);
521 major = gss_add_buffer_set_member(&minor, &qualified, &args->attrs);
522 gss_release_buffer(&minor, &qualified);
524 major = gss_add_buffer_set_member(&minor, attribute, &args->attrs);
527 return GSS_ERROR(major) == false;
531 * Enumerate attribute types, output is buffer set
534 gss_eap_attr_ctx::getAttributeTypes(gss_buffer_set_t *attrs)
536 eap_gss_get_attr_types_args args;
537 OM_uint32 major, minor;
541 major = gss_create_empty_buffer_set(&minor, attrs);
542 if (GSS_ERROR(major))
543 throw std::bad_alloc();
547 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
548 gss_eap_attr_provider *provider = m_providers[i];
552 if (provider == NULL)
555 ret = provider->getAttributeTypes(addAttribute, (void *)&args);
561 gss_release_buffer_set(&minor, attrs);
567 * Get attribute with given name
570 gss_eap_attr_ctx::getAttribute(const gss_buffer_t attr,
574 gss_buffer_t display_value,
577 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
579 gss_eap_attr_provider *provider;
582 decomposeAttributeName(attr, &type, &suffix);
584 provider = m_providers[type];
585 if (provider == NULL)
588 ret = provider->getAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix,
589 authenticated, complete,
590 value, display_value, more);
596 * Map attribute context to C++ object
599 gss_eap_attr_ctx::mapToAny(int authenticated,
600 gss_buffer_t type_id) const
603 gss_eap_attr_provider *provider;
604 gss_buffer_desc suffix;
606 decomposeAttributeName(type_id, &type, &suffix);
608 provider = m_providers[type];
609 if (provider == NULL)
610 return (gss_any_t)NULL;
612 return provider->mapToAny(authenticated, &suffix);
616 * Release mapped context
619 gss_eap_attr_ctx::releaseAnyNameMapping(gss_buffer_t type_id,
620 gss_any_t input) 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 provider->releaseAnyNameMapping(&suffix, input);
634 * Export attribute context to buffer
637 gss_eap_attr_ctx::exportToBuffer(gss_buffer_t buffer) const
642 JSONObject obj = jsonRepresentation();
648 s = obj.dump(JSON_COMPACT);
650 if (GSS_ERROR(makeStringBuffer(&minor, s, buffer)))
651 throw std::bad_alloc();
655 * Return soonest expiry time of providers
658 gss_eap_attr_ctx::getExpiryTime(void) const
661 time_t expiryTime = 0;
663 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
664 gss_eap_attr_provider *provider = m_providers[i];
665 time_t providerExpiryTime;
667 if (provider == NULL)
670 providerExpiryTime = provider->getExpiryTime();
671 if (providerExpiryTime == 0)
674 if (expiryTime == 0 || providerExpiryTime < expiryTime)
675 expiryTime = providerExpiryTime;
682 gss_eap_attr_ctx::mapException(OM_uint32 *minor, std::exception &e) const
687 /* Errors we handle ourselves */
688 if (typeid(e) == typeid(std::bad_alloc)) {
689 major = GSS_S_FAILURE;
692 } else if (typeid(e) == typeid(JSONException)) {
693 major = GSS_S_BAD_NAME;
694 *minor = GSSEAP_BAD_ATTR_TOKEN;
695 gssEapSaveStatusInfo(*minor, "%s", e.what());
699 /* Errors we delegate to providers */
700 major = GSS_S_CONTINUE_NEEDED;
702 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
703 gss_eap_attr_provider *provider = m_providers[i];
705 if (provider == NULL)
708 major = provider->mapException(minor, e);
709 if (major != GSS_S_CONTINUE_NEEDED)
713 if (major == GSS_S_CONTINUE_NEEDED) {
714 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
715 major = GSS_S_FAILURE;
719 GSSEAP_ASSERT(GSS_ERROR(major));
725 * Decompose attribute name into prefix and suffix
728 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
735 for (i = 0; i < attribute->length; i++) {
736 if (((char *)attribute->value)[i] == ' ') {
737 p = (char *)attribute->value + i + 1;
742 prefix->value = attribute->value;
745 if (p != NULL && *p != '\0') {
746 suffix->length = attribute->length - 1 - prefix->length;
750 suffix->value = NULL;
755 * Decompose attribute name into type and suffix
758 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
760 gss_buffer_t suffix) const
762 gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER;
764 decomposeAttributeName(attribute, &prefix, suffix);
765 *type = attributePrefixToType(&prefix);
769 * Compose attribute name from prefix, suffix; returns C++ string
772 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
773 const gss_buffer_t suffix)
777 if (prefix == GSS_C_NO_BUFFER || prefix->length == 0)
780 str.append((const char *)prefix->value, prefix->length);
782 if (suffix != GSS_C_NO_BUFFER) {
784 str.append((const char *)suffix->value, suffix->length);
791 * Compose attribute name from type, suffix; returns C++ string
794 gss_eap_attr_ctx::composeAttributeName(unsigned int type,
795 const gss_buffer_t suffix)
797 gss_buffer_desc prefix = attributeTypeToPrefix(type);
799 return composeAttributeName(&prefix, suffix);
803 * Compose attribute name from prefix, suffix; returns GSS buffer
806 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
807 const gss_buffer_t suffix,
808 gss_buffer_t attribute)
810 std::string str = composeAttributeName(prefix, suffix);
812 if (str.length() != 0) {
813 return duplicateBuffer(str, attribute);
815 attribute->length = 0;
816 attribute->value = NULL;
821 * Compose attribute name from type, suffix; returns GSS buffer
824 gss_eap_attr_ctx::composeAttributeName(unsigned int type,
825 const gss_buffer_t suffix,
826 gss_buffer_t attribute) const
828 gss_buffer_desc prefix = attributeTypeToPrefix(type);
830 return composeAttributeName(&prefix, suffix, attribute);
837 gssEapInquireName(OM_uint32 *minor,
841 gss_buffer_set_t *attrs)
845 if (name_is_MN != NULL)
846 *name_is_MN = (name->mechanismUsed != GSS_C_NULL_OID);
848 if (MN_mech != NULL) {
849 major = gssEapCanonicalizeOid(minor, name->mechanismUsed,
850 OID_FLAG_NULL_VALID, MN_mech);
851 if (GSS_ERROR(major))
855 if (name->attrCtx == NULL) {
856 *minor = GSSEAP_NO_ATTR_CONTEXT;
857 return GSS_S_UNAVAILABLE;
860 if (GSS_ERROR(gssEapAttrProvidersInit(minor))) {
861 return GSS_S_UNAVAILABLE;
865 if (!name->attrCtx->getAttributeTypes(attrs)) {
866 *minor = GSSEAP_NO_ATTR_CONTEXT;
867 return GSS_S_UNAVAILABLE;
869 } catch (std::exception &e) {
870 return name->attrCtx->mapException(minor, e);
873 return GSS_S_COMPLETE;
877 gssEapGetNameAttribute(OM_uint32 *minor,
883 gss_buffer_t display_value,
886 if (authenticated != NULL)
888 if (complete != NULL)
896 if (display_value != NULL) {
897 display_value->length = 0;
898 display_value->value = NULL;
901 if (name->attrCtx == NULL) {
902 *minor = GSSEAP_NO_ATTR_CONTEXT;
903 return GSS_S_UNAVAILABLE;
906 if (GSS_ERROR(gssEapAttrProvidersInit(minor))) {
907 return GSS_S_UNAVAILABLE;
911 if (!name->attrCtx->getAttribute(attr, authenticated, complete,
912 value, display_value, more)) {
913 *minor = GSSEAP_NO_SUCH_ATTR;
914 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
915 (int)attr->length, (char *)attr->value);
916 return GSS_S_UNAVAILABLE;
918 } catch (std::exception &e) {
919 return name->attrCtx->mapException(minor, e);
922 return GSS_S_COMPLETE;
926 gssEapDeleteNameAttribute(OM_uint32 *minor,
930 if (name->attrCtx == NULL) {
931 *minor = GSSEAP_NO_ATTR_CONTEXT;
932 return GSS_S_UNAVAILABLE;
935 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
936 return GSS_S_UNAVAILABLE;
939 if (!name->attrCtx->deleteAttribute(attr)) {
940 *minor = GSSEAP_NO_SUCH_ATTR;
941 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
942 (int)attr->length, (char *)attr->value);
943 return GSS_S_UNAVAILABLE;
945 } catch (std::exception &e) {
946 return name->attrCtx->mapException(minor, e);
949 return GSS_S_COMPLETE;
953 gssEapSetNameAttribute(OM_uint32 *minor,
959 if (name->attrCtx == NULL) {
960 *minor = GSSEAP_NO_ATTR_CONTEXT;
961 return GSS_S_UNAVAILABLE;
964 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
965 return GSS_S_UNAVAILABLE;
968 if (!name->attrCtx->setAttribute(complete, attr, value)) {
969 *minor = GSSEAP_NO_SUCH_ATTR;
970 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
971 (int)attr->length, (char *)attr->value);
972 return GSS_S_UNAVAILABLE;
974 } catch (std::exception &e) {
975 return name->attrCtx->mapException(minor, e);
978 return GSS_S_COMPLETE;
982 gssEapExportAttrContext(OM_uint32 *minor,
986 if (name->attrCtx == NULL) {
988 buffer->value = NULL;
990 return GSS_S_COMPLETE;
993 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
994 return GSS_S_UNAVAILABLE;
997 name->attrCtx->exportToBuffer(buffer);
998 } catch (std::exception &e) {
999 return name->attrCtx->mapException(minor, e);
1002 return GSS_S_COMPLETE;
1006 gssEapImportAttrContext(OM_uint32 *minor,
1007 gss_buffer_t buffer,
1010 gss_eap_attr_ctx *ctx = NULL;
1011 OM_uint32 major = GSS_S_FAILURE;
1013 GSSEAP_ASSERT(name->attrCtx == NULL);
1015 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1016 return GSS_S_UNAVAILABLE;
1018 if (buffer->length == 0)
1019 return GSS_S_COMPLETE;
1022 ctx = new gss_eap_attr_ctx();
1024 if (ctx->initWithBuffer(buffer)) {
1025 name->attrCtx = ctx;
1026 major = GSS_S_COMPLETE;
1029 major = GSS_S_BAD_NAME;
1030 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1032 } catch (std::exception &e) {
1034 major = ctx->mapException(minor, e);
1037 GSSEAP_ASSERT(major == GSS_S_COMPLETE || name->attrCtx == NULL);
1039 if (GSS_ERROR(major))
1046 gssEapDuplicateAttrContext(OM_uint32 *minor,
1050 gss_eap_attr_ctx *ctx = NULL;
1051 OM_uint32 major = GSS_S_FAILURE;
1053 GSSEAP_ASSERT(out->attrCtx == NULL);
1055 if (in->attrCtx == NULL) {
1057 return GSS_S_COMPLETE;
1060 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1061 return GSS_S_UNAVAILABLE;
1064 ctx = new gss_eap_attr_ctx();
1066 if (ctx->initWithExistingContext(in->attrCtx)) {
1068 major = GSS_S_COMPLETE;
1071 major = GSS_S_FAILURE;
1072 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1074 } catch (std::exception &e) {
1075 major = in->attrCtx->mapException(minor, e);
1078 GSSEAP_ASSERT(major == GSS_S_COMPLETE || out->attrCtx == NULL);
1080 if (GSS_ERROR(major))
1083 return GSS_S_COMPLETE;
1087 gssEapMapNameToAny(OM_uint32 *minor,
1090 gss_buffer_t type_id,
1093 if (name->attrCtx == NULL) {
1094 *minor = GSSEAP_NO_ATTR_CONTEXT;
1095 return GSS_S_UNAVAILABLE;
1098 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1099 return GSS_S_UNAVAILABLE;
1102 *output = name->attrCtx->mapToAny(authenticated, type_id);
1103 } catch (std::exception &e) {
1104 return name->attrCtx->mapException(minor, e);
1107 return GSS_S_COMPLETE;
1111 gssEapReleaseAnyNameMapping(OM_uint32 *minor,
1113 gss_buffer_t type_id,
1116 if (name->attrCtx == NULL) {
1117 *minor = GSSEAP_NO_ATTR_CONTEXT;
1118 return GSS_S_UNAVAILABLE;
1121 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1122 return GSS_S_UNAVAILABLE;
1126 name->attrCtx->releaseAnyNameMapping(type_id, *input);
1128 } catch (std::exception &e) {
1129 return name->attrCtx->mapException(minor, e);
1132 return GSS_S_COMPLETE;
1136 gssEapReleaseAttrContext(OM_uint32 *minor,
1139 if (name->attrCtx != NULL)
1140 delete name->attrCtx;
1143 return GSS_S_COMPLETE;
1147 * Public accessor for initialisng a context from a GSS context. Also
1148 * sets expiry time on GSS context as a side-effect.
1151 gssEapCreateAttrContext(OM_uint32 *minor,
1152 gss_cred_id_t gssCred,
1153 gss_ctx_id_t gssCtx,
1154 struct gss_eap_attr_ctx **pAttrContext,
1155 time_t *pExpiryTime)
1157 gss_eap_attr_ctx *ctx = NULL;
1160 GSSEAP_ASSERT(gssCtx != GSS_C_NO_CONTEXT);
1162 *pAttrContext = NULL;
1164 major = gssEapAttrProvidersInit(minor);
1165 if (GSS_ERROR(major))
1169 /* Set *pAttrContext here to for reentrancy */
1170 *pAttrContext = ctx = new gss_eap_attr_ctx();
1172 if (ctx->initWithGssContext(gssCred, gssCtx)) {
1173 *pExpiryTime = ctx->getExpiryTime();
1174 major = GSS_S_COMPLETE;
1177 major = GSS_S_FAILURE;
1178 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1180 } catch (std::exception &e) {
1182 major = ctx->mapException(minor, e);
1185 if (GSS_ERROR(major)) {
1187 *pAttrContext = NULL;