plugins/python/example*.py: pep8 fixes (mainly line too long)

This commit is contained in:
Robert Manner
2020-02-06 13:23:05 +01:00
committed by Todd C. Miller
parent 0f3631cc08
commit 45d2638571
8 changed files with 93 additions and 62 deletions

View File

@@ -2,6 +2,7 @@ import sudo
import signal import signal
from os import path from os import path
class ReasonLoggerIOPlugin(sudo.Plugin): class ReasonLoggerIOPlugin(sudo.Plugin):
""" """
An example sudo plugin demonstrating how to use the sudo conversation API. An example sudo plugin demonstrating how to use the sudo conversation API.
@@ -13,9 +14,10 @@ class ReasonLoggerIOPlugin(sudo.Plugin):
sudo.ConvMessage has the following fields (see help(sudo.ConvMessage)): sudo.ConvMessage has the following fields (see help(sudo.ConvMessage)):
msg_type: int Specifies the type of the conversation. msg_type: int Specifies the type of the conversation.
See sudo.CONV.* constants below. See sudo.CONV.* constants below.
timeout: int The maximum amount of time for the conversation in seconds. timeout: int The maximum amount of time for the conversation
After the timeout exceeds, the "sudo.conv" function will in seconds. After the timeout exceeds, the "sudo.conv"
raise sudo.ConversationInterrupted exception. function will raise sudo.ConversationInterrupted
exception.
msg: str The message to display for the user. msg: str The message to display for the user.
To specify the conversion type you can use the following constants: To specify the conversion type you can use the following constants:
@@ -27,17 +29,24 @@ class ReasonLoggerIOPlugin(sudo.Plugin):
sudo.CONV.PROMPT_ECHO_OK sudo.CONV.PROMPT_ECHO_OK
sudo.CONV.PREFER_TTY sudo.CONV.PREFER_TTY
""" """
def open(self, argv, command_info): def open(self, argv, command_info):
try: try:
conv_timeout = 120 # in seconds conv_timeout = 120 # in seconds
sudo.log_info("Please provide your reason for executing {}".format(argv)) sudo.log_info("Please provide your reason "
"for executing {}".format(argv))
# We ask two questions, the second is not visible on screen, so the user # We ask two questions, the second is not visible on screen,
# can hide a hidden message in case of criminals are forcing him for # so the user can hide a hidden message in case of criminals are
# running the command. # forcing him for running the command.
# You can either specify the arguments in strict order (timeout being optional), or use named arguments. # You can either specify the arguments in strict order (timeout
message1 = sudo.ConvMessage(sudo.CONV.PROMPT_ECHO_ON, "Reason: ", conv_timeout) # being optional), or use named arguments.
message2 = sudo.ConvMessage(msg="Secret reason: ", timeout=conv_timeout, msg_type=sudo.CONV.PROMPT_MASK) message1 = sudo.ConvMessage(sudo.CONV.PROMPT_ECHO_ON,
"Reason: ",
conv_timeout)
message2 = sudo.ConvMessage(msg="Secret reason: ",
timeout=conv_timeout,
msg_type=sudo.CONV.PROMPT_MASK)
reply1, reply2 = sudo.conv(message1, message2, reply1, reply2 = sudo.conv(message1, message2,
on_suspend=self.on_conversation_suspend, on_suspend=self.on_conversation_suspend,
on_resume=self.on_conversation_resume) on_resume=self.on_conversation_resume)
@@ -52,14 +61,18 @@ class ReasonLoggerIOPlugin(sudo.Plugin):
return sudo.RC.REJECT return sudo.RC.REJECT
def on_conversation_suspend(self, signum): def on_conversation_suspend(self, signum):
# This is just an example of how to do something on conversation suspend. # This is just an example of how to do something on conversation
# You can skip specifying 'on_suspend' argument if there is no need # suspend. You can skip specifying 'on_suspend' argument if there
sudo.log_info("conversation suspend: signal", self._signal_name(signum)) # is no need
sudo.log_info("conversation suspend: signal",
self._signal_name(signum))
def on_conversation_resume(self, signum): def on_conversation_resume(self, signum):
# This is just an example of how to do something on conversation resume. # This is just an example of how to do something on conversation
# You can skip specifying 'on_resume' argument if there is no need # resume. You can skip specifying 'on_resume' argument if there
sudo.log_info("conversation resume: signal was", self._signal_name(signum)) # is no need
sudo.log_info("conversation resume: signal was",
self._signal_name(signum))
# helper functions: # helper functions:
@classmethod @classmethod
@@ -70,5 +83,6 @@ class ReasonLoggerIOPlugin(sudo.Plugin):
return "{}".format(signum) return "{}".format(signum)
def _log_file_path(self): def _log_file_path(self):
log_path = sudo.options_as_dict(self.plugin_options).get("LogPath", "/tmp") options_dict = sudo.options_as_dict(self.plugin_options)
log_path = options_dict.get("LogPath", "/tmp")
return path.join(log_path, "sudo_reasons.txt") return path.join(log_path, "sudo_reasons.txt")

