Massively cleaned up #include's, so they're in a consistent
[freeradius.git] / src / modules / rlm_digest / rlm_digest.c
index 3024ca1..7576d4a 100644 (file)
  *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * Copyright 2002  The FreeRADIUS server project
+ * Copyright 2002,2006  The FreeRADIUS server project
  * Copyright 2002  Alan DeKok <aland@ox.org>
  */
 
-#include "autoconf.h"
+#include <freeradius-devel/ident.h>
+RCSID("$Id$")
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "radiusd.h"
-#include "modules.h"
-#include "conffile.h"
-
-static const char rcsid[] = "$Id$";
+#include <freeradius-devel/radiusd.h>
+#include <freeradius-devel/modules.h>
 
 static int digest_authorize(void *instance, REQUEST *request)
 {
@@ -96,10 +90,17 @@ static int digest_authenticate(void *instance, REQUEST *request)
        /*
         *      We require access to the plain-text password.
         */
-       passwd = pairfind(request->config_items, PW_PASSWORD);
-       if (!passwd) passwd = pairfind(request->config_items, PW_DIGEST_HA1);
+       passwd = pairfind(request->config_items, PW_DIGEST_HA1);
+       if (passwd) {
+               if (passwd->length != 32) {
+                       radlog(L_AUTH, "rlm_digest: Digest-HA1 has invalid length, authentication failed.");
+                       return RLM_MODULE_INVALID;
+               }
+       } else {
+               passwd = pairfind(request->config_items, PW_CLEARTEXT_PASSWORD);
+       }
        if (!passwd) {
-               radlog(L_AUTH, "rlm_digest: Configuration item \"User-Password\" or MD5-Password is required for authentication.");
+               radlog(L_AUTH, "rlm_digest: Cleartext-Password or Digest-HA1 is required for authentication.");
                return RLM_MODULE_INVALID;
        }
 
@@ -119,7 +120,7 @@ static int digest_authenticate(void *instance, REQUEST *request)
        while (vp) {
                int length = vp->length;
                int attrlen;
-               uint8_t *p = &vp->strvalue[0];
+               uint8_t *p = &vp->vp_octets[0];
                VALUE_PAIR *sub;
 
                /*
@@ -163,8 +164,8 @@ static int digest_authenticate(void *instance, REQUEST *request)
                        if (!sub) {
                                return RLM_MODULE_FAIL; /* out of memory */
                        }
-                       memcpy(&sub->strvalue[0], &p[2], attrlen - 2);
-                       sub->strvalue[attrlen - 2] = '\0';
+                       memcpy(&sub->vp_octets[0], &p[2], attrlen - 2);
+                       sub->vp_octets[attrlen - 2] = '\0';
                        sub->length = attrlen - 2;
 
                        if (debug_flag) {
@@ -210,7 +211,7 @@ static int digest_authenticate(void *instance, REQUEST *request)
                DEBUG("ERROR: No Digest-User-Name: Cannot perform Digest authentication");
                return RLM_MODULE_INVALID;
        }
-       memcpy(&a1[0], &vp->strvalue[0], vp->length);
+       memcpy(&a1[0], &vp->vp_octets[0], vp->length);
        a1_len = vp->length;
 
        a1[a1_len] = ':';
@@ -221,14 +222,14 @@ static int digest_authenticate(void *instance, REQUEST *request)
                DEBUG("ERROR: No Digest-Realm: Cannot perform Digest authentication");
                return RLM_MODULE_INVALID;
        }
-       memcpy(&a1[a1_len], &vp->strvalue[0], vp->length);
+       memcpy(&a1[a1_len], &vp->vp_octets[0], vp->length);
        a1_len += vp->length;
 
        a1[a1_len] = ':';
        a1_len++;
 
