eap_gtc.c revision c5ec7f57ead87efa365800228aa0b09a12d9e6c4
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP peer method: EAP-GTC (RFC 3748) 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_i.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_gtc_data { 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int prefix; 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void * eap_gtc_init(struct eap_sm *sm) 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_gtc_data *data; 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data = os_zalloc(sizeof(*data)); 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m && sm->m->vendor == EAP_VENDOR_IETF && 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->method == EAP_TYPE_FAST) { 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-GTC: EAP-FAST tunnel - use prefix " 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "with challenge/response"); 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->prefix = 1; 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_gtc_deinit(struct eap_sm *sm, void *priv) 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_gtc_data *data = priv; 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_gtc_process(struct eap_sm *sm, void *priv, 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_ret *ret, 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *reqData) 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_gtc_data *data = priv; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *password, *identity; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t password_len, identity_len, len, plen; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int otp; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 id; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC, reqData, &len); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) { 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = TRUE; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt id = eap_get_id(reqData); 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Request message", pos, len); 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->prefix && 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (len < 10 || os_memcmp(pos, "CHALLENGE=", 10) != 0)) { 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-GTC: Challenge did not start with " 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "expected prefix"); 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Send an empty response in order to allow tunneled 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * acknowledgement of the failure. This will also cover the 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * error case which seems to use EAP-MSCHAPv2 like error 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * reporting with EAP-GTC inside EAP-FAST tunnel. */ 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, EAP_CODE_RESPONSE, id); 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt password = eap_get_config_otp(sm, &password_len); 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (password) 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt otp = 1; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else { 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt password = eap_get_config_password(sm, &password_len); 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt otp = 0; 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (password == NULL) { 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-GTC: Password not configured"); 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_otp(sm, (const char *) pos, len); 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = TRUE; 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = FALSE; 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->methodState = data->prefix ? METHOD_MAY_CONT : METHOD_DONE; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->decision = DECISION_COND_SUCC; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->allowNotifications = FALSE; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen = password_len; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt identity = eap_get_config_identity(sm, &identity_len); 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (identity == NULL) 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->prefix) 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen += 9 + identity_len + 1; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, plen, 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_CODE_RESPONSE, id); 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->prefix) { 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(resp, "RESPONSE=", 9); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(resp, identity, identity_len); 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, '\0'); 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(resp, password, password_len); 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-GTC: Response", 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head_u8(resp) + sizeof(struct eap_hdr) + 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1, plen); 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (otp) { 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-GTC: Forgetting used password"); 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_clear_config_otp(sm); 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_peer_gtc_register(void) 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *eap; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_VENDOR_IETF, EAP_TYPE_GTC, "GTC"); 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap == NULL) 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->init = eap_gtc_init; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->deinit = eap_gtc_deinit; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->process = eap_gtc_process; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = eap_peer_method_register(eap); 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_method_free(eap); 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 146