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

📄 eapmschapv2.c

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

  myvars->NtResponse = (uint8_t *)Malloc(24);
  if (myvars->NtResponse == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for the "
		   "NtResponse!\n");
	  ipc_events_malloc_failed(NULL);

      return EAP_FAIL;
    }

  eapmschapv2_strip_backslash(eapdata->ident, &username);

  if (eapconf->nthash)
    {
      GenerateNTResponse((char *)myvars->AuthenticatorChallenge,
			 (char *)myvars->PeerChallenge, username, 
			 eapconf->nthash, (char *)myvars->NtResponse, 1);
    } else {
    GenerateNTResponse((char *)myvars->AuthenticatorChallenge,
		       (char *)myvars->PeerChallenge, username,
		       myvars->password, (char *)myvars->NtResponse, 0);
    }

  debug_printf(DEBUG_AUTHTYPES, "myvars->NtResponse = ");
  debug_hex_printf(DEBUG_AUTHTYPES, (uint8_t *) myvars->NtResponse, 24);

  // Everything is good, so continue.
  return MAY_CONT;
}

/******************************************************************
 *
 *  Process a success message.  It should return one of the eapMethod state
 *  values.
 *
 ******************************************************************/
uint8_t eapmschapv2_success(eap_type_data *eapdata)
{
  struct mschapv2_success_request *success;
  int respOk = 0;
  struct config_eap_mschapv2 *eapconf;
  struct mschapv2_vars *myvars;
  uint8_t NtHash[16], NtHashHash[16], MasterKey[16];
  uint8_t mppeSend[16], mppeRecv[16];
  uint16_t eaplen=0;

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

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

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

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

  eapconf = (struct config_eap_mschapv2 *)eapdata->eap_conf_data;

  myvars = (struct mschapv2_vars *)eapdata->eap_data;

  success = (struct mschapv2_success_request *)&eapdata->eapReqData[sizeof(struct eap_header)];  

  eaplen = eap_type_common_get_eap_length(eapdata->eapReqData);

  // Add a NULL to the end, in case we didn't get one.
  eapdata->eapReqData[eaplen+1] = 0x00;

  if (eapconf->nthash)
    {
      CheckAuthenticatorResponse(eapconf->nthash,
				 (char *)myvars->NtResponse, 
				 (char *)myvars->PeerChallenge,
				 (char *)myvars->AuthenticatorChallenge,
				 eapdata->ident, 
				 (char *)&success->MsgField[2], &respOk, 1);
    } else {
      CheckAuthenticatorResponse(myvars->password,
				 (char *)myvars->NtResponse, 
				 (char *)myvars->PeerChallenge,
				 (char *)myvars->AuthenticatorChallenge,
				 eapdata->ident, 
				 (char *)&success->MsgField[2], &respOk, 0);
    }

  if (respOk != 1)
    {
      debug_printf(DEBUG_NORMAL, "Authenticator response invalid!\n");
      return EAP_FAIL;
    }

  // Otherwise, generate our keying material.
  // We were successful, so generate keying material.
  if (!eapconf->nthash)
    {
      NtPasswordHash(myvars->password, (char *)&NtHash);
    }
  else
    {
      process_hex(myvars->password, strlen(myvars->password), 
		  (char *)NtHash);
    }

  HashNtPasswordHash((char *)&NtHash, (char *)&NtHashHash);
  GetMasterKey((char *)&NtHashHash, (char *)myvars->NtResponse, 
	       (char *)&MasterKey);

  // Now, get the send key.
  GetAsymetricStartKey((char *)&MasterKey, (char *)&mppeSend, 16, TRUE, FALSE);

  // And the recv key.
  GetAsymetricStartKey((char *)&MasterKey, (char *)&mppeRecv, 16, FALSE, 
		       FALSE);

  // Finally, populate our myvars->keyingMaterial.
  FREE(myvars->keyingMaterial);

  myvars->keyingMaterial = (uint8_t *)Malloc(64);  // 32 bytes each.
  if (myvars->keyingMaterial == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store keying"
		   " material!\n");
	  ipc_events_malloc_failed(NULL);

      return EAP_FAIL;
    }

  memcpy(&myvars->keyingMaterial[32], &mppeRecv, 16);

  memcpy(myvars->keyingMaterial, &mppeSend, 16);

  eapdata->decision = COND_SUCC;
  eapdata->eapKeyAvailable = TRUE;
  eapdata->altAccept = TRUE;

  return MAY_CONT;
}

