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