eap_gtc.c

Go to the documentation of this file.
00001 
00016 #include <stdlib.h>
00017 #include <stdio.h>
00018 #include <string.h>
00019 
00020 #include "common.h"
00021 #include "eap_i.h"
00022 #include "wpa_supplicant.h"
00023 #include "config_ssid.h"
00024 
00025 
00026 struct eap_gtc_data {
00027         int prefix;
00028 };
00029 
00030 
00031 static void * eap_gtc_init(struct eap_sm *sm)
00032 {
00033         struct eap_gtc_data *data;
00034         data = malloc(sizeof(*data));
00035         if (data == NULL)
00036                 return NULL;
00037         memset(data, 0, sizeof(*data));
00038 
00039         if (sm->m && sm->m->method == EAP_TYPE_FAST) {
00040                 wpa_printf(MSG_DEBUG, "EAP-GTC: EAP-FAST tunnel - use prefix "
00041                            "with challenge/response");
00042                 data->prefix = 1;
00043         }
00044         return data;
00045 }
00046 
00047 
00048 static void eap_gtc_deinit(struct eap_sm *sm, void *priv)
00049 {
00050         struct eap_gtc_data *data = priv;
00051         free(data);
00052 }
00053 
00054 
00055 static u8 * eap_gtc_process(struct eap_sm *sm, void *priv,
00056                             struct eap_method_ret *ret,
00057                             const u8 *reqData, size_t reqDataLen,
00058                             size_t *respDataLen)
00059 {
00060         struct eap_gtc_data *data = priv;
00061         struct wpa_ssid *config = eap_get_config(sm);
00062         const struct eap_hdr *req;
00063         struct eap_hdr *resp;
00064         const u8 *pos, *password;
00065         u8 *rpos;
00066         size_t password_len, len;
00067 
00068         pos = eap_hdr_validate(EAP_TYPE_GTC, reqData, reqDataLen, &len);
00069         if (pos == NULL) {
00070                 ret->ignore = TRUE;
00071                 return NULL;
00072         }
00073         req = (const struct eap_hdr *) reqData;
00074 
00075         wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Request message", pos, len);
00076         if (data->prefix &&
00077             (len < 10 || memcmp(pos, "CHALLENGE=", 10) != 0)) {
00078                 wpa_printf(MSG_DEBUG, "EAP-GTC: Challenge did not start with "
00079                            "expected prefix");
00080 
00081                 /* Send an empty response in order to allow tunneled
00082                  * acknowledgement of the failure. This will also cover the
00083                  * error case which seems to use EAP-MSCHAPv2 like error
00084                  * reporting with EAP-GTC inside EAP-FAST tunnel. */
00085                 *respDataLen = sizeof(struct eap_hdr) + 1;
00086                 resp = malloc(*respDataLen);
00087                 if (resp == NULL)
00088                         return NULL;
00089                 resp->code = EAP_CODE_RESPONSE;
00090                 resp->identifier = req->identifier;
00091                 resp->length = host_to_be16(*respDataLen);
00092                 rpos = (u8 *) (resp + 1);
00093                 *rpos++ = EAP_TYPE_GTC;
00094                 return (u8 *) resp;
00095         }
00096 
00097         if (config == NULL ||
00098             (config->password == NULL && config->otp == NULL)) {
00099                 wpa_printf(MSG_INFO, "EAP-GTC: Password not configured");
00100                 eap_sm_request_otp(sm, config, (const char *) pos, len);
00101                 ret->ignore = TRUE;
00102                 return NULL;
00103         }
00104 
00105         if (config->otp) {
00106                 password = config->otp;
00107                 password_len = config->otp_len;
00108         } else {
00109                 password = config->password;
00110                 password_len = config->password_len;
00111         }
00112 
00113         ret->ignore = FALSE;
00114 
00115         ret->methodState = data->prefix ? METHOD_MAY_CONT : METHOD_DONE;
00116         ret->decision = DECISION_COND_SUCC;
00117         ret->allowNotifications = FALSE;
00118 
00119         *respDataLen = sizeof(struct eap_hdr) + 1 + password_len;
00120         if (data->prefix) {
00121                 *respDataLen += 9 + config->identity_len + 1;
00122         }
00123         resp = malloc(*respDataLen);
00124         if (resp == NULL)
00125                 return NULL;
00126         resp->code = EAP_CODE_RESPONSE;
00127         resp->identifier = req->identifier;
00128         resp->length = host_to_be16(*respDataLen);
00129         rpos = (u8 *) (resp + 1);
00130         *rpos++ = EAP_TYPE_GTC;
00131         if (data->prefix) {
00132                 memcpy(rpos, "RESPONSE=", 9);
00133                 rpos += 9;
00134                 memcpy(rpos, config->identity, config->identity_len);
00135                 rpos += config->identity_len;
00136                 *rpos++ = '\0';
00137         }
00138         memcpy(rpos, password, password_len);
00139         wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-GTC: Response",
00140                               (u8 *) (resp + 1) + 1,
00141                               *respDataLen - sizeof(struct eap_hdr) - 1);
00142 
00143         if (config->otp) {
00144                 wpa_printf(MSG_DEBUG, "EAP-GTC: Forgetting used password");
00145                 memset(config->otp, 0, config->otp_len);
00146                 free(config->otp);
00147                 config->otp = NULL;
00148                 config->otp_len = 0;
00149         }
00150 
00151         return (u8 *) resp;
00152 }
00153 
00154 
00155 const struct eap_method eap_method_gtc =
00156 {
00157         .method = EAP_TYPE_GTC,
00158         .name = "GTC",
00159         .init = eap_gtc_init,
00160         .deinit = eap_gtc_deinit,
00161         .process = eap_gtc_process,
00162 };
00163 

Generated on Sat May 6 21:13:34 2006 for wpa_supplicant by  doxygen 1.4.2