eap_server_vendor_test.c revision 8d520ff1dc2da35cdca849e982051b86468016d8
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * hostapd / Test method for vendor specific (expanded) EAP type
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi>
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This program is free software; you can redistribute it and/or modify
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * it under the terms of the GNU General Public License version 2 as
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * published by the Free Software Foundation.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Alternatively, this software may be distributed under the terms of BSD
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * license.
119ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch *
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See README and COPYING for more details.
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "includes.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "common.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "eap_i.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EAP_VENDOR_ID 0xfffefd
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EAP_VENDOR_TYPE 0xfcfbfaf9
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct eap_vendor_test_data {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	enum { INIT, CONFIRM, SUCCESS, FAILURE } state;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char * eap_vendor_test_state_txt(int state)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch (state) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case INIT:
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return "INIT";
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case CONFIRM:
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return "CONFIRM";
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case SUCCESS:
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return "SUCCESS";
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case FAILURE:
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return "FAILURE";
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return "?";
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void eap_vendor_test_state(struct eap_vendor_test_data *data,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				  int state)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: %s -> %s",
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   eap_vendor_test_state_txt(data->state),
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)		   eap_vendor_test_state_txt(state));
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	data->state = state;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void * eap_vendor_test_init(struct eap_sm *sm)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct eap_vendor_test_data *data;
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	data = os_zalloc(sizeof(*data));
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (data == NULL)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return NULL;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	data->state = INIT;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return data;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void eap_vendor_test_reset(struct eap_sm *sm, void *priv)
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	struct eap_vendor_test_data *data = priv;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	os_free(data);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct wpabuf * eap_vendor_test_buildReq(struct eap_sm *sm, void *priv,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						u8 id)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	struct eap_vendor_test_data *data = priv;
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	struct wpabuf *req;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	req = eap_msg_alloc(EAP_VENDOR_ID, EAP_VENDOR_TYPE, 1,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    EAP_CODE_REQUEST, id);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (req == NULL) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		wpa_printf(MSG_ERROR, "EAP-VENDOR-TEST: Failed to allocate "
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   "memory for request");
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return NULL;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	wpabuf_put_u8(req, data->state == INIT ? 1 : 3);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return req;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static Boolean eap_vendor_test_check(struct eap_sm *sm, void *priv,
9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)				     struct wpabuf *respData)
9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	const u8 *pos;
10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	size_t len;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE, respData, &len);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (pos == NULL || len < 1) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		wpa_printf(MSG_INFO, "EAP-VENDOR-TEST: Invalid frame");
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return TRUE;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return FALSE;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void eap_vendor_test_process(struct eap_sm *sm, void *priv,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    struct wpabuf *respData)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct eap_vendor_test_data *data = priv;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const u8 *pos;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	size_t len;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE, respData, &len);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (pos == NULL || len < 1)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (data->state == INIT) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (*pos == 2)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			eap_vendor_test_state(data, CONFIRM);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			eap_vendor_test_state(data, FAILURE);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (data->state == CONFIRM) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (*pos == 4)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			eap_vendor_test_state(data, SUCCESS);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			eap_vendor_test_state(data, FAILURE);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		eap_vendor_test_state(data, FAILURE);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Boolean eap_vendor_test_isDone(struct eap_sm *sm, void *priv)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct eap_vendor_test_data *data = priv;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return data->state == SUCCESS;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static u8 * eap_vendor_test_getKey(struct eap_sm *sm, void *priv, size_t *len)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct eap_vendor_test_data *data = priv;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	u8 *key;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const int key_len = 64;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (data->state != SUCCESS)
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)		return NULL;
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	key = os_malloc(key_len);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (key == NULL)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return NULL;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	os_memset(key, 0x11, key_len / 2);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	os_memset(key + key_len / 2, 0x22, key_len / 2);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*len = key_len;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)	return key;
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Boolean eap_vendor_test_isSuccess(struct eap_sm *sm, void *priv)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct eap_vendor_test_data *data = priv;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return data->state == SUCCESS;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int eap_server_vendor_test_register(void)
1758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles){
1768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)	struct eap_method *eap;
1778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)	int ret;
1788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				      EAP_VENDOR_ID, EAP_VENDOR_TYPE,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				      "VENDOR-TEST");
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (eap == NULL)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return -1;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	eap->init = eap_vendor_test_init;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	eap->reset = eap_vendor_test_reset;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	eap->buildReq = eap_vendor_test_buildReq;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	eap->check = eap_vendor_test_check;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	eap->process = eap_vendor_test_process;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	eap->isDone = eap_vendor_test_isDone;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	eap->getKey = eap_vendor_test_getKey;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	eap->isSuccess = eap_vendor_test_isSuccess;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = eap_server_method_register(eap);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ret)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		eap_server_method_free(eap);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return ret;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)