eap_vendor_test.c
Go to the documentation of this file.
00001 /*
00002  * EAP peer method: Test method for vendor specific (expanded) EAP type
00003  * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  *
00014  * This file implements a vendor specific test method using EAP expanded types.
00015  * This is only for test use and must not be used for authentication since no
00016  * security is provided.
00017  */
00018 
00019 #include "includes.h"
00020 
00021 #include "common.h"
00022 #include "eap_i.h"
00023 #ifdef TEST_PENDING_REQUEST
00024 #include "eloop.h"
00025 #endif /* TEST_PENDING_REQUEST */
00026 
00027 
00028 #define EAP_VENDOR_ID 0xfffefd
00029 #define EAP_VENDOR_TYPE 0xfcfbfaf9
00030 
00031 
00032 /* #define TEST_PENDING_REQUEST */
00033 
00034 struct eap_vendor_test_data {
00035         enum { INIT, CONFIRM, SUCCESS } state;
00036         int first_try;
00037 };
00038 
00039 
00040 static void * eap_vendor_test_init(struct eap_sm *sm)
00041 {
00042         struct eap_vendor_test_data *data;
00043         data = os_zalloc(sizeof(*data));
00044         if (data == NULL)
00045                 return NULL;
00046         data->state = INIT;
00047         data->first_try = 1;
00048         return data;
00049 }
00050 
00051 
00052 static void eap_vendor_test_deinit(struct eap_sm *sm, void *priv)
00053 {
00054         struct eap_vendor_test_data *data = priv;
00055         os_free(data);
00056 }
00057 
00058 
00059 #ifdef TEST_PENDING_REQUEST
00060 static void eap_vendor_ready(void *eloop_ctx, void *timeout_ctx)
00061 {
00062         struct eap_sm *sm = eloop_ctx;
00063         wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Ready to re-process pending "
00064                    "request");
00065         eap_notify_pending(sm);
00066 }
00067 #endif /* TEST_PENDING_REQUEST */
00068 
00069 
00070 static struct wpabuf * eap_vendor_test_process(struct eap_sm *sm, void *priv,
00071                                                struct eap_method_ret *ret,
00072                                                const struct wpabuf *reqData)
00073 {
00074         struct eap_vendor_test_data *data = priv;
00075         struct wpabuf *resp;
00076         const u8 *pos;
00077         size_t len;
00078 
00079         pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE, reqData, &len);
00080         if (pos == NULL || len < 1) {
00081                 ret->ignore = TRUE;
00082                 return NULL;
00083         }
00084 
00085         if (data->state == INIT && *pos != 1) {
00086                 wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Unexpected message "
00087                            "%d in INIT state", *pos);
00088                 ret->ignore = TRUE;
00089                 return NULL;
00090         }
00091 
00092         if (data->state == CONFIRM && *pos != 3) {
00093                 wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Unexpected message "
00094                            "%d in CONFIRM state", *pos);
00095                 ret->ignore = TRUE;
00096                 return NULL;
00097         }
00098 
00099         if (data->state == SUCCESS) {
00100                 wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Unexpected message "
00101                            "in SUCCESS state");
00102                 ret->ignore = TRUE;
00103                 return NULL;
00104         }
00105 
00106         if (data->state == CONFIRM) {
00107 #ifdef TEST_PENDING_REQUEST
00108                 if (data->first_try) {
00109                         data->first_try = 0;
00110                         wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Testing "
00111                                    "pending request");
00112                         ret->ignore = TRUE;
00113                         eloop_register_timeout(1, 0, eap_vendor_ready, sm,
00114                                                NULL);
00115                         return NULL;
00116                 }
00117 #endif /* TEST_PENDING_REQUEST */
00118         }
00119 
00120         ret->ignore = FALSE;
00121 
00122         wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Generating Response");
00123         ret->allowNotifications = TRUE;
00124 
00125         resp = eap_msg_alloc(EAP_VENDOR_ID, EAP_VENDOR_TYPE, 1,
00126                              EAP_CODE_RESPONSE, eap_get_id(reqData));
00127         if (resp == NULL)
00128                 return NULL;
00129 
00130         if (data->state == INIT) {
00131                 wpabuf_put_u8(resp, 2);
00132                 data->state = CONFIRM;
00133                 ret->methodState = METHOD_CONT;
00134                 ret->decision = DECISION_FAIL;
00135         } else {
00136                 wpabuf_put_u8(resp, 4);
00137                 data->state = SUCCESS;
00138                 ret->methodState = METHOD_DONE;
00139                 ret->decision = DECISION_UNCOND_SUCC;
00140         }
00141 
00142         return resp;
00143 }
00144 
00145 
00146 static Boolean eap_vendor_test_isKeyAvailable(struct eap_sm *sm, void *priv)
00147 {
00148         struct eap_vendor_test_data *data = priv;
00149         return data->state == SUCCESS;
00150 }
00151 
00152 
00153 static u8 * eap_vendor_test_getKey(struct eap_sm *sm, void *priv, size_t *len)
00154 {
00155         struct eap_vendor_test_data *data = priv;
00156         u8 *key;
00157         const int key_len = 64;
00158 
00159         if (data->state != SUCCESS)
00160                 return NULL;
00161 
00162         key = os_malloc(key_len);
00163         if (key == NULL)
00164                 return NULL;
00165 
00166         os_memset(key, 0x11, key_len / 2);
00167         os_memset(key + key_len / 2, 0x22, key_len / 2);
00168         *len = key_len;
00169 
00170         return key;
00171 }
00172 
00173 
00174 int eap_peer_vendor_test_register(void)
00175 {
00176         struct eap_method *eap;
00177         int ret;
00178 
00179         eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
00180                                     EAP_VENDOR_ID, EAP_VENDOR_TYPE,
00181                                     "VENDOR-TEST");
00182         if (eap == NULL)
00183                 return -1;
00184 
00185         eap->init = eap_vendor_test_init;
00186         eap->deinit = eap_vendor_test_deinit;
00187         eap->process = eap_vendor_test_process;
00188         eap->isKeyAvailable = eap_vendor_test_isKeyAvailable;
00189         eap->getKey = eap_vendor_test_getKey;
00190 
00191         ret = eap_peer_method_register(eap);
00192         if (ret)
00193                 eap_peer_method_free(eap);
00194         return ret;
00195 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:35