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);
269 * Initialize a context from an exported context or name token
272 gss_eap_attr_ctx::initFromBuffer(const gss_buffer_t buffer)
275 gss_eap_attr_provider *primaryProvider = getPrimaryProvider();
276 gss_buffer_desc primaryBuf;
278 if (buffer->length < 4)
281 m_flags = load_uint32_be(buffer->value);
283 primaryBuf.length = buffer->length - 4;
284 primaryBuf.value = (char *)buffer->value + 4;
286 ret = primaryProvider->initFromBuffer(this, &primaryBuf);
290 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
291 gss_eap_attr_provider *provider;
293 if (!providerEnabled(i)) {
298 provider = m_providers[i];
299 if (provider == primaryProvider)
302 ret = provider->initFromGssContext(this,
314 gss_eap_attr_ctx::~gss_eap_attr_ctx(void)
316 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++)
317 delete m_providers[i];
321 * Locate provider for a given type
323 gss_eap_attr_provider *
324 gss_eap_attr_ctx::getProvider(unsigned int type) const
326 assert(type >= ATTR_TYPE_MIN && type <= ATTR_TYPE_MAX);
327 return m_providers[type];
331 * Locate provider for a given prefix
333 gss_eap_attr_provider *
334 gss_eap_attr_ctx::getProvider(const gss_buffer_t prefix) const
338 type = attributePrefixToType(prefix);
340 return m_providers[type];
344 * Get primary provider. Only the primary provider is serialised when
345 * gss_export_sec_context() or gss_export_name_composite() is called.
347 gss_eap_attr_provider *
348 gss_eap_attr_ctx::getPrimaryProvider(void) const
350 return m_providers[ATTR_TYPE_MIN];
357 gss_eap_attr_ctx::setAttribute(int complete,
358 const gss_buffer_t attr,
359 const gss_buffer_t value)
361 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
363 gss_eap_attr_provider *provider;
366 decomposeAttributeName(attr, &type, &suffix);
368 provider = m_providers[type];
369 if (provider != NULL) {
370 ret = provider->setAttribute(complete,
371 (type == ATTR_TYPE_LOCAL) ? attr : &suffix,
379 * Delete an attrbiute
382 gss_eap_attr_ctx::deleteAttribute(const gss_buffer_t attr)
384 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
386 gss_eap_attr_provider *provider;
389 decomposeAttributeName(attr, &type, &suffix);
391 provider = m_providers[type];
392 if (provider != NULL) {
393 ret = provider->deleteAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix);
400 * Enumerate attribute types with callback
403 gss_eap_attr_ctx::getAttributeTypes(gss_eap_attr_enumeration_cb cb, void *data) const
408 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
409 gss_eap_attr_provider *provider = m_providers[i];
411 if (provider == NULL)
414 ret = provider->getAttributeTypes(cb, data);
422 struct eap_gss_get_attr_types_args {
424 gss_buffer_set_t attrs;
428 addAttribute(const gss_eap_attr_provider *provider GSSEAP_UNUSED,
429 const gss_buffer_t attribute,
432 eap_gss_get_attr_types_args *args = (eap_gss_get_attr_types_args *)data;
433 gss_buffer_desc qualified;
434 OM_uint32 major, minor;
436 if (args->type != ATTR_TYPE_LOCAL) {
437 gss_eap_attr_ctx::composeAttributeName(args->type, attribute, &qualified);
438 major = gss_add_buffer_set_member(&minor, &qualified, &args->attrs);
439 gss_release_buffer(&minor, &qualified);
441 major = gss_add_buffer_set_member(&minor, attribute, &args->attrs);
444 return GSS_ERROR(major) == false;
448 * Enumerate attribute types, output is buffer set
451 gss_eap_attr_ctx::getAttributeTypes(gss_buffer_set_t *attrs)
453 eap_gss_get_attr_types_args args;
454 OM_uint32 major, minor;
458 major = gss_create_empty_buffer_set(&minor, attrs);
459 if (GSS_ERROR(major)) {
460 throw new std::bad_alloc;
466 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
467 gss_eap_attr_provider *provider = m_providers[i];
471 if (provider == NULL)
474 ret = provider->getAttributeTypes(addAttribute, (void *)&args);
480 gss_release_buffer_set(&minor, attrs);
486 * Get attribute with given name
489 gss_eap_attr_ctx::getAttribute(const gss_buffer_t attr,
493 gss_buffer_t display_value,
496 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
498 gss_eap_attr_provider *provider;
501 decomposeAttributeName(attr, &type, &suffix);
503 provider = m_providers[type];
504 if (provider == NULL)
507 ret = provider->getAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix,
508 authenticated, complete,
509 value, display_value, more);
515 * Map attribute context to C++ object
518 gss_eap_attr_ctx::mapToAny(int authenticated,
519 gss_buffer_t type_id) const
522 gss_eap_attr_provider *provider;
523 gss_buffer_desc suffix;
525 decomposeAttributeName(type_id, &type, &suffix);
527 provider = m_providers[type];
528 if (provider == NULL)
529 return (gss_any_t)NULL;
531 return provider->mapToAny(authenticated, &suffix);
535 * Release mapped context
538 gss_eap_attr_ctx::releaseAnyNameMapping(gss_buffer_t type_id,
539 gss_any_t input) const
542 gss_eap_attr_provider *provider;
543 gss_buffer_desc suffix;
545 decomposeAttributeName(type_id, &type, &suffix);
547 provider = m_providers[type];
548 if (provider != NULL)
549 provider->releaseAnyNameMapping(&suffix, input);
553 * Export attribute context to buffer
556 gss_eap_attr_ctx::exportToBuffer(gss_buffer_t buffer) const
558 const gss_eap_attr_provider *primaryProvider = getPrimaryProvider();
563 primaryProvider->exportToBuffer(&tmp);
565 buffer->length = 4 + tmp.length;
566 buffer->value = GSSEAP_MALLOC(buffer->length);
567 if (buffer->value == NULL)
568 throw new std::bad_alloc;
570 p = (unsigned char *)buffer->value;
571 store_uint32_be(m_flags, p);
572 memcpy(p + 4, tmp.value, tmp.length);
574 gss_release_buffer(&tmpMinor, &tmp);
578 * Return soonest expiry time of providers
581 gss_eap_attr_ctx::getExpiryTime(void) const
584 time_t expiryTime = 0;
586 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
587 gss_eap_attr_provider *provider = m_providers[i];
588 time_t providerExpiryTime;
590 if (provider == NULL)
593 providerExpiryTime = provider->getExpiryTime();
594 if (providerExpiryTime == 0)
597 if (expiryTime == 0 || providerExpiryTime < expiryTime)
598 expiryTime = providerExpiryTime;
605 gss_eap_attr_ctx::mapException(OM_uint32 *minor, std::exception &e) const
610 /* Errors we handle ourselves */
611 major = GSS_S_FAILURE;
613 if (typeid(e) == typeid(std::bad_alloc)) {
618 /* Errors we delegate to providers */
619 major = GSS_S_CONTINUE_NEEDED;
621 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
622 gss_eap_attr_provider *provider = m_providers[i];
624 if (provider == NULL)
627 major = provider->mapException(minor, e);
628 if (major != GSS_S_CONTINUE_NEEDED)
632 if (major == GSS_S_CONTINUE_NEEDED) {
633 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
634 major = GSS_S_FAILURE;
639 /* rethrow for now for debugging */
643 assert(GSS_ERROR(major));
649 * Decompose attribute name into prefix and suffix
652 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
659 for (i = 0; i < attribute->length; i++) {
660 if (((char *)attribute->value)[i] == ' ') {
661 p = (char *)attribute->value + i + 1;
666 prefix->value = attribute->value;
669 if (p != NULL && *p != '\0') {
670 suffix->length = attribute->length - 1 - prefix->length;
674 suffix->value = NULL;
679 * Decompose attribute name into type and suffix
682 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
686 gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER;
688 decomposeAttributeName(attribute, &prefix, suffix);
689 *type = attributePrefixToType(&prefix);
693 * Compose attribute name from prefix, suffix; returns C++ string
696 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
697 const gss_buffer_t suffix)
701 if (prefix == GSS_C_NO_BUFFER || prefix->length == 0)
704 str.append((const char *)prefix->value, prefix->length);
706 if (suffix != GSS_C_NO_BUFFER) {
708 str.append((const char *)suffix->value, suffix->length);
715 * Compose attribute name from type, suffix; returns C++ string
718 gss_eap_attr_ctx::composeAttributeName(unsigned int type,
719 const gss_buffer_t suffix)
721 const gss_buffer_t prefix = attributeTypeToPrefix(type);
723 return composeAttributeName(prefix, suffix);
727 * Compose attribute name from prefix, suffix; returns GSS buffer
730 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
731 const gss_buffer_t suffix,
732 gss_buffer_t attribute)
734 std::string str = composeAttributeName(prefix, suffix);
736 if (str.length() != 0) {
737 return duplicateBuffer(str, attribute);
739 attribute->length = 0;
740 attribute->value = NULL;
745 * Compose attribute name from type, suffix; returns GSS buffer
748 gss_eap_attr_ctx::composeAttributeName(unsigned int type,
749 const gss_buffer_t suffix,
750 gss_buffer_t attribute)
752 gss_buffer_t prefix = attributeTypeToPrefix(type);
754 return composeAttributeName(prefix, suffix, attribute);
761 gssEapInquireName(OM_uint32 *minor,
763 int *name_is_MN GSSEAP_UNUSED,
764 gss_OID *MN_mech GSSEAP_UNUSED,
765 gss_buffer_set_t *attrs)
767 if (name->attrCtx == NULL) {
768 *minor = GSSEAP_NO_ATTR_CONTEXT;
769 return GSS_S_UNAVAILABLE;
772 if (GSS_ERROR(gssEapAttrProvidersInit(minor))) {
773 return GSS_S_UNAVAILABLE;
777 if (!name->attrCtx->getAttributeTypes(attrs)) {
778 *minor = GSSEAP_NO_ATTR_CONTEXT;
779 return GSS_S_UNAVAILABLE;
781 } catch (std::exception &e) {
782 return name->attrCtx->mapException(minor, e);
785 return GSS_S_COMPLETE;
789 gssEapGetNameAttribute(OM_uint32 *minor,
795 gss_buffer_t display_value,
806 if (display_value != NULL) {
807 display_value->length = 0;
808 display_value->value = NULL;
811 if (name->attrCtx == NULL) {
812 *minor = GSSEAP_NO_ATTR_CONTEXT;
813 return GSS_S_UNAVAILABLE;
816 if (GSS_ERROR(gssEapAttrProvidersInit(minor))) {
817 return GSS_S_UNAVAILABLE;
821 if (!name->attrCtx->getAttribute(attr, authenticated, complete,
822 value, display_value, more)) {
823 *minor = GSSEAP_NO_SUCH_ATTR;
824 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
825 (int)attr->length, (char *)attr->value);
826 return GSS_S_UNAVAILABLE;
828 } catch (std::exception &e) {
829 return name->attrCtx->mapException(minor, e);
832 return GSS_S_COMPLETE;
836 gssEapDeleteNameAttribute(OM_uint32 *minor,
840 if (name->attrCtx == NULL) {
841 *minor = GSSEAP_NO_ATTR_CONTEXT;
842 return GSS_S_UNAVAILABLE;
845 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
846 return GSS_S_UNAVAILABLE;
849 if (!name->attrCtx->deleteAttribute(attr)) {
850 *minor = GSSEAP_NO_SUCH_ATTR;
851 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
852 (int)attr->length, (char *)attr->value);
853 return GSS_S_UNAVAILABLE;
855 } catch (std::exception &e) {
856 return name->attrCtx->mapException(minor, e);
859 return GSS_S_COMPLETE;
863 gssEapSetNameAttribute(OM_uint32 *minor,
869 if (name->attrCtx == NULL) {
870 *minor = GSSEAP_NO_ATTR_CONTEXT;
871 return GSS_S_UNAVAILABLE;
874 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
875 return GSS_S_UNAVAILABLE;
878 if (!name->attrCtx->setAttribute(complete, attr, value)) {
879 *minor = GSSEAP_NO_SUCH_ATTR;
880 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
881 (int)attr->length, (char *)attr->value);
882 return GSS_S_UNAVAILABLE;
884 } catch (std::exception &e) {
885 return name->attrCtx->mapException(minor, e);
888 return GSS_S_COMPLETE;
892 gssEapExportAttrContext(OM_uint32 *minor,
896 if (name->attrCtx == NULL) {
898 buffer->value = NULL;
900 return GSS_S_COMPLETE;
903 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
904 return GSS_S_UNAVAILABLE;
907 name->attrCtx->exportToBuffer(buffer);
908 } catch (std::exception &e) {
909 return name->attrCtx->mapException(minor, e);
912 return GSS_S_COMPLETE;
916 gssEapImportAttrContext(OM_uint32 *minor,
920 gss_eap_attr_ctx *ctx = NULL;
922 assert(name->attrCtx == NULL);
924 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
925 return GSS_S_UNAVAILABLE;
927 if (buffer->length != 0) {
929 ctx = new gss_eap_attr_ctx();
931 if (!ctx->initFromBuffer(buffer)) {
933 *minor = GSSEAP_BAD_ATTR_TOKEN;
934 return GSS_S_DEFECTIVE_TOKEN;
937 } catch (std::exception &e) {
939 return name->attrCtx->mapException(minor, e);
943 return GSS_S_COMPLETE;
947 gssEapDuplicateAttrContext(OM_uint32 *minor,
951 gss_eap_attr_ctx *ctx = NULL;
953 assert(out->attrCtx == NULL);
955 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
956 return GSS_S_UNAVAILABLE;
959 if (in->attrCtx != NULL) {
960 ctx = new gss_eap_attr_ctx();
961 if (!ctx->initFromExistingContext(in->attrCtx)) {
963 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
964 return GSS_S_FAILURE;
968 } catch (std::exception &e) {
970 return in->attrCtx->mapException(minor, e);
973 return GSS_S_COMPLETE;
977 gssEapMapNameToAny(OM_uint32 *minor,
980 gss_buffer_t type_id,
983 if (name->attrCtx == NULL) {
984 *minor = GSSEAP_NO_ATTR_CONTEXT;
985 return GSS_S_UNAVAILABLE;
988 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
989 return GSS_S_UNAVAILABLE;
992 *output = name->attrCtx->mapToAny(authenticated, type_id);
993 } catch (std::exception &e) {
994 return name->attrCtx->mapException(minor, e);
997 return GSS_S_COMPLETE;
1001 gssEapReleaseAnyNameMapping(OM_uint32 *minor,
1003 gss_buffer_t type_id,
1006 if (name->attrCtx == NULL) {
1007 *minor = GSSEAP_NO_ATTR_CONTEXT;
1008 return GSS_S_UNAVAILABLE;
1011 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1012 return GSS_S_UNAVAILABLE;
1016 name->attrCtx->releaseAnyNameMapping(type_id, *input);
1018 } catch (std::exception &e) {
1019 return name->attrCtx->mapException(minor, e);
1022 return GSS_S_COMPLETE;
1026 gssEapReleaseAttrContext(OM_uint32 *minor,
1029 if (name->attrCtx != NULL)
1030 delete name->attrCtx;
1033 return GSS_S_COMPLETE;
1037 * Public accessor for initialisng a context from a GSS context. Also
1038 * sets expiry time on GSS context as a side-effect.
1041 gssEapCreateAttrContext(OM_uint32 *minor,
1042 gss_cred_id_t gssCred,
1043 gss_ctx_id_t gssCtx,
1044 struct gss_eap_attr_ctx **pAttrContext,
1045 time_t *pExpiryTime)
1047 gss_eap_attr_ctx *ctx = NULL;
1050 assert(gssCtx != GSS_C_NO_CONTEXT);
1052 major = gssEapAttrProvidersInit(minor);
1053 if (GSS_ERROR(major))
1056 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1057 major = GSS_S_FAILURE;
1060 ctx = new gss_eap_attr_ctx();
1061 if (ctx->initFromGssContext(gssCred, gssCtx)) {
1063 major = GSS_S_COMPLETE;
1067 } catch (std::exception &e) {
1069 major = ctx->mapException(minor, e);
1072 if (major == GSS_S_COMPLETE) {
1073 *pAttrContext = ctx;
1074 *pExpiryTime = ctx->getExpiryTime();