plugins/python/example*.py: pep8 fixes (mainly line too long)
This commit is contained in:

committed by
Todd C. Miller

parent
0f3631cc08
commit
45d2638571
@@ -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")
|
||||||
|
@@ -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)
|
||||||
|
@@ -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 --
|
||||||
|
@@ -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
|
||||||
|
@@ -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):
|
||||||
|
@@ -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'}
|
||||||
|
@@ -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
|
||||||
|
@@ -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")
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user