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

Assigned To
Authored By
hlein
Feb 14 2024, 10:45 PM

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.