[Pkg-gnupg-commit] [gnupg2] 01/02: pull fixes from upstream (including a double-free in gpg-agent)
Daniel Kahn Gillmor
dkg at fifthhorseman.net
Wed Jan 25 14:45:29 UTC 2017
This is an automated email from the git hooks/post-receive script.
dkg pushed a commit to branch master
in repository gnupg2.
commit 8a032314b092bc35426e3a8cf580c25f329f7f3e
Author: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
Date: Wed Jan 25 09:29:14 2017 -0500
pull fixes from upstream (including a double-free in gpg-agent)
---
debian/patches/0012-tools-Fix-memory-leak.patch | 28 +++
.../0013-tools-Improve-error-handling.patch | 29 +++
.../0014-dirmngr-New-option-disable-ipv4.patch | 245 ++++++++++++++++++++
...gr-Simplify-error-returning-inside-http.c.patch | 255 +++++++++++++++++++++
.../0016-gpg-Print-a-warning-on-Tor-problems.patch | 188 +++++++++++++++
debian/patches/0017-agent-Fix-double-free.patch | 49 ++++
debian/patches/series | 6 +
7 files changed, 800 insertions(+)
diff --git a/debian/patches/0012-tools-Fix-memory-leak.patch b/debian/patches/0012-tools-Fix-memory-leak.patch
new file mode 100644
index 0000000..4d47557
--- /dev/null
+++ b/debian/patches/0012-tools-Fix-memory-leak.patch
@@ -0,0 +1,28 @@
+From: Justus Winter <justus at g10code.com>
+Date: Mon, 23 Jan 2017 11:52:30 +0100
+Subject: tools: Fix memory leak.
+
+* tools/gpgconf-comp.c (change_options_file): Fix leak.
+--
+Previously, 'src_filename' and 'orig_filename' leaked if creating the
+backup file failed.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit 5b28f025085b386e0ec49535d4cd3f875a414eb0)
+---
+ tools/gpgconf-comp.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
+index a25b5136e..85eb80ab5 100644
+--- a/tools/gpgconf-comp.c
++++ b/tools/gpgconf-comp.c
+@@ -2641,6 +2641,8 @@ change_options_file (gc_component_t component, gc_backend_t backend,
+ if (res < 0 && errno != ENOENT)
+ {
+ xfree (dest_filename);
++ xfree (src_filename);
++ xfree (orig_filename);
+ return -1;
+ }
+ if (res < 0)
diff --git a/debian/patches/0013-tools-Improve-error-handling.patch b/debian/patches/0013-tools-Improve-error-handling.patch
new file mode 100644
index 0000000..b0034da
--- /dev/null
+++ b/debian/patches/0013-tools-Improve-error-handling.patch
@@ -0,0 +1,29 @@
+From: Justus Winter <justus at g10code.com>
+Date: Mon, 23 Jan 2017 14:24:22 +0100
+Subject: tools: Improve error handling.
+
+* tools/gpgconf-comp.c (gp_component_change_options): Improve error
+handling when reading from stdin.
+--
+Previously, errors encountered while reading the configuration changes
+were ignored.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit b0348fdb26637b0bcbd68a96c1746a1613b309af)
+---
+ tools/gpgconf-comp.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
+index 85eb80ab5..180fd65c2 100644
+--- a/tools/gpgconf-comp.c
++++ b/tools/gpgconf-comp.c
+@@ -3328,6 +3328,8 @@ gc_component_change_options (int component, estream_t in, estream_t out,
+
+ change_one_value (option, runtime, flags, new_value, 0);
+ }
++ if (length < 0 || gpgrt_ferror (in))
++ gc_error (1, errno, "error reading stream 'in'");
+ }
+
+ /* Now that we have collected and locally verified the changes,
diff --git a/debian/patches/0014-dirmngr-New-option-disable-ipv4.patch b/debian/patches/0014-dirmngr-New-option-disable-ipv4.patch
new file mode 100644
index 0000000..ad0fb58
--- /dev/null
+++ b/debian/patches/0014-dirmngr-New-option-disable-ipv4.patch
@@ -0,0 +1,245 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Tue, 24 Jan 2017 16:36:28 +0100
+Subject: dirmngr: New option --disable-ipv4.
+
+* dirmngr/dirmngr.c (oDisableIPv4): New const.
+(opts): New option --disable-ipv4.
+(parse_rereadable_options): Set that option.
+* dirmngr/dirmngr.h (opt): New field 'disable_ipv4'.
+* dirmngr/dns-stuff.c (opt_disable_ipv4): bew var.
+(set_dns_disable_ipv4): New.
+(resolve_name_standard): Skip v4 addresses when OPT_DISABLE_IPV4 is
+set.
+* dirmngr/ks-engine-hkp.c (map_host): Ditto.
+(send_request): Pass HTTP_FLAG_IGNORE_IPv4 if opt.disable_v4 is set.
+* dirmngr/crlfetch.c (crl_fetch): Ditto.
+* dirmngr/ks-engine-finger.c (ks_finger_fetch): Ditto.
+* dirmngr/ks-engine-http.c (ks_http_fetch): Ditto.
+* dirmngr/ocsp.c (do_ocsp_request): Ditto.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 72736af86a501592d974d46ff754a63959e183bd)
+---
+ dirmngr/crlfetch.c | 4 +++-
+ dirmngr/dirmngr.c | 5 +++++
+ dirmngr/dirmngr.h | 1 +
+ dirmngr/dns-stuff.c | 15 +++++++++++++++
+ dirmngr/dns-stuff.h | 4 ++++
+ dirmngr/ks-engine-finger.c | 4 +++-
+ dirmngr/ks-engine-hkp.c | 8 ++++++--
+ dirmngr/ks-engine-http.c | 3 ++-
+ dirmngr/ocsp.c | 3 ++-
+ doc/dirmngr.texi | 5 +++++
+ 10 files changed, 46 insertions(+), 6 deletions(-)
+
+diff --git a/dirmngr/crlfetch.c b/dirmngr/crlfetch.c
+index 8fe6e0b1b..aa82137f7 100644
+--- a/dirmngr/crlfetch.c
++++ b/dirmngr/crlfetch.c
+@@ -198,7 +198,9 @@ crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader)
+ err = http_open_document (&hd, url, NULL,
+ ((opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+ |(DBG_LOOKUP? HTTP_FLAG_LOG_RESP:0)
+- |(opt.use_tor? HTTP_FLAG_FORCE_TOR:0)),
++ |(opt.use_tor? HTTP_FLAG_FORCE_TOR:0)
++ |(opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4:0)
++ ),
+ ctrl->http_proxy, NULL, NULL, NULL);
+
+ switch ( err? 99999 : http_get_status_code (hd) )
+diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c
+index 8d9de9e5a..83356c94c 100644
+--- a/dirmngr/dirmngr.c
++++ b/dirmngr/dirmngr.c
+@@ -111,6 +111,7 @@ enum cmd_and_opt_values {
+ oBatch,
+ oDisableHTTP,
+ oDisableLDAP,
++ oDisableIPv4,
+ oIgnoreLDAPDP,
+ oIgnoreHTTPDP,
+ oIgnoreOCSPSvcUrl,
+@@ -224,6 +225,8 @@ static ARGPARSE_OPTS opts[] = {
+
+ ARGPARSE_s_n (oUseTor, "use-tor", N_("route all network traffic via Tor")),
+
++ ARGPARSE_s_n (oDisableIPv4, "disable-ipv4", "@"),
++
+ ARGPARSE_s_s (oSocketName, "socket-name", "@"), /* Only for debugging. */
+
+ ARGPARSE_s_u (oFakedSystemTime, "faked-system-time", "@"), /*(epoch time)*/
+@@ -586,6 +589,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
+
+ case oDisableHTTP: opt.disable_http = 1; break;
+ case oDisableLDAP: opt.disable_ldap = 1; break;
++ case oDisableIPv4: opt.disable_ipv4 = 1; break;
+ case oHonorHTTPProxy: opt.honor_http_proxy = 1; break;
+ case oHTTPProxy: opt.http_proxy = pargs->r.ret_str; break;
+ case oLDAPProxy: opt.ldap_proxy = pargs->r.ret_str; break;
+@@ -645,6 +649,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
+
+ set_dns_verbose (opt.verbose, !!DBG_DNS);
+ http_set_verbose (opt.verbose, !!DBG_NETWORK);
++ set_dns_disable_ipv4 (opt.disable_ipv4);
+
+ return 1; /* Handled. */
+ }
+diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h
+index acd4c636d..fd80d7237 100644
+--- a/dirmngr/dirmngr.h
++++ b/dirmngr/dirmngr.h
+@@ -98,6 +98,7 @@ struct
+
+ int disable_http; /* Do not use HTTP at all. */
+ int disable_ldap; /* Do not use LDAP at all. */
++ int disable_ipv4; /* Do not use leagacy IP addresses. */
+ int honor_http_proxy; /* Honor the http_proxy env variable. */
+ const char *http_proxy; /* The default HTTP proxy. */
+ const char *ldap_proxy; /* Use given LDAP proxy. */
+diff --git a/dirmngr/dns-stuff.c b/dirmngr/dns-stuff.c
+index 9347196b3..ad19fc2ce 100644
+--- a/dirmngr/dns-stuff.c
++++ b/dirmngr/dns-stuff.c
+@@ -119,6 +119,10 @@ static int opt_debug;
+ /* The timeout in seconds for libdns requests. */
+ static int opt_timeout;
+
++/* The flag to disable IPv4 access - right now this only skips
++ * returned A records. */
++static int opt_disable_ipv4;
++
+ /* If set force the use of the standard resolver. */
+ static int standard_resolver;
+
+@@ -227,6 +231,15 @@ set_dns_verbose (int verbose, int debug)
+ }
+
+
++/* Set the Disable-IPv4 flag so that the name resolver does not return
++ * A addresses. */
++void
++set_dns_disable_ipv4 (int yes)
++{
++ opt_disable_ipv4 = !!yes;
++}
++
++
+ /* Set the timeout for libdns requests to SECONDS. A value of 0 sets
+ * the default timeout and values are capped at 10 minutes. */
+ void
+@@ -873,6 +886,8 @@ resolve_name_standard (const char *name, unsigned short port,
+ {
+ if (ai->ai_family != AF_INET6 && ai->ai_family != AF_INET)
+ continue;
++ if (opt_disable_ipv4 && ai->ai_family == AF_INET)
++ continue;
+
+ dai = xtrymalloc (sizeof *dai + ai->ai_addrlen - 1);
+ dai->family = ai->ai_family;
+diff --git a/dirmngr/dns-stuff.h b/dirmngr/dns-stuff.h
+index d68dd1728..9eb97fd6a 100644
+--- a/dirmngr/dns-stuff.h
++++ b/dirmngr/dns-stuff.h
+@@ -95,6 +95,10 @@ struct srventry
+ /* Set verbosity and debug mode for this module. */
+ void set_dns_verbose (int verbose, int debug);
+
++/* Set the Disable-IPv4 flag so that the name resolver does not return
++ * A addresses. */
++void set_dns_disable_ipv4 (int yes);
++
+ /* Set the timeout for libdns requests to SECONDS. */
+ void set_dns_timeout (int seconds);
+
+diff --git a/dirmngr/ks-engine-finger.c b/dirmngr/ks-engine-finger.c
+index b1f02ad7d..114f2e9ac 100644
+--- a/dirmngr/ks-engine-finger.c
++++ b/dirmngr/ks-engine-finger.c
+@@ -83,7 +83,9 @@ ks_finger_fetch (ctrl_t ctrl, parsed_uri_t uri, estream_t *r_fp)
+ *server++ = 0;
+
+ err = http_raw_connect (&http, server, 79,
+- (opt.use_tor? HTTP_FLAG_FORCE_TOR : 0), NULL);
++ ((opt.use_tor? HTTP_FLAG_FORCE_TOR : 0)
++ | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
++ NULL);
+ if (err)
+ {
+ xfree (name);
+diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
+index 2b90441e2..dad83efcd 100644
+--- a/dirmngr/ks-engine-hkp.c
++++ b/dirmngr/ks-engine-hkp.c
+@@ -526,6 +526,8 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
+ {
+ if (ai->family != AF_INET && ai->family != AF_INET6)
+ continue;
++ if (opt.disable_ipv4 && ai->family == AF_INET)
++ continue;
+ dirmngr_tick (ctrl);
+
+ add_host (name, is_pool, ai, 0, reftbl, reftblsize, &refidx);
+@@ -607,7 +609,8 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
+ {
+ for (ai = aibuf; ai; ai = ai->next)
+ {
+- if (ai->family == AF_INET6 || ai->family == AF_INET)
++ if (ai->family == AF_INET6
++ || (!opt.disable_ipv4 && ai->family == AF_INET))
+ {
+ err = resolve_dns_addr (ai->addr, ai->addrlen, 0, &host);
+ if (!err)
+@@ -1058,7 +1061,8 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
+ /* fixme: AUTH */ NULL,
+ (httpflags
+ |(opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+- |(opt.use_tor? HTTP_FLAG_FORCE_TOR:0)),
++ |(opt.use_tor? HTTP_FLAG_FORCE_TOR:0)
++ |(opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
+ ctrl->http_proxy,
+ session,
+ NULL,
+diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c
+index 858c943ea..dbbf4bb79 100644
+--- a/dirmngr/ks-engine-http.c
++++ b/dirmngr/ks-engine-http.c
+@@ -88,7 +88,8 @@ ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp)
+ /* httphost */ NULL,
+ /* fixme: AUTH */ NULL,
+ ((opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+- | (opt.use_tor? HTTP_FLAG_FORCE_TOR:0)),
++ | (opt.use_tor? HTTP_FLAG_FORCE_TOR:0)
++ | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
+ ctrl->http_proxy,
+ session,
+ NULL,
+diff --git a/dirmngr/ocsp.c b/dirmngr/ocsp.c
+index 9127cf754..b46c78567 100644
+--- a/dirmngr/ocsp.c
++++ b/dirmngr/ocsp.c
+@@ -174,7 +174,8 @@ do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, gcry_md_hd_t md,
+ once_more:
+ err = http_open (&http, HTTP_REQ_POST, url, NULL, NULL,
+ ((opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)
+- | (opt.use_tor? HTTP_FLAG_FORCE_TOR:0)),
++ | (opt.use_tor? HTTP_FLAG_FORCE_TOR:0)
++ | (opt.disable_ipv4? HTTP_FLAG_IGNORE_IPv4 : 0)),
+ ctrl->http_proxy, NULL, NULL, NULL);
+ if (err)
+ {
+diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi
+index e27157c00..fcc174f92 100644
+--- a/doc/dirmngr.texi
++++ b/doc/dirmngr.texi
+@@ -313,6 +313,11 @@ not be used a different one can be given using this option. Note that
+ a numerical IP address must be given (IPv6 or IPv4) and that no error
+ checking is done for @var{ipaddr}.
+
++ at item --disable-ipv4
++ at opindex disable-ipv4
++Disable the use of all IPv4 addresses. This option is mainly useful
++for debugging.
++
+ @item --disable-ldap
+ @opindex disable-ldap
+ Entirely disables the use of LDAP.
diff --git a/debian/patches/0015-dirmngr-Simplify-error-returning-inside-http.c.patch b/debian/patches/0015-dirmngr-Simplify-error-returning-inside-http.c.patch
new file mode 100644
index 0000000..bcf4ee6
--- /dev/null
+++ b/debian/patches/0015-dirmngr-Simplify-error-returning-inside-http.c.patch
@@ -0,0 +1,255 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Tue, 24 Jan 2017 18:41:43 +0100
+Subject: dirmngr: Simplify error returning inside http.c.
+
+* dirmngr/http.c (connect_server): Change to return an gpg_error_t
+and to store socket at the passed address.
+(http_raw_connect, send_request): Adjust accordingly.
+--
+
+This change removes cruft from the code and allows to return the error
+code from the name lookup.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 51e5a5e5a46279809848b4ab4419f35045336010)
+---
+ dirmngr/http.c | 101 ++++++++++++++++++++++++++++-----------------------------
+ 1 file changed, 50 insertions(+), 51 deletions(-)
+
+diff --git a/dirmngr/http.c b/dirmngr/http.c
+index 35877d241..fe9c3c734 100644
+--- a/dirmngr/http.c
++++ b/dirmngr/http.c
+@@ -155,9 +155,9 @@ static gpg_error_t send_request (http_t hd, const char *httphost,
+ static char *build_rel_path (parsed_uri_t uri);
+ static gpg_error_t parse_response (http_t hd);
+
+-static assuan_fd_t connect_server (const char *server, unsigned short port,
++static gpg_error_t connect_server (const char *server, unsigned short port,
+ unsigned int flags, const char *srvtag,
+- int *r_host_not_found);
++ assuan_fd_t *r_sock);
+ static gpg_error_t write_server (int sock, const char *data, size_t length);
+
+ static gpgrt_ssize_t cookie_read (void *cookie, void *buffer, size_t size);
+@@ -924,7 +924,6 @@ http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
+ gpg_error_t err = 0;
+ http_t hd;
+ cookie_t cookie;
+- int hnf;
+
+ *r_hd = NULL;
+
+@@ -950,12 +949,9 @@ http_raw_connect (http_t *r_hd, const char *server, unsigned short port,
+ {
+ assuan_fd_t sock;
+
+- sock = connect_server (server, port, hd->flags, srvtag, &hnf);
+- if (sock == ASSUAN_INVALID_FD)
++ err = connect_server (server, port, hd->flags, srvtag, &sock);
++ if (err)
+ {
+- err = gpg_err_make (default_errsource,
+- (hnf? GPG_ERR_UNKNOWN_HOST
+- : gpg_err_code_from_syserror ()));
+ xfree (hd);
+ return err;
+ }
+@@ -1643,7 +1639,6 @@ send_request (http_t hd, const char *httphost, const char *auth,
+ char *proxy_authstr = NULL;
+ char *authstr = NULL;
+ int sock;
+- int hnf;
+
+ if (hd->uri->use_tls && !hd->session)
+ {
+@@ -1713,7 +1708,6 @@ send_request (http_t hd, const char *httphost, const char *auth,
+ && *http_proxy ))
+ {
+ parsed_uri_t uri;
+- int save_errno;
+
+ if (proxy)
+ http_proxy = proxy;
+@@ -1760,25 +1754,20 @@ send_request (http_t hd, const char *httphost, const char *auth,
+ }
+ }
+
+- sock = connect_server (*uri->host ? uri->host : "localhost",
+- uri->port ? uri->port : 80,
+- hd->flags, srvtag, &hnf);
+- save_errno = errno;
++ err = connect_server (*uri->host ? uri->host : "localhost",
++ uri->port ? uri->port : 80,
++ hd->flags, srvtag, &sock);
+ http_release_parsed_uri (uri);
+- if (sock == ASSUAN_INVALID_FD)
+- gpg_err_set_errno (save_errno);
+ }
+ else
+ {
+- sock = connect_server (server, port, hd->flags, srvtag, &hnf);
++ err = connect_server (server, port, hd->flags, srvtag, &sock);
+ }
+
+- if (sock == ASSUAN_INVALID_FD)
++ if (err)
+ {
+ xfree (proxy_authstr);
+- return gpg_err_make (default_errsource,
+- (hnf? GPG_ERR_UNKNOWN_HOST
+- : gpg_err_code_from_syserror ()));
++ return err;
+ }
+ hd->sock = my_socket_new (sock);
+ if (!hd->sock)
+@@ -1788,7 +1777,6 @@ send_request (http_t hd, const char *httphost, const char *auth,
+ }
+
+
+-
+ #if HTTP_USE_NTBTLS
+ if (hd->uri->use_tls)
+ {
+@@ -2476,11 +2464,13 @@ my_sock_new_for_addr (struct sockaddr *addr, int type, int proto)
+ }
+
+
+-/* Actually connect to a server. Returns the file descriptor or -1 on
+- error. ERRNO is set on error. */
+-static assuan_fd_t
++/* Actually connect to a server. On success 0 is returned and the
++ * file descriptor for the socket is stored at R_SOCK; on error an
++ * error code is returned and ASSUAN_INVALID_FD is stored at
++ * R_SOCK. */
++static gpg_error_t
+ connect_server (const char *server, unsigned short port,
+- unsigned int flags, const char *srvtag, int *r_host_not_found)
++ unsigned int flags, const char *srvtag, assuan_fd_t *r_sock)
+ {
+ gpg_error_t err;
+ assuan_fd_t sock = ASSUAN_INVALID_FD;
+@@ -2488,11 +2478,11 @@ connect_server (const char *server, unsigned short port,
+ int hostfound = 0;
+ int anyhostaddr = 0;
+ int srv, connected;
+- int last_errno = 0;
++ gpg_error_t last_err = 0;
+ struct srventry *serverlist = NULL;
+- int ret;
+
+- *r_host_not_found = 0;
++ *r_sock = ASSUAN_INVALID_FD;
++
+ #if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
+ init_sockets ();
+ #endif /*Windows*/
+@@ -2509,18 +2499,21 @@ connect_server (const char *server, unsigned short port,
+ ASSUAN_SOCK_TOR);
+ if (sock == ASSUAN_INVALID_FD)
+ {
+- if (errno == EHOSTUNREACH)
+- *r_host_not_found = 1;
+- log_error ("can't connect to '%s': %s\n", server, strerror (errno));
++ err = gpg_err_make (default_errsource,
++ (errno == EHOSTUNREACH)? GPG_ERR_UNKNOWN_HOST
++ : gpg_err_code_from_syserror ());
++ log_error ("can't connect to '%s': %s\n", server, gpg_strerror (err));
++ return err;
+ }
+- else
+- notify_netactivity ();
+- return sock;
++
++ notify_netactivity ();
++ *r_sock = sock;
++ return 0;
+
+ #else /*!ASSUAN_SOCK_TOR*/
+
+- gpg_err_set_errno (ENETUNREACH);
+- return -1; /* Out of core. */
++ err = gpg_err_make (default_errsource, GPG_ERR_ENETUNREACH);
++ return ASSUAN_INVALID_FD;
+
+ #endif /*!HASSUAN_SOCK_TOR*/
+ }
+@@ -2533,6 +2526,7 @@ connect_server (const char *server, unsigned short port,
+ log_info ("getting '%s' SRV for '%s' failed: %s\n",
+ srvtag, server, gpg_strerror (err));
+ /* Note that on error SRVCOUNT is zero. */
++ err = 0;
+ }
+
+ if (!serverlist)
+@@ -2541,7 +2535,8 @@ connect_server (const char *server, unsigned short port,
+ up a fake SRV record. */
+ serverlist = xtrycalloc (1, sizeof *serverlist);
+ if (!serverlist)
+- return -1; /* Out of core. */
++ return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
++
+ serverlist->port = port;
+ strncpy (serverlist->target, server, DIMof (struct srventry, target));
+ serverlist->target[DIMof (struct srventry, target)-1] = '\0';
+@@ -2562,6 +2557,7 @@ connect_server (const char *server, unsigned short port,
+ {
+ log_info ("resolving '%s' failed: %s\n",
+ serverlist[srv].target, gpg_strerror (err));
++ last_err = err;
+ continue; /* Not found - try next one. */
+ }
+ hostfound = 1;
+@@ -2578,18 +2574,20 @@ connect_server (const char *server, unsigned short port,
+ sock = my_sock_new_for_addr (ai->addr, ai->socktype, ai->protocol);
+ if (sock == ASSUAN_INVALID_FD)
+ {
+- int save_errno = errno;
+- log_error ("error creating socket: %s\n", strerror (errno));
++ err = gpg_err_make (default_errsource,
++ gpg_err_code_from_syserror ());
++ log_error ("error creating socket: %s\n", gpg_strerror (err));
+ free_dns_addrinfo (aibuf);
+ xfree (serverlist);
+- errno = save_errno;
+- return ASSUAN_INVALID_FD;
++ return err;
+ }
+
+ anyhostaddr = 1;
+- ret = assuan_sock_connect (sock, ai->addr, ai->addrlen);
+- if (ret)
+- last_errno = errno;
++ if (assuan_sock_connect (sock, ai->addr, ai->addrlen))
++ {
++ last_err = gpg_err_make (default_errsource,
++ gpg_err_code_from_syserror ());
++ }
+ else
+ {
+ connected = 1;
+@@ -2616,17 +2614,18 @@ connect_server (const char *server, unsigned short port,
+ server, (int)WSAGetLastError());
+ #else
+ log_error ("can't connect to '%s': %s\n",
+- server, strerror (last_errno));
++ server, gpg_strerror (last_err));
+ #endif
+ }
+- if (!hostfound || (hostfound && !anyhostaddr))
+- *r_host_not_found = 1;
++ err = last_err? last_err : gpg_err_make (default_errsource,
++ GPG_ERR_UNKNOWN_HOST);
+ if (sock != ASSUAN_INVALID_FD)
+ assuan_sock_close (sock);
+- gpg_err_set_errno (last_errno);
+- return ASSUAN_INVALID_FD;
++ return err;
+ }
+- return sock;
++
++ *r_sock = sock;
++ return 0;
+ }
+
+
diff --git a/debian/patches/0016-gpg-Print-a-warning-on-Tor-problems.patch b/debian/patches/0016-gpg-Print-a-warning-on-Tor-problems.patch
new file mode 100644
index 0000000..1979069
--- /dev/null
+++ b/debian/patches/0016-gpg-Print-a-warning-on-Tor-problems.patch
@@ -0,0 +1,188 @@
+From: Werner Koch <wk at gnupg.org>
+Date: Tue, 24 Jan 2017 20:45:31 +0100
+Subject: gpg: Print a warning on Tor problems.
+
+* dirmngr/ks-engine-hkp.c (tor_not_running_p): New.
+(map_host): Call that to print a warning.
+(handle_send_request_error): Ditto and avoid marking the host dead.
+Also print a tor_config_problem warning. Add arg CTRL; adjust callers
+to pass that new arg.
+* g10/call-dirmngr.c (ks_status_cb): Detect and print the new
+warnings.
+
+Signed-off-by: Werner Koch <wk at gnupg.org>
+(cherry picked from commit 770b75a746836773909af25ccb9b480e61cea677)
+---
+ dirmngr/ks-engine-hkp.c | 60 ++++++++++++++++++++++++++++++++++++-------------
+ g10/call-dirmngr.c | 26 ++++++++++++++++++++-
+ 2 files changed, 70 insertions(+), 16 deletions(-)
+
+diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c
+index dad83efcd..858cd2f26 100644
+--- a/dirmngr/ks-engine-hkp.c
++++ b/dirmngr/ks-engine-hkp.c
+@@ -278,6 +278,31 @@ arecords_is_pool (dns_addrinfo_t aibuf)
+ }
+
+
++/* Print a warninng iff Tor is not running but Tor has been requested.
++ * Also return true if it is not running. */
++static int
++tor_not_running_p (ctrl_t ctrl)
++{
++ assuan_fd_t sock;
++
++ if (!opt.use_tor)
++ return 0;
++
++ sock = assuan_sock_connect_byname (NULL, 0, 0, NULL, ASSUAN_SOCK_TOR);
++ if (sock != ASSUAN_INVALID_FD)
++ {
++ assuan_sock_close (sock);
++ return 0;
++ }
++
++ log_info ("(it seems Tor is not running)\n");
++ dirmngr_status (ctrl, "WARNING", "tor_not_running 0",
++ "Tor is enabled but the local Tor daemon"
++ " seems to be down", NULL);
++ return 1;
++}
++
++
+ /* Add the host AI under the NAME into the HOSTTABLE. If PORT is not
+ zero, it specifies which port to use to talk to the host. If NAME
+ specifies a pool (as indicated by IS_POOL), update the given
+@@ -475,6 +500,8 @@ map_host (ctrl_t ctrl, const char *name, const char *srvtag, int force_reselect,
+ if (err)
+ {
+ xfree (reftbl);
++ if (gpg_err_code (err) == GPG_ERR_ECONNREFUSED)
++ tor_not_running_p (ctrl);
+ return err;
+ }
+
+@@ -1180,13 +1207,13 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
+ }
+
+
+-/* Helper to evaluate the error code ERR form a send_request() call
++/* Helper to evaluate the error code ERR from a send_request() call
+ with REQUEST. The function returns true if the caller shall try
+ again. TRIES_LEFT points to a variable to track the number of
+ retries; this function decrements it and won't return true if it is
+ down to zero. */
+ static int
+-handle_send_request_error (gpg_error_t err, const char *request,
++handle_send_request_error (ctrl_t ctrl, gpg_error_t err, const char *request,
+ unsigned int *tries_left)
+ {
+ int retry = 0;
+@@ -1197,16 +1224,9 @@ handle_send_request_error (gpg_error_t err, const char *request,
+ switch (gpg_err_code (err))
+ {
+ case GPG_ERR_ECONNREFUSED:
+- if (opt.use_tor)
+- {
+- assuan_fd_t sock;
+-
+- sock = assuan_sock_connect_byname (NULL, 0, 0, NULL, ASSUAN_SOCK_TOR);
+- if (sock == ASSUAN_INVALID_FD)
+- log_info ("(it seems Tor is not running)\n");
+- else
+- assuan_sock_close (sock);
+- }
++ if (tor_not_running_p (ctrl))
++ break; /* A retry does not make sense. */
++ /* Okay: Tor is up or --use-tor is not used. */
+ /*FALLTHRU*/
+ case GPG_ERR_ENETUNREACH:
+ case GPG_ERR_ENETDOWN:
+@@ -1224,6 +1244,16 @@ handle_send_request_error (gpg_error_t err, const char *request,
+ }
+ break;
+
++ case GPG_ERR_EACCES:
++ if (opt.use_tor)
++ {
++ log_info ("(Tor configuration problem)\n");
++ dirmngr_status (ctrl, "WARNING", "tor_config_problem 0",
++ "Please check that the \"SocksPort\" flag "
++ "\"IPv6Traffic\" is set in torrc", NULL);
++ }
++ break;
++
+ default:
+ break;
+ }
+@@ -1334,7 +1364,7 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
+ /* Send the request. */
+ err = send_request (ctrl, request, hostport, httphost, httpflags,
+ NULL, NULL, &fp, r_http_status);
+- if (handle_send_request_error (err, request, &tries))
++ if (handle_send_request_error (ctrl, err, request, &tries))
+ {
+ reselect = 1;
+ goto again;
+@@ -1468,7 +1498,7 @@ ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
+ /* Send the request. */
+ err = send_request (ctrl, request, hostport, httphost, httpflags,
+ NULL, NULL, &fp, NULL);
+- if (handle_send_request_error (err, request, &tries))
++ if (handle_send_request_error (ctrl, err, request, &tries))
+ {
+ reselect = 1;
+ goto again;
+@@ -1577,7 +1607,7 @@ ks_hkp_put (ctrl_t ctrl, parsed_uri_t uri, const void *data, size_t datalen)
+ /* Send the request. */
+ err = send_request (ctrl, request, hostport, httphost, 0,
+ put_post_cb, &parm, &fp, NULL);
+- if (handle_send_request_error (err, request, &tries))
++ if (handle_send_request_error (ctrl, err, request, &tries))
+ {
+ reselect = 1;
+ goto again;
+diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c
+index 4be9da117..2f2ba982e 100644
+--- a/g10/call-dirmngr.c
++++ b/g10/call-dirmngr.c
+@@ -374,7 +374,8 @@ ks_status_cb (void *opaque, const char *line)
+ {
+ struct ks_status_parm_s *parm = opaque;
+ gpg_error_t err = 0;
+- const char *s;
++ const char *s, *s2;
++ const char *warn;
+
+ if ((s = has_leading_keyword (line, parm->keyword? parm->keyword : "SOURCE")))
+ {
+@@ -385,6 +386,29 @@ ks_status_cb (void *opaque, const char *line)
+ err = gpg_error_from_syserror ();
+ }
+ }
++ else if ((s = has_leading_keyword (line, "WARNING")))
++ {
++ if ((s2 = has_leading_keyword (s, "tor_not_running")))
++ warn = _("Tor is not running");
++ else if ((s2 = has_leading_keyword (s, "tor_config_problem")))
++ warn = _("Tor is not properly configured");
++ else
++ warn = NULL;
++
++ if (warn)
++ {
++ log_info (_("WARNING: %s\n"), warn);
++ if (s2)
++ {
++ while (*s2 && !spacep (s2))
++ s2++;
++ while (*s2 && spacep (s2))
++ s2++;
++ if (*s2)
++ print_further_info ("%s", s2);
++ }
++ }
++ }
+
+ return err;
+ }
diff --git a/debian/patches/0017-agent-Fix-double-free.patch b/debian/patches/0017-agent-Fix-double-free.patch
new file mode 100644
index 0000000..b3d96ed
--- /dev/null
+++ b/debian/patches/0017-agent-Fix-double-free.patch
@@ -0,0 +1,49 @@
+From: Justus Winter <justus at g10code.com>
+Date: Wed, 25 Jan 2017 13:51:57 +0100
+Subject: agent: Fix double free.
+
+* agent/cache.c (agent_store_cache_hit): Make sure the update is
+atomic.
+--
+Previously, the function freed the last key, and duplicated the new
+key after doing that. There is a chance, however, that calling the
+allocator surrenders control to a different thread, causing a double
+free if a different thread also calls this function.
+
+To make sure the update is atomic under the non-preemptive thread
+model, we must make sure not to surrender control to a different
+thread. Therefore, we avoid calling the allocator during the
+update.
+
+Signed-off-by: Justus Winter <justus at g10code.com>
+(cherry picked from commit e175152ef7515921635bf1e00383e812668d13fc)
+---
+ agent/cache.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/agent/cache.c b/agent/cache.c
+index f58eaeaaa..248368277 100644
+--- a/agent/cache.c
++++ b/agent/cache.c
+@@ -475,6 +475,19 @@ agent_get_cache (const char *key, cache_mode_t cache_mode)
+ void
+ agent_store_cache_hit (const char *key)
+ {
+- xfree (last_stored_cache_key);
+- last_stored_cache_key = key? xtrystrdup (key) : NULL;
++ char *new;
++ char *old;
++
++ /* To make sure the update is atomic under the non-preemptive thread
++ * model, we must make sure not to surrender control to a different
++ * thread. Therefore, we avoid calling the allocator during the
++ * update. */
++ new = key ? xtrystrdup (key) : NULL;
++
++ /* Atomic update. */
++ old = last_stored_cache_key;
++ last_stored_cache_key = new;
++ /* Done. */
++
++ xfree (old);
+ }
diff --git a/debian/patches/series b/debian/patches/series
index a43241d..8ab8f62 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -9,3 +9,9 @@ gpg-agent-idling/0001-agent-Create-framework-of-scheduled-timers.patch
gpg-agent-idling/0002-agent-Allow-threads-to-interrupt-main-select-loop-wi.patch
gpg-agent-idling/0003-agent-Avoid-tight-timer-tick-when-possible.patch
gpg-agent-idling/0004-agent-Avoid-scheduled-checks-on-socket-when-inotify-.patch
+0012-tools-Fix-memory-leak.patch
+0013-tools-Improve-error-handling.patch
+0014-dirmngr-New-option-disable-ipv4.patch
+0015-dirmngr-Simplify-error-returning-inside-http.c.patch
+0016-gpg-Print-a-warning-on-Tor-problems.patch
+0017-agent-Fix-double-free.patch
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gnupg2.git
More information about the Pkg-gnupg-commit
mailing list