VirtualBox

Ignore:
Timestamp:
Mar 31, 2025 11:31:09 AM (2 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168237
Message:

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

Location:
trunk/src/VBox/Devices/EFI/FirmwareNew
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/FirmwareNew

  • trunk/src/VBox/Devices/EFI/FirmwareNew/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.c

    r99404 r108794  
    44
    55  (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
     6  (C) Copyright 2024 American Megatrends International LLC<BR>
    67
    78  SPDX-License-Identifier: BSD-2-Clause-Patent
     
    1112#include <RedfishCredentialDxe.h>
    1213
    13 EDKII_REDFISH_CREDENTIAL_PROTOCOL  mRedfishCredentialProtocol = {
    14   RedfishCredentialGetAuthInfo,
    15   RedfishCredentialStopService
    16 };
     14#define REDFISH_VERSION_DEFAULT_STRING  L"v1"
     15
     16REDFISH_CREDENTIAL_PRIVATE  *mCredentialPrivate = NULL;
    1717
    1818/**
     
    5252  gBS->CloseEvent (Event);
    5353}
     54
     55EFI_STATUS
     56ReleaseCredentialPrivate (
     57  );
     58
     59EFI_STATUS
     60IterateThroughBootstrapAccounts (
     61  IN  REDFISH_SERVICE  RedfishService
     62  );
    5463
    5564/**
     
    94103
    95104/**
    96   Notify the Redfish service provide to stop provide configuration service to this platform.
     105  Notify the Redfish service provider to stop provide configuration service to this platform.
    97106
    98107  This function should be called when the platfrom is about to leave the safe environment.
     
    125134
    126135/**
     136  Retrieve platform's Redfish authentication information.
     137
     138  This functions returns the Redfish authentication method together with the user Id and
     139  password.
     140  - For AuthMethodNone, the UserId and Password could be used for HTTP header authentication
     141    as defined by RFC7235.
     142  - For AuthMethodRedfishSession, the UserId and Password could be used for Redfish
     143    session login as defined by  Redfish API specification (DSP0266).
     144
     145  Callers are responsible for and freeing the returned string storage.
     146
     147  @param[in]   This                Pointer to EDKII_REDFISH_CREDENTIAL2_PROTOCOL instance.
     148  @param[out]  AuthMethod          Type of Redfish authentication method.
     149  @param[out]  UserId              The pointer to store the returned UserId string.
     150  @param[out]  Password            The pointer to store the returned Password string.
     151
     152  @retval EFI_SUCCESS              Get the authentication information successfully.
     153  @retval EFI_ACCESS_DENIED        SecureBoot is disabled after EndOfDxe.
     154  @retval EFI_INVALID_PARAMETER    This or AuthMethod or UserId or Password is NULL.
     155  @retval EFI_OUT_OF_RESOURCES     There are not enough memory resources.
     156  @retval EFI_UNSUPPORTED          Unsupported authentication method is found.
     157
     158**/
     159EFI_STATUS
     160EFIAPI
     161RedfishCredential2GetAuthInfo (
     162  IN  EDKII_REDFISH_CREDENTIAL2_PROTOCOL  *This,
     163  OUT EDKII_REDFISH_AUTH_METHOD           *AuthMethod,
     164  OUT CHAR8                               **UserId,
     165  OUT CHAR8                               **Password
     166  )
     167{
     168  EFI_STATUS  Status;
     169
     170  if ((AuthMethod == NULL) || (UserId == NULL) || (Password == NULL)) {
     171    return EFI_INVALID_PARAMETER;
     172  }
     173
     174  if (mCredentialPrivate == NULL) {
     175    DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
     176    return EFI_NOT_STARTED;
     177  }
     178
     179  Status = mCredentialPrivate->RedfishCredentialProtocol.GetAuthInfo (
     180                                                           &mCredentialPrivate->RedfishCredentialProtocol,
     181                                                           AuthMethod,
     182                                                           UserId,
     183                                                           Password
     184                                                           );
     185  if (EFI_ERROR (Status)) {
     186    DEBUG ((DEBUG_ERROR, "%a: Failed to retrieve Redfish credential - %r\n", __func__, Status));
     187  }
     188
     189  return Status;
     190}
     191
     192/**
     193  Notifies the Redfish service provider to stop providing configuration service to this platform.
     194  Deletes the bootstrap account on BMC side, so it will not be used by any other driver.
     195
     196  This function should be called when the platfrom is about to leave the safe environment.
     197  It will delete the bootstrap account sending DELETE request to BMC.
     198  It will notify the Redfish service provider to abort all logined session, and prohibit
     199  further login with original auth info. GetAuthInfo() will return EFI_UNSUPPORTED once this
     200  function is returned.
     201
     202  @param[in]   This                Pointer to EDKII_REDFISH_CREDENTIAL2_PROTOCOL instance.
     203  @param[in]   ServiceStopType     Reason of stopping Redfish service.
     204
     205  @retval EFI_SUCCESS              Service has been stoped successfully.
     206  @retval EFI_INVALID_PARAMETER    This is NULL or given the worng ServiceStopType.
     207  @retval EFI_UNSUPPORTED          Not support to stop Redfish service.
     208  @retval Others                   Some error happened.
     209
     210**/
     211EFI_STATUS
     212EFIAPI
     213RedfishCredential2StopService (
     214  IN     EDKII_REDFISH_CREDENTIAL2_PROTOCOL          *This,
     215  IN     EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE  ServiceStopType
     216  )
     217{
     218  EFI_STATUS            Status;
     219  REDFISH_SERVICE_LIST  *Instance;
     220
     221  if (mCredentialPrivate == NULL) {
     222    DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
     223    return EFI_NOT_STARTED;
     224  }
     225
     226  if ((ServiceStopType == ServiceStopTypeExitBootService) ||
     227      (ServiceStopType == ServiceStopTypeNone))
     228  {
     229    // Check PCD and skip the action if platform library is responsible for deleting account
     230    // on exit boot service event
     231    if (FixedPcdGetBool (PcdRedfishCredentialDeleteAccount)) {
     232      if (!IsListEmpty (&mCredentialPrivate->RedfishServiceList)) {
     233        Instance = (REDFISH_SERVICE_LIST *)GetFirstNode (&mCredentialPrivate->RedfishServiceList);
     234        IterateThroughBootstrapAccounts (Instance->RedfishService);
     235      }
     236
     237      ReleaseCredentialPrivate ();
     238    }
     239  }
     240
     241  Status = mCredentialPrivate->RedfishCredentialProtocol.StopService (
     242                                                           &mCredentialPrivate->RedfishCredentialProtocol,
     243                                                           ServiceStopType
     244                                                           );
     245  if (EFI_ERROR (Status)) {
     246    DEBUG ((DEBUG_ERROR, "%a: Failed to stop service - %r\n", __func__, Status));
     247  }
     248
     249  return Status;
     250}
     251
     252/**
     253  Function sends DELETE request to BMC for the account defined by the target URI.
     254
     255  @param[in]  RedfishService       Pointer to Redfish Service to be used
     256                                   for sending DELETE request to BMC.
     257  @param[in]  TargetUri            URI of bootstrap account to send DELETE request to.
     258
     259**/
     260EFI_STATUS
     261EFIAPI
     262DeleteRedfishBootstrapAccount (
     263  IN REDFISH_SERVICE  RedfishService,
     264  IN CHAR16           *TargetUri
     265  )
     266{
     267  EFI_STATUS        Status;
     268  REDFISH_RESPONSE  RedfishResponse;
     269
     270  if (mCredentialPrivate == NULL) {
     271    DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
     272    return EFI_NOT_STARTED;
     273  }
     274
     275  if ((RedfishService == NULL) || (mCredentialPrivate->AuthMethod != AuthMethodHttpBasic)) {
     276    DEBUG ((DEBUG_ERROR, "%a: Redfish service is not available\n", __func__));
     277    return EFI_INVALID_PARAMETER;
     278  }
     279
     280  //
     281  // Remove bootstrap account at /redfish/v1/AccountService/AccountId
     282  //
     283  ZeroMem (&RedfishResponse, sizeof (REDFISH_RESPONSE));
     284  Status = RedfishHttpDeleteResourceEx (
     285             RedfishService,
     286             TargetUri,
     287             "{}",
     288             2,
     289             NULL,
     290             &RedfishResponse
     291             );
     292  if (EFI_ERROR (Status)) {
     293    DEBUG ((DEBUG_ERROR, "%a: can not remove bootstrap account at BMC: %r", __func__, Status));
     294    DumpRedfishResponse (__func__, DEBUG_ERROR, &RedfishResponse);
     295  } else {
     296    DEBUG (
     297      (REDFISH_CREDENTIAL_DEBUG, "%a: bootstrap account: %a is removed from: %s\nURI - %s",
     298       __func__, mCredentialPrivate->AccountName, REDFISH_MANAGER_ACCOUNT_COLLECTION_URI, TargetUri)
     299      );
     300  }
     301
     302  RedfishHttpFreeResponse (&RedfishResponse);
     303
     304  return Status;
     305}
     306
     307/**
     308  Get the information about specific Account.
     309  Checks the User Name and if name matches delete that account
     310
     311
     312  @param[in]  RedfishService       Pointer to Redfish Service to be used
     313                                   for sending DELETE request to BMC.
     314  @param[in]  AccountUri           URI of bootstrap account to verify.
     315
     316**/
     317BOOLEAN
     318ProcessRedfishBootstarpAccount (
     319  IN REDFISH_SERVICE  RedfishService,
     320  IN EFI_STRING       AccountUri
     321  )
     322{
     323  EDKII_JSON_VALUE  JsonUserName;
     324  EDKII_JSON_VALUE  JsonValue;
     325  EFI_STATUS        Status;
     326  REDFISH_RESPONSE  RedfishResponse;
     327  REDFISH_REQUEST   RedfishRequest;
     328  BOOLEAN           Ret;
     329
     330  if (mCredentialPrivate == NULL) {
     331    DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
     332    return FALSE;
     333  }
     334
     335  if ((RedfishService == NULL) || IS_EMPTY_STRING (AccountUri) ||
     336      (mCredentialPrivate->AuthMethod != AuthMethodHttpBasic))
     337  {
     338    return FALSE;
     339  }
     340
     341  ZeroMem (&RedfishResponse, sizeof (REDFISH_RESPONSE));
     342  ZeroMem (&RedfishRequest, sizeof (REDFISH_REQUEST));
     343  Status = RedfishHttpGetResource (RedfishService, AccountUri, &RedfishRequest, &RedfishResponse, FALSE);
     344  if (EFI_ERROR (Status) || (RedfishResponse.Payload == NULL)) {
     345    DEBUG ((DEBUG_ERROR, "%a: can not get account from BMC: %r", __func__, Status));
     346    DumpRedfishResponse (__func__, DEBUG_ERROR, &RedfishResponse);
     347    return FALSE;
     348  }
     349
     350  Ret       = FALSE;
     351  JsonValue = RedfishJsonInPayload (RedfishResponse.Payload);
     352  if (JsonValueIsObject (JsonValue)) {
     353    JsonUserName = JsonObjectGetValue (JsonValueGetObject (JsonValue), "UserName");
     354    if (JsonValueIsString (JsonUserName) && (JsonValueGetAsciiString (JsonUserName) != NULL)) {
     355      if (AsciiStrCmp (mCredentialPrivate->AccountName, JsonValueGetAsciiString (JsonUserName)) == 0) {
     356        DeleteRedfishBootstrapAccount (RedfishService, AccountUri);
     357        Ret = TRUE;
     358      }
     359    }
     360  }
     361
     362  RedfishHttpFreeResponse (&RedfishResponse);
     363  RedfishHttpFreeRequest (&RedfishRequest);
     364
     365  return Ret;
     366}
     367
     368/**
     369  This function returns the string of Redfish service version.
     370
     371  @param[out]  ServiceVersionStr    Redfish service string.
     372
     373  @return     EFI_STATUS
     374
     375**/
     376EFI_STATUS
     377RedfishGetServiceVersion (
     378  OUT CHAR16  **ServiceVersionStr
     379  )
     380{
     381  *ServiceVersionStr = (CHAR16 *)PcdGetPtr (PcdDefaultRedfishVersion);
     382  if (*ServiceVersionStr == NULL) {
     383    *ServiceVersionStr = REDFISH_VERSION_DEFAULT_STRING;
     384  }
     385
     386  return EFI_SUCCESS;
     387}
     388
     389/**
     390  Iterates through all account in the account collection
     391  Get the information about specific Account.
     392  Checks the User Name and if name matches delete that account
     393
     394
     395  @param[in]  RedfishService       Pointer to Redfish Service to be used
     396                                   for sending DELETE request to BMC.
     397
     398**/
     399EFI_STATUS
     400IterateThroughBootstrapAccounts (
     401  IN  REDFISH_SERVICE  RedfishService
     402  )
     403{
     404  EFI_STATUS        Status;
     405  EDKII_JSON_VALUE  JsonMembers;
     406  EDKII_JSON_VALUE  JsonValue;
     407  EDKII_JSON_VALUE  OdataId;
     408  CHAR16            TargetUri[REDFISH_URI_LENGTH];
     409  CHAR16            *RedfishVersion;
     410  REDFISH_RESPONSE  RedfishResponse;
     411  REDFISH_REQUEST   RedfishRequest;
     412  UINTN             MembersCount, Index;
     413
     414  RedfishVersion = NULL;
     415  Status         = EFI_NOT_FOUND;
     416
     417  if (mCredentialPrivate == NULL) {
     418    DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
     419    return EFI_NOT_STARTED;
     420  }
     421
     422  if ((RedfishService == NULL) || (mCredentialPrivate->AuthMethod != AuthMethodHttpBasic) ||
     423      IS_EMPTY_STRING (mCredentialPrivate->AccountName))
     424  {
     425    return EFI_INVALID_PARAMETER;
     426  }
     427
     428  //
     429  // Carving the URI
     430  //
     431
     432  Status = RedfishGetServiceVersion (&RedfishVersion);
     433  if (EFI_ERROR (Status)) {
     434    DEBUG ((DEBUG_ERROR, "%a: can not get Redfish version\n", __func__));
     435    return Status;
     436  }
     437
     438  UnicodeSPrint (
     439    TargetUri,
     440    (sizeof (CHAR16) * REDFISH_URI_LENGTH),
     441    L"/redfish/%s/%s",
     442    RedfishVersion,
     443    REDFISH_MANAGER_ACCOUNT_COLLECTION_URI
     444    );
     445
     446  DEBUG ((REDFISH_CREDENTIAL_DEBUG, "%a: account collection URI: %s\n", __func__, TargetUri));
     447
     448  ZeroMem (&RedfishResponse, sizeof (REDFISH_RESPONSE));
     449  ZeroMem (&RedfishRequest, sizeof (REDFISH_REQUEST));
     450  Status = RedfishHttpGetResource (RedfishService, TargetUri, &RedfishRequest, &RedfishResponse, FALSE);
     451  if (EFI_ERROR (Status) || (RedfishResponse.Payload == NULL)) {
     452    DEBUG ((DEBUG_ERROR, "%a: can not get accounts from BMC: %r\n", __func__, Status));
     453    DumpRedfishResponse (__func__, DEBUG_ERROR, &RedfishResponse);
     454    return Status;
     455  }
     456
     457  JsonValue = RedfishJsonInPayload (RedfishResponse.Payload);
     458  if (!JsonValueIsObject (JsonValue)) {
     459    Status = EFI_LOAD_ERROR;
     460    goto ON_EXIT;
     461  }
     462
     463  JsonMembers = JsonObjectGetValue (JsonValueGetObject (JsonValue), "Members");
     464  if (!JsonValueIsArray (JsonMembers)) {
     465    Status = EFI_LOAD_ERROR;
     466    goto ON_EXIT;
     467  }
     468
     469  Status = EFI_NOT_FOUND;
     470
     471  MembersCount = JsonArrayCount (JsonValueGetArray (JsonMembers));
     472  for (Index = 0; Index < MembersCount; Index++) {
     473    JsonValue = JsonArrayGetValue (JsonValueGetArray (JsonMembers), Index);
     474    if (!JsonValueIsObject (JsonValue)) {
     475      Status = EFI_LOAD_ERROR;
     476      goto ON_EXIT;
     477    }
     478
     479    OdataId = JsonObjectGetValue (JsonValueGetObject (JsonValue), "@odata.id");
     480    if (!JsonValueIsString (OdataId) || (JsonValueGetAsciiString (OdataId) == NULL)) {
     481      Status = EFI_LOAD_ERROR;
     482      goto ON_EXIT;
     483    }
     484
     485    UnicodeSPrint (
     486      TargetUri,
     487      (sizeof (CHAR16) * REDFISH_URI_LENGTH),
     488      L"%a",
     489      JsonValueGetAsciiString (OdataId)
     490      );
     491    DEBUG ((REDFISH_CREDENTIAL_DEBUG, "%a: account URI:        %s\n", __func__, TargetUri));
     492    // Verify bootstrap account User Name and delete the account if User Name matches
     493    if (ProcessRedfishBootstarpAccount (RedfishService, TargetUri)) {
     494      Status = EFI_SUCCESS;
     495      break;
     496    }
     497  }
     498
     499ON_EXIT:
     500
     501  RedfishHttpFreeResponse (&RedfishResponse);
     502  RedfishHttpFreeRequest (&RedfishRequest);
     503
     504  return Status;
     505}
     506
     507/**
     508  Retrieve platform's Redfish authentication information.
     509
     510  This functions returns the Redfish authentication method together with the user Id.
     511  For AuthMethodNone, UserId will point to NULL which means authentication
     512  is not required to access the Redfish service.
     513  Callers are responsible for freeing the returned string storage pointed by UserId.
     514
     515  @param[out]  AuthMethod          Type of Redfish authentication method.
     516  @param[out]  UserId              The pointer to store the returned UserId string.
     517
     518  @retval EFI_SUCCESS              Get the authentication information successfully.
     519  @retval EFI_INVALID_PARAMETER    AuthMethod or UserId or Password is NULL.
     520  @retval EFI_UNSUPPORTED          Unsupported authentication method is found.
     521**/
     522EFI_STATUS
     523RedfishGetAuthConfig (
     524  OUT  EDKII_REDFISH_AUTH_METHOD  *AuthMethod,
     525  OUT  CHAR8                      **UserId
     526  )
     527{
     528  EFI_STATUS  Status;
     529  CHAR8       *Password;
     530
     531  Password = NULL;
     532
     533  if ((AuthMethod == NULL) || (UserId == NULL)) {
     534    return EFI_INVALID_PARAMETER;
     535  }
     536
     537  if (mCredentialPrivate == NULL) {
     538    DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
     539    return EFI_NOT_STARTED;
     540  }
     541
     542  Status = mCredentialPrivate->RedfishCredentialProtocol.GetAuthInfo (
     543                                                           &mCredentialPrivate->RedfishCredentialProtocol,
     544                                                           AuthMethod,
     545                                                           UserId,
     546                                                           &Password
     547                                                           );
     548  if (EFI_ERROR (Status)) {
     549    DEBUG ((DEBUG_ERROR, "%a: failed to retrieve Redfish credential - %r\n", __func__, Status));
     550    return Status;
     551  }
     552
     553  if (Password != NULL) {
     554    ZeroMem (Password, AsciiStrSize (Password));
     555    FreePool (Password);
     556  }
     557
     558  return Status;
     559}
     560
     561/**
     562  This function clears Redfish service internal list.
     563
     564  @retval EFI_SUCCESS              Redfish service is deleted from list successfully.
     565  @retval Others                   Fail to remove the entry
     566
     567**/
     568EFI_STATUS
     569ClearRedfishServiceList (
     570  VOID
     571  )
     572{
     573  REDFISH_SERVICE_LIST  *Instance;
     574  REDFISH_SERVICE_LIST  *NextInstance;
     575
     576  if (mCredentialPrivate == NULL) {
     577    DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
     578    return EFI_NOT_STARTED;
     579  }
     580
     581  if (!IsListEmpty (&mCredentialPrivate->RedfishServiceList)) {
     582    //
     583    // Free memory of REDFISH_SERVICE_LIST instance.
     584    //
     585    Instance = (REDFISH_SERVICE_LIST *)GetFirstNode (&mCredentialPrivate->RedfishServiceList);
     586    do {
     587      NextInstance = NULL;
     588      if (!IsNodeAtEnd (&mCredentialPrivate->RedfishServiceList, &Instance->NextInstance)) {
     589        NextInstance = (REDFISH_SERVICE_LIST *)GetNextNode (
     590                                                 &mCredentialPrivate->RedfishServiceList,
     591                                                 &Instance->NextInstance
     592                                                 );
     593      }
     594
     595      RemoveEntryList (&Instance->NextInstance);
     596      FreePool ((VOID *)Instance);
     597      Instance = NextInstance;
     598    } while (Instance != NULL);
     599  }
     600
     601  return EFI_SUCCESS;
     602}
     603
     604/**
     605  The function adds a new Redfish service to internal list
     606
     607  @param[in]  RedfishService       Pointer to REDFISH_SERVICE to be added to the list.
     608
     609  @retval EFI_SUCCESS              Redfish service is added to list successfully.
     610  @retval EFI_OUT_OF_RESOURCES     Out of resources error.
     611**/
     612EFI_STATUS
     613AddRedfishServiceToList (
     614  IN REDFISH_SERVICE  RedfishService
     615  )
     616{
     617  BOOLEAN               ServiceFound;
     618  REDFISH_SERVICE_LIST  *RedfishServiceInstance;
     619
     620  RedfishServiceInstance = NULL;
     621  ServiceFound           = FALSE;
     622
     623  if (mCredentialPrivate == NULL) {
     624    DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
     625    return EFI_NOT_STARTED;
     626  }
     627
     628  if (!IsListEmpty (&mCredentialPrivate->RedfishServiceList)) {
     629    RedfishServiceInstance = (REDFISH_SERVICE_LIST *)GetFirstNode (&mCredentialPrivate->RedfishServiceList);
     630    do {
     631      if (RedfishServiceInstance->RedfishService == RedfishService) {
     632        ServiceFound = TRUE;
     633        break;
     634      }
     635
     636      if (IsNodeAtEnd (&mCredentialPrivate->RedfishServiceList, &RedfishServiceInstance->NextInstance)) {
     637        break;
     638      }
     639
     640      RedfishServiceInstance = (REDFISH_SERVICE_LIST *)GetNextNode (
     641                                                         &mCredentialPrivate->RedfishServiceList,
     642                                                         &RedfishServiceInstance->NextInstance
     643                                                         );
     644    } while (TRUE);
     645  }
     646
     647  if (!ServiceFound) {
     648    RedfishServiceInstance = (REDFISH_SERVICE_LIST *)AllocateZeroPool (sizeof (REDFISH_SERVICE_LIST));
     649    if (RedfishServiceInstance == NULL) {
     650      return EFI_OUT_OF_RESOURCES;
     651    }
     652
     653    RedfishServiceInstance->RedfishService = RedfishService;
     654    InsertTailList (&mCredentialPrivate->RedfishServiceList, &RedfishServiceInstance->NextInstance);
     655  }
     656
     657  return EFI_SUCCESS;
     658}
     659
     660/**
     661  This function deletes Redfish service from internal list.
     662
     663  @param[in]  RedfishService       Pointer to REDFISH_SERVICE to be delete from the list.
     664
     665  @retval EFI_SUCCESS              Redfish service is deleted from list successfully.
     666  @retval Others                   Fail to remove the entry
     667
     668**/
     669EFI_STATUS
     670DeleteRedfishServiceFromList (
     671  IN REDFISH_SERVICE  RedfishService
     672  )
     673{
     674  REDFISH_SERVICE_LIST  *RedfishServiceInstance;
     675
     676  if (mCredentialPrivate == NULL) {
     677    DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
     678    return EFI_NOT_STARTED;
     679  }
     680
     681  if (!IsListEmpty (&mCredentialPrivate->RedfishServiceList)) {
     682    RedfishServiceInstance = (REDFISH_SERVICE_LIST *)GetFirstNode (&mCredentialPrivate->RedfishServiceList);
     683    do {
     684      if (RedfishServiceInstance->RedfishService == RedfishService) {
     685        RemoveEntryList (&RedfishServiceInstance->NextInstance);
     686        FreePool (RedfishServiceInstance);
     687        return EFI_SUCCESS;
     688      }
     689
     690      if (IsNodeAtEnd (&mCredentialPrivate->RedfishServiceList, &RedfishServiceInstance->NextInstance)) {
     691        break;
     692      }
     693
     694      RedfishServiceInstance = (REDFISH_SERVICE_LIST *)GetNextNode (&mCredentialPrivate->RedfishServiceList, &RedfishServiceInstance->NextInstance);
     695    } while (TRUE);
     696  }
     697
     698  return EFI_NOT_FOUND;
     699}
     700
     701/**
     702  Register Redfish service instance so protocol knows that some module uses bootstrap account.
     703
     704  @param[in]  This              Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance.
     705  @param[in]  RedfishService    Redfish service instance to register.
     706
     707  @retval EFI_SUCCESS           This Redfish service instance has been registered successfully.
     708  @retval Others                Fail to register Redfish Service
     709
     710**/
     711EFI_STATUS
     712EFIAPI
     713RedfishCredential2RegisterService (
     714  IN  EDKII_REDFISH_CREDENTIAL2_PROTOCOL  *This,
     715  IN  REDFISH_SERVICE                     RedfishService
     716  )
     717{
     718  EFI_STATUS  Status;
     719
     720  Status = EFI_SUCCESS;
     721
     722  if (mCredentialPrivate == NULL) {
     723    DEBUG ((DEBUG_ERROR, "%a: failed with error - %r\n", __func__, EFI_NOT_STARTED));
     724    return EFI_NOT_STARTED;
     725  }
     726
     727  // Check if AuthMethod has been initialized yet
     728  if (mCredentialPrivate->AuthMethod == AuthMethodMax) {
     729    Status = RedfishGetAuthConfig (
     730               &mCredentialPrivate->AuthMethod,
     731               &mCredentialPrivate->AccountName
     732               );
     733  }
     734
     735  // Bootstrap account should be deleted only if Basic Authentication is used.
     736  if (!EFI_ERROR (Status) && (mCredentialPrivate->AuthMethod == AuthMethodHttpBasic)) {
     737    Status = AddRedfishServiceToList (RedfishService);
     738    if (EFI_ERROR (Status)) {
     739      DEBUG ((DEBUG_ERROR, "%a: Failed to register Redfish service - %r\n", __func__, Status));
     740    }
     741  }
     742
     743  return Status;
     744}
     745
     746/**
     747  Unregister Redfish service instance and delete the bootstrap account
     748  when all registered services unregistered.
     749
     750  @param[in]  This              Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance.
     751  @param[in]  RedfishService    Redfish service instance to unregister.
     752
     753  @retval EFI_SUCCESS           This Redfish service instance has been unregistered successfully.
     754  @retval Others                Fail to unregister Redfish Service
     755
     756**/
     757EFI_STATUS
     758EFIAPI
     759RedfishCredential2UnregisterService (
     760  IN  EDKII_REDFISH_CREDENTIAL2_PROTOCOL  *This,
     761  IN  REDFISH_SERVICE                     RedfishService
     762  )
     763{
     764  EFI_STATUS  Status;
     765
     766  // Bootstrap account should be deleted only if Basic Authentication is used.
     767  if (mCredentialPrivate->AuthMethod != AuthMethodHttpBasic) {
     768    return EFI_SUCCESS;
     769  }
     770
     771  // Delete Redfish Service from the registered list
     772  Status = DeleteRedfishServiceFromList (RedfishService);
     773  // Check if registered list is empty
     774  if (IsListEmpty (&mCredentialPrivate->RedfishServiceList)) {
     775    // Iterate through all accounts in the account collection and delete the bootstrap account
     776    Status = IterateThroughBootstrapAccounts (RedfishService);
     777    if (!EFI_ERROR (Status)) {
     778      if (mCredentialPrivate->AccountName != NULL) {
     779        ZeroMem (mCredentialPrivate->AccountName, AsciiStrSize (mCredentialPrivate->AccountName));
     780        FreePool (mCredentialPrivate->AccountName);
     781        mCredentialPrivate->AccountName = NULL;
     782      }
     783
     784      mCredentialPrivate->AuthMethod = AuthMethodMax;
     785      Status                         = mCredentialPrivate->RedfishCredentialProtocol.StopService (
     786                                                                                       &mCredentialPrivate->RedfishCredentialProtocol,
     787                                                                                       ServiceStopTypeNone
     788                                                                                       );
     789      if (EFI_ERROR (Status)) {
     790        DEBUG ((DEBUG_ERROR, "%a: Failed to stop service - %r\n", __func__, Status));
     791      }
     792    }
     793  }
     794
     795  return Status;
     796}
     797
     798/**
    127799  Main entry for this driver.
    128800
     
    141813{
    142814  EFI_STATUS  Status;
    143   EFI_HANDLE  Handle;
    144   EFI_EVENT   EndOfDxeEvent;
    145   EFI_EVENT   ExitBootServiceEvent;
    146 
    147   Handle = NULL;
     815
     816  mCredentialPrivate = (REDFISH_CREDENTIAL_PRIVATE *)AllocateZeroPool (sizeof (REDFISH_CREDENTIAL_PRIVATE));
     817  if (mCredentialPrivate == NULL) {
     818    return EFI_OUT_OF_RESOURCES;
     819  }
     820
     821  mCredentialPrivate->AuthMethod = AuthMethodMax;
     822  InitializeListHead (&mCredentialPrivate->RedfishServiceList);
     823
     824  mCredentialPrivate->RedfishCredentialProtocol.GetAuthInfo = RedfishCredentialGetAuthInfo;
     825  mCredentialPrivate->RedfishCredentialProtocol.StopService = RedfishCredentialStopService;
     826
     827  mCredentialPrivate->RedfishCredential2Protocol.Revision                 = REDFISH_CREDENTIAL_PROTOCOL_REVISION;
     828  mCredentialPrivate->RedfishCredential2Protocol.GetAuthInfo              = RedfishCredential2GetAuthInfo;
     829  mCredentialPrivate->RedfishCredential2Protocol.StopService              = RedfishCredential2StopService;
     830  mCredentialPrivate->RedfishCredential2Protocol.RegisterRedfishService   = RedfishCredential2RegisterService;
     831  mCredentialPrivate->RedfishCredential2Protocol.UnregisterRedfishService = RedfishCredential2UnregisterService;
    148832
    149833  //
     
    151835  //
    152836  Status = gBS->InstallMultipleProtocolInterfaces (
    153                   &Handle,
     837                  &mCredentialPrivate->Handle,
    154838                  &gEdkIIRedfishCredentialProtocolGuid,
    155                   &mRedfishCredentialProtocol,
     839                  &mCredentialPrivate->RedfishCredentialProtocol,
     840                  &gEdkIIRedfishCredential2ProtocolGuid,
     841                  &mCredentialPrivate->RedfishCredential2Protocol,
    156842                  NULL
    157843                  );
     
    170856                  TPL_CALLBACK,
    171857                  RedfishCredentialEndOfDxeEventNotify,
    172                   (VOID *)&mRedfishCredentialProtocol,
     858                  (VOID *)&mCredentialPrivate->RedfishCredentialProtocol,
    173859                  &gEfiEndOfDxeEventGroupGuid,
    174                   &EndOfDxeEvent
     860                  &mCredentialPrivate->EndOfDxeEvent
    175861                  );
    176862  if (EFI_ERROR (Status)) {
     
    186872                  TPL_CALLBACK,
    187873                  RedfishCredentialExitBootServicesEventNotify,
    188                   (VOID *)&mRedfishCredentialProtocol,
     874                  (VOID *)&mCredentialPrivate->RedfishCredentialProtocol,
    189875                  &gEfiEventExitBootServicesGuid,
    190                   &ExitBootServiceEvent
     876                  &mCredentialPrivate->ExitBootServiceEvent
    191877                  );
    192878  if (EFI_ERROR (Status)) {
    193     gBS->CloseEvent (EndOfDxeEvent);
     879    gBS->CloseEvent (mCredentialPrivate->EndOfDxeEvent);
     880    mCredentialPrivate->EndOfDxeEvent = NULL;
    194881    goto ON_ERROR;
    195882  }
     
    200887
    201888  gBS->UninstallMultipleProtocolInterfaces (
    202          Handle,
     889         mCredentialPrivate->Handle,
    203890         &gEdkIIRedfishCredentialProtocolGuid,
    204          &mRedfishCredentialProtocol,
     891         &mCredentialPrivate->RedfishCredentialProtocol,
     892         &gEdkIIRedfishCredential2ProtocolGuid,
     893         &mCredentialPrivate->RedfishCredential2Protocol,
    205894         NULL
    206895         );
    207896
     897  FreePool (mCredentialPrivate);
     898
    208899  return Status;
    209900}
     901
     902/**
     903  Releases all resources allocated by the module.
     904  Uninstall all the protocols installed in the driver entry point.
     905
     906  @retval    EFI_SUCCESS           The resources are released.
     907  @retval    Others                Failed to release the resources.
     908
     909**/
     910EFI_STATUS
     911ReleaseCredentialPrivate (
     912  )
     913{
     914  if (mCredentialPrivate != NULL) {
     915    if (mCredentialPrivate->AccountName != NULL) {
     916      ZeroMem (mCredentialPrivate->AccountName, AsciiStrSize (mCredentialPrivate->AccountName));
     917      FreePool (mCredentialPrivate->AccountName);
     918      mCredentialPrivate->AccountName = NULL;
     919    }
     920
     921    ClearRedfishServiceList ();
     922  }
     923
     924  return EFI_SUCCESS;
     925}
     926
     927/**
     928  This is the unload handle for Redfish Credentials module.
     929
     930  Uninstall all the protocols installed in the driver entry point.
     931  Clear all allocated resources.
     932
     933  @param[in] ImageHandle           The drivers' driver image.
     934
     935  @retval    EFI_SUCCESS           The image is unloaded.
     936  @retval    Others                Failed to unload the image.
     937
     938**/
     939EFI_STATUS
     940EFIAPI
     941RedfishCredentialDxeDriverUnload (
     942  IN EFI_HANDLE  ImageHandle
     943  )
     944{
     945  if (mCredentialPrivate != NULL) {
     946    gBS->UninstallMultipleProtocolInterfaces (
     947           mCredentialPrivate->Handle,
     948           &gEdkIIRedfishCredentialProtocolGuid,
     949           &mCredentialPrivate->RedfishCredentialProtocol,
     950           &gEdkIIRedfishCredential2ProtocolGuid,
     951           &mCredentialPrivate->RedfishCredential2Protocol,
     952           NULL
     953           );
     954
     955    if (mCredentialPrivate->EndOfDxeEvent != NULL) {
     956      gBS->CloseEvent (mCredentialPrivate->EndOfDxeEvent);
     957      mCredentialPrivate->EndOfDxeEvent = NULL;
     958    }
     959
     960    if (mCredentialPrivate->ExitBootServiceEvent != NULL) {
     961      gBS->CloseEvent (mCredentialPrivate->ExitBootServiceEvent);
     962      mCredentialPrivate->ExitBootServiceEvent = NULL;
     963    }
     964
     965    ReleaseCredentialPrivate ();
     966
     967    FreePool (mCredentialPrivate);
     968    mCredentialPrivate = NULL;
     969  }
     970
     971  return EFI_SUCCESS;
     972}
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette