Compare commits
No commits in common. "3794c4d17545afca24999b7dd15e69ba4453d5c2" and "5350b380e287951afd143d8954fdac76413f81a0" have entirely different histories.
3794c4d175
...
5350b380e2
74
src/main.rs
74
src/main.rs
@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user