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