/** @file
  The functions for identification policy modification.
    
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials 
are licensed and made available under the terms and conditions of the BSD License 
which accompanies this distribution.  The full text of the license may be found at 
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "UserProfileManager.h"


/**
  Verify the new identity policy in the current implementation. The same credential
  provider can't appear twice in one identity policy.

  @param[in] NewGuid       Points to the credential provider guid.
  
  @retval TRUE     The NewGuid was found in the identity policy.
  @retval FALSE    The NewGuid was not found.

**/
BOOLEAN
ProviderAlreadyInPolicy (
  IN EFI_GUID                                      *NewGuid
  )
{
  UINTN                         Offset;
  EFI_USER_INFO_IDENTITY_POLICY *Identity;
  EFI_INPUT_KEY                 Key;

  Offset = 0;
  while (Offset < mUserInfo.NewIdentityPolicyLen) {
    Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (mUserInfo.NewIdentityPolicy + Offset);
    if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {
      if (CompareGuid (NewGuid, (EFI_GUID *) (Identity + 1))) {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"This Credential Provider Are Already Used!",
          L"",
          L"Press Any Key to Continue ...",
          NULL
          );
        return TRUE;
      }
    }
    Offset += Identity->Length;
  }
  
  return FALSE;
}


/**
  Add the user's credential record in the provider.

  @param[in]  Identity     Identity policy item including credential provider.
  @param[in]  User         Points to user profile.

  @retval EFI_SUCCESS      Add or delete record successfully.
  @retval Others           Fail to add or delete record.

**/
EFI_STATUS
EnrollUserOnProvider (
  IN  EFI_USER_INFO_IDENTITY_POLICY              *Identity,
  IN  EFI_USER_PROFILE_HANDLE                    User 
  )
{
  UINTN                          Index;
  EFI_USER_CREDENTIAL2_PROTOCOL  *UserCredential;
  
  //
  // Find the specified credential provider.
  //
  for (Index = 0; Index < mProviderInfo->Count; Index++) {
    UserCredential = mProviderInfo->Provider[Index];
    if (CompareGuid ((EFI_GUID *)(Identity + 1), &UserCredential->Identifier)) {
      return UserCredential->Enroll (UserCredential, User);
    }
  }

  return EFI_NOT_FOUND;  
}


/**
  Delete the User's credential record on the provider.

  @param[in]  Identity     Point to EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER user info.
  @param[in]  User         Points to user profile.

  @retval EFI_SUCCESS      Delete User's credential record successfully.
  @retval Others           Fail to add or delete record.

**/
EFI_STATUS
DeleteUserOnProvider (
  IN  EFI_USER_INFO_IDENTITY_POLICY              *Identity,
  IN  EFI_USER_PROFILE_HANDLE                    User 
  )
{
  UINTN                          Index;
  EFI_USER_CREDENTIAL2_PROTOCOL  *UserCredential;
  
  //
  // Find the specified credential provider.
  //
  for (Index = 0; Index < mProviderInfo->Count; Index++) {
    UserCredential = mProviderInfo->Provider[Index];
    if (CompareGuid ((EFI_GUID *)(Identity + 1), &UserCredential->Identifier)) {
      return UserCredential->Delete (UserCredential, User);
    }
  }

  return EFI_NOT_FOUND;  
}


/**
  Delete User's credental from all the providers that exist in User's identity policy.
  
  @param[in]  IdentityPolicy     Point to User's identity policy.
  @param[in]  IdentityPolicyLen  The length of the identity policy.
  @param[in]  User               Points to user profile.

**/
VOID
DeleteCredentialFromProviders (
  IN     UINT8                                *IdentityPolicy,
  IN     UINTN                                 IdentityPolicyLen,
  IN     EFI_USER_PROFILE_HANDLE               User 
  )
{
  EFI_USER_INFO_IDENTITY_POLICY    *Identity;
  UINTN                            Offset;

  Offset = 0;
  while (Offset < IdentityPolicyLen) {
    Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (IdentityPolicy + Offset);
    if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {
      //
      // Delete the user on this provider.
      //
      DeleteUserOnProvider (Identity, User);
    }
    Offset += Identity->Length;
  }

}


