Home | History | Annotate | Download | only in UserProfileManagerDxe
      1 /** @file
      2   The functions for identification policy modification.
      3 
      4 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "UserProfileManager.h"
     16 
     17 
     18 /**
     19   Verify the new identity policy in the current implementation. The same credential
     20   provider can't appear twice in one identity policy.
     21 
     22   @param[in] NewGuid       Points to the credential provider guid.
     23 
     24   @retval TRUE     The NewGuid was found in the identity policy.
     25   @retval FALSE    The NewGuid was not found.
     26 
     27 **/
     28 BOOLEAN
     29 ProviderAlreadyInPolicy (
     30   IN EFI_GUID                                      *NewGuid
     31   )
     32 {
     33   UINTN                         Offset;
     34   EFI_USER_INFO_IDENTITY_POLICY *Identity;
     35   EFI_INPUT_KEY                 Key;
     36 
     37   Offset = 0;
     38   while (Offset < mUserInfo.NewIdentityPolicyLen) {
     39     Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (mUserInfo.NewIdentityPolicy + Offset);
     40     if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {
     41       if (CompareGuid (NewGuid, (EFI_GUID *) (Identity + 1))) {
     42         CreatePopUp (
     43           EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
     44           &Key,
     45           L"This Credential Provider Are Already Used!",
     46           L"",
     47           L"Press Any Key to Continue ...",
     48           NULL
     49           );
     50         return TRUE;
     51       }
     52     }
     53     Offset += Identity->Length;
     54   }
     55 
     56   return FALSE;
     57 }
     58 
     59 
     60 /**
     61   Add the user's credential record in the provider.
     62 
     63   @param[in]  Identity     Identity policy item including credential provider.
     64   @param[in]  User         Points to user profile.
     65 
     66   @retval EFI_SUCCESS      Add or delete record successfully.
     67   @retval Others           Fail to add or delete record.
     68 
     69 **/
     70 EFI_STATUS
     71 EnrollUserOnProvider (
     72   IN  EFI_USER_INFO_IDENTITY_POLICY              *Identity,
     73   IN  EFI_USER_PROFILE_HANDLE                    User
     74   )
     75 {
     76   UINTN                          Index;
     77   EFI_USER_CREDENTIAL2_PROTOCOL  *UserCredential;
     78 
     79   //
     80   // Find the specified credential provider.
     81   //
     82   for (Index = 0; Index < mProviderInfo->Count; Index++) {
     83     UserCredential = mProviderInfo->Provider[Index];
     84     if (CompareGuid ((EFI_GUID *)(Identity + 1), &UserCredential->Identifier)) {
     85       return UserCredential->Enroll (UserCredential, User);
     86     }
     87   }
     88 
     89   return EFI_NOT_FOUND;
     90 }
     91 
     92 
     93 /**
     94   Delete the User's credential record on the provider.
     95 
     96   @param[in]  Identity     Point to EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER user info.
     97   @param[in]  User         Points to user profile.
     98 
     99   @retval EFI_SUCCESS      Delete User's credential record successfully.
    100   @retval Others           Fail to add or delete record.
    101 
    102 **/
    103 EFI_STATUS
    104 DeleteUserOnProvider (
    105   IN  EFI_USER_INFO_IDENTITY_POLICY              *Identity,
    106   IN  EFI_USER_PROFILE_HANDLE                    User
    107   )
    108 {
    109   UINTN                          Index;
    110   EFI_USER_CREDENTIAL2_PROTOCOL  *UserCredential;
    111 
    112   //
    113   // Find the specified credential provider.
    114   //
    115   for (Index = 0; Index < mProviderInfo->Count; Index++) {
    116     UserCredential = mProviderInfo->Provider[Index];
    117     if (CompareGuid ((EFI_GUID *)(Identity + 1), &UserCredential->Identifier)) {
    118       return UserCredential->Delete (UserCredential, User);
    119     }
    120   }
    121 
    122   return EFI_NOT_FOUND;
    123 }
    124 
    125 
    126 /**
    127   Delete User's credental from all the providers that exist in User's identity policy.
    128 
    129   @param[in]  IdentityPolicy     Point to User's identity policy.
    130   @param[in]  IdentityPolicyLen  The length of the identity policy.
    131   @param[in]  User               Points to user profile.
    132 
    133 **/
    134 VOID
    135 DeleteCredentialFromProviders (
    136   IN     UINT8                                *IdentityPolicy,
    137   IN     UINTN                                 IdentityPolicyLen,
    138   IN     EFI_USER_PROFILE_HANDLE               User
    139   )
    140 {
    141   EFI_USER_INFO_IDENTITY_POLICY    *Identity;
    142   UINTN                            Offset;
    143 
    144   Offset = 0;
    145   while (Offset < IdentityPolicyLen) {
    146     Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (IdentityPolicy + Offset);
    147     if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {
    148       //
    149       // Delete the user on this provider.
    150       //
    151       DeleteUserOnProvider (Identity, User);
    152     }
    153     Offset += Identity->Length;
    154   }
    155 
    156 }
    157 
    158 
    159 /**
    160   Remove the provider specified by Offset from the new user identification record.
    161 
    162   @param[in]  IdentityPolicy    Point to user identity item in new identification policy.
    163   @param[in]  Offset            The item offset in the new identification policy.
    164 
    165 **/
    166 VOID
    167 DeleteProviderFromPolicy (
    168   IN     EFI_USER_INFO_IDENTITY_POLICY         *IdentityPolicy,
    169   IN     UINTN                                 Offset
    170   )
    171 {
    172   UINTN                         RemainingLen;
    173   UINTN                         DeleteLen;
    174 
    175   if (IdentityPolicy->Length == mUserInfo.NewIdentityPolicyLen) {
    176     //
    177     // Only one credential provider in the identification policy.
    178     // Set the new policy to be TRUE after removed the provider.
    179     //
    180     IdentityPolicy->Type           = EFI_USER_INFO_IDENTITY_TRUE;
    181     IdentityPolicy->Length         = sizeof (EFI_USER_INFO_IDENTITY_POLICY);
    182     mUserInfo.NewIdentityPolicyLen = IdentityPolicy->Length;
    183     return ;
    184   }
    185 
    186   DeleteLen = IdentityPolicy->Length + sizeof(EFI_USER_INFO_IDENTITY_POLICY);
    187   if ((Offset + IdentityPolicy->Length) != mUserInfo.NewIdentityPolicyLen) {
    188     //
    189     // This provider is not the last item in the identification policy, delete it and the connector.
    190     //
    191     RemainingLen = mUserInfo.NewIdentityPolicyLen - Offset - DeleteLen;
    192     CopyMem ((UINT8 *) IdentityPolicy, (UINT8 *) IdentityPolicy + DeleteLen, RemainingLen);
    193   }
    194   mUserInfo.NewIdentityPolicyLen -= DeleteLen;
    195 }
    196 
    197 
    198 /**
    199   Add a new provider to the mUserInfo.NewIdentityPolicy.
    200 
    201   It is invoked when 'add option' in UI is pressed.
    202 
    203   @param[in] NewGuid       Points to the credential provider guid.
    204 
    205 **/
    206 VOID
    207 AddProviderToPolicy (
    208   IN  EFI_GUID                                  *NewGuid
    209   )
    210 {
    211   UINT8                         *NewPolicyInfo;
    212   UINTN                         NewPolicyInfoLen;
    213   EFI_USER_INFO_IDENTITY_POLICY *Policy;
    214 
    215   //
    216   // Allocate memory for the new identity policy.
    217   //
    218   NewPolicyInfoLen = mUserInfo.NewIdentityPolicyLen + sizeof (EFI_USER_INFO_IDENTITY_POLICY) + sizeof (EFI_GUID);
    219   if (mUserInfo.NewIdentityPolicyLen > 0) {
    220     //
    221     // It is not the first provider in the policy. Add a connector before provider.
    222     //
    223     NewPolicyInfoLen += sizeof (EFI_USER_INFO_IDENTITY_POLICY);
    224   }
    225   NewPolicyInfo = AllocateZeroPool (NewPolicyInfoLen);
    226   if (NewPolicyInfo == NULL) {
    227     return ;
    228   }
    229 
    230   NewPolicyInfoLen = 0;
    231   if (mUserInfo.NewIdentityPolicyLen > 0) {
    232     //
    233     // Save orginal policy.
    234     //
    235     CopyMem (NewPolicyInfo, mUserInfo.NewIdentityPolicy, mUserInfo.NewIdentityPolicyLen);
    236 
    237     //
    238     // Save logical connector.
    239     //
    240     Policy = (EFI_USER_INFO_IDENTITY_POLICY *) (NewPolicyInfo + mUserInfo.NewIdentityPolicyLen);
    241     if (mConncetLogical == 0) {
    242       Policy->Type = EFI_USER_INFO_IDENTITY_AND;
    243     } else {
    244       Policy->Type = EFI_USER_INFO_IDENTITY_OR;
    245     }
    246 
    247     Policy->Length   = sizeof (EFI_USER_INFO_IDENTITY_POLICY);
    248     NewPolicyInfoLen = mUserInfo.NewIdentityPolicyLen + Policy->Length;
    249     FreePool (mUserInfo.NewIdentityPolicy);
    250   }
    251 
    252   //
    253   // Save credential provider.
    254   //
    255   Policy = (EFI_USER_INFO_IDENTITY_POLICY *) (NewPolicyInfo + NewPolicyInfoLen);
    256   Policy->Length = sizeof (EFI_USER_INFO_IDENTITY_POLICY) + sizeof (EFI_GUID);
    257   Policy->Type   = EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER;
    258   CopyGuid ((EFI_GUID *) (Policy + 1), NewGuid);
    259   NewPolicyInfoLen += Policy->Length;
    260 
    261   //
    262   // Update identity policy choice.
    263   //
    264   mUserInfo.NewIdentityPolicy         = NewPolicyInfo;
    265   mUserInfo.NewIdentityPolicyLen      = NewPolicyInfoLen;
    266   mUserInfo.NewIdentityPolicyModified = TRUE;
    267 }
    268 
    269 
    270 /**
    271   This function replaces the old identity policy with a new identity policy.
    272 
    273   This function delete the user identity policy information.
    274   If enroll new credential failed, recover the old identity policy.
    275 
    276   @retval EFI_SUCCESS      Modify user identity policy successfully.
    277   @retval Others           Fail to modify user identity policy.
    278 
    279 **/
    280 EFI_STATUS
    281 UpdateCredentialProvider (
    282   )
    283 {
    284   EFI_STATUS                    Status;
    285   EFI_USER_INFO_IDENTITY_POLICY *Identity;
    286   UINTN                         Offset;
    287 
    288   //
    289   // Delete the old identification policy.
    290   //
    291   DeleteCredentialFromProviders (mUserInfo.IdentityPolicy, mUserInfo.IdentityPolicyLen, mModifyUser);
    292 
    293   //
    294   // Add the new identification policy.
    295   //
    296   Offset  = 0;
    297   while (Offset < mUserInfo.NewIdentityPolicyLen) {
    298     Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (mUserInfo.NewIdentityPolicy + Offset);
    299     if (Identity->Type == EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER) {
    300       //
    301       // Enroll the user on this provider
    302       //
    303       Status = EnrollUserOnProvider (Identity, mModifyUser);
    304       if (EFI_ERROR (Status)) {
    305         //
    306         // Failed to enroll the user by new identification policy.
    307         // So removed the credential provider from the identification policy
    308         //
    309         DeleteProviderFromPolicy (Identity, Offset);
    310         continue;
    311       }
    312     }
    313     Offset += Identity->Length;
    314   }
    315 
    316   return EFI_SUCCESS;
    317 }
    318 
    319 
    320 /**
    321   Check whether the identity policy is valid.
    322 
    323   @param[in]  PolicyInfo          Point to the identity policy.
    324   @param[in]  PolicyInfoLen       The policy length.
    325 
    326   @retval TRUE     The policy is a valid identity policy.
    327   @retval FALSE    The policy is not a valid identity policy.
    328 
    329 **/
    330 BOOLEAN
    331 CheckNewIdentityPolicy (
    332   IN  UINT8                                     *PolicyInfo,
    333   IN  UINTN                                     PolicyInfoLen
    334   )
    335 {
    336   EFI_USER_INFO_IDENTITY_POLICY *Identity;
    337   EFI_INPUT_KEY                 Key;
    338   UINTN                         Offset;
    339   UINT32                        OpCode;
    340 
    341   //
    342   // Check policy expression.
    343   //
    344   OpCode  = EFI_USER_INFO_IDENTITY_FALSE;
    345   Offset  = 0;
    346   while (Offset < PolicyInfoLen) {
    347     //
    348     // Check identification policy according to type
    349     //
    350     Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (PolicyInfo + Offset);
    351     switch (Identity->Type) {
    352 
    353     case EFI_USER_INFO_IDENTITY_TRUE:
    354       break;
    355 
    356     case EFI_USER_INFO_IDENTITY_OR:
    357       if (OpCode == EFI_USER_INFO_IDENTITY_AND) {
    358         CreatePopUp (
    359           EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
    360           &Key,
    361           L"Invalid Identity Policy, Mixed Connector Unsupport!",
    362           L"",
    363           L"Press Any Key to Continue ...",
    364           NULL
    365           );
    366         return FALSE;
    367       }
    368 
    369       OpCode = EFI_USER_INFO_IDENTITY_OR;
    370       break;
    371 
    372     case EFI_USER_INFO_IDENTITY_AND:
    373       if (OpCode == EFI_USER_INFO_IDENTITY_OR) {
    374         CreatePopUp (
    375           EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
    376           &Key,
    377           L"Invalid Identity Policy, Mixed Connector Unsupport!",
    378           L"",
    379           L"Press Any Key to Continue ...",
    380           NULL
    381           );
    382         return FALSE;
    383       }
    384 
    385       OpCode = EFI_USER_INFO_IDENTITY_AND;
    386       break;
    387 
    388     case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER:
    389       break;
    390 
    391     default:
    392       CreatePopUp (
    393         EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
    394         &Key,
    395         L"Unsupport parameter",
    396         L"",
    397         L"Press Any Key to Continue ...",
    398         NULL
    399         );
    400       return FALSE;
    401     }
    402     Offset += Identity->Length;
    403   }
    404 
    405   return TRUE;
    406 }
    407 
    408 
    409 /**
    410   Save the identity policy and update UI with it.
    411 
    412   This function will verify the new identity policy, in current implementation,
    413   the identity policy can be:  T, P & P & P & ..., P | P | P | ...
    414   Here, "T" means "True", "P" means "Credential Provider", "&" means "and", "|" means "or".
    415   Other identity policies are not supported.
    416 
    417 **/
    418 VOID
    419 SaveIdentityPolicy (
    420   VOID
    421   )
    422 {
    423   EFI_STATUS                    Status;
    424   EFI_USER_INFO_HANDLE          UserInfo;
    425   EFI_USER_INFO                 *Info;
    426 
    427   if (!mUserInfo.NewIdentityPolicyModified || (mUserInfo.NewIdentityPolicyLen == 0)) {
    428     return;
    429   }
    430 
    431   //
    432   // Check policy expression.
    433   //
    434   if (!CheckNewIdentityPolicy (mUserInfo.NewIdentityPolicy, mUserInfo.NewIdentityPolicyLen)) {
    435     return;
    436   }
    437 
    438   Status = FindInfoByType (mModifyUser, EFI_USER_INFO_IDENTITY_POLICY_RECORD, &UserInfo);
    439   if (EFI_ERROR (Status)) {
    440     return ;
    441   }
    442 
    443   //
    444   // Update the informantion on credential provider.
    445   //
    446   Status = UpdateCredentialProvider ();
    447   if (EFI_ERROR (Status)) {
    448     return ;
    449   }
    450 
    451   //
    452   // Save new identification policy.
    453   //
    454   Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + mUserInfo.NewIdentityPolicyLen);
    455   ASSERT (Info != NULL);
    456 
    457   Info->InfoType    = EFI_USER_INFO_IDENTITY_POLICY_RECORD;
    458   Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | EFI_USER_INFO_PUBLIC | EFI_USER_INFO_EXCLUSIVE;
    459   Info->InfoSize    = (UINT32) (sizeof (EFI_USER_INFO) + mUserInfo.NewIdentityPolicyLen);
    460   CopyMem ((UINT8 *) (Info + 1), mUserInfo.NewIdentityPolicy, mUserInfo.NewIdentityPolicyLen);
    461 
    462   Status = mUserManager->SetInfo (mUserManager, mModifyUser, &UserInfo, Info, Info->InfoSize);
    463   FreePool (Info);
    464 
    465   //
    466   // Update the mUserInfo.IdentityPolicy by mUserInfo.NewIdentityPolicy
    467   //
    468   if (mUserInfo.IdentityPolicy != NULL) {
    469     FreePool (mUserInfo.IdentityPolicy);
    470   }
    471   mUserInfo.IdentityPolicy    = mUserInfo.NewIdentityPolicy;
    472   mUserInfo.IdentityPolicyLen = mUserInfo.NewIdentityPolicyLen;
    473 
    474   mUserInfo.NewIdentityPolicy         = NULL;
    475   mUserInfo.NewIdentityPolicyLen      = 0;
    476   mUserInfo.NewIdentityPolicyModified = FALSE;
    477 
    478   //
    479   // Update identity policy choice.
    480   //
    481   ResolveIdentityPolicy (mUserInfo.IdentityPolicy, mUserInfo.IdentityPolicyLen, STRING_TOKEN (STR_IDENTIFY_POLICY_VAL));
    482 }
    483 
    484 
    485 /**
    486   Update the mUserInfo.NewIdentityPolicy, and UI when 'add option' is pressed.
    487 
    488 **/
    489 VOID
    490 AddIdentityPolicyItem (
    491   VOID
    492   )
    493 {
    494   if (mProviderInfo->Count == 0) {
    495     return ;
    496   }
    497 
    498   //
    499   // Check the identity policy.
    500   //
    501   if (ProviderAlreadyInPolicy (&mProviderInfo->Provider[mProviderChoice]->Identifier)) {
    502     return;
    503   }
    504 
    505   //
    506   // Add it to identification policy
    507   //
    508   AddProviderToPolicy (&mProviderInfo->Provider[mProviderChoice]->Identifier);
    509 
    510   //
    511   // Update identity policy choice.
    512   //
    513   ResolveIdentityPolicy (mUserInfo.NewIdentityPolicy, mUserInfo.NewIdentityPolicyLen, STRING_TOKEN (STR_IDENTIFY_POLICY_VALUE));
    514 }
    515 
    516 
    517