Init
This commit is contained in:
@@ -1 +1,3 @@
|
||||
pub mod toolbox;
|
||||
pub mod password;
|
||||
pub mod ssh_auth;
|
||||
pub mod toolbox;
|
||||
|
||||
28
src/utils/password.rs
Normal file
28
src/utils/password.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
// src/utils/password.rs
|
||||
use argon2::{
|
||||
password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString}, Algorithm, Argon2, Params,
|
||||
Version,
|
||||
};
|
||||
|
||||
/// Hache un password avec Argon2id
|
||||
/// Génère automatiquement un salt cryptographiquement sûr
|
||||
pub fn hash_password(password: &str) -> Result<String, argon2::password_hash::Error> {
|
||||
let salt = SaltString::generate(OsRng);
|
||||
let params = Params::new(65540, 18, 1, None)?;
|
||||
|
||||
let argon2 = Argon2::new(Algorithm::Argon2id, Version::V0x13, params);
|
||||
|
||||
argon2
|
||||
.hash_password(password.as_bytes(), &salt)
|
||||
.map(|hash| hash.to_string())
|
||||
}
|
||||
|
||||
/// Vérifie un password contre son hash
|
||||
pub fn verify_password(password: &str, hash: &str) -> Result<bool, argon2::password_hash::Error> {
|
||||
let parsed_hash = PasswordHash::new(hash)?;
|
||||
let argon2 = Argon2::default();
|
||||
|
||||
Ok(argon2
|
||||
.verify_password(password.as_bytes(), &parsed_hash)
|
||||
.is_ok())
|
||||
}
|
||||
61
src/utils/ssh_auth.rs
Normal file
61
src/utils/ssh_auth.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use chrono::{DateTime, Utc};
|
||||
use parking_lot::Mutex;
|
||||
use crate::utils::toolbox::ssh_generate_challenge;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct SshAuthManager {
|
||||
// session_id: String,
|
||||
challenges: Arc<Mutex<HashMap<String, SshAuthChallenge>>>,
|
||||
}
|
||||
|
||||
impl SshAuthManager {
|
||||
pub fn new() -> Self {
|
||||
let manager = Self {
|
||||
challenges: Arc::new(Mutex::new(HashMap::new()))
|
||||
};
|
||||
manager.start_cleanup_task();
|
||||
|
||||
manager
|
||||
}
|
||||
|
||||
fn start_cleanup_task(&self) {
|
||||
let challenges = self.challenges.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(30));
|
||||
loop {
|
||||
interval.tick().await;
|
||||
let mut map = challenges.lock();
|
||||
let now = Utc::now();
|
||||
map.retain(|_, challenge| {
|
||||
challenge.expires_at > now
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn add_auth_challenge(&self, session_id: String) -> SshAuthChallenge {
|
||||
let challenge = ssh_generate_challenge(1024);
|
||||
let auth_challenge = SshAuthChallenge {
|
||||
session_id: session_id.clone(),
|
||||
challenge,
|
||||
expires_at: Utc::now() + chrono::Duration::minutes(1)
|
||||
};
|
||||
|
||||
self.challenges.lock().insert(
|
||||
session_id,
|
||||
auth_challenge.clone()
|
||||
);
|
||||
|
||||
auth_challenge
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct SshAuthChallenge {
|
||||
session_id: String,
|
||||
challenge: String,
|
||||
expires_at: DateTime<Utc>
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
use rand::Rng;
|
||||
|
||||
pub fn number_of_cpus() -> usize {
|
||||
match std::thread::available_parallelism() {
|
||||
Ok(n) => n.get(),
|
||||
@@ -6,4 +8,31 @@ pub fn number_of_cpus() -> usize {
|
||||
1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_random(size: usize) -> Vec<u8> {
|
||||
let mut rng = rand::rng();
|
||||
let value = (0..size).map(|_| rng.random()).collect::<Vec<u8>>();
|
||||
value
|
||||
}
|
||||
|
||||
pub fn b64_encode(value: &[u8]) -> String {
|
||||
base64::Engine::encode(
|
||||
&base64::engine::general_purpose::STANDARD,
|
||||
value
|
||||
)
|
||||
}
|
||||
|
||||
pub fn b64_decode(value: &str) -> Result<Vec<u8>, std::io::Error> {
|
||||
base64::Engine::decode(
|
||||
&base64::engine::general_purpose::STANDARD,
|
||||
value
|
||||
).map_err(|e| {
|
||||
std::io::Error::new(std::io::ErrorKind::InvalidData, e)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn ssh_generate_challenge(size: usize) -> String {
|
||||
let challenge = generate_random(size);
|
||||
b64_encode(&challenge)
|
||||
}
|
||||
Reference in New Issue
Block a user