add RADIUS set/delete attribute code
authorLuke Howard <lukeh@padl.com>
Tue, 12 Oct 2010 01:31:05 +0000 (12:31 +1100)
committerLuke Howard <lukeh@padl.com>
Tue, 12 Oct 2010 01:31:05 +0000 (12:31 +1100)
mech_eap/util_attr.cpp
mech_eap/util_attr.h
mech_eap/util_radius.cpp
mech_eap/util_radius.h
mech_eap/util_saml.cpp
mech_eap/util_saml.h
mech_eap/util_shib.cpp
mech_eap/util_shib.h

index 57af9cd..14865fa 100644 (file)
@@ -349,7 +349,7 @@ gss_eap_attr_ctx::getPrimaryProvider(void) const
 /*
  * Set an attribute
  */
-void
+bool
 gss_eap_attr_ctx::setAttribute(int complete,
                                const gss_buffer_t attr,
                                const gss_buffer_t value)
@@ -357,34 +357,39 @@ gss_eap_attr_ctx::setAttribute(int complete,
     gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
     unsigned int type;
     gss_eap_attr_provider *provider;
+    bool ret = false;
 
     decomposeAttributeName(attr, &type, &suffix);
 
     provider = m_providers[type];
     if (provider != NULL) {
-        provider->setAttribute(complete,
-                               (type == ATTR_TYPE_LOCAL) ? attr : &suffix,
-                               value);
-    } else {
-        /* XXX TODO throw exception */
+        ret = provider->setAttribute(complete,
+                                     (type == ATTR_TYPE_LOCAL) ? attr : &suffix,
+                                     value);
     }
+
+    return ret;
 }
 
 /*
  * Delete an attrbiute
  */
-void
+bool
 gss_eap_attr_ctx::deleteAttribute(const gss_buffer_t attr)
 {
     gss_buffer_desc suffix = GSS_C_EMPTY_BUFFER;
     unsigned int type;
     gss_eap_attr_provider *provider;
+    bool ret = false;
 
     decomposeAttributeName(attr, &type, &suffix);
 
     provider = m_providers[type];
-    if (provider != NULL)
-        provider->deleteAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix);
+    if (provider != NULL) {
+        ret = provider->deleteAttribute(type == ATTR_TYPE_LOCAL ? attr : &suffix);
+    }
+
+    return ret;
 }
 
 /*
@@ -815,7 +820,12 @@ gssEapDeleteNameAttribute(OM_uint32 *minor,
         return GSS_S_UNAVAILABLE;
 
     try {
-        name->attrCtx->deleteAttribute(attr);
+        if (!name->attrCtx->deleteAttribute(attr)) {
+            *minor = GSSEAP_NO_SUCH_ATTR;
+            gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
+                                 (int)attr->length, (char *)attr->value);
+            return GSS_S_UNAVAILABLE;
+        }
     } catch (std::exception &ex) {
         return mapException(minor, ex);
     }
@@ -839,7 +849,12 @@ gssEapSetNameAttribute(OM_uint32 *minor,
         return GSS_S_UNAVAILABLE;
 
     try {
-        name->attrCtx->setAttribute(complete, attr, value);
+        if (!name->attrCtx->setAttribute(complete, attr, value)) {
+             *minor = GSSEAP_NO_SUCH_ATTR;
+            gssEapSaveStatusInfo(*minor, "Unknown naming attribute %.*s",
+                                 (int)attr->length, (char *)attr->value);
+            return GSS_S_UNAVAILABLE;
+        }
     } catch (std::exception &ex) {
         return mapException(minor, ex);
     }
index 6f6c74a..0358936 100644 (file)
@@ -87,10 +87,10 @@ public:
         return false;
     }
 
-    virtual void setAttribute(int complete,
+    virtual bool setAttribute(int complete,
                               const gss_buffer_t attr,
-                              const gss_buffer_t value) {}
-    virtual void deleteAttribute(const gss_buffer_t value) {}
+                              const gss_buffer_t value) { return false; }
+    virtual bool deleteAttribute(const gss_buffer_t value) { return false; }
     virtual bool getAttribute(const gss_buffer_t attr,
                               int *authenticated,
                               int *complete,
@@ -145,10 +145,10 @@ public:
     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,
index 5a676ab..6ab819e 100644 (file)
@@ -226,16 +226,88 @@ gss_eap_radius_attr_provider::getAttributeTypes(gss_eap_attr_enumeration_cb addA
     return true;
 }
 
-void
+uint32_t
+getAttributeId(const gss_buffer_t attr)
+{
+    OM_uint32 tmpMinor;
+    gss_buffer_desc strAttr = GSS_C_EMPTY_BUFFER;
+    DICT_ATTR *da;
+    char *s;
+    uint32_t attrid = 0;
+
+    if (attr->length < radiusUrnPrefix.length ||
+        memcmp(attr->value, radiusUrnPrefix.value, radiusUrnPrefix.length) != 0)
+        return 0;
+
+    /* need to duplicate because attr may not be NUL terminated */
+    duplicateBuffer(*attr, &strAttr);
+    s = (char *)strAttr.value + radiusUrnPrefix.length;
+
+    if (isdigit(*s)) {
+        attrid = strtoul(s, NULL, 10);
+    } else {
+        da = dict_attrbyname(s);
+        if (da != NULL)
+            attrid = da->attr;
+    }
+
+    gss_release_buffer(&tmpMinor, &strAttr);
+
+    return attrid;
+}
+
+bool
+gss_eap_radius_attr_provider::setAttribute(int complete,
+                                           uint32_t attrid,
+                                           const gss_buffer_t value)
+{
+    OM_uint32 major = GSS_S_UNAVAILABLE, minor;
+
+    if (!isSecretAttributeP(attrid) &&
+        !isHiddenAttributeP(attrid)) {
+        deleteAttribute(attrid);
+
+        major = gssEapRadiusAddAvp(&minor, &m_vps,
+                                   ATTRID(attrid), VENDOR(attrid), 
+                                   value);
+    }
+
+    return !GSS_ERROR(major);
+}
+
+bool
 gss_eap_radius_attr_provider::setAttribute(int complete,
                                            const gss_buffer_t attr,
                                            const gss_buffer_t value)
 {
+    uint32_t attrid = getAttributeId(attr);
+
+    if (!attrid)
+        return false;
+
+    return setAttribute(complete, attrid, value);
 }
 
