Skip to content

Commit

Permalink
feat(plugin): add exec_cmd helper for executing command in host
Browse files Browse the repository at this point in the history
Signed-off-by: Tw <wei.tan@intel.com>
Signed-off-by: Tw <tw19881113@gmail.com>
  • Loading branch information
tw4452852 authored Sep 9, 2021
1 parent 6d0c5a5 commit 19b3f83
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 23 deletions.
Binary file modified assets/plugins/status-bar.wasm
Binary file not shown.
Binary file modified assets/plugins/strider.wasm
Binary file not shown.
Binary file modified assets/plugins/tab-bar.wasm
Binary file not shown.
9 changes: 7 additions & 2 deletions zellij-server/src/tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
34 changes: 30 additions & 4 deletions zellij-server/src/wasm_vm.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use log::info;
use log::{info, warn};
use std::collections::{HashMap, HashSet};
use std::fs;
use std::path::PathBuf;
Expand Down Expand Up @@ -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,
Expand All @@ -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 --------------------------------------------------------------------------------------------------------
Expand All @@ -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")))
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
}
}

Expand Down Expand Up @@ -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 {
Expand Down
5 changes: 5 additions & 0 deletions zellij-tile/src/shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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();
}
6 changes: 4 additions & 2 deletions zellij-utils/assets/layouts/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ template:
split_size:
Fixed: 1
run:
plugin: tab-bar
plugin:
path: tab-bar
- direction: Vertical
body: true
- direction: Vertical
borderless: true
split_size:
Fixed: 2
run:
plugin: status-bar
plugin:
path: status-bar
tabs:
- direction: Vertical
3 changes: 2 additions & 1 deletion zellij-utils/assets/layouts/disable-status-bar.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ template:
split_size:
Fixed: 1
run:
plugin: tab-bar
plugin:
path: tab-bar
- direction: Vertical
body: true
9 changes: 6 additions & 3 deletions zellij-utils/assets/layouts/strider.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,24 @@ template:
split_size:
Fixed: 1
run:
plugin: tab-bar
plugin:
path: tab-bar
- direction: Vertical
body: true
- direction: Vertical
borderless: true
split_size:
Fixed: 2
run:
plugin: status-bar
plugin:
path: status-bar
tabs:
- direction: Vertical
parts:
- direction: Horizontal
split_size:
Percent: 20
run:
plugin: strider
plugin:
path: strider
- direction: Horizontal
10 changes: 9 additions & 1 deletion zellij-utils/src/input/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
40 changes: 32 additions & 8 deletions zellij-utils/src/input/unit/layout_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand Down

0 comments on commit 19b3f83

Please sign in to comment.