Page MenuHome GnuPG

gnupg-2.4.4 breaks dirmngr fetching keys via hkps:// from behind a proxy
Closed, ResolvedPublic

Description

When behind a proxy with:

# echo $http_proxy | sed 's/[0-9]/N/g'
http://NNN.NNN.NNN.NNN:NNNN/

# cat ~/.gnupg/dirmngr.conf 
honor-http-proxy

gnupg-2.4.3 can recv-keys fine:

# killall dirmngr 2>/dev/null ; gpg --version | head -n1 ; gpg --keyserver hkps://keys.gentoo.org --recv-keys 39EA32FE8222EEEC
gpg (GnuPG) 2.4.3
gpg: key 39EA32FE8222EEEC: "Ulrich Müller <ulm@gentoo.org>" not changed
gpg: Total number processed: 1
gpg:              unchanged: 1

gnupg 2.4.4 fails:

# killall dirmngr 2>/dev/null ; gpg --version | head -n1 ; gpg --keyserver hkps://keys.gentoo.org --recv-keys 39EA32FE8222EEEC
gpg (GnuPG) 2.4.4
gpg: keyserver receive failed: No keyserver available

When I watch the proxy, it is not that 2.4.4 makes no attempt to connect. It's that it doesn't send CONNECT, instead something the proxy server doesn't like:

NNN.NNN.NNN.NNN - - [14/Feb/2024:16:36:19 -0500] "- error:invalid-request HTTP/1.1" 400 3585 397 - "-" "-" NONE_NONE:HIER_NONE

When I sniff this, it's binary goo as soon as the 3WHS completes.

There's mentions of proxy handling changes in the 2.4.4 release notes, but they only talk about Windows systems; this is on Linux.

This might only impact hkps://. I'm having trouble finding an hkp:// server that's still alive, but when I attempt one, I see the client issuing a well-formed GET through the proxy, which of course then times out.

Details

Version
2.4.4

Event Timeline

gniibe changed the task status from Open to Testing.Feb 15 2024, 7:44 AM
gniibe claimed this task.
gniibe triaged this task as Normal priority.
gniibe added a project: gnupg24.
gniibe added a subscriber: gniibe.

Thank you for the report. There was a problem in: rG845d5e61d8e1: dirmngr: Cleanup the http module.
Pushed the fix in: rG04cbc3074aa9: dirmngr: Fix proxy with TLS.

Right. I was wrong assuming the code in 2.2 branch is stable (that is: well tested).

Another fix is pushed: rG848546b05ab0: dirmngr: Fix the regression of use of proxy for TLS connection.

We need to fix 2.2 branch too.

gniibe moved this task from Backlog to WiP on the gnupg22 board.

IIUC, the code for keep_alive is for negotiation of proxy. If so, something like this is the fix:

diff --git a/dirmngr/http.c b/dirmngr/http.c
index ac7e13241..7b206c23a 100644
--- a/dirmngr/http.c
+++ b/dirmngr/http.c
@@ -2553,7 +2553,7 @@ run_proxy_connect (http_t hd, proxy_info_t proxy,
    * RFC-4559 - SPNEGO-based Kerberos and NTLM HTTP Authentication
    */
   auth_basic = !!proxy->uri->auth;
-  hd->keep_alive = 0;
+  hd->keep_alive = !!proxy->outtoken;
 
   /* For basic authentication we need to send just one request.  */
   if (auth_basic
@@ -2717,6 +2717,14 @@ run_proxy_connect (http_t hd, proxy_info_t proxy,
     }
 
  leave:
+  if (hd->keep_alive)
+    {
+      es_fclose (hd->fp_write);
+      hd->fp_write = NULL;
+      /* The close has released the cookie and thus we better set it
+       * to NULL.  */
+      hd->write_cookie = NULL;
+    }
   /* Restore flags, destroy stream, reset state.  */
   hd->flags = saved_flags;
   es_fclose (hd->fp_read);

Thank you @gniibe! Applied the rG848546b05ab0: dirmngr: Fix the regression of use of proxy for TLS connection. changes here, and 2.4.4 works here now.

I did not try your extra keep_alive fix.

@hlein Thanks a lot for quick testing.

Please note that keep_alive fix is for Windows.

I was wrong for the semantics of proxy->outtoken. It is zero when run_proxy_connect is called and enabled during the negotiation.

I fix this in: rG2810b934647e: dirmngr: Fix keep-alive flag handling.

werner edited projects, added gnupg24 (gnupg-2.4.5); removed gnupg24.