diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2024-09-16 21:39:37 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-16 21:39:37 +0100 |
commit | 62e952559f600e72d7498c9b12f906cb0b1ba150 (patch) | |
tree | 6dbcce6592973358ef4bf6341888b0bbbdb98cc5 /ext/net | |
parent | e0b9c745c15720914f14996bf357d5b375e2dbd8 (diff) |
refactor(permissions): split up Descriptor into Allow, Deny, and Query (#25508)
This makes the permission system more versatile.
Diffstat (limited to 'ext/net')
-rw-r--r-- | ext/net/lib.rs | 45 | ||||
-rw-r--r-- | ext/net/ops.rs | 21 | ||||
-rw-r--r-- | ext/net/ops_tls.rs | 9 | ||||
-rw-r--r-- | ext/net/ops_unix.rs | 42 |
4 files changed, 76 insertions, 41 deletions
diff --git a/ext/net/lib.rs b/ext/net/lib.rs index 098d220db..0ef3e85c4 100644 --- a/ext/net/lib.rs +++ b/ext/net/lib.rs @@ -13,6 +13,7 @@ use deno_core::error::AnyError; use deno_core::OpState; use deno_tls::rustls::RootCertStore; use deno_tls::RootCertStoreProvider; +use std::borrow::Cow; use std::path::Path; use std::path::PathBuf; use std::sync::Arc; @@ -22,12 +23,27 @@ pub const UNSTABLE_FEATURE_NAME: &str = "net"; pub trait NetPermissions { fn check_net<T: AsRef<str>>( &mut self, - _host: &(T, Option<u16>), - _api_name: &str, + host: &(T, Option<u16>), + api_name: &str, ) -> Result<(), AnyError>; - fn check_read(&mut self, _p: &Path, _api_name: &str) -> Result<(), AnyError>; - fn check_write(&mut self, _p: &Path, _api_name: &str) - -> Result<(), AnyError>; + #[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"] + fn check_read( + &mut self, + p: &str, + api_name: &str, + ) -> Result<PathBuf, AnyError>; + #[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"] + fn check_write( + &mut self, + p: &str, + api_name: &str, + ) -> Result<PathBuf, AnyError>; + #[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"] + fn check_write_path<'a>( + &mut self, + p: &'a Path, + api_name: &str, + ) -> Result<Cow<'a, Path>, AnyError>; } impl NetPermissions for deno_permissions::PermissionsContainer { @@ -43,20 +59,31 @@ impl NetPermissions for deno_permissions::PermissionsContainer { #[inline(always)] fn check_read( &mut self, - path: &Path, + path: &str, api_name: &str, - ) -> Result<(), AnyError> { + ) -> Result<PathBuf, AnyError> { deno_permissions::PermissionsContainer::check_read(self, path, api_name) } #[inline(always)] fn check_write( &mut self, - path: &Path, + path: &str, api_name: &str, - ) -> Result<(), AnyError> { + ) -> Result<PathBuf, AnyError> { deno_permissions::PermissionsContainer::check_write(self, path, api_name) } + + #[inline(always)] + fn check_write_path<'a>( + &mut self, + path: &'a Path, + api_name: &str, + ) -> Result<Cow<'a, Path>, AnyError> { + deno_permissions::PermissionsContainer::check_write_path( + self, path, api_name, + ) + } } /// Helper for checking unstable features. Used for sync ops. diff --git a/ext/net/ops.rs b/ext/net/ops.rs index b74dc8d75..67d32fe03 100644 --- a/ext/net/ops.rs +++ b/ext/net/ops.rs @@ -784,6 +784,7 @@ mod tests { use std::net::Ipv6Addr; use std::net::ToSocketAddrs; use std::path::Path; + use std::path::PathBuf; use std::sync::Arc; use std::sync::Mutex; use trust_dns_proto::rr::rdata::a::A; @@ -991,18 +992,26 @@ mod tests { fn check_read( &mut self, - _p: &Path, + p: &str, _api_name: &str, - ) -> Result<(), AnyError> { - Ok(()) + ) -> Result<PathBuf, AnyError> { + Ok(PathBuf::from(p)) } fn check_write( &mut self, - _p: &Path, + p: &str, _api_name: &str, - ) -> Result<(), AnyError> { - Ok(()) + ) -> Result<PathBuf, AnyError> { + Ok(PathBuf::from(p)) + } + + fn check_write_path<'a>( + &mut self, + p: &'a Path, + _api_name: &str, + ) -> Result<Cow<'a, Path>, AnyError> { + Ok(Cow::Borrowed(p)) } } diff --git a/ext/net/ops_tls.rs b/ext/net/ops_tls.rs index 3ca5adbbe..064da5818 100644 --- a/ext/net/ops_tls.rs +++ b/ext/net/ops_tls.rs @@ -52,7 +52,6 @@ use std::io::ErrorKind; use std::io::Read; use std::net::SocketAddr; use std::num::NonZeroUsize; -use std::path::Path; use std::rc::Rc; use std::sync::Arc; use tokio::io::AsyncReadExt; @@ -356,15 +355,17 @@ where .try_borrow::<UnsafelyIgnoreCertificateErrors>() .and_then(|it| it.0.clone()); - { + let cert_file = { let mut s = state.borrow_mut(); let permissions = s.borrow_mut::<NP>(); permissions .check_net(&(&addr.hostname, Some(addr.port)), "Deno.connectTls()")?; if let Some(path) = cert_file { - permissions.check_read(Path::new(path), "Deno.connectTls()")?; + Some(permissions.check_read(path, "Deno.connectTls()")?) + } else { + None } - } + }; let mut ca_certs = args .ca_certs diff --git a/ext/net/ops_unix.rs b/ext/net/ops_unix.rs index 7d2f6af3c..95293284f 100644 --- a/ext/net/ops_unix.rs +++ b/ext/net/ops_unix.rs @@ -94,22 +94,22 @@ pub async fn op_net_accept_unix( #[serde] pub async fn op_net_connect_unix<NP>( state: Rc<RefCell<OpState>>, - #[string] path: String, + #[string] address_path: String, ) -> Result<(ResourceId, Option<String>, Option<String>), AnyError> where NP: NetPermissions + 'static, { - let address_path = Path::new(&path); - { + let address_path = { let mut state_ = state.borrow_mut(); - state_ + let address_path = state_ .borrow_mut::<NP>() - .check_read(address_path, "Deno.connect()")?; - state_ + .check_read(&address_path, "Deno.connect()")?; + _ = state_ .borrow_mut::<NP>() - .check_write(address_path, "Deno.connect()")?; - } - let unix_stream = UnixStream::connect(Path::new(&path)).await?; + .check_write_path(&address_path, "Deno.connect()")?; + address_path + }; + let unix_stream = UnixStream::connect(&address_path).await?; let local_addr = unix_stream.local_addr()?; let remote_addr = unix_stream.peer_addr()?; let local_addr_path = local_addr.as_pathname().map(pathstring).transpose()?; @@ -148,18 +148,17 @@ pub async fn op_net_recv_unixpacket( pub async fn op_net_send_unixpacket<NP>( state: Rc<RefCell<OpState>>, #[smi] rid: ResourceId, - #[string] path: String, + #[string] address_path: String, #[buffer] zero_copy: JsBuffer, ) -> Result<usize, AnyError> where NP: NetPermissions + 'static, { - let address_path = Path::new(&path); - { + let address_path = { let mut s = state.borrow_mut(); s.borrow_mut::<NP>() - .check_write(address_path, "Deno.DatagramConn.send()")?; - } + .check_write(&address_path, "Deno.DatagramConn.send()")? + }; let resource = state .borrow() @@ -178,17 +177,16 @@ where #[serde] pub fn op_net_listen_unix<NP>( state: &mut OpState, - #[string] path: String, + #[string] address_path: String, #[string] api_name: String, ) -> Result<(ResourceId, Option<String>), AnyError> where NP: NetPermissions + 'static, { - let address_path = Path::new(&path); let permissions = state.borrow_mut::<NP>(); let api_call_expr = format!("{}()", api_name); - permissions.check_read(address_path, &api_call_expr)?; - permissions.check_write(address_path, &api_call_expr)?; + let address_path = permissions.check_read(&address_path, &api_call_expr)?; + _ = permissions.check_write_path(&address_path, &api_call_expr)?; let listener = UnixListener::bind(address_path)?; let local_addr = listener.local_addr()?; let pathname = local_addr.as_pathname().map(pathstring).transpose()?; @@ -199,15 +197,15 @@ where pub fn net_listen_unixpacket<NP>( state: &mut OpState, - path: String, + address_path: String, ) -> Result<(ResourceId, Option<String>), AnyError> where NP: NetPermissions + 'static, { - let address_path = Path::new(&path); let permissions = state.borrow_mut::<NP>(); - permissions.check_read(address_path, "Deno.listenDatagram()")?; - permissions.check_write(address_path, "Deno.listenDatagram()")?; + let address_path = + permissions.check_read(&address_path, "Deno.listenDatagram()")?; + _ = permissions.check_write_path(&address_path, "Deno.listenDatagram()")?; let socket = UnixDatagram::bind(address_path)?; let local_addr = socket.local_addr()?; let pathname = local_addr.as_pathname().map(pathstring).transpose()?; |