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 "eap_tls_common.h"
00023 #include "wpa_supplicant.h"
00024 #include "config_ssid.h"
00025 #include "ms_funcs.h"
00026 #include "crypto.h"
00027 #include "tls.h"
00028 #include "eap_ttls.h"
00029
00030
00031 static void eap_ttls_deinit(struct eap_sm *sm, void *priv);
00032
00033
00034 struct eap_ttls_data {
00035 struct eap_ssl_data ssl;
00036
00037 const struct eap_method *phase2_method;
00038 void *phase2_priv;
00039 int phase2_success;
00040 int phase2_start;
00041
00042 enum {
00043 EAP_TTLS_PHASE2_EAP,
00044 EAP_TTLS_PHASE2_MSCHAPV2,
00045 EAP_TTLS_PHASE2_MSCHAP,
00046 EAP_TTLS_PHASE2_PAP,
00047 EAP_TTLS_PHASE2_CHAP
00048 } phase2_type;
00049 u8 phase2_eap_type;
00050 u8 *phase2_eap_types;
00051 size_t num_phase2_eap_types;
00052
00053 u8 auth_response[20];
00054 int auth_response_valid;
00055 u8 ident;
00056 int resuming;
00057 int reauth;
00058 u8 *key_data;
00059
00060 u8 *pending_phase2_req;
00061 size_t pending_phase2_req_len;
00062 };
00063
00064
00065 static void * eap_ttls_init(struct eap_sm *sm)
00066 {
00067 struct eap_ttls_data *data;
00068 struct wpa_ssid *config = eap_get_config(sm);
00069 char *selected;
00070
00071 data = malloc(sizeof(*data));
00072 if (data == NULL)
00073 return NULL;
00074 memset(data, 0, sizeof(*data));
00075 selected = "EAP";
00076 data->phase2_type = EAP_TTLS_PHASE2_EAP;
00077 if (config && config->phase2) {
00078 if (strstr(config->phase2, "autheap=")) {
00079 selected = "EAP";
00080 data->phase2_type = EAP_TTLS_PHASE2_EAP;
00081 } else if (strstr(config->phase2, "auth=MSCHAPV2")) {
00082 selected = "MSCHAPV2";
00083 data->phase2_type = EAP_TTLS_PHASE2_MSCHAPV2;
00084 } else if (strstr(config->phase2, "auth=MSCHAP")) {
00085 selected = "MSCHAP";
00086 data->phase2_type = EAP_TTLS_PHASE2_MSCHAP;
00087 } else if (strstr(config->phase2, "auth=PAP")) {
00088 selected = "PAP";
00089 data->phase2_type = EAP_TTLS_PHASE2_PAP;
00090 } else if (strstr(config->phase2, "auth=CHAP")) {
00091 selected = "CHAP";
00092 data->phase2_type = EAP_TTLS_PHASE2_CHAP;
00093 }
00094 }
00095 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 type: %s", selected);
00096
00097 if (data->phase2_type == EAP_TTLS_PHASE2_EAP) {
00098 if (config && config->phase2) {
00099 char *start, *pos, *buf;
00100 u8 method, *methods = NULL, *_methods;
00101 size_t num_methods = 0;
00102 start = buf = strdup(config->phase2);
00103 if (buf == NULL) {
00104 eap_ttls_deinit(sm, data);
00105 return NULL;
00106 }
00107 while (start && *start != '\0') {
00108 pos = strstr(start, "autheap=");
00109 if (pos == NULL)
00110 break;
00111 if (start != pos && *(pos - 1) != ' ') {
00112 start = pos + 8;
00113 continue;
00114 }
00115
00116 start = pos + 8;
00117 pos = strchr(start, ' ');
00118 if (pos)
00119 *pos++ = '\0';
00120 method = eap_get_phase2_type(start);
00121 if (method == EAP_TYPE_NONE) {
00122 wpa_printf(MSG_ERROR, "EAP-TTLS: "
00123 "Unsupported Phase2 EAP "
00124 "method '%s'", start);
00125 } else {
00126 num_methods++;
00127 _methods = realloc(methods,
00128 num_methods);
00129 if (_methods == NULL) {
00130 free(methods);
00131 free(buf);
00132 eap_ttls_deinit(sm, data);
00133 return NULL;
00134 }
00135 methods = _methods;
00136 methods[num_methods - 1] = method;
00137 }
00138
00139 start = pos;
00140 }
00141 free(buf);
00142 data->phase2_eap_types = methods;
00143 data->num_phase2_eap_types = num_methods;
00144 }
00145 if (data->phase2_eap_types == NULL) {
00146 data->phase2_eap_types = eap_get_phase2_types(
00147 config, &data->num_phase2_eap_types);
00148 }
00149 if (data->phase2_eap_types == NULL) {
00150 wpa_printf(MSG_ERROR, "EAP-TTLS: No Phase2 EAP method "
00151 "available");
00152 eap_ttls_deinit(sm, data);
00153 return NULL;
00154 }
00155 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Phase2 EAP types",
00156 data->phase2_eap_types,
00157 data->num_phase2_eap_types);
00158 data->phase2_eap_type = EAP_TYPE_NONE;
00159 }
00160
00161
00162 if (eap_tls_ssl_init(sm, &data->ssl, config)) {
00163 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL.");
00164 eap_ttls_deinit(sm, data);
00165 return NULL;
00166 }
00167
00168 return data;
00169 }
00170
00171
00172 static void eap_ttls_deinit(struct eap_sm *sm, void *priv)
00173 {
00174 struct eap_ttls_data *data = priv;
00175 if (data == NULL)
00176 return;
00177 if (data->phase2_priv && data->phase2_method)
00178 data->phase2_method->deinit(sm, data->phase2_priv);
00179 free(data->phase2_eap_types);
00180 eap_tls_ssl_deinit(sm, &data->ssl);
00181 free(data->key_data);
00182 free(data->pending_phase2_req);
00183 free(data);
00184 }
00185
00186
00187 static int eap_ttls_encrypt(struct eap_sm *sm, struct eap_ttls_data *data,
00188 int id, const u8 *plain, size_t plain_len,
00189 u8 **out_data, size_t *out_len)
00190 {
00191 int res;
00192 u8 *pos;
00193 struct eap_hdr *resp;
00194
00195
00196
00197 resp = malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
00198 if (resp == NULL)
00199 return -1;
00200
00201 resp->code = EAP_CODE_RESPONSE;
00202 resp->identifier = id;
00203
00204 pos = (u8 *) (resp + 1);
00205 *pos++ = EAP_TYPE_TTLS;
00206 *pos++ = 0;
00207
00208 res = tls_connection_encrypt(sm->ssl_ctx, data->ssl.conn,
00209 plain, plain_len,
00210 pos, data->ssl.tls_out_limit);
00211 if (res < 0) {
00212 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt Phase 2 "
00213 "data");
00214 free(resp);
00215 return -1;
00216 }
00217
00218 *out_len = sizeof(struct eap_hdr) + 2 + res;
00219 resp->length = host_to_be16(*out_len);
00220 *out_data = (u8 *) resp;
00221 return 0;
00222 }
00223
00224
00225 static u8 * eap_ttls_avp_hdr(u8 *avphdr, u32 avp_code, u32 vendor_id,
00226 int mandatory, size_t len)
00227 {
00228 struct ttls_avp_vendor *avp;
00229 u8 flags;
00230 size_t hdrlen;
00231
00232 avp = (struct ttls_avp_vendor *) avphdr;
00233 flags = mandatory ? AVP_FLAGS_MANDATORY : 0;
00234 if (vendor_id) {
00235 flags |= AVP_FLAGS_VENDOR;
00236 hdrlen = sizeof(*avp);
00237 avp->vendor_id = host_to_be32(vendor_id);
00238 } else {
00239 hdrlen = sizeof(struct ttls_avp);
00240 }
00241
00242 avp->avp_code = host_to_be32(avp_code);
00243 avp->avp_length = host_to_be32((flags << 24) | (hdrlen + len));
00244
00245 return avphdr + hdrlen;
00246 }
00247
00248
00249 static u8 * eap_ttls_avp_add(u8 *start, u8 *avphdr, u32 avp_code,
00250 u32 vendor_id, int mandatory,
00251 u8 *data, size_t len)
00252 {
00253 u8 *pos;
00254 pos = eap_ttls_avp_hdr(avphdr, avp_code, vendor_id, mandatory, len);
00255 memcpy(pos, data, len);
00256 pos += len;
00257 AVP_PAD(start, pos);
00258 return pos;
00259 }
00260
00261
00262 static int eap_ttls_avp_encapsulate(u8 **resp, size_t *resp_len, u32 avp_code,
00263 int mandatory)
00264 {
00265 u8 *avp, *pos;
00266
00267 avp = malloc(sizeof(struct ttls_avp) + *resp_len + 4);
00268 if (avp == NULL) {
00269 free(*resp);
00270 *resp = NULL;
00271 *resp_len = 0;
00272 return -1;
00273 }
00274
00275 pos = eap_ttls_avp_hdr(avp, avp_code, 0, mandatory, *resp_len);
00276 memcpy(pos, *resp, *resp_len);
00277 pos += *resp_len;
00278 AVP_PAD(avp, pos);
00279 free(*resp);
00280 *resp = avp;
00281 *resp_len = pos - avp;
00282 return 0;
00283 }
00284
00285
00286 static int eap_ttls_phase2_nak(struct eap_sm *sm,
00287 struct eap_ttls_data *data,
00288 struct eap_hdr *hdr,
00289 u8 **resp, size_t *resp_len)
00290 {
00291 struct eap_hdr *resp_hdr;
00292 u8 *pos = (u8 *) (hdr + 1);
00293
00294 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 Request: Nak type=%d", *pos);
00295 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Allowed Phase2 EAP types",
00296 data->phase2_eap_types, data->num_phase2_eap_types);
00297 *resp_len = sizeof(struct eap_hdr) + 1 + data->num_phase2_eap_types;
00298 *resp = malloc(*resp_len);
00299 if (*resp == NULL)
00300 return -1;
00301
00302 resp_hdr = (struct eap_hdr *) (*resp);
00303 resp_hdr->code = EAP_CODE_RESPONSE;
00304 resp_hdr->identifier = hdr->identifier;
00305 resp_hdr->length = host_to_be16(*resp_len);
00306 pos = (u8 *) (resp_hdr + 1);
00307 *pos++ = EAP_TYPE_NAK;
00308 memcpy(pos, data->phase2_eap_types, data->num_phase2_eap_types);
00309
00310 return 0;
00311 }
00312
00313
00314 static int eap_ttls_phase2_request_eap(struct eap_sm *sm,
00315 struct eap_ttls_data *data,
00316 struct eap_method_ret *ret,
00317 const struct eap_hdr *req,
00318 struct eap_hdr *hdr,
00319 u8 **resp, size_t *resp_len)
00320 {
00321 size_t len = be_to_host16(hdr->length);
00322 u8 *pos;
00323 struct eap_method_ret iret;
00324 struct wpa_ssid *config = eap_get_config(sm);
00325
00326 if (len <= sizeof(struct eap_hdr)) {
00327 wpa_printf(MSG_INFO, "EAP-TTLS: too short "
00328 "Phase 2 request (len=%lu)", (unsigned long) len);
00329 return -1;
00330 }
00331 pos = (u8 *) (hdr + 1);
00332 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 EAP Request: type=%d", *pos);
00333 switch (*pos) {
00334 case EAP_TYPE_IDENTITY:
00335 *resp = eap_sm_buildIdentity(sm, req->identifier, resp_len, 1);
00336 break;
00337 default:
00338 if (data->phase2_eap_type == EAP_TYPE_NONE) {
00339 int i;
00340 for (i = 0; i < data->num_phase2_eap_types; i++) {
00341 if (data->phase2_eap_types[i] != *pos)
00342 continue;
00343
00344 data->phase2_eap_type = *pos;
00345 wpa_printf(MSG_DEBUG, "EAP-TTLS: Selected "
00346 "Phase 2 EAP method %d",
00347 data->phase2_eap_type);
00348 break;
00349 }
00350 }
00351 if (*pos != data->phase2_eap_type || *pos == EAP_TYPE_NONE) {
00352 if (eap_ttls_phase2_nak(sm, data, hdr, resp, resp_len))
00353 return -1;
00354 break;
00355 }
00356
00357 if (data->phase2_priv == NULL) {
00358 data->phase2_method = eap_sm_get_eap_methods(*pos);
00359 if (data->phase2_method) {
00360 sm->init_phase2 = 1;
00361 data->phase2_priv =
00362 data->phase2_method->init(sm);
00363 sm->init_phase2 = 0;
00364 }
00365 }
00366 if (data->phase2_priv == NULL || data->phase2_method == NULL) {
00367 wpa_printf(MSG_INFO, "EAP-TTLS: failed to initialize "
00368 "Phase 2 EAP method %d", *pos);
00369 return -1;
00370 }
00371 memset(&iret, 0, sizeof(iret));
00372 *resp = data->phase2_method->process(sm, data->phase2_priv,
00373 &iret, (u8 *) hdr, len,
00374 resp_len);
00375 if ((iret.methodState == METHOD_DONE ||
00376 iret.methodState == METHOD_MAY_CONT) &&
00377 (iret.decision == DECISION_UNCOND_SUCC ||
00378 iret.decision == DECISION_COND_SUCC ||
00379 iret.decision == DECISION_FAIL)) {
00380 ret->methodState = iret.methodState;
00381 ret->decision = iret.decision;
00382 }
00383 break;
00384 }
00385
00386 if (*resp == NULL &&
00387 (config->pending_req_identity || config->pending_req_password ||
00388 config->pending_req_otp)) {
00389 return 0;
00390 }
00391
00392 if (*resp == NULL)
00393 return -1;
00394
00395 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP encapsulate EAP Response",
00396 *resp, *resp_len);
00397 return eap_ttls_avp_encapsulate(resp, resp_len,
00398 RADIUS_ATTR_EAP_MESSAGE, 1);
00399 }
00400
00401
00402 static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
00403 struct eap_ttls_data *data,
00404 struct eap_method_ret *ret,
00405 const struct eap_hdr *req,
00406 struct eap_hdr *hdr,
00407 u8 **resp, size_t *resp_len)
00408 {
00409 struct wpa_ssid *config = eap_get_config(sm);
00410 u8 *buf, *pos, *challenge, *username, *peer_challenge;
00411 size_t username_len;
00412 int i;
00413
00414 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 MSCHAPV2 Request");
00415
00416
00417
00418
00419 username = config->identity;
00420 username_len = config->identity_len;
00421 pos = username;
00422 for (i = 0; i < username_len; i++) {
00423 if (username[i] == '\\') {
00424 username_len -= i + 1;
00425 username += i + 1;
00426 break;
00427 }
00428 }
00429
00430 pos = buf = malloc(config->identity_len + 1000);
00431 if (buf == NULL) {
00432 wpa_printf(MSG_ERROR,
00433 "EAP-TTLS/MSCHAPV2: Failed to allocate memory");
00434 return -1;
00435 }
00436
00437
00438 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
00439 config->identity, config->identity_len);
00440
00441
00442 challenge = eap_tls_derive_key(sm, &data->ssl, "ttls challenge",
00443 EAP_TTLS_MSCHAPV2_CHALLENGE_LEN * 2 +
00444 1);
00445 if (challenge == NULL) {
00446 free(buf);
00447 wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
00448 "implicit challenge");
00449 return -1;
00450 }
00451 peer_challenge = challenge + 1 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN;
00452
00453 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_MS_CHAP_CHALLENGE,
00454 RADIUS_VENDOR_ID_MICROSOFT, 1,
00455 challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
00456
00457
00458 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_RESPONSE,
00459 RADIUS_VENDOR_ID_MICROSOFT, 1,
00460 EAP_TTLS_MSCHAPV2_RESPONSE_LEN);
00461 data->ident = challenge[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN];
00462 *pos++ = data->ident;
00463 *pos++ = 0;
00464 memcpy(pos, peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
00465 pos += EAP_TTLS_MSCHAPV2_CHALLENGE_LEN;
00466 memset(pos, 0, 8);
00467 pos += 8;
00468 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAPV2: implicit auth_challenge",
00469 challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
00470 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAPV2: peer_challenge",
00471 peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
00472 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: MSCHAPV2 username",
00473 username, username_len);
00474 wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: MSCHAPV2 password",
00475 config->password, config->password_len);
00476 generate_nt_response(challenge, peer_challenge,
00477 username, username_len,
00478 config->password, config->password_len,
00479 pos);
00480 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAPV2 response", pos, 24);
00481 generate_authenticator_response(config->password, config->password_len,
00482 peer_challenge, challenge,
00483 username, username_len,
00484 pos, data->auth_response);
00485 data->auth_response_valid = 1;
00486
00487 pos += 24;
00488 free(challenge);
00489 AVP_PAD(buf, pos);
00490
00491 *resp = buf;
00492 *resp_len = pos - buf;
00493
00494 if (sm->workaround) {
00495
00496
00497
00498 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: EAP workaround - "
00499 "allow success without tunneled response");
00500 ret->methodState = METHOD_MAY_CONT;
00501 ret->decision = DECISION_COND_SUCC;
00502 }
00503
00504 return 0;
00505 }
00506
00507
00508 static int eap_ttls_phase2_request_mschap(struct eap_sm *sm,
00509 struct eap_ttls_data *data,
00510 struct eap_method_ret *ret,
00511 const struct eap_hdr *req,
00512 struct eap_hdr *hdr,
00513 u8 **resp, size_t *resp_len)
00514 {
00515 struct wpa_ssid *config = eap_get_config(sm);
00516 u8 *buf, *pos, *challenge;
00517
00518 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 MSCHAP Request");
00519
00520 pos = buf = malloc(config->identity_len + 1000);
00521 if (buf == NULL) {
00522 wpa_printf(MSG_ERROR,
00523 "EAP-TTLS/MSCHAP: Failed to allocate memory");
00524 return -1;
00525 }
00526
00527
00528 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
00529 config->identity, config->identity_len);
00530
00531
00532 challenge = eap_tls_derive_key(sm, &data->ssl, "ttls challenge",
00533 EAP_TLS_KEY_LEN);
00534 if (challenge == NULL) {
00535 free(buf);
00536 wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAP: Failed to derive "
00537 "implicit challenge");
00538 return -1;
00539 }
00540
00541 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_MS_CHAP_CHALLENGE,
00542 RADIUS_VENDOR_ID_MICROSOFT, 1,
00543 challenge, EAP_TTLS_MSCHAP_CHALLENGE_LEN);
00544
00545
00546 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_RESPONSE,
00547 RADIUS_VENDOR_ID_MICROSOFT, 1,
00548 EAP_TTLS_MSCHAP_RESPONSE_LEN);
00549 data->ident = challenge[EAP_TTLS_MSCHAP_CHALLENGE_LEN];
00550 *pos++ = data->ident;
00551 *pos++ = 1;
00552 memset(pos, 0, 24);
00553 pos += 24;
00554 nt_challenge_response(challenge,
00555 config->password, config->password_len,
00556 pos);
00557 wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: MSCHAP password",
00558 config->password, config->password_len);
00559 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAP implicit challenge",
00560 challenge, EAP_TTLS_MSCHAP_CHALLENGE_LEN);
00561 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAP response", pos, 24);
00562 pos += 24;
00563 free(challenge);
00564 AVP_PAD(buf, pos);
00565
00566 *resp = buf;
00567 *resp_len = pos - buf;
00568
00569
00570
00571 ret->methodState = METHOD_DONE;
00572 ret->decision = DECISION_COND_SUCC;
00573
00574 return 0;
00575 }
00576
00577
00578 static int eap_ttls_phase2_request_pap(struct eap_sm *sm,
00579 struct eap_ttls_data *data,
00580 struct eap_method_ret *ret,
00581 const struct eap_hdr *req,
00582 struct eap_hdr *hdr,
00583 u8 **resp, size_t *resp_len)
00584 {
00585 struct wpa_ssid *config = eap_get_config(sm);
00586 u8 *buf, *pos;
00587 size_t pad;
00588
00589 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 PAP Request");
00590
00591 pos = buf = malloc(config->identity_len + config->password_len + 100);
00592 if (buf == NULL) {
00593 wpa_printf(MSG_ERROR,
00594 "EAP-TTLS/PAP: Failed to allocate memory");
00595 return -1;
00596 }
00597
00598
00599 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
00600 config->identity, config->identity_len);
00601
00602
00603
00604
00605 pad = (16 - (config->password_len & 15)) & 15;
00606 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_USER_PASSWORD, 0, 1,
00607 config->password_len + pad);
00608 memcpy(pos, config->password, config->password_len);
00609 pos += config->password_len;
00610 memset(pos, 0, pad);
00611 pos += pad;
00612 AVP_PAD(buf, pos);
00613
00614 *resp = buf;
00615 *resp_len = pos - buf;
00616
00617
00618
00619 ret->methodState = METHOD_DONE;
00620 ret->decision = DECISION_COND_SUCC;
00621
00622 return 0;
00623 }
00624
00625
00626 static int eap_ttls_phase2_request_chap(struct eap_sm *sm,
00627 struct eap_ttls_data *data,
00628 struct eap_method_ret *ret,
00629 const struct eap_hdr *req,
00630 struct eap_hdr *hdr,
00631 u8 **resp, size_t *resp_len)
00632 {
00633 struct wpa_ssid *config = eap_get_config(sm);
00634 u8 *buf, *pos, *challenge;
00635 const u8 *addr[3];
00636 size_t len[3];
00637
00638 wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 CHAP Request");
00639
00640 pos = buf = malloc(config->identity_len + 1000);
00641 if (buf == NULL) {
00642 wpa_printf(MSG_ERROR,
00643 "EAP-TTLS/CHAP: Failed to allocate memory");
00644 return -1;
00645 }
00646
00647
00648 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
00649 config->identity, config->identity_len);
00650
00651
00652 challenge = eap_tls_derive_key(sm, &data->ssl, "ttls challenge",
00653 EAP_TLS_KEY_LEN);
00654 if (challenge == NULL) {
00655 free(buf);
00656 wpa_printf(MSG_ERROR, "EAP-TTLS/CHAP: Failed to derive "
00657 "implicit challenge");
00658 return -1;
00659 }
00660
00661 pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_CHAP_CHALLENGE, 0, 1,
00662 challenge, EAP_TTLS_CHAP_CHALLENGE_LEN);
00663
00664
00665 pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_CHAP_PASSWORD, 0, 1,
00666 1 + EAP_TTLS_CHAP_PASSWORD_LEN);
00667 data->ident = challenge[EAP_TTLS_CHAP_CHALLENGE_LEN];
00668 *pos++ = data->ident;
00669
00670
00671 addr[0] = &data->ident;
00672 len[0] = 1;
00673 addr[1] = config->password;
00674 len[1] = config->password_len;
00675 addr[2] = challenge;
00676 len[2] = EAP_TTLS_CHAP_CHALLENGE_LEN;
00677 md5_vector(3, addr, len, pos);
00678
00679 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: CHAP username",
00680 config->identity, config->identity_len);
00681 wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: CHAP password",
00682 config->password, config->password_len);
00683 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: CHAP implicit challenge",
00684 challenge, EAP_TTLS_CHAP_CHALLENGE_LEN);
00685 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: CHAP password",
00686 pos, EAP_TTLS_CHAP_PASSWORD_LEN);
00687 pos += EAP_TTLS_CHAP_PASSWORD_LEN;
00688 free(challenge);
00689 AVP_PAD(buf, pos);
00690
00691 *resp = buf;
00692 *resp_len = pos - buf;
00693
00694
00695
00696 ret->methodState = METHOD_DONE;
00697 ret->decision = DECISION_COND_SUCC;
00698
00699 return 0;
00700 }
00701
00702
00703 static int eap_ttls_phase2_request(struct eap_sm *sm,
00704 struct eap_ttls_data *data,
00705 struct eap_method_ret *ret,
00706 const struct eap_hdr *req,
00707 struct eap_hdr *hdr,
00708 u8 **resp, size_t *resp_len)
00709 {
00710 struct wpa_ssid *config = eap_get_config(sm);
00711 int res = 0;
00712
00713 if (data->phase2_type == EAP_TTLS_PHASE2_MSCHAPV2 ||
00714 data->phase2_type == EAP_TTLS_PHASE2_MSCHAP ||
00715 data->phase2_type == EAP_TTLS_PHASE2_PAP ||
00716 data->phase2_type == EAP_TTLS_PHASE2_CHAP) {
00717 if (config->identity == NULL) {
00718 wpa_printf(MSG_INFO,
00719 "EAP-TTLS: Identity not configured");
00720 eap_sm_request_identity(sm, config);
00721 if (config->password == NULL)
00722 eap_sm_request_password(sm, config);
00723 return 0;
00724 }
00725
00726 if (config->password == NULL) {
00727 wpa_printf(MSG_INFO,
00728 "EAP-TTLS: Password not configured");
00729 eap_sm_request_password(sm, config);
00730 return 0;
00731 }
00732 }
00733
00734 switch (data->phase2_type) {
00735 case EAP_TTLS_PHASE2_EAP:
00736 res = eap_ttls_phase2_request_eap(sm, data, ret, req, hdr,
00737 resp, resp_len);
00738 break;
00739 case EAP_TTLS_PHASE2_MSCHAPV2:
00740 res = eap_ttls_phase2_request_mschapv2(sm, data, ret, req, hdr,
00741 resp, resp_len);
00742 break;
00743 case EAP_TTLS_PHASE2_MSCHAP:
00744 res = eap_ttls_phase2_request_mschap(sm, data, ret, req, hdr,
00745 resp, resp_len);
00746 break;
00747 case EAP_TTLS_PHASE2_PAP:
00748 res = eap_ttls_phase2_request_pap(sm, data, ret, req, hdr,
00749 resp, resp_len);
00750 break;
00751 case EAP_TTLS_PHASE2_CHAP:
00752 res = eap_ttls_phase2_request_chap(sm, data, ret, req, hdr,
00753 resp, resp_len);
00754 break;
00755 default:
00756 wpa_printf(MSG_ERROR, "EAP-TTLS: Phase 2 - Unknown");
00757 res = -1;
00758 break;
00759 }
00760
00761 if (res < 0) {
00762 ret->methodState = METHOD_DONE;
00763 ret->decision = DECISION_FAIL;
00764 }
00765
00766 return res;
00767 }
00768
00769
00770 static int eap_ttls_decrypt(struct eap_sm *sm, struct eap_ttls_data *data,
00771 struct eap_method_ret *ret,
00772 const struct eap_hdr *req,
00773 const u8 *in_data, size_t in_len,
00774 u8 **out_data, size_t *out_len)
00775 {
00776 u8 *in_decrypted = NULL, *pos;
00777 int buf_len, len_decrypted = 0, len, left, retval = 0;
00778 struct eap_hdr *hdr = NULL;
00779 u8 *resp = NULL, *mschapv2 = NULL, *eapdata = NULL;
00780 size_t resp_len, eap_len = 0;
00781 struct ttls_avp *avp;
00782 u8 recv_response[20];
00783 int mschapv2_error = 0;
00784 struct wpa_ssid *config = eap_get_config(sm);
00785 const u8 *msg;
00786 size_t msg_len;
00787 int need_more_input;
00788
00789 wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for"
00790 " Phase 2", (unsigned long) in_len);
00791
00792 if (data->pending_phase2_req) {
00793 wpa_printf(MSG_DEBUG, "EAP-TTLS: Pending Phase 2 request - "
00794 "skip decryption and use old data");
00795
00796 free(data->ssl.tls_in);
00797 data->ssl.tls_in = NULL;
00798 data->ssl.tls_in_len = 0;
00799 data->ssl.tls_in_left = 0;
00800 data->ssl.tls_in_total = 0;
00801
00802 in_decrypted = data->pending_phase2_req;
00803 data->pending_phase2_req = NULL;
00804 len_decrypted = data->pending_phase2_req_len;
00805 if (data->pending_phase2_req_len == 0) {
00806 free(in_decrypted);
00807 in_decrypted = NULL;
00808 goto fake_req_identity;
00809 }
00810 goto continue_req;
00811 }
00812
00813 if (in_len == 0 && data->phase2_start) {
00814 data->phase2_start = 0;
00815
00816
00817
00818
00819
00820 if (data->reauth &&
00821 tls_connection_resumed(sm->ssl_ctx, data->ssl.conn)) {
00822 wpa_printf(MSG_DEBUG, "EAP-TTLS: Session resumption - "
00823 "skip phase 2");
00824 *out_data = eap_tls_build_ack(&data->ssl, out_len,
00825 req->identifier,
00826 EAP_TYPE_TTLS, 0);
00827 ret->methodState = METHOD_DONE;
00828 ret->decision = DECISION_UNCOND_SUCC;
00829 data->phase2_success = 1;
00830 return 0;
00831 }
00832 fake_req_identity:
00833 wpa_printf(MSG_DEBUG, "EAP-TTLS: empty data in beginning of "
00834 "Phase 2 - use fake EAP-Request Identity");
00835 buf_len = sizeof(*hdr) + 1;
00836 in_decrypted = malloc(buf_len);
00837 if (in_decrypted == NULL) {
00838 wpa_printf(MSG_WARNING, "EAP-TTLS: failed to allocate "
00839 "memory for fake EAP-Identity Request");
00840 retval = -1;
00841 goto done;
00842 }
00843 hdr = (struct eap_hdr *) in_decrypted;
00844 hdr->code = EAP_CODE_REQUEST;
00845 hdr->identifier = 0;
00846 hdr->length = host_to_be16(sizeof(*hdr) + 1);
00847 in_decrypted[sizeof(*hdr)] = EAP_TYPE_IDENTITY;
00848 goto process_eap;
00849 }
00850
00851 msg = eap_tls_data_reassemble(sm, &data->ssl, in_data, in_len,
00852 &msg_len, &need_more_input);
00853 if (msg == NULL)
00854 return need_more_input ? 1 : -1;
00855
00856 buf_len = in_len;
00857 if (data->ssl.tls_in_total > buf_len)
00858 buf_len = data->ssl.tls_in_total;
00859 in_decrypted = malloc(buf_len);
00860 if (in_decrypted == NULL) {
00861 free(data->ssl.tls_in);
00862 data->ssl.tls_in = NULL;
00863 data->ssl.tls_in_len = 0;
00864 wpa_printf(MSG_WARNING, "EAP-TTLS: failed to allocate memory "
00865 "for decryption");
00866 retval = -1;
00867 goto done;
00868 }
00869
00870 len_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
00871 msg, msg_len,
00872 in_decrypted, buf_len);
00873 free(data->ssl.tls_in);
00874 data->ssl.tls_in = NULL;
00875 data->ssl.tls_in_len = 0;
00876 if (len_decrypted < 0) {
00877 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to decrypt Phase 2 "
00878 "data");
00879 retval = -1;
00880 goto done;
00881 }
00882
00883 continue_req:
00884 data->phase2_start = 0;
00885
00886 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 AVPs",
00887 in_decrypted, len_decrypted);
00888 if (len_decrypted < sizeof(struct ttls_avp)) {
00889 wpa_printf(MSG_WARNING, "EAP-TTLS: Too short Phase 2 AVP frame"
00890 " len=%d expected %lu or more - dropped",
00891 len_decrypted,
00892 (unsigned long) sizeof(struct ttls_avp));
00893 retval = -1;
00894 goto done;
00895 }
00896
00897
00898 pos = in_decrypted;
00899 left = len_decrypted;
00900 mschapv2 = NULL;
00901
00902 while (left > 0) {
00903 u32 avp_code, avp_length, vendor_id = 0;
00904 u8 avp_flags, *dpos;
00905 size_t pad, dlen;
00906 avp = (struct ttls_avp *) pos;
00907 avp_code = be_to_host32(avp->avp_code);
00908 avp_length = be_to_host32(avp->avp_length);
00909 avp_flags = (avp_length >> 24) & 0xff;
00910 avp_length &= 0xffffff;
00911 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP: code=%d flags=0x%02x "
00912 "length=%d", (int) avp_code, avp_flags,
00913 (int) avp_length);
00914 if (avp_length > left) {
00915 wpa_printf(MSG_WARNING, "EAP-TTLS: AVP overflow "
00916 "(len=%d, left=%d) - dropped",
00917 (int) avp_length, left);
00918 retval = -1;
00919 goto done;
00920 }
00921 dpos = (u8 *) (avp + 1);
00922 dlen = avp_length - sizeof(*avp);
00923 if (avp_flags & AVP_FLAGS_VENDOR) {
00924 if (dlen < 4) {
00925 wpa_printf(MSG_WARNING, "EAP-TTLS: vendor AVP "
00926 "underflow");
00927 retval = -1;
00928 goto done;
00929 }
00930 vendor_id = be_to_host32(* (u32 *) dpos);
00931 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d",
00932 (int) vendor_id);
00933 dpos += 4;
00934 dlen -= 4;
00935 }
00936
00937 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen);
00938
00939 if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) {
00940 wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message");
00941 if (eapdata == NULL) {
00942 eapdata = malloc(dlen);
00943 if (eapdata == NULL) {
00944 retval = -1;
00945 wpa_printf(MSG_WARNING, "EAP-TTLS: "
00946 "failed to allocate memory "
00947 "for Phase 2 EAP data");
00948 goto done;
00949 }
00950 memcpy(eapdata, dpos, dlen);
00951 eap_len = dlen;
00952 } else {
00953 u8 *neweap = realloc(eapdata, eap_len + dlen);
00954 if (neweap == NULL) {
00955 retval = -1;
00956 wpa_printf(MSG_WARNING, "EAP-TTLS: "
00957 "failed to allocate memory "
00958 "for Phase 2 EAP data");
00959 goto done;
00960 }
00961 memcpy(neweap + eap_len, dpos, dlen);
00962 eapdata = neweap;
00963 eap_len += dlen;
00964 }
00965 } else if (vendor_id == 0 &&
00966 avp_code == RADIUS_ATTR_REPLY_MESSAGE) {
00967
00968
00969 wpa_hexdump_ascii(MSG_DEBUG,
00970 "EAP-TTLS: AVP - Reply-Message",
00971 dpos, dlen);
00972 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
00973 avp_code == RADIUS_ATTR_MS_CHAP2_SUCCESS) {
00974 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: "
00975 "MS-CHAP2-Success", dpos, dlen);
00976 if (dlen != 43) {
00977 wpa_printf(MSG_WARNING, "EAP-TTLS: Unexpected "
00978 "MS-CHAP2-Success length "
00979 "(len=%lu, expected 43)",
00980 (unsigned long) dlen);
00981 retval = -1;
00982 break;
00983 }
00984 mschapv2 = dpos;
00985 } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
00986 avp_code == RADIUS_ATTR_MS_CHAP_ERROR) {
00987 wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: "
00988 "MS-CHAP-Error", dpos, dlen);
00989 mschapv2_error = 1;
00990 } else if (avp_flags & AVP_FLAGS_MANDATORY) {
00991 wpa_printf(MSG_WARNING, "EAP-TTLS: Unsupported "
00992 "mandatory AVP code %d vendor_id %d - "
00993 "dropped", (int) avp_code, (int) vendor_id);
00994 retval = -1;
00995 goto done;
00996 } else {
00997 wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported "
00998 "AVP code %d vendor_id %d",
00999 (int) avp_code, (int) vendor_id);
01000 }
01001
01002 pad = (4 - (avp_length & 3)) & 3;
01003 pos += avp_length + pad;
01004 left -= avp_length + pad;
01005 }
01006
01007 switch (data->phase2_type) {
01008 case EAP_TTLS_PHASE2_EAP:
01009 if (eapdata == NULL) {
01010 wpa_printf(MSG_WARNING, "EAP-TTLS: No EAP Message in "
01011 "the packet - dropped");
01012 retval = -1;
01013 goto done;
01014 }
01015
01016 wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Phase 2 EAP",
01017 eapdata, eap_len);
01018 hdr = (struct eap_hdr *) eapdata;
01019
01020 if (eap_len < sizeof(*hdr)) {
01021 wpa_printf(MSG_WARNING, "EAP-TTLS: Too short Phase 2 "
01022 "EAP frame (len=%lu, expected %lu or more) "
01023 "- dropped", (unsigned long) eap_len,
01024 (unsigned long) sizeof(*hdr));
01025 retval = -1;
01026 goto done;
01027 }
01028 len = be_to_host16(hdr->length);
01029 if (len > eap_len) {
01030 wpa_printf(MSG_INFO, "EAP-TTLS: Length mismatch in "
01031 "Phase 2 EAP frame (EAP hdr len=%d, EAP "
01032 "data len in AVP=%lu)", len,
01033 (unsigned long) eap_len);
01034 retval = -1;
01035 goto done;
01036 }
01037 wpa_printf(MSG_DEBUG, "EAP-TTLS: received Phase 2: code=%d "
01038 "identifier=%d length=%d",
01039 hdr->code, hdr->identifier, len);
01040 process_eap:
01041 switch (hdr->code) {
01042 case EAP_CODE_REQUEST:
01043 if (eap_ttls_phase2_request(sm, data, ret, req, hdr,
01044 &resp, &resp_len)) {
01045 wpa_printf(MSG_INFO, "EAP-TTLS: Phase2 "
01046 "Request processing failed");
01047 retval = -1;
01048 goto done;
01049 }
01050 break;
01051 default:
01052 wpa_printf(MSG_INFO, "EAP-TTLS: Unexpected code=%d in "
01053 "Phase 2 EAP header", hdr->code);
01054 retval = -1;
01055 break;
01056 }
01057 break;
01058 case EAP_TTLS_PHASE2_MSCHAPV2:
01059 if (mschapv2_error) {
01060 wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Received "
01061 "MS-CHAP-Error - failed");
01062 ret->methodState = METHOD_DONE;
01063 ret->decision = DECISION_FAIL;
01064 *out_data = eap_tls_build_ack(&data->ssl, out_len,
01065 req->identifier,
01066 EAP_TYPE_TTLS, 0);
01067 break;
01068 }
01069
01070 if (mschapv2 == NULL) {
01071 wpa_printf(MSG_WARNING, "EAP-TTLS: no MS-CHAP2-Success"
01072 " AVP received for Phase2 MSCHAPV2");
01073 retval = -1;
01074 break;
01075 }
01076 if (mschapv2[0] != data->ident) {
01077 wpa_printf(MSG_WARNING, "EAP-TTLS: Ident mismatch "
01078 "for Phase 2 MSCHAPV2 (received Ident "
01079 "0x%02x, expected 0x%02x)",
01080 mschapv2[0], data->ident);
01081 retval = -1;
01082 break;
01083 }
01084 if (!data->auth_response_valid ||
01085 mschapv2[1] != 'S' || mschapv2[2] != '=' ||
01086 hexstr2bin((char *) (mschapv2 + 3), recv_response, 20) ||
01087 memcmp(data->auth_response, recv_response, 20) != 0) {
01088 wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid "
01089 "authenticator response in Phase 2 "
01090 "MSCHAPV2 success request");
01091 retval = -1;
01092 break;
01093 }
01094
01095 wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 MSCHAPV2 "
01096 "authentication succeeded");
01097 ret->methodState = METHOD_DONE;
01098 ret->decision = DECISION_UNCOND_SUCC;
01099 data->phase2_success = 1;
01100
01101
01102
01103 retval = 1;
01104 goto done;
01105 case EAP_TTLS_PHASE2_MSCHAP:
01106 case EAP_TTLS_PHASE2_PAP:
01107 case EAP_TTLS_PHASE2_CHAP:
01108
01109
01110 wpa_printf(MSG_INFO, "EAP-TTLS: Phase 2 received unexpected "
01111 "tunneled data");
01112 retval = -1;
01113 break;
01114 }
01115
01116 if (resp) {
01117 wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Encrypting Phase 2 data",
01118 resp, resp_len);
01119
01120 if (eap_ttls_encrypt(sm, data, req->identifier,
01121 resp, resp_len, out_data, out_len)) {
01122 wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt "
01123 "a Phase 2 frame");
01124 }
01125 free(resp);
01126 } else if (config->pending_req_identity ||
01127 config->pending_req_password ||
01128 config->pending_req_otp ||
01129 config->pending_req_new_password) {
01130 free(data->pending_phase2_req);
01131 data->pending_phase2_req = malloc(len_decrypted);
01132 if (data->pending_phase2_req) {
01133 memcpy(data->pending_phase2_req, in_decrypted,
01134 len_decrypted);
01135 data->pending_phase2_req_len = len_decrypted;
01136 }
01137 }
01138
01139 done:
01140 free(in_decrypted);
01141 free(eapdata);
01142
01143 if (retval < 0) {
01144 ret->methodState = METHOD_DONE;
01145 ret->decision = DECISION_FAIL;
01146 }
01147
01148 return retval;
01149 }
01150
01151
01152 static u8 * eap_ttls_process(struct eap_sm *sm, void *priv,
01153 struct eap_method_ret *ret,
01154 const u8 *reqData, size_t reqDataLen,
01155 size_t *respDataLen)
01156 {
01157 const struct eap_hdr *req;
01158 size_t left;
01159 int res;
01160 u8 flags, *resp, id;
01161 const u8 *pos;
01162 struct eap_ttls_data *data = priv;
01163
01164 pos = eap_tls_process_init(sm, &data->ssl, EAP_TYPE_TTLS, ret,
01165 reqData, reqDataLen, &left, &flags);
01166 if (pos == NULL)
01167 return NULL;
01168 req = (const struct eap_hdr *) reqData;
01169 id = req->identifier;
01170
01171 if (flags & EAP_TLS_FLAGS_START) {
01172 wpa_printf(MSG_DEBUG, "EAP-TTLS: Start");
01173
01174
01175
01176
01177
01178 left = 0;
01179 }
01180
01181 resp = NULL;
01182 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
01183 !data->resuming) {
01184 res = eap_ttls_decrypt(sm, data, ret, req, pos, left,
01185 &resp, respDataLen);
01186 } else {
01187 res = eap_tls_process_helper(sm, &data->ssl, EAP_TYPE_TTLS, 0,
01188 id, pos, left,
01189 &resp, respDataLen);
01190
01191 if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
01192 wpa_printf(MSG_DEBUG,
01193 "EAP-TTLS: TLS done, proceed to Phase 2");
01194 if (data->resuming) {
01195 wpa_printf(MSG_DEBUG, "EAP-TTLS: fast reauth -"
01196 " may skip Phase 2");
01197 ret->decision = DECISION_COND_SUCC;
01198 ret->methodState = METHOD_MAY_CONT;
01199 }
01200 data->phase2_start = 1;
01201 free(data->key_data);
01202 data->key_data =
01203 eap_tls_derive_key(sm, &data->ssl,
01204 "ttls keying material",
01205 EAP_TLS_KEY_LEN);
01206 if (data->key_data) {
01207 wpa_hexdump_key(MSG_DEBUG,
01208 "EAP-TTLS: Derived key",
01209 data->key_data,
01210 EAP_TLS_KEY_LEN);
01211 } else {
01212 wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to "
01213 "derive key");
01214 }
01215
01216 if (*respDataLen == 0) {
01217 if (eap_ttls_decrypt(sm, data, ret, req, NULL,
01218 0, &resp, respDataLen)) {
01219 wpa_printf(MSG_WARNING, "EAP-TTLS: "
01220 "failed to process early "
01221 "start for Phase 2");
01222 }
01223 res = 0;
01224 }
01225 data->resuming = 0;
01226 }
01227 }
01228
01229 if (ret->methodState == METHOD_DONE) {
01230 ret->allowNotifications = FALSE;
01231 if (ret->decision == DECISION_UNCOND_SUCC ||
01232 ret->decision == DECISION_COND_SUCC) {
01233 wpa_printf(MSG_DEBUG, "EAP-TTLS: Authentication "
01234 "completed successfully");
01235 data->phase2_success = 1;
01236 }
01237 } else if (sm->workaround && ret->methodState == METHOD_MAY_CONT &&
01238 (ret->decision == DECISION_UNCOND_SUCC ||
01239 ret->decision == DECISION_COND_SUCC)) {
01240 wpa_printf(MSG_DEBUG, "EAP-TTLS: Authentication "
01241 "completed successfully (EAP workaround)");
01242 data->phase2_success = 1;
01243 }
01244
01245 if (res == 1) {
01246 return eap_tls_build_ack(&data->ssl, respDataLen, id,
01247 EAP_TYPE_TTLS, 0);
01248 }
01249 return resp;
01250 }
01251
01252
01253 static Boolean eap_ttls_has_reauth_data(struct eap_sm *sm, void *priv)
01254 {
01255 struct eap_ttls_data *data = priv;
01256 return tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
01257 data->phase2_success;
01258 }
01259
01260
01261 static void eap_ttls_deinit_for_reauth(struct eap_sm *sm, void *priv)
01262 {
01263 struct eap_ttls_data *data = priv;
01264 free(data->pending_phase2_req);
01265 data->pending_phase2_req = NULL;
01266 }
01267
01268
01269 static void * eap_ttls_init_for_reauth(struct eap_sm *sm, void *priv)
01270 {
01271 struct eap_ttls_data *data = priv;
01272 free(data->key_data);
01273 data->key_data = NULL;
01274 if (eap_tls_reauth_init(sm, &data->ssl)) {
01275 free(data);
01276 return NULL;
01277 }
01278 data->phase2_start = 0;
01279 data->phase2_success = 0;
01280 data->resuming = 1;
01281 data->reauth = 1;
01282 return priv;
01283 }
01284
01285
01286 static int eap_ttls_get_status(struct eap_sm *sm, void *priv, char *buf,
01287 size_t buflen, int verbose)
01288 {
01289 struct eap_ttls_data *data = priv;
01290 int len;
01291
01292 len = eap_tls_status(sm, &data->ssl, buf, buflen, verbose);
01293 switch (data->phase2_type) {
01294 case EAP_TTLS_PHASE2_EAP:
01295 len += snprintf(buf + len, buflen - len,
01296 "EAP-TTLS Phase2 method=EAP-%s\n",
01297 data->phase2_method ? data->phase2_method->name
01298 : "?");
01299 break;
01300 case EAP_TTLS_PHASE2_MSCHAPV2:
01301 len += snprintf(buf + len, buflen - len,
01302 "EAP-TTLS Phase2 method=MSCHAPV2\n");
01303 break;
01304 case EAP_TTLS_PHASE2_MSCHAP:
01305 len += snprintf(buf + len, buflen - len,
01306 "EAP-TTLS Phase2 method=MSCHAP\n");
01307 break;
01308 case EAP_TTLS_PHASE2_PAP:
01309 len += snprintf(buf + len, buflen - len,
01310 "EAP-TTLS Phase2 method=PAP\n");
01311 break;
01312 case EAP_TTLS_PHASE2_CHAP:
01313 len += snprintf(buf + len, buflen - len,
01314 "EAP-TTLS Phase2 method=CHAP\n");
01315 break;
01316 }
01317
01318 return len;
01319 }
01320
01321
01322 static Boolean eap_ttls_isKeyAvailable(struct eap_sm *sm, void *priv)
01323 {
01324 struct eap_ttls_data *data = priv;
01325 return data->key_data != NULL && data->phase2_success;
01326 }
01327
01328
01329 static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len)
01330 {
01331 struct eap_ttls_data *data = priv;
01332 u8 *key;
01333
01334 if (data->key_data == NULL || !data->phase2_success)
01335 return NULL;
01336
01337 key = malloc(EAP_TLS_KEY_LEN);
01338 if (key == NULL)
01339 return NULL;
01340
01341 *len = EAP_TLS_KEY_LEN;
01342 memcpy(key, data->key_data, EAP_TLS_KEY_LEN);
01343
01344 return key;
01345 }
01346
01347
01348 const struct eap_method eap_method_ttls =
01349 {
01350 .method = EAP_TYPE_TTLS,
01351 .name = "TTLS",
01352 .init = eap_ttls_init,
01353 .deinit = eap_ttls_deinit,
01354 .process = eap_ttls_process,
01355 .isKeyAvailable = eap_ttls_isKeyAvailable,
01356 .getKey = eap_ttls_getKey,
01357 .get_status = eap_ttls_get_status,
01358 .has_reauth_data = eap_ttls_has_reauth_data,
01359 .deinit_for_reauth = eap_ttls_deinit_for_reauth,
01360 .init_for_reauth = eap_ttls_init_for_reauth,
01361 };
01362