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