+ OM_uint32 major, minor;
+
+ assert(gssEapAttrProvidersInitStatus == GSS_S_UNAVAILABLE);
+
+ major = gssEapRadiusAttrProviderInit(&minor);
+ if (major == GSS_S_COMPLETE)
+ major = gssEapSamlAttrProvidersInit(&minor);
+ if (major == GSS_S_COMPLETE)
+ major = gssEapLocalAttrProviderInit(&minor);
+
+#ifdef GSSEAP_DEBUG
+ assert(major == GSS_S_COMPLETE);
+#endif
+
+ gssEapAttrProvidersInitStatus = major;
+}
+
+static OM_uint32
+gssEapAttrProvidersInit(OM_uint32 *minor)
+{
+ GSSEAP_ONCE(&gssEapAttrProvidersInitOnce, gssEapAttrProvidersInitInternal);
+
+ if (GSS_ERROR(gssEapAttrProvidersInitStatus))
+ *minor = GSSEAP_NO_ATTR_PROVIDERS;
+
+ return gssEapAttrProvidersInitStatus;
+}
+
+OM_uint32
+gssEapAttrProvidersFinalize(OM_uint32 *minor)
+{
+ OM_uint32 major = GSS_S_COMPLETE;
+
+ if (gssEapAttrProvidersInitStatus == GSS_S_COMPLETE) {
+ major = gssEapLocalAttrProviderFinalize(minor);
+ if (major == GSS_S_COMPLETE)
+ major = gssEapSamlAttrProvidersFinalize(minor);
+ if (major == GSS_S_COMPLETE)
+ major = gssEapRadiusAttrProviderFinalize(minor);
+
+ gssEapAttrProvidersInitStatus = GSS_S_UNAVAILABLE;
+ }
+
+ return major;
+}
+
+static gss_eap_attr_create_provider gssEapAttrFactories[ATTR_TYPE_MAX + 1];
+static gss_buffer_desc gssEapAttrPrefixes[ATTR_TYPE_MAX + 1];
+
+/*
+ * Register a provider for a particular type and prefix
+ */
+void
+gss_eap_attr_ctx::registerProvider(unsigned int type,
+ const char *prefix,
+ gss_eap_attr_create_provider factory)
+{
+ assert(type <= ATTR_TYPE_MAX);
+
+ assert(gssEapAttrFactories[type] == NULL);
+
+ gssEapAttrFactories[type] = factory;
+ if (prefix != NULL) {
+ gssEapAttrPrefixes[type].value = (void *)prefix;
+ gssEapAttrPrefixes[type].length = strlen(prefix);
+ } else {
+ gssEapAttrPrefixes[type].value = NULL;
+ gssEapAttrPrefixes[type].length = 0;
+ }
+}
+
+/*
+ * Unregister a provider
+ */
+void
+gss_eap_attr_ctx::unregisterProvider(unsigned int type)
+{
+ assert(type <= ATTR_TYPE_MAX);
+
+ gssEapAttrFactories[type] = NULL;
+ gssEapAttrPrefixes[type].value = NULL;
+ gssEapAttrPrefixes[type].length = 0;
+}