2020-12-09 05:20:27 +01:00
|
|
|
/** @file
|
|
|
|
RedfishCrentialDxe produces the EdkIIRedfishCredentialProtocol for the consumer
|
|
|
|
to get the Redfish credential Info and to restrict Redfish access from UEFI side.
|
|
|
|
|
|
|
|
(C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
|
2024-07-23 01:50:45 +02:00
|
|
|
(C) Copyright 2024 American Megatrends International LLC<BR>
|
2020-12-09 05:20:27 +01:00
|
|
|
|
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
#include <RedfishCredentialDxe.h>
|
|
|
|
|
2024-07-23 01:50:45 +02:00
|
|
|
#define REDFISH_VERSION_DEFAULT_STRING L"v1"
|
|
|
|
|
|
|
|
REDFISH_CREDENTIAL_PRIVATE *mCredentialPrivate = NULL;
|
2020-12-09 05:20:27 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
Callback function executed when the ExitBootServices event group is signaled.
|
|
|
|
|
|
|
|
@param[in] Event Event whose notification function is being invoked.
|
|
|
|
@param[out] Context Pointer to the buffer pass in.
|
|
|
|
**/
|
|
|
|
VOID
|
|
|
|
EFIAPI
|
|
|
|
RedfishCredentialExitBootServicesEventNotify (
|
|
|
|
IN EFI_EVENT Event,
|
|
|
|
OUT VOID *Context
|
|
|
|
)
|
|
|
|
{
|
|
|
|
LibCredentialExitBootServicesNotify ((EDKII_REDFISH_CREDENTIAL_PROTOCOL *)Context);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Callback function executed when the EndOfDxe event group is signaled.
|
|
|
|
|
|
|
|
@param[in] Event Event whose notification function is being invoked.
|
|
|
|
@param[out] Context Pointer to the buffer pass in.
|
|
|
|
**/
|
|
|
|
VOID
|
|
|
|
EFIAPI
|
|
|
|
RedfishCredentialEndOfDxeEventNotify (
|
|
|
|
IN EFI_EVENT Event,
|
|
|
|
OUT VOID *Context
|
|
|
|
)
|
|
|
|
{
|
|
|
|
LibCredentialEndOfDxeNotify ((EDKII_REDFISH_CREDENTIAL_PROTOCOL *)Context);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Close event, so it will not be invoked again.
|
|
|
|
//
|
|
|
|
gBS->CloseEvent (Event);
|
|
|
|
}
|
|
|
|
|
2024-07-23 01:50:45 +02:00
|
|
|
EFI_STATUS
|
|
|
|
ReleaseCredentialPrivate (
|
|
|
|
);
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
IterateThroughBootstrapAccounts (
|
|
|
|
IN REDFISH_SERVICE RedfishService
|
|
|
|
);
|
|
|
|
|
2020-12-09 05:20:27 +01:00
|
|
|
/**
|
|
|
|
Retrieve platform's Redfish authentication information.
|
|
|
|
|
|
|
|
This functions returns the Redfish authentication method together with the user Id and
|
|
|
|
password.
|
|
|
|
- For AuthMethodNone, the UserId and Password could be used for HTTP header authentication
|
|
|
|
as defined by RFC7235.
|
|
|
|
- For AuthMethodRedfishSession, the UserId and Password could be used for Redfish
|
|
|
|
session login as defined by Redfish API specification (DSP0266).
|
|
|
|
|
|
|
|
Callers are responsible for and freeing the returned string storage.
|
|
|
|
|
|
|
|
@param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance.
|
|
|
|
@param[out] AuthMethod Type of Redfish authentication method.
|
|
|
|
@param[out] UserId The pointer to store the returned UserId string.
|
|
|
|
@param[out] Password The pointer to store the returned Password string.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS Get the authentication information successfully.
|
|
|
|
@retval EFI_ACCESS_DENIED SecureBoot is disabled after EndOfDxe.
|
|
|
|
@retval EFI_INVALID_PARAMETER This or AuthMethod or UserId or Password is NULL.
|
|
|
|
@retval EFI_OUT_OF_RESOURCES There are not enough memory resources.
|
|
|
|
@retval EFI_UNSUPPORTED Unsupported authentication method is found.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
RedfishCredentialGetAuthInfo (
|
|
|
|
IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This,
|
|
|
|
OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod,
|
|
|
|
OUT CHAR8 **UserId,
|
|
|
|
OUT CHAR8 **Password
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if ((This == NULL) || (AuthMethod == NULL) || (UserId == NULL) || (Password == NULL)) {
|
|
|
|
return EFI_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
return LibCredentialGetAuthInfo (This, AuthMethod, UserId, Password);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2024-07-23 01:50:45 +02:00
|
|
|
Notify the Redfish service provider to stop provide configuration service to this platform.
|
2020-12-09 05:20:27 +01:00
|
|
|
|
|
|
|
This function should be called when the platfrom is about to leave the safe environment.
|
|
|
|
It will notify the Redfish service provider to abort all logined session, and prohibit
|
|
|
|
further login with original auth info. GetAuthInfo() will return EFI_UNSUPPORTED once this
|
|
|
|
function is returned.
|
|
|
|
|
|
|
|
@param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance.
|
|
|
|
@param[in] ServiceStopType Reason of stopping Redfish service.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS Service has been stoped successfully.
|
|
|
|
@retval EFI_INVALID_PARAMETER This is NULL or given the worng ServiceStopType.
|
|
|
|
@retval EFI_UNSUPPORTED Not support to stop Redfish service.
|
|
|
|
@retval Others Some error happened.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
RedfishCredentialStopService (
|
|
|
|
IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This,
|
|
|
|
IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE ServiceStopType
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (This == NULL) {
|
|
|
|
return EFI_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
return LibStopRedfishService (This, ServiceStopType);
|
|
|
|
}
|
|
|
|
|
2024-07-23 01:50:45 +02:00
|
|
|
/**
|
|
|
|
Retrieve platform's Redfish authentication information.
|
|
|
|
|
|
|
|
This functions returns the Redfish authentication method together with the user Id and
|
|
|
|
password.
|
|
|
|
- For AuthMethodNone, the UserId and Password could be used for HTTP header authentication
|
|
|
|
as defined by RFC7235.
|
|
|
|
- For AuthMethodRedfishSession, the UserId and Password could be used for Redfish
|
|
|
|
session login as defined by Redfish API specification (DSP0266).
|
|
|
|
|
|
|
|
Callers are responsible for and freeing the returned string storage.
|
|
|
|
|
|
|
|
@param[in] This Pointer to EDKII_REDFISH_CREDENTIAL2_PROTOCOL instance.
|
|
|
|
@param[out] AuthMethod Type of Redfish authentication method.
|
|
|
|
@param[out] UserId The pointer to store the returned UserId string.
|
|
|
|
@param[out] Password The pointer to store the returned Password string.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS Get the authentication information successfully.
|
|
|
|
@retval EFI_ACCESS_DENIED SecureBoot is disabled after EndOfDxe.
|
|
|
|
@retval EFI_INVALID_PARAMETER This or AuthMethod or UserId or Password is NULL.
|
|
|
|
@retval EFI_OUT_OF_RESOURCES There are not enough memory resources.
|
|
|
|
@retval EFI_UNSUPPORTED Unsupported authentication method is found.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
RedfishCredential2GetAuthInfo (
|
|
|
|
IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This,
|
|
|
|
OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod,
|
|
|
|
OUT CHAR8 **UserId,
|
|
|
|
OUT CHAR8 **Password
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
|
|
|
|
if ((AuthMethod == NULL) || (UserId == NULL) || (Password == NULL)) {
|
|
|
|
return EFI_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mCredentialPrivate == NULL) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
|
|
|
|
return EFI_NOT_STARTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = mCredentialPrivate->RedfishCredentialProtocol.GetAuthInfo (
|
|
|
|
&mCredentialPrivate->RedfishCredentialProtocol,
|
|
|
|
AuthMethod,
|
|
|
|
UserId,
|
|
|
|
Password
|
|
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: Failed to retrieve Redfish credential - %r\n", __func__, Status));
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Notifies the Redfish service provider to stop providing configuration service to this platform.
|
|
|
|
Deletes the bootstrap account on BMC side, so it will not be used by any other driver.
|
|
|
|
|
|
|
|
This function should be called when the platfrom is about to leave the safe environment.
|
|
|
|
It will delete the bootstrap account sending DELETE request to BMC.
|
|
|
|
It will notify the Redfish service provider to abort all logined session, and prohibit
|
|
|
|
further login with original auth info. GetAuthInfo() will return EFI_UNSUPPORTED once this
|
|
|
|
function is returned.
|
|
|
|
|
|
|
|
@param[in] This Pointer to EDKII_REDFISH_CREDENTIAL2_PROTOCOL instance.
|
|
|
|
@param[in] ServiceStopType Reason of stopping Redfish service.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS Service has been stoped successfully.
|
|
|
|
@retval EFI_INVALID_PARAMETER This is NULL or given the worng ServiceStopType.
|
|
|
|
@retval EFI_UNSUPPORTED Not support to stop Redfish service.
|
|
|
|
@retval Others Some error happened.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
RedfishCredential2StopService (
|
|
|
|
IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This,
|
|
|
|
IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE ServiceStopType
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
REDFISH_SERVICE_LIST *Instance;
|
|
|
|
|
|
|
|
if (mCredentialPrivate == NULL) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
|
|
|
|
return EFI_NOT_STARTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((ServiceStopType == ServiceStopTypeExitBootService) ||
|
|
|
|
(ServiceStopType == ServiceStopTypeNone))
|
|
|
|
{
|
|
|
|
// Check PCD and skip the action if platform library is responsible for deleting account
|
|
|
|
// on exit boot service event
|
|
|
|
if (FixedPcdGetBool (PcdRedfishCredentialDeleteAccount)) {
|
|
|
|
if (!IsListEmpty (&mCredentialPrivate->RedfishServiceList)) {
|
|
|
|
Instance = (REDFISH_SERVICE_LIST *)GetFirstNode (&mCredentialPrivate->RedfishServiceList);
|
|
|
|
IterateThroughBootstrapAccounts (Instance->RedfishService);
|
|
|
|
}
|
|
|
|
|
|
|
|
ReleaseCredentialPrivate ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = mCredentialPrivate->RedfishCredentialProtocol.StopService (
|
|
|
|
&mCredentialPrivate->RedfishCredentialProtocol,
|
|
|
|
ServiceStopType
|
|
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: Failed to stop service - %r\n", __func__, Status));
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Function sends DELETE request to BMC for the account defined by the target URI.
|
|
|
|
|
|
|
|
@param[in] RedfishService Pointer to Redfish Service to be used
|
|
|
|
for sending DELETE request to BMC.
|
|
|
|
@param[in] TargetUri URI of bootstrap account to send DELETE request to.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
DeleteRedfishBootstrapAccount (
|
|
|
|
IN REDFISH_SERVICE RedfishService,
|
|
|
|
IN CHAR16 *TargetUri
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
REDFISH_RESPONSE RedfishResponse;
|
|
|
|
|
|
|
|
if (mCredentialPrivate == NULL) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
|
|
|
|
return EFI_NOT_STARTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((RedfishService == NULL) || (mCredentialPrivate->AuthMethod != AuthMethodHttpBasic)) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: Redfish service is not available\n", __func__));
|
|
|
|
return EFI_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Remove bootstrap account at /redfish/v1/AccountService/AccountId
|
|
|
|
//
|
|
|
|
ZeroMem (&RedfishResponse, sizeof (REDFISH_RESPONSE));
|
|
|
|
Status = RedfishHttpDeleteResourceEx (
|
|
|
|
RedfishService,
|
|
|
|
TargetUri,
|
|
|
|
"{}",
|
|
|
|
2,
|
|
|
|
NULL,
|
|
|
|
&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_CREDENTIAL_DEBUG, "%a: bootstrap account: %a is removed from: %s\nURI - %s",
|
|
|
|
__func__, mCredentialPrivate->AccountName, REDFISH_MANAGER_ACCOUNT_COLLECTION_URI, TargetUri)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
RedfishHttpFreeResponse (&RedfishResponse);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Get the information about specific Account.
|
|
|
|
Checks the User Name and if name matches delete that account
|
|
|
|
|
|
|
|
|
|
|
|
@param[in] RedfishService Pointer to Redfish Service to be used
|
|
|
|
for sending DELETE request to BMC.
|
|
|
|
@param[in] AccountUri URI of bootstrap account to verify.
|
|
|
|
|
|
|
|
**/
|
|
|
|
BOOLEAN
|
|
|
|
ProcessRedfishBootstarpAccount (
|
|
|
|
IN REDFISH_SERVICE RedfishService,
|
|
|
|
IN EFI_STRING AccountUri
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EDKII_JSON_VALUE JsonUserName;
|
|
|
|
EDKII_JSON_VALUE JsonValue;
|
|
|
|
EFI_STATUS Status;
|
|
|
|
REDFISH_RESPONSE RedfishResponse;
|
|
|
|
REDFISH_REQUEST RedfishRequest;
|
|
|
|
BOOLEAN Ret;
|
|
|
|
|
|
|
|
if (mCredentialPrivate == NULL) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((RedfishService == NULL) || IS_EMPTY_STRING (AccountUri) ||
|
|
|
|
(mCredentialPrivate->AuthMethod != AuthMethodHttpBasic))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
ZeroMem (&RedfishResponse, sizeof (REDFISH_RESPONSE));
|
|
|
|
ZeroMem (&RedfishRequest, sizeof (REDFISH_REQUEST));
|
|
|
|
Status = RedfishHttpGetResource (RedfishService, AccountUri, &RedfishRequest, &RedfishResponse, FALSE);
|
|
|
|
if (EFI_ERROR (Status) || (RedfishResponse.Payload == NULL)) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: can not get account from BMC: %r", __func__, Status));
|
|
|
|
DumpRedfishResponse (__func__, DEBUG_ERROR, &RedfishResponse);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ret = FALSE;
|
|
|
|
JsonValue = RedfishJsonInPayload (RedfishResponse.Payload);
|
|
|
|
if (JsonValueIsObject (JsonValue)) {
|
|
|
|
JsonUserName = JsonObjectGetValue (JsonValueGetObject (JsonValue), "UserName");
|
|
|
|
if (JsonValueIsString (JsonUserName) && (JsonValueGetAsciiString (JsonUserName) != NULL)) {
|
|
|
|
if (AsciiStrCmp (mCredentialPrivate->AccountName, JsonValueGetAsciiString (JsonUserName)) == 0) {
|
|
|
|
DeleteRedfishBootstrapAccount (RedfishService, AccountUri);
|
|
|
|
Ret = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RedfishHttpFreeResponse (&RedfishResponse);
|
|
|
|
RedfishHttpFreeRequest (&RedfishRequest);
|
|
|
|
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
This function returns the string of Redfish service version.
|
|
|
|
|
|
|
|
@param[out] ServiceVersionStr Redfish service string.
|
|
|
|
|
|
|
|
@return EFI_STATUS
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
RedfishGetServiceVersion (
|
|
|
|
OUT CHAR16 **ServiceVersionStr
|
|
|
|
)
|
|
|
|
{
|
|
|
|
*ServiceVersionStr = (CHAR16 *)PcdGetPtr (PcdDefaultRedfishVersion);
|
|
|
|
if (*ServiceVersionStr == NULL) {
|
|
|
|
*ServiceVersionStr = REDFISH_VERSION_DEFAULT_STRING;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Iterates through all account in the account collection
|
|
|
|
Get the information about specific Account.
|
|
|
|
Checks the User Name and if name matches delete that account
|
|
|
|
|
|
|
|
|
|
|
|
@param[in] RedfishService Pointer to Redfish Service to be used
|
|
|
|
for sending DELETE request to BMC.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
IterateThroughBootstrapAccounts (
|
|
|
|
IN REDFISH_SERVICE RedfishService
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
EDKII_JSON_VALUE JsonMembers;
|
|
|
|
EDKII_JSON_VALUE JsonValue;
|
|
|
|
EDKII_JSON_VALUE OdataId;
|
|
|
|
CHAR16 TargetUri[REDFISH_URI_LENGTH];
|
|
|
|
CHAR16 *RedfishVersion;
|
|
|
|
REDFISH_RESPONSE RedfishResponse;
|
|
|
|
REDFISH_REQUEST RedfishRequest;
|
|
|
|
UINTN MembersCount, Index;
|
|
|
|
|
|
|
|
RedfishVersion = NULL;
|
|
|
|
Status = EFI_NOT_FOUND;
|
|
|
|
|
|
|
|
if (mCredentialPrivate == NULL) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
|
|
|
|
return EFI_NOT_STARTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((RedfishService == NULL) || (mCredentialPrivate->AuthMethod != AuthMethodHttpBasic) ||
|
|
|
|
IS_EMPTY_STRING (mCredentialPrivate->AccountName))
|
|
|
|
{
|
|
|
|
return EFI_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Carving the URI
|
|
|
|
//
|
|
|
|
|
|
|
|
Status = RedfishGetServiceVersion (&RedfishVersion);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: can not get Redfish version\n", __func__));
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
UnicodeSPrint (
|
|
|
|
TargetUri,
|
|
|
|
(sizeof (CHAR16) * REDFISH_URI_LENGTH),
|
|
|
|
L"/redfish/%s/%s",
|
|
|
|
RedfishVersion,
|
|
|
|
REDFISH_MANAGER_ACCOUNT_COLLECTION_URI
|
|
|
|
);
|
|
|
|
|
|
|
|
DEBUG ((REDFISH_CREDENTIAL_DEBUG, "%a: account collection URI: %s\n", __func__, TargetUri));
|
|
|
|
|
|
|
|
ZeroMem (&RedfishResponse, sizeof (REDFISH_RESPONSE));
|
|
|
|
ZeroMem (&RedfishRequest, sizeof (REDFISH_REQUEST));
|
|
|
|
Status = RedfishHttpGetResource (RedfishService, TargetUri, &RedfishRequest, &RedfishResponse, FALSE);
|
|
|
|
if (EFI_ERROR (Status) || (RedfishResponse.Payload == NULL)) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: can not get accounts from BMC: %r\n", __func__, Status));
|
|
|
|
DumpRedfishResponse (__func__, DEBUG_ERROR, &RedfishResponse);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
JsonValue = RedfishJsonInPayload (RedfishResponse.Payload);
|
|
|
|
if (!JsonValueIsObject (JsonValue)) {
|
|
|
|
Status = EFI_LOAD_ERROR;
|
|
|
|
goto ON_EXIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
JsonMembers = JsonObjectGetValue (JsonValueGetObject (JsonValue), "Members");
|
|
|
|
if (!JsonValueIsArray (JsonMembers)) {
|
|
|
|
Status = EFI_LOAD_ERROR;
|
|
|
|
goto ON_EXIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = EFI_NOT_FOUND;
|
|
|
|
|
|
|
|
MembersCount = JsonArrayCount (JsonValueGetArray (JsonMembers));
|
|
|
|
for (Index = 0; Index < MembersCount; Index++) {
|
|
|
|
JsonValue = JsonArrayGetValue (JsonValueGetArray (JsonMembers), Index);
|
|
|
|
if (!JsonValueIsObject (JsonValue)) {
|
|
|
|
Status = EFI_LOAD_ERROR;
|
|
|
|
goto ON_EXIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
OdataId = JsonObjectGetValue (JsonValueGetObject (JsonValue), "@odata.id");
|
|
|
|
if (!JsonValueIsString (OdataId) || (JsonValueGetAsciiString (OdataId) == NULL)) {
|
|
|
|
Status = EFI_LOAD_ERROR;
|
|
|
|
goto ON_EXIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
UnicodeSPrint (
|
|
|
|
TargetUri,
|
|
|
|
(sizeof (CHAR16) * REDFISH_URI_LENGTH),
|
|
|
|
L"%a",
|
|
|
|
JsonValueGetAsciiString (OdataId)
|
|
|
|
);
|
|
|
|
DEBUG ((REDFISH_CREDENTIAL_DEBUG, "%a: account URI: %s\n", __func__, TargetUri));
|
|
|
|
// Verify bootstrap account User Name and delete the account if User Name matches
|
|
|
|
if (ProcessRedfishBootstarpAccount (RedfishService, TargetUri)) {
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ON_EXIT:
|
|
|
|
|
|
|
|
RedfishHttpFreeResponse (&RedfishResponse);
|
|
|
|
RedfishHttpFreeRequest (&RedfishRequest);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Retrieve platform's Redfish authentication information.
|
|
|
|
|
|
|
|
This functions returns the Redfish authentication method together with the user Id.
|
|
|
|
For AuthMethodNone, UserId will point to NULL which means authentication
|
|
|
|
is not required to access the Redfish service.
|
|
|
|
Callers are responsible for freeing the returned string storage pointed by UserId.
|
|
|
|
|
|
|
|
@param[out] AuthMethod Type of Redfish authentication method.
|
|
|
|
@param[out] UserId The pointer to store the returned UserId string.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS Get the authentication information successfully.
|
|
|
|
@retval EFI_INVALID_PARAMETER AuthMethod or UserId or Password is NULL.
|
|
|
|
@retval EFI_UNSUPPORTED Unsupported authentication method is found.
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
RedfishGetAuthConfig (
|
|
|
|
OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod,
|
|
|
|
OUT CHAR8 **UserId
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
CHAR8 *Password;
|
|
|
|
|
|
|
|
Password = NULL;
|
|
|
|
|
|
|
|
if ((AuthMethod == NULL) || (UserId == NULL)) {
|
|
|
|
return EFI_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mCredentialPrivate == NULL) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
|
|
|
|
return EFI_NOT_STARTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = mCredentialPrivate->RedfishCredentialProtocol.GetAuthInfo (
|
|
|
|
&mCredentialPrivate->RedfishCredentialProtocol,
|
|
|
|
AuthMethod,
|
|
|
|
UserId,
|
|
|
|
&Password
|
|
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: failed to retrieve Redfish credential - %r\n", __func__, Status));
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Password != NULL) {
|
|
|
|
ZeroMem (Password, AsciiStrSize (Password));
|
|
|
|
FreePool (Password);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
This function clears Redfish service internal list.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS Redfish service is deleted from list successfully.
|
|
|
|
@retval Others Fail to remove the entry
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
ClearRedfishServiceList (
|
2024-10-14 06:11:01 +02:00
|
|
|
VOID
|
2024-07-23 01:50:45 +02:00
|
|
|
)
|
|
|
|
{
|
|
|
|
REDFISH_SERVICE_LIST *Instance;
|
|
|
|
REDFISH_SERVICE_LIST *NextInstance;
|
|
|
|
|
|
|
|
if (mCredentialPrivate == NULL) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
|
|
|
|
return EFI_NOT_STARTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!IsListEmpty (&mCredentialPrivate->RedfishServiceList)) {
|
|
|
|
//
|
|
|
|
// Free memory of REDFISH_SERVICE_LIST instance.
|
|
|
|
//
|
|
|
|
Instance = (REDFISH_SERVICE_LIST *)GetFirstNode (&mCredentialPrivate->RedfishServiceList);
|
|
|
|
do {
|
|
|
|
NextInstance = NULL;
|
|
|
|
if (!IsNodeAtEnd (&mCredentialPrivate->RedfishServiceList, &Instance->NextInstance)) {
|
|
|
|
NextInstance = (REDFISH_SERVICE_LIST *)GetNextNode (
|
|
|
|
&mCredentialPrivate->RedfishServiceList,
|
|
|
|
&Instance->NextInstance
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
RemoveEntryList (&Instance->NextInstance);
|
|
|
|
FreePool ((VOID *)Instance);
|
|
|
|
Instance = NextInstance;
|
|
|
|
} while (Instance != NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
The function adds a new Redfish service to internal list
|
|
|
|
|
|
|
|
@param[in] RedfishService Pointer to REDFISH_SERVICE to be added to the list.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS Redfish service is added to list successfully.
|
|
|
|
@retval EFI_OUT_OF_RESOURCES Out of resources error.
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
AddRedfishServiceToList (
|
|
|
|
IN REDFISH_SERVICE RedfishService
|
|
|
|
)
|
|
|
|
{
|
|
|
|
BOOLEAN ServiceFound;
|
|
|
|
REDFISH_SERVICE_LIST *RedfishServiceInstance;
|
|
|
|
|
|
|
|
RedfishServiceInstance = NULL;
|
|
|
|
ServiceFound = FALSE;
|
|
|
|
|
|
|
|
if (mCredentialPrivate == NULL) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
|
|
|
|
return EFI_NOT_STARTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!IsListEmpty (&mCredentialPrivate->RedfishServiceList)) {
|
|
|
|
RedfishServiceInstance = (REDFISH_SERVICE_LIST *)GetFirstNode (&mCredentialPrivate->RedfishServiceList);
|
|
|
|
do {
|
|
|
|
if (RedfishServiceInstance->RedfishService == RedfishService) {
|
|
|
|
ServiceFound = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IsNodeAtEnd (&mCredentialPrivate->RedfishServiceList, &RedfishServiceInstance->NextInstance)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
RedfishServiceInstance = (REDFISH_SERVICE_LIST *)GetNextNode (
|
|
|
|
&mCredentialPrivate->RedfishServiceList,
|
|
|
|
&RedfishServiceInstance->NextInstance
|
|
|
|
);
|
|
|
|
} while (TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ServiceFound) {
|
|
|
|
RedfishServiceInstance = (REDFISH_SERVICE_LIST *)AllocateZeroPool (sizeof (REDFISH_SERVICE_LIST));
|
|
|
|
if (RedfishServiceInstance == NULL) {
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
|
|
|
}
|
|
|
|
|
|
|
|
RedfishServiceInstance->RedfishService = RedfishService;
|
|
|
|
InsertTailList (&mCredentialPrivate->RedfishServiceList, &RedfishServiceInstance->NextInstance);
|
|
|
|
}
|
|
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
This function deletes Redfish service from internal list.
|
|
|
|
|
|
|
|
@param[in] RedfishService Pointer to REDFISH_SERVICE to be delete from the list.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS Redfish service is deleted from list successfully.
|
|
|
|
@retval Others Fail to remove the entry
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
DeleteRedfishServiceFromList (
|
|
|
|
IN REDFISH_SERVICE RedfishService
|
|
|
|
)
|
|
|
|
{
|
|
|
|
REDFISH_SERVICE_LIST *RedfishServiceInstance;
|
|
|
|
|
|
|
|
if (mCredentialPrivate == NULL) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
|
|
|
|
return EFI_NOT_STARTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!IsListEmpty (&mCredentialPrivate->RedfishServiceList)) {
|
|
|
|
RedfishServiceInstance = (REDFISH_SERVICE_LIST *)GetFirstNode (&mCredentialPrivate->RedfishServiceList);
|
|
|
|
do {
|
|
|
|
if (RedfishServiceInstance->RedfishService == RedfishService) {
|
|
|
|
RemoveEntryList (&RedfishServiceInstance->NextInstance);
|
|
|
|
FreePool (RedfishServiceInstance);
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IsNodeAtEnd (&mCredentialPrivate->RedfishServiceList, &RedfishServiceInstance->NextInstance)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
RedfishServiceInstance = (REDFISH_SERVICE_LIST *)GetNextNode (&mCredentialPrivate->RedfishServiceList, &RedfishServiceInstance->NextInstance);
|
|
|
|
} while (TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
return EFI_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Register Redfish service instance so protocol knows that some module uses bootstrap account.
|
|
|
|
|
|
|
|
@param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance.
|
|
|
|
@param[in] RedfishService Redfish service instance to register.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS This Redfish service instance has been registered successfully.
|
|
|
|
@retval Others Fail to register Redfish Service
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
RedfishCredential2RegisterService (
|
|
|
|
IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This,
|
|
|
|
IN REDFISH_SERVICE RedfishService
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
|
|
|
|
if (mCredentialPrivate == NULL) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
|
|
|
|
return EFI_NOT_STARTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if AuthMethod has been initialized yet
|
|
|
|
if (mCredentialPrivate->AuthMethod == AuthMethodMax) {
|
|
|
|
Status = RedfishGetAuthConfig (
|
|
|
|
&mCredentialPrivate->AuthMethod,
|
|
|
|
&mCredentialPrivate->AccountName
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Bootstrap account should be deleted only if Basic Authentication is used.
|
|
|
|
if (!EFI_ERROR (Status) && (mCredentialPrivate->AuthMethod == AuthMethodHttpBasic)) {
|
|
|
|
Status = AddRedfishServiceToList (RedfishService);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: Failed to register Redfish service - %r\n", __func__, Status));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Unregister Redfish service instance and delete the bootstrap account
|
|
|
|
when all registered services unregistered.
|
|
|
|
|
|
|
|
@param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance.
|
|
|
|
@param[in] RedfishService Redfish service instance to unregister.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS This Redfish service instance has been unregistered successfully.
|
|
|
|
@retval Others Fail to unregister Redfish Service
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
RedfishCredential2UnregisterService (
|
|
|
|
IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This,
|
|
|
|
IN REDFISH_SERVICE RedfishService
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
|
|
|
|
// Bootstrap account should be deleted only if Basic Authentication is used.
|
|
|
|
if (mCredentialPrivate->AuthMethod != AuthMethodHttpBasic) {
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete Redfish Service from the registered list
|
|
|
|
Status = DeleteRedfishServiceFromList (RedfishService);
|
|
|
|
// Check if registered list is empty
|
|
|
|
if (IsListEmpty (&mCredentialPrivate->RedfishServiceList)) {
|
|
|
|
// Iterate through all accounts in the account collection and delete the bootstrap account
|
|
|
|
Status = IterateThroughBootstrapAccounts (RedfishService);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
|
|
if (mCredentialPrivate->AccountName != NULL) {
|
|
|
|
ZeroMem (mCredentialPrivate->AccountName, AsciiStrSize (mCredentialPrivate->AccountName));
|
|
|
|
FreePool (mCredentialPrivate->AccountName);
|
|
|
|
mCredentialPrivate->AccountName = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
mCredentialPrivate->AuthMethod = AuthMethodMax;
|
|
|
|
Status = mCredentialPrivate->RedfishCredentialProtocol.StopService (
|
|
|
|
&mCredentialPrivate->RedfishCredentialProtocol,
|
|
|
|
ServiceStopTypeNone
|
|
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
DEBUG ((DEBUG_ERROR, "%a: Failed to stop service - %r\n", __func__, Status));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2020-12-09 05:20:27 +01:00
|
|
|
/**
|
|
|
|
Main entry for this driver.
|
|
|
|
|
|
|
|
@param ImageHandle Image handle this driver.
|
|
|
|
@param SystemTable Pointer to SystemTable.
|
|
|
|
|
2021-09-07 05:25:46 +02:00
|
|
|
@retval EFI_SUCCESS This function always complete successfully.
|
2020-12-09 05:20:27 +01:00
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
RedfishCredentialDxeDriverEntryPoint (
|
|
|
|
IN EFI_HANDLE ImageHandle,
|
|
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
|
2024-07-23 01:50:45 +02:00
|
|
|
mCredentialPrivate = (REDFISH_CREDENTIAL_PRIVATE *)AllocateZeroPool (sizeof (REDFISH_CREDENTIAL_PRIVATE));
|
|
|
|
if (mCredentialPrivate == NULL) {
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
|
|
|
}
|
|
|
|
|
|
|
|
mCredentialPrivate->AuthMethod = AuthMethodMax;
|
|
|
|
InitializeListHead (&mCredentialPrivate->RedfishServiceList);
|
|
|
|
|
|
|
|
mCredentialPrivate->RedfishCredentialProtocol.GetAuthInfo = RedfishCredentialGetAuthInfo;
|
|
|
|
mCredentialPrivate->RedfishCredentialProtocol.StopService = RedfishCredentialStopService;
|
|
|
|
|
|
|
|
mCredentialPrivate->RedfishCredential2Protocol.Revision = REDFISH_CREDENTIAL_PROTOCOL_REVISION;
|
|
|
|
mCredentialPrivate->RedfishCredential2Protocol.GetAuthInfo = RedfishCredential2GetAuthInfo;
|
|
|
|
mCredentialPrivate->RedfishCredential2Protocol.StopService = RedfishCredential2StopService;
|
|
|
|
mCredentialPrivate->RedfishCredential2Protocol.RegisterRedfishService = RedfishCredential2RegisterService;
|
|
|
|
mCredentialPrivate->RedfishCredential2Protocol.UnregisterRedfishService = RedfishCredential2UnregisterService;
|
2020-12-09 05:20:27 +01:00
|
|
|
|
|
|
|
//
|
|
|
|
// Install the RedfishCredentialProtocol onto Handle.
|
|
|
|
//
|
|
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
2024-07-23 01:50:45 +02:00
|
|
|
&mCredentialPrivate->Handle,
|
2020-12-09 05:20:27 +01:00
|
|
|
&gEdkIIRedfishCredentialProtocolGuid,
|
2024-07-23 01:50:45 +02:00
|
|
|
&mCredentialPrivate->RedfishCredentialProtocol,
|
|
|
|
&gEdkIIRedfishCredential2ProtocolGuid,
|
|
|
|
&mCredentialPrivate->RedfishCredential2Protocol,
|
2020-12-09 05:20:27 +01:00
|
|
|
NULL
|
|
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// After EndOfDxe, if SecureBoot is disabled, Redfish Credential Protocol should return
|
|
|
|
// error code to caller to avoid the 3rd code to bypass Redfish Credential Protocol and
|
|
|
|
// retrieve userid/pwd directly. So, here, we create EndOfDxe Event to check SecureBoot
|
|
|
|
// status.
|
|
|
|
//
|
|
|
|
Status = gBS->CreateEventEx (
|
|
|
|
EVT_NOTIFY_SIGNAL,
|
|
|
|
TPL_CALLBACK,
|
|
|
|
RedfishCredentialEndOfDxeEventNotify,
|
2024-07-23 01:50:45 +02:00
|
|
|
(VOID *)&mCredentialPrivate->RedfishCredentialProtocol,
|
2020-12-09 05:20:27 +01:00
|
|
|
&gEfiEndOfDxeEventGroupGuid,
|
2024-07-23 01:50:45 +02:00
|
|
|
&mCredentialPrivate->EndOfDxeEvent
|
2020-12-09 05:20:27 +01:00
|
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
goto ON_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// After ExitBootServices, Redfish Credential Protocol should stop the service.
|
|
|
|
// So, here, we create ExitBootService Event to stop service.
|
|
|
|
//
|
|
|
|
Status = gBS->CreateEventEx (
|
|
|
|
EVT_NOTIFY_SIGNAL,
|
|
|
|
TPL_CALLBACK,
|
|
|
|
RedfishCredentialExitBootServicesEventNotify,
|
2024-07-23 01:50:45 +02:00
|
|
|
(VOID *)&mCredentialPrivate->RedfishCredentialProtocol,
|
2020-12-09 05:20:27 +01:00
|
|
|
&gEfiEventExitBootServicesGuid,
|
2024-07-23 01:50:45 +02:00
|
|
|
&mCredentialPrivate->ExitBootServiceEvent
|
2020-12-09 05:20:27 +01:00
|
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
2024-07-23 01:50:45 +02:00
|
|
|
gBS->CloseEvent (mCredentialPrivate->EndOfDxeEvent);
|
|
|
|
mCredentialPrivate->EndOfDxeEvent = NULL;
|
2020-12-09 05:20:27 +01:00
|
|
|
goto ON_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
|
|
|
|
ON_ERROR:
|
|
|
|
|
|
|
|
gBS->UninstallMultipleProtocolInterfaces (
|
2024-07-23 01:50:45 +02:00
|
|
|
mCredentialPrivate->Handle,
|
2020-12-09 05:20:27 +01:00
|
|
|
&gEdkIIRedfishCredentialProtocolGuid,
|
2024-07-23 01:50:45 +02:00
|
|
|
&mCredentialPrivate->RedfishCredentialProtocol,
|
|
|
|
&gEdkIIRedfishCredential2ProtocolGuid,
|
|
|
|
&mCredentialPrivate->RedfishCredential2Protocol,
|
2020-12-09 05:20:27 +01:00
|
|
|
NULL
|
|
|
|
);
|
|
|
|
|
2024-07-23 01:50:45 +02:00
|
|
|
FreePool (mCredentialPrivate);
|
|
|
|
|
2020-12-09 05:20:27 +01:00
|
|
|
return Status;
|
|
|
|
}
|
2024-07-23 01:50:45 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
Releases all resources allocated by the module.
|
|
|
|
Uninstall all the protocols installed in the driver entry point.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS The resources are released.
|
|
|
|
@retval Others Failed to release the resources.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
ReleaseCredentialPrivate (
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (mCredentialPrivate != NULL) {
|
|
|
|
if (mCredentialPrivate->AccountName != NULL) {
|
|
|
|
ZeroMem (mCredentialPrivate->AccountName, AsciiStrSize (mCredentialPrivate->AccountName));
|
|
|
|
FreePool (mCredentialPrivate->AccountName);
|
|
|
|
mCredentialPrivate->AccountName = NULL;
|
|
|
|
}
|
|
|
|
|
2024-10-14 06:11:01 +02:00
|
|
|
ClearRedfishServiceList ();
|
2024-07-23 01:50:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
This is the unload handle for Redfish Credentials module.
|
|
|
|
|
|
|
|
Uninstall all the protocols installed in the driver entry point.
|
|
|
|
Clear all allocated resources.
|
|
|
|
|
|
|
|
@param[in] ImageHandle The drivers' driver image.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS The image is unloaded.
|
|
|
|
@retval Others Failed to unload the image.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
RedfishCredentialDxeDriverUnload (
|
|
|
|
IN EFI_HANDLE ImageHandle
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (mCredentialPrivate != NULL) {
|
|
|
|
gBS->UninstallMultipleProtocolInterfaces (
|
|
|
|
mCredentialPrivate->Handle,
|
|
|
|
&gEdkIIRedfishCredentialProtocolGuid,
|
|
|
|
&mCredentialPrivate->RedfishCredentialProtocol,
|
|
|
|
&gEdkIIRedfishCredential2ProtocolGuid,
|
|
|
|
&mCredentialPrivate->RedfishCredential2Protocol,
|
|
|
|
NULL
|
|
|
|
);
|
|
|
|
|
|
|
|
if (mCredentialPrivate->EndOfDxeEvent != NULL) {
|
|
|
|
gBS->CloseEvent (mCredentialPrivate->EndOfDxeEvent);
|
|
|
|
mCredentialPrivate->EndOfDxeEvent = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mCredentialPrivate->ExitBootServiceEvent != NULL) {
|
|
|
|
gBS->CloseEvent (mCredentialPrivate->ExitBootServiceEvent);
|
|
|
|
mCredentialPrivate->ExitBootServiceEvent = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReleaseCredentialPrivate ();
|
|
|
|
|
|
|
|
FreePool (mCredentialPrivate);
|
|
|
|
mCredentialPrivate = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|