$search
00001 /* 00002 * hostapd / Test method for vendor specific (expanded) EAP type 00003 * Copyright (c) 2005-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 00020 00021 #define EAP_VENDOR_ID 0xfffefd 00022 #define EAP_VENDOR_TYPE 0xfcfbfaf9 00023 00024 00025 struct eap_vendor_test_data { 00026 enum { INIT, CONFIRM, SUCCESS, FAILURE } state; 00027 }; 00028 00029 00030 static const char * eap_vendor_test_state_txt(int state) 00031 { 00032 switch (state) { 00033 case INIT: 00034 return "INIT"; 00035 case CONFIRM: 00036 return "CONFIRM"; 00037 case SUCCESS: 00038 return "SUCCESS"; 00039 case FAILURE: 00040 return "FAILURE"; 00041 default: 00042 return "?"; 00043 } 00044 } 00045 00046 00047 static void eap_vendor_test_state(struct eap_vendor_test_data *data, 00048 int state) 00049 { 00050 wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: %s -> %s", 00051 eap_vendor_test_state_txt(data->state), 00052 eap_vendor_test_state_txt(state)); 00053 data->state = state; 00054 } 00055 00056 00057 static void * eap_vendor_test_init(struct eap_sm *sm) 00058 { 00059 struct eap_vendor_test_data *data; 00060 00061 data = os_zalloc(sizeof(*data)); 00062 if (data == NULL) 00063 return NULL; 00064 data->state = INIT; 00065 00066 return data; 00067 } 00068 00069 00070 static void eap_vendor_test_reset(struct eap_sm *sm, void *priv) 00071 { 00072 struct eap_vendor_test_data *data = priv; 00073 os_free(data); 00074 } 00075 00076 00077 static struct wpabuf * eap_vendor_test_buildReq(struct eap_sm *sm, void *priv, 00078 u8 id) 00079 { 00080 struct eap_vendor_test_data *data = priv; 00081 struct wpabuf *req; 00082 00083 req = eap_msg_alloc(EAP_VENDOR_ID, EAP_VENDOR_TYPE, 1, 00084 EAP_CODE_REQUEST, id); 00085 if (req == NULL) { 00086 wpa_printf(MSG_ERROR, "EAP-VENDOR-TEST: Failed to allocate " 00087 "memory for request"); 00088 return NULL; 00089 } 00090 00091 wpabuf_put_u8(req, data->state == INIT ? 1 : 3); 00092 00093 return req; 00094 } 00095 00096 00097 static Boolean eap_vendor_test_check(struct eap_sm *sm, void *priv, 00098 struct wpabuf *respData) 00099 { 00100 const u8 *pos; 00101 size_t len; 00102 00103 pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE, respData, &len); 00104 if (pos == NULL || len < 1) { 00105 wpa_printf(MSG_INFO, "EAP-VENDOR-TEST: Invalid frame"); 00106 return TRUE; 00107 } 00108 00109 return FALSE; 00110 } 00111 00112 00113 static void eap_vendor_test_process(struct eap_sm *sm, void *priv, 00114 struct wpabuf *respData) 00115 { 00116 struct eap_vendor_test_data *data = priv; 00117 const u8 *pos; 00118 size_t len; 00119 00120 pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE, respData, &len); 00121 if (pos == NULL || len < 1) 00122 return; 00123 00124 if (data->state == INIT) { 00125 if (*pos == 2) 00126 eap_vendor_test_state(data, CONFIRM); 00127 else 00128 eap_vendor_test_state(data, FAILURE); 00129 } else if (data->state == CONFIRM) { 00130 if (*pos == 4) 00131 eap_vendor_test_state(data, SUCCESS); 00132 else 00133 eap_vendor_test_state(data, FAILURE); 00134 } else 00135 eap_vendor_test_state(data, FAILURE); 00136 } 00137 00138 00139 static Boolean eap_vendor_test_isDone(struct eap_sm *sm, void *priv) 00140 { 00141 struct eap_vendor_test_data *data = priv; 00142 return data->state == SUCCESS; 00143 } 00144 00145 00146 static u8 * eap_vendor_test_getKey(struct eap_sm *sm, void *priv, size_t *len) 00147 { 00148 struct eap_vendor_test_data *data = priv; 00149 u8 *key; 00150 const int key_len = 64; 00151 00152 if (data->state != SUCCESS) 00153 return NULL; 00154 00155 key = os_malloc(key_len); 00156 if (key == NULL) 00157 return NULL; 00158 00159 os_memset(key, 0x11, key_len / 2); 00160 os_memset(key + key_len / 2, 0x22, key_len / 2); 00161 *len = key_len; 00162 00163 return key; 00164 } 00165 00166 00167 static Boolean eap_vendor_test_isSuccess(struct eap_sm *sm, void *priv) 00168 { 00169 struct eap_vendor_test_data *data = priv; 00170 return data->state == SUCCESS; 00171 } 00172 00173 00174 int eap_server_vendor_test_register(void) 00175 { 00176 struct eap_method *eap; 00177 int ret; 00178 00179 eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, 00180 EAP_VENDOR_ID, EAP_VENDOR_TYPE, 00181 "VENDOR-TEST"); 00182 if (eap == NULL) 00183 return -1; 00184 00185 eap->init = eap_vendor_test_init; 00186 eap->reset = eap_vendor_test_reset; 00187 eap->buildReq = eap_vendor_test_buildReq; 00188 eap->check = eap_vendor_test_check; 00189 eap->process = eap_vendor_test_process; 00190 eap->isDone = eap_vendor_test_isDone; 00191 eap->getKey = eap_vendor_test_getKey; 00192 eap->isSuccess = eap_vendor_test_isSuccess; 00193 00194 ret = eap_server_method_register(eap); 00195 if (ret) 00196 eap_server_method_free(eap); 00197 return ret; 00198 }