/**
  Remove the provider specified by Offset from the new user identification record.
  
  @param[in]  IdentityPolicy    Point to user identity item in new identification policy.
  @param[in]  Offset            The item offset in the new identification policy.

**/
VOID
DeleteProviderFromPolicy (
  IN     EFI_USER_INFO_IDENTITY_POLICY         *IdentityPolicy,
  IN     UINTN                                 Offset
  )
{
  UINTN                         RemainingLen;
  UINTN                         DeleteLen;

  if (IdentityPolicy->Length == mUserInfo.NewIdentityPolicyLen) {
    //
    // Only one credential provider in the identification policy.
    // Set the new policy to be TRUE after removed the provider.
    //
    IdentityPolicy->Type           = EFI_USER_INFO_IDENTITY_TRUE;
    IdentityPolicy->Length         = sizeof (EFI_USER_INFO_IDENTITY_POLICY);
    mUserInfo.NewIdentityPolicyLen = IdentityPolicy->Length;
    return ;
  }

  DeleteLen = IdentityPolicy->Length + sizeof(EFI_USER_INFO_IDENTITY_POLICY);
  if ((Offset + IdentityPolicy->Length) != mUserInfo.NewIdentityPolicyLen) {
    //
    // This provider is not the last item in the identification policy, delete it and the connector.
    //    
    RemainingLen = mUserInfo.NewIdentityPolicyLen - Offset - DeleteLen;
    CopyMem ((UINT8 *) IdentityPolicy, (UINT8 *) IdentityPolicy + DeleteLen, RemainingLen);
  }
  mUserInfo.NewIdentityPolicyLen -= DeleteLen;  
}


/**
  Add a new provider to the mUserInfo.NewIdentityPolicy.

  It is invoked when 'add option' in UI is pressed.

  @param[in] NewGuid       Points to the credential provider guid.
  
**/
VOID
AddProviderToPolicy (
  IN  EFI_GUID                                  *NewGuid
  )
{
  UINT8                         *NewPolicyInfo;
  UINTN                         NewPolicyInfoLen;
  EFI_USER_INFO_IDENTITY_POLICY *Policy;

  //
  // Allocate memory for the new identity policy.
  //
  NewPolicyInfoLen = mUserInfo.NewIdentityPolicyLen + sizeof (EFI_USER_INFO_IDENTITY_POLICY) + sizeof (EFI_GUID);
  if (mUserInfo.NewIdentityPolicyLen > 0) {
    //
    // It is not the first provider in the policy. Add a connector before provider.
    //
    NewPolicyInfoLen += sizeof (EFI_USER_INFO_IDENTITY_POLICY);
  }
  NewPolicyInfo = AllocateZeroPool (NewPolicyInfoLen);
  if (NewPolicyInfo == NULL) {
    return ;
  }

  NewPolicyInfoLen = 0;
  if (mUserInfo.NewIdentityPolicyLen > 0) {
    //
    // Save orginal policy.
    //
    CopyMem (NewPolicyInfo, mUserInfo.NewIdentityPolicy, mUserInfo.NewIdentityPolicyLen);

    //
    // Save logical connector.
    //
    Policy = (EFI_USER_INFO_IDENTITY_POLICY *) (NewPolicyInfo + mUserInfo.NewIdentityPolicyLen);
    if (mConncetLogical == 0) {
      Policy->Type = EFI_USER_INFO_IDENTITY_AND;
    } else {
      Policy->Type = EFI_USER_INFO_IDENTITY_OR;
    }

    Policy->Length   = sizeof (EFI_USER_INFO_IDENTITY_POLICY);
    NewPolicyInfoLen = mUserInfo.NewIdentityPolicyLen + Policy->Length;
    FreePool (mUserInfo.NewIdentityPolicy);
  }
  
  //
  // Save credential provider.
  //
  Policy = (EFI_USER_INFO_IDENTITY_POLICY *) (NewPolicyInfo + NewPolicyInfoLen);
  Policy->Length = sizeof (EFI_USER_INFO_IDENTITY_POLICY) + sizeof (EFI_GUID);
  Policy->Type   = EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER;
  CopyGuid ((EFI_GUID *) (Policy + 1), NewGuid);
  NewPolicyInfoLen += Policy->Length;

  //
  // Update identity policy choice.
  //
  mUserInfo.NewIdentityPolicy         = NewPolicyInfo;
  mUserInfo.NewIdentityPolicyLen      = NewPolicyInfoLen;
  mUserInfo.NewIdentityPolicyModified = TRUE;
}


