summaryrefslogtreecommitdiffstats
path: root/EmulatorPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCredentialLib.c
blob: eaf9c56450e11127981d1aa21e476a71c6b2fefb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
/** @file
  EmulaotPkg RedfishPlatformCredentialLib instance

  (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/
#include <Uefi.h>
#include <Library/BaseMemoryLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiLib.h>

#include <Protocol/EdkIIRedfishCredential.h>

#include <Guid/GlobalVariable.h>
#include <Guid/ImageAuthentication.h>

BOOLEAN  mSecureBootDisabled = FALSE;
BOOLEAN  mStopRedfishService = FALSE;

EFI_STATUS
EFIAPI
LibStopRedfishService (
  IN EDKII_REDFISH_CREDENTIAL_PROTOCOL           *This,
  IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE  ServiceStopType
  );

/**
  Return the credential for accessing to Redfish servcice.

  @param[out]  AuthMethod     The authentication method.
  @param[out]  UserId         User ID.
  @param[out]  Password       USer password.

  @retval EFI_SUCCESS              Get the authentication information successfully.
  @retval EFI_OUT_OF_RESOURCES     There are not enough memory resources.

**/
EFI_STATUS
GetRedfishCredential (
  OUT EDKII_REDFISH_AUTH_METHOD  *AuthMethod,
  OUT CHAR8                      **UserId,
  OUT CHAR8                      **Password
  )
{
  UINTN  UserIdSize;
  UINTN  PasswordSize;

  //
  // AuthMethod set to HTTP Basic authentication.
  //
  *AuthMethod = AuthMethodHttpBasic;

  //
  // User ID and Password.
  //
  UserIdSize   = AsciiStrSize ((CHAR8 *)PcdGetPtr (PcdRedfishServieUserId));
  PasswordSize = AsciiStrSize ((CHAR8 *)PcdGetPtr (PcdRedfishServiePassword));
  if ((UserIdSize == 0) || (PasswordSize == 0)) {
    DEBUG ((DEBUG_ERROR, "Incorrect string of UserID or Password for REdfish service.\n"));
    return EFI_INVALID_PARAMETER;
  }

  *UserId = AllocateZeroPool (UserIdSize);
  if (*UserId == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (*UserId, (CHAR8 *)PcdGetPtr (PcdRedfishServieUserId), UserIdSize);

  *Password = AllocateZeroPool (PasswordSize);
  if (*Password == NULL) {
    FreePool (*UserId);
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (*Password, (CHAR8 *)PcdGetPtr (PcdRedfishServiePassword), PasswordSize);
  return EFI_SUCCESS;
}

/**
  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
LibCredentialGetAuthInfo (
  IN  EDKII_REDFISH_CREDENTIAL_PROTOCOL  *This,
  OUT EDKII_REDFISH_AUTH_METHOD          *AuthMethod,
  OUT CHAR8                              **UserId,
  OUT CHAR8                              **Password
  )
{
  EFI_STATUS  Status;

  if ((This == NULL) || (AuthMethod == NULL) || (UserId == NULL) || (Password == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (mStopRedfishService) {
    return EFI_ACCESS_DENIED;
  }

  if (mSecureBootDisabled) {
    Status = LibStopRedfishService (This, ServiceStopTypeSecureBootDisabled);
    if (EFI_ERROR (Status) && (Status != EFI_UNSUPPORTED)) {
      DEBUG ((DEBUG_ERROR, "SecureBoot has been disabled, but failed to stop RedfishService - %r\n", Status));
      return Status;
    }
  }

  Status = GetRedfishCredential (
             AuthMethod,
             UserId,
             Password
             );

  return Status;
}

/**
  Notify the Redfish service 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.
  @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
LibStopRedfishService (
  IN EDKII_REDFISH_CREDENTIAL_PROTOCOL           *This,
  IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE  ServiceStopType
  )
{
  if (ServiceStopType >= ServiceStopTypeMax) {
    return EFI_INVALID_PARAMETER;
  }

  if (ServiceStopType == ServiceStopTypeSecureBootDisabled) {
    //
    // Check platform PCD to determine the action for stopping
    // Redfish service due to secure boot is disabled.
    //
    if (!PcdGetBool (PcdRedfishServieStopIfSecureBootDisabled)) {
      return EFI_UNSUPPORTED;
    } else {
      mStopRedfishService = TRUE;
      DEBUG ((DEBUG_INFO, "EFI Redfish service is stopped due to SecureBoot is disabled!!\n"));
    }
  } else if (ServiceStopType == ServiceStopTypeExitBootService) {
    //
    // Check platform PCD to determine the action for stopping
    // Redfish service due to exit boot service.
    //
    if (PcdGetBool (PcdRedfishServieStopIfExitbootService)) {
      return EFI_UNSUPPORTED;
    } else {
      mStopRedfishService = TRUE;
      DEBUG ((DEBUG_INFO, "EFI Redfish service is stopped due to Exit Boot Service!!\n"));
    }
  } else {
    mStopRedfishService = TRUE;
    DEBUG ((DEBUG_INFO, "EFI Redfish service is stopped without Redfish service stop type!!\n"));
  }

  return EFI_SUCCESS;
}

/**
  Notification of Exit Boot Service.

  @param[in]  This    Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL.
**/
VOID
EFIAPI
LibCredentialExitBootServicesNotify (
  IN  EDKII_REDFISH_CREDENTIAL_PROTOCOL  *This
  )
{
  LibStopRedfishService (This, ServiceStopTypeExitBootService);
}

/**
  Notification of End of DXE.

  @param[in]  This    Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL.
**/
VOID
EFIAPI
LibCredentialEndOfDxeNotify (
  IN  EDKII_REDFISH_CREDENTIAL_PROTOCOL  *This
  )
{
  EFI_STATUS  Status;
  UINT8       *SecureBootVar;

  //
  // Check Secure Boot status and lock Redfish service if Secure Boot is disabled.
  //
  Status = GetVariable2 (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid, (VOID **)&SecureBootVar, NULL);
  if (EFI_ERROR (Status) || (*SecureBootVar != SECURE_BOOT_MODE_ENABLE)) {
    //
    // Secure Boot is disabled
    //
    mSecureBootDisabled = TRUE;
    LibStopRedfishService (This, ServiceStopTypeSecureBootDisabled);
  }
}