Compare commits

..

5 Commits

Author SHA1 Message Date
3794c4d175 Add setup instructions 2022-03-21 14:05:34 +01:00
ac9f033656 Add subcommands 2022-03-21 13:56:52 +01:00
5350b380e2 Show code lifetime 2022-03-21 12:24:47 +01:00
84d1a3cc9b Remove useless dependency 2022-03-21 12:09:23 +01:00
96656afdae Managed to generate a first secret 2022-03-21 12:08:58 +01:00
3 changed files with 67 additions and 24 deletions

8
Cargo.lock generated
View File

@ -20,10 +20,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]] [[package]]
name = "base64" name = "base32"
version = "0.13.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" checksum = "23ce669cd6c8588f79e15cf450314f9638f967fc5770ff1c7c1deb0925ea7cfa"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
@ -260,7 +260,7 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
name = "totp_generator" name = "totp_generator"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"base64", "base32",
"clap", "clap",
"totp_rfc6238", "totp_rfc6238",
] ]

View File

@ -7,5 +7,5 @@ edition = "2018"
[dependencies] [dependencies]
totp_rfc6238 = "0.5.0" totp_rfc6238 = "0.5.0"
base64 = "0.13.0" base32 = "0.4.0"
clap = { version = "3.1.6", features = ["derive"] } clap = { version = "3.1.6", features = ["derive"] }

View File

@ -1,34 +1,77 @@
use clap::Parser; use std::time::{SystemTime, UNIX_EPOCH};
use base32::Alphabet;
use clap::{Parser, Subcommand};
use totp_rfc6238::{HashAlgorithm, TotpGenerator}; use totp_rfc6238::{HashAlgorithm, TotpGenerator};
/// Get the current time since epoch
pub fn time() -> u64 {
SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()
}
/// TOTP - One Time Password generator /// TOTP - One Time Password generator
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)] #[clap(author, version, about, long_about = None)]
struct Args { struct Args {
/// The secret to use #[clap(subcommand)]
#[clap(short, long)] command: SubCommands
secret: String, }
/// Interval between two numbers generation #[derive(Subcommand, Debug)]
#[clap(short, long, default_value_t = 30)] enum SubCommands {
topt_step: u64, /// Setup configuration
Setup,
/// Size of generated secret /// Get a TOTP code
#[clap(short, long, default_value_t = 6)] #[clap(arg_required_else_help = true)]
len: usize, Code {
/// 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();
let totp_generator = TotpGenerator::new() match args.command {
.set_digit(args.len).unwrap() SubCommands::Setup => {
.set_step(args.topt_step).unwrap() println!("To configure TOPT :");
.set_hash_algorithm(HashAlgorithm::SHA1) println!("1. Please open https://mysignins.microsoft.com/security-info");
.build(); println!("2. Click on \"Add method\"");
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");
}
let key = base64::decode(args.secret).unwrap(); SubCommands::Code { secret, topt_step, len } => {
let code = totp_generator.get_code(&key); let totp_generator = TotpGenerator::new()
.set_digit(len).unwrap()
.set_step(topt_step).unwrap()
.set_hash_algorithm(HashAlgorithm::SHA1)
.build();
println!("Secret len = {}", code); let key = base32::decode(
Alphabet::RFC4648 { padding: true },
&secret,
).unwrap();
let code = totp_generator.get_code(&key);
let next_update = totp_generator.get_next_update_time().unwrap();
println!("Secret = {}", code);
println!("Next update = {} seconds", next_update - time());
}
}
} }