Skip to content

Commit

Permalink
add SETENV handling to AST processing
Browse files Browse the repository at this point in the history
  • Loading branch information
squell committed Dec 17, 2024
1 parent 91ca14b commit 58fb830
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/sudo/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ impl<Policy: PolicyPlugin, Auth: AuthPlugin> Pipeline<Policy, Auth> {
must_authenticate,
prior_validity,
allowed_attempts,
..
}: AuthorizationAllowed,
) -> Result<(), Error> {
let scope = RecordScope::for_process(&Process::new());
Expand Down
28 changes: 21 additions & 7 deletions src/sudoers/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use crate::common::{
};

/// The Sudoers file allows negating items with the exclamation mark.
#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
#[cfg_attr(test, derive(Debug, Eq))]
#[derive(Clone, PartialEq)]
#[repr(u32)]
pub enum Qualified<T> {
Allow(T) = HARDENED_ENUM_VALUE_0,
Expand Down Expand Up @@ -80,18 +81,32 @@ pub enum Authenticate {
Nopasswd = HARDENED_ENUM_VALUE_2,
}

// A type that represents a hardened bool
type EnvironmentControl = Qualified<()>;

impl Default for EnvironmentControl {
fn default() -> Self {
Qualified::Forbid(())
}
}

/// Commands in /etc/sudoers can have attributes attached to them, such as NOPASSWD, NOEXEC, ...
#[derive(Default, Clone, PartialEq)]
#[cfg_attr(test, derive(Debug, Eq))]
pub struct Tag {
pub authenticate: Authenticate,
pub cwd: Option<ChDir>,
pub(super) authenticate: Authenticate,
pub(super) cwd: Option<ChDir>,
pub(super) env: EnvironmentControl,
}

impl Tag {
pub fn needs_passwd(&self) -> bool {
matches!(self.authenticate, Authenticate::None | Authenticate::Passwd)
}

pub fn allows_setenv(&self) -> bool {
self.env == Qualified::Allow(())
}
}

/// Commands with attached attributes.
Expand Down Expand Up @@ -365,10 +380,9 @@ impl Parse for MetaOrTag {
// 'FOLLOW' and 'NOFOLLOW' are only usable in a sudoedit context, which will result in
// a parse error elsewhere. 'EXEC' and 'NOINTERCEPT' are the default behaviour.
"FOLLOW" | "NOFOLLOW" | "EXEC" | "NOINTERCEPT" => switch(|_| {})?,
"SETENV" | "NOSETENV" => {
eprintln_ignore_io_error!("{} is WIP", keyword.as_str());
switch(|_| {})?
}

"SETENV" => switch(|tag| tag.env = Qualified::Allow(()))?,
"NOSETENV" => switch(|tag| tag.env = Qualified::Forbid(()))?,
"PASSWD" => switch(|tag| tag.authenticate = Authenticate::Passwd)?,
"NOPASSWD" => switch(|tag| tag.authenticate = Authenticate::Nopasswd)?,

Expand Down
5 changes: 5 additions & 0 deletions src/sudoers/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub struct AuthorizationAllowed {
pub must_authenticate: bool,
pub allowed_attempts: u16,
pub prior_validity: Duration,
pub trust_environment: bool,
}

#[must_use]
Expand All @@ -57,6 +58,7 @@ impl Policy for Judgement {
let valid_seconds = self.settings.int_value["timestamp_timeout"];
Authorization::Allowed(AuthorizationAllowed {
must_authenticate: tag.needs_passwd(),
trust_environment: tag.allows_setenv(),
allowed_attempts,
prior_validity: Duration::seconds(valid_seconds),
})
Expand Down Expand Up @@ -107,6 +109,7 @@ impl PreJudgementPolicy for Sudoers {
fn validate_authorization(&self) -> Authorization {
Authorization::Allowed(AuthorizationAllowed {
must_authenticate: true,
trust_environment: false,
allowed_attempts: self.settings.int_value["passwd_tries"].try_into().unwrap(),
prior_validity: Duration::seconds(self.settings.int_value["timestamp_timeout"]),
})
Expand Down Expand Up @@ -139,6 +142,7 @@ mod test {
judge.authorization(),
Authorization::Allowed(AuthorizationAllowed {
must_authenticate: true,
trust_environment: false,
allowed_attempts: 3,
prior_validity: Duration::minutes(15),
})
Expand All @@ -148,6 +152,7 @@ mod test {
judge.authorization(),
Authorization::Allowed(AuthorizationAllowed {
must_authenticate: false,
trust_environment: false,
allowed_attempts: 3,
prior_validity: Duration::minutes(15),
})
Expand Down

0 comments on commit 58fb830

Please sign in to comment.