Fix unloading SSH keys in the test suite
Marco Ricci

Marco Ricci commited on 2026-03-22 13:24:44
Zeige 1 geänderte Dateien mit 21 Einfügungen und 7 Löschungen.


In the `ssh_agent_client_with_test_keys_loaded` test fixture, fix the
unloading of the SSH test keys during fixture teardown.  Previously, the
test keys were persisting in the agent due to a protocol violation in
our request -- the payload should be wrapped in an extra layer of
`SSHAgentClient.string` -- but the fixture either never unloaded keys in
the first place (for isolated agents) or it misinterpreted the resulting
error message as indicating that the key was no longer available in the
agent anyway.

To avoid making such silent errors in the future, we now always unload
keys, even for isolated agents, so that these errors have as high
a chance as possible of triggering non-silently.
... ...
@@ -1074,7 +1074,20 @@ def ssh_agent_client_with_test_keys_loaded(
1074 1074
             )
1075 1075
         yield client
1076 1076
     finally:
1077
-        if not isolated:  # pragma: no cover [external]
1077
+        request_code = _types.SSH_AGENTC.REMOVE_IDENTITY
1078
+        # For isolated agents, we have full control over the loaded key
1079
+        # set, and thus expect to successfully unload every key. For
1080
+        # non-isolated agents, the user or another process may load or
1081
+        # unload keys in the meantime, so we cannot assume that the
1082
+        # operation will succeed.
1083
+        response_code = (
1084
+            frozenset({_types.SSH_AGENT.SUCCESS})
1085
+            if isolated
1086
+            else frozenset({
1087
+                _types.SSH_AGENT.SUCCESS,
1088
+                _types.SSH_AGENT.FAILURE,
1089
+            })
1090
+        )
1078 1091
         for key_type in successfully_loaded_keys:
1079 1092
             key_struct = data.ALL_KEYS[key_type]
1080 1093
             # The public key blob is the base64-encoded part in
... ...
@@ -1082,12 +1095,13 @@ def ssh_agent_client_with_test_keys_loaded(
1082 1095
             public_key = base64.standard_b64decode(
1083 1096
                 key_struct.public_key.split(None, 2)[1]
1084 1097
             )
1085
-                request_code = _types.SSH_AGENTC.REMOVE_IDENTITY
1098
+            # Though unnecessary for isolated agents, unloading the key
1099
+            # is vital functionality for non-isolated agents.  We thus
1100
+            # always unload keys, and use the "isolated agent" case as
1101
+            # a smoke test for the more brittle "non-isolated agent"
1102
+            # case.
1086 1103
             client.request(
1087 1104
                 request_code,
1088
-                    public_key,
1089
-                    response_code=frozenset({
1090
-                        _types.SSH_AGENT.SUCCESS,
1091
-                        _types.SSH_AGENT.FAILURE,
1092
-                    }),
1105
+                ssh_agent.SSHAgentClient.string(public_key),
1106
+                response_code=response_code,
1093 1107
             )
1094 1108