plugins/python/regress/check_python_examples: add audit_plugin tests

This commit is contained in:
Robert Manner
2020-02-06 15:15:43 +01:00
committed by Todd C. Miller
parent 52d067b01f
commit 1a1cb54975
7 changed files with 341 additions and 1 deletions

View File

@@ -27,9 +27,10 @@
static const char *python_plugin_so_path = NULL;
static void *python_plugin_handle = NULL;
static struct io_plugin *python_io;
static struct io_plugin *python_io = NULL;
static struct policy_plugin *python_policy = NULL;
static struct sudoers_group_plugin *group_plugin = NULL;
static struct audit_plugin *python_audit = NULL;
static struct passwd example_pwd;
@@ -76,6 +77,19 @@ create_debugging_plugin_options(void)
);
}
void
create_audit_plugin_options(const char *extra_argument)
{
str_array_free(&data.plugin_options);
data.plugin_options = create_str_array(
4,
"ModulePath=" SRC_DIR "/example_audit_plugin.py",
"ClassName=SudoAuditPlugin",
extra_argument,
NULL
);
}
void
create_conversation_plugin_options(void)
{
@@ -995,6 +1009,281 @@ check_python_plugins_do_not_affect_each_other(void)
return true;
}
int
check_example_audit_plugin_receives_accept(void)
{
create_audit_plugin_options("");
const char *errstr = NULL;
str_array_free(&data.plugin_argv);
data.plugin_argv = create_str_array(6, "sudo", "-u", "user", "id", "--help", NULL);
str_array_free(&data.user_env);
data.user_env = create_str_array(3, "KEY1=VALUE1", "KEY2=VALUE2", NULL);
str_array_free(&data.user_info);
data.user_info = create_str_array(3, "user=testuser1", "uid=123", NULL);
VERIFY_INT(python_audit->open(SUDO_API_VERSION, fake_conversation, fake_printf,
data.settings, data.user_info, 3, data.plugin_argv,
data.user_env, data.plugin_options, &errstr), SUDO_RC_OK);
VERIFY_PTR(errstr, NULL);
str_array_free(&data.command_info);
data.command_info = create_str_array(2, "command=/sbin/id", NULL);
str_array_free(&data.plugin_argv);
data.plugin_argv = create_str_array(3, "id", "--help", NULL);
VERIFY_INT(python_audit->accept("accepter plugin name", SUDO_POLICY_PLUGIN,
data.command_info, data.plugin_argv,
data.user_env, &errstr), SUDO_RC_OK);
VERIFY_PTR(errstr, NULL);
python_audit->close(SUDO_PLUGIN_WAIT_STATUS, W_EXITCODE(2, 0)); // process exited with 2
VERIFY_STDOUT(expected_path("check_example_audit_plugin_receives_accept.stdout"));
VERIFY_STR(data.stderr_str, "");
return true;
}
int
check_example_audit_plugin_receives_reject(void)
{
create_audit_plugin_options("");
const char *errstr = NULL;
str_array_free(&data.plugin_argv);
data.plugin_argv = create_str_array(3, "sudo", "passwd", NULL);
str_array_free(&data.user_info);
data.user_info = create_str_array(3, "user=root", "uid=0", NULL);
VERIFY_INT(python_audit->open(SUDO_API_VERSION, fake_conversation, fake_printf,
data.settings, data.user_info, 1, data.plugin_argv,
data.user_env, data.plugin_options, &errstr), SUDO_RC_OK);
VERIFY_PTR(errstr, NULL);
VERIFY_INT(python_audit->reject("rejecter plugin name", SUDO_IO_PLUGIN,
"Rejected just because!", data.command_info,
&errstr), SUDO_RC_OK);
VERIFY_PTR(errstr, NULL);
python_audit->close(SUDO_PLUGIN_NO_STATUS, 0); // program was not run
VERIFY_STDOUT(expected_path("check_example_audit_plugin_receives_reject.stdout"));
VERIFY_STR(data.stderr_str, "");
return true;
}
int
check_example_audit_plugin_receives_error(void)
{
create_audit_plugin_options("");
const char *errstr = NULL;
str_array_free(&data.plugin_argv);
data.plugin_argv = create_str_array(5, "sudo", "-u", "user", "id", NULL);
VERIFY_INT(python_audit->open(SUDO_API_VERSION, fake_conversation, fake_printf,
data.settings, data.user_info, 3, data.plugin_argv,
data.user_env, data.plugin_options, &errstr), SUDO_RC_OK);
VERIFY_PTR(errstr, NULL);
str_array_free(&data.command_info);
data.command_info = create_str_array(2, "command=/sbin/id", NULL);
VERIFY_INT(python_audit->error("errorer plugin name", SUDO_AUDIT_PLUGIN,
"Some error has happened", data.command_info,
&errstr), SUDO_RC_OK);
VERIFY_PTR(errstr, NULL);
python_audit->close(SUDO_PLUGIN_SUDO_ERROR, 222);
VERIFY_STDOUT(expected_path("check_example_audit_plugin_receives_error.stdout"));
VERIFY_STR(data.stderr_str, "");
return true;
}
typedef struct audit_plugin * (audit_clone_func)(void);
int
check_example_audit_plugin_workflow_multiple(void)
{
// verify multiple python audit plugins are available
audit_clone_func *python_audit_clone = (audit_clone_func *)sudo_dso_findsym(
python_plugin_handle, "python_audit_clone");
VERIFY_PTR_NE(python_audit_clone, NULL);
struct audit_plugin *python_audit2 = NULL;
for (int i = 0; i < 7; ++i) {
python_audit2 = (*python_audit_clone)();
VERIFY_PTR_NE(python_audit2, NULL);
VERIFY_PTR_NE(python_audit2, python_audit);
}
const char *errstr = NULL;
str_array_free(&data.plugin_argv);
data.plugin_argv = create_str_array(6, "sudo", "-u", "user", "id", "--help", NULL);
str_array_free(&data.user_env);
data.user_env = create_str_array(3, "KEY1=VALUE1", "KEY2=VALUE2", NULL);
str_array_free(&data.user_info);
data.user_info = create_str_array(3, "user=default", "uid=1000", NULL);
create_audit_plugin_options("Id=1");
VERIFY_INT(python_audit->open(SUDO_API_VERSION, fake_conversation, fake_printf,
data.settings, data.user_info, 3, data.plugin_argv,
data.user_env, data.plugin_options, &errstr), SUDO_RC_OK);
VERIFY_PTR(errstr, NULL);
// For verifying the error message of no more plugin. It should be displayed only once.
VERIFY_PTR((*python_audit_clone)(), NULL);
VERIFY_PTR((*python_audit_clone)(), NULL);
create_audit_plugin_options("Id=2");
VERIFY_INT(python_audit2->open(SUDO_API_VERSION, fake_conversation, fake_printf,
data.settings, data.user_info, 3, data.plugin_argv,
data.user_env, data.plugin_options, &errstr), SUDO_RC_OK);
VERIFY_PTR(errstr, NULL);
str_array_free(&data.command_info);
data.command_info = create_str_array(2, "command=/sbin/id", NULL);
str_array_free(&data.plugin_argv);
data.plugin_argv = create_str_array(3, "id", "--help", NULL);
VERIFY_INT(python_audit->accept("accepter plugin name", SUDO_POLICY_PLUGIN,
data.command_info, data.plugin_argv,
data.user_env, &errstr), SUDO_RC_OK);
VERIFY_PTR(errstr, NULL);
VERIFY_INT(python_audit2->accept("accepter plugin name", SUDO_POLICY_PLUGIN,
data.command_info, data.plugin_argv,
data.user_env, &errstr), SUDO_RC_OK);
VERIFY_PTR(errstr, NULL);
python_audit->close(SUDO_PLUGIN_WAIT_STATUS, W_EXITCODE(0, 11)); // process got signal 11
python_audit2->close(SUDO_PLUGIN_WAIT_STATUS, W_EXITCODE(0, 11));
VERIFY_STDOUT(expected_path("check_example_audit_plugin_workflow_multiple.stdout"));
VERIFY_STDERR(expected_path("check_example_audit_plugin_workflow_multiple.stderr"));
return true;
}
int
check_example_audit_plugin_version_display(void)
{
create_audit_plugin_options("");
const char *errstr = NULL;
str_array_free(&data.user_info);
data.user_info = create_str_array(3, "user=root", "uid=0", NULL);
str_array_free(&data.plugin_argv);
data.plugin_argv = create_str_array(3, "sudo", "-V", NULL);
VERIFY_INT(python_audit->open(SUDO_API_VERSION, fake_conversation, fake_printf,
data.settings, data.user_info, 2, data.plugin_argv,
data.user_env, data.plugin_options, &errstr), SUDO_RC_OK);
VERIFY_PTR(errstr, NULL);
VERIFY_INT(python_audit->show_version(false), SUDO_RC_OK);
VERIFY_INT(python_audit->show_version(true), SUDO_RC_OK);
python_audit->close(SUDO_PLUGIN_SUDO_ERROR, 222);
VERIFY_STDOUT(expected_path("check_example_audit_plugin_version_display.stdout"));
VERIFY_STR(data.stderr_str, "");
return true;
}
int
check_audit_plugin_callbacks_are_optional(void)
{
const char *errstr = NULL;
create_debugging_plugin_options();
VERIFY_INT(python_audit->open(SUDO_API_VERSION, fake_conversation, fake_printf,
data.settings, data.user_info, 2, data.plugin_argv,
data.user_env, data.plugin_options, &errstr),
SUDO_RC_OK);
VERIFY_PTR(python_audit->accept, NULL);
VERIFY_PTR(python_audit->reject, NULL);
VERIFY_PTR(python_audit->error, NULL);
VERIFY_PTR(python_audit->show_version, NULL);
python_audit->close(SUDO_PLUGIN_NO_STATUS, 0);
return true;
}
int
check_audit_plugin_reports_error(void)
{
const char *errstr = NULL;
str_array_free(&data.plugin_options);
data.plugin_options = create_str_array(
3,
"ModulePath=" SRC_DIR "/regress/plugin_errorstr.py",
"ClassName=ConstructErrorPlugin",
NULL
);
VERIFY_INT(python_audit->open(SUDO_API_VERSION, fake_conversation, fake_printf,
data.settings, data.user_info, 0, data.plugin_argv,
data.user_env, data.plugin_options, &errstr), SUDO_RC_ERROR);
VERIFY_STR(errstr, "Something wrong in plugin constructor");
errstr = NULL;
python_audit->close(SUDO_PLUGIN_NO_STATUS, 0);
str_array_free(&data.plugin_options);
data.plugin_options = create_str_array(
3,
"ModulePath=" SRC_DIR "/regress/plugin_errorstr.py",
"ClassName=ErrorMsgPlugin",
NULL
);
VERIFY_INT(python_audit->open(SUDO_API_VERSION, fake_conversation, fake_printf,
data.settings, data.user_info, 0, data.plugin_argv,
data.user_env, data.plugin_options, &errstr), SUDO_RC_ERROR);
VERIFY_STR(errstr, "Something wrong in open");
VERIFY_INT(python_audit->accept("plugin name", SUDO_POLICY_PLUGIN,
data.command_info, data.plugin_argv,
data.user_env, &errstr), SUDO_RC_ERROR);
VERIFY_STR(errstr, "Something wrong in accept");
VERIFY_INT(python_audit->reject("plugin name", SUDO_POLICY_PLUGIN,
"audit message", data.command_info,
&errstr), SUDO_RC_ERROR);
VERIFY_STR(errstr, "Something wrong in reject");
VERIFY_INT(python_audit->error("plugin name", SUDO_POLICY_PLUGIN,
"audit message", data.command_info,
&errstr), SUDO_RC_ERROR);
VERIFY_STR(errstr, "Something wrong in error");
python_audit->close(SUDO_PLUGIN_NO_STATUS, 0);
VERIFY_STR(data.stderr_str, "");
VERIFY_STR(data.stdout_str, "");
return true;
}
static int
_load_symbols(void)
{
@@ -1009,6 +1298,10 @@ _load_symbols(void)
python_policy = sudo_dso_findsym(python_plugin_handle, "python_policy");
VERIFY_PTR_NE(python_policy, NULL);
python_audit = sudo_dso_findsym(python_plugin_handle, "python_audit");
VERIFY_PTR_NE(python_audit, NULL);
return true;
}
@@ -1018,6 +1311,7 @@ _unload_symbols(void)
python_io = NULL;
group_plugin = NULL;
python_policy = NULL;
python_audit = NULL;
VERIFY_INT(sudo_dso_unload(python_plugin_handle), 0);
return true;
}
@@ -1064,6 +1358,14 @@ main(int argc, char *argv[])
RUN_TEST(check_policy_plugin_callbacks_are_optional());
RUN_TEST(check_policy_plugin_reports_error());
RUN_TEST(check_example_audit_plugin_receives_accept());
RUN_TEST(check_example_audit_plugin_receives_reject());
RUN_TEST(check_example_audit_plugin_receives_error());
RUN_TEST(check_example_audit_plugin_workflow_multiple());
RUN_TEST(check_example_audit_plugin_version_display());
RUN_TEST(check_audit_plugin_callbacks_are_optional());
RUN_TEST(check_audit_plugin_reports_error());
RUN_TEST(check_python_plugins_do_not_affect_each_other());
RUN_TEST(check_example_debugging("plugin@err"));

