@retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry.\r
BufferSize has been updated with the size needed to complete\r
the request.\r
+ @retval EFI_ACCESS_DENIED The server needs to authenticate the client.\r
@retval Others Unexpected error happened.\r
\r
**/\r
CHAR16 *Url;\r
BOOLEAN IdentityMode;\r
UINTN ReceivedSize;\r
+ CHAR8 BaseAuthValue[80];\r
+ EFI_HTTP_HEADER *HttpHeader;\r
+ CHAR8 *Data;\r
\r
ASSERT (Private != NULL);\r
ASSERT (Private->HttpCreated);\r
// Host\r
// Accept\r
// User-Agent\r
+ // [Authorization]\r
//\r
- HttpIoHeader = HttpIoCreateHeader (3);\r
+ HttpIoHeader = HttpIoCreateHeader ((Private->AuthData != NULL) ? 4 : 3);\r
if (HttpIoHeader == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto ERROR_2;\r
goto ERROR_3;\r
}\r
\r
+ //\r
+ // Add HTTP header field 4: Authorization\r
+ //\r
+ if (Private->AuthData != NULL) {\r
+ ASSERT (HttpIoHeader->MaxHeaderCount == 4);\r
+\r
+ if ((Private->AuthScheme != NULL) && (CompareMem (Private->AuthScheme, "Basic", 5) != 0)) {\r
+ Status = EFI_UNSUPPORTED;\r
+ goto ERROR_3;\r
+ }\r
+\r
+ AsciiSPrint (\r
+ BaseAuthValue,\r
+ sizeof (BaseAuthValue),\r
+ "%a %a",\r
+ "Basic",\r
+ Private->AuthData\r
+ );\r
+\r
+ Status = HttpIoSetHeader (\r
+ HttpIoHeader,\r
+ HTTP_HEADER_AUTHORIZATION,\r
+ BaseAuthValue\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ERROR_3;\r
+ }\r
+ }\r
+\r
//\r
// 2.2 Build the rest of HTTP request info.\r
//\r
goto ERROR_4;\r
}\r
\r
+ Data = NULL;\r
Status = HttpIoRecvResponse (\r
&Private->HttpIo,\r
TRUE,\r
StatusCode = HttpIo->RspToken.Message->Data.Response->StatusCode;\r
HttpBootPrintErrorMessage (StatusCode);\r
Status = ResponseData->Status;\r
+ if ((StatusCode == HTTP_STATUS_401_UNAUTHORIZED) || \\r
+ (StatusCode == HTTP_STATUS_407_PROXY_AUTHENTICATION_REQUIRED))\r
+ {\r
+ if ((Private->AuthData != NULL) || (Private->AuthScheme != NULL)) {\r
+ if (Private->AuthData != NULL) {\r
+ FreePool (Private->AuthData);\r
+ Private->AuthData = NULL;\r
+ }\r
+\r
+ if (Private->AuthScheme != NULL) {\r
+ FreePool (Private->AuthScheme);\r
+ Private->AuthScheme = NULL;\r
+ }\r
+\r
+ Status = EFI_ACCESS_DENIED;\r
+ goto ERROR_4;\r
+ }\r
+\r
+ //\r
+ // Server indicates the user has to provide a user-id and password as a means of identification.\r
+ //\r
+ if (Private->HttpBootCallback != NULL) {\r
+ Data = AllocateZeroPool (sizeof (CHAR8) * HTTP_BOOT_AUTHENTICATION_INFO_MAX_LEN);\r
+ if (Data == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ERROR_4;\r
+ }\r
+\r
+ Status = Private->HttpBootCallback->Callback (\r
+ Private->HttpBootCallback,\r
+ HttpBootHttpAuthInfo,\r
+ TRUE,\r
+ HTTP_BOOT_AUTHENTICATION_INFO_MAX_LEN,\r
+ Data\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ if (Data != NULL) {\r
+ FreePool (Data);\r
+ }\r
+\r
+ goto ERROR_5;\r
+ }\r
+\r
+ Private->AuthData = (CHAR8 *)Data;\r
+ }\r
+\r
+ HttpHeader = HttpFindHeader (\r
+ ResponseData->HeaderCount,\r
+ ResponseData->Headers,\r
+ HTTP_HEADER_WWW_AUTHENTICATE\r
+ );\r
+ if (HttpHeader != NULL) {\r
+ Private->AuthScheme = AllocateZeroPool (AsciiStrLen (HttpHeader->FieldValue) + 1);\r
+ if (Private->AuthScheme == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ CopyMem (Private->AuthScheme, HttpHeader->FieldValue, AsciiStrLen (HttpHeader->FieldValue));\r
+ }\r
+\r
+ Status = EFI_ACCESS_DENIED;\r
+ }\r
}\r
\r
goto ERROR_5;\r
#ifndef __EFI_HTTP_BOOT_HTTP_H__\r
#define __EFI_HTTP_BOOT_HTTP_H__\r
\r
-#define HTTP_BOOT_BLOCK_SIZE 1500\r
-#define HTTP_USER_AGENT_EFI_HTTP_BOOT "UefiHttpBoot/1.0"\r
+#define HTTP_BOOT_BLOCK_SIZE 1500\r
+#define HTTP_USER_AGENT_EFI_HTTP_BOOT "UefiHttpBoot/1.0"\r
+#define HTTP_BOOT_AUTHENTICATION_INFO_MAX_LEN 255\r
\r
//\r
// Record the data length and start address of a data block.\r
@retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry.\r
BufferSize has been updated with the size needed to complete\r
the request.\r
+ @retval EFI_ACCESS_DENIED The server needs to authenticate the client.\r
@retval Others Unexpected error happened.\r
\r
**/\r
NULL,\r
&Private->ImageType\r
);\r
- if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {\r
+ if ((Private->AuthData != NULL) && (Status == EFI_ACCESS_DENIED)) {\r
+ //\r
+ // Try to use HTTP HEAD method again since the Authentication information is provided.\r
+ //\r
+ Status = HttpBootGetBootFile (\r
+ Private,\r
+ TRUE,\r
+ &Private->BootFileSize,\r
+ NULL,\r
+ &Private->ImageType\r
+ );\r
+ } else if ((EFI_ERROR (Status)) && (Status != EFI_BUFFER_TOO_SMALL)) {\r
//\r
// Failed to get file size by HEAD method, may be trunked encoding, try HTTP GET method.\r
//\r
}\r
}\r
\r
+ if (Private->AuthData != NULL) {\r
+ FreePool (Private->AuthData);\r
+ Private->AuthData = NULL;\r
+ }\r
+\r
+ if (Private->AuthScheme != NULL) {\r
+ FreePool (Private->AuthScheme);\r
+ Private->AuthScheme = NULL;\r
+ }\r
+\r
if (Private->DnsServerIp != NULL) {\r
FreePool (Private->DnsServerIp);\r
Private->DnsServerIp = NULL;\r