remove util_alloc.c
[mech_eap.git] / util_radius.cpp
index 43d329f..314c685 100644 (file)
@@ -32,7 +32,8 @@
 
 #include "gssapiP_eap.h"
 
-#define VENDORATTR(vendor, attr)            ((vendor) << 16 | (attr))
+/* stuff that should be provided by libradsec/libfreeradius-radius */
+#define VENDORATTR(vendor, attr)            (((vendor) << 16) | (attr))
 
 #ifndef ATTRID
 #define ATTRID(attr)                        ((attr) & 0xFFFF)
@@ -58,10 +59,10 @@ radiusAllocHandle(const char *configFile,
     if (rs_context_create(&rh, RS_DICT_FILE) != 0)
         return NULL;
 
-    ralloc.calloc = gssEapCalloc;
-    ralloc.malloc = gssEapMalloc;
-    ralloc.free = gssEapFree;
-    ralloc.realloc = gssEapRealloc;
+    ralloc.calloc = GSSEAP_CALLOC;
+    ralloc.malloc = GSSEAP_MALLOC;
+    ralloc.free = GSSEAP_FREE;
+    ralloc.realloc = GSSEAP_REALLOC;
 
     rs_context_set_alloc_scheme(rh, &ralloc);
 
@@ -168,7 +169,7 @@ alreadyAddedAttributeP(std::vector <std::string> &attrs, VALUE_PAIR *vp)
 }
 
 static bool
-isHiddenAttributeP(int attrid, uint16_t vendor)
+isHiddenAttributeP(uint16_t attrid, uint16_t vendor)
 {
     bool ret = false;
 
@@ -245,7 +246,7 @@ gss_eap_radius_attr_provider::getAttribute(const gss_buffer_t attr,
     OM_uint32 tmpMinor;
     gss_buffer_desc strAttr = GSS_C_EMPTY_BUFFER;
     DICT_ATTR *da;
-    int attrid;
+    uint32_t attrid;
     char *s;
 
     duplicateBuffer(*attr, &strAttr);
@@ -415,7 +416,7 @@ gssEapRadiusAddAvp(OM_uint32 *minor,
                    uint16_t vendor,
                    gss_buffer_t buffer)
 {
-    uint16_t attrid = VENDORATTR(vendor, vattrid);
+    uint32_t attrid = VENDORATTR(vendor, vattrid);
     unsigned char *p = (unsigned char *)buffer->value;
     size_t remain = buffer->length;
 
@@ -433,6 +434,8 @@ gssEapRadiusAddAvp(OM_uint32 *minor,
         }
 
         memcpy(vp->vp_octets, p, n);
+        vp->length = n;
+
         pairadd(vps, vp);
 
         p += n;
@@ -449,7 +452,7 @@ gssEapRadiusGetRawAvp(OM_uint32 *minor,
                       uint16_t vendor,
                       VALUE_PAIR **vp)
 {
-    uint16_t attr = VENDORATTR(vendor, type);
+    uint32_t attr = VENDORATTR(vendor, type);
 
     *vp = pairfind(vps, attr);
 
@@ -499,6 +502,15 @@ gssEapRadiusGetAvp(OM_uint32 *minor,
 }
 
 OM_uint32
+gssEapRadiusFreeAvps(OM_uint32 *minor,
+                     VALUE_PAIR **vps)
+{
+    pairfree(vps);
+    *minor = 0;
+    return GSS_S_COMPLETE;
+}
+
+OM_uint32
 gssEapRadiusAttrProviderInit(OM_uint32 *minor)
 {
     return gss_eap_radius_attr_provider::init()
@@ -512,13 +524,30 @@ gssEapRadiusAttrProviderFinalize(OM_uint32 *minor)
     return GSS_S_COMPLETE;
 }
 
+/* partition error namespace so it does not conflict with krb5 */
+#define ERROR_TABLE_BASE_rse (46882560L)
+
+#define RS_TO_COM_ERR(rse)                  ((rse) == RSE_OK ? 0 : (rse) + ERROR_TABLE_BASE_rse)
+#define COM_TO_RS_ERR(err)                  ((err) > ERROR_TABLE_BASE_rse && \
+                                             (err) <= (ERROR_TABLE_BASE_rse + RSE_SOME_ERROR) ? \
+                                             (err) - ERROR_TABLE_BASE_rse : RSE_SOME_ERROR)
+
 OM_uint32
 gssEapRadiusMapError(OM_uint32 *minor,
                      struct rs_error *err)
 {
+    int code = RSE_OK;
+
     if (err != NULL)
-        rs_err_code(err, 1);
+        code = rs_err_code(err, 0);
+    else
+        code = RSE_SOME_ERROR;
+
+    *minor = RS_TO_COM_ERR(code);
 
+    gssEapSaveStatusInfo(*minor, "radsec: %s", rs_err_msg(err, 0));
+
+    rs_err_free(err);
     return GSS_S_FAILURE;
 }
 
@@ -529,20 +558,25 @@ gssEapRadiusAllocConn(OM_uint32 *minor,
 {
     struct gss_eap_acceptor_ctx *actx = &ctx->acceptorCtx;
     const char *configFile = NULL;
+    const char *configStanza = "gss-eap";
     struct rs_error *err;
 
     assert(actx->radHandle == NULL);
     assert(actx->radConn == NULL);
 
-    if (cred != GSS_C_NO_CREDENTIAL && cred->radiusConfigFile != NULL)
-        configFile = cred->radiusConfigFile;
+    if (cred != GSS_C_NO_CREDENTIAL) {
+        if (cred->radiusConfigFile != NULL)
+            configFile = cred->radiusConfigFile;
+        if (cred->radiusConfigStanza != NULL)
+            configStanza = cred->radiusConfigStanza;
+    }
 
     err = radiusAllocHandle(configFile, &actx->radHandle);
     if (err != NULL || actx->radHandle == NULL) {
         return gssEapRadiusMapError(minor, err);
     }
 
-    if (rs_conn_create(actx->radHandle, &actx->radConn, "gss-eap") != 0) {
+    if (rs_conn_create(actx->radHandle, &actx->radConn, configStanza) != 0) {
         return gssEapRadiusMapError(minor, rs_err_conn_pop(actx->radConn));
     }
 
@@ -653,10 +687,14 @@ avpImport(rs_handle *rh,
         break;
     case PW_TYPE_STRING:
         /* check enough room to NUL terminate */
-        if (p[0] >= MAX_STRING_LEN)
+        if (p[0] == MAX_STRING_LEN)
             goto fail;
+        else
         /* fallthrough */
     default:
+        if (p[0] > MAX_STRING_LEN)
+            goto fail;
+
         vp->length = (uint32_t)p[0];
         memcpy(vp->vp_octets, p + 1, vp->length);