⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eapfast.c

📁 linux 下通过802.1认证的安装包
💻 C
📖 第 1 页 / 共 2 页
字号:

  phase2 = (struct eapfast_phase2 *)mytls_vars->phase2data;

  if (packet[sizeof(struct eap_header)] & EAPTLS_LENGTH_INCL)
    {
      hello = (struct tls_server_hello *)&packet[sizeof(struct eap_header)+5];
    }
  else
    {
      hello = (struct tls_server_hello *)&packet[sizeof(struct eap_header)];
    }

  if (hello->content_type != TLS_HANDSHAKE_TYPE)
    {
      debug_printf(DEBUG_AUTHTYPES, "Packet is not a handshake packet, "
		   "ignoring.\n");
      debug_printf(DEBUG_AUTHTYPES, "Expected %d, got %d.\n", 
		   TLS_HANDSHAKE_TYPE, hello->content_type);
      return;
    }

  if (ntohs(hello->rec_version) < ntohs(0x0301))
    {
      debug_printf(DEBUG_NORMAL, "TLS version is not 1.0 or greater!\n");
      return;
    }

  if (hello->handshake_type != TLS_SERVER_HELLO)
    {
      debug_printf(DEBUG_AUTHTYPES, "Packet is not a server hello.  "
		   "Ignoring.\n");
      return;
    }

  if (ntohs(hello->shake_version) < ntohs(0x0301))
    {
      debug_printf(DEBUG_NORMAL, "Server Handshake version is not TLS 1.0 "
		   "or greater!\n");
      return;
    }

  if (eapfast_calc_master_secret(mytls_vars, hello->server_random) == 0)
    {
      // We don't need to parse TLS packets anymore.
      phase2->need_ms = FALSE;
    }
}

/***************************************************************
 *
 *  Process an EAP-FAST packet.
 *
 ***************************************************************/
