1/* 2 * hostapd / EAP-TTLS (RFC 5281) 3 * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9#include "includes.h" 10 11#include "common.h" 12#include "crypto/ms_funcs.h" 13#include "crypto/sha1.h" 14#include "crypto/tls.h" 15#include "eap_server/eap_i.h" 16#include "eap_server/eap_tls_common.h" 17#include "eap_common/chap.h" 18#include "eap_common/eap_ttls.h" 19 20 21#define EAP_TTLS_VERSION 0 22 23 24static void eap_ttls_reset(struct eap_sm *sm, void *priv); 25 26 27struct eap_ttls_data { 28 struct eap_ssl_data ssl; 29 enum { 30 START, PHASE1, PHASE2_START, PHASE2_METHOD, 31 PHASE2_MSCHAPV2_RESP, SUCCESS, FAILURE 32 } state; 33 34 int ttls_version; 35 const struct eap_method *phase2_method; 36 void *phase2_priv; 37 int mschapv2_resp_ok; 38 u8 mschapv2_auth_response[20]; 39 u8 mschapv2_ident; 40 struct wpabuf *pending_phase2_eap_resp; 41 int tnc_started; 42}; 43 44 45static const char * eap_ttls_state_txt(int state) 46{ 47 switch (state) { 48 case START: 49 return "START"; 50 case PHASE1: 51 return "PHASE1"; 52 case PHASE2_START: 53 return "PHASE2_START"; 54 case PHASE2_METHOD: 55 return "PHASE2_METHOD"; 56 case PHASE2_MSCHAPV2_RESP: 57 return "PHASE2_MSCHAPV2_RESP"; 58 case SUCCESS: 59 return "SUCCESS"; 60 case FAILURE: 61 return "FAILURE"; 62 default: 63 return "Unknown?!"; 64 } 65} 66 67 68static void eap_ttls_state(struct eap_ttls_data *data, int state) 69{ 70 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s -> %s", 71 eap_ttls_state_txt(data->state), 72 eap_ttls_state_txt(state)); 73 data->state = state; 74} 75 76 77static u8 * eap_ttls_avp_hdr(u8 *avphdr, u32 avp_code, u32 vendor_id, 78 int mandatory, size_t len) 79{ 80 struct ttls_avp_vendor *avp; 81 u8 flags; 82 size_t hdrlen; 83 84 avp = (struct ttls_avp_vendor *) avphdr; 85 flags = mandatory ? AVP_FLAGS_MANDATORY : 0; 86 if (vendor_id) { 87 flags |= AVP_FLAGS_VENDOR; 88 hdrlen = sizeof(*avp); 89 avp->vendor_id = host_to_be32(vendor_id); 90 } else { 91 hdrlen = sizeof(struct ttls_avp); 92 } 93 94 avp->avp_code = host_to_be32(avp_code); 95 avp->avp_length = host_to_be32(((u32) flags << 24) | 96 ((u32) (hdrlen + len))); 97 98 return avphdr + hdrlen; 99} 100 101 102static struct wpabuf * eap_ttls_avp_encapsulate(struct wpabuf *resp, 103 u32 avp_code, int mandatory) 104{ 105 struct wpabuf *avp; 106 u8 *pos; 107 108 avp = wpabuf_alloc(sizeof(struct ttls_avp) + wpabuf_len(resp) + 4); 109 if (avp == NULL) { 110 wpabuf_free(resp); 111 return NULL; 112 } 113 114 pos = eap_ttls_avp_hdr(wpabuf_mhead(avp), avp_code, 0, mandatory, 115 wpabuf_len(resp)); 116 os_memcpy(pos, wpabuf_head(resp), wpabuf_len(resp)); 117 pos += wpabuf_len(resp); 118 AVP_PAD((const u8 *) wpabuf_head(avp), pos); 119 wpabuf_free(resp); 120 wpabuf_put(avp, pos - (u8 *) wpabuf_head(avp)); 121 return avp; 122} 123 124 125struct eap_ttls_avp { 126 /* Note: eap is allocated memory; caller is responsible for freeing 127 * it. All the other pointers are pointing to the packet data, i.e., 128 * they must not be freed separately. */ 129 u8 *eap; 130 size_t eap_len; 131 u8 *user_name; 132 size_t user_name_len; 133 u8 *user_password; 134 size_t user_password_len; 135 u8 *chap_challenge; 136 size_t chap_challenge_len; 137 u8 *chap_password; 138 size_t chap_password_len; 139 u8 *mschap_challenge; 140 size_t mschap_challenge_len; 141 u8 *mschap_response; 142 size_t mschap_response_len; 143 u8 *mschap2_response; 144 size_t mschap2_response_len; 145}; 146 147 148static int eap_ttls_avp_parse(struct wpabuf *buf, struct eap_ttls_avp *parse) 149{ 150 struct ttls_avp *avp; 151 u8 *pos; 152 int left; 153 154 pos = wpabuf_mhead(buf); 155 left = wpabuf_len(buf); 156 os_memset(parse, 0, sizeof(*parse)); 157 158 while (left > 0) { 159 u32 avp_code, avp_length, vendor_id = 0; 160 u8 avp_flags, *dpos; 161 size_t pad, dlen; 162 avp = (struct ttls_avp *) pos; 163 avp_code = be_to_host32(avp->avp_code); 164 avp_length = be_to_host32(avp->avp_length); 165 avp_flags = (avp_length >> 24) & 0xff; 166 avp_length &= 0xffffff; 167 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP: code=%d flags=0x%02x " 168 "length=%d", (int) avp_code, avp_flags, 169 (int) avp_length); 170 if ((int) avp_length > left) { 171 wpa_printf(MSG_WARNING, "EAP-TTLS: AVP overflow " 172 "(len=%d, left=%d) - dropped", 173 (int) avp_length, left); 174 goto fail; 175 } 176 if (avp_length < sizeof(*avp)) { 177 wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid AVP length " 178 "%d", avp_length); 179 goto fail; 180 } 181 dpos = (u8 *) (avp + 1); 182 dlen = avp_length - sizeof(*avp); 183 if (avp_flags & AVP_FLAGS_VENDOR) { 184 if (dlen < 4) { 185 wpa_printf(MSG_WARNING, "EAP-TTLS: vendor AVP " 186 "underflow"); 187 goto fail; 188 } 189 vendor_id = be_to_host32(* (be32 *) dpos); 190 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d", 191 (int) vendor_id); 192 dpos += 4; 193 dlen -= 4; 194 } 195 196 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen); 197 198 if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) { 199 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message"); 200 if (parse->eap == NULL) { 201 parse->eap = os_malloc(dlen); 202 if (parse->eap == NULL) { 203 wpa_printf(MSG_WARNING, "EAP-TTLS: " 204 "failed to allocate memory " 205 "for Phase 2 EAP data"); 206 goto fail; 207 } 208 os_memcpy(parse->eap, dpos, dlen); 209 parse->eap_len = dlen; 210 } else { 211 u8 *neweap = os_realloc(parse->eap, 212 parse->eap_len + dlen); 213 if (neweap == NULL) { 214 wpa_printf(MSG_WARNING, "EAP-TTLS: " 215 "failed to allocate memory " 216 "for Phase 2 EAP data"); 217 goto fail; 218 } 219 os_memcpy(neweap + parse->eap_len, dpos, dlen); 220 parse->eap = neweap; 221 parse->eap_len += dlen; 222 } 223 } else if (vendor_id == 0 && 224 avp_code == RADIUS_ATTR_USER_NAME) { 225 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: User-Name", 226 dpos, dlen); 227 parse->user_name = dpos; 228 parse->user_name_len = dlen; 229 } else if (vendor_id == 0 && 230 avp_code == RADIUS_ATTR_USER_PASSWORD) { 231 u8 *password = dpos; 232 size_t password_len = dlen; 233 while (password_len > 0 && 234 password[password_len - 1] == '\0') { 235 password_len--; 236 } 237 wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: " 238 "User-Password (PAP)", 239 password, password_len); 240 parse->user_password = password; 241 parse->user_password_len = password_len; 242 } else if (vendor_id == 0 && 243 avp_code == RADIUS_ATTR_CHAP_CHALLENGE) { 244 wpa_hexdump(MSG_DEBUG, 245 "EAP-TTLS: CHAP-Challenge (CHAP)", 246 dpos, dlen); 247 parse->chap_challenge = dpos; 248 parse->chap_challenge_len = dlen; 249 } else if (vendor_id == 0 && 250 avp_code == RADIUS_ATTR_CHAP_PASSWORD) { 251 wpa_hexdump(MSG_DEBUG, 252 "EAP-TTLS: CHAP-Password (CHAP)", 253 dpos, dlen); 254 parse->chap_password = dpos; 255 parse->chap_password_len = dlen; 256 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT && 257 avp_code == RADIUS_ATTR_MS_CHAP_CHALLENGE) { 258 wpa_hexdump(MSG_DEBUG, 259 "EAP-TTLS: MS-CHAP-Challenge", 260 dpos, dlen); 261 parse->mschap_challenge = dpos; 262 parse->mschap_challenge_len = dlen; 263 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT && 264 avp_code == RADIUS_ATTR_MS_CHAP_RESPONSE) { 265 wpa_hexdump(MSG_DEBUG, 266 "EAP-TTLS: MS-CHAP-Response (MSCHAP)", 267 dpos, dlen); 268 parse->mschap_response = dpos; 269 parse->mschap_response_len = dlen; 270 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT && 271 avp_code == RADIUS_ATTR_MS_CHAP2_RESPONSE) { 272 wpa_hexdump(MSG_DEBUG, 273 "EAP-TTLS: MS-CHAP2-Response (MSCHAPV2)", 274 dpos, dlen); 275 parse->mschap2_response = dpos; 276 parse->mschap2_response_len = dlen; 277 } else if (avp_flags & AVP_FLAGS_MANDATORY) { 278 wpa_printf(MSG_WARNING, "EAP-TTLS: Unsupported " 279 "mandatory AVP code %d vendor_id %d - " 280 "dropped", (int) avp_code, (int) vendor_id); 281 goto fail; 282 } else { 283 wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported " 284 "AVP code %d vendor_id %d", 285 (int) avp_code, (int) vendor_id); 286 } 287 288 pad = (4 - (avp_length & 3)) & 3; 289 pos += avp_length + pad; 290 left -= avp_length + pad; 291 } 292 293 return 0; 294 295fail: 296 os_free(parse->eap); 297 parse->eap = NULL; 298 return -1; 299} 300 301 302static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm, 303 struct eap_ttls_data *data, size_t len) 304{ 305 return eap_server_tls_derive_key(sm, &data->ssl, "ttls challenge", 306 len); 307} 308 309 310static void * eap_ttls_init(struct eap_sm *sm) 311{ 312 struct eap_ttls_data *data; 313 314 data = os_zalloc(sizeof(*data)); 315 if (data == NULL) 316 return NULL; 317 data->ttls_version = EAP_TTLS_VERSION; 318 data->state = START; 319 320 if (eap_server_tls_ssl_init(sm, &data->ssl, 0)) { 321 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL."); 322 eap_ttls_reset(sm, data); 323 return NULL; 324 } 325 326 return data; 327} 328 329 330static void eap_ttls_reset(struct eap_sm *sm, void *priv) 331{ 332 struct eap_ttls_data *data = priv; 333 if (data == NULL) 334 return; 335 if (data->phase2_priv && data->phase2_method) 336 data->phase2_method->reset(sm, data->phase2_priv); 337 eap_server_tls_ssl_deinit(sm, &data->ssl); 338 wpabuf_free(data->pending_phase2_eap_resp); 339 bin_clear_free(data, sizeof(*data)); 340} 341 342 343static struct wpabuf * eap_ttls_build_start(struct eap_sm *sm, 344 struct eap_ttls_data *data, u8 id) 345{ 346 struct wpabuf *req; 347 348 req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS, 1, 349 EAP_CODE_REQUEST, id); 350 if (req == NULL) { 351 wpa_printf(MSG_ERROR, "EAP-TTLS: Failed to allocate memory for" 352 " request"); 353 eap_ttls_state(data, FAILURE); 354 return NULL; 355 } 356 357 wpabuf_put_u8(req, EAP_TLS_FLAGS_START | data->ttls_version); 358 359 eap_ttls_state(data, PHASE1); 360 361 return req; 362} 363 364 365static struct wpabuf * eap_ttls_build_phase2_eap_req( 366 struct eap_sm *sm, struct eap_ttls_data *data, u8 id) 367{ 368 struct wpabuf *buf, *encr_req; 369 370 371 buf = data->phase2_method->buildReq(sm, data->phase2_priv, id); 372 if (buf == NULL) 373 return NULL; 374 375 wpa_hexdump_buf_key(MSG_DEBUG, 376 "EAP-TTLS/EAP: Encapsulate Phase 2 data", buf); 377 378 buf = eap_ttls_avp_encapsulate(buf, RADIUS_ATTR_EAP_MESSAGE, 1); 379 if (buf == NULL) { 380 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Failed to encapsulate " 381 "packet"); 382 return NULL; 383 } 384 385 wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS/EAP: Encrypt encapsulated " 386 "Phase 2 data", buf); 387 388 encr_req = eap_server_tls_encrypt(sm, &data->ssl, buf); 389 wpabuf_free(buf); 390 391 return encr_req; 392} 393 394 395static struct wpabuf * eap_ttls_build_phase2_mschapv2( 396 struct eap_sm *sm, struct eap_ttls_data *data) 397{ 398 struct wpabuf *encr_req, msgbuf; 399 u8 *req, *pos, *end; 400 int ret; 401 402 pos = req = os_malloc(100); 403 if (req == NULL) 404 return NULL; 405 end = req + 100; 406 407 if (data->mschapv2_resp_ok) { 408 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_SUCCESS, 409 RADIUS_VENDOR_ID_MICROSOFT, 1, 43); 410 *pos++ = data->mschapv2_ident; 411 ret = os_snprintf((char *) pos, end - pos, "S="); 412 if (!os_snprintf_error(end - pos, ret)) 413 pos += ret; 414 pos += wpa_snprintf_hex_uppercase( 415 (char *) pos, end - pos, data->mschapv2_auth_response, 416 sizeof(data->mschapv2_auth_response)); 417 } else { 418 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_ERROR, 419 RADIUS_VENDOR_ID_MICROSOFT, 1, 6); 420 os_memcpy(pos, "Failed", 6); 421 pos += 6; 422 AVP_PAD(req, pos); 423 } 424 425 wpabuf_set(&msgbuf, req, pos - req); 426 wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Encrypting Phase 2 " 427 "data", &msgbuf); 428 429 encr_req = eap_server_tls_encrypt(sm, &data->ssl, &msgbuf); 430 os_free(req); 431 432 return encr_req; 433} 434 435 436static struct wpabuf * eap_ttls_buildReq(struct eap_sm *sm, void *priv, u8 id) 437{ 438 struct eap_ttls_data *data = priv; 439 440 if (data->ssl.state == FRAG_ACK) { 441 return eap_server_tls_build_ack(id, EAP_TYPE_TTLS, 442 data->ttls_version); 443 } 444 445 if (data->ssl.state == WAIT_FRAG_ACK) { 446 return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TTLS, 447 data->ttls_version, id); 448 } 449 450 switch (data->state) { 451 case START: 452 return eap_ttls_build_start(sm, data, id); 453 case PHASE1: 454 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) { 455 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase1 done, " 456 "starting Phase2"); 457 eap_ttls_state(data, PHASE2_START); 458 } 459 break; 460 case PHASE2_METHOD: 461 wpabuf_free(data->ssl.tls_out); 462 data->ssl.tls_out_pos = 0; 463 data->ssl.tls_out = eap_ttls_build_phase2_eap_req(sm, data, 464 id); 465 break; 466 case PHASE2_MSCHAPV2_RESP: 467 wpabuf_free(data->ssl.tls_out); 468 data->ssl.tls_out_pos = 0; 469 data->ssl.tls_out = eap_ttls_build_phase2_mschapv2(sm, data); 470 break; 471 default: 472 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d", 473 __func__, data->state); 474 return NULL; 475 } 476 477 return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TTLS, 478 data->ttls_version, id); 479} 480 481 482static Boolean eap_ttls_check(struct eap_sm *sm, void *priv, 483 struct wpabuf *respData) 484{ 485 const u8 *pos; 486 size_t len; 487 488 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TTLS, respData, &len); 489 if (pos == NULL || len < 1) { 490 wpa_printf(MSG_INFO, "EAP-TTLS: Invalid frame"); 491 return TRUE; 492 } 493 494 return FALSE; 495} 496 497 498static void eap_ttls_process_phase2_pap(struct eap_sm *sm, 499 struct eap_ttls_data *data, 500 const u8 *user_password, 501 size_t user_password_len) 502{ 503 if (!sm->user || !sm->user->password || sm->user->password_hash || 504 !(sm->user->ttls_auth & EAP_TTLS_AUTH_PAP)) { 505 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: No plaintext user " 506 "password configured"); 507 eap_ttls_state(data, FAILURE); 508 return; 509 } 510 511 if (sm->user->password_len != user_password_len || 512 os_memcmp_const(sm->user->password, user_password, 513 user_password_len) != 0) { 514 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Invalid user password"); 515 eap_ttls_state(data, FAILURE); 516 return; 517 } 518 519 wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Correct user password"); 520 eap_ttls_state(data, SUCCESS); 521} 522 523 524static void eap_ttls_process_phase2_chap(struct eap_sm *sm, 525 struct eap_ttls_data *data, 526 const u8 *challenge, 527 size_t challenge_len, 528 const u8 *password, 529 size_t password_len) 530{ 531 u8 *chal, hash[CHAP_MD5_LEN]; 532 533 if (challenge == NULL || password == NULL || 534 challenge_len != EAP_TTLS_CHAP_CHALLENGE_LEN || 535 password_len != 1 + EAP_TTLS_CHAP_PASSWORD_LEN) { 536 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid CHAP attributes " 537 "(challenge len %lu password len %lu)", 538 (unsigned long) challenge_len, 539 (unsigned long) password_len); 540 eap_ttls_state(data, FAILURE); 541 return; 542 } 543 544 if (!sm->user || !sm->user->password || sm->user->password_hash || 545 !(sm->user->ttls_auth & EAP_TTLS_AUTH_CHAP)) { 546 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: No plaintext user " 547 "password configured"); 548 eap_ttls_state(data, FAILURE); 549 return; 550 } 551 552 chal = eap_ttls_implicit_challenge(sm, data, 553 EAP_TTLS_CHAP_CHALLENGE_LEN + 1); 554 if (chal == NULL) { 555 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Failed to generate " 556 "challenge from TLS data"); 557 eap_ttls_state(data, FAILURE); 558 return; 559 } 560 561 if (os_memcmp_const(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN) 562 != 0 || 563 password[0] != chal[EAP_TTLS_CHAP_CHALLENGE_LEN]) { 564 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Challenge mismatch"); 565 os_free(chal); 566 eap_ttls_state(data, FAILURE); 567 return; 568 } 569 os_free(chal); 570 571 /* MD5(Ident + Password + Challenge) */ 572 chap_md5(password[0], sm->user->password, sm->user->password_len, 573 challenge, challenge_len, hash); 574 575 if (os_memcmp_const(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) == 576 0) { 577 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Correct user password"); 578 eap_ttls_state(data, SUCCESS); 579 } else { 580 wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid user password"); 581 eap_ttls_state(data, FAILURE); 582 } 583} 584 585 586static void eap_ttls_process_phase2_mschap(struct eap_sm *sm, 587 struct eap_ttls_data *data, 588 u8 *challenge, size_t challenge_len, 589 u8 *response, size_t response_len) 590{ 591 u8 *chal, nt_response[24]; 592 593 if (challenge == NULL || response == NULL || 594 challenge_len != EAP_TTLS_MSCHAP_CHALLENGE_LEN || 595 response_len != EAP_TTLS_MSCHAP_RESPONSE_LEN) { 596 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid MS-CHAP " 597 "attributes (challenge len %lu response len %lu)", 598 (unsigned long) challenge_len, 599 (unsigned long) response_len); 600 eap_ttls_state(data, FAILURE); 601 return; 602 } 603 604 if (!sm->user || !sm->user->password || 605 !(sm->user->ttls_auth & EAP_TTLS_AUTH_MSCHAP)) { 606 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: No user password " 607 "configured"); 608 eap_ttls_state(data, FAILURE); 609 return; 610 } 611 612 chal = eap_ttls_implicit_challenge(sm, data, 613 EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1); 614 if (chal == NULL) { 615 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Failed to generate " 616 "challenge from TLS data"); 617 eap_ttls_state(data, FAILURE); 618 return; 619 } 620 621#ifdef CONFIG_TESTING_OPTIONS 622 eap_server_mschap_rx_callback(sm, "TTLS-MSCHAP", 623 sm->identity, sm->identity_len, 624 challenge, response + 2 + 24); 625#endif /* CONFIG_TESTING_OPTIONS */ 626 627 if (os_memcmp_const(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN) 628 != 0 || 629 response[0] != chal[EAP_TTLS_MSCHAP_CHALLENGE_LEN]) { 630 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Challenge mismatch"); 631 os_free(chal); 632 eap_ttls_state(data, FAILURE); 633 return; 634 } 635 os_free(chal); 636 637 if (sm->user->password_hash) 638 challenge_response(challenge, sm->user->password, nt_response); 639 else 640 nt_challenge_response(challenge, sm->user->password, 641 sm->user->password_len, nt_response); 642 643 if (os_memcmp_const(nt_response, response + 2 + 24, 24) == 0) { 644 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Correct response"); 645 eap_ttls_state(data, SUCCESS); 646 } else { 647 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid NT-Response"); 648 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Received", 649 response + 2 + 24, 24); 650 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Expected", 651 nt_response, 24); 652 eap_ttls_state(data, FAILURE); 653 } 654} 655 656 657static void eap_ttls_process_phase2_mschapv2(struct eap_sm *sm, 658 struct eap_ttls_data *data, 659 u8 *challenge, 660 size_t challenge_len, 661 u8 *response, size_t response_len) 662{ 663 u8 *chal, *username, nt_response[24], *rx_resp, *peer_challenge, 664 *auth_challenge; 665 size_t username_len, i; 666 667 if (challenge == NULL || response == NULL || 668 challenge_len != EAP_TTLS_MSCHAPV2_CHALLENGE_LEN || 669 response_len != EAP_TTLS_MSCHAPV2_RESPONSE_LEN) { 670 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid MS-CHAP2 " 671 "attributes (challenge len %lu response len %lu)", 672 (unsigned long) challenge_len, 673 (unsigned long) response_len); 674 eap_ttls_state(data, FAILURE); 675 return; 676 } 677 678 if (!sm->user || !sm->user->password || 679 !(sm->user->ttls_auth & EAP_TTLS_AUTH_MSCHAPV2)) { 680 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: No user password " 681 "configured"); 682 eap_ttls_state(data, FAILURE); 683 return; 684 } 685 686 if (sm->identity == NULL) { 687 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: No user identity " 688 "known"); 689 eap_ttls_state(data, FAILURE); 690 return; 691 } 692 693 /* MSCHAPv2 does not include optional domain name in the 694 * challenge-response calculation, so remove domain prefix 695 * (if present). */ 696 username = sm->identity; 697 username_len = sm->identity_len; 698 for (i = 0; i < username_len; i++) { 699 if (username[i] == '\\') { 700 username_len -= i + 1; 701 username += i + 1; 702 break; 703 } 704 } 705 706 chal = eap_ttls_implicit_challenge( 707 sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1); 708 if (chal == NULL) { 709 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Failed to generate " 710 "challenge from TLS data"); 711 eap_ttls_state(data, FAILURE); 712 return; 713 } 714 715 if (os_memcmp_const(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) 716 != 0 || 717 response[0] != chal[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN]) { 718 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Challenge mismatch"); 719 os_free(chal); 720 eap_ttls_state(data, FAILURE); 721 return; 722 } 723 os_free(chal); 724 725 auth_challenge = challenge; 726 peer_challenge = response + 2; 727 728 wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: User", 729 username, username_len); 730 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: auth_challenge", 731 auth_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN); 732 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: peer_challenge", 733 peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN); 734 735 if (sm->user->password_hash) { 736 generate_nt_response_pwhash(auth_challenge, peer_challenge, 737 username, username_len, 738 sm->user->password, 739 nt_response); 740 } else { 741 generate_nt_response(auth_challenge, peer_challenge, 742 username, username_len, 743 sm->user->password, 744 sm->user->password_len, 745 nt_response); 746 } 747 748 rx_resp = response + 2 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 8; 749#ifdef CONFIG_TESTING_OPTIONS 750 { 751 u8 challenge2[8]; 752 753 if (challenge_hash(peer_challenge, auth_challenge, 754 username, username_len, challenge2) == 0) { 755 eap_server_mschap_rx_callback(sm, "TTLS-MSCHAPV2", 756 username, username_len, 757 challenge2, rx_resp); 758 } 759 } 760#endif /* CONFIG_TESTING_OPTIONS */ 761 if (os_memcmp_const(nt_response, rx_resp, 24) == 0) { 762 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Correct " 763 "NT-Response"); 764 data->mschapv2_resp_ok = 1; 765 766 if (sm->user->password_hash) { 767 generate_authenticator_response_pwhash( 768 sm->user->password, 769 peer_challenge, auth_challenge, 770 username, username_len, nt_response, 771 data->mschapv2_auth_response); 772 } else { 773 generate_authenticator_response( 774 sm->user->password, sm->user->password_len, 775 peer_challenge, auth_challenge, 776 username, username_len, nt_response, 777 data->mschapv2_auth_response); 778 } 779 } else { 780 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid " 781 "NT-Response"); 782 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Received", 783 rx_resp, 24); 784 wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Expected", 785 nt_response, 24); 786 data->mschapv2_resp_ok = 0; 787 } 788 eap_ttls_state(data, PHASE2_MSCHAPV2_RESP); 789 data->mschapv2_ident = response[0]; 790} 791 792 793static int eap_ttls_phase2_eap_init(struct eap_sm *sm, 794 struct eap_ttls_data *data, 795 EapType eap_type) 796{ 797 if (data->phase2_priv && data->phase2_method) { 798 data->phase2_method->reset(sm, data->phase2_priv); 799 data->phase2_method = NULL; 800 data->phase2_priv = NULL; 801 } 802 data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF, 803 eap_type); 804 if (!data->phase2_method) 805 return -1; 806 807 sm->init_phase2 = 1; 808 data->phase2_priv = data->phase2_method->init(sm); 809 sm->init_phase2 = 0; 810 return data->phase2_priv == NULL ? -1 : 0; 811} 812 813 814static void eap_ttls_process_phase2_eap_response(struct eap_sm *sm, 815 struct eap_ttls_data *data, 816 u8 *in_data, size_t in_len) 817{ 818 u8 next_type = EAP_TYPE_NONE; 819 struct eap_hdr *hdr; 820 u8 *pos; 821 size_t left; 822 struct wpabuf buf; 823 const struct eap_method *m = data->phase2_method; 824 void *priv = data->phase2_priv; 825 826 if (priv == NULL) { 827 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: %s - Phase2 not " 828 "initialized?!", __func__); 829 return; 830 } 831 832 hdr = (struct eap_hdr *) in_data; 833 pos = (u8 *) (hdr + 1); 834 835 if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) { 836 left = in_len - sizeof(*hdr); 837 wpa_hexdump(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 type Nak'ed; " 838 "allowed types", pos + 1, left - 1); 839 eap_sm_process_nak(sm, pos + 1, left - 1); 840 if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS && 841 sm->user->methods[sm->user_eap_method_index].method != 842 EAP_TYPE_NONE) { 843 next_type = sm->user->methods[ 844 sm->user_eap_method_index++].method; 845 wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d", 846 next_type); 847 if (eap_ttls_phase2_eap_init(sm, data, next_type)) { 848 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to " 849 "initialize EAP type %d", 850 next_type); 851 eap_ttls_state(data, FAILURE); 852 return; 853 } 854 } else { 855 eap_ttls_state(data, FAILURE); 856 } 857 return; 858 } 859 860 wpabuf_set(&buf, in_data, in_len); 861 862 if (m->check(sm, priv, &buf)) { 863 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 check() asked to " 864 "ignore the packet"); 865 return; 866 } 867 868 m->process(sm, priv, &buf); 869 870 if (sm->method_pending == METHOD_PENDING_WAIT) { 871 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method is in " 872 "pending wait state - save decrypted response"); 873 wpabuf_free(data->pending_phase2_eap_resp); 874 data->pending_phase2_eap_resp = wpabuf_dup(&buf); 875 } 876 877 if (!m->isDone(sm, priv)) 878 return; 879 880 if (!m->isSuccess(sm, priv)) { 881 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method failed"); 882 eap_ttls_state(data, FAILURE); 883 return; 884 } 885 886 switch (data->state) { 887 case PHASE2_START: 888 if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) { 889 wpa_hexdump_ascii(MSG_DEBUG, "EAP_TTLS: Phase2 " 890 "Identity not found in the user " 891 "database", 892 sm->identity, sm->identity_len); 893 eap_ttls_state(data, FAILURE); 894 break; 895 } 896 897 eap_ttls_state(data, PHASE2_METHOD); 898 next_type = sm->user->methods[0].method; 899 sm->user_eap_method_index = 1; 900 wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d", next_type); 901 if (eap_ttls_phase2_eap_init(sm, data, next_type)) { 902 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to initialize " 903 "EAP type %d", next_type); 904 eap_ttls_state(data, FAILURE); 905 } 906 break; 907 case PHASE2_METHOD: 908 eap_ttls_state(data, SUCCESS); 909 break; 910 case FAILURE: 911 break; 912 default: 913 wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d", 914 __func__, data->state); 915 break; 916 } 917} 918 919 920static void eap_ttls_process_phase2_eap(struct eap_sm *sm, 921 struct eap_ttls_data *data, 922 const u8 *eap, size_t eap_len) 923{ 924 struct eap_hdr *hdr; 925 size_t len; 926 927 if (data->state == PHASE2_START) { 928 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: initializing Phase 2"); 929 if (eap_ttls_phase2_eap_init(sm, data, EAP_TYPE_IDENTITY) < 0) 930 { 931 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: failed to " 932 "initialize EAP-Identity"); 933 return; 934 } 935 } 936 937 if (eap_len < sizeof(*hdr)) { 938 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: too short Phase 2 EAP " 939 "packet (len=%lu)", (unsigned long) eap_len); 940 return; 941 } 942 943 hdr = (struct eap_hdr *) eap; 944 len = be_to_host16(hdr->length); 945 wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: received Phase 2 EAP: code=%d " 946 "identifier=%d length=%lu", hdr->code, hdr->identifier, 947 (unsigned long) len); 948 if (len > eap_len) { 949 wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Length mismatch in Phase 2" 950 " EAP frame (hdr len=%lu, data len in AVP=%lu)", 951 (unsigned long) len, (unsigned long) eap_len); 952 return; 953 } 954 955 switch (hdr->code) { 956 case EAP_CODE_RESPONSE: 957 eap_ttls_process_phase2_eap_response(sm, data, (u8 *) hdr, 958 len); 959 break; 960 default: 961 wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Unexpected code=%d in " 962 "Phase 2 EAP header", hdr->code); 963 break; 964 } 965} 966 967 968static void eap_ttls_process_phase2(struct eap_sm *sm, 969 struct eap_ttls_data *data, 970 struct wpabuf *in_buf) 971{ 972 struct wpabuf *in_decrypted; 973 struct eap_ttls_avp parse; 974 975 wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for" 976 " Phase 2", (unsigned long) wpabuf_len(in_buf)); 977 978 if (data->pending_phase2_eap_resp) { 979 wpa_printf(MSG_DEBUG, "EAP-TTLS: Pending Phase 2 EAP response " 980 "- skip decryption and use old data"); 981 eap_ttls_process_phase2_eap( 982 sm, data, wpabuf_head(data->pending_phase2_eap_resp), 983 wpabuf_len(data->pending_phase2_eap_resp)); 984 wpabuf_free(data->pending_phase2_eap_resp); 985 data->pending_phase2_eap_resp = NULL; 986 return; 987 } 988 989 in_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn, 990 in_buf); 991 if (in_decrypted == NULL) { 992 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to decrypt Phase 2 " 993 "data"); 994 eap_ttls_state(data, FAILURE); 995 return; 996 } 997 998 wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 EAP", 999 in_decrypted); 1000 1001 if (eap_ttls_avp_parse(in_decrypted, &parse) < 0) { 1002 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to parse AVPs"); 1003 wpabuf_free(in_decrypted); 1004 eap_ttls_state(data, FAILURE); 1005 return; 1006 } 1007 1008 if (parse.user_name) { 1009 char *nbuf; 1010 nbuf = os_malloc(parse.user_name_len * 4 + 1); 1011 if (nbuf) { 1012 printf_encode(nbuf, parse.user_name_len * 4 + 1, 1013 parse.user_name, 1014 parse.user_name_len); 1015 eap_log_msg(sm, "TTLS-User-Name '%s'", nbuf); 1016 os_free(nbuf); 1017 } 1018 1019 os_free(sm->identity); 1020 sm->identity = os_malloc(parse.user_name_len); 1021 if (sm->identity == NULL) { 1022 eap_ttls_state(data, FAILURE); 1023 goto done; 1024 } 1025 os_memcpy(sm->identity, parse.user_name, parse.user_name_len); 1026 sm->identity_len = parse.user_name_len; 1027 if (eap_user_get(sm, parse.user_name, parse.user_name_len, 1) 1028 != 0) { 1029 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 Identity not " 1030 "found in the user database"); 1031 eap_ttls_state(data, FAILURE); 1032 goto done; 1033 } 1034 } 1035 1036#ifdef EAP_SERVER_TNC 1037 if (data->tnc_started && parse.eap == NULL) { 1038 wpa_printf(MSG_DEBUG, "EAP-TTLS: TNC started but no EAP " 1039 "response from peer"); 1040 eap_ttls_state(data, FAILURE); 1041 goto done; 1042 } 1043#endif /* EAP_SERVER_TNC */ 1044 1045 if (parse.eap) { 1046 eap_ttls_process_phase2_eap(sm, data, parse.eap, 1047 parse.eap_len); 1048 } else if (parse.user_password) { 1049 eap_ttls_process_phase2_pap(sm, data, parse.user_password, 1050 parse.user_password_len); 1051 } else if (parse.chap_password) { 1052 eap_ttls_process_phase2_chap(sm, data, 1053 parse.chap_challenge, 1054 parse.chap_challenge_len, 1055 parse.chap_password, 1056 parse.chap_password_len); 1057 } else if (parse.mschap_response) { 1058 eap_ttls_process_phase2_mschap(sm, data, 1059 parse.mschap_challenge, 1060 parse.mschap_challenge_len, 1061 parse.mschap_response, 1062 parse.mschap_response_len); 1063 } else if (parse.mschap2_response) { 1064 eap_ttls_process_phase2_mschapv2(sm, data, 1065 parse.mschap_challenge, 1066 parse.mschap_challenge_len, 1067 parse.mschap2_response, 1068 parse.mschap2_response_len); 1069 } 1070 1071done: 1072 wpabuf_free(in_decrypted); 1073 os_free(parse.eap); 1074} 1075 1076 1077static void eap_ttls_start_tnc(struct eap_sm *sm, struct eap_ttls_data *data) 1078{ 1079#ifdef EAP_SERVER_TNC 1080 if (!sm->tnc || data->state != SUCCESS || data->tnc_started) 1081 return; 1082 1083 wpa_printf(MSG_DEBUG, "EAP-TTLS: Initialize TNC"); 1084 if (eap_ttls_phase2_eap_init(sm, data, EAP_TYPE_TNC)) { 1085 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to initialize TNC"); 1086 eap_ttls_state(data, FAILURE); 1087 return; 1088 } 1089 1090 data->tnc_started = 1; 1091 eap_ttls_state(data, PHASE2_METHOD); 1092#endif /* EAP_SERVER_TNC */ 1093} 1094 1095 1096static int eap_ttls_process_version(struct eap_sm *sm, void *priv, 1097 int peer_version) 1098{ 1099 struct eap_ttls_data *data = priv; 1100 if (peer_version < data->ttls_version) { 1101 wpa_printf(MSG_DEBUG, "EAP-TTLS: peer ver=%d, own ver=%d; " 1102 "use version %d", 1103 peer_version, data->ttls_version, peer_version); 1104 data->ttls_version = peer_version; 1105 } 1106 1107 return 0; 1108} 1109 1110 1111static void eap_ttls_process_msg(struct eap_sm *sm, void *priv, 1112 const struct wpabuf *respData) 1113{ 1114 struct eap_ttls_data *data = priv; 1115 1116 switch (data->state) { 1117 case PHASE1: 1118 if (eap_server_tls_phase1(sm, &data->ssl) < 0) 1119 eap_ttls_state(data, FAILURE); 1120 break; 1121 case PHASE2_START: 1122 case PHASE2_METHOD: 1123 eap_ttls_process_phase2(sm, data, data->ssl.tls_in); 1124 eap_ttls_start_tnc(sm, data); 1125 break; 1126 case PHASE2_MSCHAPV2_RESP: 1127 if (data->mschapv2_resp_ok && wpabuf_len(data->ssl.tls_in) == 1128 0) { 1129 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer " 1130 "acknowledged response"); 1131 eap_ttls_state(data, SUCCESS); 1132 } else if (!data->mschapv2_resp_ok) { 1133 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer " 1134 "acknowledged error"); 1135 eap_ttls_state(data, FAILURE); 1136 } else { 1137 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Unexpected " 1138 "frame from peer (payload len %lu, " 1139 "expected empty frame)", 1140 (unsigned long) 1141 wpabuf_len(data->ssl.tls_in)); 1142 eap_ttls_state(data, FAILURE); 1143 } 1144 eap_ttls_start_tnc(sm, data); 1145 break; 1146 default: 1147 wpa_printf(MSG_DEBUG, "EAP-TTLS: Unexpected state %d in %s", 1148 data->state, __func__); 1149 break; 1150 } 1151} 1152 1153 1154static void eap_ttls_process(struct eap_sm *sm, void *priv, 1155 struct wpabuf *respData) 1156{ 1157 struct eap_ttls_data *data = priv; 1158 if (eap_server_tls_process(sm, &data->ssl, respData, data, 1159 EAP_TYPE_TTLS, eap_ttls_process_version, 1160 eap_ttls_process_msg) < 0) 1161 eap_ttls_state(data, FAILURE); 1162} 1163 1164 1165static Boolean eap_ttls_isDone(struct eap_sm *sm, void *priv) 1166{ 1167 struct eap_ttls_data *data = priv; 1168 return data->state == SUCCESS || data->state == FAILURE; 1169} 1170 1171 1172static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len) 1173{ 1174 struct eap_ttls_data *data = priv; 1175 u8 *eapKeyData; 1176 1177 if (data->state != SUCCESS) 1178 return NULL; 1179 1180 eapKeyData = eap_server_tls_derive_key(sm, &data->ssl, 1181 "ttls keying material", 1182 EAP_TLS_KEY_LEN); 1183 if (eapKeyData) { 1184 *len = EAP_TLS_KEY_LEN; 1185 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key", 1186 eapKeyData, EAP_TLS_KEY_LEN); 1187 } else { 1188 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key"); 1189 } 1190 1191 return eapKeyData; 1192} 1193 1194 1195static Boolean eap_ttls_isSuccess(struct eap_sm *sm, void *priv) 1196{ 1197 struct eap_ttls_data *data = priv; 1198 return data->state == SUCCESS; 1199} 1200 1201 1202static u8 * eap_ttls_get_session_id(struct eap_sm *sm, void *priv, size_t *len) 1203{ 1204 struct eap_ttls_data *data = priv; 1205 1206 if (data->state != SUCCESS) 1207 return NULL; 1208 1209 return eap_server_tls_derive_session_id(sm, &data->ssl, EAP_TYPE_TTLS, 1210 len); 1211} 1212 1213 1214static u8 * eap_ttls_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 1215{ 1216 struct eap_ttls_data *data = priv; 1217 u8 *eapKeyData, *emsk; 1218 1219 if (data->state != SUCCESS) 1220 return NULL; 1221 1222 eapKeyData = eap_server_tls_derive_key(sm, &data->ssl, 1223 "ttls keying material", 1224 EAP_TLS_KEY_LEN + EAP_EMSK_LEN); 1225 if (eapKeyData) { 1226 emsk = os_malloc(EAP_EMSK_LEN); 1227 if (emsk) 1228 os_memcpy(emsk, eapKeyData + EAP_TLS_KEY_LEN, 1229 EAP_EMSK_LEN); 1230 bin_clear_free(eapKeyData, EAP_TLS_KEY_LEN + EAP_EMSK_LEN); 1231 } else 1232 emsk = NULL; 1233 1234 if (emsk) { 1235 *len = EAP_EMSK_LEN; 1236 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Derived EMSK", 1237 emsk, EAP_EMSK_LEN); 1238 } else { 1239 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive EMSK"); 1240 } 1241 1242 return emsk; 1243} 1244 1245 1246int eap_server_ttls_register(void) 1247{ 1248 struct eap_method *eap; 1249 int ret; 1250 1251 eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, 1252 EAP_VENDOR_IETF, EAP_TYPE_TTLS, "TTLS"); 1253 if (eap == NULL) 1254 return -1; 1255 1256 eap->init = eap_ttls_init; 1257 eap->reset = eap_ttls_reset; 1258 eap->buildReq = eap_ttls_buildReq; 1259 eap->check = eap_ttls_check; 1260 eap->process = eap_ttls_process; 1261 eap->isDone = eap_ttls_isDone; 1262 eap->getKey = eap_ttls_getKey; 1263 eap->isSuccess = eap_ttls_isSuccess; 1264 eap->getSessionId = eap_ttls_get_session_id; 1265 eap->get_emsk = eap_ttls_get_emsk; 1266 1267 ret = eap_server_method_register(eap); 1268 if (ret) 1269 eap_server_method_free(eap); 1270 return ret; 1271} 1272