View File

@@ -1,27 +1,35 @@
import sudo import sudo
class DebugDemoPlugin(sudo.Plugin): class DebugDemoPlugin(sudo.Plugin):
""" """
An example sudo plugin demonstrating the debugging capabilities. An example sudo plugin demonstrating the debugging capabilities.
You can install it as an extra IO plugin for example by adding the following line to sudo.conf: You can install it as an extra IO plugin for example by adding the
Plugin python_io python_plugin.so ModulePath=<path>/example_debugging.py ClassName=DebugDemoPlugin following line to sudo.conf:
Plugin python_io python_plugin.so \
ModulePath=<path>/example_debugging.py \
ClassName=DebugDemoPlugin
To see the plugin's debug output, use the following line in sudo.conf: To see the plugin's debug output, use the following line in sudo.conf:
Debug python_plugin.so /var/log/sudo_python_debug plugin@trace,c_calls@trace Debug python_plugin.so \
/var/log/sudo_python_debug plugin@trace,c_calls@trace
^ ^-- the options for the logging ^ ^-- the options for the logging
^----- the output will be placed here ^----- the output will be placed here
The options for the logging is in format of multiple "subsystem@level" separated by commas (","). The options for the logging is in format of multiple "subsystem@level"
separated by commas (",").
The most interesting subsystems are: The most interesting subsystems are:
plugin Shows each call of sudo.debug API in the log plugin Shows each call of sudo.debug API in the log
- py_calls Logs whenever a C function calls into the python module. (For example calling this __init__ function.) - py_calls Logs whenever a C function calls into the python module.
(For example calling this __init__ function.)
c_calls Logs whenever python calls into a C sudo API function c_calls Logs whenever python calls into a C sudo API function
You can also specify "all" as subsystem name to get the debug messages of all subsystems. You can also specify "all" as subsystem name to get the debug messages of
all subsystems.
Other subsystems available: Other subsystems available:
internal logs internal functions of the python language wrapper plugin internal logs internal functions of the python language wrapper
sudo_cb logs when sudo calls into its plugin API sudo_cb logs when sudo calls into its plugin API
load logs python plugin loading / unloading load logs python plugin loading / unloading
@@ -38,21 +46,29 @@ class DebugDemoPlugin(sudo.Plugin):
See the sudo.conf manual for more details ("man sudo.conf"). See the sudo.conf manual for more details ("man sudo.conf").
""" """
def __init__(self, plugin_options, **kwargs): def __init__(self, plugin_options, **kwargs):
# Specify: "py_calls@info" debug option to show the call to this constructor and the arguments passed in # Specify: "py_calls@info" debug option to show the call to this
# constructor and the arguments passed in
# Specifying "plugin@err" debug option will show this message (or any more verbose level) # Specifying "plugin@err" debug option will show this message
sudo.debug(sudo.DEBUG.ERROR, "My demo purpose plugin shows this ERROR level debug message") # (or any more verbose level)
sudo.debug(sudo.DEBUG.ERROR, "My demo purpose plugin shows "
"this ERROR level debug message")
# Specifying "plugin@info" debug option will show this message (or any more verbose level) # Specifying "plugin@info" debug option will show this message
sudo.debug(sudo.DEBUG.INFO, "My demo purpose plugin shows this INFO level debug message") # (or any more verbose level)
sudo.debug(sudo.DEBUG.INFO, "My demo purpose plugin shows "
"this INFO level debug message")
# If you raise the level to info or below, the call of the debug will also be logged. # If you raise the level to info or below, the call of the debug
# will also be logged.
# An example output you will see in the debug log file: # An example output you will see in the debug log file:
# Dec 5 15:19:19 sudo[123040] __init__ @ /.../example_debugging.py:54 debugs: # Dec 5 15:19:19 sudo[123040] __init__ @ /.../example_debugging.py:54 debugs:
# Dec 5 15:19:19 sudo[123040] My demo purpose plugin shows this ERROR level debug message # Dec 5 15:19:19 sudo[123040] My demo purpose plugin shows this ERROR level debug message
# Specify: "c_calls@diag" debug option to show this call and its arguments # Specify: "c_calls@diag" debug option to show this call and its
# If you specify info debug level instead ("c_calls@info"), # arguments. If you specify info debug level instead ("c_calls@info"),
# you will also see the python function and line from which you called the 'options_as_dict' function. # you will also see the python function and line from which you called
# the 'options_as_dict' function.
self.plugin_options = sudo.options_as_dict(plugin_options) self.plugin_options = sudo.options_as_dict(plugin_options)

