forked from bonsai/harakit
89 lines
2.3 KiB
Rust
89 lines
2.3 KiB
Rust
/*
|
|
* Copyright (c) 2024 Emma Tebibyte <emma@tebibyte.media>
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify it under
|
|
* the terms of the GNU Affero General Public License as published by the Free
|
|
* Software Foundation, either version 3 of the License, or (at your option) any
|
|
* later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
|
*/
|
|
|
|
use std::{
|
|
ffi::{ CString, c_int },
|
|
io::Error,
|
|
ptr::null,
|
|
};
|
|
|
|
mod openbsd {
|
|
use std::ffi::{ c_char, c_int };
|
|
extern "C" {
|
|
pub fn pledge(arg1: *const c_char, arg2: *const c_char) -> c_int;
|
|
|
|
pub fn unveil(arg1: *const c_char, arg2: *const c_char) -> c_int;
|
|
|
|
pub fn __errno() -> *mut c_int;
|
|
}
|
|
}
|
|
|
|
pub struct Promises(*const i8);
|
|
|
|
impl Promises {
|
|
pub fn new(promises: &str) -> Self {
|
|
let p = CString::new(promises).unwrap();
|
|
|
|
Promises(p.into_raw() as *const i8)
|
|
}
|
|
}
|
|
|
|
pub fn pledge(
|
|
promises: Option<Promises>, execpromises: Option<Promises>
|
|
) -> Result<(), Error> {
|
|
/* From pledge(2):
|
|
*
|
|
* Passing NULL to promises or execpromises specifies to not change
|
|
* the current value. */
|
|
let arg1 = promises.unwrap_or(Promises(null())).0;
|
|
let arg2 = execpromises.unwrap_or(Promises(null())).0;
|
|
|
|
unsafe {
|
|
match openbsd::pledge(arg1, arg2) {
|
|
-1 => Err(Error::from_raw_os_error(*openbsd::__errno())),
|
|
0 => Ok(()),
|
|
_ => panic!(), /* unreachable */
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct UnveilPerms(CString);
|
|
|
|
impl UnveilPerms {
|
|
pub fn new(permissions: Vec<char>) -> Self {
|
|
if permissions.is_empty() {
|
|
return UnveilPerms(CString::new("").unwrap());
|
|
}
|
|
|
|
UnveilPerms(
|
|
CString::new(permissions.iter().collect::<String>()).unwrap()
|
|
)
|
|
}
|
|
}
|
|
|
|
pub fn unveil(path: Option<&str>, permissions: Option<UnveilPerms>) -> c_int {
|
|
let path_c = path.map(CString::new).map(Result::unwrap);
|
|
let arg1 = path_c.map(|p| p.into_raw() as *const i8).unwrap_or(null());
|
|
|
|
let arg2 = permissions
|
|
.map(|p| p.0.into_raw() as *const i8)
|
|
.unwrap_or(null());
|
|
|
|
unsafe { openbsd::unveil(arg1, arg2) }
|
|
}
|