From 62489b3ac311412ef9d744d051142c941539d8b6 Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Tue, 6 Feb 2024 17:48:36 -0500 Subject: [PATCH 01/24] DropCapabilities working in OnExit for scripts --- Cargo.lock | 2 +- kinode/packages/terminal/terminal/Cargo.toml | 2 +- kinode/packages/terminal/terminal/src/lib.rs | 220 ++++++++++++------- kinode/src/kernel/mod.rs | 36 ++- kinode/src/kernel/process.rs | 107 +++++---- lib/src/core.rs | 11 +- 6 files changed, 245 insertions(+), 133 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 74b313af7..144afee19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3312,7 +3312,7 @@ dependencies = [ [[package]] name = "kinode_process_lib" version = "0.5.8" -source = "git+https://github.com/uqbar-dao/process_lib.git?tag=v0.5.9-alpha#09d411dfab23f9049fbbcbef1c56157191269ab2" +source = "git+https://github.com/uqbar-dao/process_lib.git?rev=9668c82#9668c820986e32f7b8430648147c2498d5abb9f8" dependencies = [ "anyhow", "bincode", diff --git a/kinode/packages/terminal/terminal/Cargo.toml b/kinode/packages/terminal/terminal/Cargo.toml index c036ab502..111a3c401 100644 --- a/kinode/packages/terminal/terminal/Cargo.toml +++ b/kinode/packages/terminal/terminal/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] anyhow = "1.0" bincode = "1.3.3" -kinode_process_lib = { git = "https://github.com/uqbar-dao/process_lib.git", tag = "v0.5.9-alpha" } +kinode_process_lib = { git = "https://github.com/uqbar-dao/process_lib.git", rev = "9668c82" } rand = "0.8" regex = "1.10.3" serde = { version = "1.0", features = ["derive"] } diff --git a/kinode/packages/terminal/terminal/src/lib.rs b/kinode/packages/terminal/terminal/src/lib.rs index 3636477f1..cf8348655 100644 --- a/kinode/packages/terminal/terminal/src/lib.rs +++ b/kinode/packages/terminal/terminal/src/lib.rs @@ -18,9 +18,12 @@ wit_bindgen::generate!({ }); #[derive(Debug, Serialize, Deserialize)] -struct EditAliases { - alias: String, - process: Option, +enum TerminalAction { + EditAlias { + alias: String, + process: Option, + }, + ProcessEnded(Vec<(ProcessId, Capability)>), } #[derive(Serialize, Deserialize)] @@ -130,33 +133,30 @@ impl Guest for Component { Ok(()) => continue, Err(e) => println!("terminal: {e}"), } - } else if state.our.node == source.node { - let Ok(edit_aliases) = serde_json::from_slice::(&body) else { - println!("terminal: invalid action!"); + } else if state.our.node == source.node + && state.our.package() == source.package() + { + let Ok(action) = serde_json::from_slice::(&body) else { + println!("terminal: failed to parse action from: {}", source); continue; }; - - match edit_aliases.process { - Some(process) => { - state - .aliases - .insert(edit_aliases.alias.clone(), process.clone()); - println!( - "terminal: alias {} set to {}", - edit_aliases.alias, process - ); + match action { + TerminalAction::EditAlias { alias, process } => { + match handle_alias_change(&mut state, alias, process) { + Ok(()) => continue, + Err(e) => println!("terminal: {e}"), + }; } - None => { - state.aliases.remove(&edit_aliases.alias); - println!("terminal: alias {} removed", edit_aliases.alias); + TerminalAction::ProcessEnded(drop_caps) => { + println!("terminal: process ended: {}", source); + match handle_process_cleanup(drop_caps) { + Ok(()) => continue, + Err(e) => println!("terminal: {e}"), + } } } - if let Ok(new_state) = bincode::serialize(&state) { - set_state(&new_state); - } else { - println!("terminal: failed to serialize state!"); - } } else { + println!("terminal: ignoring message from: {}", source); continue; } } @@ -205,7 +205,7 @@ fn handle_run( }; let wasm_path = format!("{}{}", drive_path, wasm_path); // build initial caps - let process_id = format!("{}:{}", rand::random::(), package); // all scripts are given random process IDs + let process_id = format!("{}:terminal:sys", rand::random::()); // all scripts are given random process IDs let Ok(parsed_new_process_id) = process_id.parse::() else { return Err(anyhow::anyhow!("app store: invalid process id!")); }; @@ -217,13 +217,79 @@ fn handle_run( action: vfs::VfsAction::Read, })?) .send_and_await_response(5)??; + // process the caps we are going to grant to other processes + let mut granted_caps: Vec<(ProcessId, Capability)> = vec![]; + if let Some(to_grant) = &entry.grant_capabilities { + for value in to_grant { + match value { + serde_json::Value::String(process_name) => { + if let Ok(parsed_process_id) = process_name.parse::() { + granted_caps.push(( + parsed_process_id, + Capability { + issuer: Address { + node: our.node.clone(), + process: parsed_new_process_id.clone(), + }, + params: "\"messaging\"".into(), + }, + )); + } + } + serde_json::Value::Object(map) => { + if let Some(process_name) = map.get("process") { + if let Ok(parsed_process_id) = process_name + .as_str() + .unwrap_or_default() + .parse::() + { + if let Some(params) = map.get("params") { + granted_caps.push(( + parsed_process_id, + Capability { + issuer: Address { + node: our.node.clone(), + process: parsed_new_process_id.clone(), + }, + params: params.to_string(), + }, + )); + } + } + } + } + _ => { + continue; + } + } + } + } + for (process, cap) in granted_caps.clone().into_iter() { + Request::new() + .target(("our", "kernel", "distro", "sys")) + .body(serde_json::to_vec(&kt::KernelCommand::GrantCapabilities { + target: process, + capabilities: vec![kt::de_wit_capability(cap)], + })?) + .send()?; + } Request::new() .target(("our", "kernel", "distro", "sys")) .body(serde_json::to_vec(&kt::KernelCommand::InitializeProcess { id: parsed_new_process_id.clone(), wasm_bytes_handle: wasm_path.clone(), wit_version: None, - on_exit: kt::OnExit::None, // TODO this should send a message back to runner:script:sys so that it can Drop capabilities + on_exit: kt::OnExit::Requests(vec![( + kt::de_wit_address(our.clone()), + kt::Request { + inherit: false, + expects_response: None, + body: serde_json::to_vec(&TerminalAction::ProcessEnded(granted_caps))?, + metadata: None, + capabilities: vec![], + }, + None, + )]), initial_capabilities: HashSet::new(), public: entry.public, })?) @@ -269,6 +335,12 @@ fn handle_run( } } } + // always give it the cap to message the terminal back + // NOTE a malicious script could use this to drop a ton of caps from other processes + requested_caps.push(kt::de_wit_capability(Capability { + issuer: our.clone(), + params: "\"messaging\"".to_string(), + })); if entry.request_networking { requested_caps.push(kt::de_wit_capability(Capability { issuer: Address::new(&our.node, ("kernel", "distro", "sys")), @@ -287,7 +359,7 @@ fn handle_run( parsed_new_process_id.clone(), wasm_path.clone(), "None", - kt::OnExit::None, + kt::OnExit::None, // TODO fix this entry.public, { let mut caps_string = "[".to_string(); @@ -305,63 +377,6 @@ fn handle_run( capabilities: requested_caps, })?) .send()?; - if let Some(to_grant) = &entry.grant_capabilities { - for value in to_grant { - match value { - serde_json::Value::String(process_name) => { - if let Ok(parsed_process_id) = process_name.parse::() { - let _ = Request::new() - .target(("our", "kernel", "distro", "sys")) - .body( - serde_json::to_vec(&kt::KernelCommand::GrantCapabilities { - target: parsed_process_id, - capabilities: vec![kt::Capability { - issuer: Address { - node: our.node.clone(), - process: parsed_new_process_id.clone(), - }, - params: "\"messaging\"".into(), - }], - }) - .unwrap(), - ) - .send()?; - } - } - serde_json::Value::Object(map) => { - if let Some(process_name) = map.get("process") { - if let Ok(parsed_process_id) = process_name - .as_str() - .unwrap_or_default() - .parse::() - { - if let Some(params) = map.get("params") { - let _ = Request::new() - .target(("our", "kernel", "distro", "sys")) - .body( - serde_json::to_vec(&kt::KernelCommand::GrantCapabilities { - target: parsed_process_id, - capabilities: vec![kt::Capability { - issuer: Address { - node: our.node.clone(), - process: parsed_new_process_id.clone(), - }, - params: params.to_string(), - }], - }) - .unwrap(), - ) - .send()?; - } - } - } - } - _ => { - continue; - } - } - } - } let _ = Request::new() .target(("our", "kernel", "distro", "sys")) .body(serde_json::to_vec(&kt::KernelCommand::RunProcess( @@ -396,3 +411,40 @@ fn handle_run( Ok(()) } + +fn handle_alias_change( + state: &mut TerminalState, + alias: String, + process: Option, +) -> anyhow::Result<()> { + match process { + Some(process) => { + state.aliases.insert(alias.clone(), process.clone()); + println!("terminal: alias {} set to {}", alias, process); + } + None => { + state.aliases.remove(&alias); + println!("terminal: alias {} removed", alias); + } + } + if let Ok(new_state) = bincode::serialize(&state) { + set_state(&new_state); + Ok(()) + } else { + Err(anyhow!("failed to serialize state!")) + } +} + +fn handle_process_cleanup(caps_to_remove: Vec<(ProcessId, Capability)>) -> anyhow::Result<()> { + for (process, cap) in caps_to_remove { + println!("terminal: cleaning up process {}, {}", process, cap); + Request::new() + .target(("our", "kernel", "distro", "sys")) + .body(serde_json::to_vec(&kt::KernelCommand::DropCapabilities { + target: process, + capabilities: vec![kt::de_wit_capability(cap)], + })?) + .send()?; + } + Ok(()) +} diff --git a/kinode/src/kernel/mod.rs b/kinode/src/kernel/mod.rs index 8e1be6a05..ff34b71d4 100644 --- a/kinode/src/kernel/mod.rs +++ b/kinode/src/kernel/mod.rs @@ -337,6 +337,36 @@ async fn handle_kernel_request( entry.capabilities.extend(signed_caps); let _ = persist_state(&our_name, &send_to_loop, process_map).await; } + t::KernelCommand::DropCapabilities { + target, + capabilities, + } => { + let Some(entry) = process_map.get_mut(&target) else { + let _ = send_to_terminal + .send(t::Printout { + verbosity: 0, + content: format!( + "kernel: no such process {:?} to DropCapabilities", + target + ), + }) + .await; + return; + }; + let _ = send_to_terminal + .send(t::Printout { + verbosity: 0, + content: format!( + "kernel: got DropCapabilities {:?}", + capabilities.clone() + ), + }) + .await; + for cap in capabilities { + entry.capabilities.remove(&cap); + } + let _ = persist_state(&our_name, &send_to_loop, process_map).await; + } // send 'run' message to a process that's already been initialized t::KernelCommand::RunProcess(process_id) => { if let Some(ProcessSender::Userspace(process_sender)) = senders.get(&process_id) { @@ -1058,13 +1088,15 @@ pub async fn kernel( let _ = persist_state(&our.name, &send_to_loop, &process_map).await; let _ = responder.send(true); }, - t::CapMessage::_Drop { on, cap, responder } => { + t::CapMessage::Drop { on, caps, responder } => { // remove cap from process map let Some(entry) = process_map.get_mut(&on) else { let _ = responder.send(false); continue; }; - entry.capabilities.remove(&cap); + for cap in &caps { + entry.capabilities.remove(&cap); + } let _ = persist_state(&our.name, &send_to_loop, &process_map).await; let _ = responder.send(true); }, diff --git a/kinode/src/kernel/process.rs b/kinode/src/kernel/process.rs index 02d355947..3e929d07b 100644 --- a/kinode/src/kernel/process.rs +++ b/kinode/src/kernel/process.rs @@ -597,30 +597,28 @@ pub async fn make_process_loop( }) .collect(); - // send message to tell main kernel loop to remove handler - send_to_loop - .send(t::KernelMessage { - id: rand::random(), - source: our_kernel.clone(), - target: our_kernel.clone(), - rsvp: None, - message: t::Message::Request(t::Request { - inherit: false, - expects_response: None, - body: serde_json::to_vec(&t::KernelCommand::KillProcess( - metadata.our.process.clone(), - )) - .unwrap(), - metadata: None, - capabilities: vec![], - }), - lazy_load_blob: None, - }) - .await?; - // fulfill the designated OnExit behavior match metadata.on_exit { t::OnExit::None => { + send_to_loop + .send(t::KernelMessage { + id: rand::random(), + source: our_kernel.clone(), + target: our_kernel.clone(), + rsvp: None, + message: t::Message::Request(t::Request { + inherit: false, + expects_response: None, + body: serde_json::to_vec(&t::KernelCommand::KillProcess( + metadata.our.process.clone(), + )) + .unwrap(), + metadata: None, + capabilities: vec![], + }), + lazy_load_blob: None, + }) + .await?; let _ = send_to_terminal .send(t::Printout { verbosity: 1, @@ -630,6 +628,25 @@ pub async fn make_process_loop( } // if restart, tell ourselves to init the app again, with same capabilities t::OnExit::Restart => { + send_to_loop + .send(t::KernelMessage { + id: rand::random(), + source: our_kernel.clone(), + target: our_kernel.clone(), + rsvp: None, + message: t::Message::Request(t::Request { + inherit: false, + expects_response: None, + body: serde_json::to_vec(&t::KernelCommand::KillProcess( + metadata.our.process.clone(), + )) + .unwrap(), + metadata: None, + capabilities: vec![], + }), + lazy_load_blob: None, + }) + .await?; if is_error { let _ = send_to_terminal .send(t::Printout { @@ -712,30 +729,36 @@ pub async fn make_process_loop( .await?; for (address, mut request, blob) in requests { request.expects_response = None; - let (tx, rx) = tokio::sync::oneshot::channel(); - caps_oracle - .send(t::CapMessage::Has { - on: metadata.our.process.clone(), - cap: t::Capability { - issuer: address.clone(), - params: "\"messaging\"".into(), - }, - responder: tx, + send_to_loop + .send(t::KernelMessage { + id: rand::random(), + source: metadata.our.clone(), + target: address, + rsvp: None, + message: t::Message::Request(request), + lazy_load_blob: blob, }) .await?; - if let Ok(true) = rx.await { - send_to_loop - .send(t::KernelMessage { - id: rand::random(), - source: metadata.our.clone(), - target: address, - rsvp: None, - message: t::Message::Request(request), - lazy_load_blob: blob, - }) - .await?; - } } + send_to_loop + .send(t::KernelMessage { + id: rand::random(), + source: our_kernel.clone(), + target: our_kernel.clone(), + rsvp: None, + message: t::Message::Request(t::Request { + inherit: false, + expects_response: None, + body: serde_json::to_vec(&t::KernelCommand::KillProcess( + metadata.our.process.clone(), + )) + .unwrap(), + metadata: None, + capabilities: vec![], + }), + lazy_load_blob: None, + }) + .await?; } } Ok(()) diff --git a/lib/src/core.rs b/lib/src/core.rs index d9885be79..a6f39096d 100644 --- a/lib/src/core.rs +++ b/lib/src/core.rs @@ -928,6 +928,11 @@ pub enum KernelCommand { target: ProcessId, capabilities: Vec, }, + /// Drop capabilities. Does nothing if process doesn't have these caps + DropCapabilities { + target: ProcessId, + capabilities: Vec, + }, /// Tell the kernel to run a process that has already been installed. /// TODO: in the future, this command could be extended to allow for /// resource provision. @@ -966,10 +971,10 @@ pub enum CapMessage { caps: Vec, responder: tokio::sync::oneshot::Sender, }, - _Drop { - // not used yet! + /// root delete: uncritically remove all `caps` from `on` + Drop { on: ProcessId, - cap: Capability, + caps: Vec, responder: tokio::sync::oneshot::Sender, }, /// does `on` have `cap` in its store? From b33af8e9581bfb92ebdee425f42d56173bb8c56f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 22:49:07 +0000 Subject: [PATCH 02/24] Format Rust code using rustfmt --- kinode/src/kernel/mod.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/kinode/src/kernel/mod.rs b/kinode/src/kernel/mod.rs index ff34b71d4..1195213f2 100644 --- a/kinode/src/kernel/mod.rs +++ b/kinode/src/kernel/mod.rs @@ -356,10 +356,7 @@ async fn handle_kernel_request( let _ = send_to_terminal .send(t::Printout { verbosity: 0, - content: format!( - "kernel: got DropCapabilities {:?}", - capabilities.clone() - ), + content: format!("kernel: got DropCapabilities {:?}", capabilities.clone()), }) .await; for cap in capabilities { From f34a928667f984a60f44e1da4ba83bbedd63d327 Mon Sep 17 00:00:00 2001 From: doria <93405247+dr-frmr@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:51:54 -0300 Subject: [PATCH 03/24] Update README.md fix clone URL so it works for everyone --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 867acfa80..cb0260a96 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ If you have questions, join the [Kinode discord](https://discord.gg/TCgdca5Bjt) ```bash # Clone the repo. -git clone git@github.com:kinode-dao/kinode.git +git clone https://github.com/kinode-dao/kinode.git # Get some stuff so we can build Wasm. From b31a95ae669d889b319b6d3b92c0d5699cee5a56 Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Wed, 7 Feb 2024 14:08:54 -0500 Subject: [PATCH 04/24] drop_capabilities added to standard_host --- kinode/src/kernel/standard_host.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/kinode/src/kernel/standard_host.rs b/kinode/src/kernel/standard_host.rs index 3e9c30f41..b30022da4 100644 --- a/kinode/src/kernel/standard_host.rs +++ b/kinode/src/kernel/standard_host.rs @@ -398,6 +398,24 @@ impl StandardHost for process::ProcessWasi { Ok(()) } + async fn drop_capabilities(&mut self, caps: Vec) -> Result<()> { + let (tx, rx) = tokio::sync::oneshot::channel(); + let _ = self + .process + .caps_oracle + .send(t::CapMessage::Drop { + on: self.process.metadata.our.process.clone(), + caps: caps + .iter() + .map(|cap| t::de_wit_capability(cap.clone()).0) + .collect(), + responder: tx, + }) + .await?; + let _ = rx.await?; + Ok(()) + } + async fn our_capabilities(&mut self) -> Result> { let (tx, rx) = tokio::sync::oneshot::channel(); let _ = self From 371a31bf28aad79bef29d5cdea86574619541a30 Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Wed, 7 Feb 2024 16:34:01 -0500 Subject: [PATCH 05/24] alias: better printout if alias dne --- kinode/packages/terminal/terminal/src/lib.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/kinode/packages/terminal/terminal/src/lib.rs b/kinode/packages/terminal/terminal/src/lib.rs index cf8348655..93f4c1762 100644 --- a/kinode/packages/terminal/terminal/src/lib.rs +++ b/kinode/packages/terminal/terminal/src/lib.rs @@ -423,8 +423,12 @@ fn handle_alias_change( println!("terminal: alias {} set to {}", alias, process); } None => { - state.aliases.remove(&alias); - println!("terminal: alias {} removed", alias); + if state.aliases.contains_key(&alias) { + state.aliases.remove(&alias); + println!("terminal: alias {} removed", alias); + } else { + println!("terminal: alias {} not found", alias); + } } } if let Ok(new_state) = bincode::serialize(&state) { From c59a6b0b2edd62c8ec6b3d5aa06ba274ac967b83 Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Wed, 7 Feb 2024 16:58:51 -0500 Subject: [PATCH 06/24] alias fixed --- kinode/packages/terminal/alias/src/lib.rs | 14 +++++++----- kinode/packages/terminal/terminal/src/lib.rs | 23 +++++++++++++++++++- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/kinode/packages/terminal/alias/src/lib.rs b/kinode/packages/terminal/alias/src/lib.rs index f7143ffc7..ed6fbca8f 100644 --- a/kinode/packages/terminal/alias/src/lib.rs +++ b/kinode/packages/terminal/alias/src/lib.rs @@ -12,10 +12,12 @@ wit_bindgen::generate!({ }, }); -#[derive(Serialize, Deserialize)] -struct EditAliases { - alias: String, - process: Option, +#[derive(Debug, Serialize, Deserialize)] +enum TerminalAction { + EditAlias { + alias: String, + process: Option, + }, } call_init!(init); @@ -38,7 +40,7 @@ fn init(_our: Address) { let _ = Request::new() .target(("our", "terminal", "terminal", "sys")) .body( - json!(EditAliases { + json!(TerminalAction::EditAlias { alias: alias.to_string(), process: None }) @@ -53,7 +55,7 @@ fn init(_our: Address) { let _ = Request::new() .target(("our", "terminal", "terminal", "sys")) .body( - json!(EditAliases { + json!(TerminalAction::EditAlias { alias: alias.to_string(), process: Some(process) }) diff --git a/kinode/packages/terminal/terminal/src/lib.rs b/kinode/packages/terminal/terminal/src/lib.rs index 93f4c1762..92cf55ec7 100644 --- a/kinode/packages/terminal/terminal/src/lib.rs +++ b/kinode/packages/terminal/terminal/src/lib.rs @@ -137,6 +137,7 @@ impl Guest for Component { && state.our.package() == source.package() { let Ok(action) = serde_json::from_slice::(&body) else { + println!("HERE {}", String::from_utf8(body).unwrap_or_default()); println!("terminal: failed to parse action from: {}", source); continue; }; @@ -148,7 +149,6 @@ impl Guest for Component { }; } TerminalAction::ProcessEnded(drop_caps) => { - println!("terminal: process ended: {}", source); match handle_process_cleanup(drop_caps) { Ok(()) => continue, Err(e) => println!("terminal: {e}"), @@ -419,6 +419,27 @@ fn handle_alias_change( ) -> anyhow::Result<()> { match process { Some(process) => { + // check to make sure the script is actually a script + let drive_path = format!("/{}:{}/pkg", process.package(), process.publisher()); + Request::new() + .target(("our", "vfs", "distro", "sys")) + .body(serde_json::to_vec(&vfs::VfsRequest { + path: format!("{}/scripts.json", drive_path), + action: vfs::VfsAction::Read, + })?) + .send_and_await_response(5)??; + let Some(blob) = get_blob() else { + return Err(anyhow::anyhow!( + "couldn't find /{}/pkg/scripts.json", + process.package() + )); + }; + let dot_scripts = String::from_utf8(blob.bytes)?; + let dot_scripts = + serde_json::from_str::>(&dot_scripts)?; + let Some(_) = dot_scripts.get(&format!("{}.wasm", process.process())) else { + return Err(anyhow::anyhow!("script not in scripts.json file")); + }; state.aliases.insert(alias.clone(), process.clone()); println!("terminal: alias {} set to {}", alias, process); } From dd64718e404aef469ffed8e84f8fa2a356f15cf5 Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Wed, 7 Feb 2024 17:16:35 -0500 Subject: [PATCH 07/24] reversions --- README.md | 2 +- kinode/src/kernel/standard_host.rs | 35 +++++++++++++++--------------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index cb0260a96..867acfa80 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ If you have questions, join the [Kinode discord](https://discord.gg/TCgdca5Bjt) ```bash # Clone the repo. -git clone https://github.com/kinode-dao/kinode.git +git clone git@github.com:kinode-dao/kinode.git # Get some stuff so we can build Wasm. diff --git a/kinode/src/kernel/standard_host.rs b/kinode/src/kernel/standard_host.rs index b30022da4..b4cbaac69 100644 --- a/kinode/src/kernel/standard_host.rs +++ b/kinode/src/kernel/standard_host.rs @@ -398,23 +398,24 @@ impl StandardHost for process::ProcessWasi { Ok(()) } - async fn drop_capabilities(&mut self, caps: Vec) -> Result<()> { - let (tx, rx) = tokio::sync::oneshot::channel(); - let _ = self - .process - .caps_oracle - .send(t::CapMessage::Drop { - on: self.process.metadata.our.process.clone(), - caps: caps - .iter() - .map(|cap| t::de_wit_capability(cap.clone()).0) - .collect(), - responder: tx, - }) - .await?; - let _ = rx.await?; - Ok(()) - } + // TODO 0.6.0 + // async fn drop_capabilities(&mut self, caps: Vec) -> Result<()> { + // let (tx, rx) = tokio::sync::oneshot::channel(); + // let _ = self + // .process + // .caps_oracle + // .send(t::CapMessage::Drop { + // on: self.process.metadata.our.process.clone(), + // caps: caps + // .iter() + // .map(|cap| t::de_wit_capability(cap.clone()).0) + // .collect(), + // responder: tx, + // }) + // .await?; + // let _ = rx.await?; + // Ok(()) + // } async fn our_capabilities(&mut self) -> Result> { let (tx, rx) = tokio::sync::oneshot::channel(); From e3ae30846134296e422d8564de4727379533841c Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Wed, 7 Feb 2024 17:18:51 -0500 Subject: [PATCH 08/24] debug print removed --- kinode/packages/terminal/terminal/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kinode/packages/terminal/terminal/src/lib.rs b/kinode/packages/terminal/terminal/src/lib.rs index 92cf55ec7..d70f9dce2 100644 --- a/kinode/packages/terminal/terminal/src/lib.rs +++ b/kinode/packages/terminal/terminal/src/lib.rs @@ -137,7 +137,6 @@ impl Guest for Component { && state.our.package() == source.package() { let Ok(action) = serde_json::from_slice::(&body) else { - println!("HERE {}", String::from_utf8(body).unwrap_or_default()); println!("terminal: failed to parse action from: {}", source); continue; }; @@ -473,3 +472,5 @@ fn handle_process_cleanup(caps_to_remove: Vec<(ProcessId, Capability)>) -> anyho } Ok(()) } + +fn get_entry() -> anyhow::Result<()> {} From 3e6594f11cb3841f9905c54bf2919c62df81951b Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Wed, 7 Feb 2024 18:45:22 -0500 Subject: [PATCH 09/24] terminal refactor --- Cargo.lock | 23 +++++- kinode/packages/terminal/terminal/Cargo.toml | 2 +- kinode/packages/terminal/terminal/src/lib.rs | 76 +++++++++----------- 3 files changed, 53 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 48f04c1a0..6549b700f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3191,8 +3191,25 @@ dependencies = [ [[package]] name = "kinode_process_lib" -version = "0.5.8" -source = "git+https://github.com/uqbar-dao/process_lib.git?rev=9668c82#9668c820986e32f7b8430648147c2498d5abb9f8" +version = "0.5.9" +source = "git+https://github.com/uqbar-dao/process_lib.git?tag=v0.5.9-alpha#5e705086bbd10fde89e11d3e3671f6a618a875a7" +dependencies = [ + "anyhow", + "bincode", + "http 1.0.0", + "mime_guess", + "rand 0.8.5", + "serde", + "serde_json", + "thiserror", + "url", + "wit-bindgen", +] + +[[package]] +name = "kinode_process_lib" +version = "0.6.0" +source = "git+https://github.com/uqbar-dao/process_lib.git?rev=509b1ed#509b1ed65041762dc6dfa7dd85811b7783c1997c" dependencies = [ "anyhow", "bincode", @@ -5535,7 +5552,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bincode", - "kinode_process_lib 0.5.9 (git+https://github.com/kinode-dao/process_lib?tag=v0.5.9-alpha)", + "kinode_process_lib 0.6.0", "rand 0.8.5", "regex", "serde", diff --git a/kinode/packages/terminal/terminal/Cargo.toml b/kinode/packages/terminal/terminal/Cargo.toml index 111a3c401..a46918194 100644 --- a/kinode/packages/terminal/terminal/Cargo.toml +++ b/kinode/packages/terminal/terminal/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] anyhow = "1.0" bincode = "1.3.3" -kinode_process_lib = { git = "https://github.com/uqbar-dao/process_lib.git", rev = "9668c82" } +kinode_process_lib = { git = "https://github.com/uqbar-dao/process_lib.git", rev = "509b1ed" } rand = "0.8" regex = "1.10.3" serde = { version = "1.0", features = ["derive"] } diff --git a/kinode/packages/terminal/terminal/src/lib.rs b/kinode/packages/terminal/terminal/src/lib.rs index d70f9dce2..414aef517 100644 --- a/kinode/packages/terminal/terminal/src/lib.rs +++ b/kinode/packages/terminal/terminal/src/lib.rs @@ -3,7 +3,7 @@ use kinode_process_lib::kernel_types as kt; use kinode_process_lib::kinode::process::standard as wit; use kinode_process_lib::{ get_blob, get_typed_state, our_capabilities, print_to_terminal, println, set_state, vfs, - Address, Capability, PackageId, ProcessId, Request, + Address, Capability, ProcessId, Request, }; use regex::Regex; use serde::{Deserialize, Serialize}; @@ -70,9 +70,7 @@ fn parse_command(state: &mut TerminalState, line: &str) -> anyhow::Result<()> { None => (args.to_string(), None), }; - let wasm_path = format!("{}.wasm", process.process()); - let package = PackageId::new(process.package(), process.publisher()); - match handle_run(&state.our, &package, wasm_path, pipe.0, pipe.1) { + match handle_run(&state.our, &process, pipe.0, pipe.1) { Ok(_) => Ok(()), // TODO clean up process Err(e) => Err(anyhow!("failed to instantiate script: {}", e)), } @@ -173,28 +171,13 @@ impl Guest for Component { fn handle_run( our: &Address, - package: &PackageId, - wasm_path: String, + process: &ProcessId, args: String, pipe: Option<(String, u64)>, ) -> anyhow::Result<()> { - let drive_path = format!("/{}/pkg", package); - Request::new() - .target(("our", "vfs", "distro", "sys")) - .body(serde_json::to_vec(&vfs::VfsRequest { - path: format!("{}/scripts.json", drive_path), - action: vfs::VfsAction::Read, - })?) - .send_and_await_response(5)??; - let Some(blob) = get_blob() else { - return Err(anyhow::anyhow!( - "couldn't find /{}/pkg/scripts.json", - package - )); - }; - let dot_scripts = String::from_utf8(blob.bytes)?; - let dot_scripts = serde_json::from_str::>(&dot_scripts)?; - let Some(entry) = dot_scripts.get(&wasm_path) else { + let wasm_path = format!("{}.wasm", process.process()); + let drive_path = format!("/{}:{}/pkg", process.package(), process.publisher()); + let Ok(entry) = get_entry(process) else { return Err(anyhow::anyhow!("script not in scripts.json file")); }; let wasm_path = if wasm_path.starts_with("/") { @@ -418,27 +401,11 @@ fn handle_alias_change( ) -> anyhow::Result<()> { match process { Some(process) => { - // check to make sure the script is actually a script - let drive_path = format!("/{}:{}/pkg", process.package(), process.publisher()); - Request::new() - .target(("our", "vfs", "distro", "sys")) - .body(serde_json::to_vec(&vfs::VfsRequest { - path: format!("{}/scripts.json", drive_path), - action: vfs::VfsAction::Read, - })?) - .send_and_await_response(5)??; - let Some(blob) = get_blob() else { - return Err(anyhow::anyhow!( - "couldn't find /{}/pkg/scripts.json", - process.package() - )); - }; - let dot_scripts = String::from_utf8(blob.bytes)?; - let dot_scripts = - serde_json::from_str::>(&dot_scripts)?; - let Some(_) = dot_scripts.get(&format!("{}.wasm", process.process())) else { - return Err(anyhow::anyhow!("script not in scripts.json file")); + // first check to make sure the script is actually a script + let Ok(_) = get_entry(&process) else { + return Err(anyhow!("terminal: process {} not found", process)); }; + state.aliases.insert(alias.clone(), process.clone()); println!("terminal: alias {} set to {}", alias, process); } @@ -473,4 +440,25 @@ fn handle_process_cleanup(caps_to_remove: Vec<(ProcessId, Capability)>) -> anyho Ok(()) } -fn get_entry() -> anyhow::Result<()> {} +fn get_entry(process: &ProcessId) -> anyhow::Result { + let drive_path = format!("/{}:{}/pkg", process.package(), process.publisher()); + Request::new() + .target(("our", "vfs", "distro", "sys")) + .body(serde_json::to_vec(&vfs::VfsRequest { + path: format!("{}/scripts.json", drive_path), + action: vfs::VfsAction::Read, + })?) + .send_and_await_response(5)??; + let Some(blob) = get_blob() else { + return Err(anyhow::anyhow!( + "couldn't find /{}/pkg/scripts.json", + process.package() + )); + }; + let dot_scripts = String::from_utf8(blob.bytes)?; + let dot_scripts = serde_json::from_str::>(&dot_scripts)?; + let Some(entry) = dot_scripts.get(&format!("{}.wasm", process.process())) else { + return Err(anyhow::anyhow!("script not in scripts.json file")); + }; + Ok(entry.clone()) +} From f0c8c2308ca924239af2e26c3dbace2e78d9aefb Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Wed, 7 Feb 2024 18:51:51 -0500 Subject: [PATCH 10/24] debug print removed --- kinode/src/kernel/mod.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/kinode/src/kernel/mod.rs b/kinode/src/kernel/mod.rs index 01424e9b5..3eeab9c7d 100644 --- a/kinode/src/kernel/mod.rs +++ b/kinode/src/kernel/mod.rs @@ -353,12 +353,6 @@ async fn handle_kernel_request( .await; return; }; - let _ = send_to_terminal - .send(t::Printout { - verbosity: 0, - content: format!("kernel: got DropCapabilities {:?}", capabilities.clone()), - }) - .await; for cap in capabilities { entry.capabilities.remove(&cap); } From 4d97def768bef86c0025ad907fbb29edaf6c4337 Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Thu, 8 Feb 2024 10:22:03 -0500 Subject: [PATCH 11/24] caps revoked on process kill --- kinode/packages/terminal/terminal/src/lib.rs | 36 +------------- kinode/src/kernel/mod.rs | 49 ++++++++++++++++++-- lib/src/core.rs | 7 +++ 3 files changed, 55 insertions(+), 37 deletions(-) diff --git a/kinode/packages/terminal/terminal/src/lib.rs b/kinode/packages/terminal/terminal/src/lib.rs index 414aef517..1b740389f 100644 --- a/kinode/packages/terminal/terminal/src/lib.rs +++ b/kinode/packages/terminal/terminal/src/lib.rs @@ -23,7 +23,6 @@ enum TerminalAction { alias: String, process: Option, }, - ProcessEnded(Vec<(ProcessId, Capability)>), } #[derive(Serialize, Deserialize)] @@ -145,12 +144,6 @@ impl Guest for Component { Err(e) => println!("terminal: {e}"), }; } - TerminalAction::ProcessEnded(drop_caps) => { - match handle_process_cleanup(drop_caps) { - Ok(()) => continue, - Err(e) => println!("terminal: {e}"), - } - } } } else { println!("terminal: ignoring message from: {}", source); @@ -261,17 +254,7 @@ fn handle_run( id: parsed_new_process_id.clone(), wasm_bytes_handle: wasm_path.clone(), wit_version: None, - on_exit: kt::OnExit::Requests(vec![( - kt::de_wit_address(our.clone()), - kt::Request { - inherit: false, - expects_response: None, - body: serde_json::to_vec(&TerminalAction::ProcessEnded(granted_caps))?, - metadata: None, - capabilities: vec![], - }, - None, - )]), + on_exit: kt::OnExit::None, initial_capabilities: HashSet::new(), public: entry.public, })?) @@ -318,7 +301,6 @@ fn handle_run( } } // always give it the cap to message the terminal back - // NOTE a malicious script could use this to drop a ton of caps from other processes requested_caps.push(kt::de_wit_capability(Capability { issuer: our.clone(), params: "\"messaging\"".to_string(), @@ -341,7 +323,7 @@ fn handle_run( parsed_new_process_id.clone(), wasm_path.clone(), "None", - kt::OnExit::None, // TODO fix this + kt::OnExit::None, entry.public, { let mut caps_string = "[".to_string(); @@ -426,20 +408,6 @@ fn handle_alias_change( } } -fn handle_process_cleanup(caps_to_remove: Vec<(ProcessId, Capability)>) -> anyhow::Result<()> { - for (process, cap) in caps_to_remove { - println!("terminal: cleaning up process {}, {}", process, cap); - Request::new() - .target(("our", "kernel", "distro", "sys")) - .body(serde_json::to_vec(&kt::KernelCommand::DropCapabilities { - target: process, - capabilities: vec![kt::de_wit_capability(cap)], - })?) - .send()?; - } - Ok(()) -} - fn get_entry(process: &ProcessId) -> anyhow::Result { let drive_path = format!("/{}:{}/pkg", process.package(), process.publisher()); Request::new() diff --git a/kinode/src/kernel/mod.rs b/kinode/src/kernel/mod.rs index 3eeab9c7d..9f4dcacda 100644 --- a/kinode/src/kernel/mod.rs +++ b/kinode/src/kernel/mod.rs @@ -86,6 +86,7 @@ async fn handle_kernel_request( senders: &mut Senders, process_handles: &mut ProcessHandles, process_map: &mut t::ProcessMap, + reverse_cap_index: &mut t::ReverseCapIndex, caps_oracle: t::CapMessageSender, engine: &Engine, ) { @@ -334,7 +335,16 @@ async fn handle_kernel_request( ) }) .collect(); - entry.capabilities.extend(signed_caps); + entry.capabilities.extend(signed_caps.clone()); + // add these to reverse cap index + for (cap, _) in &signed_caps { + reverse_cap_index + .entry(cap.clone().issuer.process) + .or_insert_with(HashMap::new) + .entry(target.clone()) + .or_insert_with(Vec::new) + .push(cap.clone()); + } let _ = persist_state(&our_name, &send_to_loop, process_map).await; } t::KernelCommand::DropCapabilities { @@ -444,7 +454,14 @@ async fn handle_kernel_request( t::KernelCommand::KillProcess(process_id) => { // brutal and savage killing: aborting the task. // do not do this to a process if you don't want to risk - // dropped messages / un-replied-to-requests + // dropped messages / un-replied-to-requests / revoked caps + caps_oracle + .send(t::CapMessage::RevokeAll { + on: process_id.clone(), + responder: tokio::sync::oneshot::channel().0, + }) + .await + .expect("event loop: fatal: sender died"); let _ = senders.remove(&process_id); let process_handle = match process_handles.remove(&process_id) { Some(ph) => ph, @@ -643,6 +660,7 @@ pub async fn kernel( our: t::Identity, keypair: Arc, mut process_map: t::ProcessMap, + mut reverse_cap_index: t::ReverseCapIndex, caps_oracle_sender: t::CapMessageSender, mut caps_oracle_receiver: t::CapMessageReceiver, send_to_loop: t::MessageSender, @@ -1025,6 +1043,7 @@ pub async fn kernel( &mut senders, &mut process_handles, &mut process_map, + &mut reverse_cap_index, caps_oracle_sender.clone(), &engine, ).await; @@ -1081,7 +1100,16 @@ pub async fn kernel( cap.clone(), keypair.sign(&rmp_serde::to_vec(&cap).unwrap()).as_ref().to_vec() )).collect(); - entry.capabilities.extend(signed_caps); + entry.capabilities.extend(signed_caps.clone()); + // now we have to insert all caps into the reverse cap index + for (cap, _) in &signed_caps { + reverse_cap_index + .entry(cap.clone().issuer.process) + .or_insert_with(HashMap::new) + .entry(on.clone()) + .or_insert_with(Vec::new) + .push(cap.clone()); + } let _ = persist_state(&our.name, &send_to_loop, &process_map).await; let _ = responder.send(true); }, @@ -1115,6 +1143,21 @@ pub async fn kernel( } ); }, + t::CapMessage::RevokeAll { on, responder } => { + let Some(granter) = reverse_cap_index.get(&on) else { + let _ = responder.send(true); + continue; + }; + for (grantee, caps) in granter { + let Some(entry) = process_map.get_mut(&grantee) else { + continue; + }; + for cap in caps { + entry.capabilities.remove(&cap); + } + } + let _ = responder.send(true); + } t::CapMessage::FilterCaps { on, caps, responder } => { let _ = responder.send( match process_map.get(&on) { diff --git a/lib/src/core.rs b/lib/src/core.rs index a6f39096d..5188d9dee 100644 --- a/lib/src/core.rs +++ b/lib/src/core.rs @@ -989,6 +989,11 @@ pub enum CapMessage { on: ProcessId, responder: tokio::sync::oneshot::Sender)>>, }, + /// Remove all caps issued by `on` from every process on the entire system + RevokeAll { + on: ProcessId, + responder: tokio::sync::oneshot::Sender, + }, /// before `on` sends a message, filter out any bogus caps it may have attached, sign any new /// caps it may have created, and retreive the signature for the caps in its store. FilterCaps { @@ -998,6 +1003,8 @@ pub enum CapMessage { }, } +pub type ReverseCapIndex = HashMap>>; + pub type ProcessMap = HashMap; #[derive(Clone, Debug, Serialize, Deserialize)] From 88ff12d14ffe3b11c854b865670d1dd703b9444f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 8 Feb 2024 15:22:27 +0000 Subject: [PATCH 12/24] Format Rust code using rustfmt --- kinode/src/kernel/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kinode/src/kernel/mod.rs b/kinode/src/kernel/mod.rs index 9f4dcacda..4dd0ba1d7 100644 --- a/kinode/src/kernel/mod.rs +++ b/kinode/src/kernel/mod.rs @@ -461,7 +461,7 @@ async fn handle_kernel_request( responder: tokio::sync::oneshot::channel().0, }) .await - .expect("event loop: fatal: sender died"); + .expect("event loop: fatal: sender died"); let _ = senders.remove(&process_id); let process_handle = match process_handles.remove(&process_id) { Some(ph) => ph, From 0e4cd175e3ccd1a75d8094748831d14abbffde90 Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Thu, 8 Feb 2024 10:22:25 -0500 Subject: [PATCH 13/24] forgot to commit main --- kinode/src/main.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kinode/src/main.rs b/kinode/src/main.rs index 065cd4467..918dbbcdc 100644 --- a/kinode/src/main.rs +++ b/kinode/src/main.rs @@ -2,6 +2,7 @@ use anyhow::Result; use clap::{arg, value_parser, Command}; +use std::collections::HashMap; use std::env; use std::sync::Arc; use tokio::sync::{mpsc, oneshot}; @@ -445,6 +446,7 @@ async fn main() { our.clone(), networking_keypair_arc.clone(), kernel_process_map.clone(), + HashMap::new(), // TODO need to persist this caps_oracle_sender.clone(), caps_oracle_receiver, kernel_message_sender.clone(), From e69e39f8bbbd3c08f197bf9eb63df5cc2b3c77ba Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Thu, 8 Feb 2024 12:19:53 -0500 Subject: [PATCH 14/24] rebuilding the persisted reverse_cap_index --- kinode/src/main.rs | 5 ++--- kinode/src/state.rs | 21 +++++++++++++++++---- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/kinode/src/main.rs b/kinode/src/main.rs index 918dbbcdc..0512ee921 100644 --- a/kinode/src/main.rs +++ b/kinode/src/main.rs @@ -2,7 +2,6 @@ use anyhow::Result; use clap::{arg, value_parser, Command}; -use std::collections::HashMap; use std::env; use std::sync::Arc; use tokio::sync::{mpsc, oneshot}; @@ -432,7 +431,7 @@ async fn main() { */ let networking_keypair_arc = Arc::new(decoded_keyfile.networking_keypair); - let (kernel_process_map, db) = state::load_state( + let (kernel_process_map, db, reverse_cap_index) = state::load_state( our.name.clone(), networking_keypair_arc.clone(), home_directory_path.clone(), @@ -446,7 +445,7 @@ async fn main() { our.clone(), networking_keypair_arc.clone(), kernel_process_map.clone(), - HashMap::new(), // TODO need to persist this + reverse_cap_index, caps_oracle_sender.clone(), caps_oracle_receiver, kernel_message_sender.clone(), diff --git a/kinode/src/state.rs b/kinode/src/state.rs index 58c332a4a..93f7ebf95 100644 --- a/kinode/src/state.rs +++ b/kinode/src/state.rs @@ -19,7 +19,7 @@ pub async fn load_state( keypair: Arc, home_directory_path: String, runtime_extensions: Vec<(ProcessId, MessageSender, bool)>, -) -> Result<(ProcessMap, DB), StateError> { +) -> Result<(ProcessMap, DB, ReverseCapIndex), StateError> { let state_path = format!("{}/kernel", &home_directory_path); if let Err(e) = fs::create_dir_all(&state_path).await { @@ -37,6 +37,7 @@ pub async fn load_state( // let cf_descriptor = ColumnFamilyDescriptor::new(cf_name, Options::default()); let db = DB::open_default(state_path).unwrap(); let mut process_map: ProcessMap = HashMap::new(); + let mut reverse_cap_index: ReverseCapIndex = HashMap::new(); let kernel_id = process_to_vec(KERNEL_PROCESS_ID.clone()); match db.get(&kernel_id) { @@ -73,11 +74,12 @@ pub async fn load_state( home_directory_path.clone(), runtime_extensions.clone(), &mut process_map, + &mut reverse_cap_index, ) .await .unwrap(); - Ok((process_map, db)) + Ok((process_map, db, reverse_cap_index)) } pub async fn state_sender( @@ -307,6 +309,7 @@ async fn bootstrap( home_directory_path: String, runtime_extensions: Vec<(ProcessId, MessageSender, bool)>, process_map: &mut ProcessMap, + reverse_cap_index: &mut ReverseCapIndex, ) -> Result<()> { // println!("bootstrapping node...\r"); @@ -699,7 +702,12 @@ async fn bootstrap( }; process .capabilities - .insert(cap.clone(), sign_cap(cap, keypair.clone())); + .insert(cap.clone(), sign_cap(cap.clone(), keypair.clone())); + reverse_cap_index.entry(cap.clone().issuer.process) + .or_insert_with(HashMap::new) + .entry(our_process_id.parse().unwrap()) + .or_insert_with(Vec::new) + .push(cap); } } } @@ -719,7 +727,12 @@ async fn bootstrap( }; process .capabilities - .insert(cap.clone(), sign_cap(cap, keypair.clone())); + .insert(cap.clone(), sign_cap(cap.clone(), keypair.clone())); + reverse_cap_index.entry(cap.clone().issuer.process) + .or_insert_with(HashMap::new) + .entry(our_process_id.parse().unwrap()) + .or_insert_with(Vec::new) + .push(cap); } } } From c58f010af736c4be34b5852cca2ecf8825fe7cb6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 8 Feb 2024 17:20:19 +0000 Subject: [PATCH 15/24] Format Rust code using rustfmt --- kinode/src/state.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/kinode/src/state.rs b/kinode/src/state.rs index 93f7ebf95..a4dd06323 100644 --- a/kinode/src/state.rs +++ b/kinode/src/state.rs @@ -703,7 +703,8 @@ async fn bootstrap( process .capabilities .insert(cap.clone(), sign_cap(cap.clone(), keypair.clone())); - reverse_cap_index.entry(cap.clone().issuer.process) + reverse_cap_index + .entry(cap.clone().issuer.process) .or_insert_with(HashMap::new) .entry(our_process_id.parse().unwrap()) .or_insert_with(Vec::new) @@ -725,10 +726,12 @@ async fn bootstrap( }, params: params.to_string(), }; - process - .capabilities - .insert(cap.clone(), sign_cap(cap.clone(), keypair.clone())); - reverse_cap_index.entry(cap.clone().issuer.process) + process.capabilities.insert( + cap.clone(), + sign_cap(cap.clone(), keypair.clone()), + ); + reverse_cap_index + .entry(cap.clone().issuer.process) .or_insert_with(HashMap::new) .entry(our_process_id.parse().unwrap()) .or_insert_with(Vec::new) From 3471951ac78b8ab8b239a7fd7273e9b6192c2c47 Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Thu, 8 Feb 2024 13:02:12 -0500 Subject: [PATCH 16/24] usage strings added to scripts --- kinode/packages/terminal/alias/src/lib.rs | 6 ++++++ kinode/packages/terminal/cat/src/lib.rs | 8 +++++++- kinode/packages/terminal/hi/src/lib.rs | 5 +++++ kinode/packages/terminal/m/src/lib.rs | 5 +++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/kinode/packages/terminal/alias/src/lib.rs b/kinode/packages/terminal/alias/src/lib.rs index ed6fbca8f..925139466 100644 --- a/kinode/packages/terminal/alias/src/lib.rs +++ b/kinode/packages/terminal/alias/src/lib.rs @@ -29,6 +29,12 @@ fn init(_our: Address) { }; let line = String::from_utf8(args).unwrap_or("alias: error".into()); + if line.is_empty() { + println!("Change alias for a process"); + println!("\x1b[1mUsage:\x1b[0m alias "); + return; + } + let (alias, process) = line.split_once(" ").unwrap_or((&line, "")); if alias.is_empty() { diff --git a/kinode/packages/terminal/cat/src/lib.rs b/kinode/packages/terminal/cat/src/lib.rs index 704a51efb..5c065ba76 100644 --- a/kinode/packages/terminal/cat/src/lib.rs +++ b/kinode/packages/terminal/cat/src/lib.rs @@ -19,10 +19,16 @@ fn init(_our: Address) { }; let Ok(file_path) = String::from_utf8(args) else { - println!("bad file path"); + println!("cat: bad args, aborting"); return; }; + if file_path.is_empty() { + println!("Print the contents of a file to the terminal"); + println!("\x1b[1mUsage:\x1b[0m cat "); + return; + } + Request::new() .target(("our", "vfs", "distro", "sys")) .body( diff --git a/kinode/packages/terminal/hi/src/lib.rs b/kinode/packages/terminal/hi/src/lib.rs index 71d090359..35b736640 100644 --- a/kinode/packages/terminal/hi/src/lib.rs +++ b/kinode/packages/terminal/hi/src/lib.rs @@ -19,6 +19,11 @@ fn init(our: Address) { }; let tail = String::from_utf8(args).unwrap(); + if tail.is_empty() { + println!("Send a Message to another node's terminal"); + println!("\x1b[1mUsage:\x1b[0m hi "); + return; + } let (node_id, message) = match tail.split_once(" ") { Some((s, t)) => (s, t), diff --git a/kinode/packages/terminal/m/src/lib.rs b/kinode/packages/terminal/m/src/lib.rs index 573633387..34a468d6c 100644 --- a/kinode/packages/terminal/m/src/lib.rs +++ b/kinode/packages/terminal/m/src/lib.rs @@ -18,6 +18,11 @@ fn init(_our: Address) { return; }; let body_string = String::from_utf8(body).unwrap(); + if body_string.is_empty() { + println!("Send a Request to a Process"); + println!("\x1b[1mUsage:\x1b[0m m [-a ]"); + return; + } let re = Regex::new(r#"'[^']*'|\S+"#).unwrap(); let mut args: Vec = re From 0833489ce7fac97c3b7fa7f3a19f072295015e49 Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Thu, 8 Feb 2024 14:44:19 -0500 Subject: [PATCH 17/24] script processids reverted to use package they come from --- Cargo.lock | 2 +- kinode/packages/terminal/terminal/Cargo.toml | 2 +- kinode/packages/terminal/terminal/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6549b700f..b91430501 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3209,7 +3209,7 @@ dependencies = [ [[package]] name = "kinode_process_lib" version = "0.6.0" -source = "git+https://github.com/uqbar-dao/process_lib.git?rev=509b1ed#509b1ed65041762dc6dfa7dd85811b7783c1997c" +source = "git+https://github.com/uqbar-dao/process_lib.git?rev=e8c2cac#e8c2cac7c4a4ed7ce3b49717ae3fe0ce4ae708d0" dependencies = [ "anyhow", "bincode", diff --git a/kinode/packages/terminal/terminal/Cargo.toml b/kinode/packages/terminal/terminal/Cargo.toml index a46918194..463a05370 100644 --- a/kinode/packages/terminal/terminal/Cargo.toml +++ b/kinode/packages/terminal/terminal/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] anyhow = "1.0" bincode = "1.3.3" -kinode_process_lib = { git = "https://github.com/uqbar-dao/process_lib.git", rev = "509b1ed" } +kinode_process_lib = { git = "https://github.com/uqbar-dao/process_lib.git", rev = "e8c2cac" } rand = "0.8" regex = "1.10.3" serde = { version = "1.0", features = ["derive"] } diff --git a/kinode/packages/terminal/terminal/src/lib.rs b/kinode/packages/terminal/terminal/src/lib.rs index 1b740389f..732fe4c87 100644 --- a/kinode/packages/terminal/terminal/src/lib.rs +++ b/kinode/packages/terminal/terminal/src/lib.rs @@ -180,7 +180,7 @@ fn handle_run( }; let wasm_path = format!("{}{}", drive_path, wasm_path); // build initial caps - let process_id = format!("{}:terminal:sys", rand::random::()); // all scripts are given random process IDs + let process_id = format!("{}:{}", rand::random::(), package); // all scripts are given random process IDs let Ok(parsed_new_process_id) = process_id.parse::() else { return Err(anyhow::anyhow!("app store: invalid process id!")); }; From 4ad3dcbbabd7fb2e72bfab214f15c04650b31939 Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Thu, 8 Feb 2024 14:52:57 -0500 Subject: [PATCH 18/24] serde issues fixed in alias --- kinode/packages/terminal/alias/src/lib.rs | 17 ++++++----------- kinode/packages/terminal/terminal/src/lib.rs | 3 ++- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/kinode/packages/terminal/alias/src/lib.rs b/kinode/packages/terminal/alias/src/lib.rs index 925139466..39acab59e 100644 --- a/kinode/packages/terminal/alias/src/lib.rs +++ b/kinode/packages/terminal/alias/src/lib.rs @@ -2,7 +2,6 @@ use kinode_process_lib::{ await_next_request_body, call_init, println, Address, ProcessId, Request, }; use serde::{Deserialize, Serialize}; -use serde_json::json; wit_bindgen::generate!({ path: "wit", @@ -46,13 +45,11 @@ fn init(_our: Address) { let _ = Request::new() .target(("our", "terminal", "terminal", "sys")) .body( - json!(TerminalAction::EditAlias { + serde_json::to_vec(&TerminalAction::EditAlias { alias: alias.to_string(), - process: None + process: None, }) - .to_string() - .as_bytes() - .to_vec(), + .unwrap(), ) .send(); } else { @@ -61,13 +58,11 @@ fn init(_our: Address) { let _ = Request::new() .target(("our", "terminal", "terminal", "sys")) .body( - json!(TerminalAction::EditAlias { + serde_json::to_vec(&TerminalAction::EditAlias { alias: alias.to_string(), - process: Some(process) + process: Some(process), }) - .to_string() - .as_bytes() - .to_vec(), + .unwrap(), ) .send(); } diff --git a/kinode/packages/terminal/terminal/src/lib.rs b/kinode/packages/terminal/terminal/src/lib.rs index 732fe4c87..98354d9aa 100644 --- a/kinode/packages/terminal/terminal/src/lib.rs +++ b/kinode/packages/terminal/terminal/src/lib.rs @@ -169,7 +169,8 @@ fn handle_run( pipe: Option<(String, u64)>, ) -> anyhow::Result<()> { let wasm_path = format!("{}.wasm", process.process()); - let drive_path = format!("/{}:{}/pkg", process.package(), process.publisher()); + let package = format!("{}:{}", process.package(), process.publisher()); + let drive_path = format!("/{}/pkg", package); let Ok(entry) = get_entry(process) else { return Err(anyhow::anyhow!("script not in scripts.json file")); }; From 78d90aa5dd528e5979e7071af2cf0de21275ebcb Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Thu, 8 Feb 2024 14:57:50 -0500 Subject: [PATCH 19/24] removed unnecessary clone --- kinode/packages/terminal/terminal/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kinode/packages/terminal/terminal/src/lib.rs b/kinode/packages/terminal/terminal/src/lib.rs index 98354d9aa..645ac2065 100644 --- a/kinode/packages/terminal/terminal/src/lib.rs +++ b/kinode/packages/terminal/terminal/src/lib.rs @@ -240,7 +240,7 @@ fn handle_run( } } } - for (process, cap) in granted_caps.clone().into_iter() { + for (process, cap) in granted_caps.into_iter() { Request::new() .target(("our", "kernel", "distro", "sys")) .body(serde_json::to_vec(&kt::KernelCommand::GrantCapabilities { From 3218e98123408150ba23cb1dfd0d8001dbf53e6b Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Thu, 8 Feb 2024 14:59:09 -0500 Subject: [PATCH 20/24] state persists after RevokeAll --- kinode/src/kernel/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/kinode/src/kernel/mod.rs b/kinode/src/kernel/mod.rs index 4dd0ba1d7..f445166dc 100644 --- a/kinode/src/kernel/mod.rs +++ b/kinode/src/kernel/mod.rs @@ -1156,6 +1156,7 @@ pub async fn kernel( entry.capabilities.remove(&cap); } } + let _ = persist_state(&our.name, &send_to_loop, &process_map).await; let _ = responder.send(true); } t::CapMessage::FilterCaps { on, caps, responder } => { From a1208cbd7176563aaa52a710c9749e2da1c38ab4 Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Thu, 8 Feb 2024 15:04:19 -0500 Subject: [PATCH 21/24] updated process_lib to 0.6.0 --- Cargo.lock | 2 +- kinode/packages/terminal/terminal/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b91430501..980a9c88b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3209,7 +3209,7 @@ dependencies = [ [[package]] name = "kinode_process_lib" version = "0.6.0" -source = "git+https://github.com/uqbar-dao/process_lib.git?rev=e8c2cac#e8c2cac7c4a4ed7ce3b49717ae3fe0ce4ae708d0" +source = "git+https://github.com/kinode-dao/process_lib.git?tag=v0.6.0-alpha#4c49368e1945c041dfcabbe15734322012239d25" dependencies = [ "anyhow", "bincode", diff --git a/kinode/packages/terminal/terminal/Cargo.toml b/kinode/packages/terminal/terminal/Cargo.toml index 463a05370..554ddb856 100644 --- a/kinode/packages/terminal/terminal/Cargo.toml +++ b/kinode/packages/terminal/terminal/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] anyhow = "1.0" bincode = "1.3.3" -kinode_process_lib = { git = "https://github.com/uqbar-dao/process_lib.git", rev = "e8c2cac" } +kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib.git", tag = "v0.6.0-alpha" } rand = "0.8" regex = "1.10.3" serde = { version = "1.0", features = ["derive"] } From 6dd455cc8e11b03fd0c4311a1785ed7f1a463a04 Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Thu, 8 Feb 2024 15:07:12 -0500 Subject: [PATCH 22/24] removed .git --- Cargo.lock | 2 +- kinode/packages/terminal/terminal/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 980a9c88b..37e83f1a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3209,7 +3209,7 @@ dependencies = [ [[package]] name = "kinode_process_lib" version = "0.6.0" -source = "git+https://github.com/kinode-dao/process_lib.git?tag=v0.6.0-alpha#4c49368e1945c041dfcabbe15734322012239d25" +source = "git+https://github.com/kinode-dao/process_lib?tag=v0.6.0-alpha#4c49368e1945c041dfcabbe15734322012239d25" dependencies = [ "anyhow", "bincode", diff --git a/kinode/packages/terminal/terminal/Cargo.toml b/kinode/packages/terminal/terminal/Cargo.toml index 554ddb856..43871bdd3 100644 --- a/kinode/packages/terminal/terminal/Cargo.toml +++ b/kinode/packages/terminal/terminal/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] anyhow = "1.0" bincode = "1.3.3" -kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib.git", tag = "v0.6.0-alpha" } +kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", tag = "v0.6.0-alpha" } rand = "0.8" regex = "1.10.3" serde = { version = "1.0", features = ["derive"] } From 923fb10449bb5880fbeb7851dbc45685c3a71df0 Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Thu, 8 Feb 2024 15:08:09 -0500 Subject: [PATCH 23/24] verb 1 --- kinode/src/kernel/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kinode/src/kernel/mod.rs b/kinode/src/kernel/mod.rs index f445166dc..ba0028e90 100644 --- a/kinode/src/kernel/mod.rs +++ b/kinode/src/kernel/mod.rs @@ -354,7 +354,7 @@ async fn handle_kernel_request( let Some(entry) = process_map.get_mut(&target) else { let _ = send_to_terminal .send(t::Printout { - verbosity: 0, + verbosity: 1, content: format!( "kernel: no such process {:?} to DropCapabilities", target From 5c9f09dda679177ed5625e8728d24aa3336986e5 Mon Sep 17 00:00:00 2001 From: Drew Tada Date: Thu, 8 Feb 2024 15:13:24 -0500 Subject: [PATCH 24/24] cleaning --- kinode/packages/terminal/terminal/src/lib.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/kinode/packages/terminal/terminal/src/lib.rs b/kinode/packages/terminal/terminal/src/lib.rs index 645ac2065..0bb426202 100644 --- a/kinode/packages/terminal/terminal/src/lib.rs +++ b/kinode/packages/terminal/terminal/src/lib.rs @@ -183,7 +183,7 @@ fn handle_run( // build initial caps let process_id = format!("{}:{}", rand::random::(), package); // all scripts are given random process IDs let Ok(parsed_new_process_id) = process_id.parse::() else { - return Err(anyhow::anyhow!("app store: invalid process id!")); + return Err(anyhow::anyhow!("terminal: invalid process id!")); }; let _bytes_response = Request::new() @@ -401,12 +401,8 @@ fn handle_alias_change( } } } - if let Ok(new_state) = bincode::serialize(&state) { - set_state(&new_state); - Ok(()) - } else { - Err(anyhow!("failed to serialize state!")) - } + set_state(&bincode::serialize(&state)?); + Ok(()) } fn get_entry(process: &ProcessId) -> anyhow::Result {