support concatenated AVPs
authorLuke Howard <lukeh@padl.com>
Tue, 21 Sep 2010 00:22:49 +0000 (02:22 +0200)
committerLuke Howard <lukeh@padl.com>
Tue, 21 Sep 2010 00:22:49 +0000 (02:22 +0200)
mech_eap/accept_sec_context.c
mech_eap/util_radius.h

index b3d817f..ecea6ec 100644 (file)
@@ -255,14 +255,16 @@ eapGssSmAcceptAuthenticate(OM_uint32 *minor,
 
     ctx->acceptorCtx.lastStatus = code;
 
-    major = getBufferFromAvps(minor, received, PW_EAP_MESSAGE, outputToken);
-    if (GSS_ERROR(major))
+    major = getBufferFromAvps(minor, received, PW_EAP_MESSAGE,
+                              outputToken, TRUE);
+    if ((major == GSS_S_UNAVAILABLE && code != OK_RC) ||
+        GSS_ERROR(major))
         goto cleanup;
 
     if (code == CHALLENGE_RC) {
         major = getBufferFromAvps(minor, received, PW_STATE,
-                                  &ctx->acceptorCtx.state);
-        if (GSS_ERROR(major))
+                                  &ctx->acceptorCtx.state, TRUE);
+        if (major != GSS_S_UNAVAILABLE && GSS_ERROR(major))
             goto cleanup;
     } else {
         ctx->acceptorCtx.avps = received;
index d6ab501..6d89c1b 100644 (file)
@@ -98,7 +98,6 @@ addAvpFromBuffer(OM_uint32 *minor,
                  gss_buffer_t buffer)
 {
     if (rc_avpair_add(rh, vp, type, buffer->value, buffer->length, 0) == NULL) {
-        *minor = ENOMEM;
         return GSS_S_FAILURE;
     }
 
@@ -109,18 +108,40 @@ static inline OM_uint32
 getBufferFromAvps(OM_uint32 *minor,
                   VALUE_PAIR *vps,
                   int type,
-                  gss_buffer_t buffer)
+                  gss_buffer_t buffer,
+                  int concat)
 {
     VALUE_PAIR *vp;
-    gss_buffer_desc tmp = GSS_C_EMPTY_BUFFER;
+    unsigned char *p;
+
+    buffer->length = 0;
+    buffer->value = NULL;
 
     vp = rc_avpair_get(vps, type, 0);
-    if (vp != NULL) {
-        tmp.length = vp->lvalue;
-        tmp.value = vp->strvalue;
+    if (vp == NULL)
+        return GSS_S_UNAVAILABLE;
+
+    do {
+        buffer->length += vp->lvalue;
+    } while (concat && (vp = rc_avpair_get(vp->next, type, 0)) != NULL);
+    
+    buffer->value = GSSEAP_MALLOC(buffer->length);
+    if (buffer->value == NULL) {
+        *minor = ENOMEM;
+        return GSS_S_FAILURE;
     }
 
-    return duplicateBuffer(minor, &tmp, buffer);
+    p = (unsigned char *)buffer->value;
+
+    for (vp = rc_avpair_get(vps, type, 0);
+         concat && vp != NULL;
+         vp = rc_avpair_get(vp->next, type, 0)) {
+        memcpy(p, vp->strvalue, vp->lvalue);
+        p += vp->lvalue;
+    }
+
+    *minor = 0;
+    return GSS_S_COMPLETE;
 }
 
 OM_uint32 gssEapRadiusAttrProviderInit(OM_uint32 *minor);