From ef70f879975d349ca51bb0b9bbfa826e1b0e19bf Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 13 Feb 2009 15:43:17 +0000 Subject: [PATCH] [http] Add support for HTTP Basic authentication --- src/net/tcp/http.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/net/tcp/http.c b/src/net/tcp/http.c index 46b5077a..1052400e 100644 --- a/src/net/tcp/http.c +++ b/src/net/tcp/http.c @@ -41,6 +41,7 @@ #include #include #include +#include #include FEATURE ( FEATURE_PROTOCOL, "HTTP", DHCP_EB_FEATURE_HTTP, 1 ); @@ -142,6 +143,8 @@ static int http_response_to_rc ( unsigned int response ) { return -ENOENT; case 403: return -EPERM; + case 401: + return -EACCES; default: return -EIO; } @@ -387,18 +390,43 @@ static void http_step ( struct process *process ) { const char *path = http->uri->path; const char *host = http->uri->host; const char *query = http->uri->query; + const char *user = http->uri->user; + const char *password = http->uri->password; + size_t user_pw_len = ( ( user && password ) ? + ( strlen ( user ) + 1 /* ":" */ + + strlen ( password ) ) : 0 ); + size_t user_pw_base64_len = base64_encoded_len ( user_pw_len ); + char user_pw[ user_pw_len + 1 /* NUL */ ]; + char user_pw_base64[ user_pw_base64_len + 1 /* NUL */ ]; int rc; if ( xfer_window ( &http->socket ) ) { + + /* We want to execute only once */ process_del ( &http->process ); + + /* Construct authorisation, if applicable */ + if ( user_pw_len ) { + snprintf ( user_pw, sizeof ( user_pw ), "%s:%s", + user, password ); + base64_encode ( user_pw, user_pw_base64 ); + } + + /* Send GET request */ if ( ( rc = xfer_printf ( &http->socket, "GET %s%s%s HTTP/1.0\r\n" "User-Agent: gPXE/" VERSION "\r\n" + "%s%s%s" "Host: %s\r\n" "\r\n", ( path ? path : "/" ), ( query ? "?" : "" ), ( query ? query : "" ), + ( user_pw_len ? + "Authorization: Basic " : "" ), + ( user_pw_len ? + user_pw_base64 : "" ), + ( user_pw_len ? "\r\n" : "" ), host ) ) != 0 ) { http_done ( http, rc ); }