-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
RedfishClientPkg: introduce RedfishBootstrapAccountDxe
-Introduce RedfishBootstrapAccountDxe to delete bootstrap account from /redfish/v1/AccountService/Accounts after BIOS finished all Redfish jobs. The bootstrap account won't be available to other application. So deleting bootstrap account helps to release resource at BMC. - After bootstrap account is deleted at BMC, the Redfish service instance is no longer usable. Close Redfish service instance to release the HTTP connection between BIOS and BMC. Signed-off-by: Nickle Wang <[email protected]> Cc: Abner Chang <[email protected]> Cc: Igor Kulchytskyy <[email protected]> Cc: Nick Ramirez <[email protected]>
- Loading branch information
Showing
5 changed files
with
450 additions
and
0 deletions.
There are no files selected for viewing
337 changes: 337 additions & 0 deletions
337
RedfishClientPkg/RedfishBootstrapAccountDxe/RedfishBootstrapAccountDxe.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,337 @@ | ||
/** @file | ||
This driver deletes bootstrap account in BMC after BIOS Redfish finished | ||
all jobs. | ||
(C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR> | ||
Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
SPDX-License-Identifier: BSD-2-Clause-Patent | ||
**/ | ||
|
||
#include "RedfishBootstrapAccountDxe.h" | ||
|
||
REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE *mBootstrapPrivate = NULL; | ||
|
||
/** | ||
Close Redfish service instance by calling RestEx protocol to release instance. | ||
@param[in] RestExHandle Handle of RestEx protocol. | ||
@retval EFI_SUCCESS The Redfish service is closed successfully. | ||
@retval EFI_INVALID_PARAMETER RestExHandle is NULL. | ||
@retval Others Error occurs. | ||
**/ | ||
EFI_STATUS | ||
CloseRedfishService ( | ||
IN EFI_HANDLE RestExHandle | ||
) | ||
{ | ||
EFI_REST_EX_PROTOCOL *RestEx; | ||
EFI_STATUS Status; | ||
|
||
if (RestExHandle == NULL) { | ||
return EFI_INVALID_PARAMETER; | ||
} | ||
|
||
Status = gBS->HandleProtocol ( | ||
RestExHandle, | ||
&gEfiRestExProtocolGuid, | ||
(VOID **)&RestEx | ||
); | ||
if (!EFI_ERROR (Status)) { | ||
Status = RestEx->Configure (RestEx, NULL); | ||
DEBUG ((REDFISH_BOOTSTRAP_ACCOUNT_DEBUG, "%a: release RestEx instance: %r\n", __func__, Status)); | ||
} | ||
|
||
return Status; | ||
} | ||
|
||
/** | ||
Callback function executed when the AfterProvisioning event group is signaled. | ||
@param[in] Event Event whose notification function is being invoked. | ||
@param[out] Context Pointer to the Context buffer | ||
**/ | ||
VOID | ||
EFIAPI | ||
RedfishBootstrapAccountOnRedfishAfterProvisioning ( | ||
IN EFI_EVENT Event, | ||
OUT VOID *Context | ||
) | ||
{ | ||
EFI_STATUS Status; | ||
REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE *Private; | ||
EDKII_REDFISH_CREDENTIAL_PROTOCOL *credentialProtocol; | ||
EDKII_REDFISH_AUTH_METHOD AuthMethod; | ||
CHAR8 *AccountName; | ||
CHAR8 *AccountCredential; | ||
CHAR16 TargetUri[REDFISH_URI_LENGTH]; | ||
CHAR16 *RedfishVersion; | ||
REDFISH_RESPONSE RedfishResponse; | ||
|
||
RedfishVersion = NULL; | ||
|
||
Private = (REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE *)Context; | ||
if ((Private == NULL) || (Private->RedfishService == NULL)) { | ||
DEBUG ((DEBUG_ERROR, "%a: Redfish service is not available\n", __func__)); | ||
return; | ||
} | ||
|
||
// | ||
// Locate Redfish Credential Protocol to get credential for | ||
// accessing to Redfish service. | ||
// | ||
Status = gBS->LocateProtocol ( | ||
&gEdkIIRedfishCredentialProtocolGuid, | ||
NULL, | ||
(VOID **)&credentialProtocol | ||
); | ||
if (EFI_ERROR (Status)) { | ||
DEBUG ((REDFISH_BOOTSTRAP_ACCOUNT_DEBUG, "%a: No Redfish Credential Protocol is installed on system.", __func__)); | ||
return; | ||
} | ||
|
||
// | ||
// This won't create new bootstrapping account at BMC. | ||
// The RedfishPlatformCredentialIpmiLib under RedfishPkg keeps | ||
// bootstrapping account in UEFI variable for the use during boot time. | ||
// And this variable gets deleted at exit-boot-service event. | ||
// We read this cached bootstrapping account here and delete this | ||
// account at BMC side. So, no bootstrapping account stays in both | ||
// BMC and host side after host boots into OS. | ||
// | ||
Status = credentialProtocol->GetAuthInfo ( | ||
credentialProtocol, | ||
&AuthMethod, | ||
&AccountName, | ||
&AccountCredential | ||
); | ||
if (EFI_ERROR (Status)) { | ||
DEBUG ((DEBUG_ERROR, "%a: can not get bootstrap account information: %r\n", __func__, Status)); | ||
return; | ||
} | ||
|
||
// | ||
// Carving the URI | ||
// | ||
RedfishVersion = RedfishGetVersion (Private->RedfishService); | ||
if (RedfishVersion == NULL) { | ||
DEBUG ((DEBUG_ERROR, "%a: can not get Redfish version\n", __func__)); | ||
return; | ||
} | ||
|
||
UnicodeSPrint (TargetUri, (sizeof (CHAR16) * REDFISH_URI_LENGTH), L"%s%s/%a", RedfishVersion, REDFISH_MANAGER_ACCOUNT_COLLECTION_URI, AccountName); | ||
|
||
DEBUG ((REDFISH_BOOTSTRAP_ACCOUNT_DEBUG, "%a: bootstrap account: %a\n", __func__, AccountName)); | ||
DEBUG ((REDFISH_BOOTSTRAP_ACCOUNT_DEBUG, "%a: bootstrap credential: %a\n", __func__, AccountCredential)); | ||
DEBUG ((REDFISH_BOOTSTRAP_ACCOUNT_DEBUG, "%a: bootstrap URI: %s\n", __func__, TargetUri)); | ||
|
||
// | ||
// Remove bootstrap account at /redfish/v1/AccountService/Account | ||
// | ||
ZeroMem (&RedfishResponse, sizeof (REDFISH_RESPONSE)); | ||
Status = RedfishHttpDeleteResource ( | ||
Private->RedfishService, | ||
TargetUri, | ||
&RedfishResponse | ||
); | ||
if (EFI_ERROR (Status)) { | ||
DEBUG ((DEBUG_ERROR, "%a: can not remove bootstrap account at BMC: %r", __func__, Status)); | ||
DumpRedfishResponse (__func__, DEBUG_ERROR, &RedfishResponse); | ||
} else { | ||
DEBUG ((REDFISH_BOOTSTRAP_ACCOUNT_DEBUG, "%a: bootstrap account: %a is removed from: %s\n", __func__, AccountName, REDFISH_MANAGER_ACCOUNT_COLLECTION_URI)); | ||
} | ||
|
||
// | ||
// Clean credential | ||
// | ||
ZeroMem (AccountName, AsciiStrSize (AccountName)); | ||
ZeroMem (AccountCredential, AsciiStrSize (AccountCredential)); | ||
|
||
// | ||
// Since the bootstrap account is deleted at BMC, the Redfish service instance is no longer usable. | ||
// Close Redfish service instance to release the HTTP connection between BIOS and BMC. | ||
// | ||
Status = CloseRedfishService (Private->RestExHandle); | ||
if (EFI_ERROR (Status)) { | ||
DEBUG ((DEBUG_ERROR, "%a: cannot close Redfish service instance: %r\n", __func__, Status)); | ||
} | ||
|
||
RedfishHttpFreeResponse (&RedfishResponse); | ||
|
||
return; | ||
} | ||
|
||
/** | ||
Initialize a Redfish configure handler. | ||
This function will be called by the Redfish config driver to initialize each Redfish configure | ||
handler. | ||
@param[in] This Pointer to EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL instance. | ||
@param[in] RedfishConfigServiceInfo Redfish service informaiton. | ||
@retval EFI_SUCCESS The handler has been initialized successfully. | ||
@retval EFI_DEVICE_ERROR Failed to create or configure the REST EX protocol instance. | ||
@retval EFI_ALREADY_STARTED This handler has already been initialized. | ||
@retval Other Error happens during the initialization. | ||
**/ | ||
EFI_STATUS | ||
EFIAPI | ||
RedfishBootstrapAccountInit ( | ||
IN EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL *This, | ||
IN REDFISH_CONFIG_SERVICE_INFORMATION *RedfishConfigServiceInfo | ||
) | ||
{ | ||
REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE *Private; | ||
|
||
Private = REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE_FROM_PROTOCOL (This); | ||
|
||
Private->RedfishService = RedfishCreateService (RedfishConfigServiceInfo); | ||
if (Private->RedfishService == NULL) { | ||
return EFI_DEVICE_ERROR; | ||
} | ||
|
||
Private->RestExHandle = RedfishConfigServiceInfo->RedfishServiceRestExHandle; | ||
|
||
return EFI_SUCCESS; | ||
} | ||
|
||
/** | ||
Stop a Redfish configure handler. | ||
@param[in] This Pointer to EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL instance. | ||
@retval EFI_SUCCESS This handler has been stoped successfully. | ||
@retval Others Some error happened. | ||
**/ | ||
EFI_STATUS | ||
EFIAPI | ||
RedfishBootstrapAccountStop ( | ||
IN EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL *This | ||
) | ||
{ | ||
REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE *Private; | ||
|
||
Private = REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE_FROM_PROTOCOL (This); | ||
|
||
if (Private->RedfishService != NULL) { | ||
RedfishCleanupService (Private->RedfishService); | ||
Private->RedfishService = NULL; | ||
} | ||
|
||
return EFI_SUCCESS; | ||
} | ||
|
||
EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL mRedfishConfigHandler = { | ||
RedfishBootstrapAccountInit, | ||
RedfishBootstrapAccountStop | ||
}; | ||
|
||
/** | ||
Unloads an image. | ||
@param[in] ImageHandle Handle that identifies the image to be unloaded. | ||
@retval EFI_SUCCESS The image has been unloaded. | ||
@retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle. | ||
**/ | ||
EFI_STATUS | ||
EFIAPI | ||
RedfishBootstrapAccountUnload ( | ||
IN EFI_HANDLE ImageHandle | ||
) | ||
{ | ||
EFI_STATUS Status; | ||
|
||
if (mBootstrapPrivate == NULL) { | ||
return EFI_SUCCESS; | ||
} | ||
|
||
if (mBootstrapPrivate->RedfishEvent != NULL) { | ||
gBS->CloseEvent (mBootstrapPrivate->RedfishEvent); | ||
} | ||
|
||
Status = gBS->UninstallProtocolInterface ( | ||
mBootstrapPrivate->ImageHandle, | ||
&gEdkIIRedfishConfigHandlerProtocolGuid, | ||
(VOID *)&mBootstrapPrivate->Protocol | ||
); | ||
if (EFI_ERROR (Status)) { | ||
DEBUG ((DEBUG_ERROR, "%a: can not uninstall Redfish config handler protocol: %r\n", __func__, Status)); | ||
} | ||
|
||
FreePool (mBootstrapPrivate); | ||
mBootstrapPrivate = NULL; | ||
|
||
return EFI_SUCCESS; | ||
} | ||
|
||
/** | ||
This is the declaration of an EFI image entry point. This entry point is | ||
the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including | ||
both device drivers and bus drivers. | ||
@param[in] ImageHandle The firmware allocated handle for the UEFI image. | ||
@param[in] SystemTable A pointer to the EFI System Table. | ||
@retval EFI_SUCCESS The operation completed successfully. | ||
@retval Others An unexpected error occurred. | ||
**/ | ||
EFI_STATUS | ||
EFIAPI | ||
RedfishBootstrapAccountEntryPoint ( | ||
IN EFI_HANDLE ImageHandle, | ||
IN EFI_SYSTEM_TABLE *SystemTable | ||
) | ||
{ | ||
EFI_STATUS Status; | ||
|
||
if (mBootstrapPrivate != NULL) { | ||
return EFI_ALREADY_STARTED; | ||
} | ||
|
||
mBootstrapPrivate = AllocateZeroPool (sizeof (REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE)); | ||
if (mBootstrapPrivate == NULL) { | ||
return EFI_OUT_OF_RESOURCES; | ||
} | ||
|
||
CopyMem (&mBootstrapPrivate->Protocol, &mRedfishConfigHandler, sizeof (EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL)); | ||
Status = gBS->InstallProtocolInterface ( | ||
&ImageHandle, | ||
&gEdkIIRedfishConfigHandlerProtocolGuid, | ||
EFI_NATIVE_INTERFACE, | ||
&mBootstrapPrivate->Protocol | ||
); | ||
if (EFI_ERROR (Status)) { | ||
DEBUG ((DEBUG_ERROR, "%a: can not install Redfish config handler protocol: %r\n", __func__, Status)); | ||
goto ON_ERROR; | ||
} | ||
|
||
// | ||
// Register after provisioning event to remove bootstrap account. | ||
// | ||
Status = CreateAfterProvisioningEvent ( | ||
RedfishBootstrapAccountOnRedfishAfterProvisioning, | ||
(VOID *)mBootstrapPrivate, | ||
&mBootstrapPrivate->RedfishEvent | ||
); | ||
if (EFI_ERROR (Status)) { | ||
DEBUG ((DEBUG_ERROR, "%a: failed to register after-provisioning event: %r\n", __func__, Status)); | ||
goto ON_ERROR; | ||
} | ||
|
||
return EFI_SUCCESS; | ||
|
||
ON_ERROR: | ||
|
||
RedfishBootstrapAccountUnload (ImageHandle); | ||
|
||
return Status; | ||
} |
58 changes: 58 additions & 0 deletions
58
RedfishClientPkg/RedfishBootstrapAccountDxe/RedfishBootstrapAccountDxe.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/** @file | ||
Common header file for RedfishBootstrapAccountDxe driver. | ||
(C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR> | ||
Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
SPDX-License-Identifier: BSD-2-Clause-Patent | ||
**/ | ||
|
||
#ifndef REDFISH_BOOTSTRAP_ACCOUNT_DXE_H_ | ||
#define REDFISH_BOOTSTRAP_ACCOUNT_DXE_H_ | ||
|
||
#include <Uefi.h> | ||
#include <RedfishBase.h> | ||
|
||
// | ||
// Libraries | ||
// | ||
#include <Library/BaseLib.h> | ||
#include <Library/BaseMemoryLib.h> | ||
#include <Library/DebugLib.h> | ||
|
||
#include <Library/MemoryAllocationLib.h> | ||
#include <Library/PrintLib.h> | ||
#include <Library/RedfishEventLib.h> | ||
#include <Library/RedfishFeatureUtilityLib.h> | ||
#include <Library/RedfishDebugLib.h> | ||
#include <Library/RedfishVersionLib.h> | ||
#include <Library/RedfishHttpLib.h> | ||
#include <Library/UefiBootServicesTableLib.h> | ||
#include <Library/UefiDriverEntryPoint.h> | ||
#include <Library/UefiLib.h> | ||
#include <Library/UefiRuntimeServicesTableLib.h> | ||
|
||
#include <Protocol/EdkIIRedfishConfigHandler.h> | ||
#include <Protocol/EdkIIRedfishCredential.h> | ||
#include <Protocol/RestEx.h> | ||
|
||
#define REDFISH_BOOTSTRAP_ACCOUNT_DEBUG DEBUG_VERBOSE | ||
#define REDFISH_MANAGER_ACCOUNT_COLLECTION_URI L"AccountService/Accounts" | ||
#define REDFISH_URI_LENGTH 128 | ||
|
||
// | ||
// Definitions of REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE | ||
// | ||
typedef struct { | ||
EFI_HANDLE ImageHandle; | ||
EFI_HANDLE RestExHandle; | ||
REDFISH_SERVICE RedfishService; | ||
EFI_EVENT RedfishEvent; | ||
EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL Protocol; | ||
} REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE; | ||
|
||
#define REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE_FROM_PROTOCOL(This) \ | ||
BASE_CR ((This), REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE, Protocol) | ||
|
||
#endif |
Oops, something went wrong.