Split login into getty and login, like other UNIXen
This commit is contained in:
parent
5a99ba6863
commit
cd47a60595
2
Makefile
2
Makefile
|
@ -28,6 +28,7 @@ clean:
|
||||||
cargo clean --manifest-path drivers/ps2d/Cargo.toml
|
cargo clean --manifest-path drivers/ps2d/Cargo.toml
|
||||||
cargo clean --manifest-path drivers/pcid/Cargo.toml
|
cargo clean --manifest-path drivers/pcid/Cargo.toml
|
||||||
cargo clean --manifest-path drivers/vesad/Cargo.toml
|
cargo clean --manifest-path drivers/vesad/Cargo.toml
|
||||||
|
cargo clean --manifest-path programs/getty/Cargo.toml
|
||||||
cargo clean --manifest-path programs/init/Cargo.toml
|
cargo clean --manifest-path programs/init/Cargo.toml
|
||||||
cargo clean --manifest-path programs/ion/Cargo.toml
|
cargo clean --manifest-path programs/ion/Cargo.toml
|
||||||
cargo clean --manifest-path programs/login/Cargo.toml
|
cargo clean --manifest-path programs/login/Cargo.toml
|
||||||
|
@ -274,6 +275,7 @@ $(BUILD)/filesystem.bin: \
|
||||||
coreutils \
|
coreutils \
|
||||||
extrautils \
|
extrautils \
|
||||||
schemes \
|
schemes \
|
||||||
|
filesystem/bin/getty \
|
||||||
filesystem/bin/ion \
|
filesystem/bin/ion \
|
||||||
filesystem/bin/login \
|
filesystem/bin/login \
|
||||||
filesystem/bin/smith
|
filesystem/bin/smith
|
||||||
|
|
6
filesystem/etc/issue
Normal file
6
filesystem/etc/issue
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
########## Redox OS ##########
|
||||||
|
# Login with the following: #
|
||||||
|
# `root` #
|
||||||
|
# `user`:`password` #
|
||||||
|
##############################
|
||||||
|
|
2
filesystem/etc/motd
Normal file
2
filesystem/etc/motd
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Welcome to Redox OS!
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
root;A69F73CCA23A9AC5C8B567DC185A756E97C982164FE25859E0D1DCC1475C80A615B2123AF1F5F94C11E3E9402C3AC558F50199D95B6D3E31758586281DCD26;0;0;root;file:root;file:bin/ion
|
root;;0;0;root;file:root;file:bin/ion
|
||||||
user;A69F73CCA23A9AC5C8B567DC185A756E97C982164FE25859E0D1DCC1475C80A615B2123AF1F5F94C11E3E9402C3AC558F50199D95B6D3E31758586281DCD26;1000;1000;user;file:home/user;file:bin/ion
|
user;E9A75486736A55AF4FEA861E237835C4A555A05094DEE1DCA2F68AFEA49CC3A5E8DE6EA131EA521311F4D6FB054A146E8282F8E35FF2E6368C1A62E909716;1000;1000;user;file:home/user;file:bin/ion
|
||||||
|
|
|
@ -2,4 +2,4 @@ initfs:bin/pcid initfs:etc/pcid.toml
|
||||||
initfs:bin/redoxfs disk:0
|
initfs:bin/redoxfs disk:0
|
||||||
file:bin/vesad
|
file:bin/vesad
|
||||||
file:bin/ps2d
|
file:bin/ps2d
|
||||||
file:bin/login display:
|
file:bin/getty display:
|
||||||
|
|
6
programs/getty/Cargo.toml
Normal file
6
programs/getty/Cargo.toml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "getty"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
syscall = { path = "../../syscall/" }
|
52
programs/getty/src/main.rs
Normal file
52
programs/getty/src/main.rs
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#![feature(question_mark)]
|
||||||
|
|
||||||
|
extern crate syscall;
|
||||||
|
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{Read, 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
|
@ -3,7 +3,6 @@ name = "login"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
syscall = { path = "../../syscall/" }
|
|
||||||
termion = "*"
|
termion = "*"
|
||||||
|
|
||||||
[dependencies.octavo]
|
[dependencies.octavo]
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#![feature(question_mark)]
|
#![feature(question_mark)]
|
||||||
|
|
||||||
extern crate octavo;
|
extern crate octavo;
|
||||||
extern crate syscall;
|
|
||||||
extern crate termion;
|
extern crate termion;
|
||||||
|
|
||||||
use octavo::octavo_digest::Digest;
|
use octavo::octavo_digest::Digest;
|
||||||
|
@ -47,48 +46,43 @@ impl<'a> Passwd<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let mut args = env::args().skip(1);
|
let stdin = io::stdin();
|
||||||
|
let mut stdin = stdin.lock();
|
||||||
|
let stdout = io::stdout();
|
||||||
|
let mut stdout = stdout.lock();
|
||||||
|
|
||||||
let tty = args.next().expect("login: no tty provided");
|
if let Ok(mut issue) = File::open("/etc/issue") {
|
||||||
|
io::copy(&mut issue, &mut stdout).unwrap();
|
||||||
let _ = syscall::close(2);
|
let _ = stdout.flush();
|
||||||
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 || {
|
loop {
|
||||||
let stdin = io::stdin();
|
stdout.write_all(b"\x1B[1mredox login:\x1B[0m ").unwrap();
|
||||||
let mut stdin = stdin.lock();
|
let _ = stdout.flush();
|
||||||
let stdout = io::stdout();
|
|
||||||
let mut stdout = stdout.lock();
|
|
||||||
|
|
||||||
loop {
|
let user = (&mut stdin as &mut Read).read_line().unwrap().unwrap_or(String::new());
|
||||||
stdout.write_all(b"\x1B[1mredox login:\x1B[0m ").unwrap();
|
if ! user.is_empty() {
|
||||||
let _ = stdout.flush();
|
let mut passwd_string = String::new();
|
||||||
|
File::open("file:etc/passwd").unwrap().read_to_string(&mut passwd_string).unwrap();
|
||||||
|
|
||||||
let user = (&mut stdin as &mut Read).read_line().unwrap().unwrap_or(String::new());
|
let mut passwd_option = None;
|
||||||
if ! user.is_empty() {
|
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();
|
stdout.write_all(b"\x1B[1mpassword:\x1B[0m ").unwrap();
|
||||||
let _ = stdout.flush();
|
let _ = stdout.flush();
|
||||||
|
|
||||||
if let Some(password) = stdin.read_passwd(&mut stdout).unwrap() {
|
if let Some(password) = stdin.read_passwd(&mut stdout).unwrap() {
|
||||||
|
stdout.write(b"\n").unwrap();
|
||||||
|
let _ = stdout.flush();
|
||||||
|
|
||||||
let password_hash = {
|
let password_hash = {
|
||||||
let mut output = vec![0; Sha512::output_bytes()];
|
let mut output = vec![0; Sha512::output_bytes()];
|
||||||
let mut hash = Sha512::default();
|
let mut hash = Sha512::default();
|
||||||
|
@ -101,15 +95,10 @@ pub fn main() {
|
||||||
encoded
|
encoded
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
if let Ok(mut debug) = File::open("debug:") {
|
||||||
let mut debug = File::open("debug:").unwrap();
|
let _ = write!(debug, "{};{}\n", user, password_hash);
|
||||||
write!(debug, "{};{}\n", user, password_hash).unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
for line in passwd_string.lines() {
|
||||||
if let Ok(passwd) = Passwd::parse(line) {
|
if let Ok(passwd) = Passwd::parse(line) {
|
||||||
if user == passwd.user && password_hash == passwd.hash {
|
if user == passwd.user && password_hash == passwd.hash {
|
||||||
|
@ -118,37 +107,39 @@ pub fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(passwd) = passwd_option {
|
|
||||||
stdout.write(b"\n").unwrap();
|
|
||||||
let _ = stdout.flush();
|
|
||||||
|
|
||||||
let mut command = Command::new(passwd.shell);
|
|
||||||
|
|
||||||
env::set_current_dir(passwd.home).unwrap();
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
env::set_current_dir("file:").unwrap();
|
|
||||||
|
|
||||||
stdout.write(b"\x1Bc").unwrap();
|
|
||||||
let _ = stdout.flush();
|
|
||||||
} else {
|
|
||||||
stdout.write(b"\nLogin failed\n").unwrap();
|
|
||||||
let _ = stdout.flush();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
env::set_current_dir(passwd.home).unwrap();
|
||||||
|
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue