[http] Add support for HTTP Basic authentication
authorMichael Brown <mcb30@etherboot.org>
Fri, 13 Feb 2009 15:43:17 +0000 (15:43 +0000)
committerMichael Brown <mcb30@etherboot.org>
Fri, 13 Feb 2009 15:43:17 +0000 (15:43 +0000)
src/net/tcp/http.c

index 46b5077..1052400 100644 (file)
@@ -41,6 +41,7 @@
 #include <gpxe/process.h>
 #include <gpxe/linebuf.h>
 #include <gpxe/features.h>
+#include <gpxe/base64.h>
 #include <gpxe/http.h>
 
 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 );
                }