View File

@@ -1,7 +1,6 @@
import sudo import sudo
from typing import Tuple from typing import Tuple
import pwd
class SudoGroupPlugin(sudo.Plugin): class SudoGroupPlugin(sudo.Plugin):
@@ -21,9 +20,9 @@ class SudoGroupPlugin(sudo.Plugin):
sudo.RC.USAGE_ERROR -2 sudo.RC.USAGE_ERROR -2
If the function returns "None" (for example does not call return), it will If the function returns "None" (for example does not call return), it will
be considered sudo.RC.OK. If an exception is raised, its backtrace will be be considered sudo.RC.OK. If an exception other than sudo.PluginError is
shown to the user and the plugin function returns sudo.RC.ERROR. If that is raised, its backtrace will be shown to the user and the plugin function
not acceptable, catch it. returns sudo.RC.ERROR. If that is not acceptable, catch it.
""" """
# -- Plugin API functions -- # -- Plugin API functions --
@@ -34,8 +33,8 @@ class SudoGroupPlugin(sudo.Plugin):
database. Otherwise it is a tuple convertible to pwd.struct_passwd. database. Otherwise it is a tuple convertible to pwd.struct_passwd.
""" """
hardcoded_user_groups = { hardcoded_user_groups = {
"testgroup": [ "testuser1", "testuser2" ], "testgroup": ["testuser1", "testuser2"],
"mygroup": [ "test" ] "mygroup": ["test"]
} }
group_has_user = user in hardcoded_user_groups.get(group, []) group_has_user = user in hardcoded_user_groups.get(group, [])

View File

