ソースを参照

[http] Work around stateful authentication schemes

As pointedly documented in RFC7230 section 2.3, HTTP is a stateless
protocol: each request message can be understood in isolation from any
other requests or responses.  Various authentication schemes such as
NTLM break this fundamental property of HTTP and rely on the same TCP
connection being reused.

Work around these broken authentication schemes by ensuring that the
most recently pooled connection is reused for the subsequent
authentication retry.

Reported-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Tested-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 6年前
コミット
e7f67d5a4c
2個のファイルの変更19行の追加2行の削除
  1. 7
    2
      src/net/tcp/httpconn.c
  2. 12
    0
      src/net/tcp/httpcore.c

+ 7
- 2
src/net/tcp/httpconn.c ファイルの表示

@@ -252,8 +252,13 @@ int http_connect ( struct interface *xfer, struct uri *uri ) {
252 252
 	/* Identify port */
253 253
 	port = uri_port ( uri, scheme->port );
254 254
 
255
-	/* Look for a reusable connection in the pool */
256
-	list_for_each_entry ( conn, &http_connection_pool, pool.list ) {
255
+	/* Look for a reusable connection in the pool.  Reuse the most
256
+	 * recent connection in order to accommodate authentication
257
+	 * schemes that break the stateless nature of HTTP and rely on
258
+	 * the same connection being reused for authentication
259
+	 * responses.
260
+	 */
261
+	list_for_each_entry_reverse ( conn, &http_connection_pool, pool.list ) {
257 262
 
258 263
 		/* Sanity checks */
259 264
 		assert ( conn->uri != NULL );

+ 12
- 0
src/net/tcp/httpcore.c ファイルの表示

@@ -778,6 +778,18 @@ static int http_transfer_complete ( struct http_transaction *http ) {
778 778
 	http->len = 0;
779 779
 	assert ( http->remaining == 0 );
780 780
 
781
+	/* Retry immediately if applicable.  We cannot rely on an
782
+	 * immediate timer expiry, since certain Microsoft-designed
783
+	 * HTTP extensions such as NTLM break the fundamentally
784
+	 * stateless nature of HTTP and rely on the same connection
785
+	 * being reused for authentication.  See RFC7230 section 2.3
786
+	 * for further details.
787
+	 */
788
+	if ( ! http->response.retry_after ) {
789
+		http_reopen ( http );
790
+		return 0;
791
+	}
792
+
781 793
 	/* Start timer to initiate retry */
782 794
 	DBGC2 ( http, "HTTP %p retrying after %d seconds\n",
783 795
 		http, http->response.retry_after );

読み込み中…
キャンセル
保存