/**
  This function replaces the old identity policy with a new identity policy.

  This function delete the user identity policy information.
  If enroll new credential failed, recover the old identity policy.

  @retval EFI_SUCCESS      Modify user identity policy successfully.
  @retval Others           Fail to modify user identity policy.

**/
EFI_STATUS
UpdateCredentialProvider (
  )
{
  EFI_STATUS                    Status;
  EFI_USER_INFO_IDENTITY_POLICY *Identity;
  UINTN                         Offset;

  //
  // Delete the old identification policy.
  //
  DeleteCredentialFromProviders (mUserInfo.IdentityPolicy, mUserInfo.IdentityPolicyLen, mModifyUser);

  //
  // Add the new identification policy.
  //
  Offset  = 0;
  while (Offset < mUserInfo.NewIdentityPolicyLen) {
    Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (mUserInfo.NewIdentityPolicy + Offset);
    if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {
      //
      // Enroll the user on this provider
      //
      Status = EnrollUserOnProvider (Identity, mModifyUser);
      if (EFI_ERROR (Status)) {
        //
        // Failed to enroll the user by new identification policy.
        // So removed the credential provider from the identification policy
        //
        DeleteProviderFromPolicy (Identity, Offset);
        continue;
      }
    }
    Offset += Identity->Length;
  }

  return EFI_SUCCESS;
}


/**
  Check whether the identity policy is valid.

  @param[in]  PolicyInfo          Point to the identity policy.
  @param[in]  PolicyInfoLen       The policy length.

  @retval TRUE     The policy is a valid identity policy.
  @retval FALSE    The policy is not a valid identity policy.
  
**/
BOOLEAN
CheckNewIdentityPolicy (
  IN  UINT8                                     *PolicyInfo,
  IN  UINTN                                     PolicyInfoLen
  )
{
  EFI_USER_INFO_IDENTITY_POLICY *Identity;
  EFI_INPUT_KEY                 Key;
  UINTN                         Offset;
  UINT32                        OpCode;
  
  //
  // Check policy expression.
  //
  OpCode  = EFI_USER_INFO_IDENTITY_FALSE;
  Offset  = 0;
  while (Offset < PolicyInfoLen) {
    //
    // Check identification policy according to type
    //
    Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (PolicyInfo + Offset);
    switch (Identity->Type) {
      
    case EFI_USER_INFO_IDENTITY_TRUE:
      break;

    case EFI_USER_INFO_IDENTITY_OR:
      if (OpCode == EFI_USER_INFO_IDENTITY_AND) {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Invalid Identity Policy, Mixed Connector Unsupport!",
          L"",
          L"Press Any Key to Continue ...",
          NULL
          );
        return FALSE;
      }

      OpCode = EFI_USER_INFO_IDENTITY_OR;
      break;

    case EFI_USER_INFO_IDENTITY_AND:
      if (OpCode == EFI_USER_INFO_IDENTITY_OR) {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Invalid Identity Policy, Mixed Connector Unsupport!",
          L"",
          L"Press Any Key to Continue ...",
          NULL
          );
        return FALSE;
      }

      OpCode = EFI_USER_INFO_IDENTITY_AND;
      break;

    case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER:
      break;

    default:
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Unsupport parameter",
        L"",
        L"Press Any Key to Continue ...",
        NULL
        );
      return FALSE;
    }
    Offset += Identity->Length;
  }

  return TRUE;
}


