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"
44 /* lazy initialisation */
45 static GSSEAP_THREAD_ONCE gssEapAttrProvidersInitOnce = GSSEAP_ONCE_INITIALIZER;
46 static OM_uint32 gssEapAttrProvidersInitStatus = GSS_S_UNAVAILABLE;
49 gssEapAttrProvidersInitInternal(void)
51 OM_uint32 major, minor;
53 assert(gssEapAttrProvidersInitStatus == GSS_S_UNAVAILABLE);
55 major = gssEapRadiusAttrProviderInit(&minor);
56 if (major == GSS_S_COMPLETE)
57 major = gssEapSamlAttrProvidersInit(&minor);
58 if (major == GSS_S_COMPLETE)
59 major = gssEapLocalAttrProviderInit(&minor);
62 assert(major == GSS_S_COMPLETE);
65 gssEapAttrProvidersInitStatus = major;
69 gssEapAttrProvidersInit(OM_uint32 *minor)
71 GSSEAP_ONCE(&gssEapAttrProvidersInitOnce, gssEapAttrProvidersInitInternal);
73 if (GSS_ERROR(gssEapAttrProvidersInitStatus))
74 *minor = GSSEAP_NO_ATTR_PROVIDERS;
76 return gssEapAttrProvidersInitStatus;
80 gssEapAttrProvidersFinalize(OM_uint32 *minor)
82 OM_uint32 major = GSS_S_COMPLETE;
84 if (gssEapAttrProvidersInitStatus == GSS_S_COMPLETE) {
85 major = gssEapLocalAttrProviderFinalize(minor);
86 if (major == GSS_S_COMPLETE)
87 major = gssEapSamlAttrProvidersFinalize(minor);
88 if (major == GSS_S_COMPLETE)
89 major = gssEapRadiusAttrProviderFinalize(minor);
91 gssEapAttrProvidersInitStatus = GSS_S_UNAVAILABLE;
97 static gss_eap_attr_create_provider gssEapAttrFactories[ATTR_TYPE_MAX + 1];
98 static gss_buffer_desc gssEapAttrPrefixes[ATTR_TYPE_MAX + 1];
101 * Register a provider for a particular type and prefix
104 gss_eap_attr_ctx::registerProvider(unsigned int type,
106 gss_eap_attr_create_provider factory)
108 assert(type <= ATTR_TYPE_MAX);
110 assert(gssEapAttrFactories[type] == NULL);
112 gssEapAttrFactories[type] = factory;
113 if (prefix != NULL) {
114 gssEapAttrPrefixes[type].value = (void *)prefix;
115 gssEapAttrPrefixes[type].length = strlen(prefix);
117 gssEapAttrPrefixes[type].value = NULL;
118 gssEapAttrPrefixes[type].length = 0;
123 * Unregister a provider
126 gss_eap_attr_ctx::unregisterProvider(unsigned int type)
128 assert(type <= ATTR_TYPE_MAX);
130 gssEapAttrFactories[type] = NULL;
131 gssEapAttrPrefixes[type].value = NULL;
132 gssEapAttrPrefixes[type].length = 0;
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)
163 for (i = ATTR_TYPE_MIN; i < ATTR_TYPE_MAX; i++) {
164 if (bufferEqual(&gssEapAttrPrefixes[i], prefix))
168 return ATTR_TYPE_LOCAL;
172 * Convert a type to an attribute prefix
175 gss_eap_attr_ctx::attributeTypeToPrefix(unsigned int type)
177 if (type < ATTR_TYPE_MIN || type >= ATTR_TYPE_MAX)
178 return GSS_C_NO_BUFFER;
180 return &gssEapAttrPrefixes[type];
184 gss_eap_attr_ctx::providerEnabled(unsigned int type) const
186 if (type == ATTR_TYPE_LOCAL &&
187 (m_flags & ATTR_FLAG_DISABLE_LOCAL))
190 if (m_providers[type] == NULL)
197 gss_eap_attr_ctx::releaseProvider(unsigned int type)
199 delete m_providers[type];
200 m_providers[type] = NULL;
204 * Initialize a context from an existing context.
207 gss_eap_attr_ctx::initFromExistingContext(const gss_eap_attr_ctx *manager)
211 m_flags = manager->m_flags;
213 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
214 gss_eap_attr_provider *provider;
216 if (!providerEnabled(i)) {
221 provider = m_providers[i];
223 ret = provider->initFromExistingContext(this,
224 manager->m_providers[i]);
235 * Initialize a context from a GSS credential and context.
238 gss_eap_attr_ctx::initFromGssContext(const gss_cred_id_t cred,
239 const gss_ctx_id_t ctx)
243 if (cred != GSS_C_NO_CREDENTIAL &&
244 (cred->flags & GSS_EAP_DISABLE_LOCAL_ATTRS_FLAG)) {
245 m_flags |= ATTR_FLAG_DISABLE_LOCAL;
248 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
249 gss_eap_attr_provider *provider;
251 if (!providerEnabled(i)) {
256 provider = m_providers[i];
258 ret = provider->initFromGssContext(this, cred, ctx);
268 #define UPDATE_REMAIN(n) do { \
273 #define CHECK_REMAIN(n) do { \
274 if (remain < (n)) { \
280 * Initialize a context from an exported context or name token
283 gss_eap_attr_ctx::initFromBuffer(const gss_buffer_t buffer)
286 size_t remain = buffer->length;
287 unsigned char *p = (unsigned char *)buffer->value;
288 bool didInit[ATTR_TYPE_MAX + 1];
291 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++)
292 didInit[type] = false;
296 m_flags = load_uint32_be(p);
301 gss_buffer_desc providerToken;
302 gss_eap_attr_provider *provider;
304 /* TLV encoding of provider type, length, value */
306 type = load_uint32_be(p);
310 providerToken.length = load_uint32_be(p);
313 CHECK_REMAIN(providerToken.length);
314 providerToken.value = p;
315 UPDATE_REMAIN(providerToken.length);
317 if (type < ATTR_TYPE_MIN || type > ATTR_TYPE_MAX ||
321 if (!providerEnabled(type)) {
322 releaseProvider(type);
326 provider = m_providers[type];
328 ret = provider->initFromBuffer(this, &providerToken);
330 releaseProvider(type);
333 didInit[type] = true;
340 * The call the initFromGssContext methods for attribute
341 * providers that can initialize themselves from other
344 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
345 gss_eap_attr_provider *provider;
347 if (didInit[type] || !providerEnabled(type))
350 provider = m_providers[type];
352 ret = provider->initFromGssContext(this,
356 releaseProvider(type);
364 gss_eap_attr_ctx::~gss_eap_attr_ctx(void)
366 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++)
367 delete m_providers[i];
371 * Locate provider for a given type
373 gss_eap_attr_provider *
374 gss_eap_attr_ctx::getProvider(unsigned int type) const
376 assert(type >= ATTR_TYPE_MIN && type <= ATTR_TYPE_MAX);
377 return m_providers[type];
381 * Locate provider for a given prefix
383 gss_eap_attr_provider *
384 gss_eap_attr_ctx::getProvider(const gss_buffer_t prefix) const
388 type = attributePrefixToType(prefix);
390 return m_providers[type];
394 * Get primary provider. Only the primary provider is serialised when
395 * gss_export_sec_context() or gss_export_name_composite() is called.
397 gss_eap_attr_provider *
398 gss_eap_attr_ctx::getPrimaryProvider(void) const
400 return m_providers[ATTR_TYPE_MIN];
407 gss_eap_attr_ctx::setAttribute(int complete,
408 const gss_buffer_t attr,
409 const gss_buffer_t value)
411 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
413 gss_eap_attr_provider *provider;
416 decomposeAttributeName(attr, &type, &suffix);
418 provider = m_providers[type];
419 if (provider != NULL) {
420 ret = provider->setAttribute(complete,
421 (type == ATTR_TYPE_LOCAL) ? attr : &suffix,
429 * Delete an attrbiute
432 gss_eap_attr_ctx::deleteAttribute(const gss_buffer_t attr)
434 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
436 gss_eap_attr_provider *provider;
439 decomposeAttributeName(attr, &type, &suffix);
441 provider = m_providers[type];
442 if (provider != NULL) {
443 ret = provider->deleteAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix);
450 * Enumerate attribute types with callback
453 gss_eap_attr_ctx::getAttributeTypes(gss_eap_attr_enumeration_cb cb, void *data) const
458 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
459 gss_eap_attr_provider *provider = m_providers[i];
461 if (provider == NULL)
464 ret = provider->getAttributeTypes(cb, data);
472 struct eap_gss_get_attr_types_args {
474 gss_buffer_set_t attrs;
478 addAttribute(const gss_eap_attr_provider *provider GSSEAP_UNUSED,
479 const gss_buffer_t attribute,
482 eap_gss_get_attr_types_args *args = (eap_gss_get_attr_types_args *)data;
483 gss_buffer_desc qualified;
484 OM_uint32 major, minor;
486 if (args->type != ATTR_TYPE_LOCAL) {
487 gss_eap_attr_ctx::composeAttributeName(args->type, attribute, &qualified);
488 major = gss_add_buffer_set_member(&minor, &qualified, &args->attrs);
489 gss_release_buffer(&minor, &qualified);
491 major = gss_add_buffer_set_member(&minor, attribute, &args->attrs);
494 return GSS_ERROR(major) == false;
498 * Enumerate attribute types, output is buffer set
501 gss_eap_attr_ctx::getAttributeTypes(gss_buffer_set_t *attrs)
503 eap_gss_get_attr_types_args args;
504 OM_uint32 major, minor;
508 major = gss_create_empty_buffer_set(&minor, attrs);
509 if (GSS_ERROR(major)) {
510 throw new std::bad_alloc;
516 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
517 gss_eap_attr_provider *provider = m_providers[i];
521 if (provider == NULL)
524 ret = provider->getAttributeTypes(addAttribute, (void *)&args);
530 gss_release_buffer_set(&minor, attrs);
536 * Get attribute with given name
539 gss_eap_attr_ctx::getAttribute(const gss_buffer_t attr,
543 gss_buffer_t display_value,
546 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
548 gss_eap_attr_provider *provider;
551 decomposeAttributeName(attr, &type, &suffix);
553 provider = m_providers[type];
554 if (provider == NULL)
557 ret = provider->getAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix,
558 authenticated, complete,
559 value, display_value, more);
565 * Map attribute context to C++ object
568 gss_eap_attr_ctx::mapToAny(int authenticated,
569 gss_buffer_t type_id) const
572 gss_eap_attr_provider *provider;
573 gss_buffer_desc suffix;
575 decomposeAttributeName(type_id, &type, &suffix);
577 provider = m_providers[type];
578 if (provider == NULL)
579 return (gss_any_t)NULL;
581 return provider->mapToAny(authenticated, &suffix);
585 * Release mapped context
588 gss_eap_attr_ctx::releaseAnyNameMapping(gss_buffer_t type_id,
589 gss_any_t input) const
592 gss_eap_attr_provider *provider;
593 gss_buffer_desc suffix;
595 decomposeAttributeName(type_id, &type, &suffix);
597 provider = m_providers[type];
598 if (provider != NULL)
599 provider->releaseAnyNameMapping(&suffix, input);
603 * Export attribute context to buffer
606 gss_eap_attr_ctx::exportToBuffer(gss_buffer_t buffer) const
609 gss_buffer_desc providerTokens[ATTR_TYPE_MAX + 1];
610 size_t length = 4; /* m_flags */
614 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
615 providerTokens[i].length = 0;
616 providerTokens[i].value = NULL;
619 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
620 gss_eap_attr_provider *provider = m_providers[i];
622 if (provider == NULL)
625 provider->exportToBuffer(&providerTokens[i]);
627 if (providerTokens[i].value != NULL)
628 length += 8 + providerTokens[i].length;
631 buffer->length = length;
632 buffer->value = GSSEAP_MALLOC(length);
633 if (buffer->value == NULL)
634 throw new std::bad_alloc;
636 p = (unsigned char *)buffer->value;
637 store_uint32_be(m_flags, p);
640 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
641 if (providerTokens[i].value == NULL)
644 store_uint32_be(i, p);
646 store_uint32_be(providerTokens[i].length, p);
648 memcpy(p, providerTokens[i].value, providerTokens[i].length);
649 p += providerTokens[i].length;
651 gss_release_buffer(&tmpMinor, &providerTokens[i]);
656 * Return soonest expiry time of providers
659 gss_eap_attr_ctx::getExpiryTime(void) const
662 time_t expiryTime = 0;
664 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
665 gss_eap_attr_provider *provider = m_providers[i];
666 time_t providerExpiryTime;
668 if (provider == NULL)
671 providerExpiryTime = provider->getExpiryTime();
672 if (providerExpiryTime == 0)
675 if (expiryTime == 0 || providerExpiryTime < expiryTime)
676 expiryTime = providerExpiryTime;
683 gss_eap_attr_ctx::mapException(OM_uint32 *minor, std::exception &e) const
688 /* Errors we handle ourselves */
689 major = GSS_S_FAILURE;
691 if (typeid(e) == typeid(std::bad_alloc)) {
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;
717 /* rethrow for now for debugging */
721 assert(GSS_ERROR(major));
727 * Decompose attribute name into prefix and suffix
730 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
737 for (i = 0; i < attribute->length; i++) {
738 if (((char *)attribute->value)[i] == ' ') {
739 p = (char *)attribute->value + i + 1;
744 prefix->value = attribute->value;
747 if (p != NULL && *p != '\0') {
748 suffix->length = attribute->length - 1 - prefix->length;
752 suffix->value = NULL;
757 * Decompose attribute name into type and suffix
760 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
764 gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER;
766 decomposeAttributeName(attribute, &prefix, suffix);
767 *type = attributePrefixToType(&prefix);
771 * Compose attribute name from prefix, suffix; returns C++ string
774 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
775 const gss_buffer_t suffix)
779 if (prefix == GSS_C_NO_BUFFER || prefix->length == 0)
782 str.append((const char *)prefix->value, prefix->length);
784 if (suffix != GSS_C_NO_BUFFER) {
786 str.append((const char *)suffix->value, suffix->length);
793 * Compose attribute name from type, suffix; returns C++ string
796 gss_eap_attr_ctx::composeAttributeName(unsigned int type,
797 const gss_buffer_t suffix)
799 const gss_buffer_t prefix = attributeTypeToPrefix(type);
801 return composeAttributeName(prefix, suffix);
805 * Compose attribute name from prefix, suffix; returns GSS buffer
808 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
809 const gss_buffer_t suffix,
810 gss_buffer_t attribute)
812 std::string str = composeAttributeName(prefix, suffix);
814 if (str.length() != 0) {
815 return duplicateBuffer(str, attribute);
817 attribute->length = 0;
818 attribute->value = NULL;
823 * Compose attribute name from type, suffix; returns GSS buffer
826 gss_eap_attr_ctx::composeAttributeName(unsigned int type,
827 const gss_buffer_t suffix,
828 gss_buffer_t attribute)
830 gss_buffer_t prefix = attributeTypeToPrefix(type);
832 return composeAttributeName(prefix, suffix, attribute);
839 gssEapInquireName(OM_uint32 *minor,
843 gss_buffer_set_t *attrs)
847 if (name_is_MN != NULL)
848 *name_is_MN = (name->mechanismUsed != GSS_C_NULL_OID);
850 if (MN_mech != NULL) {
851 major = gssEapCanonicalizeOid(minor, name->mechanismUsed,
852 OID_FLAG_NULL_VALID, MN_mech);
853 if (GSS_ERROR(major))
857 if (name->attrCtx == NULL) {
858 *minor = GSSEAP_NO_ATTR_CONTEXT;
859 return GSS_S_UNAVAILABLE;
862 if (GSS_ERROR(gssEapAttrProvidersInit(minor))) {
863 return GSS_S_UNAVAILABLE;
867 if (!name->attrCtx->getAttributeTypes(attrs)) {
868 *minor = GSSEAP_NO_ATTR_CONTEXT;
869 return GSS_S_UNAVAILABLE;
871 } catch (std::exception &e) {
872 return name->attrCtx->mapException(minor, e);
875 return GSS_S_COMPLETE;
879 gssEapGetNameAttribute(OM_uint32 *minor,
885 gss_buffer_t display_value,
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;
1012 assert(name->attrCtx == NULL);
1014 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1015 return GSS_S_UNAVAILABLE;
1017 if (buffer->length != 0) {
1019 ctx = new gss_eap_attr_ctx();
1021 if (!ctx->initFromBuffer(buffer)) {
1023 *minor = GSSEAP_BAD_ATTR_TOKEN;
1024 return GSS_S_DEFECTIVE_TOKEN;
1026 name->attrCtx = ctx;
1027 } catch (std::exception &e) {
1029 return name->attrCtx->mapException(minor, e);
1033 return GSS_S_COMPLETE;
1037 gssEapDuplicateAttrContext(OM_uint32 *minor,
1041 gss_eap_attr_ctx *ctx = NULL;
1043 assert(out->attrCtx == NULL);
1045 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1046 return GSS_S_UNAVAILABLE;
1049 if (in->attrCtx != NULL) {
1050 ctx = new gss_eap_attr_ctx();
1051 if (!ctx->initFromExistingContext(in->attrCtx)) {
1053 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1054 return GSS_S_FAILURE;
1058 } catch (std::exception &e) {
1060 return in->attrCtx->mapException(minor, e);
1063 return GSS_S_COMPLETE;
1067 gssEapMapNameToAny(OM_uint32 *minor,
1070 gss_buffer_t type_id,
1073 if (name->attrCtx == NULL) {
1074 *minor = GSSEAP_NO_ATTR_CONTEXT;
1075 return GSS_S_UNAVAILABLE;
1078 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1079 return GSS_S_UNAVAILABLE;
1082 *output = name->attrCtx->mapToAny(authenticated, type_id);
1083 } catch (std::exception &e) {
1084 return name->attrCtx->mapException(minor, e);
1087 return GSS_S_COMPLETE;
1091 gssEapReleaseAnyNameMapping(OM_uint32 *minor,
1093 gss_buffer_t type_id,
1096 if (name->attrCtx == NULL) {
1097 *minor = GSSEAP_NO_ATTR_CONTEXT;
1098 return GSS_S_UNAVAILABLE;
1101 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1102 return GSS_S_UNAVAILABLE;
1106 name->attrCtx->releaseAnyNameMapping(type_id, *input);
1108 } catch (std::exception &e) {
1109 return name->attrCtx->mapException(minor, e);
1112 return GSS_S_COMPLETE;
1116 gssEapReleaseAttrContext(OM_uint32 *minor,
1119 if (name->attrCtx != NULL)
1120 delete name->attrCtx;
1123 return GSS_S_COMPLETE;
1127 * Public accessor for initialisng a context from a GSS context. Also
1128 * sets expiry time on GSS context as a side-effect.
1131 gssEapCreateAttrContext(OM_uint32 *minor,
1132 gss_cred_id_t gssCred,
1133 gss_ctx_id_t gssCtx,
1134 struct gss_eap_attr_ctx **pAttrContext,
1135 time_t *pExpiryTime)
1137 gss_eap_attr_ctx *ctx = NULL;
1140 assert(gssCtx != GSS_C_NO_CONTEXT);
1142 major = gssEapAttrProvidersInit(minor);
1143 if (GSS_ERROR(major))
1146 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1147 major = GSS_S_FAILURE;
1150 ctx = new gss_eap_attr_ctx();
1151 if (ctx->initFromGssContext(gssCred, gssCtx)) {
1153 major = GSS_S_COMPLETE;
1157 } catch (std::exception &e) {
1159 major = ctx->mapException(minor, e);
1162 if (major == GSS_S_COMPLETE) {
1163 *pAttrContext = ctx;
1164 *pExpiryTime = ctx->getExpiryTime();