ttlsphase2.c

来自「访问基于802.1x认证方式的网络」· C语言 代码 · 共 626 行 · 第 1/2 页

C
626
字号
  phase2data = (struct config_mschap *)userdata->phase2_data;  if (phase2data->username == NULL)    {      username = thisint->identity;    } else {      username = phase2data->username;    }  username_size = strlen(username);  // Send the Username AVP  build_avp(USER_NAME_AVP, 0, MANDITORY_FLAG, username, username_size, out_data, &avp_out_size);  avp_offset = avp_out_size;  challenge = implicit_challenge(thisint);  memcpy((char *)&mschap_challenge[0], challenge, 8);  id = challenge[9];  // Send the MS-CHAP AVP  build_avp(MS_CHAP_CHALLENGE, MS_VENDOR_ATTR, (MANDITORY_FLAG | VENDOR_FLAG), (char *)&mschap_challenge, 8, &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);  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), (char *)&mschap_answer, 50, &out_data[avp_offset], &avp_out_size);  avp_offset+=avp_out_size;  *out_size = avp_offset;} // 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.  void ttls_do_chap(struct generic_eap_data *thisint, char *out_data, int *out_size){  u_char *challenge = NULL, *tohash = NULL;  u_char *user_passwd = NULL;  u_char 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;  outerdata = (struct config_eap_ttls *)thisint->eap_conf_data;  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->username == NULL)    {      username = thisint->identity;    } else {      username = phase2data->username;    }  username_size = strlen(username);  build_avp(USER_NAME_AVP, 0, MANDITORY_FLAG, username, username_size, out_data, &avp_out_size);  avp_offset = avp_out_size;  // Get the implicit challenge.  challenge = implicit_challenge(thisint);  assert(challenge != NULL);  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 = phase2data->password;  tohash = (char *)malloc(1+16+strlen(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(user_passwd));  memcpy(&tohash[1+strlen(user_passwd)], &chap_challenge, 16);  hashlen = 1+strlen(user_passwd)+16;  EVP_DigestInit(ctx, EVP_md5());  EVP_DigestUpdate(ctx, tohash, hashlen);  EVP_DigestFinal(ctx, (char *)&chap_hash[1], (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, &out_data[avp_offset], &avp_out_size);  avp_offset += avp_out_size;  build_avp(CHAP_CHALLENGE_AVP, 0, MANDITORY_FLAG, (char *)&chap_challenge, 16, &out_data[avp_offset], &avp_out_size);  if (tohash != NULL)    {      free(tohash);      tohash = NULL;    }  if (ctx != NULL)    {      free(ctx);      ctx = NULL;    }  //  if (user_passwd != NULL) free(user_passwd);  *out_size = avp_offset+avp_out_size;}void ttls_do_bogus(struct generic_eap_data *thisint, char *out_data, int *out_size){  debug_printf(DEBUG_NORMAL, "Attempting to call an undefined Phase 2!\n");  exit(255);}void ttls_do_pap(struct generic_eap_data *thisint, 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;  outerdata = (struct config_eap_ttls *)thisint->eap_conf_data;  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->username == NULL)    {      username = thisint->identity;    } else {      username = phase2data->username;    }  debug_printf(DEBUG_AUTHTYPES, "Phase 2 Username : %s\n",username);  avp_offset = 0;  build_avp(USER_NAME_AVP, 0, MANDITORY_FLAG, username, 	    strlen(username), out_data, &avp_out_size);  avp_offset += avp_out_size;  if (phase2data->password == NULL)    {      // We probably have a tempPassword.      if (thisint->tempPwd == NULL)	{	  debug_printf(DEBUG_NORMAL, "There is no valid password!!!\n");	  return;	}      // So, copy it to phase2data.      phase2data->password = (char *)malloc(strlen(thisint->tempPwd)+1);      if (phase2data->password == NULL)	{	  debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for phase2data->password!\n");	  return;	}      bzero(phase2data->password, strlen(thisint->tempPwd)+1);      strcpy(phase2data->password, thisint->tempPwd);      // We are done with tempPwd, so clear it.      free(thisint->tempPwd);      thisint->tempPwd = NULL;    }  //  debug_printf(DEBUG_AUTHTYPES, "Phase 2 Password : %s\n",phase2data->password);  // 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, tempbuf, passwd_size, &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, out_data, *out_size);}// We don't do anything with the "in" stuff for now..void ttls_do_phase2(struct generic_eap_data *thisint, char *in, int in_size, char *out, int *out_size){  int toencsize, i;  char *toencout;  struct config_eap_ttls *userdata;  struct config_ttls_phase2 *phase2data;  userdata = (struct config_eap_ttls *)thisint->eap_conf_data;  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;    }  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! (Auto)\n", phase2types[i].phase2name);      (*phase2types[i].phase2handler)(thisint, toencout, &toencsize);    } else {      debug_printf(DEBUG_NORMAL, "ERROR!  : No phase 2 TTLS method was defined!\n");      toencsize = 0;    }  if (toencsize == 0)    {      *out_size = 0;      free(toencout);      return;    }  tls_crypt_encrypt_nolen(thisint, toencout, toencsize, out, out_size);  free(toencout);  debug_printf(DEBUG_AUTHTYPES, "Returning from (TTLS) do_phase2 : \n");  debug_hex_dump(DEBUG_AUTHTYPES, out, *out_size);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?