📄 ttlsphase2.c
字号:
} 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); 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; // Get the implicit challenge. challenge = (uint8_t *) implicit_challenge(thisint); if (challenge == NULL) { debug_printf(DEBUG_NORMAL, "Invalid implicit challenge in ttls_do_chap()!\n"); return; } memcpy(&chap_challenge, challenge, 16); session_id = challenge[16]; // Build the password hash. ctx = (EVP_MD_CTX *)malloc(sizeof(EVP_MD_CTX)); if (ctx == NULL) { debug_printf(DEBUG_NORMAL, "Error with malloc of ctx in ttls_do_chap().\n"); return; } user_passwd = (uint8_t *) phase2data->password; tohash = (uint8_t *)malloc(1+16+strlen((char *) user_passwd)); if (tohash == NULL) { debug_printf(DEBUG_NORMAL, "Error with malloc of \"tohash\" in ttls_do_chap().\n"); return; } tohash[0] = session_id; memcpy(&tohash[1], user_passwd, strlen((char *) user_passwd)); memcpy(&tohash[1+strlen((char *) user_passwd)], &chap_challenge, 16); hashlen = 1+strlen((char *) user_passwd)+16; EVP_DigestInit(ctx, EVP_md5()); EVP_DigestUpdate(ctx, tohash, hashlen); EVP_DigestFinal(ctx, (uint8_t *)&chap_hash[1], (u_int *)&md5_length); if (md5_length != 16) // We didn't get back a valid hash! { debug_printf(DEBUG_NORMAL, "CHAP (MD5) hash length was not 16!\n"); } chap_hash[0]=session_id; build_avp(CHAP_PASSWORD_AVP, 0, MANDITORY_FLAG, chap_hash, 17, (uint8_t *) &out_data[avp_offset], &avp_out_size); avp_offset += avp_out_size; build_avp(CHAP_CHALLENGE_AVP, 0, MANDITORY_FLAG, (uint8_t *) &chap_challenge, 16, (uint8_t *) &out_data[avp_offset], &avp_out_size); if (tohash != NULL) { free(tohash); tohash = NULL; } if (ctx != NULL) { free(ctx); ctx = NULL; } *out_size = avp_offset+avp_out_size;#ifdef HAVE_TNC ttls_tnc_start((uint8_t *)out_data, (size_t*)out_size);#endif}void ttls_do_bogus(struct generic_eap_data *thisint, char *indata, int insize, char *out_data, int *out_size){ debug_printf(DEBUG_NORMAL, "Attempting to call an undefined Phase 2!\n");}/************************************************************************ * * Complete a PAP authentication. indata, and insize are not used because * it is a one-way conversation. * ************************************************************************/void ttls_do_pap(struct generic_eap_data *thisint, char *indata, int insize, char *out_data, int *out_size){ char *tempbuf, *username; int passwd_size, avp_out_size, avp_offset; struct config_ttls_phase2 *userdata; struct config_eap_ttls *outerdata; struct config_pap *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_pap()!\n"); return; } userdata = (struct config_ttls_phase2 *)outerdata->phase2; while ((userdata != NULL) && (userdata->phase2_type != TTLS_PHASE2_PAP)) { userdata =userdata->next; } phase2data = (struct config_pap *)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 (PAP)"); 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; } avp_offset = 0; build_avp(USER_NAME_AVP, 0, MANDITORY_FLAG, (uint8_t *) username, strlen(username), (uint8_t *) out_data, &avp_out_size); avp_offset += avp_out_size; // We have the username AVP loaded, so it's time to build the password AVP. passwd_size = (strlen(phase2data->password) + (16-(strlen(phase2data->password) % 16))); tempbuf = (char *)malloc(passwd_size); if (tempbuf == NULL) { debug_printf(DEBUG_NORMAL, "Error with malloc of tempbuf in ttls_do_pap().\n"); return; } bzero(tempbuf, passwd_size); memcpy(tempbuf, phase2data->password, strlen(phase2data->password)); build_avp(USER_PASSWORD_AVP, 0, MANDITORY_FLAG, (uint8_t *) tempbuf, passwd_size, (uint8_t *) &out_data[avp_offset], &avp_out_size); *out_size = avp_offset + avp_out_size; if (tempbuf != NULL) { free(tempbuf); tempbuf = NULL; } debug_printf(DEBUG_AUTHTYPES, "Returning from do_pap :\n"); debug_hex_dump(DEBUG_AUTHTYPES, (uint8_t *) out_data, *out_size);#ifdef HAVE_TNC ttls_tnc_start((uint8_t *)out_data, (size_t*)out_size);#endif}int ttls_do_phase2(struct generic_eap_data *thisint, char *in, int in_size, char *out, int *out_size){ int toencsize, i, decrsize = 0; char *toencout; struct config_eap_ttls *userdata; struct config_ttls_phase2 *phase2data; char decr_data[1550]; if (!xsup_assert((out_size != NULL), "out_size != NULL", FALSE)) return XEMALLOC; *out_size = 0; if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE)) return XEMALLOC; if (!xsup_assert((thisint->eap_conf_data != NULL), "thisint->eap_conf_data != NULL", FALSE)) return XEMALLOC; debug_printf(DEBUG_AUTHTYPES, "Encrypted Inner (%d) : \n", in_size); debug_hex_dump(DEBUG_AUTHTYPES, (uint8_t *) in, in_size); userdata = (struct config_eap_ttls *)thisint->eap_conf_data; if (!userdata->phase2) { debug_printf(DEBUG_NORMAL, "Invalid userdata in ttls_do_phase2()!\n"); return XEGENERROR; } phase2data = (struct config_ttls_phase2 *)userdata->phase2; toencout = (char *)malloc(1550); if (toencout == NULL) { debug_printf(DEBUG_NORMAL, "Couldn't allocate memory needed for encryption!\n"); return XEMALLOC; } // This is a hack. :-( It is needed for TTLS-MS-CHAPv2. // XXX Fix better! // A better fix would be to figure out how to have OpenSSL tell us how much // of the packet it processed, so we can move our offset pointer to the end // of the data that has been used. This would result in a NULL packet // being passed in for the first part, and the encrypted packet being // passed in the second part. This would allow us to process the packets // "correctly" inside of the specific phase 2 handler. if ((in_size > 0) && (in[0] != 0x14)) { // We have something to decrypt! tls_crypt_decrypt(thisint, (uint8_t *) in, in_size, (uint8_t *) decr_data, &decrsize); debug_printf(DEBUG_AUTHTYPES, "Decrypted Inner (%d) : \n", in_size); debug_hex_dump(DEBUG_AUTHTYPES, (uint8_t *) decr_data, decrsize);#ifdef HAVE_TNC // See if we have any Integrity Messages from the IMV to // pass to our IMC toencsize = 0; ttls_tnc_process((uint8_t*)decr_data, decrsize, (uint8_t*)toencout, (size_t*)&toencsize); if (toencsize) goto encrypt;#endif if ((decr_data[0] == 0x00) && (userdata->phase2_type != TTLS_PHASE2_EAP_MD5)) { debug_printf(DEBUG_AUTHTYPES, "(Hack) Acking for second inner phase " "packet!\n"); out[0] = 0x00; // ACK *out_size = 1; return XENONE; } } toencsize = 1550; // We need to see what phase 2 method we should use. i = 0; while ((phase2types[i].phase2type != -1) && (userdata->phase2_type != phase2types[i].phase2type)) { i++; } if (phase2types[i].phase2type > 0) { debug_printf(DEBUG_AUTHTYPES, "Doing Phase 2 %s!\n", phase2types[i].phase2name); (*phase2types[i].phase2handler)(thisint, decr_data, decrsize, toencout, &toencsize); } else { debug_printf(DEBUG_NORMAL, "ERROR! : No phase 2 TTLS method was " "defined!\n"); toencsize = 0; } // ifdef this so that it doesn't cause compiler warnings when building // without TNC.#ifdef HAVE_TNC encrypt:#endif if (toencsize == 0) { *out_size = 0; free(toencout); return XENONE; } tls_crypt_encrypt_nolen(thisint, (uint8_t *) toencout, toencsize, (uint8_t *) out, out_size); free(toencout); debug_printf(DEBUG_AUTHTYPES, "Returning from (TTLS) do_phase2 : \n"); debug_hex_dump(DEBUG_AUTHTYPES, (uint8_t *) out, *out_size); return XENONE;}void ttls_phase2_failed(struct generic_eap_data *thisint){ struct config_eap_ttls *userdata; if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE)) return; if (!xsup_assert((thisint->eap_conf_data != NULL), "thisint->eap_conf_data != NULL", FALSE)) return; userdata = (struct config_eap_ttls *)thisint->eap_conf_data; if (!userdata->phase2) { debug_printf(DEBUG_NORMAL, "Invalid userdata in ttls_phase2_failed()!\n"); return; } if (userdata->phase2_type == TTLS_PHASE2_EAP_MD5) { if (eap_clear_active_method(userdata->phase2_eap_data) != XENONE) { debug_printf(DEBUG_NORMAL, "Couldn't clean up EAP-MD5 from TTLS " "phase 2.\n"); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -