diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2024-09-04 14:51:24 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-04 14:51:24 +0200 |
commit | 74fc66da110ec20d12751e7a0922cea300314399 (patch) | |
tree | b0b057b7539b506b8db39287cd799e7c9cbd526f /runtime/permissions/lib.rs | |
parent | 334c842392e2587b8ca1d7cc7cc7d9231fc15286 (diff) |
fix: lock down allow-run permissions more (#25370)
`--allow-run` even with an allow list has essentially been
`--allow-all`... this locks it down more.
1. Resolves allow list for `--allow-run=` on startup to an absolute
path, then uses these paths when evaluating if a command can execute.
Also, adds these paths to `--deny-write`
1. Resolves the environment (cwd and env vars) before evaluating
permissions and before executing a command. Then uses this environment
to evaluate the permissions and then evaluate the command.
Diffstat (limited to 'runtime/permissions/lib.rs')
-rw-r--r-- | runtime/permissions/lib.rs | 431 |
1 files changed, 231 insertions, 200 deletions
diff --git a/runtime/permissions/lib.rs b/runtime/permissions/lib.rs index 7227bebf8..2eacd8bcc 100644 --- a/runtime/permissions/lib.rs +++ b/runtime/permissions/lib.rs @@ -32,7 +32,6 @@ use std::path::PathBuf; use std::str::FromStr; use std::string::ToString; use std::sync::Arc; -use which::which; pub mod prompter; use prompter::permission_prompt; @@ -317,7 +316,7 @@ pub trait Descriptor: Eq + Clone + Hash { /// Parse this descriptor from a list of Self::Arg, which may have been converted from /// command-line strings. - fn parse(list: &Option<Vec<Self::Arg>>) -> Result<HashSet<Self>, AnyError>; + fn parse(list: Option<&[Self::Arg]>) -> Result<HashSet<Self>, AnyError>; /// Generic check function to check this descriptor against a `UnaryPermission`. fn check_in_permission( @@ -333,9 +332,6 @@ pub trait Descriptor: Eq + Clone + Hash { fn stronger_than(&self, other: &Self) -> bool { self == other } - fn aliases(&self) -> Vec<Self> { - vec![] - } } #[derive(Clone, Debug, Eq, PartialEq)] @@ -423,43 +419,33 @@ impl<T: Descriptor + Hash> UnaryPermission<T> { desc: Option<&T>, allow_partial: AllowPartial, ) -> PermissionState { - let aliases = desc.map_or(vec![], T::aliases); - for desc in [desc] - .into_iter() - .chain(aliases.iter().map(Some).collect::<Vec<_>>()) - { - let state = if self.is_flag_denied(desc) || self.is_prompt_denied(desc) { - PermissionState::Denied - } else if self.is_granted(desc) { - match allow_partial { - AllowPartial::TreatAsGranted => PermissionState::Granted, - AllowPartial::TreatAsDenied => { - if self.is_partial_flag_denied(desc) { - PermissionState::Denied - } else { - PermissionState::Granted - } + if self.is_flag_denied(desc) || self.is_prompt_denied(desc) { + PermissionState::Denied + } else if self.is_granted(desc) { + match allow_partial { + AllowPartial::TreatAsGranted => PermissionState::Granted, + AllowPartial::TreatAsDenied => { + if self.is_partial_flag_denied(desc) { + PermissionState::Denied + } else { + PermissionState::Granted } - AllowPartial::TreatAsPartialGranted => { - if self.is_partial_flag_denied(desc) { - PermissionState::GrantedPartial - } else { - PermissionState::Granted - } + } + AllowPartial::TreatAsPartialGranted => { + if self.is_partial_flag_denied(desc) { + PermissionState::GrantedPartial + } else { + PermissionState::Granted } } - } else if matches!(allow_partial, AllowPartial::TreatAsDenied) - && self.is_partial_flag_denied(desc) - { - PermissionState::Denied - } else { - PermissionState::Prompt - }; - if state != PermissionState::Prompt { - return state; } + } else if matches!(allow_partial, AllowPartial::TreatAsDenied) + && self.is_partial_flag_denied(desc) + { + PermissionState::Denied + } else { + PermissionState::Prompt } - PermissionState::Prompt } fn request_desc( @@ -512,9 +498,6 @@ impl<T: Descriptor + Hash> UnaryPermission<T> { match desc { Some(desc) => { self.granted_list.retain(|v| !v.stronger_than(desc)); - for alias in desc.aliases() { - self.granted_list.retain(|v| !v.stronger_than(&alias)); - } } None => { self.granted_global = false; @@ -582,11 +565,7 @@ impl<T: Descriptor + Hash> UnaryPermission<T> { ) { match desc { Some(desc) => { - let aliases = desc.aliases(); list.insert(desc); - for alias in aliases { - list.insert(alias); - } } None => *list_global = true, } @@ -612,7 +591,7 @@ impl<T: Descriptor + Hash> UnaryPermission<T> { ChildUnaryPermissionArg::GrantedList(granted_list) => { let granted: Vec<T::Arg> = granted_list.into_iter().map(From::from).collect(); - perms.granted_list = T::parse(&Some(granted))?; + perms.granted_list = T::parse(Some(&granted))?; if !perms .granted_list .iter() @@ -649,7 +628,7 @@ impl Descriptor for ReadDescriptor { perm.check_desc(Some(self), true, api_name, || None) } - fn parse(args: &Option<Vec<Self::Arg>>) -> Result<HashSet<Self>, AnyError> { + fn parse(args: Option<&[Self::Arg]>) -> Result<HashSet<Self>, AnyError> { parse_path_list(args, ReadDescriptor) } @@ -681,7 +660,7 @@ impl Descriptor for WriteDescriptor { perm.check_desc(Some(self), true, api_name, || None) } - fn parse(args: &Option<Vec<Self::Arg>>) -> Result<HashSet<Self>, AnyError> { + fn parse(args: Option<&[Self::Arg]>) -> Result<HashSet<Self>, AnyError> { parse_path_list(args, WriteDescriptor) } @@ -754,7 +733,7 @@ impl Descriptor for NetDescriptor { perm.check_desc(Some(self), false, api_name, || None) } - fn parse(args: &Option<Vec<Self::Arg>>) -> Result<HashSet<Self>, AnyError> { + fn parse(args: Option<&[Self::Arg]>) -> Result<HashSet<Self>, AnyError> { parse_net_list(args) } @@ -864,7 +843,7 @@ impl Descriptor for EnvDescriptor { perm.check_desc(Some(self), false, api_name, || None) } - fn parse(list: &Option<Vec<Self::Arg>>) -> Result<HashSet<Self>, AnyError> { + fn parse(list: Option<&[Self::Arg]>) -> Result<HashSet<Self>, AnyError> { parse_env_list(list) } @@ -883,6 +862,11 @@ impl AsRef<str> for EnvDescriptor { } } +pub enum RunDescriptorArg { + Name(String), + Path(PathBuf), +} + #[derive(Clone, Eq, PartialEq, Hash, Debug)] pub enum RunDescriptor { /// Warning: You may want to construct with `RunDescriptor::from()` for case @@ -893,8 +877,26 @@ pub enum RunDescriptor { Path(PathBuf), } +impl From<String> for RunDescriptorArg { + fn from(s: String) -> Self { + #[cfg(windows)] + let s = s.to_lowercase(); + let is_path = s.contains('/'); + #[cfg(windows)] + let is_path = is_path || s.contains('\\') || Path::new(&s).is_absolute(); + if is_path { + Self::Path(resolve_from_cwd(Path::new(&s)).unwrap()) + } else { + match which::which(&s) { + Ok(path) => Self::Path(path), + Err(_) => Self::Name(s), + } + } + } +} + impl Descriptor for RunDescriptor { - type Arg = String; + type Arg = RunDescriptorArg; fn check_in_permission( &self, @@ -905,7 +907,7 @@ impl Descriptor for RunDescriptor { perm.check_desc(Some(self), false, api_name, || None) } - fn parse(args: &Option<Vec<Self::Arg>>) -> Result<HashSet<Self>, AnyError> { + fn parse(args: Option<&[Self::Arg]>) -> Result<HashSet<Self>, AnyError> { parse_run_list(args) } @@ -916,16 +918,6 @@ impl Descriptor for RunDescriptor { fn name(&self) -> Cow<str> { Cow::from(self.to_string()) } - - fn aliases(&self) -> Vec<Self> { - match self { - RunDescriptor::Name(name) => match which(name) { - Ok(path) => vec![RunDescriptor::Path(path)], - Err(_) => vec![], - }, - RunDescriptor::Path(_) => vec![], - } - } } impl From<String> for RunDescriptor { @@ -938,7 +930,10 @@ impl From<String> for RunDescriptor { if is_path { Self::Path(resolve_from_cwd(Path::new(&s)).unwrap()) } else { - Self::Name(s) + match which::which(&s) { + Ok(path) => Self::Path(path), + Err(_) => Self::Name(s), + } } } } @@ -947,11 +942,7 @@ impl From<PathBuf> for RunDescriptor { fn from(p: PathBuf) -> Self { #[cfg(windows)] let p = PathBuf::from(p.to_string_lossy().to_string().to_lowercase()); - if p.is_absolute() { - Self::Path(p) - } else { - Self::Path(resolve_from_cwd(&p).unwrap()) - } + Self::Path(resolve_from_cwd(&p).unwrap()) } } @@ -988,7 +979,7 @@ impl Descriptor for SysDescriptor { perm.check_desc(Some(self), false, api_name, || None) } - fn parse(list: &Option<Vec<Self::Arg>>) -> Result<HashSet<Self>, AnyError> { + fn parse(list: Option<&[Self::Arg]>) -> Result<HashSet<Self>, AnyError> { parse_sys_list(list) } @@ -1025,7 +1016,7 @@ impl Descriptor for FfiDescriptor { perm.check_desc(Some(self), true, api_name, || None) } - fn parse(list: &Option<Vec<Self::Arg>>) -> Result<HashSet<Self>, AnyError> { + fn parse(list: Option<&[Self::Arg]>) -> Result<HashSet<Self>, AnyError> { parse_path_list(list, FfiDescriptor) } @@ -1330,15 +1321,16 @@ impl UnaryPermission<RunDescriptor> { pub fn check( &mut self, - cmd: &str, + cmd: &Path, api_name: Option<&str>, ) -> Result<(), AnyError> { + debug_assert!(cmd.is_absolute()); skip_check_if_is_permission_fully_granted!(self); self.check_desc( - Some(&RunDescriptor::from(cmd.to_string())), + Some(&RunDescriptor::Path(cmd.to_path_buf())), false, api_name, - || Some(format!("\"{}\"", cmd)), + || Some(format!("\"{}\"", cmd.display())), ) } @@ -1346,6 +1338,21 @@ impl UnaryPermission<RunDescriptor> { skip_check_if_is_permission_fully_granted!(self); self.check_desc(None, false, api_name, || None) } + + /// Queries without prompting + pub fn query_all(&mut self, api_name: Option<&str>) -> bool { + if self.is_allow_all() { + return true; + } + let (result, _prompted, _is_allow_all) = + self.query_desc(None, AllowPartial::TreatAsDenied).check2( + RunDescriptor::flag_name(), + api_name, + || None, + /* prompt */ false, + ); + result.is_ok() + } } impl UnaryPermission<FfiDescriptor> { @@ -1429,7 +1436,7 @@ pub struct PermissionsOptions { pub deny_ffi: Option<Vec<PathBuf>>, pub allow_read: Option<Vec<PathBuf>>, pub deny_read: Option<Vec<PathBuf>>, - pub allow_run: Option<Vec<String>>, + pub allow_run: Option<Vec<PathBuf>>, pub deny_run: Option<Vec<String>>, pub allow_sys: Option<Vec<String>>, pub deny_sys: Option<Vec<String>>, @@ -1440,8 +1447,8 @@ pub struct PermissionsOptions { impl Permissions { pub fn new_unary<T>( - allow_list: &Option<Vec<T::Arg>>, - deny_list: &Option<Vec<T::Arg>>, + allow_list: Option<&[T::Arg]>, + deny_list: Option<&[T::Arg]>, prompt: bool, ) -> Result<UnaryPermission<T>, AnyError> where @@ -1470,38 +1477,54 @@ impl Permissions { pub fn from_options(opts: &PermissionsOptions) -> Result<Self, AnyError> { Ok(Self { read: Permissions::new_unary( - &opts.allow_read, - &opts.deny_read, + opts.allow_read.as_deref(), + opts.deny_read.as_deref(), opts.prompt, )?, write: Permissions::new_unary( - &opts.allow_write, - &opts.deny_write, + opts.allow_write.as_deref(), + opts.deny_write.as_deref(), opts.prompt, )?, net: Permissions::new_unary( - &opts.allow_net, - &opts.deny_net, + opts.allow_net.as_deref(), + opts.deny_net.as_deref(), opts.prompt, )?, env: Permissions::new_unary( - &opts.allow_env, - &opts.deny_env, + opts.allow_env.as_deref(), + opts.deny_env.as_deref(), opts.prompt, )?, sys: Permissions::new_unary( - &opts.allow_sys, - &opts.deny_sys, + opts.allow_sys.as_deref(), + opts.deny_sys.as_deref(), opts.prompt, )?, run: Permissions::new_unary( - &opts.allow_run, - &opts.deny_run, + opts + .allow_run + .as_ref() + .map(|d| { + d.iter() + .map(|s| RunDescriptorArg::Path(s.clone())) + .collect::<Vec<_>>() + }) + .as_deref(), + opts + .deny_run + .as_ref() + .map(|d| { + d.iter() + .map(|s| RunDescriptorArg::from(s.clone())) + .collect::<Vec<_>>() + }) + .as_deref(), opts.prompt, )?, ffi: Permissions::new_unary( - &opts.allow_ffi, - &opts.deny_ffi, + opts.allow_ffi.as_deref(), + opts.deny_ffi.as_deref(), opts.prompt, )?, all: Permissions::new_all(opts.allow_all), @@ -1534,13 +1557,13 @@ impl Permissions { fn none(prompt: bool) -> Self { Self { - read: Permissions::new_unary(&None, &None, prompt).unwrap(), - write: Permissions::new_unary(&None, &None, prompt).unwrap(), - net: Permissions::new_unary(&None, &None, prompt).unwrap(), - env: Permissions::new_unary(&None, &None, prompt).unwrap(), - sys: Permissions::new_unary(&None, &None, prompt).unwrap(), - run: Permissions::new_unary(&None, &None, prompt).unwrap(), - ffi: Permissions::new_unary(&None, &None, prompt).unwrap(), + read: Permissions::new_unary(None, None, prompt).unwrap(), + write: Permissions::new_unary(None, None, prompt).unwrap(), + net: Permissions::new_unary(None, None, prompt).unwrap(), + env: Permissions::new_unary(None, None, prompt).unwrap(), + sys: Permissions::new_unary(None, None, prompt).unwrap(), + run: Permissions::new_unary(None, None, prompt).unwrap(), + ffi: Permissions::new_unary(None, None, prompt).unwrap(), all: Permissions::new_all(false), } } @@ -1669,7 +1692,7 @@ impl PermissionsContainer { #[inline(always)] pub fn check_run( &mut self, - cmd: &str, + cmd: &Path, api_name: &str, ) -> Result<(), AnyError> { self.0.lock().run.check(cmd, Some(api_name)) @@ -1681,6 +1704,11 @@ impl PermissionsContainer { } #[inline(always)] + pub fn query_run_all(&mut self, api_name: &str) -> bool { + self.0.lock().run.query_all(Some(api_name)) + } + + #[inline(always)] pub fn check_sys(&self, kind: &str, api_name: &str) -> Result<(), AnyError> { self.0.lock().sys.check(kind, Some(api_name)) } @@ -1871,12 +1899,12 @@ const fn unit_permission_from_flag_bools( } } -fn global_from_option<T>(flag: &Option<Vec<T>>) -> bool { +fn global_from_option<T>(flag: Option<&[T]>) -> bool { matches!(flag, Some(v) if v.is_empty()) } fn parse_net_list( - list: &Option<Vec<String>>, + list: Option<&[String]>, ) -> Result<HashSet<NetDescriptor>, AnyError> { if let Some(v) = list { v.iter() @@ -1888,7 +1916,7 @@ fn parse_net_list( } fn parse_env_list( - list: &Option<Vec<String>>, + list: Option<&[String]>, ) -> Result<HashSet<EnvDescriptor>, AnyError> { if let Some(v) = list { v.iter() @@ -1906,7 +1934,7 @@ fn parse_env_list( } fn parse_path_list<T: Descriptor + Hash>( - list: &Option<Vec<PathBuf>>, + list: Option<&[PathBuf]>, f: fn(PathBuf) -> T, ) -> Result<HashSet<T>, AnyError> { if let Some(v) = list { @@ -1925,7 +1953,7 @@ fn parse_path_list<T: Descriptor + Hash>( } fn parse_sys_list( - list: &Option<Vec<String>>, + list: Option<&[String]>, ) -> Result<HashSet<SysDescriptor>, AnyError> { if let Some(v) = list { v.iter() @@ -1943,22 +1971,19 @@ fn parse_sys_list( } fn parse_run_list( - list: &Option<Vec<String>>, + list: Option<&[RunDescriptorArg]>, ) -> Result<HashSet<RunDescriptor>, AnyError> { - let mut result = HashSet::new(); - if let Some(v) = list { - for s in v { - if s.is_empty() { - return Err(AnyError::msg("Empty path is not allowed")); - } else { - let desc = RunDescriptor::from(s.to_string()); - let aliases = desc.aliases(); - result.insert(desc); - result.extend(aliases); - } - } - } - Ok(result) + let Some(v) = list else { + return Ok(HashSet::new()); + }; + Ok( + v.iter() + .map(|arg| match arg { + RunDescriptorArg::Name(s) => RunDescriptor::Name(s.clone()), + RunDescriptorArg::Path(l) => RunDescriptor::Path(l.clone()), + }) + .collect(), + ) } fn escalation_error() -> AnyError { @@ -2298,6 +2323,9 @@ mod tests { macro_rules! svec { ($($x:expr),*) => (vec![$($x.to_string()),*]); } + macro_rules! sarr { + ($($x:expr),*) => ([$($x.to_string()),*]); + } #[test] fn check_paths() { @@ -2678,94 +2706,88 @@ mod tests { set_prompter(Box::new(TestPrompter)); let perms1 = Permissions::allow_all(); let perms2 = Permissions { - read: Permissions::new_unary( - &Some(vec![PathBuf::from("/foo")]), - &None, - false, - ) - .unwrap(), + read: Permissions::new_unary(Some(&[PathBuf::from("/foo")]), None, false) + .unwrap(), write: Permissions::new_unary( - &Some(vec![PathBuf::from("/foo")]), - &None, + Some(&[PathBuf::from("/foo")]), + None, false, ) .unwrap(), - ffi: Permissions::new_unary( - &Some(vec![PathBuf::from("/foo")]), - &None, + ffi: Permissions::new_unary(Some(&[PathBuf::from("/foo")]), None, false) + .unwrap(), + net: Permissions::new_unary(Some(&sarr!["127.0.0.1:8000"]), None, false) + .unwrap(), + env: Permissions::new_unary(Some(&sarr!["HOME"]), None, false).unwrap(), + sys: Permissions::new_unary(Some(&sarr!["hostname"]), None, false) + .unwrap(), + run: Permissions::new_unary( + Some(&["deno".to_string().into()]), + None, false, ) .unwrap(), - net: Permissions::new_unary(&Some(svec!["127.0.0.1:8000"]), &None, false) - .unwrap(), - env: Permissions::new_unary(&Some(svec!["HOME"]), &None, false).unwrap(), - sys: Permissions::new_unary(&Some(svec!["hostname"]), &None, false) - .unwrap(), - run: Permissions::new_unary(&Some(svec!["deno"]), &None, false).unwrap(), all: Permissions::new_all(false), }; let perms3 = Permissions { - read: Permissions::new_unary( - &None, - &Some(vec![PathBuf::from("/foo")]), - false, - ) - .unwrap(), + read: Permissions::new_unary(None, Some(&[PathBuf::from("/foo")]), false) + .unwrap(), write: Permissions::new_unary( - &None, - &Some(vec![PathBuf::from("/foo")]), + None, + Some(&[PathBuf::from("/foo")]), false, ) .unwrap(), - ffi: Permissions::new_unary( - &None, - &Some(vec![PathBuf::from("/foo")]), + ffi: Permissions::new_unary(None, Some(&[PathBuf::from("/foo")]), false) + .unwrap(), + net: Permissions::new_unary(None, Some(&sarr!["127.0.0.1:8000"]), false) + .unwrap(), + env: Permissions::new_unary(None, Some(&sarr!["HOME"]), false).unwrap(), + sys: Permissions::new_unary(None, Some(&sarr!["hostname"]), false) + .unwrap(), + run: Permissions::new_unary( + None, + Some(&["deno".to_string().into()]), false, ) .unwrap(), - net: Permissions::new_unary(&None, &Some(svec!["127.0.0.1:8000"]), false) - .unwrap(), - env: Permissions::new_unary(&None, &Some(svec!["HOME"]), false).unwrap(), - sys: Permissions::new_unary(&None, &Some(svec!["hostname"]), false) - .unwrap(), - run: Permissions::new_unary(&None, &Some(svec!["deno"]), false).unwrap(), all: Permissions::new_all(false), }; let perms4 = Permissions { read: Permissions::new_unary( - &Some(vec![]), - &Some(vec![PathBuf::from("/foo")]), + Some(&[]), + Some(&[PathBuf::from("/foo")]), false, ) .unwrap(), write: Permissions::new_unary( - &Some(vec![]), - &Some(vec![PathBuf::from("/foo")]), + Some(&[]), + Some(&[PathBuf::from("/foo")]), false, ) .unwrap(), ffi: Permissions::new_unary( - &Some(vec![]), - &Some(vec![PathBuf::from("/foo")]), + Some(&[]), + Some(&[PathBuf::from("/foo")]), false, ) .unwrap(), net: Permissions::new_unary( - &Some(vec![]), - &Some(svec!["127.0.0.1:8000"]), + Some(&[]), + Some(&sarr!["127.0.0.1:8000"]), false, ) .unwrap(), - env: Permissions::new_unary(&Some(vec![]), &Some(svec!["HOME"]), false) + env: Permissions::new_unary(Some(&[]), Some(&sarr!["HOME"]), false) .unwrap(), - sys: Permissions::new_unary( - &Some(vec![]), - &Some(svec!["hostname"]), + sys: Permissions::new_unary(Some(&[]), Some(&sarr!["hostname"]), false) + .unwrap(), + run: Permissions::new_unary( + Some(&[]), + Some(&["deno".to_string().into()]), false, ) .unwrap(), - run: Permissions::new_unary(&Some(vec![]), &Some(svec!["deno"]), false) - .unwrap(), all: Permissions::new_all(false), }; #[rustfmt::skip] @@ -2894,33 +2916,38 @@ mod tests { set_prompter(Box::new(TestPrompter)); let mut perms = Permissions { read: Permissions::new_unary( - &Some(vec![PathBuf::from("/foo"), PathBuf::from("/foo/baz")]), - &None, + Some(&[PathBuf::from("/foo"), PathBuf::from("/foo/baz")]), + None, false, ) .unwrap(), write: Permissions::new_unary( - &Some(vec![PathBuf::from("/foo"), PathBuf::from("/foo/baz")]), - &None, + Some(&[PathBuf::from("/foo"), PathBuf::from("/foo/baz")]), + None, false, ) .unwrap(), ffi: Permissions::new_unary( - &Some(vec![PathBuf::from("/foo"), PathBuf::from("/foo/baz")]), - &None, + Some(&[PathBuf::from("/foo"), PathBuf::from("/foo/baz")]), + None, false, ) .unwrap(), net: Permissions::new_unary( - &Some(svec!["127.0.0.1", "127.0.0.1:8000"]), - &None, + Some(&sarr!["127.0.0.1", "127.0.0.1:8000"]), + None, false, ) .unwrap(), - env: Permissions::new_unary(&Some(svec!["HOME"]), &None, false).unwrap(), - sys: Permissions::new_unary(&Some(svec!["hostname"]), &None, false) + env: Permissions::new_unary(Some(&sarr!["HOME"]), None, false).unwrap(), + sys: Permissions::new_unary(Some(&sarr!["hostname"]), None, false) .unwrap(), - run: Permissions::new_unary(&Some(svec!["deno"]), &None, false).unwrap(), + run: Permissions::new_unary( + Some(&["deno".to_string().into()]), + None, + false, + ) + .unwrap(), all: Permissions::new_all(false), }; #[rustfmt::skip] @@ -3006,11 +3033,13 @@ mod tests { .check(&NetDescriptor("deno.land".parse().unwrap(), None), None) .is_err()); + #[allow(clippy::disallowed_methods)] + let cwd = std::env::current_dir().unwrap(); prompt_value.set(true); - assert!(perms.run.check("cat", None).is_ok()); + assert!(perms.run.check(&cwd.join("cat"), None).is_ok()); prompt_value.set(false); - assert!(perms.run.check("cat", None).is_ok()); - assert!(perms.run.check("ls", None).is_err()); + assert!(perms.run.check(&cwd.join("cat"), None).is_ok()); + assert!(perms.run.check(&cwd.join("ls"), None).is_err()); prompt_value.set(true); assert!(perms.env.check("HOME", None).is_ok()); @@ -3102,12 +3131,14 @@ mod tests { .is_ok()); prompt_value.set(false); - assert!(perms.run.check("cat", None).is_err()); + #[allow(clippy::disallowed_methods)] + let cwd = std::env::current_dir().unwrap(); + assert!(perms.run.check(&cwd.join("cat"), None).is_err()); prompt_value.set(true); - assert!(perms.run.check("cat", None).is_err()); - assert!(perms.run.check("ls", None).is_ok()); + assert!(perms.run.check(&cwd.join("cat"), None).is_err()); + assert!(perms.run.check(&cwd.join("ls"), None).is_ok()); prompt_value.set(false); - assert!(perms.run.check("ls", None).is_ok()); + assert!(perms.run.check(&cwd.join("ls"), None).is_ok()); prompt_value.set(false); assert!(perms.env.check("HOME", None).is_err()); @@ -3134,7 +3165,7 @@ mod tests { let mut perms = Permissions::allow_all(); perms.env = UnaryPermission { granted_global: false, - ..Permissions::new_unary(&Some(svec!["HOME"]), &None, false).unwrap() + ..Permissions::new_unary(Some(&sarr!["HOME"]), None, false).unwrap() }; prompt_value.set(true); @@ -3150,14 +3181,14 @@ mod tests { fn test_check_partial_denied() { let mut perms = Permissions { read: Permissions::new_unary( - &Some(vec![]), - &Some(vec![PathBuf::from("/foo/bar")]), + Some(&[]), + Some(&[PathBuf::from("/foo/bar")]), false, ) .unwrap(), write: Permissions::new_unary( - &Some(vec![]), - &Some(vec![PathBuf::from("/foo/bar")]), + Some(&[]), + Some(&[PathBuf::from("/foo/bar")]), false, ) .unwrap(), @@ -3175,8 +3206,8 @@ mod tests { fn test_net_fully_qualified_domain_name() { let mut perms = Permissions { net: Permissions::new_unary( - &Some(vec!["allowed.domain".to_string(), "1.1.1.1".to_string()]), - &Some(vec!["denied.domain".to_string(), "2.2.2.2".to_string()]), + Some(&["allowed.domain".to_string(), "1.1.1.1".to_string()]), + Some(&["denied.domain".to_string(), "2.2.2.2".to_string()]), false, ) .unwrap(), @@ -3341,8 +3372,8 @@ mod tests { fn test_create_child_permissions() { set_prompter(Box::new(TestPrompter)); let mut main_perms = Permissions { - env: Permissions::new_unary(&Some(vec![]), &None, false).unwrap(), - net: Permissions::new_unary(&Some(svec!["foo", "bar"]), &None, false) + env: Permissions::new_unary(Some(&[]), None, false).unwrap(), + net: Permissions::new_unary(Some(&sarr!["foo", "bar"]), None, false) .unwrap(), ..Permissions::none_without_prompt() }; @@ -3358,8 +3389,8 @@ mod tests { ) .unwrap(), Permissions { - env: Permissions::new_unary(&Some(vec![]), &None, false).unwrap(), - net: Permissions::new_unary(&Some(svec!["foo"]), &None, false).unwrap(), + env: Permissions::new_unary(Some(&[]), None, false).unwrap(), + net: Permissions::new_unary(Some(&sarr!["foo"]), None, false).unwrap(), ..Permissions::none_without_prompt() } ); @@ -3445,20 +3476,20 @@ mod tests { set_prompter(Box::new(TestPrompter)); assert!(Permissions::new_unary::<ReadDescriptor>( - &Some(vec![Default::default()]), - &None, + Some(&[Default::default()]), + None, false ) .is_err()); assert!(Permissions::new_unary::<EnvDescriptor>( - &Some(vec![Default::default()]), - &None, + Some(&[Default::default()]), + None, false ) .is_err()); assert!(Permissions::new_unary::<NetDescriptor>( - &Some(vec![Default::default()]), - &None, + Some(&[Default::default()]), + None, false ) .is_err()); |