dls: add password hash function
This commit is contained in:
804
Cargo.lock
generated
804
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -28,10 +28,12 @@ hex = "0.4.3"
|
|||||||
human-units = "0.5.3"
|
human-units = "0.5.3"
|
||||||
log = "0.4.27"
|
log = "0.4.27"
|
||||||
lz4 = "1.28.1"
|
lz4 = "1.28.1"
|
||||||
nix = { version = "0.30.1", features = ["user"] }
|
nix = { version = "0.31.2", features = ["user"] }
|
||||||
openssl = "0.10.73"
|
openssl = "0.10.73"
|
||||||
page_size = "0.6.0"
|
page_size = "0.6.0"
|
||||||
reqwest = { version = "0.13.1", features = ["json", "stream", "native-tls", "socks"] }
|
reqwest = { version = "0.13.1", features = ["json", "stream", "native-tls", "socks"], default-features = false }
|
||||||
|
rpassword = "7.4.0"
|
||||||
|
rust-argon2 = "3.0.0"
|
||||||
serde = { version = "1.0.219", features = ["derive"] }
|
serde = { version = "1.0.219", features = ["derive"] }
|
||||||
serde_json = "1.0.140"
|
serde_json = "1.0.140"
|
||||||
serde_yaml = "0.9.34"
|
serde_yaml = "0.9.34"
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ enum Command {
|
|||||||
},
|
},
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
DlSet(DlSet),
|
DlSet(DlSet),
|
||||||
|
/// hash a password
|
||||||
|
Hash {
|
||||||
|
salt: String,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
@@ -103,14 +107,16 @@ async fn main() -> eyre::Result<()> {
|
|||||||
.parse_default_env()
|
.parse_default_env()
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
let token = std::env::var("DLS_TOKEN").map_err(|_| format_err!("DLS_TOKEN should be set"))?;
|
let dls = || {
|
||||||
|
let token = std::env::var("DLS_TOKEN").expect("DLS_TOKEN should be set");
|
||||||
let dls = dls::Client::new(cli.dls, token);
|
dls::Client::new(cli.dls, token)
|
||||||
|
};
|
||||||
|
|
||||||
use Command as C;
|
use Command as C;
|
||||||
match cli.command {
|
match cli.command {
|
||||||
C::Clusters => write_json(&dls.clusters().await?),
|
C::Clusters => write_json(&dls().clusters().await?),
|
||||||
C::Cluster { cluster, command } => {
|
C::Cluster { cluster, command } => {
|
||||||
|
let dls = dls();
|
||||||
let cluster = dls.cluster(cluster);
|
let cluster = dls.cluster(cluster);
|
||||||
|
|
||||||
use ClusterCommand as CC;
|
use ClusterCommand as CC;
|
||||||
@@ -155,8 +161,9 @@ async fn main() -> eyre::Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
C::Hosts => write_json(&dls.hosts().await?),
|
C::Hosts => write_json(&dls().hosts().await?),
|
||||||
C::Host { out, host, asset } => {
|
C::Host { out, host, asset } => {
|
||||||
|
let dls = dls();
|
||||||
let host_name = host.clone();
|
let host_name = host.clone();
|
||||||
let host = dls.host(host);
|
let host = dls.host(host);
|
||||||
match asset {
|
match asset {
|
||||||
@@ -171,7 +178,7 @@ async fn main() -> eyre::Result<()> {
|
|||||||
C::DlSet(set) => match set {
|
C::DlSet(set) => match set {
|
||||||
DlSet::Sign { expiry, items } => {
|
DlSet::Sign { expiry, items } => {
|
||||||
let req = dls::DownloadSetReq { expiry, items };
|
let req = dls::DownloadSetReq { expiry, items };
|
||||||
let signed = dls.sign_dl_set(&req).await?;
|
let signed = dls().sign_dl_set(&req).await?;
|
||||||
println!("{signed}");
|
println!("{signed}");
|
||||||
}
|
}
|
||||||
DlSet::Show { signed_set } => {
|
DlSet::Show { signed_set } => {
|
||||||
@@ -211,11 +218,19 @@ async fn main() -> eyre::Result<()> {
|
|||||||
name,
|
name,
|
||||||
asset,
|
asset,
|
||||||
} => {
|
} => {
|
||||||
|
let dls = dls();
|
||||||
let stream = dls.fetch_dl_set(&signed_set, &kind, &name, &asset).await?;
|
let stream = dls.fetch_dl_set(&signed_set, &kind, &name, &asset).await?;
|
||||||
let mut out = create_asset_file(out, &kind, &name, &asset).await?;
|
let mut out = create_asset_file(out, &kind, &name, &asset).await?;
|
||||||
copy_stream(stream, &mut out).await?;
|
copy_stream(stream, &mut out).await?;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
C::Hash { salt } => {
|
||||||
|
let salt = dkl::base64_decode(&salt)?;
|
||||||
|
let passphrase = rpassword::prompt_password("password to hash: ")?;
|
||||||
|
let hash = dls::store::hash_password(&salt, &passphrase)?;
|
||||||
|
println!("hash (hex): {}", hex::encode(&hash));
|
||||||
|
println!("hash (base64): {}", dkl::base64_encode(&hash));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ use std::collections::BTreeMap as Map;
|
|||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
|
|
||||||
|
pub mod store;
|
||||||
|
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
base_url: String,
|
base_url: String,
|
||||||
token: String,
|
token: String,
|
||||||
|
|||||||
17
src/dls/store.rs
Normal file
17
src/dls/store.rs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
pub fn hash_password(salt: &[u8], passphrase: &str) -> argon2::Result<[u8; 32]> {
|
||||||
|
let hash = argon2::hash_raw(
|
||||||
|
passphrase.as_bytes(),
|
||||||
|
salt,
|
||||||
|
&argon2::Config {
|
||||||
|
variant: argon2::Variant::Argon2id,
|
||||||
|
hash_length: 32,
|
||||||
|
time_cost: 1,
|
||||||
|
mem_cost: 65536,
|
||||||
|
thread_mode: argon2::ThreadMode::Parallel,
|
||||||
|
lanes: 4,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
unsafe { Ok(hash.try_into().unwrap_unchecked()) }
|
||||||
|
}
|
||||||
@@ -83,6 +83,11 @@ impl Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn base64_decode(s: &str) -> Result<Vec<u8>, base64::DecodeError> {
|
pub fn base64_decode(s: &str) -> Result<Vec<u8>, base64::DecodeError> {
|
||||||
use base64::{Engine, prelude::BASE64_STANDARD_NO_PAD as B64};
|
use base64::{prelude::BASE64_STANDARD_NO_PAD as B64, Engine as _};
|
||||||
B64.decode(s.trim_end_matches('='))
|
B64.decode(s.trim_end_matches('='))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn base64_encode(b: &[u8]) -> String {
|
||||||
|
use base64::{prelude::BASE64_STANDARD as B64, Engine as _};
|
||||||
|
B64.encode(b)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user