eap_server_md5.c
Go to the documentation of this file.
00001 /*
00002  * hostapd / EAP-MD5 server
00003  * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
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 #define CHALLENGE_LEN 16
00023 
00024 struct eap_md5_data {
00025         u8 challenge[CHALLENGE_LEN];
00026         enum { CONTINUE, SUCCESS, FAILURE } state;
00027 };
00028 
00029 
00030 static void * eap_md5_init(struct eap_sm *sm)
00031 {
00032         struct eap_md5_data *data;
00033 
00034         data = os_zalloc(sizeof(*data));
00035         if (data == NULL)
00036                 return NULL;
00037         data->state = CONTINUE;
00038 
00039         return data;
00040 }
00041 
00042 
00043 static void eap_md5_reset(struct eap_sm *sm, void *priv)
00044 {
00045         struct eap_md5_data *data = priv;
00046         os_free(data);
00047 }
00048 
00049 
00050 static struct wpabuf * eap_md5_buildReq(struct eap_sm *sm, void *priv, u8 id)
00051 {
00052         struct eap_md5_data *data = priv;
00053         struct wpabuf *req;
00054 
00055         if (os_get_random(data->challenge, CHALLENGE_LEN)) {
00056                 wpa_printf(MSG_ERROR, "EAP-MD5: Failed to get random data");
00057                 data->state = FAILURE;
00058                 return NULL;
00059         }
00060 
00061         req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MD5, 1 + CHALLENGE_LEN,
00062                             EAP_CODE_REQUEST, id);
00063         if (req == NULL) {
00064                 wpa_printf(MSG_ERROR, "EAP-MD5: Failed to allocate memory for "
00065                            "request");
00066                 data->state = FAILURE;
00067                 return NULL;
00068         }
00069 
00070         wpabuf_put_u8(req, CHALLENGE_LEN);
00071         wpabuf_put_data(req, data->challenge, CHALLENGE_LEN);
00072         wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Challenge", data->challenge,
00073                     CHALLENGE_LEN);
00074 
00075         data->state = CONTINUE;
00076 
00077         return req;
00078 }
00079 
00080 
00081 static Boolean eap_md5_check(struct eap_sm *sm, void *priv,
00082                              struct wpabuf *respData)
00083 {
00084         const u8 *pos;
00085         size_t len;
00086 
00087         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MD5, respData, &len);
00088         if (pos == NULL || len < 1) {
00089                 wpa_printf(MSG_INFO, "EAP-MD5: Invalid frame");
00090                 return TRUE;
00091         }
00092         if (*pos != CHAP_MD5_LEN || 1 + CHAP_MD5_LEN > len) {
00093                 wpa_printf(MSG_INFO, "EAP-MD5: Invalid response "
00094                            "(response_len=%d payload_len=%lu",
00095                            *pos, (unsigned long) len);
00096                 return TRUE;
00097         }
00098 
00099         return FALSE;
00100 }
00101 
00102 
00103 static void eap_md5_process(struct eap_sm *sm, void *priv,
00104                             struct wpabuf *respData)
00105 {
00106         struct eap_md5_data *data = priv;
00107         const u8 *pos;
00108         size_t plen;
00109         u8 hash[CHAP_MD5_LEN], id;
00110 
00111         if (sm->user == NULL || sm->user->password == NULL ||
00112             sm->user->password_hash) {
00113                 wpa_printf(MSG_INFO, "EAP-MD5: Plaintext password not "
00114                            "configured");
00115                 data->state = FAILURE;
00116                 return;
00117         }
00118 
00119         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MD5, respData, &plen);
00120         if (pos == NULL || *pos != CHAP_MD5_LEN || plen < 1 + CHAP_MD5_LEN)
00121                 return; /* Should not happen - frame already validated */
00122 
00123         pos++; /* Skip response len */
00124         wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Response", pos, CHAP_MD5_LEN);
00125 
00126         id = eap_get_id(respData);
00127         chap_md5(id, sm->user->password, sm->user->password_len,
00128                  data->challenge, CHALLENGE_LEN, hash);
00129 
00130         if (os_memcmp(hash, pos, CHAP_MD5_LEN) == 0) {
00131                 wpa_printf(MSG_DEBUG, "EAP-MD5: Done - Success");
00132                 data->state = SUCCESS;
00133         } else {
00134                 wpa_printf(MSG_DEBUG, "EAP-MD5: Done - Failure");
00135                 data->state = FAILURE;
00136         }
00137 }
00138 
00139 
00140 static Boolean eap_md5_isDone(struct eap_sm *sm, void *priv)
00141 {
00142         struct eap_md5_data *data = priv;
00143         return data->state != CONTINUE;
00144 }
00145 
00146 
00147 static Boolean eap_md5_isSuccess(struct eap_sm *sm, void *priv)
00148 {
00149         struct eap_md5_data *data = priv;
00150         return data->state == SUCCESS;
00151 }
00152 
00153 
00154 int eap_server_md5_register(void)
00155 {
00156         struct eap_method *eap;
00157         int ret;
00158 
00159         eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
00160                                       EAP_VENDOR_IETF, EAP_TYPE_MD5, "MD5");
00161         if (eap == NULL)
00162                 return -1;
00163 
00164         eap->init = eap_md5_init;
00165         eap->reset = eap_md5_reset;
00166         eap->buildReq = eap_md5_buildReq;
00167         eap->check = eap_md5_check;
00168         eap->process = eap_md5_process;
00169         eap->isDone = eap_md5_isDone;
00170         eap->isSuccess = eap_md5_isSuccess;
00171 
00172         ret = eap_server_method_register(eap);
00173         if (ret)
00174                 eap_server_method_free(eap);
00175         return ret;
00176 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Jan 2 2014 11:26:37