📄 ttlsphase2.c
字号:
build_avp(EAP_MESSAGE, 0, MANDITORY_FLAG, (uint8_t *) eapdata, eapsize, (uint8_t *) out_data, out_size); debug_printf(DEBUG_INT, "EAP Identity AVP dump (%d) : \n", (*out_size)); debug_hex_dump(DEBUG_INT, out_data, (*out_size)); return; } // Skip past the AVP data. // XXX Clean this up, we should verify that it is really the EAP AVP! indata+=8; insize -= 8; if (eap_create_active_method(&ttlsdata->phase2_eap_data, identity, thisint->tempPwd, thisint->intName) != 0) { debug_printf(DEBUG_NORMAL, "Couldn't build active method! Phase 2 " "authentication will not happen!\n"); return; } // We need to create a config_eap_method struct to pass in. eapmethod.method_num = EAP_TYPE_MD5; eapmethod.method_data = (void *)md5data; eapmethod.next = NULL; eap_request_auth(ttlsdata->phase2_eap_data, &eapmethod, (char *) indata, insize, (char *) eapdata, &eapsize); debug_printf(DEBUG_INT, "Response data (%d) :\n", eapsize); debug_hex_dump(DEBUG_INT, eapdata, eapsize); build_avp(EAP_MESSAGE, 0, MANDITORY_FLAG, (uint8_t *) eapdata, eapsize, (uint8_t *) out_data, out_size); debug_printf(DEBUG_INT, "TTLS Phase 2 EAP dump (%d) : \n", (*out_size)); debug_hex_dump(DEBUG_INT, out_data, (*out_size));}/************************************************************** * * Do an MS-CHAPv2 authentication. indata, and insize are not used * in this function. (As this is only a one-way conversation.) * **************************************************************/void ttls_do_mschapv2(struct generic_eap_data *thisint, char *indata, int insize, char *out_data, int *out_size){ uint8_t mschap_challenge[16], mschap_answer[50]; uint8_t mschap_result[24]; char *username = NULL, *password = NULL, *challenge = NULL; int avp_offset, avp_out_size, username_size, id; struct config_mschapv2 *phase2data; struct config_eap_ttls *outerdata; struct config_ttls_phase2 *userdata;#ifdef HAVE_TNC struct config_network *net;#endif if (!xsup_assert((out_size != NULL), "out_size != NULL", FALSE)) return; *out_size =0; if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE)) return; if (!xsup_assert((thisint->eap_conf_data != NULL), "thisint->eap_conf_data != NULL", FALSE)) return; outerdata = (struct config_eap_ttls *)thisint->eap_conf_data; if (!outerdata->phase2) { debug_printf(DEBUG_NORMAL, "Invalid phase 2 data.\n"); return; } userdata = (struct config_ttls_phase2 *)outerdata->phase2; while ((userdata != NULL) && (userdata->phase2_type != TTLS_PHASE2_MSCHAPV2)) { userdata = userdata->next; } if (!userdata->phase2_data) { debug_printf(DEBUG_NORMAL, "Invalid phase 2 config in MS-CHAPv2!\n"); return; } phase2data = (struct config_mschapv2 *)userdata->phase2_data; // Check that we have a password. if ((phase2data->password == NULL) && (thisint->tempPwd == NULL)) { debug_printf(DEBUG_AUTHTYPES, "Phase 2 doesn't appear to have a password. Requesting one!\n"); thisint->need_password = 1; thisint->eaptype = strdup("EAP-TTLS Phase 2 (MS-CHAPv2)"); thisint->eapchallenge = NULL; *out_size = 0; return; } if ((phase2data->password == NULL) && (thisint->tempPwd != NULL)) { phase2data->password = thisint->tempPwd; thisint->tempPwd = NULL; } if (phase2data->username == NULL) { username = thisint->identity; } else { username = phase2data->username; } if (username == NULL) { debug_printf(DEBUG_NORMAL, "Invalid phase 2 username. (You may need to " "populate the phase 2 username field.)\n"); return; } username_size = strlen(username); // Send the Username AVP build_avp(USER_NAME_AVP, 0, MANDITORY_FLAG, (uint8_t *) username, username_size, (uint8_t *) out_data, &avp_out_size); avp_offset = avp_out_size; challenge = implicit_challenge(thisint); if (challenge == NULL) { debug_printf(DEBUG_NORMAL, "Invalid implicit challenge in MS-CHAPv2!\n"); return; } memcpy(&mschap_challenge, challenge, 16); id = challenge[16]; // Send the MS-CHAP AVP build_avp(MS_CHAP_CHALLENGE, MS_VENDOR_ATTR, (MANDITORY_FLAG | VENDOR_FLAG), (uint8_t *) &mschap_challenge, 16, (uint8_t *) &out_data[avp_offset], &avp_out_size); avp_offset+=avp_out_size; bzero(&mschap_answer, 50); // Clear it out. memcpy(&mschap_answer, &mschap_challenge, 16); // The first 24 bytes should be left as 0s. password = phase2data->password; // Get our password. GenerateNTResponse((char *)&mschap_challenge, (char *)&mschap_challenge, username, password, (char *)&mschap_result, 0); mschap_answer[0] = id; mschap_answer[1] = 0; memcpy(&mschap_answer[2], &mschap_challenge, 16); memcpy(&mschap_answer[26], &mschap_result, 24); build_avp(MS_CHAP2_RESPONSE, MS_VENDOR_ATTR, (MANDITORY_FLAG | VENDOR_FLAG), (uint8_t *) &mschap_answer, 50, (uint8_t *) &out_data[avp_offset], &avp_out_size); avp_offset+=avp_out_size; *out_size = avp_offset;#ifdef HAVE_TNC net = config_get_network_config(); if (TEST_FLAG(net->flags, CONFIG_NET_USE_TNC)) { ttls_tnc_start((uint8_t *)out_data, (size_t*)out_size); }#endif}/********************************************************************* * * Create a phase 2 MS-CHAP response. For phase 2 MS-CHAP, we get 8 bytes * implicit challenge, and 1 byte for ID. indata, and insize are not used * in this function, since it is a one-way conversation. * *********************************************************************/void ttls_do_mschap(struct generic_eap_data *thisint, char *indata, int insize, char *out_data, int *out_size){ uint8_t mschap_challenge[8], mschap_answer[50]; uint8_t mschap_result[24]; char *username = NULL, *password = NULL, *challenge = NULL; int avp_offset, avp_out_size, username_size, id; struct config_ttls_phase2 *userdata; struct config_eap_ttls *outerdata; struct config_mschap *phase2data; if (!xsup_assert((out_size != NULL), "out_size != NULL", FALSE)) return; *out_size = 0; if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE)) return; if (!xsup_assert((thisint->eap_conf_data != NULL), "thisint->eap_conf_data != NULL", FALSE)) return; outerdata = (struct config_eap_ttls *)thisint->eap_conf_data; if (!outerdata) { debug_printf(DEBUG_NORMAL, "Invalid configuration data in MS-CHAP!\n"); return; } userdata = (struct config_ttls_phase2 *)outerdata->phase2; while ((userdata != NULL) && (userdata->phase2_type != TTLS_PHASE2_MSCHAP)) { userdata = userdata->next; } phase2data = (struct config_mschap *)userdata->phase2_data; // Check that we have a password. if ((phase2data->password == NULL) && (thisint->tempPwd == NULL)) { debug_printf(DEBUG_AUTHTYPES, "Phase 2 doesn't appear to have a password. Requesting one!\n"); thisint->need_password = 1; thisint->eaptype = strdup("EAP-TTLS Phase 2 (MS-CHAP)"); thisint->eapchallenge = NULL; *out_size = 0; return; } if ((phase2data->password == NULL) && (thisint->tempPwd != NULL)) { phase2data->password = thisint->tempPwd; thisint->tempPwd = NULL; } if (phase2data->username == NULL) { username = thisint->identity; } else { username = phase2data->username; } if (username == NULL) { debug_printf(DEBUG_NORMAL, "Invalid phase 2 username! (You may need to " "populate the phase 2 username field.)\n"); return; } username_size = strlen(username); // Send the Username AVP build_avp(USER_NAME_AVP, 0, MANDITORY_FLAG, (uint8_t *) username, username_size, (uint8_t *) out_data, &avp_out_size); avp_offset = avp_out_size; challenge = implicit_challenge(thisint); if (challenge == NULL) { debug_printf(DEBUG_NORMAL, "Invalid implicit challenge!\n"); return; } memcpy((char *)&mschap_challenge[0], challenge, 8); id = challenge[8]; // Send the MS-CHAP AVP build_avp(MS_CHAP_CHALLENGE, MS_VENDOR_ATTR, (MANDITORY_FLAG | VENDOR_FLAG), (uint8_t *) &mschap_challenge, 8, (uint8_t *) &out_data[avp_offset], &avp_out_size); avp_offset+=avp_out_size; bzero((char *)&mschap_answer[0], 49); // Clear it out. password = phase2data->password; // Get our password. NtChallengeResponse((char *)&mschap_challenge, password, (char *)&mschap_result, 0); mschap_answer[0] = id; mschap_answer[1] = 1; // Use NT Style Passwords. memcpy((char *)&mschap_answer[26], (char *)&mschap_result, 24); build_avp(MS_CHAP_RESPONSE, MS_VENDOR_ATTR, (MANDITORY_FLAG | VENDOR_FLAG), (uint8_t *) &mschap_answer, 50, (uint8_t *) &out_data[avp_offset], &avp_out_size); avp_offset+=avp_out_size; *out_size = avp_offset;#ifdef HAVE_TNC ttls_tnc_start((uint8_t *)out_data, (size_t*)out_size);#endif} // For phase 2 CHAP, we need to get an implicit_challenge from the phase 1,// and use the first 16 bytes for challenge, and the 17th byte as the ID.// Then, to find the CHAP password hash, we find MD5(id + password + // challenge). Then, we need to send 3 AVPs back to the authenticator.// The username, challenge, and password AVPs. Where the challenge is the// 16 bytes from the implicit challenge. //// indata and insize are not used because this is a one way conversation.void ttls_do_chap(struct generic_eap_data *thisint, char *indata, int insize, char *out_data, int *out_size){ uint8_t *challenge = NULL, *tohash = NULL; uint8_t *user_passwd = NULL; uint8_t chap_challenge[18], chap_hash[17]; uint8_t session_id; int username_size, avp_out_size; int avp_offset, md5_length, hashlen; EVP_MD_CTX *ctx=NULL; char *username = NULL; struct config_ttls_phase2 *userdata; struct config_eap_ttls *outerdata; struct config_chap *phase2data; if (!xsup_assert((out_size != NULL), "out_size != NULL", FALSE)) return; *out_size = 0; if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE)) return; if (!xsup_assert((thisint->eap_conf_data != NULL), "thisint->eap_conf_data != NULL", FALSE)) return; outerdata = (struct config_eap_ttls *)thisint->eap_conf_data; if (!outerdata->phase2) { debug_printf(DEBUG_NORMAL, "Invalid phase 2 data in ttls_do_chap()!\n"); return; } userdata = (struct config_ttls_phase2 *)outerdata->phase2; while ((userdata != NULL) && (userdata->phase2_type != TTLS_PHASE2_CHAP)) { userdata = userdata->next; } phase2data = (struct config_chap *)userdata->phase2_data; // Check that we have a password. if ((phase2data->password == NULL) && (thisint->tempPwd == NULL)) { debug_printf(DEBUG_AUTHTYPES, "Phase 2 doesn't appear to have a password. Requesting one!\n"); thisint->need_password = 1; thisint->eaptype = strdup("EAP-TTLS Phase 2 (CHAP)"); thisint->eapchallenge = NULL; *out_size = 0; return; } if ((phase2data->password == NULL) && (thisint->tempPwd != NULL)) { phase2data->password = thisint->tempPwd; thisint->tempPwd = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -