return 1;
}
+static const struct socks_proxy_type {
+ const char *name;
+ long curlsym;
+} socks_proxy_types[] = {
+ { "socks", CURLPROXY_SOCKS4 },
+ { "socks4", CURLPROXY_SOCKS4 },
+ { "socks4a", CURLPROXY_SOCKS4A },
+ { "socks5", CURLPROXY_SOCKS5 },
+ { "socks5h", CURLPROXY_SOCKS5_HOSTNAME },
+};
+
+static const struct socks_proxy_type *find_socks_proxy_type(const char *protocol)
+{
+ int i;
+
+ if (!protocol)
+ return NULL;
+
+ for (i = 0; i < ARRAY_SIZE(socks_proxy_types); i++) {
+ if (!strcmp(socks_proxy_types[i].name, protocol))
+ return &socks_proxy_types[i];
+ }
+
+ return NULL;
+}
+
+static int is_socks_proxy_protocol(const char *protocol)
+{
+ return !!find_socks_proxy_type(protocol);
+}
+
+static int set_curl_proxy_type(CURL *result, const char *protocol)
+{
+ const struct socks_proxy_type *socks_proxy_type;
+
+ if (!protocol || !strcmp(protocol, "http"))
+ return 0;
+
+ socks_proxy_type = find_socks_proxy_type(protocol);
+ if (socks_proxy_type) {
+ curl_easy_setopt(result, CURLOPT_PROXYTYPE, socks_proxy_type->curlsym);
+ return 0;
+ }
+
+ if (!strcmp(protocol, "https")) {
+ curl_easy_setopt(result, CURLOPT_PROXYTYPE, (long)CURLPROXY_HTTPS);
+
+ if (http_proxy_ssl_cert)
+ curl_easy_setopt(result, CURLOPT_PROXY_SSLCERT,
+ http_proxy_ssl_cert);
+
+ if (http_proxy_ssl_key)
+ curl_easy_setopt(result, CURLOPT_PROXY_SSLKEY,
+ http_proxy_ssl_key);
+
+ if (has_proxy_cert_password())
+ curl_easy_setopt(result, CURLOPT_PROXY_KEYPASSWD,
+ proxy_cert_auth.password);
+ }
+
+ return -1;
+}
+
/* Return 1 if redactions have been made, 0 otherwise. */
static int redact_sensitive_header(struct strbuf *header, size_t offset)
{
} else if (curl_http_proxy) {
struct strbuf proxy = STRBUF_INIT;
- if (starts_with(curl_http_proxy, "socks5h"))
- curl_easy_setopt(result,
- CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS5_HOSTNAME);
- else if (starts_with(curl_http_proxy, "socks5"))
- curl_easy_setopt(result,
- CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS5);
- else if (starts_with(curl_http_proxy, "socks4a"))
- curl_easy_setopt(result,
- CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS4A);
- else if (starts_with(curl_http_proxy, "socks"))
- curl_easy_setopt(result,
- CURLOPT_PROXYTYPE, (long)CURLPROXY_SOCKS4);
- else if (starts_with(curl_http_proxy, "https")) {
- curl_easy_setopt(result, CURLOPT_PROXYTYPE, (long)CURLPROXY_HTTPS);
-
- if (http_proxy_ssl_cert)
- curl_easy_setopt(result, CURLOPT_PROXY_SSLCERT, http_proxy_ssl_cert);
-
- if (http_proxy_ssl_key)
- curl_easy_setopt(result, CURLOPT_PROXY_SSLKEY, http_proxy_ssl_key);
-
- if (has_proxy_cert_password())
- curl_easy_setopt(result, CURLOPT_PROXY_KEYPASSWD, proxy_cert_auth.password);
- }
if (strstr(curl_http_proxy, "://"))
credential_from_url(&proxy_auth, curl_http_proxy);
else {
strbuf_release(&url);
}
+ if (set_curl_proxy_type(result, proxy_auth.protocol) < 0)
+ die("Invalid proxy URL '%s': unsupported proxy scheme '%s'",
+ curl_http_proxy, proxy_auth.protocol);
+
if (!proxy_auth.host)
die("Invalid proxy URL '%s'", curl_http_proxy);
if (ver->version_num < 0x075400)
die("libcurl 7.84 or later is required to support paths in proxy URLs");
- if (!starts_with(proxy_auth.protocol, "socks"))
+ if (!is_socks_proxy_protocol(proxy_auth.protocol))
die("Invalid proxy URL '%s': only SOCKS proxies support paths",
curl_http_proxy);