1214501Srpaulo/* 2214501Srpaulo * hostapd / Test method for vendor specific (expanded) EAP type 3214501Srpaulo * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi> 4214501Srpaulo * 5252726Srpaulo * This software may be distributed under the terms of the BSD license. 6252726Srpaulo * See README for more details. 7214501Srpaulo */ 8214501Srpaulo 9214501Srpaulo#include "includes.h" 10214501Srpaulo 11214501Srpaulo#include "common.h" 12214501Srpaulo#include "eap_i.h" 13214501Srpaulo 14214501Srpaulo 15252726Srpaulo#define EAP_VENDOR_ID EAP_VENDOR_HOSTAP 16214501Srpaulo#define EAP_VENDOR_TYPE 0xfcfbfaf9 17214501Srpaulo 18214501Srpaulo 19214501Srpaulostruct eap_vendor_test_data { 20214501Srpaulo enum { INIT, CONFIRM, SUCCESS, FAILURE } state; 21214501Srpaulo}; 22214501Srpaulo 23214501Srpaulo 24214501Srpaulostatic const char * eap_vendor_test_state_txt(int state) 25214501Srpaulo{ 26214501Srpaulo switch (state) { 27214501Srpaulo case INIT: 28214501Srpaulo return "INIT"; 29214501Srpaulo case CONFIRM: 30214501Srpaulo return "CONFIRM"; 31214501Srpaulo case SUCCESS: 32214501Srpaulo return "SUCCESS"; 33214501Srpaulo case FAILURE: 34214501Srpaulo return "FAILURE"; 35214501Srpaulo default: 36214501Srpaulo return "?"; 37214501Srpaulo } 38214501Srpaulo} 39214501Srpaulo 40214501Srpaulo 41214501Srpaulostatic void eap_vendor_test_state(struct eap_vendor_test_data *data, 42214501Srpaulo int state) 43214501Srpaulo{ 44214501Srpaulo wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: %s -> %s", 45214501Srpaulo eap_vendor_test_state_txt(data->state), 46214501Srpaulo eap_vendor_test_state_txt(state)); 47214501Srpaulo data->state = state; 48214501Srpaulo} 49214501Srpaulo 50214501Srpaulo 51214501Srpaulostatic void * eap_vendor_test_init(struct eap_sm *sm) 52214501Srpaulo{ 53214501Srpaulo struct eap_vendor_test_data *data; 54214501Srpaulo 55214501Srpaulo data = os_zalloc(sizeof(*data)); 56214501Srpaulo if (data == NULL) 57214501Srpaulo return NULL; 58214501Srpaulo data->state = INIT; 59214501Srpaulo 60214501Srpaulo return data; 61214501Srpaulo} 62214501Srpaulo 63214501Srpaulo 64214501Srpaulostatic void eap_vendor_test_reset(struct eap_sm *sm, void *priv) 65214501Srpaulo{ 66214501Srpaulo struct eap_vendor_test_data *data = priv; 67214501Srpaulo os_free(data); 68214501Srpaulo} 69214501Srpaulo 70214501Srpaulo 71214501Srpaulostatic struct wpabuf * eap_vendor_test_buildReq(struct eap_sm *sm, void *priv, 72214501Srpaulo u8 id) 73214501Srpaulo{ 74214501Srpaulo struct eap_vendor_test_data *data = priv; 75214501Srpaulo struct wpabuf *req; 76214501Srpaulo 77214501Srpaulo req = eap_msg_alloc(EAP_VENDOR_ID, EAP_VENDOR_TYPE, 1, 78214501Srpaulo EAP_CODE_REQUEST, id); 79214501Srpaulo if (req == NULL) { 80214501Srpaulo wpa_printf(MSG_ERROR, "EAP-VENDOR-TEST: Failed to allocate " 81214501Srpaulo "memory for request"); 82214501Srpaulo return NULL; 83214501Srpaulo } 84214501Srpaulo 85214501Srpaulo wpabuf_put_u8(req, data->state == INIT ? 1 : 3); 86214501Srpaulo 87214501Srpaulo return req; 88214501Srpaulo} 89214501Srpaulo 90214501Srpaulo 91214501Srpaulostatic Boolean eap_vendor_test_check(struct eap_sm *sm, void *priv, 92214501Srpaulo struct wpabuf *respData) 93214501Srpaulo{ 94214501Srpaulo const u8 *pos; 95214501Srpaulo size_t len; 96214501Srpaulo 97214501Srpaulo pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE, respData, &len); 98214501Srpaulo if (pos == NULL || len < 1) { 99214501Srpaulo wpa_printf(MSG_INFO, "EAP-VENDOR-TEST: Invalid frame"); 100214501Srpaulo return TRUE; 101214501Srpaulo } 102214501Srpaulo 103214501Srpaulo return FALSE; 104214501Srpaulo} 105214501Srpaulo 106214501Srpaulo 107214501Srpaulostatic void eap_vendor_test_process(struct eap_sm *sm, void *priv, 108214501Srpaulo struct wpabuf *respData) 109214501Srpaulo{ 110214501Srpaulo struct eap_vendor_test_data *data = priv; 111214501Srpaulo const u8 *pos; 112214501Srpaulo size_t len; 113214501Srpaulo 114214501Srpaulo pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE, respData, &len); 115214501Srpaulo if (pos == NULL || len < 1) 116214501Srpaulo return; 117214501Srpaulo 118214501Srpaulo if (data->state == INIT) { 119214501Srpaulo if (*pos == 2) 120214501Srpaulo eap_vendor_test_state(data, CONFIRM); 121214501Srpaulo else 122214501Srpaulo eap_vendor_test_state(data, FAILURE); 123214501Srpaulo } else if (data->state == CONFIRM) { 124214501Srpaulo if (*pos == 4) 125214501Srpaulo eap_vendor_test_state(data, SUCCESS); 126214501Srpaulo else 127214501Srpaulo eap_vendor_test_state(data, FAILURE); 128214501Srpaulo } else 129214501Srpaulo eap_vendor_test_state(data, FAILURE); 130214501Srpaulo} 131214501Srpaulo 132214501Srpaulo 133214501Srpaulostatic Boolean eap_vendor_test_isDone(struct eap_sm *sm, void *priv) 134214501Srpaulo{ 135214501Srpaulo struct eap_vendor_test_data *data = priv; 136214501Srpaulo return data->state == SUCCESS; 137214501Srpaulo} 138214501Srpaulo 139214501Srpaulo 140214501Srpaulostatic u8 * eap_vendor_test_getKey(struct eap_sm *sm, void *priv, size_t *len) 141214501Srpaulo{ 142214501Srpaulo struct eap_vendor_test_data *data = priv; 143214501Srpaulo u8 *key; 144214501Srpaulo const int key_len = 64; 145214501Srpaulo 146214501Srpaulo if (data->state != SUCCESS) 147214501Srpaulo return NULL; 148214501Srpaulo 149214501Srpaulo key = os_malloc(key_len); 150214501Srpaulo if (key == NULL) 151214501Srpaulo return NULL; 152214501Srpaulo 153214501Srpaulo os_memset(key, 0x11, key_len / 2); 154214501Srpaulo os_memset(key + key_len / 2, 0x22, key_len / 2); 155214501Srpaulo *len = key_len; 156214501Srpaulo 157214501Srpaulo return key; 158214501Srpaulo} 159214501Srpaulo 160214501Srpaulo 161214501Srpaulostatic Boolean eap_vendor_test_isSuccess(struct eap_sm *sm, void *priv) 162214501Srpaulo{ 163214501Srpaulo struct eap_vendor_test_data *data = priv; 164214501Srpaulo return data->state == SUCCESS; 165214501Srpaulo} 166214501Srpaulo 167214501Srpaulo 168214501Srpauloint eap_server_vendor_test_register(void) 169214501Srpaulo{ 170214501Srpaulo struct eap_method *eap; 171214501Srpaulo 172214501Srpaulo eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, 173214501Srpaulo EAP_VENDOR_ID, EAP_VENDOR_TYPE, 174214501Srpaulo "VENDOR-TEST"); 175214501Srpaulo if (eap == NULL) 176214501Srpaulo return -1; 177214501Srpaulo 178214501Srpaulo eap->init = eap_vendor_test_init; 179214501Srpaulo eap->reset = eap_vendor_test_reset; 180214501Srpaulo eap->buildReq = eap_vendor_test_buildReq; 181214501Srpaulo eap->check = eap_vendor_test_check; 182214501Srpaulo eap->process = eap_vendor_test_process; 183214501Srpaulo eap->isDone = eap_vendor_test_isDone; 184214501Srpaulo eap->getKey = eap_vendor_test_getKey; 185214501Srpaulo eap->isSuccess = eap_vendor_test_isSuccess; 186214501Srpaulo 187337817Scy return eap_server_method_register(eap); 188214501Srpaulo} 189