/**
  Save the identity policy and update UI with it.
  
  This function will verify the new identity policy, in current implementation, 
  the identity policy can be:  T, P & P & P & ..., P | P | P | ...
  Here, "T" means "True", "P" means "Credential Provider", "&" means "and", "|" means "or".
  Other identity policies are not supported.  

**/
VOID
SaveIdentityPolicy (
  VOID
  )
{
  EFI_STATUS                    Status;
  EFI_USER_INFO_HANDLE          UserInfo;
  EFI_USER_INFO                 *Info;

  if (!mUserInfo.NewIdentityPolicyModified || (mUserInfo.NewIdentityPolicyLen == 0)) {
    return;
  }

  //
  // Check policy expression.
  //
  if (!CheckNewIdentityPolicy (mUserInfo.NewIdentityPolicy, mUserInfo.NewIdentityPolicyLen)) {
    return;
  }

  Status = FindInfoByType (mModifyUser, EFI_USER_INFO_IDENTITY_POLICY_RECORD, &UserInfo);
  if (EFI_ERROR (Status)) {
    return ;
  }
  
  //
  // Update the informantion on credential provider.
  //
  Status = UpdateCredentialProvider ();
  if (EFI_ERROR (Status)) {
    return ;
  }
  
  //
  // Save new identification policy.
  //
  Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + mUserInfo.NewIdentityPolicyLen);
  ASSERT (Info != NULL);

  Info->InfoType    = EFI_USER_INFO_IDENTITY_POLICY_RECORD;
  Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;
  Info->InfoSize    = (UINT32) (sizeof (EFI_USER_INFO) + mUserInfo.NewIdentityPolicyLen);
  CopyMem ((UINT8 *) (Info + 1), mUserInfo.NewIdentityPolicy, mUserInfo.NewIdentityPolicyLen);

  Status = mUserManager->SetInfo (mUserManager, mModifyUser, &UserInfo, Info, Info->InfoSize);
  FreePool (Info);
   
  //
  // Update the mUserInfo.IdentityPolicy by mUserInfo.NewIdentityPolicy
  //
  if (mUserInfo.IdentityPolicy != NULL) {
    FreePool (mUserInfo.IdentityPolicy);
  }
  mUserInfo.IdentityPolicy    = mUserInfo.NewIdentityPolicy;
  mUserInfo.IdentityPolicyLen = mUserInfo.NewIdentityPolicyLen;

  mUserInfo.NewIdentityPolicy         = NULL;
  mUserInfo.NewIdentityPolicyLen      = 0;
  mUserInfo.NewIdentityPolicyModified = FALSE;   

  //
  // Update identity policy choice.
  //
  ResolveIdentityPolicy (mUserInfo.IdentityPolicy, mUserInfo.IdentityPolicyLen, STRING_TOKEN (STR_IDENTIFY_POLICY_VAL));
}


/**
  Update the mUserInfo.NewIdentityPolicy, and UI when 'add option' is pressed.

**/
VOID
AddIdentityPolicyItem (
  VOID
  )
{
  if (mProviderInfo->Count == 0) {
    return ;
  }
  
  //
  // Check the identity policy.
  //
  if (ProviderAlreadyInPolicy (&mProviderInfo->Provider[mProviderChoice]->Identifier)) {
    return;
  }

  //
  // Add it to identification policy
  //
  AddProviderToPolicy (&mProviderInfo->Provider[mProviderChoice]->Identifier);

  //
  // Update identity policy choice.
  //
  ResolveIdentityPolicy (mUserInfo.NewIdentityPolicy, mUserInfo.NewIdentityPolicyLen, STRING_TOKEN (STR_IDENTIFY_POLICY_VALUE));
}