void eapfast_process(eap_type_data *eapdata)
{
  uint8_t *tls_type = NULL, *resbuf = NULL;
  uint8_t fast_version;
  struct tls_vars *mytls_vars;
  struct eapfast_phase2 *phase2;
  uint8_t *aid = NULL;
  uint16_t aid_len, resout;
  int bufsiz;
  struct config_eap_fast *fastconf;

  debug_printf(DEBUG_AUTHTYPES, "(EAP-FAST) Processing.\n");
  if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
    return;

  if (!xsup_assert((eapdata->eap_data != NULL),
		   "eapdata->eap_data != NULL", FALSE))
    {
      eap_type_common_fail(eapdata);
      return;
    }

  if (!xsup_assert((eapdata->eap_conf_data != NULL),
		   "eapdata->eap_conf_data != NULL", FALSE))
    {
      eap_type_common_fail(eapdata);
      return;
    }

  fastconf = (struct config_eap_fast *)eapdata->eap_conf_data;
  mytls_vars = eapdata->eap_data;

  tls_type = &eapdata->eapReqData[sizeof(struct eap_header)];
  fast_version = (tls_type[0] & FAST_VERSION_MASK);

  eapfast_set_ver(eapdata, fast_version);

  debug_printf(DEBUG_AUTHTYPES, "Request EAP-FAST version is %d.\n", 
	       fast_version);

  tls_type[0] = (tls_type[0] & FAST_VERSION_MASK_OUT);

  if ((eapdata->eapReqData[sizeof(struct eap_header)] == EAPTLS_START)
      || (mytls_vars->handshake_done != TRUE))
    {
      debug_printf(DEBUG_AUTHTYPES, "(EAP-FAST) Processing packet.\n");

      if (eapdata->eapReqData[sizeof(struct eap_header)] == EAPTLS_START)
	{
	  if (eapfast_get_aid(&eapdata->eapReqData[sizeof(struct eap_header)+1],
			      &aid, &aid_len) == TRUE)
	    {
	      debug_printf(DEBUG_AUTHTYPES, "Got AID (%d byte(s)) : ", aid_len);
	      debug_hex_printf(DEBUG_AUTHTYPES, aid, aid_len);
	      
	      if (eapfast_check_pac(eapdata, aid, aid_len) == FALSE)
		{
		  debug_printf(DEBUG_AUTHTYPES, "Couldn't locate a PAC file. "
			       "We will provision one.\n");
		  // We don't have a PAC, are we allowed to provision one?
		  if (fastconf->provision != RES_YES)
		    {
		      debug_printf(DEBUG_NORMAL, "We are not configured to "
				   "allow provisioning!  Your authentication"
				   " cannot continue.\n");
		      eap_type_common_fail(eapdata);
		      return;
		    }

		  // Otherwise, determine how we can provision credentials.
		  // Right now, we only support unauthenticated mode.

		  // XXX -  Add authenticated mode!
		  if (tls_funcs_set_anon_dh_aes(mytls_vars) == -1)
		    {
		      eap_type_common_fail(eapdata);
		      return;
		    }

		  phase2 = (struct eapfast_phase2 *)mytls_vars->phase2data;
		  phase2->provisioning = TRUE;
		}
	      else
		{
		  phase2 = (struct eapfast_phase2 *)mytls_vars->phase2data;
		  phase2->provisioning = FALSE;

		  // We have a PAC, so configure TLS, and move on.
		  if (tls_funcs_set_hello_extension(mytls_vars, 
						    FAST_SESSION_TICKET,
						    phase2->pacs->pac_opaque,
						    phase2->pacs->pac_opaque_len) != 1)
		    {
		      debug_printf(DEBUG_NORMAL, "Error attempting to set the "
				   "session key data for EAP-FAST!\n");
		      eap_type_common_fail(eapdata);
		      return;
		    }
		  
		  // Let us know that we need to "hand parse" the Server 
		  // Hello packet to get the server random.
		  phase2->need_ms = TRUE;
		}
	    }
	  else
	    {
	      eap_type_common_fail(eapdata);
	      return;
	    }
	}

      FREE(aid);

      phase2 = (struct eapfast_phase2 *)mytls_vars->phase2data;

      if (phase2->need_ms == 1)
	{
	  eapfast_parse_tls(mytls_vars, eapdata->eapReqData);
	}

      eapdata->methodState = tls_funcs_process(eapdata->eap_data,
					       eapdata->eapReqData);

      if ((mytls_vars->handshake_done == TRUE) && (phase2->provisioning == TRUE))
	mytls_vars->send_ack = TRUE;
    }
  else
    {
      // Handle phase 2 stuff.
      resout = eap_type_common_get_eap_length(eapdata->eapReqData);

      if (tls_funcs_buffer(eapdata->eap_data, 
			   &eapdata->eapReqData[sizeof(struct eap_header)],
			   resout) != XENONE)
	{
	  debug_printf(DEBUG_NORMAL, "There was an error buffering data "
		       "fragments.  Discarding fragment.\n");
	  eapdata->ignore = FALSE;
	  return;
	}

      bufsiz = tls_funcs_decrypt_ready(eapdata->eap_data);
      debug_printf(DEBUG_AUTHTYPES, "Decrypt ready returned : %d\n", bufsiz);
      switch (bufsiz)
	{
	case 0:
	  // Nothing to do yet.
	  break;

	case -1:
	  // Got an error.  Discard the frame.
	  eap_type_common_fail(eapdata);
	  break;

	default:
	  resbuf = Malloc(bufsiz);
	  if (resbuf == NULL)
	    {
	      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory needed to "
			   "store decrypted data!\n");
	      eap_type_common_fail(eapdata);
	      break;
	    }

	  resout = bufsiz;

	  if (tls_funcs_decrypt(eapdata->eap_data, resbuf, &resout) != XENONE)
	    {
	      debug_printf(DEBUG_NORMAL, "Decryption failed!\n");
	      eap_type_common_fail(eapdata);
	      break;
	    }

	  debug_printf(DEBUG_AUTHTYPES, "Inner dump (%d) :\n", resout);
	  debug_hex_dump(DEBUG_AUTHTYPES, resbuf, resout);
	  eapfast_phase2_process(eapdata, resbuf, resout);

	  FREE(resbuf);
	  break;
	}
    }
}

/***************************************************************
 *
 *  Build a response to an EAP-FAST request.
 *
 ***************************************************************/