-void
-gss_eap_radius_attr_provider::deleteAttribute(const gss_buffer_t value)
+bool
+gss_eap_radius_attr_provider::deleteAttribute(uint32_t attrid)
 {
+    if (isSecretAttributeP(attrid) || isHiddenAttributeP(attrid) ||
+        pairfind(m_vps, attrid) == NULL)
+        return false;
+
+    pairdelete(&m_vps, attrid);
+    return true;
+}
+
+bool
+gss_eap_radius_attr_provider::deleteAttribute(const gss_buffer_t attr)
+{
+    uint32_t attrid = getAttributeId(attr);
+
+    if (!attrid)
+        return false;
+
+    return deleteAttribute(attrid);
 }
 
 bool
@@ -246,34 +318,12 @@ gss_eap_radius_attr_provider::getAttribute(const gss_buffer_t attr,
                                            gss_buffer_t display_value,
                                            int *more) const
 {
-    OM_uint32 tmpMinor;
-    gss_buffer_desc strAttr = GSS_C_EMPTY_BUFFER;
-    DICT_ATTR *da;
     uint32_t attrid;
-    char *s;
-
-    duplicateBuffer(*attr, &strAttr);
-    s = (char *)strAttr.value;
 
-    if (attr->length < radiusUrnPrefix.length ||
-        memcmp(s, radiusUrnPrefix.value, radiusUrnPrefix.length) != 0)
+    attrid = getAttributeId(attr);
+    if (!attrid)
         return false;
 
-    s += radiusUrnPrefix.length;
-
-    if (isdigit(*s)) {
-        attrid = strtoul(s, NULL, 10);
-    } else {
-        da = dict_attrbyname(s);
-        if (da == NULL) {
-            gss_release_buffer(&tmpMinor, &strAttr);
-            return false;
-        }
-        attrid = da->attr;
-    }
-
-    gss_release_buffer(&tmpMinor, &strAttr);
-
     return getAttribute(attrid, authenticated, complete,
                         value, display_value, more);
 }
@@ -415,7 +465,7 @@ gssEapRadiusAddAvp(OM_uint32 *minor,
                    VALUE_PAIR **vps,
                    uint16_t attribute,
                    uint16_t vendor,
-                   gss_buffer_t buffer)
+                   const gss_buffer_t buffer)
 {
     uint32_t attrid = VENDORATTR(vendor, attribute);
     unsigned char *p = (unsigned char *)buffer->value;
index 4ab7b91..805f57e 100644 (file)
@@ -47,10 +47,10 @@ public:
                             const gss_ctx_id_t ctx);
 
     bool getAttributeTypes(gss_eap_attr_enumeration_cb, void *data) const;