/******************************************************************
 *
 *  Parse an MS-CHAPv2 error string in to the numeric failure value, 
 *  and the text error value.
 *
 ******************************************************************/
uint8_t eapmschapv2_parse_error_string(char *err_string, uint16_t *errcode, 
				       char **errtext)
{
  /*
   The Message field format is:

     "E=eeeeeeeeee R=r C=cccccccccccccccccccccccccccccccc V=vvvvvvvvvv M=<msg>"

  */
  uint16_t offset = 0;
  char *strdata = NULL;

  if ((err_string[0] != 'E') || (err_string[1] != '='))
    {
      debug_printf(DEBUG_NORMAL, "Message string contains invalid starting "
		   "characters.  It should start with 'E=', but actually "
		   "started with '%c%c'.\n", err_string[0], err_string[1]);
      return XEGENERROR;
    }

  strdata = err_string + 2;  // Start beyond the E= portion.

  while ((offset < strlen(err_string)) && (strdata[offset] != ' '))
    {
      offset++;
    }

  if (strdata[offset] == ' ')
    {
      strdata[offset] = 0x00;  // Set a NULL so that atoi can handle it.
      *errcode = atoi(strdata);
      
      debug_printf(DEBUG_AUTHTYPES, "Numeric error code is %d\n", *errcode);
    }

  offset++;

  if ((strdata[offset] != 'R') || (strdata[offset+1] != '='))
    {
      debug_printf(DEBUG_NORMAL, "Message contains invalid characters for "
		   "second element.  It should be 'R=', but actually was "
		   "'%c%c'.\n", strdata[offset], strdata[offset+1]);
      return XEGENERROR;
    }

  offset+=4;  // This should get us to the C= section.

  if ((strdata[offset] != 'C') || (strdata[offset+1] != '='))
    {
      debug_printf(DEBUG_NORMAL, "Message contains invalid characters for "
		   "third element.  It should be 'C=', but actually was "
		   "'%c%c'.\n", strdata[offset], strdata[offset+1]);
      return XEGENERROR;
    }

  offset+=35;  // This should get us to the V= section.

  if ((strdata[offset] != 'V') || (strdata[offset+1] != '='))
    {
      debug_printf(DEBUG_NORMAL, "Message contains invalid characters for "
		   "fourth element.  It should be 'V=', but actually was "
		   "'%c%c'.\n", strdata[offset], strdata[offset+1]);
      return XEGENERROR;
    }

  offset+=2;

  strdata += offset;
  offset = 0;

  while ((offset < strlen(strdata)) && (strdata[offset] != ' '))
    {
      offset++;
    }

  if (strdata[offset] != ' ')
    {
      debug_printf(DEBUG_AUTHTYPES, "Message didn't appear to be valid following"
		   " the password change section.  (Section 'V=')\n");

      // Some authentication servers don't send a properly formatted failure
      // response.  They may omit the text version of the error code.
      return XENONE;
    }

  // Otherwise, set this to a null character.
  strdata[offset] = 0x00;

  if (atoi(strdata) != MSCHAPV2_PASSWORD_CHANGE_VER)
    {
      debug_printf(DEBUG_NORMAL, "The server requested a password change "
		   "protocol version that we don't understand.  Expected "
		   "version %d.  Got version %d.\n", 
		   MSCHAPV2_PASSWORD_CHANGE_VER, atoi(strdata));
      // This error isn't fatal!
    }

  // Finally!  We get to the text version of the failure.
  offset++;
  strdata += offset;
  offset = 0;

  if ((strdata[offset] != 'M') || (strdata[offset+1] != '='))
    {
      debug_printf(DEBUG_NORMAL, "This message didn't appear to have a valid"
		   " text version of the error!  Expected 'M=', found "
		   "'%c%c'.\n", strdata[offset], strdata[offset+1]);
      return XEGENERROR;
    }

  // Otherwise, update our pointer to point to the text of the error.
  strdata += 2;
  *errtext = strdata;

  return XENONE;
}

