Browse Source

[http] Gracefully handle offers of multiple authentication schemes

Servers may provide multiple WWW-Authenticate headers, each offering a
different authentication scheme.  We currently fail the request as
soon as we encounter an unrecognised scheme, which prevents subsequent
offers from succeeding.

Fix by silently ignoring headers for schemes that we do not recognise.
If no schemes are recognised then the request will eventually fail
anyway due to the 401 response code.

If multiple schemes are supported, arbitrarily choose the scheme
appearing first within the response headers.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 6 years ago
parent
commit
c49acbb4d2
1 changed files with 10 additions and 3 deletions
  1. 10
    3
      src/net/tcp/httpauth.c

+ 10
- 3
src/net/tcp/httpauth.c View File

104
 static int http_parse_www_authenticate ( struct http_transaction *http,
104
 static int http_parse_www_authenticate ( struct http_transaction *http,
105
 					 char *line ) {
105
 					 char *line ) {
106
 	struct http_www_authenticate_field *field;
106
 	struct http_www_authenticate_field *field;
107
+	struct http_authentication *auth;
107
 	char *name;
108
 	char *name;
108
 	char *key;
109
 	char *key;
109
 	char *value;
110
 	char *value;
118
 	}
119
 	}
119
 
120
 
120
 	/* Identify scheme */
121
 	/* Identify scheme */
121
-	http->response.auth.auth = http_authentication ( name );
122
-	if ( ! http->response.auth.auth ) {
122
+	auth = http_authentication ( name );
123
+	if ( ! auth ) {
123
 		DBGC ( http, "HTTP %p unrecognised authentication scheme "
124
 		DBGC ( http, "HTTP %p unrecognised authentication scheme "
124
 		       "\"%s\"\n", http, name );
125
 		       "\"%s\"\n", http, name );
125
-		return -ENOTSUP;
126
+		/* Ignore; the server may offer other schemes */
127
+		return 0;
126
 	}
128
 	}
127
 
129
 
130
+	/* Use first supported scheme */
131
+	if ( http->response.auth.auth )
132
+		return 0;
133
+	http->response.auth.auth = auth;
134
+
128
 	/* Process fields */
135
 	/* Process fields */
129
 	while ( ( key = http_token ( &line, &value ) ) ) {
136
 	while ( ( key = http_token ( &line, &value ) ) ) {
130
 		for ( i = 0 ; i < ( sizeof ( http_www_auth_fields ) /
137
 		for ( i = 0 ; i < ( sizeof ( http_www_auth_fields ) /

Loading…
Cancel
Save