From 1fcb031192d4888b41f2e2128b1c3531d7058e83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Sat, 21 Sep 2019 03:47:30 +0200 Subject: [PATCH] Add support for run_service(..., filter_esc=True) in a VM Since qrexec-client-vm got support for filtering escape characters, use it here too. QubesOS/qubes-issues#5322 --- qubesadmin/app.py | 15 ++++++++++----- qubesadmin/tests/app.py | 16 ++++++++++++---- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/qubesadmin/app.py b/qubesadmin/app.py index e1469d6..440f9fd 100644 --- a/qubesadmin/app.py +++ b/qubesadmin/app.py @@ -678,14 +678,16 @@ class QubesRemote(QubesBase): :param bool wait: wait for process to finish :rtype: subprocess.Popen """ - if filter_esc: - raise NotImplementedError( - 'filter_esc not implemented for calls from VM') if user: raise ValueError( 'non-default user not possible for calls from VM') if not wait and localcmd: raise ValueError('wait=False incompatible with localcmd') + qrexec_opts = [] + if filter_esc: + qrexec_opts.extend(['-t']) + if filter_esc or os.isatty(sys.stderr.fileno()): + qrexec_opts.extend(['-T']) if not wait: # qrexec-client-vm can only request service calls, which are # started using MSG_EXEC_CMDLINE qrexec protocol message; this @@ -700,6 +702,9 @@ class QubesRemote(QubesBase): kwargs.setdefault('stdout', subprocess.PIPE) kwargs.setdefault('stderr', subprocess.PIPE) proc = subprocess.Popen( - [qubesadmin.config.QREXEC_CLIENT_VM, dest or '', service] + ( - shlex.split(localcmd) if localcmd else []), **kwargs) + [qubesadmin.config.QREXEC_CLIENT_VM] + + qrexec_opts + + [dest or '', service] + + (shlex.split(localcmd) if localcmd else []), + **kwargs) return proc diff --git a/qubesadmin/tests/app.py b/qubesadmin/tests/app.py index 4a19cb1..143a314 100644 --- a/qubesadmin/tests/app.py +++ b/qubesadmin/tests/app.py @@ -880,26 +880,34 @@ class TC_30_QubesRemote(unittest.TestCase): ]) self.assertEqual(value, b'return-value') + @mock.patch('os.isatty', lambda fd: fd == 2) def test_010_run_service(self): self.app.run_service('some-vm', 'service.name') self.proc_mock.assert_called_once_with([ qubesadmin.config.QREXEC_CLIENT_VM, - 'some-vm', 'service.name'], + '-T', 'some-vm', 'service.name'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + @mock.patch('os.isatty', lambda fd: fd == 2) def test_011_run_service_filter_esc(self): - with self.assertRaises(NotImplementedError): - p = self.app.run_service('some-vm', 'service.name', filter_esc=True) + self.app.run_service('some-vm', 'service.name', filter_esc=True) + self.proc_mock.assert_called_once_with([ + qubesadmin.config.QREXEC_CLIENT_VM, + '-t', '-T', 'some-vm', 'service.name'], + stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + @mock.patch('os.isatty', lambda fd: fd == 2) def test_012_run_service_user(self): with self.assertRaises(ValueError): p = self.app.run_service('some-vm', 'service.name', user='user') + @mock.patch('os.isatty', lambda fd: fd == 2) def test_013_run_service_default_target(self): self.app.run_service('', 'service.name') self.proc_mock.assert_called_once_with([ qubesadmin.config.QREXEC_CLIENT_VM, - '', 'service.name'], + '-T', '', 'service.name'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)