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;
858 if (!name->attrCtx->getAttributeTypes(attrs)) {
859 *minor = GSSEAP_NO_ATTR_CONTEXT;
860 return GSS_S_UNAVAILABLE;
862 } catch (std::exception &e) {
863 return name->attrCtx->mapException(minor, e);
866 return GSS_S_COMPLETE;
870 gssEapGetNameAttribute(OM_uint32 *minor,
876 gss_buffer_t display_value,
879 if (authenticated != NULL)
881 if (complete != NULL)
889 if (display_value != NULL) {
890 display_value->length = 0;
891 display_value->value = NULL;
894 if (name->attrCtx == NULL) {
895 *minor = GSSEAP_NO_ATTR_CONTEXT;
896 return GSS_S_UNAVAILABLE;
899 if (GSS_ERROR(gssEapAttrProvidersInit(minor))) {
900 return GSS_S_UNAVAILABLE;
904 if (!name->attrCtx->getAttribute(attr, authenticated, complete,
905 value, display_value, more)) {
906 *minor = GSSEAP_NO_SUCH_ATTR;
907 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
908 (int)attr->length, (char *)attr->value);
909 return GSS_S_UNAVAILABLE;
911 } catch (std::exception &e) {
912 return name->attrCtx->mapException(minor, e);
915 return GSS_S_COMPLETE;
919 gssEapDeleteNameAttribute(OM_uint32 *minor,
923 if (name->attrCtx == NULL) {
924 *minor = GSSEAP_NO_ATTR_CONTEXT;
925 return GSS_S_UNAVAILABLE;
928 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
929 return GSS_S_UNAVAILABLE;
932 if (!name->attrCtx->deleteAttribute(attr)) {
933 *minor = GSSEAP_NO_SUCH_ATTR;
934 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
935 (int)attr->length, (char *)attr->value);
936 return GSS_S_UNAVAILABLE;
938 } catch (std::exception &e) {
939 return name->attrCtx->mapException(minor, e);
942 return GSS_S_COMPLETE;
946 gssEapSetNameAttribute(OM_uint32 *minor,
952 if (name->attrCtx == NULL) {
953 *minor = GSSEAP_NO_ATTR_CONTEXT;
954 return GSS_S_UNAVAILABLE;
957 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
958 return GSS_S_UNAVAILABLE;
961 if (!name->attrCtx->setAttribute(complete, attr, value)) {
962 *minor = GSSEAP_NO_SUCH_ATTR;
963 gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
964 (int)attr->length, (char *)attr->value);
965 return GSS_S_UNAVAILABLE;
967 } catch (std::exception &e) {
968 return name->attrCtx->mapException(minor, e);
971 return GSS_S_COMPLETE;
975 gssEapExportAttrContext(OM_uint32 *minor,
979 if (name->attrCtx == NULL) {
981 buffer->value = NULL;
983 return GSS_S_COMPLETE;
986 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
987 return GSS_S_UNAVAILABLE;
990 name->attrCtx->exportToBuffer(buffer);
991 } catch (std::exception &e) {
992 return name->attrCtx->mapException(minor, e);
995 return GSS_S_COMPLETE;
999 gssEapImportAttrContext(OM_uint32 *minor,
1000 gss_buffer_t buffer,
1003 gss_eap_attr_ctx *ctx = NULL;
1004 OM_uint32 major = GSS_S_FAILURE;
1006 assert(name->attrCtx == NULL);
1008 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1009 return GSS_S_UNAVAILABLE;
1011 if (buffer->length == 0)
1012 return GSS_S_COMPLETE;
1015 ctx = new gss_eap_attr_ctx();
1017 if (ctx->initWithBuffer(buffer)) {
1018 name->attrCtx = ctx;
1019 major = GSS_S_COMPLETE;
1022 major = GSS_S_BAD_NAME;
1023 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1025 } catch (std::exception &e) {
1027 major = ctx->mapException(minor, e);
1030 assert(major == GSS_S_COMPLETE || name->attrCtx == NULL);
1032 if (GSS_ERROR(major))
1039 gssEapDuplicateAttrContext(OM_uint32 *minor,
1043 gss_eap_attr_ctx *ctx = NULL;
1044 OM_uint32 major = GSS_S_FAILURE;
1046 assert(out->attrCtx == NULL);
1048 if (in->attrCtx == NULL) {
1050 return GSS_S_COMPLETE;
1053 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1054 return GSS_S_UNAVAILABLE;
1057 ctx = new gss_eap_attr_ctx();
1059 if (ctx->initWithExistingContext(in->attrCtx)) {
1061 major = GSS_S_COMPLETE;
1064 major = GSS_S_FAILURE;
1065 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1067 } catch (std::exception &e) {
1068 major = in->attrCtx->mapException(minor, e);
1071 assert(major == GSS_S_COMPLETE || out->attrCtx == NULL);
1073 if (GSS_ERROR(major))
1076 return GSS_S_COMPLETE;
1080 gssEapMapNameToAny(OM_uint32 *minor,
1083 gss_buffer_t type_id,
1086 if (name->attrCtx == NULL) {
1087 *minor = GSSEAP_NO_ATTR_CONTEXT;
1088 return GSS_S_UNAVAILABLE;
1091 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1092 return GSS_S_UNAVAILABLE;
1095 *output = name->attrCtx->mapToAny(authenticated, type_id);
1096 } catch (std::exception &e) {
1097 return name->attrCtx->mapException(minor, e);
1100 return GSS_S_COMPLETE;
1104 gssEapReleaseAnyNameMapping(OM_uint32 *minor,
1106 gss_buffer_t type_id,
1109 if (name->attrCtx == NULL) {
1110 *minor = GSSEAP_NO_ATTR_CONTEXT;
1111 return GSS_S_UNAVAILABLE;
1114 if (GSS_ERROR(gssEapAttrProvidersInit(minor)))
1115 return GSS_S_UNAVAILABLE;
1119 name->attrCtx->releaseAnyNameMapping(type_id, *input);
1121 } catch (std::exception &e) {
1122 return name->attrCtx->mapException(minor, e);
1125 return GSS_S_COMPLETE;
1129 gssEapReleaseAttrContext(OM_uint32 *minor,
1132 if (name->attrCtx != NULL)
1133 delete name->attrCtx;
1136 return GSS_S_COMPLETE;
1140 * Public accessor for initialisng a context from a GSS context. Also
1141 * sets expiry time on GSS context as a side-effect.
1144 gssEapCreateAttrContext(OM_uint32 *minor,
1145 gss_cred_id_t gssCred,
1146 gss_ctx_id_t gssCtx,
1147 struct gss_eap_attr_ctx **pAttrContext,
1148 time_t *pExpiryTime)
1150 gss_eap_attr_ctx *ctx = NULL;
1153 assert(gssCtx != GSS_C_NO_CONTEXT);
1155 *pAttrContext = NULL;
1157 major = gssEapAttrProvidersInit(minor);
1158 if (GSS_ERROR(major))
1162 /* Set *pAttrContext here to for reentrancy */
1163 *pAttrContext = ctx = new gss_eap_attr_ctx();
1165 if (ctx->initWithGssContext(gssCred, gssCtx)) {
1166 *pExpiryTime = ctx->getExpiryTime();
1167 major = GSS_S_COMPLETE;
1170 major = GSS_S_FAILURE;
1171 *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
1173 } catch (std::exception &e) {
1175 major = ctx->mapException(minor, e);
1178 if (GSS_ERROR(major)) {
1180 *pAttrContext = NULL;