@@ -5,7 +5,7 @@ import errno
import signal import signal
import sys import sys
import json import json
from typing import Tuple, Dict from typing import Tuple
VERSION = 1.0 VERSION = 1.0
@@ -30,14 +30,15 @@ class SudoIOPlugin(sudo.Plugin):
sudo.RC.USAGE_ERROR -2 sudo.RC.USAGE_ERROR -2
If the function returns "None" (for example does not call return), it will If the function returns "None" (for example does not call return), it will
be considered sudo.RC.OK. If an exception is raised, its backtrace will be be considered sudo.RC.OK. If an exception other than sudo.PluginError is
shown to the user and the plugin function returns sudo.RC.ERROR. If that is raised, its backtrace will be shown to the user and the plugin function
not acceptable, catch it. returns sudo.RC.ERROR. If that is not acceptable, catch it.
""" """
# -- Plugin API functions -- # -- Plugin API functions --
def __init__(self, version: str, plugin_options: Tuple[str, ...], **kwargs): def __init__(self, version: str,
plugin_options: Tuple[str, ...], **kwargs):
"""The constructor of the IO plugin. """The constructor of the IO plugin.
Other variables you can currently use as arguments are: Other variables you can currently use as arguments are:
@@ -65,7 +66,8 @@ class SudoIOPlugin(sudo.Plugin):
self._log("", "-- Plugin DESTROYED --") self._log("", "-- Plugin DESTROYED --")
self._log_file.close() self._log_file.close()
def open(self, argv: Tuple[str, ...], command_info: Tuple[str, ...]) -> int: def open(self, argv: Tuple[str, ...],
command_info: Tuple[str, ...]) -> int:
"""Receives the command the user wishes to run. """Receives the command the user wishes to run.
This function works the same as open() call of the C IO plugin API (see This function works the same as open() call of the C IO plugin API (see

View File

@@ -6,8 +6,7 @@ import os
import pwd import pwd
import grp import grp
import shutil import shutil
from copy import copy from typing import Tuple
from typing import Tuple, Dict
VERSION = 1.0 VERSION = 1.0
@@ -36,9 +35,9 @@ class SudoPolicyPlugin(sudo.Plugin):
sudo.RC.USAGE_ERROR -2 sudo.RC.USAGE_ERROR -2
If the function returns "None" (for example does not call return), it will If the function returns "None" (for example does not call return), it will
be considered sudo.RC.OK. If an exception is raised, its backtrace will be be considered sudo.RC.OK. If an exception other than sudo.PluginError is
shown to the user and the plugin function returns sudo.RC.ERROR. If that is raised, its backtrace will be shown to the user and the plugin function
not acceptable, catch it. returns sudo.RC.ERROR. If that is not acceptable, catch it.
""" """
_allowed_commands = ("id", "whoami") _allowed_commands = ("id", "whoami")
@@ -99,7 +98,7 @@ class SudoPolicyPlugin(sudo.Plugin):
# This is how you change the user_env: # This is how you change the user_env:
return (sudo.RC.OK, user_env + ("PLUGIN_EXAMPLE_ENV=1",)) return (sudo.RC.OK, user_env + ("PLUGIN_EXAMPLE_ENV=1",))
# If you do not want to change user_env, you can also just return (or None): # If you do not want to change user_env, you can just return (or None):
# return sudo.RC.OK # return sudo.RC.OK
def list(self, argv: Tuple[str, ...], is_verbose: int, user: str): def list(self, argv: Tuple[str, ...], is_verbose: int, user: str):
@@ -122,7 +121,8 @@ class SudoPolicyPlugin(sudo.Plugin):
pass # we have no cache pass # we have no cache
def show_version(self, is_verbose: int): def show_version(self, is_verbose: int):
sudo.log_info("Python Example Policy Plugin version: {}".format(VERSION)) sudo.log_info("Python Example Policy Plugin "
"version: {}".format(VERSION))
if is_verbose: if is_verbose:
sudo.log_info("Python interpreter version:", sys.version) sudo.log_info("Python interpreter version:", sys.version)
@@ -148,7 +148,7 @@ class SudoPolicyPlugin(sudo.Plugin):
path = self.user_env.get("PATH", "/usr/bin:/bin") path = self.user_env.get("PATH", "/usr/bin:/bin")
absolute_cmd = shutil.which(cmd, path=path) absolute_cmd = shutil.which(cmd, path=path)
if not absolute_cmd: if not absolute_cmd:
raise SudoPluginError("Can not find cmd '{}' on PATH".format(cmd)) raise sudo.PluginError("Can not find cmd '{}' on PATH".format(cmd))
return absolute_cmd return absolute_cmd
def _runas_pwd(self): def _runas_pwd(self):

View File

@@ -1,7 +1,7 @@
__init__ @ SRC_DIR/example_debugging.py:45 calls C function: __init__ @ SRC_DIR/example_debugging.py:56 calls C function:
sudo.debug was called with arguments: (<DEBUG.ERROR: 2>, 'My demo purpose plugin shows this ERROR level debug message') sudo.debug was called with arguments: (<DEBUG.ERROR: 2>, 'My demo purpose plugin shows this ERROR level debug message')
__init__ @ SRC_DIR/example_debugging.py:48 calls C function: __init__ @ SRC_DIR/example_debugging.py:61 calls C function:
sudo.debug was called with arguments: (<DEBUG.INFO: 6>, 'My demo purpose plugin shows this INFO level debug message') sudo.debug was called with arguments: (<DEBUG.INFO: 6>, 'My demo purpose plugin shows this INFO level debug message')
__init__ @ SRC_DIR/example_debugging.py:58 calls C function: __init__ @ SRC_DIR/example_debugging.py:74 calls C function:
sudo.options_as_dict was called with arguments: (('ModulePath=SRC_DIR/example_debugging.py', 'ClassName=DebugDemoPlugin'),) sudo.options_as_dict was called with arguments: (('ModulePath=SRC_DIR/example_debugging.py', 'ClassName=DebugDemoPlugin'),)
sudo.options_as_dict returned result: {'ModulePath': 'SRC_DIR/example_debugging.py', 'ClassName': 'DebugDemoPlugin'} sudo.options_as_dict returned result: {'ModulePath': 'SRC_DIR/example_debugging.py', 'ClassName': 'DebugDemoPlugin'}

View File

@@ -1,4 +1,4 @@
__init__ @ SRC_DIR/example_debugging.py:45 debugs: __init__ @ SRC_DIR/example_debugging.py:56 debugs:
My demo purpose plugin shows this ERROR level debug message My demo purpose plugin shows this ERROR level debug message
__init__ @ SRC_DIR/example_debugging.py:48 debugs: __init__ @ SRC_DIR/example_debugging.py:61 debugs:
My demo purpose plugin shows this INFO level debug message My demo purpose plugin shows this INFO level debug message

View File

@@ -1,7 +1,7 @@
Example sudo python plugin will log to /some/not/writable/directory/sudo.log Example sudo python plugin will log to /some/not/writable/directory/sudo.log
Traceback: Traceback:
File "SRC_DIR/example_io_plugin.py", line 60, in __init__ File "SRC_DIR/example_io_plugin.py", line 61, in __init__
self._open_log_file(path.join(log_path, "sudo.log")) self._open_log_file(path.join(log_path, "sudo.log"))
File "SRC_DIR/example_io_plugin.py", line 132, in _open_log_file File "SRC_DIR/example_io_plugin.py", line 134, in _open_log_file
self._log_file = open(log_path, "a") self._log_file = open(log_path, "a")