#ipc #process #channel #serialization #deserialize #tokio #privilege

sandbox-ipc

An IPC implementation with an eye toward enabling privilege separation

5 releases (3 breaking)

Uses old Rust 2015

0.4.0 Aug 29, 2018
0.3.0 Mar 26, 2018
0.2.0 Nov 9, 2017
0.1.1 Oct 17, 2017
0.1.0 Oct 17, 2017

#1524 in Encoding

MIT/Apache

140KB
3K SLoC

sandbox-ipc

A Rust IPC implementation with an eye toward enabling privilege separation.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.


lib.rs:

Convenient and powerful cross-platform IPC primitives, designed with privilege separation in mind.

The core of this crate is the MessageChannel. It not only automatically serializes and deserializes messages via serde, but can even send OS resources like files to other processes. To get started, spawn a child process with MessageChannel::establish_with_child and transmit the initial channel with an environment variable:

extern crate futures;
extern crate tokio;
extern crate sandbox_ipc as ipc;
extern crate serde_json as json;

use std::{fs, env};
use std::process::Command;
use std::io::Write;

use ipc::io::SendableFile;
use futures::prelude::*; 
use tokio::runtime::Runtime;

const CHANNEL_ENV_VAR: &str = "ENV_IPC_CHANNEL";

fn main() {
    // IO operations are done within a Tokio event loop
    let mut core = Runtime::new().unwrap();
    
    let mut child_command = Command::new("some_child_executable");
    let (channel, child) = ipc::MessageChannel::<SendableFile, i32>::establish_with_child(
        &mut child_command, 8192, core.reactor(), |command, child_channel| {
            command
                .env(CHANNEL_ENV_VAR, json::to_string(child_channel).unwrap())
                .spawn()
        }
    ).unwrap();

    let secret_file = fs::File::create("secret_file.txt").unwrap();
    let channel = core.block_on(channel.send(SendableFile(secret_file))).unwrap();

    let (reason, _channel) = core.block_on(channel.into_future()).map_err(|(err, _)| err).unwrap();
    let reason = reason.unwrap();
    assert_eq!(42i32, reason);
}

fn child_main() {
    let mut core = Runtime::new().unwrap();

    let channel: ipc::ChildMessageChannel = 
        json::from_str(&env::var(CHANNEL_ENV_VAR).unwrap()).unwrap();
    let channel = channel.into_channel::<i32, SendableFile>(core.reactor()).unwrap();

    let (secret_file, channel) = core.block_on(channel.into_future())
        .map_err(|(err, _)| err).unwrap();
    let SendableFile(mut secret_file) = secret_file.unwrap();

    write!(&mut secret_file, "psst").unwrap();

    let _channel = core.block_on(channel.send(42i32)).unwrap();
}

Dependencies

~3.5–4.5MB
~87K SLoC