-       if (passwd->attribute == PW_USER_PASSWORD) {
-               memcpy(&a1[a1_len], &passwd->strvalue[0], passwd->length);
+       if (passwd->attribute == PW_CLEARTEXT_PASSWORD) {
+               memcpy(&a1[a1_len], &passwd->vp_octets[0], passwd->length);
                a1_len += passwd->length;
                a1[a1_len] = '\0';
                DEBUG2("A1 = %s", a1);
@@ -244,26 +245,29 @@ static int digest_authenticate(void *instance, REQUEST *request)
         */
        algo = pairfind(request->packet->vps, PW_DIGEST_ALGORITHM);
        if ((algo == NULL) || 
-           (strcasecmp(algo->strvalue, "MD5") == 0)) {
+           (strcasecmp(algo->vp_strvalue, "MD5") == 0)) {
                /*
                 *      Set A1 to Digest-HA1 if no User-Password found
                 */
-               if (passwd->attribute != PW_USER_PASSWORD) {
-                       memcpy(&a1[0], passwd->strvalue, 16);
+               if (passwd->attribute == PW_DIGEST_HA1) {
+                       if (lrad_hex2bin(passwd->vp_strvalue, &a1[0], 16) != 16) {
+                               DEBUG2("rlm_digest: Invalid text in Digest-HA1");
+                               return RLM_MODULE_INVALID;
+                       }
                }
 
-       } else if (strcasecmp(algo->strvalue, "MD5-sess") == 0) {
+       } else if (strcasecmp(algo->vp_strvalue, "MD5-sess") == 0) {
                /*
                 *      K1 = H(A1) : Digest-Nonce ... : H(A2)
                 *
                 *      If we find Digest-HA1, we assume it contains
                 *      H(A1).
                 */
-               if (passwd->attribute == PW_USER_PASSWORD) {
+               if (passwd->attribute == PW_CLEARTEXT_PASSWORD) {
                        librad_md5_calc(hash, &a1[0], a1_len);
                        lrad_bin2hex(hash, &a1[0], 16);
-               } else {
-                       lrad_bin2hex(passwd->strvalue, &a1[0], 16);
+               } else {        /* MUST be Digest-HA1 */
+                       memcpy(&a1[0], passwd->vp_strvalue, 32);
                }
                a1_len = 32;
 
@@ -277,7 +281,7 @@ static int digest_authenticate(void *instance, REQUEST *request)
                        DEBUG("ERROR: Received Digest-Nonce hex string with invalid length: Cannot perform Digest authentication");
                        return RLM_MODULE_INVALID;
                }
-               memcpy(&a1[a1_len], &nonce->strvalue[0], nonce->length);
+               memcpy(&a1[a1_len], &nonce->vp_octets[0], nonce->length);
                a1_len += nonce->length;
 
                a1[a1_len] = ':';
@@ -296,16 +300,16 @@ static int digest_authenticate(void *instance, REQUEST *request)
                        DEBUG("ERROR: Received Digest-CNonce hex string with invalid length: Cannot perform Digest authentication");
                        return RLM_MODULE_INVALID;
                }
-               memcpy(&a1[a1_len], &vp->strvalue[0], vp->length);
+               memcpy(&a1[a1_len], &vp->vp_octets[0], vp->length);
                a1_len += vp->length;
 
        } else if ((algo != NULL) &&
-                  (strcasecmp(algo->strvalue, "MD5") != 0)) {
+                  (strcasecmp(algo->vp_strvalue, "MD5") != 0)) {
                /*
                 *      We check for "MD5-sess" and "MD5".
                 *      Anything else is an error.
                 */
-               DEBUG("ERROR: Unknown Digest-Algorithm \"%s\": Cannot perform Digest authentication", vp->strvalue);
+               DEBUG("ERROR: Unknown Digest-Algorithm \"%s\": Cannot perform Digest authentication", vp->vp_strvalue);
                return RLM_MODULE_INVALID;
        }
 
@@ -317,7 +321,7 @@ static int digest_authenticate(void *instance, REQUEST *request)
                DEBUG("ERROR: No Digest-Method: Cannot perform Digest authentication");
                return RLM_MODULE_INVALID;
        }
-       memcpy(&a2[0], &vp->strvalue[0], vp->length);
+       memcpy(&a2[0], &vp->vp_octets[0], vp->length);
        a2_len = vp->length;
 
        a2[a2_len] = ':';
@@ -328,7 +332,7 @@ static int digest_authenticate(void *instance, REQUEST *request)
                DEBUG("ERROR: No Digest-URI: Cannot perform Digest authentication");
                return RLM_MODULE_INVALID;
        }
