re-arranged pap_authorize so that it will clean up base64 & hex
authoraland <aland>
Fri, 18 Feb 2005 21:34:59 +0000 (21:34 +0000)
committeraland <aland>
Fri, 18 Feb 2005 21:34:59 +0000 (21:34 +0000)
password attributes, so that other modules may use them.

This allows (for example) LDAP to store NT passwords base64-encoded,
with a header of {nt}.  The LDAP module will add an attribute
NT-Password, with the value as base64-encoded.  The PAP module
will base64-decode it during the "authorize" phase, so that the
mschap module can use the 16-byte NT hash during the authentication
phase.

src/modules/rlm_pap/rlm_pap.c

index 8234f2d..6ae3c65 100644 (file)
@@ -224,6 +224,7 @@ static void normify(VALUE_PAIR *vp, int min_length)
        if (vp->length >= (2 * min_length)) {
                decoded = lrad_hex2bin(vp->strvalue, buffer, vp->length >> 1);
                if (decoded == (vp->length >> 1)) {
+                       DEBUG2("rlm_pap: Normalizing %s from hex encoding", vp->name);
                        memcpy(vp->strvalue, buffer, decoded);
                        vp->length = decoded;
                        return;
@@ -237,6 +238,7 @@ static void normify(VALUE_PAIR *vp, int min_length)
        if ((vp->length * 3) >= ((min_length * 4))) {
                decoded = base64_decode(vp->strvalue, buffer);
                if (decoded >= min_length) {
+                       DEBUG2("rlm_pap: Normalizing %s from base64 encoding", vp->name);
                        memcpy(vp->strvalue, buffer, decoded);
                        vp->length = decoded;
                        return;
@@ -257,44 +259,35 @@ static void normify(VALUE_PAIR *vp, int min_length)
  */
 static int pap_authorize(void *instance, REQUEST *request)
 {
-       VALUE_PAIR *vp, *pw = NULL;
+       int auth_type = FALSE;
+       int found_pw = FALSE;
+       VALUE_PAIR *vp;
 
        instance = instance;    /* -Wunused */
 
-       /*
-        *      Can't do PAP if there's no password.
-        */
-       if (!request->password ||
-           (request->password->attribute != PW_USER_PASSWORD)) {
-               /*
-                *      Don't print out debugging messages if we know
-                *      they're useless.
-                */
-               if (request->packet->code == PW_ACCESS_CHALLENGE) {
-                       return RLM_MODULE_NOOP;
-               }
-
-               DEBUG2("rlm_pap: No clear-text password in the request.  Not performing PAP.");
-               return RLM_MODULE_NOOP;
-       }
-
-
        for (vp = request->config_items; vp != NULL; vp = vp->next) {
                switch (vp->attribute) {
                case PW_USER_PASSWORD:
                case PW_CRYPT_PASSWORD:
+                       break;  /* don't touch these */
+
                case PW_MD5_PASSWORD:
-               case PW_SHA_PASSWORD:
+               case PW_SMD5_PASSWORD:
                case PW_NT_PASSWORD:
                case PW_LM_PASSWORD:
-               case PW_SMD5_PASSWORD:
+                       normify(vp, 16); /* ensure it's in the right format */
+                       found_pw = TRUE;
+                       break;
+
+               case PW_SHA_PASSWORD:
                case PW_SSHA_PASSWORD:
-                       pw = vp;
+                       normify(vp, 20); /* ensure it's in the right format */
+                       found_pw = TRUE;
                        break;
 
                case PW_AUTH_TYPE:
-                       DEBUG2("rlm_pap: Found existing Auth-Type, not changing it.");
-                       return RLM_MODULE_NOOP;
+                       auth_type = TRUE;
+                       break;
 
                default:
                        break;  /* ignore it */
@@ -305,11 +298,37 @@ static int pap_authorize(void *instance, REQUEST *request)
        /*
         *      Print helpful warnings if there was no password.
         */
-       if (!pw) {
+       if (!found_pw) {
                DEBUG("rlm_pap: WARNING! No \"known good\" password found for the user.  Authentication will probably fail");
                return RLM_MODULE_NOOP;
        }
 
+       /*
+        *      Don't touch existing Auth-Types.
+        */
+       if (auth_type) {
+               DEBUG2("rlm_pap: Found existing Auth-Type, not changing it.");
+               return RLM_MODULE_NOOP;
+       }       
+
+       /*
+        *      Can't do PAP if there's no password.
+        */
+       if (!request->password ||
+           (request->password->attribute != PW_USER_PASSWORD)) {
+               /*
+                *      Don't print out debugging messages if we know
+                *      they're useless.
+                */
+               if (request->packet->code == PW_ACCESS_CHALLENGE) {
+                       return RLM_MODULE_NOOP;
+               }
+
+               DEBUG2("rlm_pap: No clear-text password in the request.  Not performing PAP.");
+               return RLM_MODULE_NOOP;
+       }
+
+
        vp = pairmake("Auth-Type", "PAP", T_OP_SET);
        if (!vp) return RLM_MODULE_FAIL;