mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
dirmngr: Implement automatic proxy detection on Windows.
* dirmngr/http.c [W32]: Include winhttp.h (w32_get_internet_session): New. (w32_get_proxy): New. (get_proxy_for_url): Implement automatic proxy detection and fix error in last patch. (http_reinitialize): New. * dirmngr/dirmngr.c (dirmngr_sighup_action): Call reinitialize. * dirmngr/Makefile.am (NETLIBS) [W32]: Link with winhttp. -- GnuPG-bug-id: 5768
This commit is contained in:
parent
fed33baed1
commit
1e120f5a8d
@ -68,6 +68,7 @@ AM_CFLAGS = $(USE_C99_CFLAGS) \
|
|||||||
|
|
||||||
if HAVE_W32_SYSTEM
|
if HAVE_W32_SYSTEM
|
||||||
ldap_url = ldap-url.h ldap-url.c
|
ldap_url = ldap-url.h ldap-url.c
|
||||||
|
NETLIBS += -lwinhttp
|
||||||
else
|
else
|
||||||
ldap_url =
|
ldap_url =
|
||||||
endif
|
endif
|
||||||
|
@ -2045,6 +2045,7 @@ dirmngr_sighup_action (void)
|
|||||||
crl_cache_deinit ();
|
crl_cache_deinit ();
|
||||||
cert_cache_init (hkp_cacert_filenames);
|
cert_cache_init (hkp_cacert_filenames);
|
||||||
crl_cache_init ();
|
crl_cache_init ();
|
||||||
|
http_reinitialize ();
|
||||||
reload_dns_stuff (0);
|
reload_dns_stuff (0);
|
||||||
ks_hkp_reload ();
|
ks_hkp_reload ();
|
||||||
}
|
}
|
||||||
|
@ -22,4 +22,6 @@
|
|||||||
|
|
||||||
const char *get_default_keyserver (int name_only);
|
const char *get_default_keyserver (int name_only);
|
||||||
|
|
||||||
|
void http_reinitialize (void);
|
||||||
|
|
||||||
#endif /* HTTP_COMMON_H */
|
#endif /* HTTP_COMMON_H */
|
||||||
|
162
dirmngr/http.c
162
dirmngr/http.c
@ -64,6 +64,7 @@
|
|||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
# endif
|
# endif
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
|
# include <winhttp.h>
|
||||||
# ifndef EHOSTUNREACH
|
# ifndef EHOSTUNREACH
|
||||||
# define EHOSTUNREACH WSAEHOSTUNREACH
|
# define EHOSTUNREACH WSAEHOSTUNREACH
|
||||||
# endif
|
# endif
|
||||||
@ -1827,6 +1828,141 @@ release_proxy_info (proxy_info_t proxy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return an http session object. If clear is set, the object is
|
||||||
|
* destroyed. On error nULL is returned. */
|
||||||
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|
static HINTERNET
|
||||||
|
w32_get_internet_session (int clear)
|
||||||
|
{
|
||||||
|
static HINTERNET session;
|
||||||
|
|
||||||
|
if (clear)
|
||||||
|
{
|
||||||
|
if (session)
|
||||||
|
{
|
||||||
|
WinHttpCloseHandle (session);
|
||||||
|
session = NULL;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!session)
|
||||||
|
{
|
||||||
|
session = WinHttpOpen (L"GnuPG dirmngr",
|
||||||
|
WINHTTP_ACCESS_TYPE_NO_PROXY,
|
||||||
|
WINHTTP_NO_PROXY_NAME,
|
||||||
|
WINHTTP_NO_PROXY_BYPASS,
|
||||||
|
0);
|
||||||
|
if (!session)
|
||||||
|
{
|
||||||
|
log_error ("WinHttpOpen failed: %s\n", w32_strerror (-1));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
#endif /*HAVE_W32_SYSTEM*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Return a proxy using a Windows API. */
|
||||||
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|
static char *
|
||||||
|
w32_get_proxy (const char *url)
|
||||||
|
{
|
||||||
|
WINHTTP_AUTOPROXY_OPTIONS options = {0};
|
||||||
|
WINHTTP_PROXY_INFO info;
|
||||||
|
char *result = NULL;
|
||||||
|
char *p;
|
||||||
|
wchar_t *wurl;
|
||||||
|
int defaultcfg = 0;
|
||||||
|
|
||||||
|
wurl = utf8_to_wchar (url);
|
||||||
|
if (!wurl)
|
||||||
|
{
|
||||||
|
log_error ("utf8_to_wchar failed: %s\n",
|
||||||
|
gpg_strerror (gpg_error_from_syserror ()));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
options.dwFlags = (WINHTTP_AUTOPROXY_ALLOW_AUTOCONFIG
|
||||||
|
| WINHTTP_AUTOPROXY_ALLOW_CM
|
||||||
|
| WINHTTP_AUTOPROXY_ALLOW_STATIC
|
||||||
|
| WINHTTP_AUTOPROXY_AUTO_DETECT
|
||||||
|
| WINHTTP_AUTOPROXY_SORT_RESULTS);
|
||||||
|
options.dwAutoDetectFlags = (WINHTTP_AUTO_DETECT_TYPE_DHCP
|
||||||
|
| WINHTTP_AUTO_DETECT_TYPE_DNS_A);
|
||||||
|
options.fAutoLogonIfChallenged = TRUE;
|
||||||
|
|
||||||
|
if (opt_debug)
|
||||||
|
log_debug ("calling WinHttpGetProxyForUrl (%s)\n", url);
|
||||||
|
if (!WinHttpGetProxyForUrl (w32_get_internet_session (0),
|
||||||
|
wurl, &options, &info))
|
||||||
|
{
|
||||||
|
int ec = (int)GetLastError ();
|
||||||
|
if (ec == ERROR_WINHTTP_AUTODETECTION_FAILED)
|
||||||
|
{
|
||||||
|
if (opt_debug)
|
||||||
|
log_debug ("calling WinHttpGetDefaultProxyConfiguration\n");
|
||||||
|
if (!WinHttpGetDefaultProxyConfiguration (&info))
|
||||||
|
{
|
||||||
|
if (opt_verbose)
|
||||||
|
log_info ("WinHttpGetDefaultProxyConfiguration failed: "
|
||||||
|
"%s (%d)\n", w32_strerror (ec), ec);
|
||||||
|
xfree (wurl);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
defaultcfg = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (opt_verbose)
|
||||||
|
log_info ("WinHttpGetProxyForUrl failed: %s (%d)\n",
|
||||||
|
w32_strerror (ec), ec);
|
||||||
|
xfree (wurl);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xfree (wurl);
|
||||||
|
|
||||||
|
if (info.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY)
|
||||||
|
{
|
||||||
|
result = wchar_to_utf8 (info.lpszProxy);
|
||||||
|
if (!result)
|
||||||
|
log_error ("wchar_to_utf8 failed: %s\n",
|
||||||
|
gpg_strerror (gpg_error_from_syserror ()));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (opt_debug)
|
||||||
|
log_debug ("proxies to use: '%s'\n", result);
|
||||||
|
/* The returned proxies are delimited by whitespace or
|
||||||
|
* semicolons. We return only the first proxy. */
|
||||||
|
for (p=result; *p; p++)
|
||||||
|
if (spacep (p) || *p == ';')
|
||||||
|
{
|
||||||
|
*p = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (info.dwAccessType == WINHTTP_ACCESS_TYPE_NO_PROXY)
|
||||||
|
{
|
||||||
|
/* No proxy shall be used. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log_error ("%s returned unexpected code %lu\n",
|
||||||
|
defaultcfg? "WinHttpGetDefaultProxyConfiguration"
|
||||||
|
:"WinHttpGetProxyForUrl", info.dwAccessType);
|
||||||
|
|
||||||
|
if (info.lpszProxy)
|
||||||
|
GlobalFree (info.lpszProxy);
|
||||||
|
if (info.lpszProxyBypass)
|
||||||
|
GlobalFree (info.lpszProxyBypass);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif /*HAVE_W32_SYSTEM*/
|
||||||
|
|
||||||
|
|
||||||
/* Return the proxy to be used for the URL or host specified in HD.
|
/* Return the proxy to be used for the URL or host specified in HD.
|
||||||
* If OVERRIDE_PROXY is not NULL and not empty, this proxy will be
|
* If OVERRIDE_PROXY is not NULL and not empty, this proxy will be
|
||||||
* used instead of any configured or dynamically determined proxy. If
|
* used instead of any configured or dynamically determined proxy. If
|
||||||
@ -1838,11 +1974,14 @@ release_proxy_info (proxy_info_t proxy)
|
|||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
get_proxy_for_url (http_t hd, const char *override_proxy, proxy_info_t *r_proxy)
|
get_proxy_for_url (http_t hd, const char *override_proxy, proxy_info_t *r_proxy)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err = 0;
|
||||||
const char *proxystr, *s;
|
const char *proxystr, *s;
|
||||||
proxy_info_t proxy;
|
proxy_info_t proxy;
|
||||||
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|
char *proxystrbuf = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
r_proxy = NULL;
|
*r_proxy = NULL;
|
||||||
|
|
||||||
if (override_proxy && *override_proxy)
|
if (override_proxy && *override_proxy)
|
||||||
proxystr = override_proxy;
|
proxystr = override_proxy;
|
||||||
@ -1851,6 +1990,9 @@ get_proxy_for_url (http_t hd, const char *override_proxy, proxy_info_t *r_proxy)
|
|||||||
else if ((s = getenv (HTTP_PROXY_ENV)) && *s)
|
else if ((s = getenv (HTTP_PROXY_ENV)) && *s)
|
||||||
proxystr = s;
|
proxystr = s;
|
||||||
#ifdef HAVE_W32_SYSTEM
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|
else if (hd->uri && hd->uri->original
|
||||||
|
&& (proxystrbuf = w32_get_proxy (hd->uri->original)))
|
||||||
|
proxystr = proxystrbuf;
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
return 0; /* No proxy known. */
|
return 0; /* No proxy known. */
|
||||||
@ -1860,7 +2002,7 @@ get_proxy_for_url (http_t hd, const char *override_proxy, proxy_info_t *r_proxy)
|
|||||||
{
|
{
|
||||||
err = gpg_error_from_syserror ();
|
err = gpg_error_from_syserror ();
|
||||||
log_error ("error allocating memory for proxy\n");
|
log_error ("error allocating memory for proxy\n");
|
||||||
return err;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = parse_uri (&proxy->uri, proxystr, 0, 0);
|
err = parse_uri (&proxy->uri, proxystr, 0, 0);
|
||||||
@ -1901,6 +2043,10 @@ get_proxy_for_url (http_t hd, const char *override_proxy, proxy_info_t *r_proxy)
|
|||||||
proxystr, hd->uri? hd->uri->original : NULL);
|
proxystr, hd->uri? hd->uri->original : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
leave:
|
||||||
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|
xfree (proxystrbuf);
|
||||||
|
#endif
|
||||||
if (err)
|
if (err)
|
||||||
xfree (proxy);
|
xfree (proxy);
|
||||||
else
|
else
|
||||||
@ -3938,3 +4084,13 @@ http_status2string (unsigned int status)
|
|||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Fucntion called on SIGHUP to flush internal variables. */
|
||||||
|
void
|
||||||
|
http_reinitialize (void)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|
w32_get_internet_session (1); /* Clear our session. */
|
||||||
|
#endif /*HAVE_W32_SYSTEM*/
|
||||||
|
}
|
||||||
|
@ -427,7 +427,9 @@ force the use of the default responder.
|
|||||||
@item --honor-http-proxy
|
@item --honor-http-proxy
|
||||||
@opindex honor-http-proxy
|
@opindex honor-http-proxy
|
||||||
If the environment variable @env{http_proxy} has been set, use its
|
If the environment variable @env{http_proxy} has been set, use its
|
||||||
value to access HTTP servers.
|
value to access HTTP servers. If on Windows the option is used but
|
||||||
|
the environment variable is not set, the proxy settings are taken
|
||||||
|
from the system.
|
||||||
|
|
||||||
@item --http-proxy @var{host}[:@var{port}]
|
@item --http-proxy @var{host}[:@var{port}]
|
||||||
@opindex http-proxy
|
@opindex http-proxy
|
||||||
|
Loading…
x
Reference in New Issue
Block a user