1 /* 2 * hostapd / Test method for vendor specific (expanded) EAP type 3 * Copyright (c) 2005-2007, Jouni Malinen <j (at) 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 25 struct eap_vendor_test_data { 26 enum { INIT, CONFIRM, SUCCESS, FAILURE } state; 27 }; 28 29 30 static 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 47 static 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 57 static 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 70 static 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 77 static 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 97 static 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 113 static 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 139 static 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 146 static 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 167 static 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 174 int 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