use std::path::Path;
pub enum RuntimeMode {
SmtpRelay,
SendmailPipe {
pipe_command: String,
},
}
pub fn apply_initial_restrictions(config_path: &Path) -> Result<(), String> {
platform::apply_initial_restrictions(config_path)
}
pub fn apply_runtime_restrictions(mode: RuntimeMode) -> Result<(), String> {
platform::apply_runtime_restrictions(mode)
}
#[cfg(target_os = "openbsd")]
mod platform {
use super::RuntimeMode;
use std::path::Path;
pub fn apply_initial_restrictions(config_path: &Path) -> Result<(), String> {
unveil::unveil(config_path, "r")
.map_err(|e| format!("unveil config path failed: {}", e))?;
unveil::unveil("", "")
.map_err(|e| format!("unveil lock failed: {}", e))?;
pledge::pledge("stdio rpath inet", None)
.map_err(|e| format!("initial pledge failed: {}", e))?;
Ok(())
}
pub fn apply_runtime_restrictions(mode: RuntimeMode) -> Result<(), String> {
match mode {
RuntimeMode::SmtpRelay => {
pledge::pledge("stdio inet", None)
.map_err(|e| format!("runtime pledge failed: {}", e))?;
}
RuntimeMode::SendmailPipe { ref pipe_command } => {
unveil::unveil(pipe_command, "x")
.map_err(|e| format!("unveil pipe command failed: {}", e))?;
unveil::unveil("", "")
.map_err(|e| format!("unveil lock failed: {}", e))?;
pledge::pledge("stdio exec proc", None)
.map_err(|e| format!("runtime pledge (pipe) failed: {}", e))?;
}
}
Ok(())
}
}
#[cfg(not(target_os = "openbsd"))]
mod platform {
use super::RuntimeMode;
use std::path::Path;
pub fn apply_initial_restrictions(_config_path: &Path) -> Result<(), String> {
tracing::warn!(
"OpenBSD pledge/unveil are not available on this platform; \
security restrictions are not applied"
);
Ok(())
}
pub fn apply_runtime_restrictions(_mode: RuntimeMode) -> Result<(), String> {
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn apply_restrictions_succeeds_on_non_openbsd() {
let result = apply_initial_restrictions(Path::new("/etc/http-smtp-rele.toml"));
assert!(result.is_ok());
}
#[test]
fn apply_runtime_restrictions_smtp_relay_succeeds_on_non_openbsd() {
let result = apply_runtime_restrictions(RuntimeMode::SmtpRelay);
assert!(result.is_ok());
}
#[test]
fn apply_runtime_restrictions_pipe_mode_succeeds_on_non_openbsd() {
let result = apply_runtime_restrictions(RuntimeMode::SendmailPipe {
pipe_command: "/usr/sbin/sendmail".into(),
});
assert!(result.is_ok());
}
}