This commit is contained in:
2026-02-21 10:39:52 +01:00
parent f7c975a3f0
commit 66c1fe0025
38 changed files with 1543 additions and 616 deletions

View File

@@ -1 +1,3 @@
pub mod toolbox;
pub mod password;
pub mod ssh_auth;
pub mod toolbox;

28
src/utils/password.rs Normal file
View 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
View 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>
}

View File

@@ -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)
}