Add a require_message_authenticator configuration option
[mech_eap.git] / src / radius / radius.c
index b92cce7..407e4f8 100644 (file)
@@ -173,6 +173,7 @@ static const struct radius_attr_type radius_attrs[] =
        { RADIUS_ATTR_USER_PASSWORD, "User-Password", RADIUS_ATTR_UNDIST },
        { RADIUS_ATTR_NAS_IP_ADDRESS, "NAS-IP-Address", RADIUS_ATTR_IP },
        { RADIUS_ATTR_NAS_PORT, "NAS-Port", RADIUS_ATTR_INT32 },
+       { RADIUS_ATTR_SERVICE_TYPE, "Service-Type", RADIUS_ATTR_INT32 },
        { RADIUS_ATTR_FRAMED_IP_ADDRESS, "Framed-IP-Address", RADIUS_ATTR_IP },
        { RADIUS_ATTR_FRAMED_MTU, "Framed-MTU", RADIUS_ATTR_INT32 },
        { RADIUS_ATTR_REPLY_MESSAGE, "Reply-Message", RADIUS_ATTR_TEXT },
@@ -537,7 +538,8 @@ int radius_msg_verify_acct_req(struct radius_msg *msg, const u8 *secret,
 
 
 int radius_msg_verify_das_req(struct radius_msg *msg, const u8 *secret,
-                             size_t secret_len)
+                             size_t secret_len,
+                             int require_message_authenticator)
 {
        const u8 *addr[4];
        size_t len[4];
@@ -576,7 +578,11 @@ int radius_msg_verify_das_req(struct radius_msg *msg, const u8 *secret,
        }
 
        if (attr == NULL) {
-               /* Message-Authenticator is MAY; not required */
+               if (require_message_authenticator) {
+                       wpa_printf(MSG_WARNING,
+                                  "Missing Message-Authenticator attribute in RADIUS message");
+                       return 1;
+               }
                return 0;
        }
 
@@ -817,8 +823,9 @@ int radius_msg_verify_msg_auth(struct radius_msg *msg, const u8 *secret,
                os_memcpy(msg->hdr->authenticator, req_auth,
                          sizeof(msg->hdr->authenticator));
        }
-       hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
-                wpabuf_len(msg->buf), auth);
+       if (hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
+                    wpabuf_len(msg->buf), auth) < 0)
+               return 1;
        os_memcpy(attr + 1, orig, MD5_MAC_LEN);
        if (req_auth) {
                os_memcpy(msg->hdr->authenticator, orig_authenticator,
@@ -861,8 +868,8 @@ int radius_msg_verify(struct radius_msg *msg, const u8 *secret,
        len[2] = wpabuf_len(msg->buf) - sizeof(struct radius_hdr);
        addr[3] = secret;
        len[3] = secret_len;
-       md5_vector(4, addr, len, hash);
-       if (os_memcmp_const(hash, msg->hdr->authenticator, MD5_MAC_LEN) != 0) {
+       if (md5_vector(4, addr, len, hash) < 0 ||
+           os_memcmp_const(hash, msg->hdr->authenticator, MD5_MAC_LEN) != 0) {
                wpa_printf(MSG_INFO, "Response Authenticator invalid!");
                return 1;
        }
@@ -1016,7 +1023,10 @@ static u8 * decrypt_ms_key(const u8 *key, size_t len,
                        addr[1] = pos - MD5_MAC_LEN;
                        elen[1] = MD5_MAC_LEN;
                }
-               md5_vector(first ? 3 : 2, addr, elen, hash);
+               if (md5_vector(first ? 3 : 2, addr, elen, hash) < 0) {
+                       os_free(plain);
+                       return NULL;
+               }
                first = 0;
 
                for (i = 0; i < MD5_MAC_LEN; i++)
@@ -1198,8 +1208,10 @@ int radius_msg_add_mppe_keys(struct radius_msg *msg,
        vhdr = (struct radius_attr_vendor *) pos;
        vhdr->vendor_type = RADIUS_VENDOR_ATTR_MS_MPPE_SEND_KEY;
        pos = (u8 *) (vhdr + 1);
-       if (os_get_random((u8 *) &salt, sizeof(salt)) < 0)
+       if (os_get_random((u8 *) &salt, sizeof(salt)) < 0) {
+               os_free(buf);
                return 0;
+       }
        salt |= 0x8000;
        WPA_PUT_BE16(pos, salt);
        pos += 2;