Fix SSH agent spawning on POSIX in the test suite
Marco Ricci

Marco Ricci commited on 2026-01-04 22:06:26
Zeige 1 geänderte Dateien mit 11 Einfügungen und 2 Löschungen.


If the `executable` passed to the `spawn_named_agent` function is
`None`, we now correctly locate the agent in `PATH` using its default
name, for all our SSH agent spawning functions.  This was advertised to
work this way when we introduced SSH agent interfacing functions in the
test suite in 41029a5e6ef04a9870dcaf044b54a26af94260ab and updated the
`spawn_named_agent` signature to match in
6340b5a541970c9d00ee653926102657028de309, but was never actually
implemented, until now.

Prior to 6340b5a541970c9d00ee653926102657028de309, the `executable`
argument to `spawn_named_agent` was both a registry key and the basename
of the executable to call, to be located in `PATH`.  In that scheme,
a `None` value meant that there was no external executable to spawn, so
the agent-specific spawning functions would return a failure code.  In
6340b5a541970c9d00ee653926102657028de309, the interpretation was changed
to an "override" path: a string value for `executable` meant "use this
path for the executable", a `None` value meant "use the default name,
and locate the executable in `PATH`".  But the corresponding *logic* for
the `None` value case, i.e., searching `PATH`, was never actually
implemented.

Because none of the standard agent spawning/interfacing function
definitions made use of this override mechanism, all SSH agent spawning
functions were silently breaking, flatly claiming that the agents were
not available even though they actually might have been.  Furthermore,
because this code refactoring was developed on The Annoying OS, where
all current SSH agents are interfaced, not spawned, this failure went
completely unnoticed.  Now, while double-checking that the new
Annoying-OS-specific code also works on POSIX, this misbehavior of the
SSH agent spawning logic became apparent again, because on POSIX we *do*
have agents that are spawned, not merely interfaced.

So reintroduce the logic to locate the (default) executable if the path
is not overriden.
... ...
@@ -11,6 +11,7 @@ import datetime
11 11
 import importlib
12 12
 import importlib.util
13 13
 import os
14
+import shutil
14 15
 import socket
15 16
 import subprocess
16 17
 import sys
... ...
@@ -240,7 +241,11 @@ def spawn_pageant_on_posix(  # pragma: no cover [external]
240 241
         subprocess.
241 242
 
242 243
     """
243
-    if executable is None or os.name == "nt":  # pragma: no cover [external]
244
+    if os.name == "nt":  # pragma: no cover [external]
245
+        return None
246
+    if executable is None:  # pragma: no cover [external]
247
+        executable = shutil.which("pageant")
248
+        if executable is None:
244 249
             return None
245 250
 
246 251
     # Apparently, Pageant 0.81 and lower running in debug mode does
... ...
@@ -307,7 +312,11 @@ def spawn_openssh_agent_on_posix(  # pragma: no cover [external]
307 312
         subprocess.
308 313
 
309 314
     """
310
-    if executable is None or os.name == "nt":  # pragma: no cover [external]
315
+    if os.name == "nt":  # pragma: no cover [external]
316
+        return None
317
+    if executable is None:  # pragma: no cover [external]
318
+        executable = shutil.which("ssh-agent")
319
+        if executable is None:
311 320
             return None
312 321
     return subprocess.Popen(
313 322
         ["ssh-agent", "-D", "-s"],
314 323