uint8_t *eapfast_buildResp(eap_type_data *eapdata)
{
  struct config_eap_fast *eapconf;
  uint8_t *res = NULL, *fastres = NULL;
  uint16_t res_size = 0, total_size = 0;
  struct eap_header *eaphdr;
  uint8_t reqId;
  struct tls_vars *mytls_vars = NULL;

  if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
    return NULL;

  if (!xsup_assert((eapdata->eap_data != NULL), "eapdata->eap_data != NULL",
		   FALSE))
    return NULL;

  if (!xsup_assert((eapdata->eap_conf_data != NULL),
		   "eapdata->eap_conf_data != NULL", FALSE))
    return NULL;

  eapconf = eapdata->eap_conf_data;
  mytls_vars = (struct tls_vars *)eapdata->eap_data;

  if ((mytls_vars->handshake_done == TRUE) &&
      (tls_funcs_data_pending(mytls_vars) == 0))
    {
      if ((mytls_vars->handshake_done == TRUE) && 
	  (tls_funcs_decrypt_ready(mytls_vars) == 0) &&
	  (mytls_vars->send_ack == FALSE))
	{
	  // Handle phase 2 stuff.
	  res = Malloc(1520);
	  if (res == NULL) 
	    {
	      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store "
			   "result.\n");
	      return NULL;
	    }
	  eapfast_phase2_buildResp(eapdata, res, &res_size);
	  
	  tls_funcs_encrypt(eapdata->eap_data, res, res_size);
	  
	  FREE(res);
	}
    }

  if ((eapconf->chunk_size == 0) || (eapconf->chunk_size > MAX_CHUNK))
    eapconf->chunk_size = MAX_CHUNK;

  if (tls_funcs_get_packet(eapdata->eap_data, eapconf->chunk_size, &res,
			   &res_size) != XENONE)
    {
      return NULL;
    }

  if (res == NULL) return NULL;

  mytls_vars->send_ack = FALSE;

  eaphdr = (struct eap_header *)eapdata->eapReqData;
  reqId = eaphdr->eap_identifier;

  fastres = Malloc(res_size + sizeof(struct eap_header));
  if (fastres == NULL) return NULL;

  eaphdr = (struct eap_header *)fastres;

  eaphdr->eap_code = EAP_RESPONSE_PKT;
  eaphdr->eap_identifier = reqId;
  total_size = res_size + sizeof(struct eap_header);
  eaphdr->eap_length = htons(total_size);
  eaphdr->eap_type = EAP_TYPE_FAST;

  memcpy(&fastres[sizeof(struct eap_header)], res, res_size);

  fastres[sizeof(struct eap_header)] |= eapfast_get_ver(eapdata);

  FREE(res);

  return fastres;
}

/***************************************************************
 *
 *  Determine if we have keying material available.
 *
 ***************************************************************/
uint8_t eapfast_isKeyAvailable(eap_type_data *eapdata)
{
  struct tls_vars *mytls_vars;
  uint8_t *simckj;

  if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
    return FALSE;

  if (!xsup_assert((eapdata->eap_data != NULL), "eapdata->eap_data != NULL",
		   FALSE))
    return FALSE;

  mytls_vars = (struct tls_vars *)eapdata->eap_data;

  if (mytls_vars->handshake_done == FALSE) return FALSE;

  if (mytls_vars->keyblock != NULL) 
    {
      FREE(mytls_vars->keyblock);
    }

  simckj = eapfast_phase2_get_simckj(eapdata);

  if (simckj == NULL) return FALSE;

  mytls_vars->keyblock = eapfast_phase2_t_prf(simckj, 40, FAST_SESSION_KEY,
					      NULL, 0, 64);

  if (mytls_vars->keyblock != NULL) return TRUE;

  return FALSE;
}

/***************************************************************
 *
 *  If there is keying material available, then return a key.
 *
 ***************************************************************/
uint8_t *eapfast_getKey(eap_type_data *eapdata)
{
  struct tls_vars *mytls_vars;
  uint8_t *retkey;

  if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
    return NULL;

  if (!xsup_assert((eapdata->eap_data != NULL), "eapdata->eap_data != NULL",
		   FALSE))
    return NULL;

  mytls_vars = (struct tls_vars *)eapdata->eap_data;

  retkey = Malloc(64);
  if (retkey == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to return key "
		   "data!\n");
      return NULL;
    }

  memcpy(retkey, mytls_vars->keyblock, 64);

  return retkey;
}

/***************************************************************
 *
 *  Clean up any memory that we have used.
 *
 ***************************************************************/
void eapfast_deinit(eap_type_data *eapdata)
{
  struct tls_vars *mytls_vars;

  if (!xsup_assert((eapdata != NULL), "eapdata != NULL", FALSE))
    return;

  if (!xsup_assert((eapdata->eap_data != NULL),
		   "eapdata->eap_data != NULL", FALSE))
    return;

  mytls_vars = (struct tls_vars *)eapdata->eap_data;

  eapfast_phase2_deinit(eapdata);
  tls_funcs_deinit(mytls_vars);

  FREE(mytls_vars);
  FREE(eapdata->eap_data);

  debug_printf(DEBUG_DEINIT, "(EAP-FAST) Cleaned up.\n");
}

#endif // EAP_FAST

⌨️ 快捷键说明

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