initial libradsec port
[mech_eap.orig] / util_attr.cpp
index 56a0088..89296e6 100644 (file)
 #include <exception>
 #include <new>
 
+/* lazy initialisation */
+static GSSEAP_THREAD_ONCE gssEapAttrProvidersInitOnce = GSSEAP_ONCE_INITIALIZER;
+static OM_uint32 gssEapAttrProvidersInitStatus = GSS_S_UNAVAILABLE;
+
+static void
+gssEapAttrProvidersInitInternal(void)
+{
+    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(void)
+{
+    GSSEAP_ONCE(&gssEapAttrProvidersInitOnce, gssEapAttrProvidersInitInternal);
+    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];
 
@@ -683,6 +732,9 @@ gssEapInquireName(OM_uint32 *minor,
     if (name->attrCtx == NULL)
         return GSS_S_UNAVAILABLE;
 
+    if (GSS_ERROR(gssEapAttrProvidersInit()))
+        return GSS_S_UNAVAILABLE;
+
     try {
         if (!name->attrCtx->getAttributeTypes(attrs))
             return GSS_S_UNAVAILABLE;
@@ -719,6 +771,9 @@ gssEapGetNameAttribute(OM_uint32 *minor,
     if (name->attrCtx == NULL)
         return GSS_S_UNAVAILABLE;
 
+    if (GSS_ERROR(gssEapAttrProvidersInit()))
+        return GSS_S_UNAVAILABLE;
+
     try {
         if (!name->attrCtx->getAttribute(attr, authenticated, complete,
                                          value, display_value, more))
@@ -738,6 +793,9 @@ gssEapDeleteNameAttribute(OM_uint32 *minor,
     if (name->attrCtx == NULL)
         return GSS_S_UNAVAILABLE;
 
+    if (GSS_ERROR(gssEapAttrProvidersInit()))
+        return GSS_S_UNAVAILABLE;
+
     try {
         name->attrCtx->deleteAttribute(attr);
     } catch (std::exception &ex) {
@@ -757,6 +815,9 @@ gssEapSetNameAttribute(OM_uint32 *minor,
     if (name->attrCtx == NULL)
         return GSS_S_UNAVAILABLE;
 
+    if (GSS_ERROR(gssEapAttrProvidersInit()))
+        return GSS_S_UNAVAILABLE;
+
     try {
         name->attrCtx->setAttribute(complete, attr, value);
     } catch (std::exception &ex) {
@@ -778,6 +839,9 @@ gssEapExportAttrContext(OM_uint32 *minor,
         return GSS_S_COMPLETE;
     }
 
+    if (GSS_ERROR(gssEapAttrProvidersInit()))
+        return GSS_S_UNAVAILABLE;
+
     try {
         name->attrCtx->exportToBuffer(buffer);
     } catch (std::exception &e) {
@@ -796,6 +860,9 @@ gssEapImportAttrContext(OM_uint32 *minor,
 
     assert(name->attrCtx == NULL);
 
+    if (GSS_ERROR(gssEapAttrProvidersInit()))
+        return GSS_S_UNAVAILABLE;
+
     if (buffer->length != 0) {
         try {
             ctx = new gss_eap_attr_ctx();
@@ -823,6 +890,9 @@ gssEapDuplicateAttrContext(OM_uint32 *minor,
 
     assert(out->attrCtx == NULL);
 
+    if (GSS_ERROR(gssEapAttrProvidersInit()))
+        return GSS_S_UNAVAILABLE;
+
     try {
         if (in->attrCtx != NULL) {
             ctx = new gss_eap_attr_ctx();
@@ -850,6 +920,9 @@ gssEapMapNameToAny(OM_uint32 *minor,
     if (name->attrCtx == NULL)
         return GSS_S_UNAVAILABLE;
 
+    if (GSS_ERROR(gssEapAttrProvidersInit()))
+        return GSS_S_UNAVAILABLE;
+
     try {
         *output = name->attrCtx->mapToAny(authenticated, type_id);
     } catch (std::exception &e) {
@@ -868,6 +941,9 @@ gssEapReleaseAnyNameMapping(OM_uint32 *minor,
     if (name->attrCtx == NULL)
         return GSS_S_UNAVAILABLE;
 
+    if (GSS_ERROR(gssEapAttrProvidersInit()))
+        return GSS_S_UNAVAILABLE;
+
     try {
         if (*input != NULL)
             name->attrCtx->releaseAnyNameMapping(type_id, *input);
@@ -901,6 +977,9 @@ gssEapCreateAttrContext(gss_cred_id_t gssCred,
 
     assert(gssCtx != GSS_C_NO_CONTEXT);
 
+    if (GSS_ERROR(gssEapAttrProvidersInit()))
+        return NULL;
+
     ctx = new gss_eap_attr_ctx();
     if (!ctx->initFromGssContext(gssCred, gssCtx)) {
         delete ctx;