|
|
5d780f |
From 9788a62272269242d07151df490935e5bf0a4e6a Mon Sep 17 00:00:00 2001
|
|
|
5d780f |
From: Javier Martinez Canillas <javierm@redhat.com>
|
|
|
5d780f |
Date: Thu, 5 Mar 2020 16:21:58 +0100
|
|
|
5d780f |
Subject: [PATCH 3/3] efi/http: Enclose literal IPv6 addresses in square
|
|
|
5d780f |
brackets
|
|
|
5d780f |
|
|
|
5d780f |
According to RFC 2732 (https://www.ietf.org/rfc/rfc2732.txt), literal IPv6
|
|
|
5d780f |
addresses must be enclosed in square brackets. But GRUB currently does not
|
|
|
5d780f |
do this and is causing HTTP servers to send Bad Request (400) responses.
|
|
|
5d780f |
|
|
|
5d780f |
For example, the following is the HTTP stream when fetching a config file:
|
|
|
5d780f |
|
|
|
5d780f |
HEAD /EFI/BOOT/grub.cfg HTTP/1.1
|
|
|
5d780f |
Host: 2000:dead:beef:a::1
|
|
|
5d780f |
Accept: */*
|
|
|
5d780f |
User-Agent: UefiHttpBoot/1.0
|
|
|
5d780f |
|
|
|
5d780f |
HTTP/1.1 400 Bad Request
|
|
|
5d780f |
Date: Thu, 05 Mar 2020 14:46:02 GMT
|
|
|
5d780f |
Server: Apache/2.4.41 (Fedora) OpenSSL/1.1.1d
|
|
|
5d780f |
Connection: close
|
|
|
5d780f |
Content-Type: text/html; charset=iso-8859-1
|
|
|
5d780f |
|
|
|
5d780f |
and after enclosing the IPv6 address the HTTP request is successful:
|
|
|
5d780f |
|
|
|
5d780f |
GET /EFI/BOOT/grub.cfg HTTP/1.1
|
|
|
5d780f |
Host: [2000:dead:beef:a::1]
|
|
|
5d780f |
Accept: */*
|
|
|
5d780f |
User-Agent: UefiHttpBoot/1.0
|
|
|
5d780f |
|
|
|
5d780f |
HTTP/1.1 200 OK
|
|
|
5d780f |
Date: Thu, 05 Mar 2020 14:48:04 GMT
|
|
|
5d780f |
Server: Apache/2.4.41 (Fedora) OpenSSL/1.1.1d
|
|
|
5d780f |
Last-Modified: Thu, 27 Feb 2020 17:45:58 GMT
|
|
|
5d780f |
ETag: "206-59f924b24b1da"
|
|
|
5d780f |
Accept-Ranges: bytes
|
|
|
5d780f |
Content-Length: 518
|
|
|
5d780f |
|
|
|
5d780f |
Resolves: rhbz#1732765
|
|
|
5d780f |
|
|
|
5d780f |
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
|
|
5d780f |
---
|
|
|
5d780f |
grub-core/net/efi/http.c | 37 ++++++++++++++++++++++++++++---------
|
|
|
5d780f |
1 file changed, 28 insertions(+), 9 deletions(-)
|
|
|
5d780f |
|
|
|
5d780f |
diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c
|
|
|
5d780f |
index 755b7a6d054..fc8cb25ae0a 100644
|
|
|
5d780f |
--- a/grub-core/net/efi/http.c
|
|
|
5d780f |
+++ b/grub-core/net/efi/http.c
|
|
|
5d780f |
@@ -158,13 +158,7 @@ efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https,
|
|
|
5d780f |
grub_efi_status_t status;
|
|
|
5d780f |
grub_efi_boot_services_t *b = grub_efi_system_table->boot_services;
|
|
|
5d780f |
char *url = NULL;
|
|
|
5d780f |
-
|
|
|
5d780f |
- request_headers[0].field_name = (grub_efi_char8_t *)"Host";
|
|
|
5d780f |
- request_headers[0].field_value = (grub_efi_char8_t *)server;
|
|
|
5d780f |
- request_headers[1].field_name = (grub_efi_char8_t *)"Accept";
|
|
|
5d780f |
- request_headers[1].field_value = (grub_efi_char8_t *)"*/*";
|
|
|
5d780f |
- request_headers[2].field_name = (grub_efi_char8_t *)"User-Agent";
|
|
|
5d780f |
- request_headers[2].field_value = (grub_efi_char8_t *)"UefiHttpBoot/1.0";
|
|
|
5d780f |
+ char *hostname = NULL;
|
|
|
5d780f |
|
|
|
5d780f |
{
|
|
|
5d780f |
grub_efi_ipv6_address_t address;
|
|
|
5d780f |
@@ -174,9 +168,24 @@ efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https,
|
|
|
5d780f |
const char *protocol = (use_https == 1) ? "https" : "http";
|
|
|
5d780f |
|
|
|
5d780f |
if (grub_efi_string_to_ip6_address (server, &address, &rest) && *rest == 0)
|
|
|
5d780f |
- url = grub_xasprintf ("%s://[%s]%s", protocol, server, name);
|
|
|
5d780f |
+ {
|
|
|
5d780f |
+ hostname = grub_xasprintf ("[%s]", server);
|
|
|
5d780f |
+ if (!hostname)
|
|
|
5d780f |
+ return GRUB_ERR_OUT_OF_MEMORY;
|
|
|
5d780f |
+
|
|
|
5d780f |
+ server = hostname;
|
|
|
5d780f |
+
|
|
|
5d780f |
+ url = grub_xasprintf ("%s://%s%s", protocol, server, name);
|
|
|
5d780f |
+ if (!url)
|
|
|
5d780f |
+ {
|
|
|
5d780f |
+ grub_free (hostname);
|
|
|
5d780f |
+ return GRUB_ERR_OUT_OF_MEMORY;
|
|
|
5d780f |
+ }
|
|
|
5d780f |
+ }
|
|
|
5d780f |
else
|
|
|
5d780f |
- url = grub_xasprintf ("%s://%s%s", protocol, server, name);
|
|
|
5d780f |
+ {
|
|
|
5d780f |
+ url = grub_xasprintf ("%s://%s%s", protocol, server, name);
|
|
|
5d780f |
+ }
|
|
|
5d780f |
|
|
|
5d780f |
if (!url)
|
|
|
5d780f |
{
|
|
|
5d780f |
@@ -199,6 +208,13 @@ efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https,
|
|
|
5d780f |
request_data.url = ucs2_url;
|
|
|
5d780f |
}
|
|
|
5d780f |
|
|
|
5d780f |
+ request_headers[0].field_name = (grub_efi_char8_t *)"Host";
|
|
|
5d780f |
+ request_headers[0].field_value = (grub_efi_char8_t *)server;
|
|
|
5d780f |
+ request_headers[1].field_name = (grub_efi_char8_t *)"Accept";
|
|
|
5d780f |
+ request_headers[1].field_value = (grub_efi_char8_t *)"*/*";
|
|
|
5d780f |
+ request_headers[2].field_name = (grub_efi_char8_t *)"User-Agent";
|
|
|
5d780f |
+ request_headers[2].field_value = (grub_efi_char8_t *)"UefiHttpBoot/1.0";
|
|
|
5d780f |
+
|
|
|
5d780f |
request_data.method = (headeronly > 0) ? GRUB_EFI_HTTPMETHODHEAD : GRUB_EFI_HTTPMETHODGET;
|
|
|
5d780f |
|
|
|
5d780f |
request_message.data.request = &request_data;
|
|
|
5d780f |
@@ -228,6 +244,9 @@ efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https,
|
|
|
5d780f |
|
|
|
5d780f |
status = efi_call_2 (http->request, http, &request_token);
|
|
|
5d780f |
|
|
|
5d780f |
+ if (hostname)
|
|
|
5d780f |
+ grub_free (hostname);
|
|
|
5d780f |
+
|
|
|
5d780f |
if (status != GRUB_EFI_SUCCESS)
|
|
|
5d780f |
{
|
|
|
5d780f |
efi_call_1 (b->close_event, request_token.event);
|
|
|
5d780f |
--
|
|
|
5d780f |
2.24.1
|
|
|
5d780f |
|