-    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 attr);
     bool getAttribute(const gss_buffer_t attr,
                       int *authenticated,
                       int *complete,
@@ -79,6 +79,10 @@ public:
                       gss_buffer_t value,
                       gss_buffer_t display_value,
                       int *more) const;
+    bool setAttribute(int complete,
+                      uint32_t attribute,
+                      const gss_buffer_t value);
+    bool deleteAttribute(uint32_t attribute);
 
     bool getFragmentedAttribute(uint16_t attribute,
                                 uint16_t vendor,
@@ -113,7 +117,7 @@ gssEapRadiusAddAvp(OM_uint32 *minor,
                    VALUE_PAIR **vp,
                    uint16_t type,
                    uint16_t vendor,
-                   gss_buffer_t buffer);
+                   const gss_buffer_t buffer);
 
 OM_uint32
 gssEapRadiusGetAvp(OM_uint32 *minor,
index 820896f..7e088eb 100644 (file)
@@ -183,22 +183,27 @@ gss_eap_saml_assertion_provider::getAttributeTypes(gss_eap_attr_enumeration_cb a
     return ret;
 }
 
-void
+bool
 gss_eap_saml_assertion_provider::setAttribute(int complete,
                                               const gss_buffer_t attr,
                                               const gss_buffer_t value)
 {
     if (attr == GSS_C_NO_BUFFER || attr->length == 0) {
         setAssertion(value);
+        return true;
     }
+
+    return false;
 }
 
-void
+bool
 gss_eap_saml_assertion_provider::deleteAttribute(const gss_buffer_t value)
 {
     delete m_assertion;
     m_assertion = NULL;
     m_authenticated = false;
+
+    return true;
 }
 
 time_t
@@ -408,16 +413,18 @@ gss_eap_saml_attr_provider::getAttributeTypes(gss_eap_attr_enumeration_cb addAtt
     return ret;
 }
 
-void
+bool
 gss_eap_saml_attr_provider::setAttribute(int complete,
                                          const gss_buffer_t attr,
                                          const gss_buffer_t value)
 {
+    return false;
 }
 
-void
+bool
 gss_eap_saml_attr_provider::deleteAttribute(const gss_buffer_t value)
 {
+    return false;
 }
 
 static BaseRefVectorOf<XMLCh> *
index 7a750a0..7c457e8 100644 (file)
@@ -55,10 +55,10 @@ public:
                             const gss_ctx_id_t ctx);
 
     bool getAttributeTypes(gss_eap_attr_enumeration_cb, void *data) const;
-    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,
@@ -107,10 +107,10 @@ public:
     ~gss_eap_saml_attr_provider(void) {}
 
     bool getAttributeTypes(gss_eap_attr_enumeration_cb, void *data) const;
-    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,
index a37329f..d2e7eec 100644 (file)
@@ -214,7 +214,7 @@ gss_eap_shib_attr_provider::getAttributeIndex(const gss_buffer_t attr) const
     return -1;
 }
 
-void
+bool
 gss_eap_shib_attr_provider::setAttribute(int complete,
                                          const gss_buffer_t attr,
                                          const gss_buffer_t value)
@@ -231,9 +231,11 @@ gss_eap_shib_attr_provider::setAttribute(int complete,
 
     m_attributes.push_back(a);
     m_authenticated = false;
+
+    return true;
 }
 
-void
+bool
 gss_eap_shib_attr_provider::deleteAttribute(const gss_buffer_t attr)
 {
     int i;
@@ -243,6 +245,8 @@ gss_eap_shib_attr_provider::deleteAttribute(const gss_buffer_t attr)
         m_attributes.erase(m_attributes.begin() + i);
 
     m_authenticated = false;
+
+    return true;
 }
 
 bool
index c57d9aa..6189360 100644 (file)
@@ -56,10 +56,10 @@ public:
                             const gss_cred_id_t cred,
                             const gss_ctx_id_t ctx);
 
-    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 getAttributeTypes(gss_eap_attr_enumeration_cb, void *data) const;
     bool getAttribute(const gss_buffer_t attr,
                       int *authenticated,