mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-30 17:14:07 +02:00
RedfishPkg: Allow deletion of the bootstrap account
Extending the Redfish Credential protocol to allow Redfish Clients to be registered/unregistered for tracking their end of work and delete a bootstrap account when all registered Redfish clients finish their communication with Redfish service. Redfish Http module also was updated to register/unregister clients on Redfish Service creation/stop event. Cc: Abner Chang <abner.chang@amd.com> Cc: Nickle Wang <nicklew@nvidia.com> Signed-off-by: Igor Kulchytskyy <igork@ami.com>
This commit is contained in:
parent
a29a9cce5f
commit
9761137743
128
RedfishPkg/Include/Protocol/EdkIIRedfishCredential2.h
Normal file
128
RedfishPkg/Include/Protocol/EdkIIRedfishCredential2.h
Normal file
@ -0,0 +1,128 @@
|
||||
/** @file
|
||||
This file defines the EDKII_REDFISH_CREDENTIAL2_PROTOCOL interface.
|
||||
|
||||
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
|
||||
(C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
|
||||
(C) Copyright 2024 American Megatrends International LLC<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#ifndef EDKII_REDFISH_CREDENTIAL2_H_
|
||||
#define EDKII_REDFISH_CREDENTIAL2_H_
|
||||
|
||||
#include <Protocol/EdkIIRedfishCredential.h>
|
||||
#include <RedfishServiceData.h>
|
||||
|
||||
typedef struct _EDKII_REDFISH_CREDENTIAL2_PROTOCOL EDKII_REDFISH_CREDENTIAL2_PROTOCOL;
|
||||
|
||||
#define REDFISH_CREDENTIAL_PROTOCOL_REVISION 0x00010000
|
||||
|
||||
#define EDKII_REDFISH_CREDENTIAL2_PROTOCOL_GUID \
|
||||
{ \
|
||||
0x936b81dc, 0x348c, 0x42e3, { 0x9e, 0x82, 0x2, 0x91, 0x4f, 0xd3, 0x48, 0x86 } \
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EDKII_REDFISH_CREDENTIAL2_PROTOCOL_GET_AUTH_INFO)(
|
||||
IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This,
|
||||
OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod,
|
||||
OUT CHAR8 **UserId,
|
||||
OUT CHAR8 **Password
|
||||
);
|
||||
|
||||
/**
|
||||
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 stopped successfully.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval Others Some error happened.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EDKII_REDFISH_CREDENTIAL2_PROTOCOL_STOP_SERVICE)(
|
||||
IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This,
|
||||
IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE ServiceStopType
|
||||
);
|
||||
|
||||
/**
|
||||
Register Redfish service instance so protocol knows that some module uses bootstrap account .
|
||||
|
||||
@param[in] This Pointer to EDKII_REDFISH_CREDENTIAL2_PROTOCOL instance.
|
||||
@param[in] RedfishService Redfish service instance to register.
|
||||
|
||||
@retval EFI_SUCCESS This Redfish service instance has been registered successfully.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EDKII_REDFISH_CREDENTIAL2_PROTOCOL_REGISTER_REDFISH_SERVICE)(
|
||||
IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This,
|
||||
IN REDFISH_SERVICE RedfishService
|
||||
);
|
||||
|
||||
/**
|
||||
Unregister Redfish service instance and delete the bootstrap account
|
||||
when all registered services unregistered.
|
||||
|
||||
@param[in] This Pointer to EDKII_REDFISH_CREDENTIAL2_PROTOCOL instance.
|
||||
@param[in] RedfishService Redfish service instance to unregister.
|
||||
|
||||
@retval EFI_SUCCESS This Redfish service instance has been unregistered successfully.
|
||||
|
||||
**/
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EDKII_REDFISH_CREDENTIAL2_PROTOCOL_UNREGISTER_REDFISH_SERVICE)(
|
||||
IN EDKII_REDFISH_CREDENTIAL2_PROTOCOL *This,
|
||||
IN REDFISH_SERVICE RedfishService
|
||||
);
|
||||
|
||||
struct _EDKII_REDFISH_CREDENTIAL2_PROTOCOL {
|
||||
UINT64 Revision;
|
||||
EDKII_REDFISH_CREDENTIAL2_PROTOCOL_GET_AUTH_INFO GetAuthInfo;
|
||||
EDKII_REDFISH_CREDENTIAL2_PROTOCOL_STOP_SERVICE StopService;
|
||||
EDKII_REDFISH_CREDENTIAL2_PROTOCOL_REGISTER_REDFISH_SERVICE RegisterRedfishService;
|
||||
EDKII_REDFISH_CREDENTIAL2_PROTOCOL_UNREGISTER_REDFISH_SERVICE UnregisterRedfishService;
|
||||
};
|
||||
|
||||
extern EFI_GUID gEdkIIRedfishCredential2ProtocolGuid;
|
||||
|
||||
#endif
|
@ -3,6 +3,7 @@
|
||||
to get the Redfish credential Info and to restrict Redfish access from UEFI side.
|
||||
|
||||
(C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
|
||||
(C) Copyright 2024 American Megatrends International LLC<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -10,10 +11,9 @@
|
||||
|
||||
#include <RedfishCredentialDxe.h>
|
||||
|
||||
EDKII_REDFISH_CREDENTIAL_PROTOCOL mRedfishCredentialProtocol = {
|
||||
RedfishCredentialGetAuthInfo,
|
||||
RedfishCredentialStopService
|
||||
};
|
||||
#define REDFISH_VERSION_DEFAULT_STRING L"v1"
|
||||
|
||||
REDFISH_CREDENTIAL_PRIVATE *mCredentialPrivate = NULL;
|
||||
|
||||
/**
|
||||
Callback function executed when the ExitBootServices event group is signaled.
|
||||
@ -52,6 +52,15 @@ RedfishCredentialEndOfDxeEventNotify (
|
||||
gBS->CloseEvent (Event);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
ReleaseCredentialPrivate (
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
IterateThroughBootstrapAccounts (
|
||||
IN REDFISH_SERVICE RedfishService
|
||||
);
|
||||
|
||||
/**
|
||||
Retrieve platform's Redfish authentication information.
|
||||
|
||||
@ -93,7 +102,7 @@ RedfishCredentialGetAuthInfo (
|
||||
}
|
||||
|
||||
/**
|
||||
Notify the Redfish service provide to stop provide configuration service to this platform.
|
||||
Notify the Redfish service provider to stop provide configuration service to this platform.
|
||||
|
||||
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
|
||||
@ -123,6 +132,668 @@ RedfishCredentialStopService (
|
||||
return LibStopRedfishService (This, ServiceStopType);
|
||||
}
|
||||
|
||||
/**
|
||||
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 (
|
||||
)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
Main entry for this driver.
|
||||
|
||||
@ -140,19 +811,33 @@ RedfishCredentialDxeDriverEntryPoint (
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_EVENT EndOfDxeEvent;
|
||||
EFI_EVENT ExitBootServiceEvent;
|
||||
|
||||
Handle = NULL;
|
||||
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;
|
||||
|
||||
//
|
||||
// Install the RedfishCredentialProtocol onto Handle.
|
||||
//
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&Handle,
|
||||
&mCredentialPrivate->Handle,
|
||||
&gEdkIIRedfishCredentialProtocolGuid,
|
||||
&mRedfishCredentialProtocol,
|
||||
&mCredentialPrivate->RedfishCredentialProtocol,
|
||||
&gEdkIIRedfishCredential2ProtocolGuid,
|
||||
&mCredentialPrivate->RedfishCredential2Protocol,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
@ -169,9 +854,9 @@ RedfishCredentialDxeDriverEntryPoint (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_CALLBACK,
|
||||
RedfishCredentialEndOfDxeEventNotify,
|
||||
(VOID *)&mRedfishCredentialProtocol,
|
||||
(VOID *)&mCredentialPrivate->RedfishCredentialProtocol,
|
||||
&gEfiEndOfDxeEventGroupGuid,
|
||||
&EndOfDxeEvent
|
||||
&mCredentialPrivate->EndOfDxeEvent
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto ON_ERROR;
|
||||
@ -185,12 +870,13 @@ RedfishCredentialDxeDriverEntryPoint (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_CALLBACK,
|
||||
RedfishCredentialExitBootServicesEventNotify,
|
||||
(VOID *)&mRedfishCredentialProtocol,
|
||||
(VOID *)&mCredentialPrivate->RedfishCredentialProtocol,
|
||||
&gEfiEventExitBootServicesGuid,
|
||||
&ExitBootServiceEvent
|
||||
&mCredentialPrivate->ExitBootServiceEvent
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
gBS->CloseEvent (EndOfDxeEvent);
|
||||
gBS->CloseEvent (mCredentialPrivate->EndOfDxeEvent);
|
||||
mCredentialPrivate->EndOfDxeEvent = NULL;
|
||||
goto ON_ERROR;
|
||||
}
|
||||
|
||||
@ -199,11 +885,87 @@ RedfishCredentialDxeDriverEntryPoint (
|
||||
ON_ERROR:
|
||||
|
||||
gBS->UninstallMultipleProtocolInterfaces (
|
||||
Handle,
|
||||
mCredentialPrivate->Handle,
|
||||
&gEdkIIRedfishCredentialProtocolGuid,
|
||||
&mRedfishCredentialProtocol,
|
||||
&mCredentialPrivate->RedfishCredentialProtocol,
|
||||
&gEdkIIRedfishCredential2ProtocolGuid,
|
||||
&mCredentialPrivate->RedfishCredential2Protocol,
|
||||
NULL
|
||||
);
|
||||
|
||||
FreePool (mCredentialPrivate);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
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;
|
||||
}
|
||||
|
||||
ClearRedfishServiceList (mCredentialPrivate);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
Definition of Redfish Credential DXE driver.
|
||||
|
||||
(C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
|
||||
(C) Copyright 2024 American Megatrends International LLC<BR>
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@ -10,7 +11,7 @@
|
||||
#ifndef EDKII_REDFISH_CREDENTIAL_DXE_H_
|
||||
#define EDKII_REDFISH_CREDENTIAL_DXE_H_
|
||||
|
||||
#include <Protocol/EdkIIRedfishCredential.h>
|
||||
#include <Protocol/EdkIIRedfishCredential2.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
@ -18,60 +19,40 @@
|
||||
#include <Library/RedfishCredentialLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/RedfishHttpLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/RedfishDebugLib.h>
|
||||
|
||||
/**
|
||||
Retrieve platform's Redfish authentication information.
|
||||
#define REDFISH_CREDENTIAL_DEBUG DEBUG_VERBOSE
|
||||
#define REDFISH_MANAGER_ACCOUNT_COLLECTION_URI L"AccountService/Accounts"
|
||||
#define REDFISH_URI_LENGTH 128
|
||||
|
||||
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).
|
||||
#ifndef IS_EMPTY_STRING
|
||||
#define IS_EMPTY_STRING(a) ((a) == NULL || (a)[0] == '\0')
|
||||
#endif
|
||||
|
||||
Callers are responsible for and freeing the returned string storage.
|
||||
///
|
||||
/// Definition of REDFISH_SERVICE_LIST
|
||||
///
|
||||
typedef struct {
|
||||
LIST_ENTRY NextInstance;
|
||||
REDFISH_SERVICE RedfishService;
|
||||
} REDFISH_SERVICE_LIST;
|
||||
|
||||
@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
|
||||
);
|
||||
|
||||
/**
|
||||
Notify the Redfish service provide to stop provide configuration service to this platform.
|
||||
|
||||
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.
|
||||
|
||||
@retval EFI_SUCCESS Service has been stoped successfully.
|
||||
@retval EFI_INVALID_PARAMETER This is NULL.
|
||||
@retval Others Some error happened.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
RedfishCredentialStopService (
|
||||
IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This,
|
||||
IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE ServiceStopType
|
||||
);
|
||||
//
|
||||
// Definitions of REDFISH_BOOTSTRAP_ACCOUNT_PRIVATE
|
||||
//
|
||||
typedef struct {
|
||||
EFI_HANDLE Handle;
|
||||
EFI_EVENT EndOfDxeEvent;
|
||||
EFI_EVENT ExitBootServiceEvent;
|
||||
EDKII_REDFISH_AUTH_METHOD AuthMethod;
|
||||
CHAR8 *AccountName;
|
||||
EDKII_REDFISH_CREDENTIAL_PROTOCOL RedfishCredentialProtocol;
|
||||
EDKII_REDFISH_CREDENTIAL2_PROTOCOL RedfishCredential2Protocol;
|
||||
LIST_ENTRY RedfishServiceList;
|
||||
} REDFISH_CREDENTIAL_PRIVATE;
|
||||
|
||||
#endif
|
||||
|
@ -15,6 +15,7 @@
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = RedfishCredentialDxeDriverEntryPoint
|
||||
UNLOAD_IMAGE = RedfishCredentialDxeDriverUnload
|
||||
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64
|
||||
@ -38,14 +39,22 @@
|
||||
UefiDriverEntryPoint
|
||||
UefiRuntimeServicesTableLib
|
||||
UefiLib
|
||||
RedfishHttpLib
|
||||
RedfishDebugLib
|
||||
JsonLib
|
||||
|
||||
[Protocols]
|
||||
gEdkIIRedfishCredentialProtocolGuid ## BY_START
|
||||
gEdkIIRedfishCredential2ProtocolGuid ## BY_START
|
||||
|
||||
|
||||
[Guids]
|
||||
gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
|
||||
gEfiEventExitBootServicesGuid ## CONSUMES ## Event
|
||||
|
||||
[Pcd]
|
||||
gEfiRedfishPkgTokenSpaceGuid.PcdRedfishCredentialDeleteAccount
|
||||
gEfiRedfishPkgTokenSpaceGuid.PcdDefaultRedfishVersion
|
||||
|
||||
[Depex]
|
||||
TRUE
|
||||
|
@ -83,7 +83,7 @@ typedef struct {
|
||||
EFI_EVENT NotifyEvent;
|
||||
REDFISH_HTTP_CACHE_LIST CacheList;
|
||||
EDKII_REDFISH_HTTP_PROTOCOL Protocol;
|
||||
EDKII_REDFISH_CREDENTIAL_PROTOCOL *CredentialProtocol;
|
||||
EDKII_REDFISH_CREDENTIAL2_PROTOCOL *CredentialProtocol;
|
||||
REDFISH_HTTP_RETRY_SETTING RetrySetting;
|
||||
} REDFISH_HTTP_CACHE_PRIVATE;
|
||||
|
||||
|
@ -313,10 +313,10 @@ RedfishCreateRedfishService (
|
||||
&Username,
|
||||
&Password
|
||||
);
|
||||
if (EFI_ERROR (Status) || IS_EMPTY_STRING (Username) || IS_EMPTY_STRING (Password)) {
|
||||
if (EFI_ERROR (Status) || ((AuthMethod != AuthMethodNone) && (IS_EMPTY_STRING (Username) || IS_EMPTY_STRING (Password)))) {
|
||||
DEBUG ((DEBUG_ERROR, "%a: cannot get authentication information: %r\n", __func__, Status));
|
||||
goto ON_RELEASE;
|
||||
} else {
|
||||
} else if (AuthMethod != AuthMethodNone) {
|
||||
DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Auth method: 0x%x username: %a password: %a\n", __func__, AuthMethod, Username, Password));
|
||||
|
||||
//
|
||||
@ -371,6 +371,14 @@ RedfishCreateRedfishService (
|
||||
NewService = CreateRedfishService (Host, AsciiLocation, EncodedAuthString, NULL, RestEx);
|
||||
if (NewService == NULL) {
|
||||
DEBUG ((DEBUG_ERROR, "%a: CreateRedfishService\n", __func__));
|
||||
goto ON_RELEASE;
|
||||
}
|
||||
|
||||
if (Private->CredentialProtocol != NULL) {
|
||||
Status = Private->CredentialProtocol->RegisterRedfishService (Private->CredentialProtocol, NewService);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "%a: Failed to register Redfish service - %r\n", __func__, Status));
|
||||
}
|
||||
}
|
||||
|
||||
ON_RELEASE:
|
||||
@ -424,17 +432,33 @@ RedfishFreeRedfishService (
|
||||
IN REDFISH_SERVICE RedfishService
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
REDFISH_SERVICE_PRIVATE *Service;
|
||||
REDFISH_HTTP_CACHE_PRIVATE *Private;
|
||||
|
||||
if ((This == NULL) || (RedfishService == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Private = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
|
||||
|
||||
Service = (REDFISH_SERVICE_PRIVATE *)RedfishService;
|
||||
if (Service->Signature != REDFISH_HTTP_SERVICE_SIGNATURE) {
|
||||
DEBUG ((DEBUG_ERROR, "%a: signature check failure\n", __func__));
|
||||
}
|
||||
|
||||
if (Private->CredentialProtocol != NULL) {
|
||||
Status = Private->CredentialProtocol->UnregisterRedfishService (Private->CredentialProtocol, RedfishService);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "%a: Failed to unregister Redfish service - %r\n", __func__, Status));
|
||||
} else {
|
||||
if (Service->RestEx != NULL) {
|
||||
Status = Service->RestEx->Configure (Service->RestEx, NULL);
|
||||
DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: release RestEx instance: %r\n", __func__, Status));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ReleaseRedfishService (Service);
|
||||
}
|
||||
|
||||
@ -1245,10 +1269,10 @@ CredentialProtocolInstalled (
|
||||
}
|
||||
|
||||
//
|
||||
// Locate HII database protocol.
|
||||
// Locate HII credential protocol.
|
||||
//
|
||||
Status = gBS->LocateProtocol (
|
||||
&gEdkIIRedfishCredentialProtocolGuid,
|
||||
&gEdkIIRedfishCredential2ProtocolGuid,
|
||||
NULL,
|
||||
(VOID **)&Private->CredentialProtocol
|
||||
);
|
||||
@ -1327,14 +1351,14 @@ RedfishHttpEntryPoint (
|
||||
// Install protocol notification if credential protocol is installed.
|
||||
//
|
||||
mRedfishHttpCachePrivate->NotifyEvent = EfiCreateProtocolNotifyEvent (
|
||||
&gEdkIIRedfishCredentialProtocolGuid,
|
||||
&gEdkIIRedfishCredential2ProtocolGuid,
|
||||
TPL_CALLBACK,
|
||||
CredentialProtocolInstalled,
|
||||
mRedfishHttpCachePrivate,
|
||||
&Registration
|
||||
);
|
||||
if (mRedfishHttpCachePrivate->NotifyEvent == NULL) {
|
||||
DEBUG ((DEBUG_ERROR, "%a: failed to create protocol notification for gEdkIIRedfishCredentialProtocolGuid\n", __func__));
|
||||
DEBUG ((DEBUG_ERROR, "%a: failed to create protocol notification for gEdkIIRedfishCredential2ProtocolGuid\n", __func__));
|
||||
ASSERT (FALSE);
|
||||
RedfishHttpDriverUnload (ImageHandle);
|
||||
return Status;
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#include <Protocol/Http.h>
|
||||
#include <Protocol/EdkIIRedfishHttpProtocol.h>
|
||||
#include <Protocol/EdkIIRedfishCredential.h>
|
||||
#include <Protocol/EdkIIRedfishCredential2.h>
|
||||
#include <Protocol/RestEx.h>
|
||||
|
||||
#define IS_EMPTY_STRING(a) ((a) == NULL || (a)[0] == '\0')
|
||||
|
@ -56,7 +56,7 @@
|
||||
|
||||
[Protocols]
|
||||
gEdkIIRedfishHttpProtocolGuid ## PRODUCED
|
||||
gEdkIIRedfishCredentialProtocolGuid ## CONSUMES
|
||||
gEdkIIRedfishCredential2ProtocolGuid ## CONSUMES
|
||||
gEfiRestExProtocolGuid ## CONSUEMS
|
||||
|
||||
[Pcd]
|
||||
|
@ -90,6 +90,9 @@
|
||||
## Include/Protocol/EdkIIRedfishCredential.h
|
||||
gEdkIIRedfishCredentialProtocolGuid = { 0x8804377, 0xaf7a, 0x4496, { 0x8a, 0x7b, 0x17, 0x59, 0x0, 0xe9, 0xab, 0x46 } }
|
||||
|
||||
## Include/Protocol/EdkIIRedfishCredential.h
|
||||
gEdkIIRedfishCredential2ProtocolGuid = { 0x936b81dc, 0x348c, 0x42e3, { 0x9e, 0x82, 0x2, 0x91, 0x4f, 0xd3, 0x48, 0x86 } }
|
||||
|
||||
## Include/Protocol/Edk2RedfishConfigHandler.h
|
||||
gEdkIIRedfishConfigHandlerProtocolGuid = { 0xbc0fe6bb, 0x2cc9, 0x463e, { 0x90, 0x82, 0xfa, 0x11, 0x76, 0xfc, 0x67, 0xde } }
|
||||
|
||||
@ -208,3 +211,7 @@
|
||||
#
|
||||
# Redfish RedfishPlatformConfigDxe feature Properties
|
||||
gEfiRedfishPkgTokenSpaceGuid.PcdRedfishPlatformConfigFeatureProperty|0|UINT32|0x00001014
|
||||
## This is used to disable a deletion of the bootstrap account.
|
||||
gEfiRedfishPkgTokenSpaceGuid.PcdRedfishCredentialDeleteAccount|TRUE|BOOLEAN|0x00001015
|
||||
## Default Redfish version string
|
||||
gEfiRedfishPkgTokenSpaceGuid.PcdDefaultRedfishVersion|L"v1"|VOID*|0x00001016
|
||||
|
Loading…
x
Reference in New Issue
Block a user