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;
50 gssEapAttrProvidersInitInternal(void)
52 OM_uint32 major, minor;
54 assert(gssEapAttrProvidersInitStatus == GSS_S_UNAVAILABLE);
56 major = gssEapRadiusAttrProviderInit(&minor);
60 major = gssEapSamlAttrProvidersInit(&minor);
64 /* Allow Shibboleth initialization failure to be non-fatal */
65 gssEapLocalAttrProviderInit(&minor);
69 assert(major == GSS_S_COMPLETE);
72 gssEapAttrProvidersInitStatus = major;
76 gssEapAttrProvidersInit(OM_uint32 *minor)
78 GSSEAP_ONCE(&gssEapAttrProvidersInitOnce, gssEapAttrProvidersInitInternal);
80 if (GSS_ERROR(gssEapAttrProvidersInitStatus))
81 *minor = GSSEAP_NO_ATTR_PROVIDERS;
83 return gssEapAttrProvidersInitStatus;
87 gssEapAttrProvidersFinalize(OM_uint32 *minor)
89 OM_uint32 major = GSS_S_COMPLETE;
91 if (gssEapAttrProvidersInitStatus == GSS_S_COMPLETE) {
92 major = gssEapLocalAttrProviderFinalize(minor);
93 if (major == GSS_S_COMPLETE)
94 major = gssEapSamlAttrProvidersFinalize(minor);
95 if (major == GSS_S_COMPLETE)
96 major = gssEapRadiusAttrProviderFinalize(minor);
98 gssEapAttrProvidersInitStatus = GSS_S_UNAVAILABLE;
104 static gss_eap_attr_create_provider gssEapAttrFactories[ATTR_TYPE_MAX + 1];
107 * Register a provider for a particular type and prefix
110 gss_eap_attr_ctx::registerProvider(unsigned int type,
111 gss_eap_attr_create_provider factory)
113 assert(type <= ATTR_TYPE_MAX);
115 assert(gssEapAttrFactories[type] == NULL);
117 gssEapAttrFactories[type] = factory;
121 * Unregister a provider
124 gss_eap_attr_ctx::unregisterProvider(unsigned int type)
126 assert(type <= ATTR_TYPE_MAX);
128 gssEapAttrFactories[type] = NULL;
132 * Create an attribute context, that manages instances of providers
134 gss_eap_attr_ctx::gss_eap_attr_ctx(void)
138 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
139 gss_eap_attr_provider *provider;
141 if (gssEapAttrFactories[i] != NULL) {
142 provider = (gssEapAttrFactories[i])();
147 m_providers[i] = provider;
152 * Convert an attribute prefix to a type
155 gss_eap_attr_ctx::attributePrefixToType(const gss_buffer_t prefix) const
159 for (i = ATTR_TYPE_MIN; i < ATTR_TYPE_MAX; i++) {
162 if (!providerEnabled(i))
165 pprefix = m_providers[i]->prefix();
169 if (strlen(pprefix) == prefix->length &&
170 memcmp(pprefix, prefix->value, prefix->length) == 0)
174 return ATTR_TYPE_LOCAL;
178 * Convert a type to an attribute prefix
181 gss_eap_attr_ctx::attributeTypeToPrefix(unsigned int type) const
183 gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER;
185 if (type < ATTR_TYPE_MIN || type >= ATTR_TYPE_MAX)
188 if (!providerEnabled(type))
191 prefix.value = (void *)m_providers[type]->prefix();
192 if (prefix.value != NULL)
193 prefix.length = strlen((char *)prefix.value);
199 gss_eap_attr_ctx::providerEnabled(unsigned int type) const
201 if (type == ATTR_TYPE_LOCAL &&
202 (m_flags & ATTR_FLAG_DISABLE_LOCAL))
205 if (m_providers[type] == NULL)
212 gss_eap_attr_ctx::releaseProvider(unsigned int type)
214 delete m_providers[type];
215 m_providers[type] = NULL;
219 * Initialize a context from an existing context.
222 gss_eap_attr_ctx::initWithExistingContext(const gss_eap_attr_ctx *manager)
226 m_flags = manager->m_flags;
228 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
229 gss_eap_attr_provider *provider;
231 if (!providerEnabled(i)) {
236 provider = m_providers[i];
238 ret = provider->initWithExistingContext(this,
239 manager->m_providers[i]);
250 * Initialize a context from a GSS credential and context.
253 gss_eap_attr_ctx::initWithGssContext(const gss_cred_id_t cred,
254 const gss_ctx_id_t ctx)
258 if (cred != GSS_C_NO_CREDENTIAL &&
259 (cred->flags & GSS_EAP_DISABLE_LOCAL_ATTRS_FLAG)) {
260 m_flags |= ATTR_FLAG_DISABLE_LOCAL;
263 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
264 gss_eap_attr_provider *provider;
266 if (!providerEnabled(i)) {
271 provider = m_providers[i];
273 ret = provider->initWithGssContext(this, cred, ctx);
284 gss_eap_attr_ctx::initWithJsonObject(JSONObject &obj)
287 bool foundSource[ATTR_TYPE_MAX + 1];
290 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++)
291 foundSource[type] = false;
293 if (obj["version"].integer() != 1)
296 m_flags = obj["flags"].integer();
298 JSONObject sources = obj["sources"];
300 /* Initialize providers from serialized state */
301 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
302 gss_eap_attr_provider *provider;
305 if (!providerEnabled(type)) {
306 releaseProvider(type);
310 provider = m_providers[type];
311 key = provider->name();
315 JSONObject source = sources.get(key);
316 if (!source.isNull() &&
317 !provider->initWithJsonObject(this, source)) {
318 releaseProvider(type);
322 foundSource[type] = true;
325 /* Initialize remaining providers from initialized providers */
326 for (type = ATTR_TYPE_MIN; type <= ATTR_TYPE_MAX; type++) {
327 gss_eap_attr_provider *provider;
329 if (foundSource[type] || !providerEnabled(type))
332 provider = m_providers[type];
334 ret = provider->initWithGssContext(this,
338 releaseProvider(type);
347 gss_eap_attr_ctx::jsonRepresentation(void) const
349 JSONObject obj, sources;
352 obj.set("version", 1);
353 obj.set("flags", m_flags);
355 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
356 gss_eap_attr_provider *provider;
359 provider = m_providers[i];
360 if (provider == NULL)
361 continue; /* provider not initialised */
363 key = provider->name();
365 continue; /* provider does not have state */
367 JSONObject source = provider->jsonRepresentation();
368 sources.set(key, source);
371 obj.set("sources", sources);
377 * Initialize a context from an exported context or name token
380 gss_eap_attr_ctx::initWithBuffer(const gss_buffer_t buffer)
382 OM_uint32 major, minor;
387 major = bufferToString(&minor, buffer, &s);
388 if (GSS_ERROR(major))
391 JSONObject obj = JSONObject::load(s, 0, &error);
393 ret = initWithJsonObject(obj);
402 gss_eap_attr_ctx::~gss_eap_attr_ctx(void)
404 for (unsigned int i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++)
405 delete m_providers[i];
409 * Locate provider for a given type
411 gss_eap_attr_provider *
412 gss_eap_attr_ctx::getProvider(unsigned int type) const
414 assert(type >= ATTR_TYPE_MIN && type <= ATTR_TYPE_MAX);
415 return m_providers[type];
419 * Get primary provider. Only the primary provider is serialised when
420 * gss_export_sec_context() or gss_export_name_composite() is called.
422 gss_eap_attr_provider *
423 gss_eap_attr_ctx::getPrimaryProvider(void) const
425 return m_providers[ATTR_TYPE_MIN];
432 gss_eap_attr_ctx::setAttribute(int complete,
433 const gss_buffer_t attr,
434 const gss_buffer_t value)
436 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
438 gss_eap_attr_provider *provider;
441 decomposeAttributeName(attr, &type, &suffix);
443 provider = m_providers[type];
444 if (provider != NULL) {
445 ret = provider->setAttribute(complete,
446 (type == ATTR_TYPE_LOCAL) ? attr : &suffix,
454 * Delete an attrbiute
457 gss_eap_attr_ctx::deleteAttribute(const gss_buffer_t attr)
459 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
461 gss_eap_attr_provider *provider;
464 decomposeAttributeName(attr, &type, &suffix);
466 provider = m_providers[type];
467 if (provider != NULL) {
468 ret = provider->deleteAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix);
475 * Enumerate attribute types with callback
478 gss_eap_attr_ctx::getAttributeTypes(gss_eap_attr_enumeration_cb cb, void *data) const
483 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
484 gss_eap_attr_provider *provider = m_providers[i];
486 if (provider == NULL)
489 ret = provider->getAttributeTypes(cb, data);
497 struct eap_gss_get_attr_types_args {
499 gss_buffer_set_t attrs;
503 addAttribute(const gss_eap_attr_ctx *manager,
504 const gss_eap_attr_provider *provider GSSEAP_UNUSED,
505 const gss_buffer_t attribute,
508 eap_gss_get_attr_types_args *args = (eap_gss_get_attr_types_args *)data;
509 gss_buffer_desc qualified;
510 OM_uint32 major, minor;
512 if (args->type != ATTR_TYPE_LOCAL) {
513 manager->composeAttributeName(args->type, attribute, &qualified);
514 major = gss_add_buffer_set_member(&minor, &qualified, &args->attrs);
515 gss_release_buffer(&minor, &qualified);
517 major = gss_add_buffer_set_member(&minor, attribute, &args->attrs);
520 return GSS_ERROR(major) == false;
524 * Enumerate attribute types, output is buffer set
527 gss_eap_attr_ctx::getAttributeTypes(gss_buffer_set_t *attrs)
529 eap_gss_get_attr_types_args args;
530 OM_uint32 major, minor;
534 major = gss_create_empty_buffer_set(&minor, attrs);
535 if (GSS_ERROR(major))
536 throw std::bad_alloc();
540 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
541 gss_eap_attr_provider *provider = m_providers[i];
545 if (provider == NULL)
548 ret = provider->getAttributeTypes(addAttribute, (void *)&args);
554 gss_release_buffer_set(&minor, attrs);
560 * Get attribute with given name
563 gss_eap_attr_ctx::getAttribute(const gss_buffer_t attr,
567 gss_buffer_t display_value,
570 gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
572 gss_eap_attr_provider *provider;
575 decomposeAttributeName(attr, &type, &suffix);
577 provider = m_providers[type];
578 if (provider == NULL)
581 ret = provider->getAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix,
582 authenticated, complete,
583 value, display_value, more);
589 * Map attribute context to C++ object
592 gss_eap_attr_ctx::mapToAny(int authenticated,
593 gss_buffer_t type_id) const
596 gss_eap_attr_provider *provider;
597 gss_buffer_desc suffix;
599 decomposeAttributeName(type_id, &type, &suffix);
601 provider = m_providers[type];
602 if (provider == NULL)
603 return (gss_any_t)NULL;
605 return provider->mapToAny(authenticated, &suffix);
609 * Release mapped context
612 gss_eap_attr_ctx::releaseAnyNameMapping(gss_buffer_t type_id,
613 gss_any_t input) const
616 gss_eap_attr_provider *provider;
617 gss_buffer_desc suffix;
619 decomposeAttributeName(type_id, &type, &suffix);
621 provider = m_providers[type];
622 if (provider != NULL)
623 provider->releaseAnyNameMapping(&suffix, input);
627 * Export attribute context to buffer
630 gss_eap_attr_ctx::exportToBuffer(gss_buffer_t buffer) const
635 JSONObject obj = jsonRepresentation();
641 s = obj.dump(JSON_COMPACT);
643 if (GSS_ERROR(makeStringBuffer(&minor, s, buffer)))
644 throw std::bad_alloc();
648 * Return soonest expiry time of providers
651 gss_eap_attr_ctx::getExpiryTime(void) const
654 time_t expiryTime = 0;
656 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
657 gss_eap_attr_provider *provider = m_providers[i];
658 time_t providerExpiryTime;
660 if (provider == NULL)
663 providerExpiryTime = provider->getExpiryTime();
664 if (providerExpiryTime == 0)
667 if (expiryTime == 0 || providerExpiryTime < expiryTime)
668 expiryTime = providerExpiryTime;
675 gss_eap_attr_ctx::mapException(OM_uint32 *minor, std::exception &e) const
680 /* Errors we handle ourselves */
681 if (typeid(e) == typeid(std::bad_alloc)) {
682 major = GSS_S_FAILURE;
685 } else if (typeid(e) == typeid(JSONException)) {
686 major = GSS_S_BAD_NAME;
687 *minor = GSSEAP_BAD_ATTR_TOKEN;
688 gssEapSaveStatusInfo(*minor, "%s", e.what());
692 /* Errors we delegate to providers */
693 major = GSS_S_CONTINUE_NEEDED;
695 for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
696 gss_eap_attr_provider *provider = m_providers[i];
698 if (provider == NULL)
701 major = provider->mapException(minor, e);
702 if (major != GSS_S_CONTINUE_NEEDED)
706 if (major == GSS_S_CONTINUE_NEEDED) {
707 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
708 major = GSS_S_FAILURE;
712 assert(GSS_ERROR(major));
718 * Decompose attribute name into prefix and suffix
721 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
728 for (i = 0; i < attribute->length; i++) {
729 if (((char *)attribute->value)[i] == ' ') {
730 p = (char *)attribute->value + i + 1;
735 prefix->value = attribute->value;
738 if (p != NULL && *p != '\0') {
739 suffix->length = attribute->length - 1 - prefix->length;
743 suffix->value = NULL;
748 * Decompose attribute name into type and suffix
751 gss_eap_attr_ctx::decomposeAttributeName(const gss_buffer_t attribute,
753 gss_buffer_t suffix) const
755 gss_buffer_desc prefix = GSS_C_EMPTY_BUFFER;
757 decomposeAttributeName(attribute, &prefix, suffix);
758 *type = attributePrefixToType(&prefix);
762 * Compose attribute name from prefix, suffix; returns C++ string
765 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
766 const gss_buffer_t suffix)
770 if (prefix == GSS_C_NO_BUFFER || prefix->length == 0)
773 str.append((const char *)prefix->value, prefix->length);
775 if (suffix != GSS_C_NO_BUFFER) {
777 str.append((const char *)suffix->value, suffix->length);
784 * Compose attribute name from type, suffix; returns C++ string
787 gss_eap_attr_ctx::composeAttributeName(unsigned int type,
788 const gss_buffer_t suffix)
790 gss_buffer_desc prefix = attributeTypeToPrefix(type);
792 return composeAttributeName(&prefix, suffix);
796 * Compose attribute name from prefix, suffix; returns GSS buffer
799 gss_eap_attr_ctx::composeAttributeName(const gss_buffer_t prefix,
800 const gss_buffer_t suffix,
801 gss_buffer_t attribute)
803 std::string str = composeAttributeName(prefix, suffix);
805 if (str.length() != 0) {
806 return duplicateBuffer(str, attribute);
808 attribute->length = 0;
809 attribute->value = NULL;
814 * Compose attribute name from type, suffix; returns GSS buffer
817 gss_eap_attr_ctx::composeAttributeName(unsigned int type,
818 const gss_buffer_t suffix,
819 gss_buffer_t attribute) const
821 gss_buffer_desc prefix = attributeTypeToPrefix(type);
823 return composeAttributeName(&prefix, suffix, attribute);
830 gssEapInquireName(OM_uint32 *minor,
834 gss_buffer_set_t *attrs)
838 if (name_is_MN != NULL)
839 *name_is_MN = (name->mechanismUsed != GSS_C_NULL_OID);
841 if (MN_mech != NULL) {
842 major = gssEapCanonicalizeOid(minor, name->mechanismUsed,
843 OID_FLAG_NULL_VALID, MN_mech);
844 if (GSS_ERROR(major))
848 if (name->attrCtx == NULL) {
849 *minor = GSSEAP_NO_ATTR_CONTEXT;
850 return GSS_S_UNAVAILABLE;
853 if (GSS_ERROR(gssEapAttrProvidersInit(minor))) {
854 return GSS_S_UNAVAILABLE;
859 if (!name->attrCtx->getAttributeTypes(attrs)) {
860 *minor = GSSEAP_NO_ATTR_CONTEXT;
861 return GSS_S_UNAVAILABLE;
863 } catch (std::exception &e) {
864 return name->attrCtx->mapException(minor, e);
868 return GSS_S_COMPLETE;
872 gssEapGetNameAttribute(OM_uint32 *minor,
878 gss_buffer_t display_value,
881 if (authenticated != NULL)
883 if (complete != NULL)
891 if (display_value != NULL) {
892 display_value->length = 0;
893 display_value->value = NULL;
896 if (name->attrCtx == NULL) {
897 *minor = GSSEAP_NO_ATTR_CONTEXT;
898 return GSS_S_UNAVAILABLE;
901 if (GSS_ERROR(gssEapAttrProvidersInit(minor))) {
902 return GSS_S_UNAVAILABLE;
906 if (!name->attrCtx->getAttribute(attr, authenticated, complete,
907 value, display_value, more)) {
908 *minor = GSSEAP_NO_SUCH_ATTR;
909 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
910 (int)attr->length, (char *)attr->value);
911 return GSS_S_UNAVAILABLE;
913 } catch (std::exception &e) {
914 return name->attrCtx->mapException(minor, e);
917 return GSS_S_COMPLETE;
921 gssEapDeleteNameAttribute(OM_uint32 *minor,
925 if (name->attrCtx == NULL) {
926 *minor = GSSEAP_NO_ATTR_CONTEXT;
927 return GSS_S_UNAVAILABLE;
930 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
931 return GSS_S_UNAVAILABLE;
934 if (!name->attrCtx->deleteAttribute(attr)) {
935 *minor = GSSEAP_NO_SUCH_ATTR;
936 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
937 (int)attr->length, (char *)attr->value);
938 return GSS_S_UNAVAILABLE;
940 } catch (std::exception &e) {
941 return name->attrCtx->mapException(minor, e);
944 return GSS_S_COMPLETE;
948 gssEapSetNameAttribute(OM_uint32 *minor,
954 if (name->attrCtx == NULL) {
955 *minor = GSSEAP_NO_ATTR_CONTEXT;
956 return GSS_S_UNAVAILABLE;
959 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
960 return GSS_S_UNAVAILABLE;
963 if (!name->attrCtx->setAttribute(complete, attr, value)) {
964 *minor = GSSEAP_NO_SUCH_ATTR;
965 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
966 (int)attr->length, (char *)attr->value);
967 return GSS_S_UNAVAILABLE;
969 } catch (std::exception &e) {
970 return name->attrCtx->mapException(minor, e);
973 return GSS_S_COMPLETE;
977 gssEapExportAttrContext(OM_uint32 *minor,
981 if (name->attrCtx == NULL) {
983 buffer->value = NULL;
985 return GSS_S_COMPLETE;
988 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
989 return GSS_S_UNAVAILABLE;
992 name->attrCtx->exportToBuffer(buffer);
993 } catch (std::exception &e) {
994 return name->attrCtx->mapException(minor, e);
997 return GSS_S_COMPLETE;
1001 gssEapImportAttrContext(OM_uint32 *minor,
1002 gss_buffer_t buffer,
1005 gss_eap_attr_ctx *ctx = NULL;
1006 OM_uint32 major = GSS_S_FAILURE;
1008 assert(name->attrCtx == NULL);
1010 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1011 return GSS_S_UNAVAILABLE;
1013 if (buffer->length == 0)
1014 return GSS_S_COMPLETE;
1017 ctx = new gss_eap_attr_ctx();
1019 if (ctx->initWithBuffer(buffer)) {
1020 name->attrCtx = ctx;
1021 major = GSS_S_COMPLETE;
1024 major = GSS_S_BAD_NAME;
1025 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1027 } catch (std::exception &e) {
1029 major = ctx->mapException(minor, e);
1032 assert(major == GSS_S_COMPLETE || name->attrCtx == NULL);
1034 if (GSS_ERROR(major))
1041 gssEapDuplicateAttrContext(OM_uint32 *minor,
1045 gss_eap_attr_ctx *ctx = NULL;
1046 OM_uint32 major = GSS_S_FAILURE;
1048 assert(out->attrCtx == NULL);
1050 if (in->attrCtx == NULL) {
1052 return GSS_S_COMPLETE;
1055 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1056 return GSS_S_UNAVAILABLE;
1059 ctx = new gss_eap_attr_ctx();
1061 if (ctx->initWithExistingContext(in->attrCtx)) {
1063 major = GSS_S_COMPLETE;
1066 major = GSS_S_FAILURE;
1067 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1069 } catch (std::exception &e) {
1070 major = in->attrCtx->mapException(minor, e);
1073 assert(major == GSS_S_COMPLETE || out->attrCtx == NULL);
1075 if (GSS_ERROR(major))
1078 return GSS_S_COMPLETE;
1082 gssEapMapNameToAny(OM_uint32 *minor,
1085 gss_buffer_t type_id,
1088 if (name->attrCtx == NULL) {
1089 *minor = GSSEAP_NO_ATTR_CONTEXT;
1090 return GSS_S_UNAVAILABLE;
1093 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1094 return GSS_S_UNAVAILABLE;
1097 *output = name->attrCtx->mapToAny(authenticated, type_id);
1098 } catch (std::exception &e) {
1099 return name->attrCtx->mapException(minor, e);
1102 return GSS_S_COMPLETE;
1106 gssEapReleaseAnyNameMapping(OM_uint32 *minor,
1108 gss_buffer_t type_id,
1111 if (name->attrCtx == NULL) {
1112 *minor = GSSEAP_NO_ATTR_CONTEXT;
1113 return GSS_S_UNAVAILABLE;
1116 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1117 return GSS_S_UNAVAILABLE;
1121 name->attrCtx->releaseAnyNameMapping(type_id, *input);
1123 } catch (std::exception &e) {
1124 return name->attrCtx->mapException(minor, e);
1127 return GSS_S_COMPLETE;
1131 gssEapReleaseAttrContext(OM_uint32 *minor,
1134 if (name->attrCtx != NULL)
1135 delete name->attrCtx;
1138 return GSS_S_COMPLETE;
1142 * Public accessor for initialisng a context from a GSS context. Also
1143 * sets expiry time on GSS context as a side-effect.
1146 gssEapCreateAttrContext(OM_uint32 *minor,
1147 gss_cred_id_t gssCred,
1148 gss_ctx_id_t gssCtx,
1149 struct gss_eap_attr_ctx **pAttrContext,
1150 time_t *pExpiryTime)
1152 gss_eap_attr_ctx *ctx = NULL;
1155 assert(gssCtx != GSS_C_NO_CONTEXT);
1157 *pAttrContext = NULL;
1159 major = gssEapAttrProvidersInit(minor);
1160 if (GSS_ERROR(major))
1164 /* Set *pAttrContext here to for reentrancy */
1165 *pAttrContext = ctx = new gss_eap_attr_ctx();
1167 if (ctx->initWithGssContext(gssCred, gssCtx)) {
1168 *pExpiryTime = ctx->getExpiryTime();
1169 major = GSS_S_COMPLETE;
1172 major = GSS_S_FAILURE;
1173 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1175 } catch (std::exception &e) {
1177 major = ctx->mapException(minor, e);
1180 if (GSS_ERROR(major)) {
1182 *pAttrContext = NULL;