use JSON instead of DDF marshalling
[mech_eap.git] / util_attr.h
index abdcb99..1a427f7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, JANET(UK)
+ * Copyright (c) 2011, JANET(UK)
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * SUCH DAMAGE.
  */
 
+/*
+ * Attribute provider interface.
+ */
+
 #ifndef _UTIL_ATTR_H_
 #define _UTIL_ATTR_H_ 1
 
-#define ATTR_TYPE_RADIUS            0U
-#define ATTR_TYPE_SAML_ASSERTION    1U
-#define ATTR_TYPE_SAML              2U
-#define ATTR_TYPE_LOCAL             3U
-#define ATTR_TYPE_MIN               ATTR_TYPE_RADIUS
-#define ATTR_TYPE_MAX               (ATTR_TYPE_LOCAL + 1U)
-
 #ifdef __cplusplus
+#include <string>
+#include <new>
+
+#include <jansson.h>
+
+struct gss_eap_attr_provider;
 struct gss_eap_attr_ctx;
 
+typedef bool
+(*gss_eap_attr_enumeration_cb)(const gss_eap_attr_ctx *ctx,
+                               const gss_eap_attr_provider *source,
+                               const gss_buffer_t attribute,
+                               void *data);
+
+#define ATTR_TYPE_RADIUS            0U                  /* RADIUS AVPs */
+#define ATTR_TYPE_SAML_ASSERTION    1U                  /* SAML assertion */
+#define ATTR_TYPE_SAML              2U                  /* SAML attributes */
+#define ATTR_TYPE_LOCAL             3U                  /* Local attributes */
+#define ATTR_TYPE_MIN               ATTR_TYPE_RADIUS
+#define ATTR_TYPE_MAX               ATTR_TYPE_LOCAL
+
+#define ATTR_FLAG_DISABLE_LOCAL     0x00000001
+
+/*
+ * Attribute provider: this represents a source of attributes derived
+ * from the security context.
+ */
 struct gss_eap_attr_provider
 {
 public:
-    gss_eap_attr_provider(const gss_eap_attr_ctx *ctx,
-                          gss_cred_id_t acceptorCred = GSS_C_NO_CREDENTIAL,
-                          gss_ctx_id_t acceptorCtx = GSS_C_NO_CONTEXT)
+    gss_eap_attr_provider(void) {}
+    virtual ~gss_eap_attr_provider(void) {}
+
+    bool initWithManager(const gss_eap_attr_ctx *manager)
     {
-        m_source = ctx;
+        m_manager = manager;
+        return true;
     }
 
-    gss_eap_attr_provider(const gss_eap_attr_provider &ctx) {}
-    virtual ~gss_eap_attr_provider(void) {}
+    virtual bool initFromExistingContext(const gss_eap_attr_ctx *manager,
+                                         const gss_eap_attr_provider *ctx GSSEAP_UNUSED)
+    {
+        return initWithManager(manager);
+    }
+
+    virtual bool initFromGssContext(const gss_eap_attr_ctx *manager,
+                                    const gss_cred_id_t cred GSSEAP_UNUSED,
+                                    const gss_ctx_id_t ctx GSSEAP_UNUSED)
+    {
+        return initWithManager(manager);
+    }
 
-    typedef bool
-    gss_eap_attr_enumeration_cb(const gss_eap_attr_provider *provider,
-                                const gss_buffer_t attribute,
-                                void *data);
+    virtual bool getAttributeTypes(gss_eap_attr_enumeration_cb GSSEAP_UNUSED,
+                                   void *data GSSEAP_UNUSED) const
+    {
+        return false;
+    }
+
+    virtual bool setAttribute(int complete GSSEAP_UNUSED,
+                              const gss_buffer_t attr GSSEAP_UNUSED,
+                              const gss_buffer_t value GSSEAP_UNUSED)
+    {
+        return false;
+    }
+
+    virtual bool deleteAttribute(const gss_buffer_t value GSSEAP_UNUSED)
+    {
+        return false;
+    }
 
-    virtual bool getAttributeTypes(gss_eap_attr_enumeration_cb, void *data) const
+    virtual bool getAttribute(const gss_buffer_t attr GSSEAP_UNUSED,
+                              int *authenticated GSSEAP_UNUSED,
+                              int *complete GSSEAP_UNUSED,
+                              gss_buffer_t value GSSEAP_UNUSED,
+                              gss_buffer_t display_value GSSEAP_UNUSED,
+                              int *more GSSEAP_UNUSED) const
     {
         return false;
     }
 
-    virtual void setAttribute(int complete,
-                              const gss_buffer_t attr,
-                              const gss_buffer_t value) {}
-    virtual void deleteAttribute(const gss_buffer_t value) {}
-    virtual bool getAttribute(const gss_buffer_t attr,
-                              int *authenticated,
-                              int *complete,
-                              gss_buffer_t value,
-                              gss_buffer_t display_value,
-                              int *more) const { return false; }
-
-    virtual gss_any_t mapToAny(int authenticated,
-                               gss_buffer_t type_id) const { return NULL; }
-    virtual void releaseAnyNameMapping(gss_buffer_t type_id,
-                                       gss_any_t input) const {}
-
-    virtual void marshall(gss_buffer_t buffer) const {}
-    static gss_eap_attr_provider *unmarshall(const gss_eap_attr_ctx *ctx,
-                                             const gss_buffer_t buffer)
-    { return NULL; }
-
-    static bool init() { return true; }
-    static void finalize() {}
-
-    static gss_eap_attr_provider *
-    createAttrContext(const gss_eap_attr_ctx *ctx,
-                           gss_cred_id_t acceptorCred,
-                           gss_ctx_id_t acceptorCtx) { return NULL; }
+    virtual gss_any_t mapToAny(int authenticated GSSEAP_UNUSED,
+                               gss_buffer_t type_id GSSEAP_UNUSED) const
+    {
+        return NULL;
+    }
+
+    virtual void releaseAnyNameMapping(gss_buffer_t type_id GSSEAP_UNUSED,
+                                       gss_any_t input GSSEAP_UNUSED) const
+    {
+    }
+
+    /* prefix to be prepended to attributes emitted by gss_get_name_attribute */
+    virtual const char *prefix(void) const
+    {
+        return NULL;
+    }
+
+    /* optional key for storing JSON dictionary */
+    virtual const char *name(void) const
+    {
+        return NULL;
+    }
+
+    virtual bool initWithJsonObject(const gss_eap_attr_ctx *manager,
+                                    json_t *object GSSEAP_UNUSED)
+    {
+        return initWithManager(manager);
+    }
+
+
+    virtual json_t *jsonRepresentation(void) const
+    {
+        return NULL;
+    }
+
+    virtual time_t getExpiryTime(void) const { return 0; }
+
+    virtual OM_uint32 mapException(OM_uint32 *minor GSSEAP_UNUSED,
+                                   std::exception &e GSSEAP_UNUSED) const
+    {
+        return GSS_S_CONTINUE_NEEDED;
+    }
+
+    static bool init(void) { return true; }
+    static void finalize(void) {}
+
+    static gss_eap_attr_provider *createAttrContext(void) { return NULL; }
 
 protected:
-    const gss_eap_attr_ctx *m_source;
+    const gss_eap_attr_ctx *m_manager;
+
+private:
+    /* make non-copyable */
+    gss_eap_attr_provider(const gss_eap_attr_provider&);
+    gss_eap_attr_provider& operator=(const gss_eap_attr_provider&);
 };
 
