00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016
00017 #include "common.h"
00018 #include "eap_i.h"
00019 #include "eap_common/chap.h"
00020
00021
00022 static void * eap_md5_init(struct eap_sm *sm)
00023 {
00024
00025
00026 return (void *) 1;
00027 }
00028
00029
00030 static void eap_md5_deinit(struct eap_sm *sm, void *priv)
00031 {
00032 }
00033
00034
00035 static struct wpabuf * eap_md5_process(struct eap_sm *sm, void *priv,
00036 struct eap_method_ret *ret,
00037 const struct wpabuf *reqData)
00038 {
00039 struct wpabuf *resp;
00040 const u8 *pos, *challenge, *password;
00041 u8 *rpos, id;
00042 size_t len, challenge_len, password_len;
00043
00044 password = eap_get_config_password(sm, &password_len);
00045 if (password == NULL) {
00046 wpa_printf(MSG_INFO, "EAP-MD5: Password not configured");
00047 eap_sm_request_password(sm);
00048 ret->ignore = TRUE;
00049 return NULL;
00050 }
00051
00052 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MD5, reqData, &len);
00053 if (pos == NULL || len == 0) {
00054 wpa_printf(MSG_INFO, "EAP-MD5: Invalid frame (pos=%p len=%lu)",
00055 pos, (unsigned long) len);
00056 ret->ignore = TRUE;
00057 return NULL;
00058 }
00059
00060
00061
00062
00063
00064 challenge_len = *pos++;
00065 if (challenge_len == 0 || challenge_len > len - 1) {
00066 wpa_printf(MSG_INFO, "EAP-MD5: Invalid challenge "
00067 "(challenge_len=%lu len=%lu)",
00068 (unsigned long) challenge_len, (unsigned long) len);
00069 ret->ignore = TRUE;
00070 return NULL;
00071 }
00072 ret->ignore = FALSE;
00073 challenge = pos;
00074 wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Challenge",
00075 challenge, challenge_len);
00076
00077 wpa_printf(MSG_DEBUG, "EAP-MD5: Generating Challenge Response");
00078 ret->methodState = METHOD_DONE;
00079 ret->decision = DECISION_COND_SUCC;
00080 ret->allowNotifications = TRUE;
00081
00082 resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MD5, 1 + CHAP_MD5_LEN,
00083 EAP_CODE_RESPONSE, eap_get_id(reqData));
00084 if (resp == NULL)
00085 return NULL;
00086
00087
00088
00089
00090
00091 wpabuf_put_u8(resp, CHAP_MD5_LEN);
00092
00093 id = eap_get_id(resp);
00094 rpos = wpabuf_put(resp, CHAP_MD5_LEN);
00095 chap_md5(id, password, password_len, challenge, challenge_len, rpos);
00096 wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Response", rpos, CHAP_MD5_LEN);
00097
00098 return resp;
00099 }
00100
00101
00102 int eap_peer_md5_register(void)
00103 {
00104 struct eap_method *eap;
00105 int ret;
00106
00107 eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
00108 EAP_VENDOR_IETF, EAP_TYPE_MD5, "MD5");
00109 if (eap == NULL)
00110 return -1;
00111
00112 eap->init = eap_md5_init;
00113 eap->deinit = eap_md5_deinit;
00114 eap->process = eap_md5_process;
00115
00116 ret = eap_peer_method_register(eap);
00117 if (ret)
00118 eap_peer_method_free(eap);
00119 return ret;
00120 }