From b4e4680ef49c4062e8603cd6e86e93f8520f1d41 Mon Sep 17 00:00:00 2001 From: Scott Kuhl Date: Mon, 1 Jan 2024 16:01:39 -0500 Subject: [PATCH] Workaround when sudo prints text to standard out When we use sudo and start the firewall process, we should be able to read standard in and find the string "READY". However, some administrators use a wrapper around sudo to print warning messages (instead of sudo's lecture feature) to standard out. This commit reads up to 100 lines looking for "READY" instead of expecting it on the first line. I believe this should fix issue #916. --- sshuttle/client.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/sshuttle/client.py b/sshuttle/client.py index c652f65..2b0bd18 100644 --- a/sshuttle/client.py +++ b/sshuttle/client.py @@ -302,10 +302,28 @@ class FirewallClient: '%r returned %d' % (self.argv, rv)) continue + # Normally, READY will be the first text on the first + # line. However, if an administrator replaced sudo with a + # shell script that echos a message to stdout and then + # runs sudo, READY won't be on the first line. To + # workaround this problem, we read a limited number of + # lines until we encounter "READY". Store all of the text + # we skipped in case we need it for an error message. + # + # A proper way to print a sudo warning message is to use + # sudo's lecture feature. sshuttle works correctly without + # this hack if sudo's lecture feature is used instead. + skipped_text = line + for i in range(100): + if line[0:5] == b'READY': + break + line = self.pfile.readline() + skipped_text += line + if line[0:5] != b'READY': debug1('Unable to start firewall manager. ' 'Expected READY, got %r. ' - 'Command=%r' % (line, self.argv)) + 'Command=%r' % (skipped_text, self.argv)) continue method_name = line[6:-1]