2 * EAP peer method: Test method for vendor specific (expanded) EAP type
3 * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
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.
26 #define EAP_VENDOR_ID 0xfffefd
27 #define EAP_VENDOR_TYPE 0xfcfbfaf9
30 /* #define TEST_PENDING_REQUEST */
32 struct eap_vendor_test_data {
33 enum { INIT, CONFIRM, SUCCESS } state;
38 static void * eap_vendor_test_init(struct eap_sm *sm)
40 struct eap_vendor_test_data *data;
41 data = os_zalloc(sizeof(*data));
50 static void eap_vendor_test_deinit(struct eap_sm *sm, void *priv)
52 struct eap_vendor_test_data *data = priv;
57 #ifdef TEST_PENDING_REQUEST
58 static void eap_vendor_ready(void *eloop_ctx, void *timeout_ctx)
60 struct eap_sm *sm = eloop_ctx;
61 wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Ready to re-process pending "
63 eap_notify_pending(sm);
65 #endif /* TEST_PENDING_REQUEST */
68 static u8 * eap_vendor_test_process(struct eap_sm *sm, void *priv,
69 struct eap_method_ret *ret,
70 const u8 *reqData, size_t reqDataLen,
73 struct eap_vendor_test_data *data = priv;
74 const struct eap_hdr *req;
80 pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE,
81 reqData, reqDataLen, &len);
82 if (pos == NULL || len < 1) {
87 if (data->state == INIT && *pos != 1) {
88 wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Unexpected message "
89 "%d in INIT state", *pos);
94 if (data->state == CONFIRM && *pos != 3) {
95 wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Unexpected message "
96 "%d in CONFIRM state", *pos);
101 if (data->state == SUCCESS) {
102 wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Unexpected message "
108 if (data->state == CONFIRM) {
109 #ifdef TEST_PENDING_REQUEST
110 if (data->first_try) {
112 wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Testing "
115 eloop_register_timeout(1, 0, eap_vendor_ready, sm,
119 #endif /* TEST_PENDING_REQUEST */
123 req = (const struct eap_hdr *) reqData;
125 wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Generating Response");
126 ret->allowNotifications = TRUE;
128 resp = eap_msg_alloc(EAP_VENDOR_ID, EAP_VENDOR_TYPE, respDataLen, 1,
129 EAP_CODE_RESPONSE, req->identifier, &rpos);
133 if (data->state == INIT) {
135 data->state = CONFIRM;
136 ret->methodState = METHOD_CONT;
137 ret->decision = DECISION_FAIL;
140 data->state = SUCCESS;
141 ret->methodState = METHOD_DONE;
142 ret->decision = DECISION_UNCOND_SUCC;
149 static Boolean eap_vendor_test_isKeyAvailable(struct eap_sm *sm, void *priv)
151 struct eap_vendor_test_data *data = priv;
152 return data->state == SUCCESS;
156 static u8 * eap_vendor_test_getKey(struct eap_sm *sm, void *priv, size_t *len)
158 struct eap_vendor_test_data *data = priv;
160 const int key_len = 64;
162 if (data->state != SUCCESS)
165 key = os_malloc(key_len);
169 os_memset(key, 0x11, key_len / 2);
170 os_memset(key + key_len / 2, 0x22, key_len / 2);
177 int eap_peer_vendor_test_register(void)
179 struct eap_method *eap;
182 eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
183 EAP_VENDOR_ID, EAP_VENDOR_TYPE,
188 eap->init = eap_vendor_test_init;
189 eap->deinit = eap_vendor_test_deinit;
190 eap->process = eap_vendor_test_process;
191 eap->isKeyAvailable = eap_vendor_test_isKeyAvailable;
192 eap->getKey = eap_vendor_test_getKey;
194 ret = eap_peer_method_register(eap);
196 eap_peer_method_free(eap);