Visitar URL original
fix(auth): properly extract stdout from gnubby webauthn plugin failur… · googleapis/google-cloud-python@744e826 · GitHub
Skip to content

Commit 744e826

Browse files
authored
fix(auth): properly extract stdout from gnubby webauthn plugin failures (#17885)
Context: b/534311894
1 parent b692dae commit 744e826

2 files changed

Lines changed: 39 additions & 3 deletions

File tree

‎packages/google-auth/google/oauth2/webauthn_handler.py‎

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,24 @@ def _call_plugin(self, cmd: str, input_json: str) -> str:
5757
request = length_bytes_le + input_json.encode()
5858

5959
# Call plugin
60-
process_result = subprocess.run(
61-
[cmd], input=request, capture_output=True, check=True
62-
)
60+
process_result = subprocess.run([cmd], input=request, capture_output=True)
61+
62+
if process_result.returncode != 0:
63+
stdout_bytes = process_result.stdout
64+
if (
65+
len(stdout_bytes) >= 4
66+
and struct.unpack("<I", stdout_bytes[:4])[0] == len(stdout_bytes) - 4
67+
):
68+
stdout_bytes = stdout_bytes[4:]
69+
70+
error_msg = "Command '{}' returned non-zero exit status {}.\nStdout: {}\nStderr: {}".format(
71+
cmd,
72+
process_result.returncode,
73+
stdout_bytes.decode(errors="replace").strip(),
74+
process_result.stderr.decode(errors="replace").strip(),
75+
)
76+
77+
raise exceptions.GoogleAuthError(error_msg)
6378

6479
# Check length of response
6580
response_len_le = process_result.stdout[:4]

‎packages/google-auth/tests/oauth2/test_webauthn_handler.py‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ def test_malformated_get_assertion_response(os_get_stub, subprocess_run_stub):
4949
response_len = struct.pack("<I", 5)
5050
response = "1234567890"
5151
mock_response = mock.Mock()
52+
mock_response.returncode = 0
5253
mock_response.stdout = response_len + response.encode()
5354
subprocess_run_stub.return_value = mock_response
5455

@@ -68,6 +69,7 @@ def test_failure_get_assertion(os_get_stub, subprocess_run_stub):
6869

6970
# process returns get response in json
7071
mock_response = mock.Mock()
72+
mock_response.returncode = 0
7173
mock_response.stdout = response_len + response_json
7274
subprocess_run_stub.return_value = mock_response
7375

@@ -96,6 +98,7 @@ def test_success_get_assertion(os_get_stub, subprocess_run_stub):
9698

9799
# process returns get response in json
98100
mock_response = mock.Mock()
101+
mock_response.returncode = 0
99102
mock_response.stdout = valid_plugin_response_len + valid_plugin_response_json
100103
subprocess_run_stub.return_value = mock_response
101104

@@ -146,3 +149,21 @@ def test_success_get_assertion(os_get_stub, subprocess_run_stub):
146149
assert (
147150
got_response.response.user_handle == success_response["response"]["userHandle"]
148151
)
152+
153+
154+
def test_plugin_nonzero_exit(os_get_stub, subprocess_run_stub):
155+
response_json = b"detailed_gnubby_internal_crash_log"
156+
response_len = struct.pack("<I", len(response_json))
157+
158+
mock_response = mock.Mock()
159+
mock_response.returncode = 1
160+
mock_response.stdout = response_len + response_json
161+
mock_response.stderr = b"stderr dump"
162+
subprocess_run_stub.return_value = mock_response
163+
164+
test_handler = webauthn_handler.PluginHandler()
165+
with pytest.raises(exceptions.GoogleAuthError) as excinfo:
166+
test_handler.get(GET_ASSERTION_REQUEST)
167+
168+
assert "returned non-zero exit status 1" in str(excinfo.value)
169+
assert "detailed_gnubby_internal_crash_log" in str(excinfo.value)

0 commit comments

Comments
 (0)