git: d7682961d386 - stable/13 - libfetch: Retry with proxy auth when server returns 407

Renato Botelho garga at FreeBSD.org
Wed Apr 28 19:38:02 UTC 2021


The branch stable/13 has been updated by garga (ports committer):

URL: https://cgit.FreeBSD.org/src/commit/?id=d7682961d386ebc7d5ec9cb38e609d3ec9bb978a

commit d7682961d386ebc7d5ec9cb38e609d3ec9bb978a
Author:     Renato Botelho <garga at FreeBSD.org>
AuthorDate: 2021-04-01 21:02:57 +0000
Commit:     Renato Botelho <garga at FreeBSD.org>
CommitDate: 2021-04-28 19:21:26 +0000

    libfetch: Retry with proxy auth when server returns 407
    
    PR:             220468
    Submitted by:   Egil Hasting <egil.hasting at higen.org> (based on)
    Reviewed by:    kevans, kp
    Approved by:    kp
    MFC after:      2 weeks
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D29533
    
    (cherry picked from commit 345c30a94f6425954163f1e0b075a75f603d27cd)
---
 lib/libfetch/http.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 49 insertions(+), 6 deletions(-)

diff --git a/lib/libfetch/http.c b/lib/libfetch/http.c
index 7f37b7d67197..e61e23b1425a 100644
--- a/lib/libfetch/http.c
+++ b/lib/libfetch/http.c
@@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$");
 #include <locale.h>
 #include <netdb.h>
 #include <stdarg.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -1387,6 +1388,8 @@ http_connect(struct url *URL, struct url *purl, const char *flags)
 	int verbose;
 	int af, val;
 	int serrno;
+	bool isproxyauth = false;
+	http_auth_challenges_t proxy_challenges;
 
 #ifdef INET6
 	af = AF_UNSPEC;
@@ -1404,18 +1407,58 @@ http_connect(struct url *URL, struct url *purl, const char *flags)
 
 	curl = (purl != NULL) ? purl : URL;
 
+retry:
 	if ((conn = fetch_connect(curl->host, curl->port, af, verbose)) == NULL)
 		/* fetch_connect() has already set an error code */
 		return (NULL);
 	init_http_headerbuf(&headerbuf);
 	if (strcmp(URL->scheme, SCHEME_HTTPS) == 0 && purl) {
-		http_cmd(conn, "CONNECT %s:%d HTTP/1.1",
-		    URL->host, URL->port);
-		http_cmd(conn, "Host: %s:%d",
-		    URL->host, URL->port);
+		init_http_auth_challenges(&proxy_challenges);
+		http_cmd(conn, "CONNECT %s:%d HTTP/1.1", URL->host, URL->port);
+		http_cmd(conn, "Host: %s:%d", URL->host, URL->port);
+		if (isproxyauth) {
+			http_auth_params_t aparams;
+			init_http_auth_params(&aparams);
+			if (*purl->user || *purl->pwd) {
+				aparams.user = strdup(purl->user);
+				aparams.password = strdup(purl->pwd);
+			} else if ((p = getenv("HTTP_PROXY_AUTH")) != NULL &&
+				    *p != '\0') {
+				if (http_authfromenv(p, &aparams) < 0) {
+					http_seterr(HTTP_NEED_PROXY_AUTH);
+					fetch_syserr();
+					goto ouch;
+				}
+			} else if (fetch_netrc_auth(purl) == 0) {
+				aparams.user = strdup(purl->user);
+				aparams.password = strdup(purl->pwd);
+			} else {
+				/*
+				 * No auth information found in system - exiting
+				 * with warning.
+				 */
+				warnx("Missing username and/or password set");
+				fetch_syserr();
+				goto ouch;
+			}
+			http_authorize(conn, "Proxy-Authorization",
+			    &proxy_challenges, &aparams, purl);
+			clean_http_auth_params(&aparams);
+		}
 		http_cmd(conn, "");
-		if (http_get_reply(conn) != HTTP_OK) {
-			http_seterr(conn->err);
+		/* Get reply from CONNECT Tunnel attempt */
+		int httpreply = http_get_reply(conn);
+		if (httpreply != HTTP_OK) {
+			http_seterr(httpreply);
+			/* If the error is a 407/HTTP_NEED_PROXY_AUTH */
+			if (httpreply == HTTP_NEED_PROXY_AUTH &&
+			    ! isproxyauth) {
+				/* Try again with authentication. */
+				clean_http_headerbuf(&headerbuf);
+				fetch_close(conn);
+				isproxyauth = true;
+				goto retry;
+			}
 			goto ouch;
 		}
 		/* Read and discard the rest of the proxy response */


More information about the dev-commits-src-all mailing list