]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/UserIdentification/PwdCredentialProviderDxe/PwdCredentialProvider.c
Update UID drivers to align with latest UEFI spec 2.3.1 errata A.
[mirror_edk2.git] / SecurityPkg / UserIdentification / PwdCredentialProviderDxe / PwdCredentialProvider.c
CommitLineData
0c18794e 1/** @file\r
2 Password Credential Provider driver implementation.\r
3 \r
4Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials \r
6are licensed and made available under the terms and conditions of the BSD License \r
7which accompanies this distribution. The full text of the license may be found at \r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "PwdCredentialProvider.h"\r
16\r
17CREDENTIAL_TABLE *mPwdTable = NULL;\r
18PWD_PROVIDER_CALLBACK_INFO *mCallbackInfo = NULL;\r
19PASSWORD_CREDENTIAL_INFO *mPwdInfoHandle = NULL;\r
20\r
21//\r
22// Used for save password credential and form browser.\r
23// Also used as provider identifier.\r
24//\r
25EFI_GUID mPwdCredentialGuid = PWD_CREDENTIAL_PROVIDER_GUID;\r
26\r
27HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {\r
28 {\r
29 {\r
30 HARDWARE_DEVICE_PATH,\r
31 HW_VENDOR_DP,\r
32 {\r
33 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
34 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
35 }\r
36 },\r
37 { 0xeba7fc2b, 0xa465, 0x4d96, { 0x85, 0xa9, 0xd2, 0xf6, 0x64, 0xdf, 0x9b, 0x45 } } \r
38 },\r
39 {\r
40 END_DEVICE_PATH_TYPE,\r
41 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
42 {\r
43 (UINT8) (END_DEVICE_PATH_LENGTH),\r
44 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
45 }\r
46 }\r
47};\r
48\r
49EFI_USER_CREDENTIAL_PROTOCOL gPwdCredentialProviderDriver = {\r
50 PWD_CREDENTIAL_PROVIDER_GUID,\r
51 EFI_USER_CREDENTIAL_CLASS_PASSWORD,\r
52 CredentialEnroll,\r
53 CredentialForm,\r
54 CredentialTile,\r
55 CredentialTitle,\r
56 CredentialUser,\r
57 CredentialSelect,\r
58 CredentialDeselect,\r
59 CredentialDefault,\r
60 CredentialGetInfo,\r
61 CredentialGetNextInfo\r
62};\r
63\r
64\r
65/**\r
66 Get string by string id from HII Interface.\r
67\r
68\r
69 @param[in] Id String ID to get the string from.\r
70\r
71 @retval CHAR16 * String from ID.\r
72 @retval NULL If error occurs.\r
73\r
74**/\r
75CHAR16 *\r
76GetStringById (\r
77 IN EFI_STRING_ID Id\r
78 )\r
79{\r
80 //\r
81 // Get the current string for the current Language.\r
82 //\r
83 return HiiGetString (mCallbackInfo->HiiHandle, Id, NULL);\r
84}\r
85\r
86\r
87/**\r
88 Expand password table size.\r
89\r
90**/\r
91VOID\r
92ExpandTableSize (\r
93 VOID\r
94 )\r
95{\r
96 CREDENTIAL_TABLE *NewTable;\r
97 UINTN Count;\r
98\r
99 Count = mPwdTable->MaxCount + PASSWORD_TABLE_INC;\r
100 //\r
101 // Create new credential table.\r
102 //\r
103 NewTable = (CREDENTIAL_TABLE *) AllocateZeroPool (\r
104 sizeof (CREDENTIAL_TABLE) + \r
105 (Count - 1) * sizeof (PASSWORD_INFO)\r
106 );\r
107 ASSERT (NewTable != NULL); \r
108\r
109 NewTable->MaxCount = Count;\r
110 NewTable->Count = mPwdTable->Count;\r
111 NewTable->ValidIndex = mPwdTable->ValidIndex;\r
112 //\r
113 // Copy old entries\r
114 //\r
115 CopyMem (\r
116 &NewTable->UserInfo, \r
117 &mPwdTable->UserInfo, \r
118 mPwdTable->Count * sizeof (PASSWORD_INFO)\r
119 );\r
120 FreePool (mPwdTable);\r
121 mPwdTable = NewTable;\r
122}\r
123\r
124\r
125/**\r
126 Add or delete info in table, and sync with NV variable.\r
127\r
128 @param[in] Index The index of the password in table. The index begin from 1.\r
129 If index is found in table, delete the info, else add the \r
130 into to table. \r
131 @param[in] Info The new password info to add into table.\r
132\r
133 @retval EFI_INVALID_PARAMETER Info is NULL when save the info.\r
134 @retval EFI_SUCCESS Modify the table successfully.\r
135 @retval Others Failed to modify the table.\r
136\r
137**/\r
138EFI_STATUS\r
139ModifyTable (\r
140 IN UINTN Index,\r
141 IN PASSWORD_INFO * Info OPTIONAL\r
142 )\r
143{\r
144 EFI_STATUS Status;\r
145 \r
146 if (Index < mPwdTable->Count) {\r
147 //\r
148 // Delete the specified entry.\r
149 //\r
150 mPwdTable->Count--;\r
151 if (Index != mPwdTable->Count) {\r
152 CopyMem (\r
153 &mPwdTable->UserInfo[Index],\r
154 &mPwdTable->UserInfo[mPwdTable->Count],\r
155 sizeof (PASSWORD_INFO)\r
156 );\r
157 }\r
158 } else {\r
159 //\r
160 // Add a new entry.\r
161 //\r
162 if (Info == NULL) {\r
163 return EFI_INVALID_PARAMETER;\r
164 }\r
165\r
166 if (mPwdTable->Count >= mPwdTable->MaxCount) {\r
167 ExpandTableSize ();\r
168 }\r
169\r
170 CopyMem (\r
171 &mPwdTable->UserInfo[mPwdTable->Count], \r
172 Info, \r
173 sizeof (PASSWORD_INFO)\r
174 );\r
175 mPwdTable->Count++;\r
176 }\r
177\r
178 //\r
179 // Save the credential table.\r
180 //\r
181 Status = gRT->SetVariable (\r
182 L"PwdCredential",\r
183 &mPwdCredentialGuid,\r
184 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
185 mPwdTable->Count * sizeof (PASSWORD_INFO),\r
186 &mPwdTable->UserInfo\r
187 );\r
188 return Status;\r
189}\r
190\r
191\r
192/**\r
193 Create a password table.\r
194\r
195 @retval EFI_SUCCESS Create a password table successfully.\r
196 @retval Others Failed to create a password.\r
197\r
198**/\r
199EFI_STATUS\r
200InitCredentialTable (\r
201 VOID\r
202 )\r
203{\r
204 EFI_STATUS Status;\r
205 UINT8 *Var;\r
206 UINTN VarSize;\r
207\r
208 //\r
209 // Get Password credential data from NV variable.\r
210 //\r
211 VarSize = 0;\r
212 Var = NULL;\r
213 Status = gRT->GetVariable (\r
214 L"PwdCredential", \r
215 &mPwdCredentialGuid, \r
216 NULL, \r
217 &VarSize,\r
218 Var\r
219 );\r
220 if (Status == EFI_BUFFER_TOO_SMALL) {\r
221 Var = AllocateZeroPool (VarSize);\r
222 if (Var == NULL) {\r
223 return EFI_OUT_OF_RESOURCES;\r
224 }\r
225 Status = gRT->GetVariable (\r
226 L"PwdCredential", \r
227 &mPwdCredentialGuid, \r
228 NULL, \r
229 &VarSize,\r
230 Var\r
231 );\r
232 }\r
233 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {\r
234 return Status;\r
235 }\r
236 \r
237 //\r
238 // Create the password credential table.\r
239 //\r
240 mPwdTable = AllocateZeroPool (\r
241 sizeof (CREDENTIAL_TABLE) - sizeof (PASSWORD_INFO) +\r
242 PASSWORD_TABLE_INC * sizeof (PASSWORD_INFO) + \r
243 VarSize\r
244 );\r
245 if (mPwdTable == NULL) {\r
246 FreePool (Var);\r
247 return EFI_OUT_OF_RESOURCES;\r
248 }\r
249\r
250 mPwdTable->Count = VarSize / sizeof (PASSWORD_INFO);\r
251 mPwdTable->MaxCount = mPwdTable->Count + PASSWORD_TABLE_INC;\r
252 mPwdTable->ValidIndex = 0;\r
253 if (Var != NULL) {\r
254 CopyMem (mPwdTable->UserInfo, Var, VarSize);\r
255 FreePool (Var);\r
256 }\r
257 return EFI_SUCCESS;\r
258}\r
259\r
260\r
261/**\r
262 Hash the password to get credential.\r
263\r
264 @param[in] Password Points to the input password.\r
265 @param[in] PasswordSize The size of password, in bytes.\r
266 @param[out] Credential Points to the hashed result.\r
267\r
268 @retval TRUE Hash the password successfully.\r
269 @retval FALSE Failed to hash the password.\r
270 \r
271**/\r
272BOOLEAN\r
273GenerateCredential (\r
274 IN CHAR16 *Password,\r
275 IN UINTN PasswordSize,\r
276 OUT UINT8 *Credential\r
277 )\r
278{\r
279 BOOLEAN Status;\r
280 UINTN HashSize;\r
281 VOID *Hash;\r
282 \r
283 HashSize = Sha1GetContextSize ();\r
284 Hash = AllocatePool (HashSize);\r
285 ASSERT (Hash != NULL);\r
286 \r
287 Status = Sha1Init (Hash);\r
288 if (!Status) {\r
289 goto Done;\r
290 }\r
291 \r
292 Status = Sha1Update (Hash, Password, PasswordSize);\r
293 if (!Status) {\r
294 goto Done;\r
295 }\r
296 \r
297 Status = Sha1Final (Hash, Credential);\r
298 \r
299Done:\r
300 FreePool (Hash);\r
301 return Status;\r
302}\r
303\r
304\r
305/**\r
306 Get password from user input.\r
307\r
308 @param[in] FirstPwd If True, prompt to input the first password.\r
309 If False, prompt to input password again.\r
310 @param[out] Credential Points to the input password.\r
311\r
312**/\r
313VOID\r
314GetPassword (\r
315 IN BOOLEAN FirstPwd,\r
316 OUT CHAR8 *Credential\r
317 )\r
318{\r
319 EFI_INPUT_KEY Key;\r
320 CHAR16 PasswordMask[CREDENTIAL_LEN + 1];\r
321 CHAR16 Password[CREDENTIAL_LEN];\r
322 UINTN PasswordLen;\r
323 CHAR16 *QuestionStr;\r
324 CHAR16 *LineStr;\r
325 \r
326 PasswordLen = 0;\r
327 while (TRUE) {\r
328 PasswordMask[PasswordLen] = L'_';\r
329 PasswordMask[PasswordLen + 1] = L'\0';\r
330 LineStr = GetStringById (STRING_TOKEN (STR_DRAW_A_LINE));\r
331 if (FirstPwd) {\r
332 QuestionStr = GetStringById (STRING_TOKEN (STR_INPUT_PASSWORD));\r
333 } else {\r
334 QuestionStr = GetStringById (STRING_TOKEN (STR_INPUT_PASSWORD_AGAIN));\r
335 }\r
336 CreatePopUp (\r
337 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
338 &Key,\r
339 QuestionStr,\r
340 LineStr,\r
341 PasswordMask,\r
342 NULL\r
343 );\r
344 FreePool (QuestionStr);\r
345 FreePool (LineStr);\r
346 \r
347 //\r
348 // Check key stroke\r
349 //\r
350 if (Key.ScanCode == SCAN_NULL) {\r
351 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
352 break;\r
353 } else if (Key.UnicodeChar == CHAR_BACKSPACE) {\r
354 if (PasswordLen > 0) {\r
355 PasswordLen--;\r
356 }\r
357 } else if ((Key.UnicodeChar == CHAR_NULL) || \r
358 (Key.UnicodeChar == CHAR_TAB) || \r
359 (Key.UnicodeChar == CHAR_LINEFEED)) {\r
360 continue;\r
361 } else {\r
362 Password[PasswordLen] = Key.UnicodeChar;\r
363 PasswordMask[PasswordLen] = L'*';\r
364 PasswordLen++;\r
365 if (PasswordLen == CREDENTIAL_LEN) {\r
366 break;\r
367 }\r
368 }\r
369 }\r
370 }\r
371 \r
372 PasswordLen = PasswordLen * sizeof (CHAR16);\r
373 GenerateCredential (Password, PasswordLen, (UINT8 *)Credential);\r
374}\r
375\r
376/**\r
377 Check whether the password can be found on this provider.\r
378\r
379 @param[in] Password The password to be found.\r
380\r
381 @retval EFI_SUCCESS Found password sucessfully.\r
382 @retval EFI_NOT_FOUND Fail to find the password.\r
383\r
384**/\r
385EFI_STATUS\r
386CheckPassword (\r
387 IN CHAR8 *Password\r
388 )\r
389{\r
390 UINTN Index;\r
391 CHAR8 *Pwd;\r
392 \r
393 //\r
394 // Check password credential.\r
395 //\r
396 mPwdTable->ValidIndex = 0;\r
397 for (Index = 0; Index < mPwdTable->Count; Index++) {\r
398 Pwd = mPwdTable->UserInfo[Index].Password;\r
399 if (CompareMem (Pwd, Password, CREDENTIAL_LEN) == 0) {\r
400 mPwdTable->ValidIndex = Index + 1;\r
401 return EFI_SUCCESS;\r
402 }\r
403 }\r
404\r
405 return EFI_NOT_FOUND;\r
406}\r
407\r
408\r
409/**\r
410 Find a user infomation record by the information record type.\r
411\r
412 This function searches all user information records of User from beginning \r
413 until either the information is found, or there are no more user infomation\r
414 records. A match occurs when a Info.InfoType field matches the user information\r
415 record type.\r
416\r
417 @param[in] User Points to the user profile record to search. \r
418 @param[in] InfoType The infomation type to be searched.\r
419 @param[out] Info Points to the user info found, the caller is responsible\r
420 to free.\r
421 \r
422 @retval EFI_SUCCESS Find the user information successfully.\r
423 @retval Others Fail to find the user information.\r
424\r
425**/\r
426EFI_STATUS\r
427FindUserInfoByType (\r
428 IN EFI_USER_PROFILE_HANDLE User,\r
429 IN UINT8 InfoType,\r
430 OUT EFI_USER_INFO **Info\r
431 )\r
432{\r
433 EFI_STATUS Status;\r
434 EFI_USER_INFO *UserInfo;\r
435 UINTN UserInfoSize;\r
436 EFI_USER_INFO_HANDLE UserInfoHandle;\r
437 EFI_USER_MANAGER_PROTOCOL *UserManager;\r
438 \r
439 //\r
440 // Find user information by information type.\r
441 //\r
442 if (Info == NULL) {\r
443 return EFI_INVALID_PARAMETER;\r
444 }\r
445\r
446 Status = gBS->LocateProtocol (\r
447 &gEfiUserManagerProtocolGuid,\r
448 NULL,\r
449 (VOID **) &UserManager\r
450 );\r
451 if (EFI_ERROR (Status)) {\r
452 return EFI_NOT_FOUND;\r
453 }\r
454\r
455 //\r
456 // Get each user information.\r
457 //\r
458\r
459 UserInfoHandle = NULL;\r
460 UserInfo = NULL;\r
461 UserInfoSize = 0;\r
462 while (TRUE) {\r
463 Status = UserManager->GetNextInfo (UserManager, User, &UserInfoHandle);\r
464 if (EFI_ERROR (Status)) {\r
465 break;\r
466 }\r
467 //\r
468 // Get information.\r
469 //\r
470 Status = UserManager->GetInfo (\r
471 UserManager,\r
472 User,\r
473 UserInfoHandle,\r
474 UserInfo,\r
475 &UserInfoSize\r
476 );\r
477 if (Status == EFI_BUFFER_TOO_SMALL) {\r
478 if (UserInfo != NULL) {\r
479 FreePool (UserInfo);\r
480 }\r
481 UserInfo = AllocateZeroPool (UserInfoSize);\r
482 if (UserInfo == NULL) {\r
483 return EFI_OUT_OF_RESOURCES;\r
484 }\r
485 Status = UserManager->GetInfo (\r
486 UserManager,\r
487 User,\r
488 UserInfoHandle,\r
489 UserInfo,\r
490 &UserInfoSize\r
491 );\r
492 }\r
493 if (EFI_ERROR (Status)) {\r
494 break;\r
495 }\r
496\r
497 ASSERT (UserInfo != NULL);\r
498 if (UserInfo->InfoType == InfoType) {\r
499 *Info = UserInfo;\r
500 return EFI_SUCCESS;\r
501 } \r
502 }\r
503\r
504 if (UserInfo != NULL) {\r
505 FreePool (UserInfo);\r
506 }\r
507 return Status;\r
508}\r
509\r
510\r
511/**\r
512 This function processes the results of changes in configuration.\r
513\r
514 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
515 @param Action Specifies the type of action taken by the browser.\r
516 @param QuestionId A unique value which is sent to the original\r
517 exporting driver so that it can identify the type\r
518 of data to expect.\r
519 @param Type The type of value for the question.\r
520 @param Value A pointer to the data being sent to the original\r
521 exporting driver.\r
522 @param ActionRequest On return, points to the action requested by the\r
523 callback function.\r
524\r
525 @retval EFI_SUCCESS The callback successfully handled the action.\r
526 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
527 variable and its data.\r
528 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
529 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
530 callback.\r
531\r
532**/\r
533EFI_STATUS\r
534EFIAPI\r
535CredentialDriverCallback (\r
536 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
537 IN EFI_BROWSER_ACTION Action,\r
538 IN EFI_QUESTION_ID QuestionId,\r
539 IN UINT8 Type,\r
540 IN EFI_IFR_TYPE_VALUE *Value,\r
541 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
542 )\r
543{\r
544 EFI_STATUS Status;\r
545 EFI_INPUT_KEY Key;\r
546 CHAR8 Password[CREDENTIAL_LEN];\r
547 CHAR16 *PromptStr;\r
548\r
549 if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
550 if (QuestionId == KEY_GET_PASSWORD) {\r
551 //\r
552 // Get and check password.\r
553 //\r
554 GetPassword (TRUE, Password);\r
555 Status = CheckPassword (Password);\r
556 if (EFI_ERROR (Status)) {\r
557 PromptStr = GetStringById (STRING_TOKEN (STR_PASSWORD_INCORRECT));\r
558 CreatePopUp (\r
559 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
560 &Key,\r
561 L"",\r
562 PromptStr,\r
563 L"",\r
564 NULL\r
565 );\r
566 FreePool (PromptStr);\r
567 return Status;\r
568 }\r
569 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
570 } \r
571 return EFI_SUCCESS;\r
572 }\r
573\r
574 //\r
575 // All other action return unsupported.\r
576 //\r
577 return EFI_UNSUPPORTED;\r
578}\r
579\r
580\r
581/**\r
582 This function allows a caller to extract the current configuration for one\r
583 or more named elements from the target driver.\r
584\r
585\r
586 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
587 @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
588 @param Progress On return, points to a character in the Request string.\r
589 Points to the string's null terminator if request was successful.\r
590 Points to the most recent '&' before the first failing name/value\r
591 pair (or the beginning of the string if the failure is in the\r
592 first name/value pair) if the request was not successful.\r
593 @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
594 has all values filled in for the names in the Request string.\r
595 String to be allocated by the called function.\r
596\r
597 @retval EFI_SUCCESS The Results is filled with the requested values.\r
598 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
599 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
600 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
601\r
602**/\r
603EFI_STATUS\r
604EFIAPI\r
605FakeExtractConfig (\r
606 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
607 IN CONST EFI_STRING Request,\r
608 OUT EFI_STRING *Progress,\r
609 OUT EFI_STRING *Results\r
610 )\r
611{\r
612 if (Progress == NULL || Results == NULL) {\r
613 return EFI_INVALID_PARAMETER;\r
614 }\r
615 *Progress = Request;\r
616 return EFI_NOT_FOUND;\r
617}\r
618\r
619/**\r
620 This function processes the results of changes in configuration.\r
621\r
622\r
623 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
624 @param Configuration A null-terminated Unicode string in <ConfigResp> format.\r
625 @param Progress A pointer to a string filled in with the offset of the most\r
626 recent '&' before the first failing name/value pair (or the\r
627 beginning of the string if the failure is in the first\r
628 name/value pair) or the terminating NULL if all was successful.\r
629\r
630 @retval EFI_SUCCESS The Results is processed successfully.\r
631 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
632 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
633\r
634**/\r
635EFI_STATUS\r
636EFIAPI\r
637FakeRouteConfig (\r
638 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
639 IN CONST EFI_STRING Configuration,\r
640 OUT EFI_STRING *Progress\r
641 )\r
642{\r
643 if (Configuration == NULL || Progress == NULL) {\r
644 return EFI_INVALID_PARAMETER;\r
645 }\r
646\r
647 return EFI_NOT_FOUND;\r
648}\r
649\r
650/**\r
651 This function initialize the data mainly used in form browser.\r
652\r
653 @retval EFI_SUCCESS Initialize form data successfully.\r
654 @retval Others Fail to Initialize form data.\r
655\r
656**/\r
657EFI_STATUS\r
658InitFormBrowser (\r
659 VOID\r
660 )\r
661{\r
662 EFI_STATUS Status;\r
663 PWD_PROVIDER_CALLBACK_INFO *CallbackInfo;\r
664\r
665 //\r
666 // Initialize driver private data.\r
667 //\r
668 CallbackInfo = AllocateZeroPool (sizeof (PWD_PROVIDER_CALLBACK_INFO));\r
669 if (CallbackInfo == NULL) {\r
670 return EFI_OUT_OF_RESOURCES;\r
671 }\r
672\r
673 CallbackInfo->Signature = PWD_PROVIDER_SIGNATURE;\r
674 CallbackInfo->ConfigAccess.ExtractConfig = FakeExtractConfig;\r
675 CallbackInfo->ConfigAccess.RouteConfig = FakeRouteConfig;\r
676 CallbackInfo->ConfigAccess.Callback = CredentialDriverCallback;\r
677 CallbackInfo->DriverHandle = NULL;\r
678\r
679 //\r
680 // Install Device Path Protocol and Config Access protocol to driver handle.\r
681 //\r
682 Status = gBS->InstallMultipleProtocolInterfaces (\r
683 &CallbackInfo->DriverHandle,\r
684 &gEfiDevicePathProtocolGuid,\r
685 &mHiiVendorDevicePath,\r
686 &gEfiHiiConfigAccessProtocolGuid,\r
687 &CallbackInfo->ConfigAccess,\r
688 NULL\r
689 );\r
690 ASSERT_EFI_ERROR (Status);\r
691\r
692 //\r
693 // Publish HII data.\r
694 //\r
695 CallbackInfo->HiiHandle = HiiAddPackages (\r
696 &mPwdCredentialGuid,\r
697 CallbackInfo->DriverHandle,\r
698 PwdCredentialProviderStrings,\r
699 PwdCredentialProviderVfrBin,\r
700 NULL\r
701 );\r
702 if (CallbackInfo->HiiHandle == NULL) {\r
703 return EFI_OUT_OF_RESOURCES;\r
704 }\r
705 mCallbackInfo = CallbackInfo;\r
706\r
707 return Status;\r
708}\r
709\r
710\r
711/**\r
712 Enroll a user on a credential provider.\r
713\r
714 This function enrolls and deletes a user profile using this credential provider. \r
715 If a user profile is successfully enrolled, it calls the User Manager Protocol \r
716 function Notify() to notify the user manager driver that credential information \r
717 has changed. If an enrolled user does exist, delete the user on the credential \r
718 provider.\r
719 \r
720 @param[in] This Points to this instance of EFI_USER_CREDENTIAL_PROTOCOL.\r
721 @param[in] User The user profile to enroll.\r
722 \r
723 @retval EFI_SUCCESS User profile was successfully enrolled.\r
724 @retval EFI_ACCESS_DENIED Current user profile does not permit enrollment on the\r
725 user profile handle. Either the user profile cannot enroll\r
726 on any user profile or cannot enroll on a user profile \r
727 other than the current user profile.\r
728 @retval EFI_UNSUPPORTED This credential provider does not support enrollment in\r
729 the pre-OS.\r
730 @retval EFI_DEVICE_ERROR The new credential could not be created because of a device\r
731 error.\r
732 @retval EFI_INVALID_PARAMETER User does not refer to a valid user profile handle.\r
733 \r
734**/\r
735EFI_STATUS\r
736EFIAPI\r
737CredentialEnroll (\r
738 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,\r
739 IN EFI_USER_PROFILE_HANDLE User\r
740 )\r
741{\r
742 EFI_STATUS Status;\r
743 UINTN Index;\r
744 PASSWORD_INFO PwdInfo;\r
745 EFI_USER_INFO *UserInfo;\r
746 CHAR8 Password[CREDENTIAL_LEN];\r
747 EFI_INPUT_KEY Key;\r
748 EFI_USER_MANAGER_PROTOCOL *UserManager;\r
749 UINT8 *UserId;\r
750 UINT8 *NewUserId;\r
751 CHAR16 *QuestionStr;\r
752 CHAR16 *PromptStr;\r
753\r
754 if ((This == NULL) || (User == NULL)) {\r
755 return EFI_INVALID_PARAMETER;\r
756 }\r
757\r
758 Status = gBS->LocateProtocol (\r
759 &gEfiUserManagerProtocolGuid,\r
760 NULL,\r
761 (VOID **) &UserManager\r
762 );\r
763 if (EFI_ERROR (Status)) {\r
764 return EFI_UNSUPPORTED;\r
765 }\r
766\r
767 //\r
768 // Get User Identifier.\r
769 //\r
770 UserInfo = NULL;\r
771 Status = FindUserInfoByType (\r
772 User,\r
773 EFI_USER_INFO_IDENTIFIER_RECORD,\r
774 &UserInfo\r
775 );\r
776 if (EFI_ERROR (Status)) {\r
777 return EFI_INVALID_PARAMETER;\r
778 }\r
779\r
780 //\r
781 // If User exists in mPwdTable, delete User.\r
782 // \r
783 for (Index = 0; Index < mPwdTable->Count; Index++) {\r
784 UserId = (UINT8 *) &mPwdTable->UserInfo[Index].UserId;\r
785 NewUserId = (UINT8 *) (UserInfo + 1);\r
786 if (CompareMem (UserId, NewUserId, sizeof (EFI_USER_INFO_IDENTIFIER)) == 0) {\r
787 //\r
788 // Delete the existing password.\r
789 //\r
790 FreePool (UserInfo);\r
791 return ModifyTable (Index, NULL);\r
792 }\r
793 }\r
794\r
795 //\r
796 // The User doesn't exist in mPwdTable; Enroll the new User.\r
797 // \r
798 while (TRUE) {\r
799 //\r
800 // Input password.\r
801 //\r
802 GetPassword (TRUE, PwdInfo.Password);\r
803\r
804 //\r
805 // Input password again.\r
806 //\r
807 GetPassword (FALSE, Password);\r
808\r
809 //\r
810 // Compare the two password consistency.\r
811 //\r
812 if (CompareMem (PwdInfo.Password, Password, CREDENTIAL_LEN) == 0) {\r
813 break;\r
814 } \r
815\r
816 QuestionStr = GetStringById (STRING_TOKEN (STR_PASSWORD_MISMATCH));\r
817 PromptStr = GetStringById (STRING_TOKEN (STR_INPUT_PASSWORD_AGAIN)); \r
818 CreatePopUp (\r
819 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
820 &Key,\r
821 QuestionStr,\r
822 L"",\r
823 PromptStr,\r
824 NULL\r
825 );\r
826 FreePool (QuestionStr);\r
827 FreePool (PromptStr);\r
828 }\r
829\r
830 CopyMem (\r
831 PwdInfo.UserId, \r
832 (UINT8 *) (UserInfo + 1), \r
833 sizeof (EFI_USER_INFO_IDENTIFIER)\r
834 ); \r
835 FreePool (UserInfo);\r
836 \r
837 //\r
838 // Save the new added entry.\r
839 //\r
840 Status = ModifyTable (mPwdTable->Count, &PwdInfo);\r
841 if (EFI_ERROR (Status)) {\r
842 return Status;\r
843 }\r
844\r
845 //\r
846 // Notify the user manager driver that credential information has changed.\r
847 //\r
848 UserManager->Notify (UserManager, mCallbackInfo->DriverHandle); \r
849\r
850 return EFI_SUCCESS;\r
851}\r
852\r
853\r
854/**\r
855 Returns the user interface information used during user identification.\r
856\r
857 This function returns information about the form used when interacting with the\r
858 user during user identification. The form is the first enabled form in the form-set\r
859 class EFI_HII_USER_CREDENTIAL_FORMSET_GUID installed on the HII handle HiiHandle. If \r
860 the user credential provider does not require a form to identify the user, then this\r
861 function should return EFI_NOT_FOUND.\r
862\r
863 @param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.\r
864 @param[out] Hii On return, holds the HII database handle.\r
865 @param[out] FormSetId On return, holds the identifier of the form set which contains\r
866 the form used during user identification.\r
867 @param[out] FormId On return, holds the identifier of the form used during user \r
868 identification.\r
869 \r
870 @retval EFI_SUCCESS Form returned successfully.\r
871 @retval EFI_NOT_FOUND Form not returned.\r
872 @retval EFI_INVALID_PARAMETER Hii is NULL or FormSetId is NULL or FormId is NULL.\r
873 \r
874**/\r
875EFI_STATUS\r
876EFIAPI\r
877CredentialForm (\r
878 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,\r
879 OUT EFI_HII_HANDLE *Hii,\r
880 OUT EFI_GUID *FormSetId,\r
881 OUT EFI_FORM_ID *FormId\r
882 )\r
883{\r
884 if ((This == NULL) || (Hii == NULL) || \r
885 (FormSetId == NULL) || (FormId == NULL)) {\r
886 return EFI_INVALID_PARAMETER;\r
887 }\r
888\r
889 *Hii = mCallbackInfo->HiiHandle;\r
890 *FormId = FORMID_GET_PASSWORD_FORM;\r
891 CopyGuid (FormSetId, &mPwdCredentialGuid);\r
892 \r
893 return EFI_SUCCESS;\r
894}\r
895\r
896\r
897/**\r
898 Returns bitmap used to describe the credential provider type.\r
899\r
900 This optional function returns a bitmap that is less than or equal to the number\r
901 of pixels specified by Width and Height. If no such bitmap exists, then EFI_NOT_FOUND\r
902 is returned. \r
903\r
904 @param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.\r
905 @param[in, out] Width On entry, points to the desired bitmap width. If NULL then no \r
906 bitmap information will be returned. On exit, points to the \r
907 width of the bitmap returned.\r
908 @param[in, out] Height On entry, points to the desired bitmap height. If NULL then no\r
909 bitmap information will be returned. On exit, points to the \r
910 height of the bitmap returned\r
911 @param[out] Hii On return, holds the HII database handle. \r
912 @param[out] Image On return, holds the HII image identifier. \r
913 \r
914 @retval EFI_SUCCESS Image identifier returned successfully.\r
915 @retval EFI_NOT_FOUND Image identifier not returned.\r
916 @retval EFI_INVALID_PARAMETER Hii is NULL or Image is NULL.\r
917 \r
918**/\r
919EFI_STATUS\r
920EFIAPI\r
921CredentialTile (\r
922 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,\r
923 IN OUT UINTN *Width,\r
924 IN OUT UINTN *Height,\r
925 OUT EFI_HII_HANDLE *Hii,\r
926 OUT EFI_IMAGE_ID *Image\r
927 )\r
928{ \r
929 if ((This == NULL) || (Hii == NULL) || (Image == NULL)) {\r
930 return EFI_INVALID_PARAMETER;\r
931 }\r
932 return EFI_NOT_FOUND;\r
933}\r
934\r
935\r
936/**\r
937 Returns string used to describe the credential provider type.\r
938\r
939 This function returns a string which describes the credential provider. If no\r
940 such string exists, then EFI_NOT_FOUND is returned. \r
941\r
942 @param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.\r
943 @param[out] Hii On return, holds the HII database handle.\r
944 @param[out] String On return, holds the HII string identifier.\r
945 \r
946 @retval EFI_SUCCESS String identifier returned successfully.\r
947 @retval EFI_NOT_FOUND String identifier not returned.\r
948 @retval EFI_INVALID_PARAMETER Hii is NULL or String is NULL.\r
949 \r
950**/\r
951EFI_STATUS\r
952EFIAPI\r
953CredentialTitle (\r
954 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,\r
955 OUT EFI_HII_HANDLE *Hii,\r
956 OUT EFI_STRING_ID *String\r
957 )\r
958{\r
959 if ((This == NULL) || (Hii == NULL) || (String == NULL)) {\r
960 return EFI_INVALID_PARAMETER;\r
961 }\r
962 \r
963 //\r
964 // Set Hii handle and String ID.\r
965 //\r
966 *Hii = mCallbackInfo->HiiHandle;\r
967 *String = STRING_TOKEN (STR_CREDENTIAL_TITLE);\r
968\r
969 return EFI_SUCCESS;\r
970}\r
971\r
972\r
973/**\r
974 Return the user identifier associated with the currently authenticated user.\r
975\r
976 This function returns the user identifier of the user authenticated by this credential\r
977 provider. This function is called after the credential-related information has been \r
978 submitted on a form, OR after a call to Default() has returned that this credential is\r
979 ready to log on.\r
980\r
981 @param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.\r
982 @param[in] User The user profile handle of the user profile currently being \r
983 considered by the user identity manager. If NULL, then no user\r
984 profile is currently under consideration.\r
985 @param[out] Identifier On return, points to the user identifier. \r
986 \r
987 @retval EFI_SUCCESS User identifier returned successfully.\r
988 @retval EFI_NOT_READY No user identifier can be returned.\r
989 @retval EFI_ACCESS_DENIED The user has been locked out of this user credential.\r
990 @retval EFI_INVALID_PARAMETER This is NULL, or Identifier is NULL.\r
991 @retval EFI_NOT_FOUND User is not NULL, and the specified user handle can't be\r
992 found in user profile database\r
993 \r
994**/\r
995EFI_STATUS\r
996EFIAPI\r
997CredentialUser (\r
998 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,\r
999 IN EFI_USER_PROFILE_HANDLE User,\r
1000 OUT EFI_USER_INFO_IDENTIFIER *Identifier\r
1001 )\r
1002{\r
1003 EFI_STATUS Status;\r
1004 UINTN Index;\r
1005 EFI_USER_INFO *UserInfo;\r
1006 UINT8 *UserId;\r
1007 UINT8 *NewUserId;\r
1008 CHAR8 *Pwd;\r
1009 CHAR8 *NewPwd;\r
1010\r
1011 if ((This == NULL) || (Identifier == NULL)) {\r
1012 return EFI_INVALID_PARAMETER;\r
1013 }\r
1014\r
1015 if (mPwdTable->ValidIndex == 0) {\r
1016 //\r
1017 // No password input, or the input password doesn't match\r
1018 // anyone in PwdTable.\r
1019 //\r
1020 return EFI_NOT_READY;\r
1021 }\r
1022 \r
1023 if (User == NULL) {\r
1024 //\r
1025 // Return the user ID whose password matches the input password.\r
1026 // \r
1027 CopyMem (\r
1028 Identifier, \r
1029 &mPwdTable->UserInfo[mPwdTable->ValidIndex - 1].UserId, \r
1030 sizeof (EFI_USER_INFO_IDENTIFIER)\r
1031 ); \r
1032 return EFI_SUCCESS;\r
1033 }\r
1034 \r
1035 //\r
1036 // Get the User's ID.\r
1037 //\r
1038 Status = FindUserInfoByType (\r
1039 User,\r
1040 EFI_USER_INFO_IDENTIFIER_RECORD,\r
1041 &UserInfo\r
1042 );\r
1043 if (EFI_ERROR (Status)) {\r
1044 return EFI_NOT_FOUND;\r
1045 }\r
1046 \r
1047 //\r
1048 // Check whether the input password matches one in PwdTable.\r
1049 //\r
1050 for (Index = 0; Index < mPwdTable->Count; Index++) {\r
1051 UserId = (UINT8 *) &mPwdTable->UserInfo[Index].UserId;\r
1052 NewUserId = (UINT8 *) (UserInfo + 1);\r
1053 if (CompareMem (UserId, NewUserId, sizeof (EFI_USER_INFO_IDENTIFIER)) == 0) {\r
1054 Pwd = mPwdTable->UserInfo[Index].Password;\r
1055 NewPwd = mPwdTable->UserInfo[mPwdTable->ValidIndex - 1].Password;\r
1056 if (CompareMem (Pwd, NewPwd, CREDENTIAL_LEN) == 0) {\r
1057 CopyMem (Identifier, UserId, sizeof (EFI_USER_INFO_IDENTIFIER));\r
1058 FreePool (UserInfo);\r
1059 return EFI_SUCCESS;\r
1060 } \r
1061 }\r
1062 }\r
1063\r
0c18794e 1064 FreePool (UserInfo); \r
ae4cb94f 1065 return EFI_NOT_READY;\r
0c18794e 1066}\r
1067\r
1068\r
1069/**\r
1070 Indicate that user interface interaction has begun for the specified credential.\r
1071\r
1072 This function is called when a credential provider is selected by the user. If \r
1073 AutoLogon returns FALSE, then the user interface will be constructed by the User\r
1074 Identity Manager. \r
1075\r
1076 @param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.\r
1077 @param[out] AutoLogon On return, points to the credential provider's capabilities \r
1078 after the credential provider has been selected by the user. \r
1079 \r
1080 @retval EFI_SUCCESS Credential provider successfully selected.\r
1081 @retval EFI_INVALID_PARAMETER AutoLogon is NULL.\r
1082 \r
1083**/\r
1084EFI_STATUS\r
1085EFIAPI\r
1086CredentialSelect (\r
1087 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,\r
1088 OUT EFI_CREDENTIAL_LOGON_FLAGS *AutoLogon\r
1089 )\r
1090{\r
1091 if ((This == NULL) || (AutoLogon == NULL)) {\r
1092 return EFI_INVALID_PARAMETER;\r
1093 }\r
1094 *AutoLogon = 0;\r
1095\r
1096 return EFI_SUCCESS;\r
1097}\r
1098\r
1099\r
1100/**\r
1101 Indicate that user interface interaction has ended for the specified credential.\r
1102\r
1103 This function is called when a credential provider is deselected by the user.\r
1104\r
1105 @param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.\r
1106 \r
1107 @retval EFI_SUCCESS Credential provider successfully deselected.\r
1108 \r
1109**/\r
1110EFI_STATUS\r
1111EFIAPI\r
1112CredentialDeselect (\r
1113 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This\r
1114 )\r
1115{\r
1116 if (This == NULL) {\r
1117 return EFI_INVALID_PARAMETER;\r
1118 }\r
1119 return EFI_SUCCESS;\r
1120}\r
1121\r
1122\r
1123/**\r
1124 Return the default logon behavior for this user credential.\r
1125\r
1126 This function reports the default login behavior regarding this credential provider. \r
1127\r
1128 @param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.\r
1129 @param[out] AutoLogon On return, holds whether the credential provider should be used\r
1130 by default to automatically log on the user. \r
1131 \r
1132 @retval EFI_SUCCESS Default information successfully returned.\r
1133 @retval EFI_INVALID_PARAMETER AutoLogon is NULL.\r
1134 \r
1135**/\r
1136EFI_STATUS\r
1137EFIAPI\r
1138CredentialDefault (\r
1139 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,\r
1140 OUT EFI_CREDENTIAL_LOGON_FLAGS *AutoLogon\r
1141 )\r
1142{\r
1143 if ((This == NULL) || (AutoLogon == NULL)) {\r
1144 return EFI_INVALID_PARAMETER;\r
1145 }\r
1146 *AutoLogon = 0;\r
1147 \r
1148 return EFI_SUCCESS;\r
1149}\r
1150\r
1151\r
1152/**\r
1153 Return information attached to the credential provider.\r
1154\r
1155 This function returns user information. \r
1156\r
1157 @param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.\r
1158 @param[in] UserInfo Handle of the user information data record. \r
1159 @param[out] Info On entry, points to a buffer of at least *InfoSize bytes. On\r
1160 exit, holds the user information. If the buffer is too small\r
1161 to hold the information, then EFI_BUFFER_TOO_SMALL is returned\r
1162 and InfoSize is updated to contain the number of bytes actually\r
1163 required.\r
1164 @param[in, out] InfoSize On entry, points to the size of Info. On return, points to the \r
1165 size of the user information. \r
1166 \r
1167 @retval EFI_SUCCESS Information returned successfully.\r
1168 @retval EFI_BUFFER_TOO_SMALL The size specified by InfoSize is too small to hold all of the\r
1169 user information. The size required is returned in *InfoSize.\r
1170 @retval EFI_INVALID_PARAMETER Info is NULL or InfoSize is NULL.\r
1171 @retval EFI_NOT_FOUND The specified UserInfo does not refer to a valid user info handle. \r
1172 \r
1173**/\r
1174EFI_STATUS\r
1175EFIAPI\r
1176CredentialGetInfo (\r
1177 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,\r
1178 IN EFI_USER_INFO_HANDLE UserInfo,\r
1179 OUT EFI_USER_INFO *Info,\r
1180 IN OUT UINTN *InfoSize\r
1181 )\r
1182{\r
1183 EFI_USER_INFO *CredentialInfo;\r
1184 UINTN Index;\r
1185 \r
1186 if ((This == NULL) || (InfoSize == NULL) || (Info == NULL)) {\r
1187 return EFI_INVALID_PARAMETER;\r
1188 }\r
1189\r
1190 if ((UserInfo == NULL) || (mPwdInfoHandle == NULL)) {\r
1191 return EFI_NOT_FOUND;\r
1192 }\r
1193 \r
1194 //\r
1195 // Find information handle in credential info table.\r
1196 //\r
1197 for (Index = 0; Index < mPwdInfoHandle->Count; Index++) {\r
1198 CredentialInfo = mPwdInfoHandle->Info[Index];\r
1199 if (UserInfo == (EFI_USER_INFO_HANDLE)CredentialInfo) {\r
1200 //\r
1201 // The handle is found, copy the user info.\r
1202 //\r
1203 if (CredentialInfo->InfoSize > *InfoSize) {\r
1204 *InfoSize = CredentialInfo->InfoSize;\r
1205 return EFI_BUFFER_TOO_SMALL;\r
1206 }\r
1207 CopyMem (Info, CredentialInfo, CredentialInfo->InfoSize); \r
1208 return EFI_SUCCESS; \r
1209 }\r
1210 }\r
1211 \r
1212 return EFI_NOT_FOUND;\r
1213}\r
1214\r
1215\r
1216/**\r
1217 Enumerate all of the user informations on the credential provider.\r
1218\r
1219 This function returns the next user information record. To retrieve the first user\r
1220 information record handle, point UserInfo at a NULL. Each subsequent call will retrieve\r
1221 another user information record handle until there are no more, at which point UserInfo\r
1222 will point to NULL. \r
1223\r
1224 @param[in] This Points to this instance of the EFI_USER_CREDENTIAL_PROTOCOL.\r
1225 @param[in, out] UserInfo On entry, points to the previous user information handle or NULL\r
1226 to start enumeration. On exit, points to the next user information\r
1227 handle or NULL if there is no more user information.\r
1228 \r
1229 @retval EFI_SUCCESS User information returned.\r
1230 @retval EFI_NOT_FOUND No more user information found.\r
1231 @retval EFI_INVALID_PARAMETER UserInfo is NULL.\r
1232 \r
1233**/\r
1234EFI_STATUS\r
1235EFIAPI\r
1236CredentialGetNextInfo (\r
1237 IN CONST EFI_USER_CREDENTIAL_PROTOCOL *This,\r
1238 IN OUT EFI_USER_INFO_HANDLE *UserInfo\r
1239 )\r
1240{\r
1241 EFI_USER_INFO *Info;\r
1242 CHAR16 *ProvNameStr;\r
1243 UINTN InfoLen;\r
1244 UINTN Index;\r
1245 UINTN ProvStrLen;\r
1246 \r
1247 if ((This == NULL) || (UserInfo == NULL)) {\r
1248 return EFI_INVALID_PARAMETER;\r
1249 }\r
1250\r
1251 if (mPwdInfoHandle == NULL) {\r
1252 //\r
1253 // Initilized user info table. There are 4 user info records in the table.\r
1254 //\r
1255 InfoLen = sizeof (PASSWORD_CREDENTIAL_INFO) + (4 - 1) * sizeof (EFI_USER_INFO *);\r
1256 mPwdInfoHandle = AllocateZeroPool (InfoLen);\r
1257 if (mPwdInfoHandle == NULL) {\r
1258 *UserInfo = NULL;\r
1259 return EFI_NOT_FOUND;\r
1260 }\r
1261\r
1262 //\r
1263 // The first information, Credential Provider info.\r
1264 //\r
1265 InfoLen = sizeof (EFI_USER_INFO) + sizeof (EFI_GUID);\r
1266 Info = AllocateZeroPool (InfoLen);\r
1267 ASSERT (Info != NULL);\r
1268 \r
1269 Info->InfoType = EFI_USER_INFO_CREDENTIAL_PROVIDER_RECORD;\r
1270 Info->InfoSize = (UINT32) InfoLen;\r
1271 Info->InfoAttribs = EFI_USER_INFO_PROTECTED;\r
1272 CopyGuid (&Info->Credential, &mPwdCredentialGuid);\r
1273 CopyGuid ((EFI_GUID *)(Info + 1), &mPwdCredentialGuid);\r
1274 \r
1275 mPwdInfoHandle->Info[0] = Info;\r
1276 mPwdInfoHandle->Count++;\r
1277\r
1278 //\r
1279 // The second information, Credential Provider name info.\r
1280 //\r
1281 ProvNameStr = GetStringById (STRING_TOKEN (STR_PROVIDER_NAME));\r
1282 ProvStrLen = StrSize (ProvNameStr);\r
1283 InfoLen = sizeof (EFI_USER_INFO) + ProvStrLen;\r
1284 Info = AllocateZeroPool (InfoLen);\r
1285 ASSERT (Info != NULL);\r
1286 \r
1287 Info->InfoType = EFI_USER_INFO_CREDENTIAL_PROVIDER_NAME_RECORD;\r
1288 Info->InfoSize = (UINT32) InfoLen;\r
1289 Info->InfoAttribs = EFI_USER_INFO_PROTECTED;\r
1290 CopyGuid (&Info->Credential, &mPwdCredentialGuid);\r
1291 CopyMem ((UINT8*)(Info + 1), ProvNameStr, ProvStrLen);\r
1292 FreePool (ProvNameStr);\r
1293\r
1294 mPwdInfoHandle->Info[1] = Info;\r
1295 mPwdInfoHandle->Count++;\r
1296\r
1297 //\r
1298 // The third information, Credential Provider type info.\r
1299 //\r
1300 InfoLen = sizeof (EFI_USER_INFO) + sizeof (EFI_GUID);\r
1301 Info = AllocateZeroPool (InfoLen);\r
1302 ASSERT (Info != NULL);\r
1303 \r
1304 Info->InfoType = EFI_USER_INFO_CREDENTIAL_TYPE_RECORD;\r
1305 Info->InfoSize = (UINT32) InfoLen;\r
1306 Info->InfoAttribs = EFI_USER_INFO_PROTECTED;\r
1307 CopyGuid (&Info->Credential, &mPwdCredentialGuid);\r
1308 CopyGuid ((EFI_GUID *)(Info + 1), &gEfiUserCredentialClassPasswordGuid);\r
1309 \r
1310 mPwdInfoHandle->Info[2] = Info;\r
1311 mPwdInfoHandle->Count++;\r
1312 \r
1313 //\r
1314 // The fourth information, Credential Provider type name info.\r
1315 //\r
1316 ProvNameStr = GetStringById (STRING_TOKEN (STR_PROVIDER_TYPE_NAME));\r
1317 ProvStrLen = StrSize (ProvNameStr);\r
1318 InfoLen = sizeof (EFI_USER_INFO) + ProvStrLen;\r
1319 Info = AllocateZeroPool (InfoLen);\r
1320 ASSERT (Info != NULL);\r
1321 \r
1322 Info->InfoType = EFI_USER_INFO_CREDENTIAL_PROVIDER_NAME_RECORD;\r
1323 Info->InfoSize = (UINT32) InfoLen;\r
1324 Info->InfoAttribs = EFI_USER_INFO_PROTECTED;\r
1325 CopyGuid (&Info->Credential, &mPwdCredentialGuid);\r
1326 CopyMem ((UINT8*)(Info + 1), ProvNameStr, ProvStrLen);\r
1327 FreePool (ProvNameStr);\r
1328 \r
1329 mPwdInfoHandle->Info[3] = Info;\r
1330 mPwdInfoHandle->Count++;\r
1331 }\r
1332 \r
1333 if (*UserInfo == NULL) {\r
1334 //\r
1335 // Return the first info handle.\r
1336 //\r
1337 *UserInfo = (EFI_USER_INFO_HANDLE) mPwdInfoHandle->Info[0];\r
1338 return EFI_SUCCESS;\r
1339 }\r
1340 \r
1341 //\r
1342 // Find information handle in credential info table.\r
1343 //\r
1344 for (Index = 0; Index < mPwdInfoHandle->Count; Index++) {\r
1345 Info = mPwdInfoHandle->Info[Index];\r
1346 if (*UserInfo == (EFI_USER_INFO_HANDLE)Info) {\r
1347 //\r
1348 // The handle is found, get the next one.\r
1349 //\r
1350 if (Index == mPwdInfoHandle->Count - 1) {\r
1351 //\r
1352 // Already last one.\r
1353 //\r
1354 *UserInfo = NULL;\r
1355 return EFI_NOT_FOUND;\r
1356 }\r
1357 \r
1358 Index++;\r
1359 *UserInfo = (EFI_USER_INFO_HANDLE)mPwdInfoHandle->Info[Index];\r
1360 return EFI_SUCCESS; \r
1361 }\r
1362 }\r
1363\r
1364 *UserInfo = NULL;\r
1365 return EFI_NOT_FOUND;\r
1366}\r
1367\r
1368\r
1369/**\r
1370 Main entry for this driver.\r
1371\r
1372 @param ImageHandle Image handle this driver.\r
1373 @param SystemTable Pointer to SystemTable.\r
1374\r
1375 @retval EFI_SUCESS This function always complete successfully.\r
1376\r
1377**/\r
1378EFI_STATUS\r
1379EFIAPI\r
1380PasswordProviderInit (\r
1381 IN EFI_HANDLE ImageHandle,\r
1382 IN EFI_SYSTEM_TABLE *SystemTable\r
1383 )\r
1384{\r
1385 EFI_STATUS Status;\r
1386\r
1387 //\r
1388 // Init credential table.\r
1389 //\r
1390 Status = InitCredentialTable ();\r
1391 if (EFI_ERROR (Status)) {\r
1392 return Status;\r
1393 }\r
1394 \r
1395 //\r
1396 // Init Form Browser.\r
1397 //\r
1398 Status = InitFormBrowser ();\r
1399 if (EFI_ERROR (Status)) {\r
1400 return Status;\r
1401 }\r
1402 \r
1403 //\r
1404 // Install protocol interfaces for the password credential provider.\r
1405 //\r
1406 Status = gBS->InstallProtocolInterface (\r
1407 &mCallbackInfo->DriverHandle,\r
1408 &gEfiUserCredentialProtocolGuid,\r
1409 EFI_NATIVE_INTERFACE,\r
1410 &gPwdCredentialProviderDriver\r
1411 );\r
1412 return Status;\r
1413}\r