18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd / 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 enum { CONTINUE, SUCCESS, FAILURE } state; 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int prefix; 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void * eap_gtc_init(struct eap_sm *sm) 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_gtc_data *data; 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data = os_zalloc(sizeof(*data)); 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = CONTINUE; 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_FAST 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->m && sm->m->vendor == EAP_VENDOR_IETF && 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->m->method == EAP_TYPE_FAST) { 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-GTC: EAP-FAST tunnel - use prefix " 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "with challenge/response"); 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->prefix = 1; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_FAST */ 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data; 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_gtc_reset(struct eap_sm *sm, void *priv) 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_gtc_data *data = priv; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data); 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_gtc_buildReq(struct eap_sm *sm, void *priv, u8 id) 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_gtc_data *data = priv; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *msg; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t msg_len; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = data->prefix ? "CHALLENGE=Password" : "Password"; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg_len = os_strlen(msg); 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, msg_len, 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_CODE_REQUEST, id); 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) { 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "EAP-GTC: Failed to allocate memory for " 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "request"); 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = FAILURE; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(req, msg, msg_len); 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = CONTINUE; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return req; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eap_gtc_check(struct eap_sm *sm, void *priv, 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *respData) 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC, respData, &len); 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL || len < 1) { 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-GTC: Invalid frame"); 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TRUE; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return FALSE; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_gtc_process(struct eap_sm *sm, void *priv, 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *respData) 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_gtc_data *data = priv; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC, respData, &rlen); 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL || rlen < 1) 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; /* Should not happen - frame already validated */ 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-GTC: Response", pos, rlen); 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_FAST 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->prefix) { 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos2, *end; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* "RESPONSE=<user>\0<password>" */ 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rlen < 10) { 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-GTC: Too short response " 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for EAP-FAST prefix"); 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = FAILURE; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + rlen; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 9; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 = pos; 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos2 < end && *pos2) 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2++; 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos2 == end) { 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-GTC: No password in " 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "response to EAP-FAST prefix"); 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = FAILURE; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Response user", 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, pos2 - pos); 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->identity && sm->require_identity_match && 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (pos2 - pos != (int) sm->identity_len || 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(pos, sm->identity, sm->identity_len))) { 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-GTC: Phase 2 Identity did " 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "not match with required Identity"); 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Expected " 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "identity", 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->identity, sm->identity_len); 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = FAILURE; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sm->identity); 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->identity_len = pos2 - pos; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->identity = os_malloc(sm->identity_len); 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->identity == NULL) { 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = FAILURE; 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sm->identity, pos, sm->identity_len); 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) { 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "EAP-GTC: Phase2 " 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Identity not found in the user " 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "database", 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->identity, sm->identity_len); 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = FAILURE; 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = pos2 + 1; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rlen = end - pos; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii_key(MSG_MSGDUMP, 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "EAP-GTC: Response password", 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, rlen); 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_FAST */ 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sm->user == NULL || sm->user->password == NULL || 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->user->password_hash) { 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-GTC: Plaintext password not " 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "configured"); 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = FAILURE; 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rlen != sm->user->password_len || 178c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt os_memcmp_const(pos, sm->user->password, rlen) != 0) { 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-GTC: Done - Failure"); 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = FAILURE; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-GTC: Done - Success"); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = SUCCESS; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eap_gtc_isDone(struct eap_sm *sm, void *priv) 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_gtc_data *data = priv; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data->state != CONTINUE; 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eap_gtc_isSuccess(struct eap_sm *sm, void *priv) 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_gtc_data *data = priv; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data->state == SUCCESS; 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_server_gtc_register(void) 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *eap; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_VENDOR_IETF, EAP_TYPE_GTC, "GTC"); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap == NULL) 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->init = eap_gtc_init; 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->reset = eap_gtc_reset; 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->buildReq = eap_gtc_buildReq; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->check = eap_gtc_check; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->process = eap_gtc_process; 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->isDone = eap_gtc_isDone; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->isSuccess = eap_gtc_isSuccess; 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = eap_server_method_register(eap); 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_method_free(eap); 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 225