From 75b9a26a37f556bfc8cefe94bcdab07cd92876d3 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Thu, 9 Apr 2020 10:49:59 -0600 Subject: [PATCH] If the signal.Signals enum is not present, search the dictionary. The Signals enum was added in Python 3.5. If it is not present we need to iterate over the dictionary items, looking for signal name to number mappings. Fixes the signal tests with Python 3.4. --- plugins/python/example_conversation.py | 20 ++++++++++++++----- plugins/python/example_io_plugin.py | 20 +++++++++++++++---- ..._plugin_fails_with_python_backtrace.stdout | 2 +- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/plugins/python/example_conversation.py b/plugins/python/example_conversation.py index 3414fbe30..8e68d369b 100644 --- a/plugins/python/example_conversation.py +++ b/plugins/python/example_conversation.py @@ -75,11 +75,21 @@ class ReasonLoggerIOPlugin(sudo.Plugin): self._signal_name(signum)) # helper functions: - @classmethod - def _signal_name(cls, signum): - try: - return signal.Signals(signum).name - except Exception: + if hasattr(signal, "Signals"): + @classmethod + def _signal_name(cls, signum: int): + try: + return signal.Signals(signum).name + except Exception: + return "{}".format(signum) + else: + @classmethod + def _signal_name(cls, signum: int): + for n, v in sorted(signal.__dict__.items()): + if v != signum: + continue + if n.startswith("SIG") and not n.startswith("SIG_"): + return n return "{}".format(signum) def _log_file_path(self): diff --git a/plugins/python/example_io_plugin.py b/plugins/python/example_io_plugin.py index 6cb644b73..dc4c6a762 100644 --- a/plugins/python/example_io_plugin.py +++ b/plugins/python/example_io_plugin.py @@ -104,10 +104,7 @@ class SudoIOPlugin(sudo.Plugin): self._log("WINSIZE", "{}x{}".format(line, cols)) def log_suspend(self, signo: int) -> int: - try: - signal_description = signal.Signals(signo).name - except (AttributeError, ValueError): - signal_description = "signal {}".format(signo) + signal_description = self._signal_name(signo) self._log("SUSPEND", signal_description) @@ -139,3 +136,18 @@ class SudoIOPlugin(sudo.Plugin): def _log(self, type, message): print(type, message, file=self._log_file) return sudo.RC.ACCEPT + + if hasattr(signal, "Signals"): + def _signal_name(cls, signo: int): + try: + return signal.Signals(signo).name + except ValueError: + return "signal {}".format(signo) + else: + def _signal_name(cls, signo: int): + for n, v in sorted(signal.__dict__.items()): + if v != signo: + continue; + if n.startswith("SIG") and not n.startswith("SIG_"): + return n + return "signal {}".format(signo) diff --git a/plugins/python/regress/testdata/check_example_io_plugin_fails_with_python_backtrace.stdout b/plugins/python/regress/testdata/check_example_io_plugin_fails_with_python_backtrace.stdout index eb938f069..10b0e237f 100644 --- a/plugins/python/regress/testdata/check_example_io_plugin_fails_with_python_backtrace.stdout +++ b/plugins/python/regress/testdata/check_example_io_plugin_fails_with_python_backtrace.stdout @@ -2,6 +2,6 @@ Example sudo python plugin will log to /some/not/writable/directory/sudo.log Traceback: File "SRC_DIR/example_io_plugin.py", line 64, in __init__ self._open_log_file(path.join(log_path, "sudo.log")) - File "SRC_DIR/example_io_plugin.py", line 137, in _open_log_file + File "SRC_DIR/example_io_plugin.py", line 134, in _open_log_file self._log_file = open(log_path, "a")