-       memcpy(&a2[a2_len], &vp->strvalue[0], vp->length);
+       memcpy(&a2[a2_len], &vp->vp_octets[0], vp->length);
        a2_len += vp->length;
 
        /*
@@ -336,7 +340,7 @@ static int digest_authenticate(void *instance, REQUEST *request)
         */
        qop = pairfind(request->packet->vps, PW_DIGEST_QOP);
        if ((qop != NULL) &&
-           (strcasecmp(qop->strvalue, "auth-int") == 0)) {
+           (strcasecmp(qop->vp_strvalue, "auth-int") == 0)) {
                VALUE_PAIR *body;
 
                /*
@@ -359,12 +363,12 @@ static int digest_authenticate(void *instance, REQUEST *request)
                        return RLM_MODULE_INVALID;
                }
 
-               memcpy(a2 + a2_len, body->strvalue, body->length);
+               memcpy(a2 + a2_len, body->vp_octets, body->length);
                a2_len += body->length;
 
        } else if ((qop != NULL) &&
-                  (strcasecmp(qop->strvalue, "auth") != 0)) {
-               DEBUG("ERROR: Unknown Digest-QOP \"%s\": Cannot perform Digest authentication", qop->strvalue);
+                  (strcasecmp(qop->vp_strvalue, "auth") != 0)) {
+               DEBUG("ERROR: Unknown Digest-QOP \"%s\": Cannot perform Digest authentication", qop->vp_strvalue);
                return RLM_MODULE_INVALID;
        }
 
@@ -377,9 +381,9 @@ static int digest_authenticate(void *instance, REQUEST *request)
         *     or if we found a User-Password.
         */
        if (((algo != NULL) && 
-            (strcasecmp(algo->strvalue, "MD5-Sess") == 0)) ||
-           (passwd->attribute == PW_USER_PASSWORD)) {
-         a1[a1_len] = '\0';
+            (strcasecmp(algo->vp_strvalue, "MD5-Sess") == 0)) ||
+           (passwd->attribute == PW_CLEARTEXT_PASSWORD)) {
+               a1[a1_len] = '\0';
                librad_md5_calc(&hash[0], &a1[0], a1_len);
        } else {
                memcpy(&hash[0], &a1[0], a1_len);
@@ -400,7 +404,7 @@ static int digest_authenticate(void *instance, REQUEST *request)
        kd[kd_len] = ':';
        kd_len++;
 
-       memcpy(&kd[kd_len], nonce->strvalue, nonce->length);
+       memcpy(&kd[kd_len], nonce->vp_octets, nonce->length);
        kd_len += nonce->length;
 
        /*
@@ -424,7 +428,7 @@ static int digest_authenticate(void *instance, REQUEST *request)
                        DEBUG("ERROR: No Digest-Nonce-Count: Cannot perform Digest authentication");
                        return RLM_MODULE_INVALID;
                }
-               memcpy(&kd[kd_len], &vp->strvalue[0], vp->length);
+               memcpy(&kd[kd_len], &vp->vp_octets[0], vp->length);
                kd_len += vp->length;
 
                kd[kd_len] = ':';
@@ -435,13 +439,13 @@ static int digest_authenticate(void *instance, REQUEST *request)
                        DEBUG("ERROR: No Digest-CNonce: Cannot perform Digest authentication");
                        return RLM_MODULE_INVALID;
                }
-               memcpy(&kd[kd_len], &vp->strvalue[0], vp->length);
+               memcpy(&kd[kd_len], &vp->vp_octets[0], vp->length);
                kd_len += vp->length;
 
                kd[kd_len] = ':';
                kd_len++;
 
-               memcpy(&kd[kd_len], &qop->strvalue[0], qop->length);
+               memcpy(&kd[kd_len], &qop->vp_octets[0], qop->length);
                kd_len += qop->length;
        }
 
@@ -485,7 +489,10 @@ static int digest_authenticate(void *instance, REQUEST *request)
                return RLM_MODULE_INVALID;
        }
 
-       lrad_hex2bin(&vp->strvalue[0], &hash[0], vp->length >> 1);
+       if (lrad_hex2bin(&vp->vp_octets[0], &hash[0], vp->length >> 1) != (vp->length >> 1)) {
+               DEBUG2("rlm_digest: Invalid text in Digest-Response");
+               return RLM_MODULE_INVALID;
+       }
 
 #ifndef NDEBUG
        if (debug_flag) {
@@ -524,10 +531,11 @@ static int digest_authenticate(void *instance, REQUEST *request)
  *     is single-threaded.
  */
 module_t rlm_digest = {
-       "DIGEST",
+       RLM_MODULE_INIT,
+       "digest",
        0,                              /* type */
-       NULL,                           /* initialization */
        NULL,                           /* instantiation */
+       NULL,                           /* detach */
        {
                digest_authenticate,    /* authentication */
                digest_authorize,       /* authorization */
@@ -538,6 +546,4 @@ module_t rlm_digest = {
                NULL,                   /* post-proxy */
                NULL                    /* post-auth */
        },
-       NULL,                           /* detach */
-       NULL,                           /* destroy */
 };