| /* |
| * hostapd / Test method for vendor specific (expanded) EAP type |
| * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi> |
| * |
| * This software may be distributed under the terms of the BSD license. |
| * See README for more details. |
| */ |
| |
| #include "includes.h" |
| |
| #include "common.h" |
| #include "eap_i.h" |
| |
| |
| #define EAP_VENDOR_ID EAP_VENDOR_HOSTAP |
| #define EAP_VENDOR_TYPE 0xfcfbfaf9 |
| |
| |
| struct eap_vendor_test_data { |
| enum { INIT, CONFIRM, SUCCESS, FAILURE } state; |
| }; |
| |
| |
| static const char * eap_vendor_test_state_txt(int state) |
| { |
| switch (state) { |
| case INIT: |
| return "INIT"; |
| case CONFIRM: |
| return "CONFIRM"; |
| case SUCCESS: |
| return "SUCCESS"; |
| case FAILURE: |
| return "FAILURE"; |
| default: |
| return "?"; |
| } |
| } |
| |
| |
| static void eap_vendor_test_state(struct eap_vendor_test_data *data, |
| int state) |
| { |
| wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: %s -> %s", |
| eap_vendor_test_state_txt(data->state), |
| eap_vendor_test_state_txt(state)); |
| data->state = state; |
| } |
| |
| |
| static void * eap_vendor_test_init(struct eap_sm *sm) |
| { |
| struct eap_vendor_test_data *data; |
| |
| data = os_zalloc(sizeof(*data)); |
| if (data == NULL) |
| return NULL; |
| data->state = INIT; |
| |
| return data; |
| } |
| |
| |
| static void eap_vendor_test_reset(struct eap_sm *sm, void *priv) |
| { |
| struct eap_vendor_test_data *data = priv; |
| os_free(data); |
| } |
| |
| |
| static struct wpabuf * eap_vendor_test_buildReq(struct eap_sm *sm, void *priv, |
| u8 id) |
| { |
| struct eap_vendor_test_data *data = priv; |
| struct wpabuf *req; |
| |
| req = eap_msg_alloc(EAP_VENDOR_ID, EAP_VENDOR_TYPE, 1, |
| EAP_CODE_REQUEST, id); |
| if (req == NULL) { |
| wpa_printf(MSG_ERROR, "EAP-VENDOR-TEST: Failed to allocate " |
| "memory for request"); |
| return NULL; |
| } |
| |
| wpabuf_put_u8(req, data->state == INIT ? 1 : 3); |
| |
| return req; |
| } |
| |
| |
| static Boolean eap_vendor_test_check(struct eap_sm *sm, void *priv, |
| struct wpabuf *respData) |
| { |
| const u8 *pos; |
| size_t len; |
| |
| pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE, respData, &len); |
| if (pos == NULL || len < 1) { |
| wpa_printf(MSG_INFO, "EAP-VENDOR-TEST: Invalid frame"); |
| return TRUE; |
| } |
| |
| return FALSE; |
| } |
| |
| |
| static void eap_vendor_test_process(struct eap_sm *sm, void *priv, |
| struct wpabuf *respData) |
| { |
| struct eap_vendor_test_data *data = priv; |
| const u8 *pos; |
| size_t len; |
| |
| pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE, respData, &len); |
| if (pos == NULL || len < 1) |
| return; |
| |
| if (data->state == INIT) { |
| if (*pos == 2) |
| eap_vendor_test_state(data, CONFIRM); |
| else |
| eap_vendor_test_state(data, FAILURE); |
| } else if (data->state == CONFIRM) { |
| if (*pos == 4) |
| eap_vendor_test_state(data, SUCCESS); |
| else |
| eap_vendor_test_state(data, FAILURE); |
| } else |
| eap_vendor_test_state(data, FAILURE); |
| } |
| |
| |
| static Boolean eap_vendor_test_isDone(struct eap_sm *sm, void *priv) |
| { |
| struct eap_vendor_test_data *data = priv; |
| return data->state == SUCCESS; |
| } |
| |
| |
| static u8 * eap_vendor_test_getKey(struct eap_sm *sm, void *priv, size_t *len) |
| { |
| struct eap_vendor_test_data *data = priv; |
| u8 *key; |
| const int key_len = 64; |
| |
| if (data->state != SUCCESS) |
| return NULL; |
| |
| key = os_malloc(key_len); |
| if (key == NULL) |
| return NULL; |
| |
| os_memset(key, 0x11, key_len / 2); |
| os_memset(key + key_len / 2, 0x22, key_len / 2); |
| *len = key_len; |
| |
| return key; |
| } |
| |
| |
| static Boolean eap_vendor_test_isSuccess(struct eap_sm *sm, void *priv) |
| { |
| struct eap_vendor_test_data *data = priv; |
| return data->state == SUCCESS; |
| } |
| |
| |
| int eap_server_vendor_test_register(void) |
| { |
| struct eap_method *eap; |
| int ret; |
| |
| eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, |
| EAP_VENDOR_ID, EAP_VENDOR_TYPE, |
| "VENDOR-TEST"); |
| if (eap == NULL) |
| return -1; |
| |
| eap->init = eap_vendor_test_init; |
| eap->reset = eap_vendor_test_reset; |
| eap->buildReq = eap_vendor_test_buildReq; |
| eap->check = eap_vendor_test_check; |
| eap->process = eap_vendor_test_process; |
| eap->isDone = eap_vendor_test_isDone; |
| eap->getKey = eap_vendor_test_getKey; |
| eap->isSuccess = eap_vendor_test_isSuccess; |
| |
| ret = eap_server_method_register(eap); |
| if (ret) |
| eap_server_method_free(eap); |
| return ret; |
| } |