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
00082
00083
00084
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