use std::io::{Read, Write}; use std::path::Path; use clap::Args; use clap::{Parser, Subcommand}; mod config; #[derive(Parser)] #[command(version, about, long_about=include_str!("../README.md"))] struct Cli { #[command(subcommand)] command: Commands, } #[derive(Subcommand)] enum Commands { Auth(Auth), Login(Login), } #[derive(Args)] struct Auth { user: String, home: String, keytype: String, keydata: String, } #[derive(Args)] struct Login { keytype: String, keydata: String, } fn main() { systemd_journal_logger::JournalLog::new() .unwrap() .with_extra_fields(vec![("VERSION", env!("CARGO_PKG_VERSION"))]) .with_syslog_identifier("fagit".to_string()) .install() .unwrap(); log::set_max_level(log::LevelFilter::Info); let args = std::env::args().collect::>(); if args.len() == 0 { println!(include_str!("../README.md")); } let cli = Cli::parse(); match &cli.command { Commands::Auth(auth) => find_auth_keys(auth), Commands::Login(login) => crate::login::do_login(login), } } mod login; fn find_auth_keys(auth: &Auth) { if auth.user != config::ssh_user() { let authorized_keys_path = Path::new(&auth.home).join(".ssh/authorized_keys"); let mut data = std::fs::File::open(authorized_keys_path).unwrap(); let mut vec = vec![]; data.read_to_end(&mut vec).unwrap(); std::io::stdout().write_all(&vec).unwrap(); return; } // TODO: escape shit in here properly let login_command = format!( "{} login {} {}", config::binary_path(), auth.keytype, auth.keydata ); println!("command=\"{}\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,no-user-rc,restrict {} {}", login_command, auth.keytype, auth.keydata ); }