diff --git a/bls-runtime/src/cli_clap.rs b/bls-runtime/src/cli_clap.rs index 4a5d04d..440c119 100644 --- a/bls-runtime/src/cli_clap.rs +++ b/bls-runtime/src/cli_clap.rs @@ -92,10 +92,14 @@ const ALLOW_READ_ALL_HELP: &str = "Allow the app to all read permissions."; const ALLOW_WRITE_HELP: &str = "Allow the app to write permissions."; +const ALLOW_NET_HELP: &str = "Allow the app to net accessing permissions."; + const DENY_READ_HELP: &str = "Deny the app to read permissions."; const DENY_WRITE_HELP: &str = "Deny the app to write permissions."; +const DENY_NET_HELP: &str = "Deny the app to net accessing permissions."; + const ALLOW_WRITE_ALL_HELP: &str = "Allow the app to all write permissions."; fn parse_envs(envs: &str) -> Result<(String, String)> { @@ -235,12 +239,18 @@ pub struct PermissionFlags { #[clap(long = "allow-write", id="allow-write", num_args=(0..) , value_name = "PATH[,]", help = ALLOW_WRITE_HELP, value_parser = parser_allow)] pub allow_write: Option, + #[clap(long = "allow-net", id="allow-net", num_args=(0..) , value_name = "PATH[,]", help = ALLOW_NET_HELP, value_parser = parser_allow)] + pub allow_net: Option, + #[clap(long = "deny-read", id="deny-read", num_args=(0..) , value_name = "PATH[,]", help = DENY_READ_HELP, value_parser = parser_allow)] pub deny_read: Option, #[clap(long = "deny-write", id="deny-write", num_args=(0..) , value_name = "PATH[,]", help = DENY_WRITE_HELP, value_parser = parser_allow)] pub deny_write: Option, + #[clap(long = "deny-net", id="deny-net", num_args=(0..) , value_name = "URL[,]", help = DENY_NET_HELP, value_parser = parser_allow)] + pub deny_net: Option, + #[clap(long = "allow-all", id = "allow-all", help = "Allow all permissions.")] pub allow_all: bool, } @@ -252,6 +262,8 @@ impl Into for PermissionFlags { deny_read: self.deny_read, allow_write: self.allow_write, deny_write: self.deny_write, + deny_net: self.deny_net, + allow_net: self.allow_net, allow_all: self.allow_all, }; permissions diff --git a/bls-runtime/src/main.rs b/bls-runtime/src/main.rs index 5992ba6..58735ea 100644 --- a/bls-runtime/src/main.rs +++ b/bls-runtime/src/main.rs @@ -232,6 +232,8 @@ fn parse_args() -> CliCommandOpts { set_perm_grant!("allow-write", o.permission_flags.allow_write); set_perm_grant!("deny-read", o.permission_flags.deny_read); set_perm_grant!("deny-write", o.permission_flags.deny_write); + set_perm_grant!("allow-net", o.permission_flags.allow_net); + set_perm_grant!("deny-net", o.permission_flags.deny_net); o } Err(_) => { diff --git a/crates/blockless-drivers/src/ipfs_driver/http_raw.rs b/crates/blockless-drivers/src/ipfs_driver/http_raw.rs index bb3919d..e360370 100644 --- a/crates/blockless-drivers/src/ipfs_driver/http_raw.rs +++ b/crates/blockless-drivers/src/ipfs_driver/http_raw.rs @@ -109,8 +109,10 @@ impl HttpRaw { buf.write_all(format!("Content-Length: {}", body_buf.len()).as_bytes()) .unwrap(); buf.write_all(EOL).unwrap(); - buf.write_all(format!("Content-Type: multipart/form-data; boundary={}", boundary).as_bytes()) - .unwrap(); + buf.write_all( + format!("Content-Type: multipart/form-data; boundary={}", boundary).as_bytes(), + ) + .unwrap(); buf.write_all(EOL).unwrap(); buf.write_all(EOL).unwrap(); buf.extend_from_slice(&body_buf); diff --git a/crates/blockless-drivers/src/lib.rs b/crates/blockless-drivers/src/lib.rs index 40ecc3b..ff44e41 100644 --- a/crates/blockless-drivers/src/lib.rs +++ b/crates/blockless-drivers/src/lib.rs @@ -30,11 +30,7 @@ type OpenFuture = Pin, ErrorKin pub trait Driver { fn name(&self) -> &str; - fn open( - &self, - uri: &str, - opts: &str, - ) -> OpenFuture; + fn open(&self, uri: &str, opts: &str) -> OpenFuture; } lazy_static! { diff --git a/crates/blockless-drivers/src/wasi/http.rs b/crates/blockless-drivers/src/wasi/http.rs index 789713e..ad763c4 100644 --- a/crates/blockless-drivers/src/wasi/http.rs +++ b/crates/blockless-drivers/src/wasi/http.rs @@ -1,6 +1,9 @@ #![allow(non_upper_case_globals)] +use std::str::FromStr; + use crate::{http_driver, HttpErrorKind}; use log::error; +use url::Url; use wasi_common::WasiCtx; use wiggle::{GuestMemory, GuestPtr}; @@ -107,7 +110,9 @@ impl blockless_http::BlocklessHttp for WasiCtx { HttpErrorKind::Utf8Error })? .unwrap(); - if !self.resource_permission(url) { + + let url_ = Url::from_str(url).map_err(|_| HttpErrorKind::InvalidUrl)?; + if !self.check_url_permissions(&url_, "http_req") { error!("Permission Deny"); return Err(HttpErrorKind::PermissionDeny); } diff --git a/crates/blockless-drivers/src/wasi/socket.rs b/crates/blockless-drivers/src/wasi/socket.rs index dcc3183..bbcb5c5 100644 --- a/crates/blockless-drivers/src/wasi/socket.rs +++ b/crates/blockless-drivers/src/wasi/socket.rs @@ -85,7 +85,10 @@ impl blockless_socket::BlocklessSocket for WasiCtx { .map_err(|_| BlocklessSocketErrorKind::ParameterError)? .unwrap(); let mode = FileAccessMode::READ | FileAccessMode::WRITE; - match tcp_bind(&addr).await.map(|f| Arc::new(FileEntry::new(f, mode))) { + match tcp_bind(&addr) + .await + .map(|f| Arc::new(FileEntry::new(f, mode))) + { Ok(f) => { let fd_num = self.table().push(f).unwrap(); let fd = types::SocketHandle::from(fd_num); @@ -105,7 +108,10 @@ impl blockless_socket::BlocklessSocket for WasiCtx { .map_err(|_| BlocklessSocketErrorKind::ParameterError)? .unwrap(); let mode = FileAccessMode::READ | FileAccessMode::WRITE; - match tcp_connect(&addr).await.map(|f| Arc::new(FileEntry::new(f, mode))) { + match tcp_connect(&addr) + .await + .map(|f| Arc::new(FileEntry::new(f, mode))) + { Ok(f) => { let fd_num = self.table().push(f).unwrap(); let fd = types::SocketHandle::from(fd_num); diff --git a/crates/wasi-common/src/blockless/config.rs b/crates/wasi-common/src/blockless/config.rs index ff1910b..bba0499 100644 --- a/crates/wasi-common/src/blockless/config.rs +++ b/crates/wasi-common/src/blockless/config.rs @@ -502,6 +502,8 @@ pub struct PermissionsConfig { pub allow_write: Option, pub deny_read: Option, pub deny_write: Option, + pub allow_net: Option, + pub deny_net: Option, pub allow_all: bool, } @@ -526,6 +528,8 @@ impl Into for &PermissionsConfig { set_perm!(&self.allow_write, options.allow_write); set_perm!(&self.deny_read, options.deny_read); set_perm!(&self.deny_write, options.deny_write); + set_perm!(&self.allow_net, options.allow_net); + set_perm!(&self.deny_net, options.deny_net); options.prompt = true; options.allow_all = self.allow_all; options @@ -537,8 +541,10 @@ impl Default for PermissionsConfig { PermissionsConfig { allow_read: None, allow_write: None, + allow_net: None, deny_read: None, deny_write: None, + deny_net: None, allow_all: false, } } diff --git a/crates/wasi-common/src/blockless/permissions.rs b/crates/wasi-common/src/blockless/permissions.rs index cf8ae7a..144e845 100644 --- a/crates/wasi-common/src/blockless/permissions.rs +++ b/crates/wasi-common/src/blockless/permissions.rs @@ -74,12 +74,18 @@ impl BlsRuntimePermissionsContainer { if let Some(PermissionGrant::All) = config.deny_write { permissions.write.flag_denied_global = true; } + if let Some(PermissionGrant::All) = config.deny_net { + permissions.net.flag_denied_global = true; + } if let Some(PermissionGrant::All) = config.allow_read { permissions.read.granted_global = true; } if let Some(PermissionGrant::All) = config.allow_write { permissions.write.granted_global = true; } + if let Some(PermissionGrant::All) = config.allow_net { + permissions.net.granted_global = true; + } *self.inner.lock() = permissions; Ok(()) } @@ -254,7 +260,7 @@ impl BlsRuntimePermissionsContainer { } #[inline(always)] - pub fn check_net_url(&mut self, url: &Url, api_name: &str) -> Result<(), AnyError> { + pub fn check_net_url(&self, url: &Url, api_name: &str) -> Result<(), AnyError> { self.inner.check_net_url(url, api_name) } diff --git a/crates/wasi-common/src/ctx.rs b/crates/wasi-common/src/ctx.rs index df54b2d..fe07c2b 100644 --- a/crates/wasi-common/src/ctx.rs +++ b/crates/wasi-common/src/ctx.rs @@ -6,6 +6,7 @@ use crate::string_array::StringArray; use crate::table::Table; use crate::{BlocklessConfig, BlsRuntimePermissionsContainer, PermissionsConfig}; use crate::{Error, StringArrayError}; +use bls_permissions::Url; use cap_rand::RngCore; use std::ops::Deref; use std::path::{Path, PathBuf}; @@ -74,6 +75,13 @@ impl WasiCtx { .and_then(|l| l.fix_stdin_ref().map(String::from)) } + pub fn check_url_permissions(&self, host: &Url, api_name: &str) -> bool { + match self.perms_container.check_net_url(host, api_name) { + Ok(_) => true, + Err(_) => false, + } + } + pub fn resource_permission(&self, resource: &str) -> bool { match self.blockless_config.lock().unwrap().deref() { Some(ref c) => c.resource_permission(resource),