Skip to content

Commit

Permalink
feat: Implement dump-seeds command
Browse files Browse the repository at this point in the history
  • Loading branch information
jaysonsantos committed Aug 12, 2021
1 parent 9ea6b5c commit 02b4ae4
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 10 deletions.
16 changes: 10 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ enum Config {
#[structopt(short, long, help = "fuzzy search a service by its name")]
service_name: String,
},
DumpSeeds,
}

pub fn setup_error_handlers() -> Result<()> {
Expand Down Expand Up @@ -121,6 +122,26 @@ async fn work() -> Result<()> {
)
}
}
Config::DumpSeeds => {
let client = get_saved_client()?;
let mut services: Vec<AuthenticatorToken> = match mambembe_keyring::get() {
Ok(services) => services,
Err(MambembeKeyringError::NoPasswordFound) => {
let services = client.list_authenticator_tokens().await?;
mambembe_keyring::set(&services).unwrap();
services
}
Err(err) => return Err(err.into()),
};
for service in services.iter_mut() {
client.initialize_authenticator_token(service)?;
println!(
"Servie: {} Seed: {}",
service.name,
&service.dump_seed()?
);
}
}
}

// client.check_current_device().await?;
Expand Down
1 change: 1 addition & 0 deletions keyring/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ mambembe-lib = { path = "../lib" }
serde = "1.0.125"
serde_json = "1.0.64"
thiserror = "1.0.24"
tracing = "0.1.26"

[features]
with-keyring = ["keyring"]
Expand Down
5 changes: 5 additions & 0 deletions keyring/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use keyring::{Keyring, KeyringError};
use serde::{de::DeserializeOwned, Serialize};
use serde_json::{from_str, to_string_pretty};
use thiserror::Error;
use tracing::instrument;

use mambembe_lib::{models::AuthenticatorToken, AuthyClient};

Expand Down Expand Up @@ -35,17 +36,20 @@ pub trait Data<T> {
}

impl<T> Data<T> for AuthyClient {
#[instrument]
fn get_keyring() -> &'static Keyring<'static> {
&DEVICES
}
}

impl<T> Data<T> for Vec<AuthenticatorToken> {
#[instrument]
fn get_keyring() -> &'static Keyring<'static> {
&TOKENS
}
}

#[instrument]
pub fn get<T>() -> Result<T>
where
T: DeserializeOwned + Data<T>,
Expand All @@ -58,6 +62,7 @@ where
Ok(from_str(&data)?)
}

#[instrument(skip(data))]
pub fn set<T>(data: &T) -> Result<()>
where
T: Serialize + Data<T>,
Expand Down
1 change: 1 addition & 0 deletions lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ aes = "*"
async-trait = "0.1.48"
block-modes = "*"
data-encoding = "2.3.2"
hex = "0.4.3"
hmac = "0.10.1"
itertools = "0.10.0"
json = "0.12.4"
Expand Down
16 changes: 13 additions & 3 deletions lib/src/models.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use data_encoding::HEXLOWER;
use data_encoding::{BASE32, HEXLOWER};
use serde::{Deserialize, Serialize};
use sha2::Digest;

use crate::{
client::TimeSync, crypto::decrypt_data, error::Result, password::derive_key,
tokens::calculate_future_tokens, MambembeError,
client::TimeSync,
crypto::decrypt_data,
error::Result,
password::derive_key,
tokens::{calculate_future_tokens, decode_seed},
MambembeError,
};

pub type Pin = String;
Expand Down Expand Up @@ -89,4 +93,10 @@ impl AuthenticatorToken {

Ok(data)
}

pub fn dump_seed(&self) -> Result<String> {
self.decrypt_seed()
.map(decode_seed)
.map(|seed| BASE32.encode(&seed)) // Re-encode again because most of the clients expect this
}
}
6 changes: 5 additions & 1 deletion lib/src/tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@ pub(crate) fn calculate_token(
digits: usize,
time_sync: Option<&TimeSync>,
) -> InternalResult<String> {
let seed = BASE32.decode(seed).unwrap_or_else(|_| seed.to_vec());
let seed = decode_seed(seed);
// let seed = HEXLOWER.encode(&seed);
let time = get_time(time_sync);
let s = build_slauth_context(&seed, digits, time / OTHERS_DEFAULT_PERIOD);
Ok(s.gen())
}

pub(crate) fn decode_seed<T>(seed: T) -> Vec<u8> where T: AsRef<[u8]> {
BASE32.decode(seed.as_ref()).unwrap_or_else(|_| seed.as_ref().to_vec())
}

pub(crate) fn build_slauth_context(seed: &[u8], digits: usize, padded_time: u64) -> HOTPContext {
HOTPBuilder::new()
.algorithm(HashesAlgorithm::SHA1)
Expand Down

0 comments on commit 02b4ae4

Please sign in to comment.