From 6dbcede71c827c578a39aa888863f383a2b7cc49 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 12 Jul 2023 15:24:07 +0200 Subject: [PATCH 1/3] visudo: test --no-includes and --strict --- .../sudo-compliance-tests/src/visudo.rs | 2 + .../src/visudo/flag_no_includes.rs | 112 ++++++++++++++++++ .../src/visudo/flag_strict.rs | 56 +++++++++ 3 files changed, 170 insertions(+) create mode 100644 test-framework/sudo-compliance-tests/src/visudo/flag_no_includes.rs create mode 100644 test-framework/sudo-compliance-tests/src/visudo/flag_strict.rs diff --git a/test-framework/sudo-compliance-tests/src/visudo.rs b/test-framework/sudo-compliance-tests/src/visudo.rs index d0f6219d..fcb85406 100644 --- a/test-framework/sudo-compliance-tests/src/visudo.rs +++ b/test-framework/sudo-compliance-tests/src/visudo.rs @@ -7,9 +7,11 @@ use crate::{Result, SUDOERS_ALL_ALL_NOPASSWD}; mod flag_check; mod flag_file; mod flag_help; +mod flag_no_includes; mod flag_owner; mod flag_perms; mod flag_quiet; +mod flag_strict; mod flag_version; mod sudoers; mod what_now_prompt; diff --git a/test-framework/sudo-compliance-tests/src/visudo/flag_no_includes.rs b/test-framework/sudo-compliance-tests/src/visudo/flag_no_includes.rs new file mode 100644 index 00000000..0830759b --- /dev/null +++ b/test-framework/sudo-compliance-tests/src/visudo/flag_no_includes.rs @@ -0,0 +1,112 @@ +use sudo_test::{Command, Env, TextFile}; + +use crate::{ + visudo::{CHMOD_EXEC, DEFAULT_EDITOR, LOGS_PATH}, + Result, +}; + +#[test] +fn does_not_edit_at_include_files_that_dont_contain_syntax_errors() -> Result<()> { + let env = Env("# 1 +@include sudoers2") + .file("/etc/sudoers2", "# 2") + .file( + DEFAULT_EDITOR, + TextFile(format!( + "#!/bin/sh +cat $2 >> {LOGS_PATH}" + )) + .chmod(CHMOD_EXEC), + ) + .build()?; + + Command::new("visudo") + .arg("--no-includes") + .output(&env)? + .assert_success()?; + let logs = Command::new("cat").arg(LOGS_PATH).output(&env)?.stdout()?; + + let comments = logs + .lines() + .filter(|line| line.starts_with('#')) + .collect::>(); + + assert_eq!(["# 1"], &*comments); + + Ok(()) +} + +#[test] +fn does_edit_at_include_files_that_contain_syntax_errors() -> Result<()> { + let env = Env("# 1 +@include sudoers2") + .file( + "/etc/sudoers2", + "# 2 +this is fine", + ) + .file( + DEFAULT_EDITOR, + TextFile(format!( + "#!/bin/sh +cat $2 >> {LOGS_PATH}" + )) + .chmod(CHMOD_EXEC), + ) + .build()?; + + Command::new("visudo") + .arg("--no-includes") + .output(&env)? + .assert_success()?; + let logs = Command::new("cat").arg(LOGS_PATH).output(&env)?.stdout()?; + + let comments = logs + .lines() + .filter(|line| line.starts_with('#')) + .collect::>(); + + assert_eq!(["# 1"], &*comments); + + Ok(()) +} + +#[test] +fn does_not_edit_deep_at_include_files_that_contain_syntax_errors() -> Result<()> { + let env = Env("# 1 +@include sudoers2") + .file( + "/etc/sudoers2", + "# 2 +@include sudoers3", + ) + .file( + "/etc/sudoers3", + "# 3 +this is fine", + ) + .file( + DEFAULT_EDITOR, + TextFile(format!( + "#!/bin/sh +cat $2 >> {LOGS_PATH}" + )) + .chmod(CHMOD_EXEC), + ) + .build()?; + + Command::new("visudo") + .arg("--no-includes") + .output(&env)? + .assert_success()?; + let logs = Command::new("cat").arg(LOGS_PATH).output(&env)?.stdout()?; + + let comments = logs + .lines() + .filter(|line| line.starts_with('#')) + .collect::>(); + + assert_eq!(["# 1"], &*comments); + + Ok(()) +} diff --git a/test-framework/sudo-compliance-tests/src/visudo/flag_strict.rs b/test-framework/sudo-compliance-tests/src/visudo/flag_strict.rs new file mode 100644 index 00000000..15d98dc0 --- /dev/null +++ b/test-framework/sudo-compliance-tests/src/visudo/flag_strict.rs @@ -0,0 +1,56 @@ +use sudo_test::{Command, Env, TextFile}; + +use crate::{ + visudo::{CHMOD_EXEC, DEFAULT_EDITOR, EDITOR_TRUE}, + Result, +}; + +#[test] +fn undefined_alias() -> Result<()> { + let env = Env(["# User_Alias ADMINS = root", "ADMINS ALL=(ALL:ALL) ALL"]) + .file(DEFAULT_EDITOR, TextFile(EDITOR_TRUE).chmod(CHMOD_EXEC)) + .build()?; + + let output = Command::new("visudo").arg("--strict").output(&env)?; + + let diagnostic = r#"User_Alias "ADMINS" referenced but not defined"#; + let prompt = "What now?"; + + assert!(output.status().success()); + assert_contains!(output.stderr(), diagnostic); + // we only get this prompt in `--strict` mode + assert_contains!(output.stdout()?, prompt); + + let output = Command::new("visudo").output(&env)?; + + assert!(output.status().success()); + assert_contains!(output.stderr(), diagnostic); + assert_not_contains!(output.stdout()?, prompt); + + Ok(()) +} + +#[test] +fn alias_cycle() -> Result<()> { + let env = Env(["User_Alias FOO = FOO", "FOO ALL=(ALL:ALL) ALL"]) + .file(DEFAULT_EDITOR, TextFile(EDITOR_TRUE).chmod(CHMOD_EXEC)) + .build()?; + + let output = Command::new("visudo").arg("--strict").output(&env)?; + + let diagnostic = r#"cycle in User_Alias "FOO""#; + let prompt = "What now?"; + + assert!(output.status().success()); + assert_contains!(output.stderr(), diagnostic); + // we only get this prompt in `--strict` mode + assert_contains!(output.stdout()?, prompt); + + let output = Command::new("visudo").output(&env)?; + + assert!(output.status().success()); + assert_contains!(output.stderr(), diagnostic); + assert_not_contains!(output.stdout()?, prompt); + + Ok(()) +} From 9e3b8038ebd34bb91c2a936229b80f137761a712 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 12 Jul 2023 15:32:05 +0200 Subject: [PATCH 2/3] ignore failing tests --- .../sudo-compliance-tests/src/visudo/flag_strict.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test-framework/sudo-compliance-tests/src/visudo/flag_strict.rs b/test-framework/sudo-compliance-tests/src/visudo/flag_strict.rs index 15d98dc0..7b2d6a0d 100644 --- a/test-framework/sudo-compliance-tests/src/visudo/flag_strict.rs +++ b/test-framework/sudo-compliance-tests/src/visudo/flag_strict.rs @@ -6,6 +6,7 @@ use crate::{ }; #[test] +#[ignore = "gh657"] fn undefined_alias() -> Result<()> { let env = Env(["# User_Alias ADMINS = root", "ADMINS ALL=(ALL:ALL) ALL"]) .file(DEFAULT_EDITOR, TextFile(EDITOR_TRUE).chmod(CHMOD_EXEC)) @@ -38,7 +39,11 @@ fn alias_cycle() -> Result<()> { let output = Command::new("visudo").arg("--strict").output(&env)?; - let diagnostic = r#"cycle in User_Alias "FOO""#; + let diagnostic = if sudo_test::is_original_sudo() { + r#"cycle in User_Alias "FOO""# + } else { + "syntax error: recursive alias: 'FOO'" + }; let prompt = "What now?"; assert!(output.status().success()); From b2194cdc2b5c90b09ad04d4216bfe63494de39c3 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 12 Jul 2023 16:04:44 +0200 Subject: [PATCH 3/3] tweak one --strict test because visudo-rs is stricter --- .../sudo-compliance-tests/src/visudo/flag_strict.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test-framework/sudo-compliance-tests/src/visudo/flag_strict.rs b/test-framework/sudo-compliance-tests/src/visudo/flag_strict.rs index 7b2d6a0d..94e6395b 100644 --- a/test-framework/sudo-compliance-tests/src/visudo/flag_strict.rs +++ b/test-framework/sudo-compliance-tests/src/visudo/flag_strict.rs @@ -55,7 +55,12 @@ fn alias_cycle() -> Result<()> { assert!(output.status().success()); assert_contains!(output.stderr(), diagnostic); - assert_not_contains!(output.stdout()?, prompt); + if sudo_test::is_original_sudo() { + assert_not_contains!(output.stdout()?, prompt); + } else { + // visudo-rs is always strict + assert_contains!(output.stdout()?, prompt); + } Ok(()) }