pledge-0.3.1/.gitignore01006440000767000002400000000022132073336120013156 0ustar0000000000000000target Cargo.lock pledge-0.3.1/.travis.yml01006440000767000002400000000213132073361760013311 0ustar0000000000000000language: rust sudo: false dist: trusty matrix: include: - rust: stable - rust: beta notifications: email: false pledge-0.3.1/Cargo.toml.orig01006440000767000002400000000501132073351350014061 0ustar0000000000000000[package] name = "pledge" version = "0.3.1" authors = ["Andrew Aldridge "] description = "Rust binding to OpenBSD's pledge(2) interface" readme = "README.md" repository = "https://github.com/i80and/pledge-rs" keywords = ["openbsd", "binding", "security"] license = "MIT" [dependencies] libc = "0.2" pledge-0.3.1/Cargo.toml0000644000000015240007314 0ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g. crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] name = "pledge" version = "0.3.1" authors = ["Andrew Aldridge "] description = "Rust binding to OpenBSD's pledge(2) interface" readme = "README.md" keywords = ["openbsd", "binding", "security"] license = "MIT" repository = "https://github.com/i80and/pledge-rs" [dependencies.libc] version = "0.2" pledge-0.3.1/LICENSE01006440000767000002400000002060132073336120012177 0ustar0000000000000000MIT License Copyright (c) 2016 Andrew Aldridge Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. pledge-0.3.1/README.md01006440000767000002400000001674132073350120012457 0ustar0000000000000000# pledge-rs [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE) [![crates.io](http://meritbadge.herokuapp.com/pledge)](https://crates.io/crates/pledge) A Rust binding to OpenBSD's pledge(2) interface. ## Usage #[macro_use] extern crate pledge; use pledge::{pledge, Promise, ToPromiseString}; fn foo() { match pledge![Stdio, RPath] { Err(_) => println!("Failed to pledge"), _ => () } } This is equivalent to: extern crate pledge; use pledge::{pledge, Promise, ToPromiseString}; fn foo() { match pledge(&vec![Promise::Stdio, Promise::RPath].to_promise_string()) { Err(_) => println!("Failed to pledge"), _ => () } } You may also provide promises directly as a string: use pledge::pledge; fn foo() { if pledge("stdio rpath").is_err() { panic!("Failed to pledge"); } } pledge-0.3.1/src/lib.rs01006440000767000002400000010502132073351050013074 0ustar0000000000000000use std::os::raw::c_int; use std::{error, fmt}; #[derive(PartialEq, Eq, Debug)] pub enum Error { UnsupportedPlatform, Other(c_int), } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Error::UnsupportedPlatform => write!(f, "pledge is unsupported on this platform"), Error::Other(errno) => write!(f, "unable to pledge ({})", errno), } } } impl error::Error for Error { fn description(&self) -> &str { match *self { Error::UnsupportedPlatform => "pledge is unsupported on this platform", Error::Other(_) => "unable to pledge", } } } pub enum Promise { Audio, Chown, CPath, DiskLabel, Dns, DPath, Drm, Exec, Fattr, Flock, Getpw, Id, Inet, Ioctl, MCast, Pf, Proc, ProtExec, Ps, Recvfd, Route, RPath, Sendfd, Settime, Stdio, TMPPath, Tty, Unix, Vminfo, Vmm, WPath, } impl Promise { pub fn to_promise_string(&self) -> &'static str { match *self { Promise::Audio => "audio", Promise::Chown => "chown", Promise::CPath => "cpath", Promise::DiskLabel => "disklabel", Promise::Dns => "dns", Promise::DPath => "dpath", Promise::Drm => "drm", Promise::Exec => "exec", Promise::Fattr => "fattr", Promise::Flock => "flock", Promise::Getpw => "getpw", Promise::Id => "id", Promise::Inet => "inet", Promise::Ioctl => "ioctl", Promise::MCast => "mcast", Promise::Pf => "pf", Promise::Proc => "proc", Promise::ProtExec => "prot_exec", Promise::Ps => "ps", Promise::Recvfd => "recvfd", Promise::Route => "route", Promise::RPath => "rpath", Promise::Sendfd => "sendfd", Promise::Settime => "settime", Promise::Stdio => "stdio", Promise::TMPPath => "tmppath", Promise::Tty => "tty", Promise::Unix => "unix", Promise::Vminfo => "vminfo", Promise::Vmm => "vmm", Promise::WPath => "wpath", } } } pub trait ToPromiseString { fn to_promise_string(&self) -> String; } impl ToPromiseString for [Promise] { fn to_promise_string(&self) -> String { self.iter() .map(|p| p.to_promise_string()) .collect::>() .join(" ") } } #[cfg(any(target_os = "bitrig", target_os = "openbsd"))] mod openbsd; #[cfg(any(target_os = "bitrig", target_os = "openbsd"))] pub use openbsd::pledge_with_paths; #[cfg(not(any(target_os = "bitrig", target_os = "openbsd")))] pub fn pledge_with_paths(_: &str, _: &[&std::path::Path]) -> Result<(), Error> { Err(Error::UnsupportedPlatform) } pub fn pledge(promises: &str) -> Result<(), Error> { pledge_with_paths(promises, &[]) } #[macro_export] macro_rules! pledge { ( $( $x:ident ),* ) => { { let mut promises = Vec::new(); $( promises.push(Promise::$x); )* let promises_str = promises.to_promise_string(); pledge(&promises_str) } }; } #[cfg(test)] mod tests { use super::{pledge, Promise, ToPromiseString}; #[test] fn test_promise_str() { use super::ToPromiseString; assert_eq!(vec![].to_promise_string(), ""); assert_eq!(vec![Promise::Dns].to_promise_string(), "dns"); assert_eq!( vec![Promise::Stdio, Promise::ProtExec].to_promise_string(), "stdio prot_exec" ); } #[test] #[cfg(not(any(target_os = "bitrig", target_os = "openbsd")))] fn test_pledge_unsupported() { use super::Error; assert_eq!(pledge![Stdio].unwrap_err(), Error::UnsupportedPlatform); } #[test] #[cfg(any(target_os = "bitrig", target_os = "openbsd"))] fn test_pledge_supported() { pledge![Stdio].unwrap(); assert!(pledge![Stdio, Audio].is_err()); } #[test] #[cfg(target_os = "openbsd")] fn test_as_string() { if pledge("stdio").is_err() { panic!("pledge"); } println!("hello world"); } } pledge-0.3.1/src/openbsd.rs01006440000767000002400000002005132073350430013760 0ustar0000000000000000extern crate libc; use std::ffi::CString; use std::os::raw::{c_char, c_int}; use std::os::unix::ffi::OsStrExt; use std::path; use std::ptr; use Error; pub fn pledge_with_paths(promises: &str, paths: &[&path::Path]) -> Result<(), Error> { extern "C" { fn pledge(promises: *const c_char, paths: *const *const c_char) -> c_int; } let cstr = CString::new(promises).unwrap(); let mut cpaths = Vec::with_capacity(paths.len()); for path in paths { cpaths.push(CString::new(path.as_os_str().as_bytes()).unwrap()); } let mut cpaths_raw = cpaths .iter() .map(|path| path.as_ptr()) .collect::>(); unsafe { let cpaths_ptr = if !cpaths.is_empty() { cpaths_raw.push(ptr::null()); cpaths_raw.as_ptr() } else { ptr::null() }; return match pledge(cstr.as_ptr(), cpaths_ptr) { 0 => Ok(()), _ => Err(Error::Other(*libc::__errno())), }; } }