示例#1
0
文件: SockImpl.c 项目: MattDevo/edk2
/**
  Called by the low layer protocol to copy some data in socket send
  buffer starting from the specific offset to a buffer provided by
  the caller.

  @param  Sock                  Pointer to the socket.
  @param  Offset                The start point of the data to be copied.
  @param  Len                   The length of the data to be copied.
  @param  Dest                  Pointer to the destination to copy the data.

  @return The data size copied.

**/
UINT32
SockGetDataToSend (
  IN SOCKET      *Sock,
  IN UINT32      Offset,
  IN UINT32      Len,
  IN UINT8       *Dest
  )
{
  ASSERT ((Sock != NULL) && SockStream == Sock->Type);

  return NetbufQueCopy (
          Sock->SndBuffer.DataQueue,
          Offset,
          Len,
          Dest
          );
}
示例#2
0
/**
  Copy data from socket buffer to an application provided receive buffer.

  @param[in]  Sock        Pointer to the socket.
  @param[in]  TcpRxData   Pointer to the application provided receive buffer.
  @param[in]  RcvdBytes   The maximum length of the data can be copied.
  @param[in]  IsUrg       If TRUE the data is Out of Bound, FALSE the data is normal.

**/
VOID
SockSetTcpRxData (
  IN SOCKET     *Sock,
  IN VOID       *TcpRxData,
  IN UINT32     RcvdBytes,
  IN BOOLEAN    IsUrg
  )
{
  UINT32                  Index;
  UINT32                  CopyBytes;
  UINT32                  OffSet;
  EFI_TCP4_RECEIVE_DATA   *RxData;
  EFI_TCP4_FRAGMENT_DATA  *Fragment;

  RxData  = (EFI_TCP4_RECEIVE_DATA *) TcpRxData;

  OffSet  = 0;

  ASSERT (RxData->DataLength >= RcvdBytes);

  RxData->DataLength  = RcvdBytes;
  RxData->UrgentFlag  = IsUrg;

  //
  // Copy the CopyBytes data from socket receive buffer to RxData.
  //
  for (Index = 0; (Index < RxData->FragmentCount) && (RcvdBytes > 0); Index++) {

    Fragment  = &RxData->FragmentTable[Index];
    CopyBytes = MIN ((UINT32) (Fragment->FragmentLength), RcvdBytes);

    NetbufQueCopy (
      Sock->RcvBuffer.DataQueue,
      OffSet,
      CopyBytes,
      Fragment->FragmentBuffer
      );

    Fragment->FragmentLength = CopyBytes;
    RcvdBytes -= CopyBytes;
    OffSet += CopyBytes;
  }
}
示例#3
0
文件: IScsiCHAP.c 项目: jeppeter/vbox
/**
  This function checks the received iSCSI Login Response during the security
  negotiation stage.

  @param[in] Conn             The iSCSI connection.

  @retval EFI_SUCCESS          The Login Response passed the CHAP validation.
  @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
  @retval EFI_PROTOCOL_ERROR   Some kind of protocol error occurred.
  @retval Others               Other errors as indicated.

**/
EFI_STATUS
IScsiCHAPOnRspReceived (
  IN ISCSI_CONNECTION  *Conn
  )
{
  EFI_STATUS                  Status;
  ISCSI_SESSION               *Session;
  ISCSI_CHAP_AUTH_DATA        *AuthData;
  CHAR8                       *Value;
  UINT8                       *Data;
  UINT32                      Len;
  LIST_ENTRY                  *KeyValueList;
  UINTN                       Algorithm;
  CHAR8                       *Identifier;
  CHAR8                       *Challenge;
  CHAR8                       *Name;
  CHAR8                       *Response;
  UINT8                       TargetRsp[ISCSI_CHAP_RSP_LEN];
  UINT32                      RspLen;
  UINTN                       Result;

  ASSERT (Conn->CurrentStage == ISCSI_SECURITY_NEGOTIATION);
  ASSERT (Conn->RspQue.BufNum != 0);

  Session     = Conn->Session;
  AuthData    = &Session->AuthData.CHAP;
  Len         = Conn->RspQue.BufSize;
  Data        = AllocateZeroPool (Len);
  if (Data == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Copy the data in case the data spans over multiple PDUs.
  //
  NetbufQueCopy (&Conn->RspQue, 0, Len, Data);

  //
  // Build the key-value list from the data segment of the Login Response.
  //
  KeyValueList = IScsiBuildKeyValueList ((CHAR8 *) Data, Len);
  if (KeyValueList == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  Status = EFI_PROTOCOL_ERROR;

  switch (Conn->AuthStep) {
  case ISCSI_AUTH_INITIAL:
    //
    // The first Login Response.
    //
    Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_TARGET_PORTAL_GROUP_TAG);
    if (Value == NULL) {
      goto ON_EXIT;
    }

    Result = IScsiNetNtoi (Value);
    if (Result > 0xFFFF) {
      goto ON_EXIT;
    }

    Session->TargetPortalGroupTag = (UINT16) Result;

    Value                         = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_AUTH_METHOD);
    if (Value == NULL) {
      goto ON_EXIT;
    }
    //
    // Initiator mandates CHAP authentication but target replies without "CHAP", or
    // initiator suggets "None" but target replies with some kind of auth method.
    //
    if (Session->AuthType == ISCSI_AUTH_TYPE_NONE) {
      if (AsciiStrCmp (Value, ISCSI_KEY_VALUE_NONE) != 0) {
        goto ON_EXIT;
      }
    } else if (Session->AuthType == ISCSI_AUTH_TYPE_CHAP) {
      if (AsciiStrCmp (Value, ISCSI_AUTH_METHOD_CHAP) != 0) {
        goto ON_EXIT;
      }
    } else {
      goto ON_EXIT;
    }

    //
    // Transit to CHAP step one.
    //
    Conn->AuthStep  = ISCSI_CHAP_STEP_ONE;
    Status          = EFI_SUCCESS;
    break;

  case ISCSI_CHAP_STEP_TWO:
    //
    // The Target replies with CHAP_A=<A> CHAP_I=<I> CHAP_C=<C>
    //
    Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_ALGORITHM);
    if (Value == NULL) {
      goto ON_EXIT;
    }

    Algorithm = IScsiNetNtoi (Value);
    if (Algorithm != ISCSI_CHAP_ALGORITHM_MD5) {
      //
      // Unsupported algorithm is chosen by target.
      //
      goto ON_EXIT;
    }

    Identifier = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_IDENTIFIER);
    if (Identifier == NULL) {
      goto ON_EXIT;
    }

    Challenge = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_CHALLENGE);
    if (Challenge == NULL) {
      goto ON_EXIT;
    }
    //
    // Process the CHAP identifier and CHAP Challenge from Target.
    // Calculate Response value.
    //
    Result = IScsiNetNtoi (Identifier);
    if (Result > 0xFF) {
      goto ON_EXIT;
    }

    AuthData->InIdentifier      = (UINT32) Result;
    AuthData->InChallengeLength = ISCSI_CHAP_AUTH_MAX_LEN;
    IScsiHexToBin ((UINT8 *) AuthData->InChallenge, &AuthData->InChallengeLength, Challenge);
    Status = IScsiCHAPCalculateResponse (
               AuthData->InIdentifier,
               AuthData->AuthConfig->CHAPSecret,
               (UINT32) AsciiStrLen (AuthData->AuthConfig->CHAPSecret),
               AuthData->InChallenge,
               AuthData->InChallengeLength,
               AuthData->CHAPResponse
               );

    //
    // Transit to next step.
    //
    Conn->AuthStep = ISCSI_CHAP_STEP_THREE;
    break;

  case ISCSI_CHAP_STEP_THREE:
    //
    // One way CHAP authentication and the target would like to
    // authenticate us.
    //
    Status = EFI_SUCCESS;
    break;

  case ISCSI_CHAP_STEP_FOUR:
    ASSERT (AuthData->AuthConfig->CHAPType == ISCSI_CHAP_MUTUAL);
    //
    // The forth step, CHAP_N=<N> CHAP_R=<R> is received from Target.
    //
    Name = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_NAME);
    if (Name == NULL) {
      goto ON_EXIT;
    }

    Response = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_RESPONSE);
    if (Response == NULL) {
      goto ON_EXIT;
    }

    RspLen = ISCSI_CHAP_RSP_LEN;
    IScsiHexToBin (TargetRsp, &RspLen, Response);

    //
    // Check the CHAP Name and Response replied by Target.
    //
    Status = IScsiCHAPAuthTarget (AuthData, TargetRsp);
    break;

  default:
    break;
  }

ON_EXIT:

  if (KeyValueList != NULL) {
    IScsiFreeKeyValueList (KeyValueList);
  }

  FreePool (Data);

  return Status;
}