eap_server_vendor_test.c revision 214501
1/* 2 * hostapd / Test method for vendor specific (expanded) EAP type 3 * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15#include "includes.h" 16 17#include "common.h" 18#include "eap_i.h" 19 20 21#define EAP_VENDOR_ID 0xfffefd 22#define EAP_VENDOR_TYPE 0xfcfbfaf9 23 24 25struct eap_vendor_test_data { 26 enum { INIT, CONFIRM, SUCCESS, FAILURE } state; 27}; 28 29 30static const char * eap_vendor_test_state_txt(int state) 31{ 32 switch (state) { 33 case INIT: 34 return "INIT"; 35 case CONFIRM: 36 return "CONFIRM"; 37 case SUCCESS: 38 return "SUCCESS"; 39 case FAILURE: 40 return "FAILURE"; 41 default: 42 return "?"; 43 } 44} 45 46 47static void eap_vendor_test_state(struct eap_vendor_test_data *data, 48 int state) 49{ 50 wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: %s -> %s", 51 eap_vendor_test_state_txt(data->state), 52 eap_vendor_test_state_txt(state)); 53 data->state = state; 54} 55 56 57static void * eap_vendor_test_init(struct eap_sm *sm) 58{ 59 struct eap_vendor_test_data *data; 60 61 data = os_zalloc(sizeof(*data)); 62 if (data == NULL) 63 return NULL; 64 data->state = INIT; 65 66 return data; 67} 68 69 70static void eap_vendor_test_reset(struct eap_sm *sm, void *priv) 71{ 72 struct eap_vendor_test_data *data = priv; 73 os_free(data); 74} 75 76 77static struct wpabuf * eap_vendor_test_buildReq(struct eap_sm *sm, void *priv, 78 u8 id) 79{ 80 struct eap_vendor_test_data *data = priv; 81 struct wpabuf *req; 82 83 req = eap_msg_alloc(EAP_VENDOR_ID, EAP_VENDOR_TYPE, 1, 84 EAP_CODE_REQUEST, id); 85 if (req == NULL) { 86 wpa_printf(MSG_ERROR, "EAP-VENDOR-TEST: Failed to allocate " 87 "memory for request"); 88 return NULL; 89 } 90 91 wpabuf_put_u8(req, data->state == INIT ? 1 : 3); 92 93 return req; 94} 95 96 97static Boolean eap_vendor_test_check(struct eap_sm *sm, void *priv, 98 struct wpabuf *respData) 99{ 100 const u8 *pos; 101 size_t len; 102 103 pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE, respData, &len); 104 if (pos == NULL || len < 1) { 105 wpa_printf(MSG_INFO, "EAP-VENDOR-TEST: Invalid frame"); 106 return TRUE; 107 } 108 109 return FALSE; 110} 111 112 113static void eap_vendor_test_process(struct eap_sm *sm, void *priv, 114 struct wpabuf *respData) 115{ 116 struct eap_vendor_test_data *data = priv; 117 const u8 *pos; 118 size_t len; 119 120 pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE, respData, &len); 121 if (pos == NULL || len < 1) 122 return; 123 124 if (data->state == INIT) { 125 if (*pos == 2) 126 eap_vendor_test_state(data, CONFIRM); 127 else 128 eap_vendor_test_state(data, FAILURE); 129 } else if (data->state == CONFIRM) { 130 if (*pos == 4) 131 eap_vendor_test_state(data, SUCCESS); 132 else 133 eap_vendor_test_state(data, FAILURE); 134 } else 135 eap_vendor_test_state(data, FAILURE); 136} 137 138 139static Boolean eap_vendor_test_isDone(struct eap_sm *sm, void *priv) 140{ 141 struct eap_vendor_test_data *data = priv; 142 return data->state == SUCCESS; 143} 144 145 146static u8 * eap_vendor_test_getKey(struct eap_sm *sm, void *priv, size_t *len) 147{ 148 struct eap_vendor_test_data *data = priv; 149 u8 *key; 150 const int key_len = 64; 151 152 if (data->state != SUCCESS) 153 return NULL; 154 155 key = os_malloc(key_len); 156 if (key == NULL) 157 return NULL; 158 159 os_memset(key, 0x11, key_len / 2); 160 os_memset(key + key_len / 2, 0x22, key_len / 2); 161 *len = key_len; 162 163 return key; 164} 165 166 167static Boolean eap_vendor_test_isSuccess(struct eap_sm *sm, void *priv) 168{ 169 struct eap_vendor_test_data *data = priv; 170 return data->state == SUCCESS; 171} 172 173 174int eap_server_vendor_test_register(void) 175{ 176 struct eap_method *eap; 177 int ret; 178 179 eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, 180 EAP_VENDOR_ID, EAP_VENDOR_TYPE, 181 "VENDOR-TEST"); 182 if (eap == NULL) 183 return -1; 184 185 eap->init = eap_vendor_test_init; 186 eap->reset = eap_vendor_test_reset; 187 eap->buildReq = eap_vendor_test_buildReq; 188 eap->check = eap_vendor_test_check; 189 eap->process = eap_vendor_test_process; 190 eap->isDone = eap_vendor_test_isDone; 191 eap->getKey = eap_vendor_test_getKey; 192 eap->isSuccess = eap_vendor_test_isSuccess; 193 194 ret = eap_server_method_register(eap); 195 if (ret) 196 eap_server_method_free(eap); 197 return ret; 198} 199