Fixes for Heimdal (macOS) builds from Stefan.
[mech_eap.git] / mech_eap / util_radius.cpp
index e9c0d64..d8ec3df 100644 (file)
  */
 
 #include "gssapiP_eap.h"
+#include "util_radius.h"
+#include "utils/radius_utils.h"
 
-#define RS_MAP_ERROR(code)  (ERROR_TABLE_BASE_rse + (code))
+#ifdef GSSEAP_ENABLE_ACCEPTOR
 
-static gss_buffer_desc radiusUrnPrefix = {
-    sizeof("urn:x-radius:") - 1,
-    (void *)"urn:x-radius:"
-};
+#define RS_MAP_ERROR(code)  (ERROR_TABLE_BASE_rse + (code))
 
 static rs_avp *copyAvps(rs_const_avp *src);
 
@@ -176,11 +175,19 @@ isInternalAttributeP(const gss_eap_attrid &attrid)
     switch (attrid.first) {
     case VENDORPEC_UKERNA:
         switch (attrid.second) {
+        case PW_SAML_AAA_ASSERTION:
+            bInternalAttribute = true;
+            break;
+        default:
+            break;
+        }
+        break;
+    case 0:
+        switch (attrid.second) {
         case PW_GSS_ACCEPTOR_SERVICE_NAME:
         case PW_GSS_ACCEPTOR_HOST_NAME:
-        case PW_GSS_ACCEPTOR_SERVICE_SPECIFIC:
+        case PW_GSS_ACCEPTOR_SERVICE_SPECIFICS:
         case PW_GSS_ACCEPTOR_REALM_NAME:
-        case PW_SAML_AAA_ASSERTION:
             bInternalAttribute = true;
             break;
         default:
@@ -257,16 +264,13 @@ gss_eap_radius_attr_provider::getAttributeTypes(gss_eap_attr_enumeration_cb addA
         if (alreadyAddedAttributeP(seen, attrid))
             continue;
 
-        if (attrid.second != 0) {
-            snprintf(buf, sizeof(buf), "%s%u.%u",
-                     (char *)radiusUrnPrefix.value, attrid.first, attrid.second);
-        } else {
-            snprintf(buf, sizeof(buf), "%s%u",
-                     (char *)radiusUrnPrefix.value, attrid.second);
-        }
+        if (rs_attr_display_name(attrid.second, attrid.first,
+                                 buf, sizeof(buf), TRUE) != RSE_OK ||
+            strncmp(buf, "Attr-", 5) != 0)
+            continue;
 
-        desc.value = buf;
-        desc.length = strlen(buf);
+        desc.value = &buf[5];
+        desc.length = strlen((char *)desc.value);
 
         if (!addAttribute(m_manager, this, &desc, data))
             return false;
@@ -281,44 +285,35 @@ static bool
 getAttributeId(const gss_buffer_t desc,
                gss_eap_attrid *attrid)
 {
-    OM_uint32 tmpMinor;
-    gss_buffer_desc strAttr = GSS_C_EMPTY_BUFFER;
-    char *s;
-    bool ret;
+    char *strAttr, *s;
+    int canon, code;
 
-    if (desc->length < radiusUrnPrefix.length ||
-        memcmp(desc->value, radiusUrnPrefix.value, radiusUrnPrefix.length) != 0)
+    if (desc->length == 0)
         return false;
 
+    canon = isdigit(*(char *)desc->value);
+
     /* need to duplicate because attr may not be NUL terminated */
-    duplicateBuffer(*desc, &strAttr);
-    s = (char *)strAttr.value + radiusUrnPrefix.length;
+    strAttr = (char *)GSSEAP_MALLOC((canon ? 5 : 0) + desc->length + 1);
+    if (strAttr == NULL)
+        throw new std::bad_alloc();
 
-    if (!isdigit(*s)) {
-        /* No digits */
-        ret = (rs_attr_find(s, &attrid->second, &attrid->first) == RSE_OK);
-    } else {
-        char *s2;
-        unsigned int tmp = strtoul(s, &s2, 10);
-
-        if (s2 == NULL) {
-            /* Non-vendor attrbiute */
-            attrid->first = 0;
-            attrid->second = tmp;
-            ret = true;
-        } else if (*s2 == '.') {
-            /* Vendor attributes formatted as Vendor.Attribute */
-            attrid->first = tmp;
-            attrid->second = strtoul(s2 + 1, NULL, 10);
-            ret = true;
-        } else {
-            ret = false;
-        }
+    s = strAttr;
+
+    if (canon) {
+        memcpy(s, "Attr-", 5);
+        s += 5;
     }
 
-    gss_release_buffer(&tmpMinor, &strAttr);
+    memcpy(s, desc->value, desc->length);
+    s += desc->length;
+    *s = '\0';
+
+    code = rs_attr_parse_name(strAttr, &attrid->second, &attrid->first);
 
-    return ret;
+    GSSEAP_FREE(strAttr);
+
+    return (code == RSE_OK);
 }
 
 bool
@@ -839,7 +834,7 @@ gss_eap_radius_attr_provider::initWithJsonObject(const gss_eap_attr_ctx *ctx,
 const char *
 gss_eap_radius_attr_provider::prefix(void) const
 {
-    return "urn:ietf:params:gss-eap:radius-avp";
+    return "urn:ietf:params:gss:radius-attribute";
 }
 
 JSONObject
@@ -943,3 +938,17 @@ fail:
 
     return major;
 }
+
+#endif /* GSSEAP_ENABLE_ACCEPTOR */
+
+OM_uint32
+gssEapRadiusAddAttr(OM_uint32 *minor, struct wpabuf **buf, uint16_t attr,
+                    uint16_t vendor, gss_buffer_t buffer)
+{
+    if (radius_add_tlv(buf, attr, vendor, (u8 *)buffer->value,
+                       buffer->length) < 0) {
+        *minor = ENOMEM; /* could be length too long, though */
+        return GSS_S_FAILURE;
+    }
+    return GSS_S_COMPLETE;
+}