Home | History | Annotate | Download | only in eap_server
      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 
    172 	eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
    173 				      EAP_VENDOR_ID, EAP_VENDOR_TYPE,
    174 				      "VENDOR-TEST");
    175 	if (eap == NULL)
    176 		return -1;
    177 
    178 	eap->init = eap_vendor_test_init;
    179 	eap->reset = eap_vendor_test_reset;
    180 	eap->buildReq = eap_vendor_test_buildReq;
    181 	eap->check = eap_vendor_test_check;
    182 	eap->process = eap_vendor_test_process;
    183 	eap->isDone = eap_vendor_test_isDone;
    184 	eap->getKey = eap_vendor_test_getKey;
    185 	eap->isSuccess = eap_vendor_test_isSuccess;
    186 
    187 	return eap_server_method_register(eap);
    188 }
    189