|
| 1 | +use std::io::Write; |
| 2 | + |
| 3 | +use agnos::config::Config; |
| 4 | +use clap::{Arg, ArgAction}; |
| 5 | + |
| 6 | +fn main() -> anyhow::Result<()> { |
| 7 | + let mut stdin_lines = std::io::stdin().lines(); |
| 8 | + let cli_ops = clap::command!() |
| 9 | + .about("Generate non existing private accounts keys from agnos' configuration.") |
| 10 | + .arg_required_else_help(true) |
| 11 | + .arg( |
| 12 | + Arg::new("config") |
| 13 | + .required(true) |
| 14 | + .action(ArgAction::Set) |
| 15 | + .value_name("config.toml") |
| 16 | + .help("Path to the configuration file."), |
| 17 | + ) |
| 18 | + .arg( |
| 19 | + Arg::new("key-size") |
| 20 | + .long("key-size") |
| 21 | + .action(ArgAction::Set) |
| 22 | + .default_value("4096") |
| 23 | + .help("Size in bits of the RSA private key.") |
| 24 | + .value_parser(clap::value_parser!(u32)), |
| 25 | + ) |
| 26 | + .arg( |
| 27 | + Arg::new("no-confirm") |
| 28 | + .long("no-confirm") |
| 29 | + .action(ArgAction::SetTrue) |
| 30 | + .help("Do not prompt user and create all non-existing keys."), |
| 31 | + ) |
| 32 | + .get_matches(); |
| 33 | + let key_size = cli_ops.get_one("key-size").unwrap(); |
| 34 | + let no_confirm = cli_ops.get_flag("no-confirm"); |
| 35 | + let config_file = std::fs::read_to_string(cli_ops.get_one::<String>("config").unwrap())?; |
| 36 | + let config: Config = toml::from_str(&config_file)?; |
| 37 | + 'accounts_loop: for account in config.accounts { |
| 38 | + if !account.private_key_path.exists() { |
| 39 | + println!( |
| 40 | + "Private key for account <{}> expected to be located at {} does not exist.", |
| 41 | + account.email, |
| 42 | + account.private_key_path.display() |
| 43 | + ); |
| 44 | + if !no_confirm { |
| 45 | + 'input_loop: loop { |
| 46 | + print!("Do you want to create it? (y(es) | n(o) -- default: yes)? "); |
| 47 | + std::io::stdout().flush()?; |
| 48 | + let l = match stdin_lines.next() { |
| 49 | + None => return Ok(()), |
| 50 | + Some(l) => l?, |
| 51 | + }; |
| 52 | + match l.trim() { |
| 53 | + "" | "y" | "yes" | "Y" | "YES" => break 'input_loop, |
| 54 | + "n" | "no" | "N" | "NO" => continue 'accounts_loop, |
| 55 | + _ => continue 'input_loop, |
| 56 | + } |
| 57 | + } |
| 58 | + } |
| 59 | + print!("Generating private key... "); |
| 60 | + std::io::stdout().flush()?; |
| 61 | + let key = openssl::rsa::Rsa::generate(*key_size)?; |
| 62 | + let pem = key.private_key_to_pem()?; |
| 63 | + std::fs::write(account.private_key_path, &pem)?; |
| 64 | + println!("Private key generated!") |
| 65 | + } |
| 66 | + } |
| 67 | + Ok(()) |
| 68 | +} |
0 commit comments