/******************************************************************
 *
 *  Process a failure message.
 *
 ******************************************************************/
uint8_t eapmschapv2_failure(eap_type_data *eapdata)
{
  struct mschapv2_fail_request *fail = NULL;
  char *err_string = NULL, *err_text = NULL;
  uint16_t errlen = 0, errcode = 0;

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

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

  // In case we fail parsing the error code, we still end up with the
  // proper end result.
  eapdata->altReject = TRUE;

  fail = (struct mschapv2_fail_request *)&eapdata->eapReqData[sizeof(struct eap_header)];

  if (fail->OpCode != MS_CHAPV2_FAILURE)
    {
      debug_printf(DEBUG_NORMAL, "The OpCode in the MS-CHAPv2 packet doesn't "
		   "indicate that we got an error.  But, we ended up in the "
		   "error state anyway?\n");
      return EAP_FAIL;
    }
  
  errlen = ntohs(fail->MS_Length);

  err_string = Malloc(errlen+1);
  if (err_string == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't allocate memory needed to parse "
		   "the error string!\n");
	  ipc_events_malloc_failed(NULL);
      return EAP_FAIL;
    }

  memcpy(err_string, fail->MsgField, errlen);

  debug_printf(DEBUG_AUTHTYPES, "Error string is : %s\n", err_string);

  if (eapmschapv2_parse_error_string(err_string, &errcode, &err_text) != XENONE)
    {
      return EAP_FAIL;
    }

  switch (errcode)
    {
    case MSCHAPV2_RESTRICTED_LOGON_HOURS:
      debug_printf(DEBUG_NORMAL, "Your account is restricted to the hours "
		   "you may log in.\n");
	  ipc_events_error(NULL, IPC_EVENT_ERROR_RESTRICTED_HOURS, NULL);
      break;

    case MSCHAPV2_ACCT_DISABLED:
      debug_printf(DEBUG_NORMAL, "Your account has been disabled.\n");
	  ipc_events_error(NULL, IPC_EVENT_ERROR_ACCT_DISABLED, NULL);
      break;

    case MSCHAPV2_PASSWD_EXPIRED:
      debug_printf(DEBUG_NORMAL, "Your password has expired.\n");
	  ipc_events_error(NULL, IPC_EVENT_ERROR_PASSWD_EXPIRED, NULL);
      break;

    case MSCHAPV2_NO_DIALIN_PERMISSION:
      debug_printf(DEBUG_NORMAL, "Your account does not have permission to "
		   "use this network.\n");
	  ipc_events_error(NULL, IPC_EVENT_ERROR_NO_PERMS, NULL);
      break;

    case MSCHAPV2_AUTHENTICATION_FAILURE:
      debug_printf(DEBUG_NORMAL, "General authentication failure.\n");
	  // Don't send an error event here, because it won't be useful to the user.
	  // Instead, they should look at the log file to determine what went wrong.
      break;

    case MSCHAPV2_CHANGING_PASSWORD:
      debug_printf(DEBUG_NORMAL, "There was an error changing your password."
		   "\n");
	  ipc_events_error(NULL, IPC_EVENT_ERROR_CHANGING_PASSWD, NULL);
      break;

    default:
      debug_printf(DEBUG_NORMAL, "Unknown error type %d returned.  Please "
		   "see text description of the error (on the next line) "
		   "for more information.\n");
	  ipc_events_error(NULL, IPC_EVENT_ERROR_TEXT, err_text);
      break;
    }

  debug_printf(DEBUG_NORMAL, "Server provided text description of the error : "
	       "%s\n", err_text);

  return EAP_FAIL;
}

/******************************************************************
 *
 * Process an EAP-MSCHAPv2 packet, and develop the data needed for
 * the response.
 *
 ******************************************************************/
void eapmschapv2_process(eap_type_data *eapdata)
{
  struct config_eap_mschapv2 *eapconf = NULL;
  struct mschapv2_challenge *challenge = NULL;

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

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

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

  eapconf = (struct config_eap_mschapv2 *)eapdata->eap_conf_data;

  if (eapdata->methodState == INIT)
    {

⌨️ 快捷键说明

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