summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--assets/plugins/status-bar.wasmbin435070 -> 435055 bytes
-rw-r--r--assets/plugins/strider.wasmbin535162 -> 535152 bytes
-rw-r--r--assets/plugins/tab-bar.wasmbin424785 -> 424733 bytes
-rw-r--r--zellij-server/src/tab.rs9
-rw-r--r--zellij-server/src/wasm_vm.rs34
-rw-r--r--zellij-tile/src/shim.rs5
-rw-r--r--zellij-utils/assets/layouts/default.yaml6
-rw-r--r--zellij-utils/assets/layouts/disable-status-bar.yaml3
-rw-r--r--zellij-utils/assets/layouts/strider.yaml9
-rw-r--r--zellij-utils/src/input/layout.rs10
-rw-r--r--zellij-utils/src/input/unit/fixtures/layouts/three-panes-with-tab-and-default-plugins.yaml6
-rw-r--r--zellij-utils/src/input/unit/layout_test.rs40
12 files changed, 99 insertions, 23 deletions
diff --git a/assets/plugins/status-bar.wasm b/assets/plugins/status-bar.wasm
index d1ad39e90..285669e59 100644
--- a/assets/plugins/status-bar.wasm
+++ b/assets/plugins/status-bar.wasm
Binary files differ
diff --git a/assets/plugins/strider.wasm b/assets/plugins/strider.wasm
index b57557a7a..ab3d3cd9f 100644
--- a/assets/plugins/strider.wasm
+++ b/assets/plugins/strider.wasm
Binary files differ
diff --git a/assets/plugins/tab-bar.wasm b/assets/plugins/tab-bar.wasm
index 896512fe2..39705bcb1 100644
--- a/assets/plugins/tab-bar.wasm
+++ b/assets/plugins/tab-bar.wasm
Binary files differ
diff --git a/zellij-server/src/tab.rs b/zellij-server/src/tab.rs
index b90d7827c..ba8a8c88b 100644
--- a/zellij-server/src/tab.rs
+++ b/zellij-server/src/tab.rs
@@ -325,10 +325,15 @@ impl Tab {
if let Some(Run::Plugin(Some(plugin))) = &layout.run {
let (pid_tx, pid_rx) = channel();
self.senders
- .send_to_plugin(PluginInstruction::Load(pid_tx, plugin.clone(), tab_index))
+ .send_to_plugin(PluginInstruction::Load(
+ pid_tx,
+ plugin.path.clone(),
+ tab_index,
+ plugin._allow_exec_host_cmd,
+ ))
.unwrap();
let pid = pid_rx.recv().unwrap();
- let title = String::from(plugin.as_path().as_os_str().to_string_lossy());
+ let title = String::from(plugin.path.as_path().as_os_str().to_string_lossy());
let mut new_plugin = PluginPane::new(
pid,
*position_and_size,
diff --git a/zellij-server/src/wasm_vm.rs b/zellij-server/src/wasm_vm.rs
index e8d9344ee..cda114292 100644
--- a/zellij-server/src/wasm_vm.rs
+++ b/zellij-server/src/wasm_vm.rs
@@ -1,4 +1,4 @@
-use log::info;
+use log::{info, warn};
use std::collections::{HashMap, HashSet};
use std::fs;
use std::path::PathBuf;
@@ -28,8 +28,8 @@ use zellij_utils::{input::command::TerminalAction, serde, zellij_tile};
#[derive(Clone, Debug)]
pub(crate) enum PluginInstruction {
- Load(Sender<u32>, PathBuf, usize), // tx_pid, path_of_plugin , tab_index
- Update(Option<u32>, Event), // Focused plugin / broadcast, event data
+ Load(Sender<u32>, PathBuf, usize, bool), // tx_pid, path_of_plugin , tab_index, allow_exec_host_cmd
+ Update(Option<u32>, Event), // Focused plugin / broadcast, event data
Render(Sender<String>, u32, usize, usize), // String buffer, plugin id, rows, cols
Unload(u32),
Exit,
@@ -54,6 +54,8 @@ pub(crate) struct PluginEnv {
pub senders: ThreadSenders,
pub wasi_env: WasiEnv,
pub subscriptions: Arc<Mutex<HashSet<EventType>>>,
+ // FIXME: Once permission system is ready, this could be removed
+ pub _allow_exec_host_cmd: bool,
}
// Thread main --------------------------------------------------------------------------------------------------------
@@ -65,7 +67,7 @@ pub(crate) fn wasm_thread_main(bus: Bus<PluginInstruction>, store: Store, data_d
let (event, mut err_ctx) = bus.recv().expect("failed to receive event on channel");
err_ctx.add_call(ContextType::Plugin((&event).into()));
match event {
- PluginInstruction::Load(pid_tx, path, tab_index) => {
+ PluginInstruction::Load(pid_tx, path, tab_index, _allow_exec_host_cmd) => {
let plugin_dir = data_dir.join("plugins/");
let wasm_bytes = fs::read(&path)
.or_else(|_| fs::read(&path.with_extension("wasm")))
@@ -99,12 +101,17 @@ pub(crate) fn wasm_thread_main(bus: Bus<PluginInstruction>, store: Store, data_d
let wasi = wasi_env.import_object(&module).unwrap();
+ if _allow_exec_host_cmd {
+ info!("Plugin({:?}) is able to run any host command, this may lead to some security issues!", path);
+ }
+
let plugin_env = PluginEnv {
plugin_id,
tab_index,
senders: bus.senders.clone(),
wasi_env,
subscriptions: Arc::new(Mutex::new(HashSet::new())),
+ _allow_exec_host_cmd,
};
let zellij = zellij_exports(&store, &plugin_env);
@@ -174,6 +181,7 @@ pub(crate) fn zellij_exports(store: &Store, plugin_env: &PluginEnv) -> ImportObj
host_get_plugin_ids,
host_open_file,
host_set_timeout,
+ host_exec_cmd,
}
}
@@ -248,6 +256,24 @@ fn host_set_timeout(plugin_env: &PluginEnv, secs: f64) {
});
}
+fn host_exec_cmd(plugin_env: &PluginEnv) {
+ let mut cmdline: Vec<String> = wasi_read_object(&plugin_env.wasi_env);
+ let command = cmdline.remove(0);
+
+ // Bail out if we're forbidden to run command
+ if !plugin_env._allow_exec_host_cmd {
+ warn!("This plugin isn't allow to run command in host side, skip running this command: '{cmd} {args}'.",
+ cmd = command, args = cmdline.join(" "));
+ return;
+ }
+
+ // Here, we don't wait the command to finish
+ process::Command::new(command)
+ .args(cmdline)
+ .spawn()
+ .unwrap();
+}
+
// Helper Functions ---------------------------------------------------------------------------------------------------
pub fn wasi_read_string(wasi_env: &WasiEnv) -> String {
diff --git a/zellij-tile/src/shim.rs b/zellij-tile/src/shim.rs
index b514b55aa..bdd6f4fb1 100644
--- a/zellij-tile/src/shim.rs
+++ b/zellij-tile/src/shim.rs
@@ -37,6 +37,10 @@ pub fn open_file(path: &Path) {
pub fn set_timeout(secs: f64) {
unsafe { host_set_timeout(secs) };
}
+pub fn exec_cmd(cmd: &[&str]) {
+ object_to_stdout(&cmd);
+ unsafe { host_exec_cmd() };
+}
// Internal Functions
@@ -60,4 +64,5 @@ extern "C" {
fn host_get_plugin_ids();
fn host_open_file();
fn host_set_timeout(secs: f64);
+ fn host_exec_cmd();
}
diff --git a/zellij-utils/assets/layouts/default.yaml b/zellij-utils/assets/layouts/default.yaml
index e0a28da12..549dea24b 100644
--- a/zellij-utils/assets/layouts/default.yaml
+++ b/zellij-utils/assets/layouts/default.yaml
@@ -7,7 +7,8 @@ template:
split_size:
Fixed: 1
run:
- plugin: tab-bar
+ plugin:
+ path: tab-bar
- direction: Vertical
body: true
- direction: Vertical
@@ -15,6 +16,7 @@ template:
split_size:
Fixed: 2
run:
- plugin: status-bar
+ plugin:
+ path: status-bar
tabs:
- direction: Vertical
diff --git a/zellij-utils/assets/layouts/disable-status-bar.yaml b/zellij-utils/assets/layouts/disable-status-bar.yaml
index a58ef4cf4..e97bb8f1e 100644
--- a/zellij-utils/assets/layouts/disable-status-bar.yaml
+++ b/zellij-utils/assets/layouts/disable-status-bar.yaml
@@ -7,6 +7,7 @@ template:
split_size:
Fixed: 1
run:
- plugin: tab-bar
+ plugin:
+ path: tab-bar
- direction: Vertical
body: true
diff --git a/zellij-utils/assets/layouts/strider.yaml b/zellij-utils/assets/layouts/strider.yaml
index 96e3c290e..ccb2a5748 100644
--- a/zellij-utils/assets/layouts/strider.yaml
+++ b/zellij-utils/assets/layouts/strider.yaml
@@ -7,7 +7,8 @@ template:
split_size:
Fixed: 1
run:
- plugin: tab-bar
+ plugin:
+ path: tab-bar
- direction: Vertical
body: true
- direction: Vertical
@@ -15,7 +16,8 @@ template:
split_size:
Fixed: 2
run:
- plugin: status-bar
+ plugin:
+ path: status-bar
tabs:
- direction: Vertical
parts:
@@ -23,5 +25,6 @@ tabs:
split_size:
Percent: 20
run:
- plugin: strider
+ plugin:
+ path: strider
- direction: Horizontal
diff --git a/zellij-utils/src/input/layout.rs b/zellij-utils/src/input/layout.rs
index be71130cd..5d4b34926 100644
--- a/zellij-utils/src/input/layout.rs
+++ b/zellij-utils/src/input/layout.rs
@@ -53,11 +53,19 @@ pub enum SplitSize {
#[serde(crate = "self::serde")]
pub enum Run {
#[serde(rename = "plugin")]
- Plugin(Option<PathBuf>),
+ Plugin(Option<RunPlugin>),
#[serde(rename = "command")]
Command(RunCommand),
}
+#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq, Eq)]
+#[serde(crate = "self::serde")]
+pub struct RunPlugin {
+ pub path: PathBuf,
+ #[serde(default)]
+ pub _allow_exec_host_cmd: bool,
+}
+
// The layout struct ultimately used to build the layouts.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(crate = "self::serde")]
diff --git a/zellij-utils/src/input/unit/fixtures/layouts/three-panes-with-tab-and-default-plugins.yaml b/zellij-utils/src/input/unit/fixtures/layouts/three-panes-with-tab-and-default-plugins.yaml
index 880463957..ae54a0c9b 100644
--- a/zellij-utils/src/input/unit/fixtures/layouts/three-panes-with-tab-and-default-plugins.yaml
+++ b/zellij-utils/src/input/unit/fixtures/layouts/three-panes-with-tab-and-default-plugins.yaml
@@ -6,14 +6,16 @@ template:
split_size:
Fixed: 1
run:
- plugin: tab-bar
+ plugin:
+ path: tab-bar
- direction: Horizontal
body: true
- direction: Vertical
split_size:
Fixed: 2
run:
- plugin: status-bar
+ plugin:
+ path: status-bar
tabs:
- direction: Vertical
diff --git a/zellij-utils/src/input/unit/layout_test.rs b/zellij-utils/src/input/unit/layout_test.rs
index abce56a4e..1b696b0a1 100644
--- a/zellij-utils/src/input/unit/layout_test.rs
+++ b/zellij-utils/src/input/unit/layout_test.rs
@@ -45,7 +45,10 @@ fn default_layout_merged_correctly() {
borderless: true,
parts: vec![],
split_size: Some(SplitSize::Fixed(1)),
- run: Some(Run::Plugin(Some("tab-bar".into()))),
+ run: Some(Run::Plugin(Some(RunPlugin {
+ path: "tab-bar".into(),
+ ..Default::default()
+ }))),
},
Layout {
direction: Direction::Vertical,
@@ -59,7 +62,10 @@ fn default_layout_merged_correctly() {
borderless: true,
parts: vec![],
split_size: Some(SplitSize::Fixed(2)),
- run: Some(Run::Plugin(Some("status-bar".into()))),
+ run: Some(Run::Plugin(Some(RunPlugin {
+ path: "status-bar".into(),
+ ..Default::default()
+ }))),
},
],
split_size: None,
@@ -83,7 +89,10 @@ fn default_layout_new_tab_correct() {
borderless: true,
parts: vec![],
split_size: Some(SplitSize::Fixed(1)),
- run: Some(Run::Plugin(Some("tab-bar".into()))),
+ run: Some(Run::Plugin(Some(RunPlugin {
+ path: "tab-bar".into(),
+ ..Default::default()
+ }))),
},
Layout {
direction: Direction::Horizontal,
@@ -97,7 +106,10 @@ fn default_layout_new_tab_correct() {
borderless: true,
parts: vec![],
split_size: Some(SplitSize::Fixed(2)),
- run: Some(Run::Plugin(Some("status-bar".into()))),
+ run: Some(Run::Plugin(Some(RunPlugin {
+ path: "status-bar".into(),
+ ..Default::default()
+ }))),
},
],
split_size: None,
@@ -253,7 +265,10 @@ fn three_panes_with_tab_and_default_plugins_merged_correctly() {
borderless: false,
parts: vec![],
split_size: Some(SplitSize::Fixed(1)),
- run: Some(Run::Plugin(Some("tab-bar".into()))),
+ run: Some(Run::Plugin(Some(RunPlugin {
+ path: "tab-bar".into(),
+ ..Default::default()
+ }))),
},
Layout {
direction: Direction::Vertical,
@@ -297,7 +312,10 @@ fn three_panes_with_tab_and_default_plugins_merged_correctly() {
borderless: false,
parts: vec![],
split_size: Some(SplitSize::Fixed(2)),
- run: Some(Run::Plugin(Some("status-bar".into()))),
+ run: Some(Run::Plugin(Some(RunPlugin {
+ path: "status-bar".into(),
+ ..Default::default()
+ }))),
},
],
split_size: None,
@@ -321,7 +339,10 @@ fn three_panes_with_tab_and_default_plugins_new_tab_is_correct() {
borderless: false,
parts: vec![],
split_size: Some(SplitSize::Fixed(1)),
- run: Some(Run::Plugin(Some("tab-bar".into()))),
+ run: Some(Run::Plugin(Some(RunPlugin {
+ path: "tab-bar".into(),
+ ..Default::default()
+ }))),
},
Layout {
direction: Direction::Horizontal,
@@ -335,7 +356,10 @@ fn three_panes_with_tab_and_default_plugins_new_tab_is_correct() {
borderless: false,
parts: vec![],
split_size: Some(SplitSize::Fixed(2)),
- run: Some(Run::Plugin(Some("status-bar".into()))),
+ run: Some(Run::Plugin(Some(RunPlugin {
+ path: "status-bar".into(),
+ ..Default::default()
+ }))),
},
],
split_size: None,