From 0d1afaa016a6459cf746d26d7a747ed3d162b550 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 7 Oct 2016 10:42:17 -0600 Subject: [PATCH] Add userutils --- .gitmodules | 3 + Makefile | 26 ++++--- programs/coreutils | 2 +- programs/getty/Cargo.toml | 6 -- programs/getty/src/main.rs | 51 ------------- programs/id/Cargo.toml | 6 -- programs/id/src/main.rs | 9 --- programs/login/Cargo.toml | 15 ---- programs/login/src/main.rs | 149 ------------------------------------- programs/sudo/Cargo.toml | 6 -- programs/sudo/src/main.rs | 123 ------------------------------ programs/userutils | 1 + 12 files changed, 21 insertions(+), 376 deletions(-) delete mode 100644 programs/getty/Cargo.toml delete mode 100644 programs/getty/src/main.rs delete mode 100644 programs/id/Cargo.toml delete mode 100644 programs/id/src/main.rs delete mode 100644 programs/login/Cargo.toml delete mode 100644 programs/login/src/main.rs delete mode 100644 programs/sudo/Cargo.toml delete mode 100644 programs/sudo/src/main.rs create mode 160000 programs/userutils diff --git a/.gitmodules b/.gitmodules index fd45382..2d6ca04 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,3 +25,6 @@ [submodule "programs/smith"] path = programs/smith url = https://github.com/IGI-111/Smith.git +[submodule "programs/userutils"] + path = programs/userutils + url = https://github.com/redox-os/userutils.git diff --git a/Makefile b/Makefile index 6aa7c00..2df2be4 100644 --- a/Makefile +++ b/Makefile @@ -28,15 +28,11 @@ clean: cargo clean --manifest-path drivers/ps2d/Cargo.toml cargo clean --manifest-path drivers/pcid/Cargo.toml cargo clean --manifest-path drivers/vesad/Cargo.toml - cargo clean --manifest-path programs/getty/Cargo.toml - cargo clean --manifest-path programs/id/Cargo.toml cargo clean --manifest-path programs/init/Cargo.toml - cargo clean --manifest-path programs/sudo/Cargo.toml cargo clean --manifest-path programs/ion/Cargo.toml - cargo clean --manifest-path programs/login/Cargo.toml - cargo clean --manifest-path programs/sudo/Cargo.toml cargo clean --manifest-path programs/coreutils/Cargo.toml cargo clean --manifest-path programs/extrautils/Cargo.toml + cargo clean --manifest-path programs/userutils/Cargo.toml cargo clean --manifest-path programs/smith/Cargo.toml cargo clean --manifest-path schemes/example/Cargo.toml cargo clean --manifest-path schemes/redoxfs/Cargo.toml @@ -217,6 +213,12 @@ filesystem/bin/%: programs/extrautils/Cargo.toml programs/extrautils/src/bin/%.r strip $@ rm $@.d +filesystem/bin/%: programs/userutils/Cargo.toml programs/userutils/src/bin/%.rs $(BUILD)/libstd.rlib + mkdir -p filesystem/bin + $(CARGO) rustc --manifest-path $< --bin $* $(CARGOFLAGS) -o $@ + strip $@ + rm $@.d + filesystem/bin/%: schemes/%/Cargo.toml schemes/%/src/** $(BUILD)/libstd.rlib mkdir -p filesystem/bin $(CARGO) rustc --manifest-path $< --bin $* $(CARGOFLAGS) -o $@ @@ -269,6 +271,12 @@ extrautils: \ filesystem/bin/rem \ #filesystem/bin/dmesg filesystem/bin/info filesystem/bin/man filesystem/bin/watch +userutils: \ + filesystem/bin/getty \ + filesystem/bin/id \ + filesystem/bin/login \ + filesystem/bin/su \ + filesystem/bin/sudo schemes: \ filesystem/bin/example @@ -277,13 +285,10 @@ $(BUILD)/filesystem.bin: \ drivers \ coreutils \ extrautils \ + userutils \ schemes \ - filesystem/bin/getty \ - filesystem/bin/id \ filesystem/bin/ion \ - filesystem/bin/login \ - filesystem/bin/smith \ - filesystem/bin/sudo + filesystem/bin/smith rm -rf $@ $(BUILD)/filesystem/ echo exit | cargo run --manifest-path schemes/redoxfs/Cargo.toml --bin redoxfs-utility $@ 8 mkdir -p $(BUILD)/filesystem/ @@ -294,6 +299,7 @@ $(BUILD)/filesystem.bin: \ -chown -R 1000:1000 $(BUILD)/filesystem/home/user/ -chmod 700 $(BUILD)/filesystem/root/ -chmod 700 $(BUILD)/filesystem/home/user/ + -chmod +s $(BUILD)/filesystem/bin/su -chmod +s $(BUILD)/filesystem/bin/sudo sync -fusermount -u $(BUILD)/filesystem/ diff --git a/programs/coreutils b/programs/coreutils index dc2ebd6..adbf938 160000 --- a/programs/coreutils +++ b/programs/coreutils @@ -1 +1 @@ -Subproject commit dc2ebd63734f30f345732fcd2e51e3f485d0ed0d +Subproject commit adbf93876da794bde338ed8d53e5e7c4f14549dc diff --git a/programs/getty/Cargo.toml b/programs/getty/Cargo.toml deleted file mode 100644 index 49e1459..0000000 --- a/programs/getty/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "getty" -version = "0.1.0" - -[dependencies] -syscall = { path = "../../syscall/" } diff --git a/programs/getty/src/main.rs b/programs/getty/src/main.rs deleted file mode 100644 index ec4f361..0000000 --- a/programs/getty/src/main.rs +++ /dev/null @@ -1,51 +0,0 @@ -#![feature(question_mark)] - -extern crate syscall; - -use std::io::Write; -use std::process::Command; -use std::{env, io, str, thread}; - -pub fn main() { - let mut args = env::args().skip(1); - - let tty = args.next().expect("getty: no tty provided"); - - let _ = syscall::close(2); - let _ = syscall::close(1); - let _ = syscall::close(0); - - let _ = syscall::open(&tty, syscall::flag::O_RDWR); - let _ = syscall::open(&tty, syscall::flag::O_RDWR); - let _ = syscall::open(&tty, syscall::flag::O_RDWR); - - env::set_current_dir("file:").unwrap(); - - env::set_var("TTY", &tty); - { - let mut path = [0; 4096]; - if let Ok(count) = syscall::fpath(0, &mut path) { - let path_str = str::from_utf8(&path[..count]).unwrap_or(""); - let reference = path_str.split(':').nth(1).unwrap_or(""); - let mut parts = reference.split('/'); - env::set_var("COLUMNS", parts.next().unwrap_or("80")); - env::set_var("LINES", parts.next().unwrap_or("30")); - } - } - - thread::spawn(move || { - let stdout = io::stdout(); - let mut stdout = stdout.lock(); - loop { - stdout.write(b"\x1Bc").unwrap(); - let _ = stdout.flush(); - match Command::new("file:bin/login").spawn() { - Ok(mut child) => match child.wait() { - Ok(_status) => (), //println!("getty: waited for login: {:?}", status.code()), - Err(err) => panic!("getty: failed to wait for login: {}", err) - }, - Err(err) => panic!("getty: failed to execute login: {}", err) - } - } - }); -} diff --git a/programs/id/Cargo.toml b/programs/id/Cargo.toml deleted file mode 100644 index d9dedcd..0000000 --- a/programs/id/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "id" -version = "0.1.0" - -[dependencies] -syscall = { path = "../../syscall/" } diff --git a/programs/id/src/main.rs b/programs/id/src/main.rs deleted file mode 100644 index b161353..0000000 --- a/programs/id/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -extern crate syscall; - -use std::env; - -pub fn main() { - let uid = syscall::getuid().expect("id: failed to get UID"); - let gid = syscall::getgid().expect("id: failed to get GID"); - println!("uid={}({}) gid={}({})", uid, env::var("USER").unwrap_or(String::new()), gid, ""); -} diff --git a/programs/login/Cargo.toml b/programs/login/Cargo.toml deleted file mode 100644 index 0462d1b..0000000 --- a/programs/login/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "login" -version = "0.1.0" - -[dependencies] -termion = "*" - -[dependencies.octavo] -git = "https://github.com/libOctavo/octavo" -default-features = false -features = ["digest"] - -[replace] -"libc:0.2.16" = { git = "https://github.com/redox-os/liblibc.git", branch = "new_kernel" } -"rustc-serialize:0.3.19" = { git = "https://github.com/redox-os/rustc-serialize.git" } diff --git a/programs/login/src/main.rs b/programs/login/src/main.rs deleted file mode 100644 index 079e870..0000000 --- a/programs/login/src/main.rs +++ /dev/null @@ -1,149 +0,0 @@ -#![feature(question_mark)] - -extern crate octavo; -extern crate termion; - -use octavo::octavo_digest::Digest; -use octavo::octavo_digest::sha3::Sha512; -use std::fs::File; -use std::io::{self, Read, Write}; -use std::os::unix::process::CommandExt; -use std::process::Command; -use std::str; -use termion::input::TermRead; - -pub struct Passwd<'a> { - user: &'a str, - hash: &'a str, - uid: u32, - gid: u32, - name: &'a str, - home: &'a str, - shell: &'a str -} - -impl<'a> Passwd<'a> { - pub fn parse(line: &'a str) -> Result, ()> { - let mut parts = line.split(';'); - - let user = parts.next().ok_or(())?; - let hash = parts.next().ok_or(())?; - let uid = parts.next().ok_or(())?.parse::().or(Err(()))?; - let gid = parts.next().ok_or(())?.parse::().or(Err(()))?; - let name = parts.next().ok_or(())?; - let home = parts.next().ok_or(())?; - let shell = parts.next().ok_or(())?; - - Ok(Passwd { - user: user, - hash: hash, - uid: uid, - gid: gid, - name: name, - home: home, - shell: shell - }) - } -} - -pub fn main() { - let stdin = io::stdin(); - let mut stdin = stdin.lock(); - let stdout = io::stdout(); - let mut stdout = stdout.lock(); - - if let Ok(mut issue) = File::open("/etc/issue") { - io::copy(&mut issue, &mut stdout).unwrap(); - let _ = stdout.flush(); - } - - loop { - stdout.write_all(b"\x1B[1mredox login:\x1B[0m ").unwrap(); - let _ = stdout.flush(); - - let user = (&mut stdin as &mut Read).read_line().unwrap().unwrap_or(String::new()); - if ! user.is_empty() { - let mut passwd_string = String::new(); - File::open("file:etc/passwd").unwrap().read_to_string(&mut passwd_string).unwrap(); - - let mut passwd_option = None; - for line in passwd_string.lines() { - if let Ok(passwd) = Passwd::parse(line) { - if user == passwd.user && "" == passwd.hash { - passwd_option = Some(passwd); - break; - } - } - } - - if passwd_option.is_none() { - stdout.write_all(b"\x1B[1mpassword:\x1B[0m ").unwrap(); - let _ = stdout.flush(); - - if let Some(password) = stdin.read_passwd(&mut stdout).unwrap() { - stdout.write(b"\n").unwrap(); - let _ = stdout.flush(); - - let password_hash = { - let mut output = vec![0; Sha512::output_bytes()]; - let mut hash = Sha512::default(); - hash.update(&password.as_bytes()); - hash.result(&mut output); - let mut encoded = String::new(); - for b in output.iter() { - encoded.push_str(&format!("{:X}", b)); - } - encoded - }; - - if let Ok(mut debug) = File::open("debug:") { - let _ = write!(debug, "{};{}\n", user, password_hash); - } - - for line in passwd_string.lines() { - if let Ok(passwd) = Passwd::parse(line) { - if user == passwd.user && password_hash == passwd.hash { - passwd_option = Some(passwd); - break; - } - } - } - } - } - - if let Some(passwd) = passwd_option { - if let Ok(mut motd) = File::open("/etc/motd") { - io::copy(&mut motd, &mut stdout).unwrap(); - let _ = stdout.flush(); - } - - let mut command = Command::new(passwd.shell); - - command.uid(passwd.uid); - command.gid(passwd.gid); - - command.current_dir(passwd.home); - - command.env("USER", &user); - command.env("HOME", passwd.home); - command.env("PATH", "file:bin"); - - match command.spawn() { - Ok(mut child) => match child.wait() { - Ok(_status) => (), //println!("login: waited for {}: {:?}", sh, status.code()), - Err(err) => panic!("login: failed to wait for '{}': {}", passwd.shell, err) - }, - Err(err) => panic!("login: failed to execute '{}': {}", passwd.shell, err) - } - - break; - } else { - stdout.write(b"\nLogin failed\n").unwrap(); - let _ = stdout.flush(); - } - } else { - stdout.write(b"\n").unwrap(); - let _ = stdout.flush(); - } - } -} diff --git a/programs/sudo/Cargo.toml b/programs/sudo/Cargo.toml deleted file mode 100644 index 7ca45f7..0000000 --- a/programs/sudo/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "sudo" -version = "0.1.0" - -[dependencies] -syscall = { path = "../../syscall/" } diff --git a/programs/sudo/src/main.rs b/programs/sudo/src/main.rs deleted file mode 100644 index f9306f9..0000000 --- a/programs/sudo/src/main.rs +++ /dev/null @@ -1,123 +0,0 @@ -#![feature(question_mark)] - -extern crate syscall; - -use std::env; -use std::fs::File; -use std::io::Read; -use std::os::unix::process::CommandExt; -use std::process::{self, Command}; - -pub struct Passwd<'a> { - user: &'a str, - hash: &'a str, - uid: u32, - gid: u32, - name: &'a str, - home: &'a str, - shell: &'a str -} - -impl<'a> Passwd<'a> { - pub fn parse(line: &'a str) -> Result, ()> { - let mut parts = line.split(';'); - - let user = parts.next().ok_or(())?; - let hash = parts.next().ok_or(())?; - let uid = parts.next().ok_or(())?.parse::().or(Err(()))?; - let gid = parts.next().ok_or(())?.parse::().or(Err(()))?; - let name = parts.next().ok_or(())?; - let home = parts.next().ok_or(())?; - let shell = parts.next().ok_or(())?; - - Ok(Passwd { - user: user, - hash: hash, - uid: uid, - gid: gid, - name: name, - home: home, - shell: shell - }) - } -} - -pub struct Group<'a> { - group: &'a str, - gid: u32, - users: &'a str, -} - -impl<'a> Group<'a> { - pub fn parse(line: &'a str) -> Result, ()> { - let mut parts = line.split(';'); - - let group = parts.next().ok_or(())?; - let gid = parts.next().ok_or(())?.parse::().or(Err(()))?; - let users = parts.next().ok_or(())?; - - Ok(Group { - group: group, - gid: gid, - users: users - }) - } -} - -pub fn main() { - let mut args = env::args().skip(1); - let cmd = args.next().expect("sudo: no command provided"); - - let uid = syscall::getuid().unwrap() as u32; - - if uid != 0 { - let mut passwd_string = String::new(); - File::open("file:etc/passwd").unwrap().read_to_string(&mut passwd_string).unwrap(); - - let mut passwd_option = None; - for line in passwd_string.lines() { - if let Ok(passwd) = Passwd::parse(line) { - if uid == passwd.uid { - passwd_option = Some(passwd); - break; - } - } - } - - let passwd = passwd_option.expect("sudo: user not found in passwd"); - - let mut group_string = String::new(); - File::open("file:etc/group").unwrap().read_to_string(&mut group_string).unwrap(); - - let mut group_option = None; - for line in group_string.lines() { - if let Ok(group) = Group::parse(line) { - if group.group == "sudo" && group.users.split(',').any(|name| name == passwd.user) { - group_option = Some(group); - break; - } - } - } - - if group_option.is_none() { - panic!("sudo: '{}' not in sudo group", passwd.user); - } - } - - let mut command = Command::new(&cmd); - for arg in args { - command.arg(&arg); - } - - command.uid(0); - command.gid(0); - command.env("USER", "root"); - - match command.spawn() { - Ok(mut child) => match child.wait() { - Ok(status) => process::exit(status.code().unwrap_or(0)), - Err(err) => panic!("sudo: failed to wait for {}: {}", cmd, err) - }, - Err(err) => panic!("sudo: failed to execute {}: {}", cmd, err) - } -} diff --git a/programs/userutils b/programs/userutils new file mode 160000 index 0000000..eaf2676 --- /dev/null +++ b/programs/userutils @@ -0,0 +1 @@ +Subproject commit eaf26765c12efe5519fb2af72557dc0ee8286bcd