-typedef gss_eap_attr_provider * (*gss_eap_attr_create_cb)(
-    const gss_eap_attr_ctx *ctx,
-    gss_cred_id_t acceptorCred,
-    gss_ctx_id_t acceptorCtx);
+typedef gss_eap_attr_provider *(*gss_eap_attr_create_provider)(void);
 
-struct gss_eap_attr_ctx : gss_eap_attr_provider
+/*
+ * Attribute context: this manages a set of providers for a given
+ * security context.
+ */
+struct gss_eap_attr_ctx
 {
 public:
-    gss_eap_attr_ctx(const gss_eap_attr_ctx *ctx,
-                     gss_cred_id_t acceptorCred,
-                     gss_ctx_id_t acceptorCtx) :
-        gss_eap_attr_provider(ctx, acceptorCred, acceptorCtx) {}
-
-    gss_eap_attr_ctx(const gss_eap_attr_ctx &ctx);
-
+    gss_eap_attr_ctx(void);
     ~gss_eap_attr_ctx(void);
 
-    static gss_eap_attr_ctx *createAttrContext(gss_cred_id_t acceptorCred,
-                                                    gss_ctx_id_t acceptorCtx);
+    bool initFromExistingContext(const gss_eap_attr_ctx *manager);
+    bool initFromGssContext(const gss_cred_id_t cred,
+                            const gss_ctx_id_t ctx);
 
     bool getAttributeTypes(gss_eap_attr_enumeration_cb, void *data) const;
     bool getAttributeTypes(gss_buffer_set_t *attrs);
 
-    void setAttribute(int complete,
+    bool setAttribute(int complete,
                       const gss_buffer_t attr,
                       const gss_buffer_t value);
-    void deleteAttribute(const gss_buffer_t value);
+    bool deleteAttribute(const gss_buffer_t value);
     bool getAttribute(const gss_buffer_t attr,
                       int *authenticated,
                       int *complete,
@@ -137,18 +209,12 @@ public:
     void releaseAnyNameMapping(gss_buffer_t type_id,
                                gss_any_t input) const;
 
-    void marshall(gss_buffer_t buffer) const;
-    gss_eap_attr_provider *unmarshall(const gss_eap_attr_ctx *ctx,
-                                      const gss_buffer_t buffer);
-    static bool init();
-    static void finalize();
-
-    static unsigned int
-    attributePrefixToType(const gss_buffer_t prefix);
-
-    static gss_buffer_t
-    attributeTypeToPrefix(unsigned int type);
+    void exportToBuffer(gss_buffer_t buffer) const;
+    bool initFromBuffer(const gss_buffer_t buffer);
 
+    static std::string
+    composeAttributeName(const gss_buffer_t prefix,
+                         const gss_buffer_t suffix);
     static void
     decomposeAttributeName(const gss_buffer_t attribute,
                            gss_buffer_t prefix,
@@ -157,28 +223,57 @@ public:
     composeAttributeName(const gss_buffer_t prefix,
                          const gss_buffer_t suffix,
                          gss_buffer_t attribute);
-    static void
+
+    std::string
+    composeAttributeName(unsigned int type,
+                         const gss_buffer_t suffix);
+    void
     decomposeAttributeName(const gss_buffer_t attribute,
                            unsigned int *type,
-                           gss_buffer_t suffix);
-    static void
+                           gss_buffer_t suffix) const;
+    void
     composeAttributeName(unsigned int type,
                          const gss_buffer_t suffix,
-                         gss_buffer_t attribute);
+                         gss_buffer_t attribute) const;
 
     gss_eap_attr_provider *getProvider(unsigned int type) const;
-    gss_eap_attr_provider *getProvider(const gss_buffer_t prefix) const;
+
+    static void
+    registerProvider(unsigned int type,
+                     gss_eap_attr_create_provider factory);
+    static void
+    unregisterProvider(unsigned int type);
+
+    time_t getExpiryTime(void) const;
+    OM_uint32 mapException(OM_uint32 *minor, std::exception &e) const;
 
 private:
-    gss_eap_attr_provider *m_providers[ATTR_TYPE_MAX];
+    bool providerEnabled(unsigned int type) const;
+    void releaseProvider(unsigned int type);
+
+    unsigned int attributePrefixToType(const gss_buffer_t prefix) const;
+    gss_buffer_desc attributeTypeToPrefix(unsigned int type) const;
+
+    bool initWithJsonObject(json_t *object);
+    json_t *jsonRepresentation(void) const;
+
+    gss_eap_attr_provider *getPrimaryProvider(void) const;
+
+    /* make non-copyable */
+    gss_eap_attr_ctx(const gss_eap_attr_ctx&);
+    gss_eap_attr_ctx& operator=(const gss_eap_attr_ctx&);
+
+    uint32_t m_flags;
+    gss_eap_attr_provider *m_providers[ATTR_TYPE_MAX + 1];
 };
 
+#endif /* __cplusplus */
+
 #include "util_radius.h"
 #include "util_saml.h"
 #include "util_shib.h"
 
-#include <string>
-#include <new>
+#ifdef __cplusplus
 
 static inline void
 duplicateBuffer(gss_buffer_desc &src, gss_buffer_t dst)
@@ -208,9 +303,18 @@ struct gss_eap_attr_ctx;
 extern "C" {
 #endif
 
-struct gss_eap_attr_ctx *
-gssEapCreateAttrContext(gss_cred_id_t acceptorCred,
-                        gss_ctx_id_t acceptorCtx);
+/*
+ * C wrappers for attribute context functions. These match their
+ * GSS naming extension equivalents. The caller is required to
+ * obtain the name mutex.
+ */
+
+OM_uint32
+gssEapCreateAttrContext(OM_uint32 *minor,
+                        gss_cred_id_t acceptorCred,
+                        gss_ctx_id_t acceptorCtx,
+                        struct gss_eap_attr_ctx **pAttrCtx,
+                        time_t *pExpiryTime);
 
 OM_uint32
 gssEapInquireName(OM_uint32 *minor,
@@ -274,9 +378,6 @@ gssEapReleaseAttrContext(OM_uint32 *minor,
                          gss_name_t name);
 
 OM_uint32
-gssEapAttrProvidersInit(OM_uint32 *minor);
-
-OM_uint32
 gssEapAttrProvidersFinalize(OM_uint32 *minor);
 
 #ifdef __cplusplus