Package: git Version: 1:2.42.0-1 Tags: patch Dear Maintainer,
git does not support AF_UNIX proxies, despite the git-config manual page suggesting it will accept anything supported by curl: http.proxy Override the HTTP proxy, normally configured using the http_proxy, https_proxy, and all_proxy environment variables (see curl(1)). In addition to the syntax understood by curl, it is possible to specify a proxy string with a user name but no password, I tried to use "torsocks git fetch" with a .onion remote I'd cloned from in the past, and got an error: fatal: unable to access 'http://[elided].onion/git/': Not resolving .onion address (RFC 7686) It seems to be a known problem, and I tried working around it by setting an AF_UNIX proxy as documented for --proxy in the curl(1) manual: export all_proxy=socks5h://localhost/run/tor/socks That works for curl, but "git fetch" gives an error: fatal: unable to access 'http://[elided].onion/git/': Failed to connect to localhost port 1080 after 0 ms: Couldn't connect to server While debugging, I found that git was reading this environment variable, parsing it poorly, and overriding it by giving libcurl a proxy string of just "localhost"; seeing no path or port number, curl tries AF_INET6 and AF_INET with port 1080. I'm attaching a patch that fixes this. I haven't tested thoroughly, but tried to avoid unnecessary changes to the credential code (which I think should use libcurl to parse URLs). The flags for curl_url_set() are the same as in curl's own parse_proxy() function. Permission is hereby granted, irrevocably and free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - Michael -- System Information: Debian Release: trixie/sid APT prefers unstable-debug APT policy: (500, 'unstable-debug'), (500, 'unstable'), (1, 'experimental') Architecture: amd64 (x86_64) Kernel: Linux 6.5.0-1-amd64 (SMP w/32 CPU threads; PREEMPT) Locale: LANG=en_CA.UTF-8, LC_CTYPE=en_CA.UTF-8 (charmap=UTF-8), LANGUAGE=en_CA:en Shell: /bin/sh linked to /usr/bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled Versions of packages git depends on: ii git-man 1:2.42.0-1 ii libc6 2.37-11 ii libcurl3-gnutls 8.3.0-2 ii liberror-perl 0.17029-2 ii libexpat1 2.5.0-2 ii libpcre2-8-0 10.42-4 ii perl 5.36.0-9 ii zlib1g 1:1.2.13.dfsg-3 Versions of packages git recommends: ii ca-certificates 20230311 ii less 590-2 ii openssh-client [ssh-client] 1:9.4p1-1 ii patch 2.7.6-7 Versions of packages git suggests: ii gettext-base 0.21-13+b1 pn git-cvs <none> pn git-daemon-run | git-daemon-sysvinit <none> ii git-doc 1:2.42.0-1 ii git-email 1:2.42.0-1 pn git-gui <none> pn git-mediawiki <none> pn git-svn <none> ii gitk 1:2.42.0-1 pn gitweb <none> -- no debconf information
diff --git a/http.c b/http.c index e138b4b96fb9..7ba155a77406 100644 --- a/http.c +++ b/http.c @@ -1135,32 +1135,39 @@ static CURL *get_curl_handle(void) */ curl_easy_setopt(result, CURLOPT_PROXY, ""); } else if (curl_http_proxy) { - if (starts_with(curl_http_proxy, "socks5h")) - curl_easy_setopt(result, - CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5_HOSTNAME); - else if (starts_with(curl_http_proxy, "socks5")) - curl_easy_setopt(result, - CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); - else if (starts_with(curl_http_proxy, "socks4a")) - curl_easy_setopt(result, - CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4A); - else if (starts_with(curl_http_proxy, "socks")) - curl_easy_setopt(result, - CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); -#ifdef GIT_CURL_HAVE_CURLOPT_PROXY_KEYPASSWD - else if (starts_with(curl_http_proxy, "https")) { - curl_easy_setopt(result, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS); + CURLU *url = curl_url(); + CURLUcode urc; + char *url_str = NULL; + + url = curl_url(); + if (!url) { + urc = CURLUE_OUT_OF_MEMORY; + goto proxy_out; + } - if (http_proxy_ssl_cert) - curl_easy_setopt(result, CURLOPT_PROXY_SSLCERT, http_proxy_ssl_cert); + urc = curl_url_set(url, CURLUPART_URL, curl_http_proxy, + CURLU_NON_SUPPORT_SCHEME|CURLU_GUESS_SCHEME); + if (urc) + goto proxy_out; - if (http_proxy_ssl_key) - curl_easy_setopt(result, CURLOPT_PROXY_SSLKEY, http_proxy_ssl_key); + if (http_proxy_ssl_cert) { + urc = curl_easy_setopt(result, CURLOPT_PROXY_SSLCERT, http_proxy_ssl_cert); + if (urc) + goto proxy_out; + } - if (has_proxy_cert_password()) - curl_easy_setopt(result, CURLOPT_PROXY_KEYPASSWD, proxy_cert_auth.password); + if (http_proxy_ssl_key) { + urc = curl_easy_setopt(result, CURLOPT_PROXY_SSLKEY, http_proxy_ssl_key); + if (urc) + goto proxy_out; } -#endif + + if (has_proxy_cert_password()) { + urc = curl_easy_setopt(result, CURLOPT_PROXY_KEYPASSWD, proxy_cert_auth.password); + if (urc) + goto proxy_out; + } + if (strstr(curl_http_proxy, "://")) credential_from_url(&proxy_auth, curl_http_proxy); else { @@ -1170,13 +1177,45 @@ static CURL *get_curl_handle(void) strbuf_release(&url); } - if (!proxy_auth.host) - die("Invalid proxy URL '%s'", curl_http_proxy); + if (!proxy_auth.host) { + urc = CURLUE_URLDECODE; + goto proxy_out; + } + + /* Set a proxy URL without username or password. + * init_curl_proxy_auth() will deal with those. + */ + urc = curl_url_set(url, CURLUPART_USER, NULL, + CURLU_NON_SUPPORT_SCHEME|CURLU_GUESS_SCHEME); + if (urc) + goto proxy_out; + + urc = curl_url_set(url, CURLUPART_PASSWORD, NULL, + CURLU_NON_SUPPORT_SCHEME|CURLU_GUESS_SCHEME); + if (urc) + goto proxy_out; + + urc = curl_url_get(url, CURLUPART_URL, &url_str, 0); + if (urc) + goto proxy_out; + + urc = curl_easy_setopt(result, CURLOPT_PROXY, url_str); + if (urc) + goto proxy_out; - curl_easy_setopt(result, CURLOPT_PROXY, proxy_auth.host); var_override(&curl_no_proxy, getenv("NO_PROXY")); var_override(&curl_no_proxy, getenv("no_proxy")); - curl_easy_setopt(result, CURLOPT_NOPROXY, curl_no_proxy); + urc = curl_easy_setopt(result, CURLOPT_NOPROXY, curl_no_proxy); + if (urc) + goto proxy_out; + +proxy_out: + curl_url_cleanup(url); + curl_free(url_str); + if (urc) { + die("Unable to parse proxy URL '%s': %s", + curl_http_proxy, curl_url_strerror(urc)); + } } init_curl_proxy_auth(result);
signature.asc
Description: PGP signature