added --debug CLI flag

This commit is contained in:
Eugene Pankov 2022-09-05 23:33:00 +02:00
parent 3f83eba680
commit 26b55494b5
No known key found for this signature in database
GPG key ID: 5896FCBBDD1CF4F4
6 changed files with 23 additions and 92 deletions

View file

@ -5,7 +5,7 @@ use anyhow::{Context, Result};
use russh_keys::key::{KeyPair, SignatureHash};
use russh_keys::{encode_pkcs8_pem, load_secret_key};
use tracing::*;
use warpgate_common::helpers::fs::secure_directory;
use warpgate_common::helpers::fs::{secure_directory, secure_file};
use warpgate_common::WarpgateConfig;
fn get_keys_path(config: &WarpgateConfig) -> PathBuf {
@ -23,18 +23,20 @@ pub fn generate_host_keys(config: &WarpgateConfig) -> Result<()> {
if !key_path.exists() {
info!("Generating Ed25519 host key");
let key = KeyPair::generate_ed25519().context("Failed to generate Ed25519 host key")?;
let f = File::create(key_path)?;
let f = File::create(&key_path)?;
encode_pkcs8_pem(&key, f)?;
}
secure_file(&key_path)?;
let key_path = path.join("host-rsa");
if !key_path.exists() {
info!("Generating RSA host key");
let key = KeyPair::generate_rsa(4096, SignatureHash::SHA2_512)
.context("Failed to generate RSA key")?;
let f = File::create(key_path)?;
let f = File::create(&key_path)?;
encode_pkcs8_pem(&key, f)?;
}
secure_file(&key_path)?;
Ok(())
}
@ -61,18 +63,20 @@ pub fn generate_client_keys(config: &WarpgateConfig) -> Result<()> {
if !key_path.exists() {
info!("Generating Ed25519 client key");
let key = KeyPair::generate_ed25519().context("Failed to generate Ed25519 client key")?;
let f = File::create(key_path)?;
let f = File::create(&key_path)?;
encode_pkcs8_pem(&key, f)?;
}
secure_file(&key_path)?;
let key_path = path.join("client-rsa");
if !key_path.exists() {
info!("Generating RSA client key");
let key = KeyPair::generate_rsa(4096, SignatureHash::SHA2_512)
.context("Failed to generate RSA client key")?;
let f = File::create(key_path)?;
let f = File::create(&key_path)?;
encode_pkcs8_pem(&key, f)?;
}
secure_file(&key_path)?;
Ok(())
}

View file

@ -1,21 +0,0 @@
use std::io::stdin;
use anyhow::Result;
use dialoguer::theme::ColorfulTheme;
use warpgate_common::helpers::hash::hash_password;
pub(crate) async fn command() -> Result<()> {
let mut input = String::new();
if atty::is(atty::Stream::Stdin) {
input = dialoguer::Password::with_theme(&ColorfulTheme::default())
.with_prompt("Password to be hashed")
.interact()?;
} else {
stdin().read_line(&mut input)?;
}
let hash = hash_password(&input);
println!("{}", hash);
Ok(())
}

View file

@ -1,7 +1,5 @@
pub mod check;
pub mod client_keys;
pub mod hash;
pub mod otp;
pub mod run;
pub mod setup;
pub mod test_target;

View file

@ -1,54 +0,0 @@
use ansi_term::Color::{Black, White};
use ansi_term::Style;
use anyhow::Result;
use data_encoding::BASE64;
use qrcode::{Color, QrCode};
use tracing::*;
use warpgate_common::helpers::otp::{generate_key, generate_setup_url};
pub(crate) async fn command() -> Result<()> {
let key = generate_key();
let url = generate_setup_url(&key, "test");
let code = QrCode::new(url.expose_secret().as_bytes())?;
let width = code.width();
let pixels = code.into_colors();
for _ in 0..width + 4 {
print!("{}", Style::new().on(White).paint(" "));
}
println!();
for hy in 0..(pixels.len() + width - 1) / width / 2 + 1 {
print!("{}", Style::new().on(White).paint(" "));
for x in 0..width {
let top = pixels
.get(hy * 2 * width + x)
.map(|x| *x == Color::Dark)
.unwrap_or(false);
let bottom = pixels
.get((hy * 2 + 1) * width + x)
.map(|x| *x == Color::Dark)
.unwrap_or(false);
print!(
"{}",
match (top, bottom) {
(true, true) => Style::new().fg(Black).paint(""),
(true, false) => Style::new().fg(Black).on(White).paint(""),
(false, true) => Style::new().fg(Black).on(White).paint(""),
(false, false) => Style::new().on(White).paint(" "),
}
);
}
println!("{}", Style::new().on(White).paint(" "));
}
println!();
info!("Setup URL: {}", url.expose_secret());
info!("Config file snippet:");
println!();
println!(" - type: otp");
println!(" key: {}", BASE64.encode(key.expose_secret()));
Ok(())
}

View file

@ -9,9 +9,16 @@ use tracing_subscriber::{EnvFilter, Layer};
use warpgate_common::WarpgateConfig;
use warpgate_core::logging::{make_database_logger_layer, make_socket_logger_layer};
pub async fn init_logging(config: Option<&WarpgateConfig>) {
use crate::Cli;
pub async fn init_logging(config: Option<&WarpgateConfig>, cli: &Cli) {
if std::env::var("RUST_LOG").is_err() {
std::env::set_var("RUST_LOG", "warpgate=info")
match cli.debug {
0 => std::env::set_var("RUST_LOG", "warpgate=info"),
1 => std::env::set_var("RUST_LOG", "warpgate=debug"),
2 => std::env::set_var("RUST_LOG", "warpgate=debug,russh=debug"),
_ => std::env::set_var("RUST_LOG", "debug"),
}
}
let offset = UtcOffset::current_local_offset().unwrap_or(UtcOffset::UTC);

View file

@ -18,12 +18,15 @@ static ALLOC: dhat::Alloc = dhat::Alloc;
#[derive(clap::Parser)]
#[clap(author, version, about, long_about = None)]
#[clap(propagate_version = true)]
struct Cli {
pub struct Cli {
#[clap(subcommand)]
command: Commands,
#[clap(long, short, default_value = "/etc/warpgate.yaml", action=ArgAction::Set)]
config: PathBuf,
#[clap(long, short, action=ArgAction::Count)]
debug: u8,
}
#[derive(clap::Subcommand)]
@ -35,33 +38,27 @@ enum Commands {
/// Run Warpgate
Run,
/// Create a password hash for use in the config file
Hash,
/// Validate config file
Check,
/// Test the connection to a target host
TestTarget {
#[clap(action=ArgAction::Set)]
target_name: String,
},
/// Generate a new 2FA (TOTP) enrollment key
GenerateOtp,
}
async fn _main() -> Result<()> {
let cli = Cli::parse();
init_logging(load_config(&cli.config, false).ok().as_ref()).await;
init_logging(load_config(&cli.config, false).ok().as_ref(), &cli).await;
match &cli.command {
Commands::Run => crate::commands::run::command(&cli).await,
Commands::Hash => crate::commands::hash::command().await,
Commands::Check => crate::commands::check::command(&cli).await,
Commands::TestTarget { target_name } => {
crate::commands::test_target::command(&cli, target_name).await
}
Commands::Setup => crate::commands::setup::command(&cli).await,
Commands::ClientKeys => crate::commands::client_keys::command(&cli).await,
Commands::GenerateOtp => crate::commands::otp::command().await,
}
}