Home | History | Annotate | Download | only in eap_peer
      1 /*
      2  * EAP peer method: Test method for vendor specific (expanded) EAP type
      3  * Copyright (c) 2005-2006, 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  * This file implements a vendor specific test method using EAP expanded types.
     15  * This is only for test use and must not be used for authentication since no
     16  * security is provided.
     17  */
     18 
     19 #include "includes.h"
     20 
     21 #include "common.h"
     22 #include "eap_i.h"
     23 #ifdef TEST_PENDING_REQUEST
     24 #include "eloop.h"
     25 #endif /* TEST_PENDING_REQUEST */
     26 
     27 
     28 #define EAP_VENDOR_ID 0xfffefd
     29 #define EAP_VENDOR_TYPE 0xfcfbfaf9
     30 
     31 
     32 /* #define TEST_PENDING_REQUEST */
     33 
     34 struct eap_vendor_test_data {
     35 	enum { INIT, CONFIRM, SUCCESS } state;
     36 	int first_try;
     37 };
     38 
     39 
     40 static void * eap_vendor_test_init(struct eap_sm *sm)
     41 {
     42 	struct eap_vendor_test_data *data;
     43 	data = os_zalloc(sizeof(*data));
     44 	if (data == NULL)
     45 		return NULL;
     46 	data->state = INIT;
     47 	data->first_try = 1;
     48 	return data;
     49 }
     50 
     51 
     52 static void eap_vendor_test_deinit(struct eap_sm *sm, void *priv)
     53 {
     54 	struct eap_vendor_test_data *data = priv;
     55 	os_free(data);
     56 }
     57 
     58 
     59 #ifdef TEST_PENDING_REQUEST
     60 static void eap_vendor_ready(void *eloop_ctx, void *timeout_ctx)
     61 {
     62 	struct eap_sm *sm = eloop_ctx;
     63 	wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Ready to re-process pending "
     64 		   "request");
     65 	eap_notify_pending(sm);
     66 }
     67 #endif /* TEST_PENDING_REQUEST */
     68 
     69 
     70 static struct wpabuf * eap_vendor_test_process(struct eap_sm *sm, void *priv,
     71 					       struct eap_method_ret *ret,
     72 					       const struct wpabuf *reqData)
     73 {
     74 	struct eap_vendor_test_data *data = priv;
     75 	struct wpabuf *resp;
     76 	const u8 *pos;
     77 	size_t len;
     78 
     79 	pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE, reqData, &len);
     80 	if (pos == NULL || len < 1) {
     81 		ret->ignore = TRUE;
     82 		return NULL;
     83 	}
     84 
     85 	if (data->state == INIT && *pos != 1) {
     86 		wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Unexpected message "
     87 			   "%d in INIT state", *pos);
     88 		ret->ignore = TRUE;
     89 		return NULL;
     90 	}
     91 
     92 	if (data->state == CONFIRM && *pos != 3) {
     93 		wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Unexpected message "
     94 			   "%d in CONFIRM state", *pos);
     95 		ret->ignore = TRUE;
     96 		return NULL;
     97 	}
     98 
     99 	if (data->state == SUCCESS) {
    100 		wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Unexpected message "
    101 			   "in SUCCESS state");
    102 		ret->ignore = TRUE;
    103 		return NULL;
    104 	}
    105 
    106 	if (data->state == CONFIRM) {
    107 #ifdef TEST_PENDING_REQUEST
    108 		if (data->first_try) {
    109 			data->first_try = 0;
    110 			wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Testing "
    111 				   "pending request");
    112 			ret->ignore = TRUE;
    113 			eloop_register_timeout(1, 0, eap_vendor_ready, sm,
    114 					       NULL);
    115 			return NULL;
    116 		}
    117 #endif /* TEST_PENDING_REQUEST */
    118 	}
    119 
    120 	ret->ignore = FALSE;
    121 
    122 	wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Generating Response");
    123 	ret->allowNotifications = TRUE;
    124 
    125 	resp = eap_msg_alloc(EAP_VENDOR_ID, EAP_VENDOR_TYPE, 1,
    126 			     EAP_CODE_RESPONSE, eap_get_id(reqData));
    127 	if (resp == NULL)
    128 		return NULL;
    129 
    130 	if (data->state == INIT) {
    131 		wpabuf_put_u8(resp, 2);
    132 		data->state = CONFIRM;
    133 		ret->methodState = METHOD_CONT;
    134 		ret->decision = DECISION_FAIL;
    135 	} else {
    136 		wpabuf_put_u8(resp, 4);
    137 		data->state = SUCCESS;
    138 		ret->methodState = METHOD_DONE;
    139 		ret->decision = DECISION_UNCOND_SUCC;
    140 	}
    141 
    142 	return resp;
    143 }
    144 
    145 
    146 static Boolean eap_vendor_test_isKeyAvailable(struct eap_sm *sm, void *priv)
    147 {
    148 	struct eap_vendor_test_data *data = priv;
    149 	return data->state == SUCCESS;
    150 }
    151 
    152 
    153 static u8 * eap_vendor_test_getKey(struct eap_sm *sm, void *priv, size_t *len)
    154 {
    155 	struct eap_vendor_test_data *data = priv;
    156 	u8 *key;
    157 	const int key_len = 64;
    158 
    159 	if (data->state != SUCCESS)
    160 		return NULL;
    161 
    162 	key = os_malloc(key_len);
    163 	if (key == NULL)
    164 		return NULL;
    165 
    166 	os_memset(key, 0x11, key_len / 2);
    167 	os_memset(key + key_len / 2, 0x22, key_len / 2);
    168 	*len = key_len;
    169 
    170 	return key;
    171 }
    172 
    173 
    174 int eap_peer_vendor_test_register(void)
    175 {
    176 	struct eap_method *eap;
    177 	int ret;
    178 
    179 	eap = eap_peer_method_alloc(EAP_PEER_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->deinit = eap_vendor_test_deinit;
    187 	eap->process = eap_vendor_test_process;
    188 	eap->isKeyAvailable = eap_vendor_test_isKeyAvailable;
    189 	eap->getKey = eap_vendor_test_getKey;
    190 
    191 	ret = eap_peer_method_register(eap);
    192 	if (ret)
    193 		eap_peer_method_free(eap);
    194 	return ret;
    195 }
    196