Adapt sudo and getty to new namespace management, and enforce strict namespace at login.
This commit is contained in:
committed by
Jeremy Soller
parent
8ccf37d74a
commit
3bdd1d9a6e
Generated
+138
-10
@@ -108,6 +108,12 @@ version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "extra"
|
||||
version = "0.1.0"
|
||||
@@ -116,7 +122,7 @@ source = "git+https://gitlab.redox-os.org/redox-os/libextra.git#cf213969493db866
|
||||
[[package]]
|
||||
name = "generic-rt"
|
||||
version = "0.1.0"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/relibc#250f072973b96ee2d2ab921b7c2114b5178ec4d1"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/relibc#3a8f64aa143184dc11fe1927a4f9e55c33ae3052"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
@@ -140,6 +146,12 @@ dependencies = [
|
||||
"scroll",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
@@ -149,6 +161,26 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.11.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ioslice"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e571352c8a3b89074d12e3ee5173ffe162159105352aaaf1fc5764da747e31b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
@@ -172,11 +204,12 @@ checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.11"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df15f6eac291ed1cf25865b1ee60399f57e7c227e7f51bdbd4c5270396a9ed50"
|
||||
checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"ioslice",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
]
|
||||
@@ -244,11 +277,12 @@ checksum = "436d45c2b6a5b159d43da708e62b25be3a4a3d5550d654b72216ade4c4bfd717"
|
||||
[[package]]
|
||||
name = "redox-rt"
|
||||
version = "0.1.0"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/relibc#250f072973b96ee2d2ab921b7c2114b5178ec4d1"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/relibc#3a8f64aa143184dc11fe1927a4f9e55c33ae3052"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"generic-rt",
|
||||
"goblin",
|
||||
"ioslice",
|
||||
"plain",
|
||||
"redox-path",
|
||||
"redox_syscall",
|
||||
@@ -256,9 +290,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox-scheme"
|
||||
version = "0.8.3"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2cea2668a5932f878a4298a1d7f8950249bbbb77120fb263da252c589152f5ea"
|
||||
checksum = "5eb0cee524a5c6e4db180250f699e101ee25f3f79ad2618527e539e028cb6722"
|
||||
dependencies = [
|
||||
"libredox",
|
||||
"redox_syscall",
|
||||
@@ -266,9 +300,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox_event"
|
||||
version = "0.4.1"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69609faa5d5992247a4ef379917bb3e39be281405d6a0ccd4f942429400b956f"
|
||||
checksum = "c30b73c93693667b5a8e6f54bddcc5a57449ef17c99f4b55c12d5bae4ab79e82"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"libredox",
|
||||
@@ -289,8 +323,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.6.0"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/syscall.git#2d11366fd160ec1dd3918164fa324275e1bab070"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
]
|
||||
@@ -369,6 +404,45 @@ dependencies = [
|
||||
"version-compare",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strip-ansi-escapes"
|
||||
version = "0.2.1"
|
||||
@@ -436,6 +510,47 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_write",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_write"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.19"
|
||||
@@ -454,6 +569,8 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"extra",
|
||||
"ioslice",
|
||||
"libc",
|
||||
"libredox",
|
||||
"orbclient",
|
||||
"plain",
|
||||
@@ -464,7 +581,9 @@ dependencies = [
|
||||
"redox_syscall",
|
||||
"redox_termios",
|
||||
"redox_users",
|
||||
"serde",
|
||||
"termion",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -516,6 +635,15 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.8.2"
|
||||
|
||||
+8
-7
@@ -57,19 +57,20 @@ extra = { git = "https://gitlab.redox-os.org/redox-os/libextra.git" }
|
||||
orbclient = "0.3.47"
|
||||
plain = "0.2.3"
|
||||
redox_liner = "0.5.2"
|
||||
libredox = "0.1.3"
|
||||
libredox = { version = "0.1.12", features = ["mkns"] }
|
||||
redox_termios = "0.1.3"
|
||||
redox_event = "0.4"
|
||||
redox-scheme = "0.8.3"
|
||||
redox_syscall = "0.6"
|
||||
redox_event = "0.4.3"
|
||||
redox-scheme = "0.9.0"
|
||||
redox_syscall = "0.7.0"
|
||||
redox_users = "0.4.6"
|
||||
termion = "4"
|
||||
libc = "0.2"
|
||||
serde = { version = "1.0.203", features = ["derive"] }
|
||||
toml = "0.8.11"
|
||||
ioslice = "0.6"
|
||||
|
||||
[target.'cfg(target_os = "redox")'.dependencies]
|
||||
redox-rt = { git = "https://gitlab.redox-os.org/redox-os/relibc", default-features = false }
|
||||
|
||||
[patch.crates-io]
|
||||
redox_syscall = { git = "https://gitlab.redox-os.org/redox-os/syscall.git" }
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
||||
+97
-1
@@ -1,12 +1,13 @@
|
||||
#[macro_use]
|
||||
extern crate clap;
|
||||
|
||||
use libredox::error::Result;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Write};
|
||||
use std::str;
|
||||
|
||||
use extra::option::OptionalExt;
|
||||
use redox_users::{All, AllUsers, Config};
|
||||
use redox_users::{All, AllUsers, Config, User};
|
||||
use termion::input::TermRead;
|
||||
use userutils::spawn_shell;
|
||||
|
||||
@@ -33,6 +34,89 @@ AUTHOR
|
||||
const ISSUE_FILE: &'static str = "/etc/issue";
|
||||
const MOTD_FILE: &'static str = "/etc/motd";
|
||||
|
||||
// TODO: Move to redox_users once the definition solidifies.
|
||||
const DEFAULT_SCHEMES: [&'static str; 26] = [
|
||||
// Kernel schemes
|
||||
"debug",
|
||||
"event",
|
||||
"memory",
|
||||
"pipe",
|
||||
"serio",
|
||||
"irq",
|
||||
"time",
|
||||
"sys",
|
||||
// Base schemes
|
||||
"rand",
|
||||
"null",
|
||||
"zero",
|
||||
"log",
|
||||
// Network schemes
|
||||
"ip",
|
||||
"icmp",
|
||||
"tcp",
|
||||
"udp",
|
||||
// IPC schemes
|
||||
"shm",
|
||||
"chan",
|
||||
"uds_stream",
|
||||
"uds_dgram",
|
||||
// File schemes
|
||||
"file",
|
||||
// Display schemes
|
||||
"display.vesa",
|
||||
"display*",
|
||||
// Other schemes
|
||||
"pty",
|
||||
"sudo",
|
||||
"audio",
|
||||
];
|
||||
pub fn apply_login_schemes(
|
||||
user: &User<redox_users::auth::Full>,
|
||||
default_schemes: &[&str],
|
||||
) -> Result<libredox::Fd> {
|
||||
let schemes = match load_config_schemes(user) {
|
||||
Some(s) => s,
|
||||
_ => default_schemes.iter().map(|s| s.to_string()).collect(),
|
||||
};
|
||||
|
||||
let mut names: Vec<ioslice::IoSlice> = Vec::with_capacity(schemes.len());
|
||||
for scheme in schemes.iter() {
|
||||
names.push(ioslice::IoSlice::new(scheme.as_bytes()));
|
||||
}
|
||||
|
||||
let ns_fd = libredox::call::mkns(&names)?;
|
||||
let before_ns_fd = libredox::Fd::new(libredox::call::setns(ns_fd)?);
|
||||
|
||||
Ok(before_ns_fd)
|
||||
}
|
||||
|
||||
fn load_config_schemes(user: &User<redox_users::auth::Full>) -> Option<Vec<String>> {
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs;
|
||||
|
||||
const LOGIN_SCHEMES_FILE: &'static str = "/etc/login_schemes.toml";
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
struct UserSchemeConfig {
|
||||
pub schemes: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
struct LoginConfig {
|
||||
#[serde(rename = "user_schemes")]
|
||||
pub user_schemes: BTreeMap<String, UserSchemeConfig>,
|
||||
}
|
||||
|
||||
let config_str = fs::read_to_string(LOGIN_SCHEMES_FILE).ok()?;
|
||||
let config: LoginConfig = toml::from_str(&config_str).ok()?;
|
||||
|
||||
config
|
||||
.user_schemes
|
||||
.get(&user.user)
|
||||
.map(|cfg| cfg.schemes.clone())
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let mut stdout = io::stdout();
|
||||
let mut stderr = io::stderr();
|
||||
@@ -76,7 +160,19 @@ pub fn main() {
|
||||
stdout.flush().r#try(&mut stderr);
|
||||
}
|
||||
|
||||
let before_ns_fd =
|
||||
apply_login_schemes(user, &DEFAULT_SCHEMES).unwrap_or_exit(1);
|
||||
|
||||
let _ = syscall::fcntl(
|
||||
before_ns_fd.raw(),
|
||||
syscall::F_SETFD,
|
||||
syscall::O_CLOEXEC,
|
||||
);
|
||||
spawn_shell(user).unwrap_or_exit(1);
|
||||
let _ = syscall::fcntl(before_ns_fd.raw(), syscall::F_SETFD, 0);
|
||||
let _ = libredox::call::close(
|
||||
libredox::call::setns(before_ns_fd.into_raw()).unwrap_or_exit(1),
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+32
-3
@@ -9,7 +9,7 @@ use extra::option::OptionalExt;
|
||||
use libredox::flag::O_CLOEXEC;
|
||||
use redox_rt::protocol::ProcCall;
|
||||
use redox_rt::sys::proc_call;
|
||||
use redox_scheme::scheme::SchemeSync;
|
||||
use redox_scheme::scheme::{SchemeSync, register_sync_scheme};
|
||||
use redox_scheme::{
|
||||
CallerCtx, OpenResult, RequestKind, Response, SendFdRequest, SignalBehavior, Socket,
|
||||
};
|
||||
@@ -157,10 +157,31 @@ enum Handle {
|
||||
AwaitingNewPassword { uid: u32 },
|
||||
|
||||
Placeholder,
|
||||
|
||||
SchemeRoot,
|
||||
}
|
||||
|
||||
impl SchemeSync for Scheme {
|
||||
fn open(&mut self, path: &str, _flags: usize, ctx: &CallerCtx) -> Result<OpenResult> {
|
||||
fn scheme_root(&mut self) -> Result<usize> {
|
||||
let fd = self.next_fd;
|
||||
self.next_fd = self.next_fd.checked_add(1).ok_or(Error::new(EMFILE))?;
|
||||
self.handles.insert(fd, Handle::SchemeRoot);
|
||||
Ok(fd)
|
||||
}
|
||||
fn openat(
|
||||
&mut self,
|
||||
dirfd: usize,
|
||||
path: &str,
|
||||
_flags: usize,
|
||||
_fcntl_flags: u32,
|
||||
ctx: &CallerCtx,
|
||||
) -> Result<OpenResult> {
|
||||
if !matches!(
|
||||
self.handles.get(&dirfd).ok_or(Error::new(EBADF))?,
|
||||
Handle::SchemeRoot
|
||||
) {
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
let fd = self.next_fd;
|
||||
self.next_fd = self.next_fd.checked_add(1).ok_or(Error::new(EMFILE))?;
|
||||
let handle = match path {
|
||||
@@ -261,6 +282,11 @@ impl SchemeSync for Scheme {
|
||||
eprintln!("sudo: found placeholder handle with ID {id}");
|
||||
return Err(Error::new(EBADFD));
|
||||
}
|
||||
|
||||
Handle::SchemeRoot => {
|
||||
eprintln!("sudo: found Scheme root handle with ID {id}");
|
||||
return Err(Error::new(EBADFD));
|
||||
}
|
||||
}
|
||||
Ok(buf.len())
|
||||
}
|
||||
@@ -309,13 +335,16 @@ impl Scheme {
|
||||
|
||||
fn daemon_main() -> ! {
|
||||
// TODO: Linux kernel audit-like logging?
|
||||
let socket = Socket::create("sudo").expect("failed to open scheme socket");
|
||||
let socket = Socket::create().expect("failed to open scheme socket");
|
||||
|
||||
let mut scheme = Scheme {
|
||||
next_fd: 1,
|
||||
handles: HashMap::new(),
|
||||
};
|
||||
|
||||
register_sync_scheme(&socket, "sudo", &mut scheme)
|
||||
.expect("failed to register sudo scheme to namespace");
|
||||
|
||||
loop {
|
||||
let Some(req) = socket
|
||||
.next_request(SignalBehavior::Restart)
|
||||
|
||||
Reference in New Issue
Block a user