View File

@@ -0,0 +1,7 @@
(AUDIT) -- Started by user testuser1 (123) --
(AUDIT) Requested command: id --help
(AUDIT) Accepted command: /sbin/id --help
(AUDIT) By the plugin: accepter plugin name (type=POLICY)
(AUDIT) Environment: KEY1=VALUE1 KEY2=VALUE2
(AUDIT) Command returned with exit code 2
(AUDIT) -- Finished --

View File

@@ -0,0 +1,5 @@
(AUDIT) -- Started by user ??? (???) --
(AUDIT) Requested command: id
(AUDIT) Plugin errorer plugin name (type=AUDIT) got an error: Some error has happened
(AUDIT) Sudo has run into an error: 222
(AUDIT) -- Finished --

View File

@@ -0,0 +1,5 @@
(AUDIT) -- Started by user root (0) --
(AUDIT) Requested command: passwd
(AUDIT) Rejected by plugin rejecter plugin name (type=IO): Rejected just because!
(AUDIT) The command was not executed
(AUDIT) -- Finished --

View File

@@ -0,0 +1,6 @@
(AUDIT) -- Started by user root (0) --
Python Example Audit Plugin
Python audit plugin API version 1.0
Python Example Audit Plugin (version=1.0)
(AUDIT) Sudo has run into an error: 222
(AUDIT) -- Finished --

View File

@@ -0,0 +1 @@
sudo: loading more than 8 sudo python audit plugins is not supported

View File

@@ -0,0 +1,14 @@
(AUDIT1) -- Started by user default (1000) --
(AUDIT1) Requested command: id --help
(AUDIT2) -- Started by user default (1000) --
(AUDIT2) Requested command: id --help
(AUDIT1) Accepted command: /sbin/id --help
(AUDIT1) By the plugin: accepter plugin name (type=POLICY)
(AUDIT1) Environment: KEY1=VALUE1 KEY2=VALUE2
(AUDIT2) Accepted command: /sbin/id --help
(AUDIT2) By the plugin: accepter plugin name (type=POLICY)
(AUDIT2) Environment: KEY1=VALUE1 KEY2=VALUE2
(AUDIT1) Command exited due to signal 11
(AUDIT1) -- Finished --
(AUDIT2) Command exited due to signal 11
(AUDIT2) -- Finished --