From 7f0fc4189a4abe252ea1ca9054ae5c49480f1a4c Mon Sep 17 00:00:00 2001 From: Saloni Kasbekar Date: Fri, 16 Dec 2022 18:47:19 +0100 Subject: [PATCH] NetworkPkg/HttpBootDxe: Use ProxyUri from HII to build boot option Build boot option with HII provided ProxyUri by utilizing URI validation path in HII callback for ProxyUri. Implementation based on UEFI Specification v2.11 Section 24.7.3.1 to use device path with ProxyURI included Signed-off-by: Saloni Kasbekar --- NetworkPkg/HttpBootDxe/HttpBootConfig.c | 107 ++++++++++++++++++------ 1 file changed, 81 insertions(+), 26 deletions(-) diff --git a/NetworkPkg/HttpBootDxe/HttpBootConfig.c b/NetworkPkg/HttpBootDxe/HttpBootConfig.c index 42d3fdc1fb..e92fee5961 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootConfig.c +++ b/NetworkPkg/HttpBootDxe/HttpBootConfig.c @@ -18,6 +18,7 @@ CHAR16 mHttpBootConfigStorageName[] = L"HTTP_BOOT_CONFIG_IFR_NVDATA"; @param[in] UsingIpv6 Set to TRUE if creating boot option for IPv6. @param[in] Description The description text of the boot option. @param[in] Uri The URI string of the boot file. + @param[in] ProxyUri The Proxy URI string for the boot path. @retval EFI_SUCCESS The boot option is created successfully. @retval Others Failed to create new boot option. @@ -28,48 +29,61 @@ HttpBootAddBootOption ( IN HTTP_BOOT_PRIVATE_DATA *Private, IN BOOLEAN UsingIpv6, IN CHAR16 *Description, - IN CHAR16 *Uri + IN CHAR16 *Uri, + IN CHAR16 *ProxyUri ) { EFI_DEV_PATH *Node; EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath; EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; + EFI_DEVICE_PATH_PROTOCOL *FinalDevicePath; UINTN Length; CHAR8 AsciiUri[URI_STR_MAX_SIZE]; + CHAR8 AsciiProxyUri[URI_STR_MAX_SIZE]; + UINTN AsciiProxyUriSize; EFI_STATUS Status; - UINTN Index; EFI_BOOT_MANAGER_LOAD_OPTION NewOption; - NewDevicePath = NULL; - Node = NULL; - TmpDevicePath = NULL; + NewDevicePath = NULL; + Node = NULL; + TmpDevicePath = NULL; + FinalDevicePath = NULL; if (StrLen (Description) == 0) { return EFI_INVALID_PARAMETER; } // - // Convert the scheme to all lower case. + // Check the URI Scheme // - for (Index = 0; Index < StrLen (Uri); Index++) { - if (Uri[Index] == L':') { - break; + UnicodeStrToAsciiStrS (Uri, AsciiUri, sizeof (AsciiUri)); + UnicodeStrToAsciiStrS (ProxyUri, AsciiProxyUri, sizeof (AsciiProxyUri)); + Status = HttpBootCheckUriScheme (AsciiUri); + if (EFI_ERROR (Status)) { + if (Status == EFI_INVALID_PARAMETER) { + DEBUG ((DEBUG_ERROR, "Error: Invalid URI address.\n")); + } else if (Status == EFI_ACCESS_DENIED) { + DEBUG ((DEBUG_ERROR, "Error: Access forbidden, only HTTPS connection is allowed.\n")); } - if ((Uri[Index] >= L'A') && (Uri[Index] <= L'Z')) { - Uri[Index] -= (CHAR16)(L'A' - L'a'); + return Status; + } + + if (StrLen (ProxyUri) != 0) { + Status = HttpBootCheckUriScheme (AsciiProxyUri); + if (EFI_ERROR (Status)) { + if (Status == EFI_INVALID_PARAMETER) { + DEBUG ((DEBUG_ERROR, "Error: Invalid URI address.\n")); + } else if (Status == EFI_ACCESS_DENIED) { + DEBUG ((DEBUG_ERROR, "Error: Access forbidden, only HTTPS connection is allowed.\n")); + } + + return Status; } } // - // Only accept empty URI, or http and https URI. - // - if ((StrLen (Uri) != 0) && (StrnCmp (Uri, L"http://", 7) != 0) && (StrnCmp (Uri, L"https://", 8) != 0)) { - return EFI_INVALID_PARAMETER; - } - - // - // Create a new device path by appending the IP node and URI node to + // Create a new device path by appending the IP node, Proxy node and URI node to // the driver's parent device path // if (!UsingIpv6) { @@ -100,15 +114,43 @@ HttpBootAddBootOption ( return EFI_OUT_OF_RESOURCES; } + // + // Update the Proxy node with the input Proxy URI + // + if (StrLen (ProxyUri) != 0) { + AsciiProxyUriSize = AsciiStrSize (AsciiProxyUri); + Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) + AsciiProxyUriSize; + Node = AllocatePool (Length); + if (Node == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + Node->DevPath.Type = MESSAGING_DEVICE_PATH; + Node->DevPath.SubType = MSG_URI_DP; + SetDevicePathNodeLength (Node, Length); + CopyMem ( + (UINT8 *)Node + sizeof (EFI_DEVICE_PATH_PROTOCOL), + AsciiProxyUri, + AsciiProxyUriSize + ); + NewDevicePath = AppendDevicePathNode (TmpDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)Node); + FreePool (Node); + if (NewDevicePath == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + } else { + NewDevicePath = TmpDevicePath; + } + // // Update the URI node with the input boot file URI. // - UnicodeStrToAsciiStrS (Uri, AsciiUri, sizeof (AsciiUri)); Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) + AsciiStrSize (AsciiUri); Node = AllocatePool (Length); if (Node == NULL) { Status = EFI_OUT_OF_RESOURCES; - FreePool (TmpDevicePath); goto ON_EXIT; } @@ -116,10 +158,9 @@ HttpBootAddBootOption ( Node->DevPath.SubType = MSG_URI_DP; SetDevicePathNodeLength (Node, Length); CopyMem ((UINT8 *)Node + sizeof (EFI_DEVICE_PATH_PROTOCOL), AsciiUri, AsciiStrSize (AsciiUri)); - NewDevicePath = AppendDevicePathNode (TmpDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)Node); + FinalDevicePath = AppendDevicePathNode (NewDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)Node); FreePool (Node); - FreePool (TmpDevicePath); - if (NewDevicePath == NULL) { + if (FinalDevicePath == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } @@ -133,7 +174,7 @@ HttpBootAddBootOption ( LoadOptionTypeBoot, LOAD_OPTION_ACTIVE, Description, - NewDevicePath, + FinalDevicePath, NULL, 0 ); @@ -146,10 +187,22 @@ HttpBootAddBootOption ( ON_EXIT: + if (TmpDevicePath != NULL) { + if (TmpDevicePath == NewDevicePath) { + NewDevicePath = NULL; + } + + FreePool (TmpDevicePath); + } + if (NewDevicePath != NULL) { FreePool (NewDevicePath); } + if (FinalDevicePath != NULL) { + FreePool (FinalDevicePath); + } + return Status; } @@ -406,7 +459,8 @@ HttpBootFormRouteConfig ( Private, (CallbackInfo->HttpBootNvData.IpVersion == HTTP_BOOT_IP_VERSION_6) ? TRUE : FALSE, CallbackInfo->HttpBootNvData.Description, - CallbackInfo->HttpBootNvData.Uri + CallbackInfo->HttpBootNvData.Uri, + CallbackInfo->HttpBootNvData.ProxyUri ); return EFI_SUCCESS; @@ -472,6 +526,7 @@ HttpBootFormCallback ( switch (QuestionId) { case KEY_INITIATOR_URI: + case KEY_INITIATOR_PROXY_URI: // // Get user input URI string //