]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/UserIdentification/UserProfileManagerDxe/ModifyIdentityPolicy.c
ArmPkg/ArmMmuLib ARM: fix thinko in second level page table handling
[mirror_edk2.git] / SecurityPkg / UserIdentification / UserProfileManagerDxe / ModifyIdentityPolicy.c
1 /** @file
2 The functions for identification policy modification.
3
4 Copyright (c) 2009 - 2018, 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