Compare commits

..

No commits in common. "3794c4d17545afca24999b7dd15e69ba4453d5c2" and "5350b380e287951afd143d8954fdac76413f81a0" have entirely different histories.

View File

@ -1,7 +1,7 @@
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
use base32::Alphabet; use base32::Alphabet;
use clap::{Parser, Subcommand}; use clap::Parser;
use totp_rfc6238::{HashAlgorithm, TotpGenerator}; use totp_rfc6238::{HashAlgorithm, TotpGenerator};
/// Get the current time since epoch /// Get the current time since epoch
@ -14,64 +14,36 @@ pub fn time() -> u64 {
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)] #[clap(author, version, about, long_about = None)]
struct Args { struct Args {
#[clap(subcommand)] /// The secret to use
command: SubCommands #[clap(short, long)]
} secret: String,
#[derive(Subcommand, Debug)] /// Interval between two numbers generation
enum SubCommands { #[clap(short, long, default_value_t = 30)]
/// Setup configuration topt_step: u64,
Setup,
/// Get a TOTP code /// Size of generated secret
#[clap(arg_required_else_help = true)] #[clap(short, long, default_value_t = 6)]
Code { len: usize,
/// The secret to use
#[clap(short, long)]
secret: String,
/// Interval between two numbers generation
#[clap(short, long, default_value_t = 30)]
topt_step: u64,
/// Size of generated secret
#[clap(short, long, default_value_t = 6)]
len: usize,
},
} }
fn main() { fn main() {
let args: Args = Args::parse(); let args: Args = Args::parse();
match args.command { let totp_generator = TotpGenerator::new()
SubCommands::Setup => { .set_digit(args.len).unwrap()
println!("To configure TOPT :"); .set_step(args.topt_step).unwrap()
println!("1. Please open https://mysignins.microsoft.com/security-info"); .set_hash_algorithm(HashAlgorithm::SHA1)
println!("2. Click on \"Add method\""); .build();
println!("3. On the popup that appears, choose \"Authenticator app\" and click \"Add\".");
println!("4. Click on \"I want to use a different authenticator app\" and click \"Next\"");
println!("5. Click on \"Can't save image ?\" and copy the \"Secret key\"");
println!("6. Re-run this program running {} code --secret <SECRET>", std::env::args().next().unwrap());
println!("7. Back on the browser, click Next and paste copied code");
}
SubCommands::Code { secret, topt_step, len } => { let key = base32::decode(
let totp_generator = TotpGenerator::new() Alphabet::RFC4648 { padding: true },
.set_digit(len).unwrap() &args.secret,
.set_step(topt_step).unwrap() ).unwrap();
.set_hash_algorithm(HashAlgorithm::SHA1)
.build();
let key = base32::decode( let code = totp_generator.get_code(&key);
Alphabet::RFC4648 { padding: true }, let next_update = totp_generator.get_next_update_time().unwrap();
&secret,
).unwrap();
let code = totp_generator.get_code(&key); println!("Secret = {}", code);
let next_update = totp_generator.get_next_update_time().unwrap(); println!("Next update = {} seconds", next_update - time());
println!("Secret = {}", code);
println!("Next update = {} seconds", next_update - time());
}
}
} }