plugins/python: example plugin demonstrating conversation and debug API
This commit is contained in:

committed by
Todd C. Miller

parent
523bcbedb6
commit
4ad362dd8f
69
plugins/python/example_conversation.py
Normal file
69
plugins/python/example_conversation.py
Normal file
@@ -0,0 +1,69 @@
|
||||
import sudo
|
||||
import signal
|
||||
|
||||
class ReasonLoggerIOPlugin(sudo.Plugin):
|
||||
"""
|
||||
An example sudo plugin demonstrating how to use the sudo conversation API.
|
||||
|
||||
From the python plugin, you can ask something from the user using the
|
||||
"sudo.conv" function. It expects one or more "sudo.ConvMessage" instances
|
||||
which specifies how the interaction has to look like.
|
||||
|
||||
sudo.ConvMessage has the following fields (see help(sudo.ConvMessage)):
|
||||
msg_type: int Specifies the type of the conversation.
|
||||
See sudo.CONV_* constants below.
|
||||
timeout: int The maximum amount of time for the conversation in seconds.
|
||||
After the timeout exceeds, the "sudo.conv" function will
|
||||
raise sudo.ConversationInterrupted exception.
|
||||
msg: str The message to display for the user.
|
||||
|
||||
To specify the conversion type you can use the following constants:
|
||||
sudo.CONV_PROMPT_ECHO_OFF
|
||||
sudo.CONV_PROMPT_ECHO_ON
|
||||
sudo.CONV_ERROR_MSG
|
||||
sudo.CONV_INFO_MSG
|
||||
sudo.CONV_PROMPT_MASK
|
||||
sudo.CONV_PROMPT_ECHO_OK
|
||||
sudo.CONV_PREFER_TTY
|
||||
"""
|
||||
def open(self, argv, command_info):
|
||||
try:
|
||||
conv_timeout = 120 # in seconds
|
||||
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
|
||||
# can hide a hidden message in case of criminals are forcing him for
|
||||
# running the command.
|
||||
# You can either specify the arguments in strict order (timeout being optional), or use named arguments.
|
||||
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,
|
||||
on_suspend=self.on_conversation_suspend,
|
||||
on_resume=self.on_conversation_resume)
|
||||
|
||||
with open("/tmp/sudo_reasons.txt", "a") as file:
|
||||
print("Executed", ' '.join(argv), file=file)
|
||||
print("Reason:", reply1, file=file)
|
||||
print("Hidden reason:", reply2, file=file)
|
||||
|
||||
except sudo.ConversationInterrupted:
|
||||
sudo.log_error("You did not answer in time")
|
||||
return sudo.RC_REJECT
|
||||
|
||||
def on_conversation_suspend(self, signum):
|
||||
# This is just an example of how to do something on conversation suspend.
|
||||
# You can skip specifying 'on_suspend' argument if there is no need
|
||||
sudo.log_info("conversation suspend: signal", self._signal_name(signum))
|
||||
|
||||
def on_conversation_resume(self, signum):
|
||||
# This is just an example of how to do something on conversation resume.
|
||||
# You can skip specifying 'on_resume' argument if there is no need
|
||||
sudo.log_info("conversation resume: signal was", self._signal_name(signum))
|
||||
|
||||
# helper functions:
|
||||
@classmethod
|
||||
def _signal_name(cls, signum):
|
||||
try:
|
||||
return "{} ({})".format(signal.Signals(signum).name, signum)
|
||||
except Exception:
|
||||
return "{}".format(signum)
|
58
plugins/python/example_debugging.py
Normal file
58
plugins/python/example_debugging.py
Normal file
@@ -0,0 +1,58 @@
|
||||
import sudo
|
||||
|
||||
class DebugDemoPlugin(sudo.Plugin):
|
||||
"""
|
||||
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:
|
||||
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:
|
||||
Debug python_plugin.so /var/log/sudo_python_debug plugin@trace,c_calls@trace
|
||||
^ ^-- the options for the logging
|
||||
^----- the output will be placed here
|
||||
|
||||
The options for the logging is in format of multiple "subsystem@level" separated by commas (",").
|
||||
The most interesting subsystems are:
|
||||
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.)
|
||||
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.
|
||||
|
||||
Other subsystems available:
|
||||
internal logs internal functions of the python language wrapper plugin
|
||||
sudo_cb logs when sudo calls into its plugin API
|
||||
load logs python plugin loading / unloading
|
||||
|
||||
Log levels
|
||||
crit sudo.DEBUG_CRIT --> only cricital messages
|
||||
err sudo.DEBUG_ERROR
|
||||
warn sudo.DEBUG_WARN
|
||||
notice sudo.DEBUG_NOTICE
|
||||
diag sudo.DEBUG_DIAG
|
||||
info sudo.DEBUG_INFO
|
||||
trace sudo.DEBUG_TRACE
|
||||
debug sudo.DEBUG_DEBUG --> very extreme verbose debugging
|
||||
|
||||
See the sudo.conf manual for more details ("man sudo.conf").
|
||||
|
||||
"""
|
||||
def __init__(self, plugin_options, **kwargs):
|
||||
# Specify: "py_calls@info" debug option to show the call to this constructor and the arguments passed in
|
||||
|
||||
# Specifying "plugin@error" debug option will show this 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)
|
||||
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.
|
||||
# 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] My demo purpose plugin shows this ERROR level debug message
|
||||
|
||||
# Specify: "c_calls@diag" debug option to show this call and its arguments
|
||||
# If you specify info debug level instead ("c_call@info"),
|
||||
# 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)
|
Reference in New Issue
Block a user