Updated Password-With-Header handling to make it more robust.
authorAlan T. DeKok <aland@freeradius.org>
Mon, 19 Jul 2010 13:24:58 +0000 (15:24 +0200)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 19 Jul 2010 21:52:04 +0000 (23:52 +0200)
* Added "Password-With-Header == userPassword" to raddb/ldap.attrmap
  This will automatically convert more passwords.
* Updated rlm_pap to decode Password-With-Header, if it was base64
  encoded, and to treat the contents as potentially binary data.

raddb/ldap.attrmap
src/modules/rlm_pap/rlm_pap.c

index 0176330..1aa7592 100644 (file)
@@ -38,6 +38,7 @@ checkItem     NT-Password                     ntPassword
 checkItem      LM-Password                     sambaLmPassword
 checkItem      NT-Password                     sambaNtPassword
 checkItem      LM-Password                     dBCSPwd
+checkitem      Password-With-Header            userPassword
 checkItem      SMB-Account-CTRL-TEXT           acctFlags
 checkItem      Expiration                      radiusExpiration
 checkItem      NAS-IP-Address                  radiusNASIpAddress
index 83f5bb1..9fa68ea 100644 (file)
@@ -313,19 +313,41 @@ static int pap_authorize(void *instance, REQUEST *request)
                {
                        int attr;
                        char *p, *q;
-                       char buffer[64];
+                       char buffer[128];
                        VALUE_PAIR *new_vp;
 
                        found_pw = TRUE;
+               redo:
                        q = vp->vp_strvalue;
                        p = strchr(q + 1, '}');
                        if (!p) {
+                               int decoded;
+
+                               /*
+                                *      Password already exists: use
+                                *      that instead of this one.
+                                */
+                               if (pairfind(request->config_items, PW_USER_PASSWORD) ||
+                                   pairfind(request->config_items, PW_CLEARTEXT_PASSWORD)) {
+                                       RDEBUG("Config already contains \"known good\" password.  Ignoring Password-With-Header");
+                                       break;
+                               }
+
                                /*
-                                *      FIXME: Turn it into a
-                                *      cleartext-password, unless it,
-                                *      or user-password already
-                                *      exists.
+                                *      If it's binary, it may be
+                                *      base64 encoded.  Decode it,
+                                *      and re-write the attribute to
+                                *      have the decoded value.
                                 */
+                               decoded = base64_decode(vp->vp_strvalue, buffer);
+                               if ((decoded > 0) && (buffer[0] == '{') &&
+                                   (strchr(buffer, '}') != NULL)) {
+                                       memcpy(vp->vp_octets, buffer, decoded);
+                                       vp->length = decoded;
+                                       goto redo;
+                               }
+
+                               RDEBUG("Failed to decode Password-With-Header = \"%s\"", vp->vp_strvalue);
                                break;
                        }
 
@@ -343,8 +365,14 @@ static int pap_authorize(void *instance, REQUEST *request)
                        new_vp = radius_paircreate(request,
                                                   &request->config_items,
                                                   attr, 0, PW_TYPE_STRING);
-                       strcpy(new_vp->vp_strvalue, p + 1);/* bounds OK */
-                       new_vp->length = strlen(new_vp->vp_strvalue);
+                       
+                       /*
+                        *      The data after the '}' may be binary,
+                        *      so we copy it via memcpy.
+                        */
+                       new_vp->length = vp->length;
+                       new_vp->length -= (p - q + 1);
+                       memcpy(new_vp->vp_strvalue, p + 1, new_vp->length);
 
                        /*
                         *      May be old-style User-Password with header.