### Setup Before Capability Mode in Rust Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/errors.md This example shows essential setup operations, like opening files and defining rights, that must be completed before entering Capsicum capability mode. It includes error handling for file operations and rights limiting. ```rust use capsicum::{FileRights, Right, enter}; use std::fs::File; // All setup that might fail should happen BEFORE entering capability mode let file = File::open("/etc/passwd").expect("Failed to open file before sandboxing"); let mut rights = FileRights::new(); rights.allow(Right::Read).allow(Right::Seek); match rights.limit(&file) { Ok(()) => { if enter().is_ok() { // Now we're sandboxed and rights are applied assert!(capsicum::sandboxed()); } } Err(e) => eprintln!("Failed to restrict file descriptor: {}", e), } ``` -------------------------------- ### Minimum Viable Capsicum Sandboxing Example Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/TECHNICAL-REFERENCE.md A comprehensive example showing the setup, capability restriction, entering a sandbox, and using the sandboxed environment. This snippet illustrates the core workflow for sandboxing with capsicum-rs. ```rust use capsicum::{enter, sandboxed, FileRights, Right}; use std::fs::File; use std::io::Read; fn main() -> std::io::Result<()> { // 1. Setup: Open files before sandboxing let mut config = File::open("/etc/config")?; // 2. Optional: Restrict capabilities FileRights::new() .allow(Right::Read) .limit(&config)?; // 3. Enter sandbox (one-way) enter()?; assert!(sandboxed()); // 4. Use sandboxed environment let mut buf = String::new(); config.read_to_string(&mut buf)?; println!("Config: {}", buf); Ok(()) } ``` -------------------------------- ### Compiling and Running Capsicum Example Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/TECHNICAL-REFERENCE.md Command to compile and run the capsicum-rs example on a FreeBSD system using a specific target architecture. ```bash $ cargo run --target x86_64-unknown-freebsd ``` -------------------------------- ### Migrate from FcntlsBuilder to FcntlRights Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/deprecated.md Example showing the transition from the deprecated `FcntlsBuilder` to the `FcntlRights` API for managing file control operations. ```rust // Old code let rights = FcntlsBuilder::new(Fcntl::GetFL) .add(Fcntl::SetFL) .finalize(); // New code let mut rights = FcntlRights::new(); rights.allow(Fcntl::GetFL).allow(Fcntl::SetFL); ``` -------------------------------- ### Casper ServiceRegisterFlags Example Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/casper.md Demonstrates how to instantiate ServiceRegisterFlags. Flags control service behavior during registration. ```rust use capsicum::casper::ServiceRegisterFlags; let flags = ServiceRegisterFlags::FD; ``` -------------------------------- ### Initialize and Enter Capability Mode with Casper Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/TECHNICAL-REFERENCE.md Demonstrates initializing Casper, forking, and entering capability mode. This setup is required for operations needing global namespace access. Ensure single-threaded execution during initialization. ```rust #[cfg(feature = "casper")] fn example() -> std::io::Result<()> { use capsicum::casper::Casper; // Initialize Casper (must be single-threaded at this point) let mut casper = unsafe { Casper::new()? }; // Fork Casper and self, then enter capability mode capsicum::enter()?; // Use Casper services (via generated helper functions) // Example: connect to system.pwd service // let mut pwd = casper.pwd()?; // Requires service_connection! macro Ok(()) } ``` -------------------------------- ### Connect to a System Service with Casper Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/casper.md Use the `casper::service_connection!` macro to define a type for connecting to a system service. This example shows how to connect to the `system.pwd` service and obtain a `Casper` handle. ```rust use capsicum::casper; casper::service_connection!( pub CapSystemUserAgent, c"system.pwd", pwd ); fn main() { unsafe { let mut casper = capsicum::casper::Casper::new().unwrap(); // Open connection to system.pwd service let mut pwd_service = casper.pwd().unwrap(); // Communicate with the service using xfer_nvlist // (service-specific protocol not shown) } } ``` -------------------------------- ### Deprecated RightsBuilder Example Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/deprecated.md Demonstrates the deprecated pattern of using `RightsBuilder` to construct file rights. The modern alternative uses `FileRights` directly. ```rust use capsicum::{Right, RightsBuilder}; let rights = RightsBuilder::new() .allow(Right::Read) .allow(Right::Seek) .finalize(); ``` -------------------------------- ### Migrate from RightsBuilder to FileRights Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/deprecated.md Example demonstrating the migration from the deprecated `RightsBuilder` to the current `FileRights` API for managing file permissions. ```rust // Old code let rights = RightsBuilder::new() .allow(Right::Read) .allow(Right::Write) .finalize(); // New code let mut rights = FileRights::new(); rights.allow(Right::Read).allow(Right::Write); ``` -------------------------------- ### Implementing EchoService Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/casper.md Example implementation of the `Service` trait for an `EchoService`. This service echoes received `NvList` data when the command is 'echo'. ```rust use capsicum::casper::Service; use libnv::libnv::NvList; use std::ffi::CStr; use std::io; struct EchoService; impl Service for EchoService { const SERVICE_NAME: &'static CStr = c"echo"; fn cmd(cmd: &str, _: Option<&NvList>, nvin: Option<&mut NvList>, nvout: &mut NvList) -> io::Result<()> { if cmd == "echo" { if let Some(nvl) = nvin { nvl.clone_to(nvout)?; } } Ok(()) } } ``` -------------------------------- ### Deprecated Struct Example Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/configuration.md Illustrates a deprecated struct used for backwards compatibility, with a note to use 'FileRights' directly. ```rust #[deprecated(since = "0.4.0", note = "Use FileRights directly")] pub struct RightsBuilder(cap_rights_t) ``` -------------------------------- ### Restricting File Rights with FileRights::limit() Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/file-rights.md Demonstrates how to use FileRights::limit() to restrict read access to a file. This example shows setting read rights, applying the limit to a file descriptor, and then verifying that read operations succeed while implicitly showing that other operations (like write) would fail. ```rust use capsicum::{FileRights, Right}; use std::fs::File; use std::io::Read; let mut file = File::open("/etc/passwd").unwrap(); let mut rights = FileRights::new(); rights.allow(Right::Read); rights.limit(&file).unwrap(); capsicum::enter().unwrap(); let mut buf = vec![0u8; 100]; assert!(file.read(&mut buf).is_ok()); // Read allowed // Write would fail because we didn't allow Right::Write ``` -------------------------------- ### Retrieve IoctlRights from a file descriptor Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/ioctl-rights.md Use IoctlRights::from_file() to get the current ioctl restrictions from a file descriptor. This requires a file descriptor and a size hint for the buffer. The example demonstrates setting rights and then retrieving them. ```rust use capsicum::IoctlsBuilder; use tempfile::tempfile; let file = tempfile().unwrap(); let rights = IoctlsBuilder::new() .allow(libc::TIOCGETD) .finalize(); rights.limit(&file).unwrap(); // Retrieve the restrictions (with a reasonable size hint) let retrieved = IoctlRights::from_file(&file, 100).unwrap(); ``` -------------------------------- ### Casper::new() Errors Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/errors.md Documents the errors for `Casper::new()`, which initializes a new Casper instance. Errors can arise from OS errors during the `cap_init()` system call or issues with fork/IPC setup. ```APIDOC ## Casper::new() (Feature: casper) ### Description Initializes a new Casper instance. ### Method `pub unsafe fn new() -> io::Result` ### Possible Errors - OS errors from `cap_init()` system call - Typically fails if fork fails or IPC setup fails ``` -------------------------------- ### Restricting ioctls with IoctlsBuilder and limit() Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/ioctl-rights.md This example demonstrates how to use IoctlsBuilder to define a set of allowed ioctl commands (specifically FIONREAD) and then apply these restrictions to a temporary file descriptor using the rights.limit() method. It also shows how to verify that an allowed ioctl operation succeeds after the restrictions are applied. ```rust use capsicum::IoctlsBuilder; use std::os::unix::io::AsRawFd; use nix::ioctl_read; use tempfile::tempfile; const FIONREAD: libc::c_ulong = libc::FIONREAD; ioctl_read!(fionread_cmd, b'f', 127, libc::c_int); let file = tempfile().unwrap(); let rights = IoctlsBuilder::new() .allow(FIONREAD) .finalize(); rights.limit(&file).unwrap(); capsicum::enter().unwrap(); // FIONREAD is allowed let mut n: libc::c_int = 0; unsafe { fionread_cmd(file.as_raw_fd(), &mut n as *mut _) }.unwrap(); ``` -------------------------------- ### IoctlsBuilder::new() Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/ioctl-rights.md Creates a new builder for constructing ioctl rights with an empty initial list. This is the starting point for defining allowed ioctl commands. ```APIDOC ## IoctlsBuilder::new() ### Description Creates a new builder for constructing ioctl rights with an empty initial list. ### Returns `IoctlsBuilder` — A new empty ioctl builder. ### Example ```rust use capsicum::IoctlsBuilder; let builder = IoctlsBuilder::new(); ``` ``` -------------------------------- ### Create New IoctlsBuilder Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/ioctl-rights.md Creates a new builder for constructing ioctl rights with an empty initial list. Use this to start defining allowed ioctl commands. ```rust use capsicum::IoctlsBuilder; let builder = IoctlsBuilder::new(); ``` -------------------------------- ### Build IoctlRights with finalize() Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/ioctl-rights.md Use IoctlsBuilder to construct an IoctlRights object and finalize it. This example shows how to allow a specific ioctl command. ```rust use capsicum::IoctlsBuilder; let rights = IoctlsBuilder::new() .allow(libc::TIOCGETD) .finalize(); ``` -------------------------------- ### Rust: Casper::new() Signature (Feature: casper) Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/errors.md This unsafe function signature can return OS errors from the cap_init() system call. It typically fails if fork fails or IPC setup fails. ```rust pub unsafe fn new() -> io::Result ``` -------------------------------- ### Initializing and Using Casper Services Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/module-index.md Shows the steps to initialize a Casper service and send commands to it. This requires unsafe initialization and uses macro-generated methods for service interaction. ```rust use capsicum::casper::Casper; // 1. Initialize Casper: unsafe { Casper::new()? } let casper = unsafe { Casper::new()? }; // 2. Open service: casper.service_name() (via macro-generated method) // let service = casper.service_name(); // 3. Send commands: service.xfer_nvlist(nvlist)? // let nvlist = ...; // service.xfer_nvlist(nvlist)?; ``` -------------------------------- ### Cargo Documentation with All Features Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/configuration.md Generates documentation for the project, enabling all features for a specific target, and opens it in a browser. ```bash cargo doc --target x86_64-unknown-freebsd --all-features --open ``` -------------------------------- ### Get Capability Mode Status Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/module-index.md Safely queries the capability mode status of the current process. Returns a Result. ```rust fn get_mode() -> io::Result ``` -------------------------------- ### Enter Capability Mode in Rust Source: https://github.com/dlrobertson/capsicum-rs/blob/main/README.md Demonstrates entering capability mode and verifying sandboxing. File operations attempted after entering capability mode should fail if not previously allowed. ```rust use capsicum::{enter, sandboxed}; use std::fs::File; use std::io::Read; let mut ok_file = File::open("/tmp/foo").unwrap(); let mut s = String::new(); enter().expect("enter failed!"); assert!(sandboxed(), "application is not sandboxed!"); match File::create("/tmp/cant_touch_this") { Ok(_) => panic!("application is not properly sandboxed!"), Err(e) => println!("properly sandboxed: {:?}", e) } match ok_file.read_to_string(&mut s) { Ok(_) => println!("This is okay since we opened the descriptor before sandboxing"), Err(_) => panic!("application is not properly sandboxed!") } ``` -------------------------------- ### Restrict ioctl Commands Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/README.md Use `IoctlsBuilder` to specify allowed `ioctl` commands for a file descriptor. This example permits the `TIOCGETD` command. ```rust use capsicum::IoctlsBuilder; let rights = IoctlsBuilder::new() .allow(libc::TIOCGETD) .finalize(); rights.limit(&fd?); ``` -------------------------------- ### Enter Capability Mode Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/README.md Use the `enter` function to transition the current process into capability mode. After entering, `sandboxed()` will return true. This is a one-way operation. ```rust use capsicum::enter; enter()?; // One-way operation assert!(capsicum::sandboxed()); ``` -------------------------------- ### Initialize Casper Service Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/README.md Use `Casper::new()` to initialize a handle to the Casper daemon. This requires the `casper` feature to be enabled. Interaction with Casper services is typically done via macro-generated methods. ```rust use capsicum::casper::Casper; unsafe { let mut casper = Casper::new()?; } // Use via macro-generated service methods ``` -------------------------------- ### Retrieve File Rights Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/file-rights.md Get the current capability rights enforced on an open file descriptor. This is useful for auditing or verifying applied restrictions. ```rust use capsicum::{FileRights, Right}; use tempfile::tempfile; let file = tempfile().unwrap(); let mut rights = FileRights::new(); rights.allow(Right::Read).allow(Right::Seek); rights.limit(&file).unwrap(); let retrieved = FileRights::from_file(&file).unwrap(); assert_eq!(rights, retrieved); ``` -------------------------------- ### Enter Capability Mode in Rust Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/TECHNICAL-REFERENCE.md Demonstrates the basic workflow for entering capability mode. Ensure all necessary files are opened before entering the sandbox, as subsequent file operations will be restricted. The `sandboxed()` function can be used to check if the process is currently in capability mode. ```rust use capsicum::{enter, sandboxed, FileRights, Right}; use std::fs::File; use std::io::Read; fn main() -> std::io::Result<()> { // Step 1: Open all files before entering sandbox let mut file = File::open("/etc/passwd")?; // Step 2: Limit capabilities (optional but recommended) let mut rights = FileRights::new(); rights.allow(Right::Read).allow(Right::Seek); rights.limit(&file)?; // Step 3: Enter capability mode (one-way operation) enter()?; assert!(sandboxed()); // Step 4: Use the sandboxed process let mut buf = vec![0u8; 1024]; file.read_exact(&mut buf[..])?; // Attempting to open new files will fail: let err = File::open("/tmp/newfile"); assert!(err.is_err()); Ok(()) } ``` -------------------------------- ### Restrict fcntl Commands Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/README.md Use `FcntlRights` to limit the `fcntl` system calls that can be performed on a file descriptor. This example only allows querying file flags. ```rust use capsicum::{FcntlRights, Fcntl}; let mut rights = FcntlRights::new(); rights.allow(Fcntl::GetFL); // Only allow querying flags rights.limit(&file?); ``` -------------------------------- ### Modern FcntlRights Initialization Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/deprecated.md Shows the modern alternative to FcntlsBuilder using FcntlRights for constructing fcntl command restrictions. This is the recommended approach. ```rust use capsicum::{Fcntl, FcntlRights}; let mut rights = FcntlRights::new(); rights.allow(Fcntl::GetFL).allow(Fcntl::SetFL); ``` -------------------------------- ### Retrieve FcntlRights from File Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/fcntl-rights.md Use `FcntlRights::from_file()` to get the currently enforced fcntl restrictions from an existing file descriptor. This requires the file descriptor to implement `AsFd`. ```rust use capsicum::{FcntlRights, Fcntl}; use tempfile::tempfile; let file = tempfile().unwrap(); let mut rights = FcntlRights::new(); rights.allow(Fcntl::GetFL); rights.limit(&file).unwrap(); let retrieved = FcntlRights::from_file(&file).unwrap(); assert_eq!(rights, retrieved); ``` -------------------------------- ### Specify Documentation Targets for Docs.rs Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/configuration.md Configure the documentation build on docs.rs to target specific platform triples, such as FreeBSD. ```toml [package.metadata.docs.rs] targets = [ "x86_64-unknown-freebsd", ] ``` -------------------------------- ### Initialize RightsBuilder (Deprecated) Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/deprecated.md Initializes a new `RightsBuilder` with no rights. This pattern is deprecated; use `FileRights::new()` instead. ```rust pub fn new() -> RightsBuilder ``` -------------------------------- ### Clone and Build capsicum-rs Source: https://github.com/dlrobertson/capsicum-rs/blob/main/README.md Standard procedure to clone the repository and build the project using Cargo. ```bash git clone https://github.com/danlrobertson/capsicum-rs cd capsicum-rs cargo build ``` -------------------------------- ### Configure docs.rs Metadata Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/configuration.md Set metadata for docs.rs to enable all features, add rustdoc arguments, and specify build targets. ```toml [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] targets = [ "x86_64-unknown-freebsd", ] ``` -------------------------------- ### Configure Files to Include in Package Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/configuration.md Specify which files and directories should be included when publishing the package to crates.io. ```toml include = [ "src/**/*", "test/**/*", "build.rs", "LICENSE", "README.md", "CHANGELOG.md" ] ``` -------------------------------- ### Using cap-std for Ambient Capabilities Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/TECHNICAL-REFERENCE.md Demonstrates how to use the cap-std crate to access ambient capabilities and open directories in a sandboxed environment. This approach is more ergonomic than using the raw capsicum API directly. ```rust use cap_std::ambient_authority; use cap_std::fs::Dir; // In capability mode let aa = ambient_authority(); // Requires separate safety argument let etc = Dir::open_ambient_dir("/etc", aa)?; let passwd = etc.open("passwd")?; ``` -------------------------------- ### Enter Capability Mode Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/INDEX.md Call the `enter` function to transition the current process into capability mode. This is a global operation for the process. ```rust use capsicum::enter; enter()?; ``` -------------------------------- ### Minimal Cargo Build Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/configuration.md Compiles the project with default settings for a specific target. ```bash cargo build --target x86_64-unknown-freebsd ``` -------------------------------- ### Check for ENOSYS (No Capability Support) Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/errors.md Shows how to check if the FreeBSD kernel supports capability mode by examining the error returned by `get_mode()` for ENOSYS. ```rust use capsicum::get_mode; match get_mode() {{ Ok(_) => {{ /* Capability support available */ }} Err(e) if e.raw_os_error() == Some(libc::ENOSYS) => {{ eprintln!("Capability mode not supported by kernel"); }} Err(e) => {{ /* Other error */ }} }} ``` -------------------------------- ### Initialize Casper Connection Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/casper.md Initializes a connection to the Casper daemon and forks the Casper service process. Must be called early, before spawning threads. Returns a handle to Casper or an OS error. ```rust use capsicum::casper::Casper; fn main() { // Must be called early, before spawning threads let mut casper = unsafe { Casper::new() }.expect("Failed to initialize Casper"); // Now safe to proceed with capability mode and multi-threading } ``` -------------------------------- ### IoctlRights::from_file() Errors Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/errors.md Explains the errors for `IoctlRights::from_file()`, which creates `IoctlRights` from a file descriptor. Errors include invalid file descriptors, OS errors from `cap_ioctls_get(2)`, and potential panics. ```APIDOC ## IoctlRights::from_file() ### Description Creates `IoctlRights` from a file descriptor. ### Method `IoctlRights::from_file(f: &F, len: usize) -> io::Result` ### Possible Errors - `EBADF` — Invalid file descriptor - Other OS errors from `cap_ioctls_get(2)` - Panics if kernel returns more ioctls than the provided buffer size ``` -------------------------------- ### Casper Methods Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/module-index.md Methods for interacting with the Casper functionality, including initialization, cloning, and opening services. ```APIDOC ## Casper Methods (Feature: casper) ### `Casper::new()` #### Description Initialize Casper. This operation is unsafe as it may fork. #### Signature `unsafe fn() -> io::Result` ### `Casper::try_clone()` #### Description Clone the Casper handle. #### Signature `fn(&mut self) -> io::Result` ### `Casper::service_open()` #### Description Open a service associated with Casper. #### Signature `fn(&mut self, &CStr) -> io::Result` ### `Service::cmd()` #### Description Handle a service command. Safety is implementation-defined. #### Signature (trait method) ### `Service::limit()` #### Description Handle a restriction for a service. Safety is implementation-defined. #### Signature (trait method) ``` -------------------------------- ### Limit File Rights in Rust Source: https://github.com/dlrobertson/capsicum-rs/blob/main/README.md Shows how to create a set of capabilities for a file descriptor, including conditionally adding read rights, and then limiting the file's rights. ```rust use capsicum::{CapRights, Right, RightsBuilder}; use std::fs::File; use std::io::Read; let x = rand::random::(); let mut ok_file = File::open("/tmp/foo").unwrap(); let mut s = String::new(); let mut builder = RightsBuilder::new(Right::Seek); if x { builder.add(Right::Read); } let rights = builder.finalize().unwrap(); rights.limit(&ok_file).unwrap(); match ok_file.read_to_string(&mut s) { Ok(_) if x => println!("Allowed reading: x = {} ", x), Err(_) if !x => println!("Did not allow reading: x = {}", x), _ => panic!("Not properly sandboxed"), } ``` -------------------------------- ### service! Macro Definition Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/module-index.md Defines a macro for generating service structs, which includes creating a service connection and registering with the Casper daemon. Requires the 'casper' feature. ```rust #[macro_export] macro_rules! service { ( $(#[$attr:meta])* $vis:vis $sstruct:ident, $astruct:ident, $meth:ident, $flags:expr ) => { ... } } ``` -------------------------------- ### Casper::service_open() Errors Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/errors.md Explains the errors for `Casper::service_open()`, which opens a service channel. Errors can stem from OS errors during `cap_service_open()`, service unavailability, or permission issues. ```APIDOC ## Casper::service_open() (Feature: casper) ### Description Opens a service channel for communication. ### Method `pub fn service_open(&mut self, name: &CStr) -> io::Result` ### Possible Errors - OS errors from `cap_service_open()` system call - Service does not exist or is not accessible - Permission denied for the requested service ``` -------------------------------- ### Setting File Rights with Capsicum Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/right-enum.md Demonstrates how to use the `FileRights` and `Right` enums to set read and seek permissions on a file. Ensure the `capsicum` crate is imported. ```rust use capsicum::{FileRights, Right}; use std::fs::File; let mut file = File::open("/etc/passwd").unwrap(); let mut rights = FileRights::new(); rights.allow(Right::Read).allow(Right::Seek); rights.limit(&file).unwrap(); ``` -------------------------------- ### Deprecated FcntlsBuilder Initialization Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/deprecated.md Demonstrates the deprecated pattern for initializing FcntlsBuilder with fcntl commands. Use FcntlRights directly for modern applications. ```rust use capsicum::{Fcntl, FcntlsBuilder}; let rights = FcntlsBuilder::new(Fcntl::GetFL) .add(Fcntl::SetFL) .finalize(); ``` -------------------------------- ### Enter Capability Mode Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/module-index.md Use this function to enter capability mode. It returns a Result indicating success or failure. ```rust fn enter() -> io::Result<()> ``` -------------------------------- ### Use Feature Gates for Documentation Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/configuration.md Conditionally compile documentation for specific features using `#[cfg]` and `#[cfg_attr]` attributes. ```rust #[cfg(feature = "casper")] #[cfg_attr(docsrs, doc(cfg(feature = "casper")))] pub mod casper; ``` -------------------------------- ### FcntlRights::new() Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/fcntl-rights.md Creates a new FcntlRights structure with no fcntl commands allowed by default. ```APIDOC ## FcntlRights::new() ### Description Creates a new `FcntlRights` structure with no fcntl commands allowed. ### Returns `FcntlRights` — A new empty fcntl rights structure. ### Example ```rust use capsicum::FcntlRights; let rights = FcntlRights::new(); ``` ``` -------------------------------- ### Casper::new() Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/casper.md Initializes a connection to the Casper daemon and forks the Casper service process. This function must be called when the program is single-threaded. ```APIDOC ## Casper::new() ### Description Initializes a connection to the Casper daemon and forks the Casper service process. ### Method `unsafe fn new() -> io::Result` ### Parameters (none) ### Returns `io::Result` — A handle to Casper, or OS error. ### Safety Must be called when the program is single-threaded. It is safe to spawn threads after this call completes. ### Errors - OS errors from the underlying `cap_init()` system call ### Example ```rust use capsicum::casper::Casper; fn main() { // Must be called early, before spawning threads let mut casper = unsafe { Casper::new() }.expect("Failed to initialize Casper"); // Now safe to proceed with capability mode and multi-threading } ``` ``` -------------------------------- ### Migrate from Directory to cap_std::fs::Dir Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/deprecated.md Illustrates the migration from the `capsicum::util::Directory` type to `cap_std::fs::Dir` for directory operations. ```rust // Old code use capsicum::util::Directory; let dir = Directory::new("./src")?; let file = dir.open_file("lib.rs", libc::O_RDONLY, None)?; // New code use cap_std::ambient_authority; use cap_std::fs::Dir; let aa = ambient_authority(); let dir = Dir::open_ambient_dir("./src", aa)?; let file = dir.open("lib.rs")?; ``` -------------------------------- ### Entry Points for New Sandboxing in Capsicum Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/module-index.md Illustrates the sequence of operations for entering a sandboxed environment. This involves opening files, building rights, limiting them, and then entering the sandboxed mode. ```rust use capsicum::enter; use capsicum::right::{FileRights, Right}; // 1. Open files before capability mode: std::fs::File::open() let file = std::fs::File::open("some_file.txt")?; // 2. Build rights: FileRights::new().allow(Right::Read).allow(Right::Seek) let rights = FileRights::new().allow(Right::Read).allow(Right::Seek); // 3. Apply rights: rights.limit(&file)? rights.limit(&file)?; // 4. Enter mode: enter()? enters()?; ``` -------------------------------- ### Create New FcntlRights Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/fcntl-rights.md Use `FcntlRights::new()` to create a new structure with no fcntl commands initially allowed. ```rust use capsicum::FcntlRights; let rights = FcntlRights::new(); ``` -------------------------------- ### service! Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/casper.md Declares a custom Casper service implementation. It generates a struct for accessing the service, an `impl Service for Casper` extension trait, and a module-level initializer to register the service. This macro is used when you want to implement your own service that can be managed by Casper. ```APIDOC ## service! ### Description Declares a custom Casper service implementation. ### Method Signature ```rust #[macro_export] macro_rules! service!( $(#[$attr:meta])* $vis:vis $sstruct:ident, $astruct:ident, $meth:ident, $flags:expr ) ``` ### Arguments - `vis`: Visibility of the generated struct. - `sstruct`: Name of struct implementing `Service` trait. - `astruct`: Name of the generated struct that accesses the service. - `meth`: Name of the accessor method to add to `Casper`. - `flags`: `ServiceRegisterFlags` controlling behavior. ### Generates - A struct for accessing the service (same as `service_connection!`). - An `impl Service for Casper` extension trait. - A module-level initializer that registers the service with Casper. ### Example ```rust use capsicum::casper::{self, Service}; use libnv::libnv::NvList; use std::ffi::CStr; use std::io; struct MyCustomService; impl Service for MyCustomService { const SERVICE_NAME: &'static CStr = c"my.custom"; fn cmd(cmd: &str, limits: Option<&NvList>, nvin: Option<&mut NvList>, nvout: &mut NvList) -> io::Result<()> { // Handle commands Ok(()) } fn limit(_oldlimits: Option<&NvList>, _newlimits: Option<&NvList>) -> io::Result<()> { Ok(()) } } casper::service!(MyCustomService, MyServiceAgent, my_service, casper::ServiceRegisterFlags::NONE); ``` ``` -------------------------------- ### IoctlRights Methods Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/module-index.md Methods for querying and applying ioctl rights to a file. ```APIDOC ## IoctlRights Methods ### `from_file()` #### Description Query the ioctl rights of a file. #### Signature `fn(f: &F, len: usize) -> io::Result` ### `limit()` #### Description Apply these ioctl rights to a file. #### Signature `fn(&self, f: &F) -> io::Result<()>` ``` -------------------------------- ### Configure Build Script in Cargo.toml Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/configuration.md Specifies the build script to be executed during the build process. This is typically used for compile-time configuration. ```toml [package] build = "build.rs" ``` -------------------------------- ### Rust: Casper::service_open() Signature (Feature: casper) Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/errors.md This function signature can return OS errors from the cap_service_open() system call. It may also fail if the service does not exist, is inaccessible, or if permission is denied for the requested service. ```rust pub fn service_open(&mut self, name: &CStr) -> io::Result ``` -------------------------------- ### Query Capability Mode with Error Handling Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/process.md Queries the kernel for the process's capability mode status. This is a more formal alternative to `sandboxed()` that can report system errors, such as when the kernel lacks capability support (ENOSYS). ```rust use capsicum::{enter, get_mode}; match get_mode() { Ok(in_sandbox) => { println!("Capability mode: {}", in_sandbox); enter().unwrap(); let (in_sandbox2, _) = get_mode().unwrap(); assert!(in_sandbox2); } Err(e) => eprintln!("Capability support not available: {}", e), } ``` -------------------------------- ### enter() Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/process.md Enters capability mode for the current process. After calling this function, the process loses access to global namespaces and can only operate on file descriptors that were opened prior to entering capability mode or through relative directory operations. ```APIDOC ## enter() ### Description Enters capability mode for the current process. After calling this function, the process loses access to global namespaces and can only operate on file descriptors that were opened prior to entering capability mode or through relative directory operations. ### Method Rust Function ### Endpoint N/A ### Parameters (none) ### Returns `io::Result<()>` — Success if capability mode was entered; OS error otherwise. ### Errors - OS-level errors from the underlying `cap_enter(2)` system call ### Example ```rust use capsicum::enter; use std::fs::File; // Open file descriptor before entering sandbox let file = File::open("/etc/passwd").unwrap(); // Enter capability mode enter().expect("Failed to enter capability mode"); // This will fail - cannot open new files in capability mode let err = File::open("/tmp/newfile"); assert!(err.is_err()); ``` ``` -------------------------------- ### Modern Alternative for Rights Construction Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/deprecated.md Shows the modern approach to constructing file rights using `FileRights` directly, which is preferred over the deprecated `RightsBuilder`. ```rust use capsicum::{FileRights, Right}; let mut rights = FileRights::new(); rights.allow(Right::Read).allow(Right::Seek); ``` -------------------------------- ### FcntlRights Methods Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/module-index.md Methods for managing file control (fcntl) rights, including creating, modifying, querying, and applying rights. ```APIDOC ## FcntlRights Methods ### `new()` #### Description Create empty fcntl rights. #### Signature `fn() -> Self` ### `allow()` #### Description Add an fcntl command to the rights. #### Signature `fn(&mut self, right: Fcntl) -> &mut Self` ### `deny()` #### Description Remove an fcntl command from the rights. #### Signature `fn(&mut self, right: Fcntl) -> &mut Self` ### `from_file()` #### Description Query the current fcntl rights of a file. #### Signature `fn(f: &F) -> io::Result` ### `limit()` #### Description Apply these fcntl rights to a file descriptor. #### Signature `fn(&self, fd: &F) -> io::Result<()>` ``` -------------------------------- ### Build Multiple Capability Sets for Descriptors Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/TECHNICAL-REFERENCE.md Create distinct capability sets for different file descriptors. This allows fine-grained control over the rights granted to each descriptor. ```rust use capsicum::{FileRights, Right}; use std::fs::{File, OpenOptions}; let mut read_only = File::open("input.txt")?; let mut write_only = OpenOptions::new() .write(true) .create(true) .open("output.txt")?; FileRights::new() .allow(Right::Read) .allow(Right::Seek) .limit(&read_only)?; FileRights::new() .allow(Right::Write) .allow(Right::Seek) .limit(&write_only)?; capsicum::enter()?; // Each file has exactly the rights it needs ``` -------------------------------- ### Enable Casper Feature in Cargo.toml Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/configuration.md To enable Casper daemon integration, add the 'casper' feature to your capsicum dependency in Cargo.toml. ```toml [dependencies] capsicum = { version = "0.4", features = ["casper"] } ``` -------------------------------- ### Declare Casper Service Connection Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/casper.md Use this macro to declare a connection to an existing Casper service. It generates a struct for accessing the service and adds an accessor method to the `Casper` struct. ```rust use capsicum::casper; casper::service_connection!( pub CapGroupAgent, c"system.grp", group ); // Usage: unsafe { let mut casper = capsicum::casper::Casper::new().unwrap(); let mut group_service = casper.group().unwrap(); // Now use group_service.limit_get(), limit_set(), xfer_nvlist() } ``` -------------------------------- ### service_connection! Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/casper.md Declares a connection to an existing Casper service. It generates a struct for accessing the service and adds an accessor method to the `Casper` struct. This macro is useful for interacting with system services or services not implemented in Rust. ```APIDOC ## service_connection! ### Description Declares a connection to an existing Casper service (or a system service not implemented in Rust). ### Method Signature ```rust #[macro_export] macro_rules! service_connection!( $(#[$attr:meta])* $vis:vis $astruct:ident, $cname:expr, $meth:ident ) ``` ### Arguments - `vis`: Visibility of the generated struct. - `astruct`: Name of the struct that accesses the service. - `cname`: The service name as a `&'static CStr` (e.g., `c"system.grp"`). - `meth`: Name of the accessor method to add to `Casper`. ### Generated Methods - `limit_get()` → `io::Result`: Retrieve existing service limits. - `limit_set(limits: NvList)` → `io::Result<()>`: Set service limits. - `xfer_nvlist(invl: NvList)` → `io::Result`: Send command and receive response. ### Example ```rust use capsicum::casper; casper::service_connection!( pub CapGroupAgent, c"system.grp", group ); // Usage: unsafe { let mut casper = capsicum::casper::Casper::new().unwrap(); let mut group_service = casper.group().unwrap(); // Now use group_service.limit_get(), limit_set(), xfer_nvlist() } ``` ``` -------------------------------- ### FFI Linkage Configuration Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/configuration.md Specifies the native library to link against for FFI bindings. ```toml links = "casper" ``` -------------------------------- ### Usage with FcntlRights Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/fcntl-enum.md Demonstrates how to use the Fcntl enum variants with FcntlRights to specify and apply restrictions on fcntl commands for a file descriptor. ```APIDOC ## Usage with FcntlRights Fcntl variants are passed to `FcntlRights` to specify which fcntl commands are allowed: ```rust use capsicum::{FcntlRights, Fcntl}; use std::fs::File; let mut file = File::open("/etc/passwd").unwrap(); let mut rights = FcntlRights::new(); rights.allow(Fcntl::GetFL); // Allow querying file access mode rights.limit(&file).unwrap(); capsicum::enter().unwrap(); // Now F_GETFL operations work, but F_SETFL would fail with ENOTCAPABLE ``` ``` -------------------------------- ### Create New FileRights Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/file-rights.md Creates a new FileRights structure with no rights enabled, representing the most restrictive state. ```rust use capsicum::FileRights; let rights = FileRights::new(); ``` -------------------------------- ### Cargo Build with Casper Feature Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/configuration.md Compiles the project enabling the 'casper' feature for a specific target. ```bash cargo build --target x86_64-unknown-freebsd --features casper ``` -------------------------------- ### Query File Descriptor Capabilities Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/TECHNICAL-REFERENCE.md Inspect the capabilities currently assigned to a file descriptor. This allows verification of granted rights, such as Read or Seek. ```rust use capsicum::{FileRights, Right}; use std::fs::File; let file = File::open("data")?; FileRights::new() .allow(Right::Read) .allow(Right::Seek) .limit(&file)?; // Later, verify what was set: let actual = FileRights::from_file(&file)?; assert!(actual.is_set(Right::Read)); assert!(!actual.is_set(Right::Write)); ``` -------------------------------- ### Casper::try_clone() Errors Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/errors.md Details the errors for `Casper::try_clone()`, which attempts to clone a Casper instance. Errors are typically OS errors from the `cap_clone()` system call. ```APIDOC ## Casper::try_clone() (Feature: casper) ### Description Attempts to clone a Casper instance. ### Method `pub fn try_clone(&mut self) -> io::Result` ### Possible Errors - OS errors from `cap_clone()` system call ``` -------------------------------- ### Enter Capability Mode Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/process.md Enters capability mode for the current process. After calling this function, the process loses access to global namespaces and can only operate on file descriptors that were opened prior to entering capability mode or through relative directory operations. This function returns an OS error if the underlying cap_enter(2) system call fails. ```rust use capsicum::enter; use std::fs::File; // Open file descriptor before entering sandbox let file = File::open("/etc/passwd").unwrap(); // Enter capability mode enter().expect("Failed to enter capability mode"); // This will fail - cannot open new files in capability mode let err = File::open("/tmp/newfile"); assert!(err.is_err()); ``` -------------------------------- ### Declare Custom Casper Service Implementation Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/casper.md Use this macro to declare a custom Casper service implementation. It generates a struct for accessing the service, implements the `Service` trait for `Casper`, and registers the service. ```rust use capsicum::casper::{self, Service}; use libnv::libnv::NvList; use std::ffi::CStr; use std::io; struct MyCustomService; impl Service for MyCustomService { const SERVICE_NAME: &'static CStr = c"my.custom"; fn cmd(cmd: &str, limits: Option<&NvList>, nvin: Option<&mut NvList>, nvout: &mut NvList) -> io::Result<()> { // Handle commands Ok(()) } fn limit(_oldlimits: Option<&NvList>, _newlimits: Option<&NvList>) -> io::Result<()> { Ok(()) } } casper::service!(MyCustomService, MyServiceAgent, my_service, casper::ServiceRegisterFlags::NONE); ``` -------------------------------- ### Usage with FcntlRights Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/api-reference/fcntl-enum.md Demonstrates how to use the Fcntl enum with FcntlRights to allow specific fcntl commands on a file descriptor. After limiting rights, only allowed operations will succeed. ```rust use capsicum::{FcntlRights, Fcntl}; use std::fs::File; let mut file = File::open("/etc/passwd").unwrap(); let mut rights = FcntlRights::new(); rights.allow(Fcntl::GetFL); // Allow querying file access mode rights.limit(&file).unwrap(); capsicum::enter().unwrap(); // Now F_GETFL operations work, but F_SETFL would fail with ENOTCAPABLE ``` -------------------------------- ### FcntlRights::from_file() Errors Source: https://github.com/dlrobertson/capsicum-rs/blob/main/_autodocs/errors.md Describes the errors for `FcntlRights::from_file()`, which creates `FcntlRights` from a file descriptor. Errors include invalid file descriptors and OS errors from `cap_fcntls_get(2)`. ```APIDOC ## FcntlRights::from_file() ### Description Creates `FcntlRights` from a file descriptor. ### Method `FcntlRights::from_file(f: &F) -> io::Result` ### Possible Errors - `EBADF` — Invalid file descriptor - Other OS errors from `cap_fcntls_get(2)` ```