aboutsummaryrefslogtreecommitdiff
path: root/src/login
diff options
context:
space:
mode:
authorQuentin Dufour <quentin@deuxfleurs.fr>2023-12-06 20:57:25 +0100
committerQuentin Dufour <quentin@deuxfleurs.fr>2023-12-06 20:57:25 +0100
commit3ddbce4529225fe004acde3ab2e95261673bafc3 (patch)
tree799b7fa0e1aa8d173c89a2124ffc2865f3d6ced0 /src/login
parent2779837a3750c3b2964c3a4d5d43de25218bc605 (diff)
downloadaerogramme-3ddbce4529225fe004acde3ab2e95261673bafc3.tar.gz
aerogramme-3ddbce4529225fe004acde3ab2e95261673bafc3.zip
WIP refactor
Diffstat (limited to 'src/login')
-rw-r--r--src/login/mod.rs43
-rw-r--r--src/login/static_provider.rs44
2 files changed, 36 insertions, 51 deletions
diff --git a/src/login/mod.rs b/src/login/mod.rs
index 216c340..a9b9efe 100644
--- a/src/login/mod.rs
+++ b/src/login/mod.rs
@@ -45,6 +45,7 @@ pub struct PublicCredentials {
pub public_key: PublicKey,
}
+/*
/// The struct UserSecrets represents intermediary secrets that are mixed in with the user's
/// password when decrypting the cryptographic keys that are stored in their bucket.
/// These secrets should be stored somewhere else (e.g. in the LDAP server or in the
@@ -57,6 +58,7 @@ pub struct UserSecrets {
/// with old passwords
pub alternate_user_secrets: Vec<String>,
}
+*/
/// The struct CryptoKeys contains the cryptographic keys used to encrypt and decrypt
/// data in a user's mailbox.
@@ -85,7 +87,6 @@ impl Credentials {
impl CryptoKeys {
pub async fn init(
storage: &Builders,
- user_secrets: &UserSecrets,
password: &str,
) -> Result<Self> {
// Check that salt and public don't exist already
@@ -113,7 +114,7 @@ impl CryptoKeys {
thread_rng().fill(&mut kdf_salt);
// Calculate key for password secret box
- let password_key = user_secrets.derive_password_key(&kdf_salt, password)?;
+ let password_key = derive_password_key(&kdf_salt, password)?;
// Seal a secret box that contains our crypto keys
let password_sealed = seal(&keys.serialize(), &password_key)?;
@@ -169,7 +170,6 @@ impl CryptoKeys {
pub async fn open(
storage: &Builders,
- user_secrets: &UserSecrets,
password: &str,
) -> Result<Self> {
let k2v = storage.row_store()?;
@@ -200,8 +200,7 @@ impl CryptoKeys {
// Try to open blob
let kdf_salt = &password_blob[..32];
- let password_openned =
- user_secrets.try_open_encrypted_keys(kdf_salt, password, &password_blob[32..])?;
+ let password_openned = try_open_encrypted_keys(kdf_salt, password, &password_blob[32..])?;
let keys = Self::deserialize(&password_openned)?;
if keys.public != expected_public {
@@ -238,7 +237,6 @@ impl CryptoKeys {
pub async fn add_password(
&self,
storage: &Builders,
- user_secrets: &UserSecrets,
password: &str,
) -> Result<()> {
let k2v = storage.row_store()?;
@@ -252,7 +250,7 @@ impl CryptoKeys {
thread_rng().fill(&mut kdf_salt);
// Calculate key for password secret box
- let password_key = user_secrets.derive_password_key(&kdf_salt, password)?;
+ let password_key = derive_password_key(&kdf_salt, password)?;
// Seal a secret box that contains our crypto keys
let password_sealed = seal(&self.serialize(), &password_key)?;
@@ -418,32 +416,13 @@ impl CryptoKeys {
}
}
-impl UserSecrets {
- fn derive_password_key_with(user_secret: &str, kdf_salt: &[u8], password: &str) -> Result<Key> {
- let tmp = format!("{}\n\n{}", user_secret, password);
- Ok(Key::from_slice(&argon2_kdf(kdf_salt, tmp.as_bytes(), 32)?).unwrap())
- }
-
- fn derive_password_key(&self, kdf_salt: &[u8], password: &str) -> Result<Key> {
- Self::derive_password_key_with(&self.user_secret, kdf_salt, password)
- }
+fn derive_password_key(kdf_salt: &[u8], password: &str) -> Result<Key> {
+ Ok(Key::from_slice(&argon2_kdf(kdf_salt, password.as_bytes(), 32)?).unwrap())
+}
- fn try_open_encrypted_keys(
- &self,
- kdf_salt: &[u8],
- password: &str,
- encrypted_keys: &[u8],
- ) -> Result<Vec<u8>> {
- let secrets_to_try =
- std::iter::once(&self.user_secret).chain(self.alternate_user_secrets.iter());
- for user_secret in secrets_to_try {
- let password_key = Self::derive_password_key_with(user_secret, kdf_salt, password)?;
- if let Ok(res) = open(encrypted_keys, &password_key) {
- return Ok(res);
- }
- }
- bail!("Unable to decrypt password blob.");
- }
+fn try_open_encrypted_keys(kdf_salt: &[u8], password: &str, encrypted_keys: &[u8]) -> Result<Vec<u8>> {
+ let password_key = derive_password_key(kdf_salt, password)?;
+ open(encrypted_keys, &password_key)
}
// ---- UTIL ----
diff --git a/src/login/static_provider.rs b/src/login/static_provider.rs
index 0b726cb..3f6a840 100644
--- a/src/login/static_provider.rs
+++ b/src/login/static_provider.rs
@@ -1,5 +1,6 @@
use std::collections::HashMap;
use std::sync::Arc;
+use std::path::PathBuf;
use anyhow::{anyhow, bail, Result};
use async_trait::async_trait;
@@ -10,13 +11,28 @@ use crate::login::*;
use crate::storage;
pub struct StaticLoginProvider {
- users: HashMap<String, Arc<LoginStaticUser>>,
- users_by_email: HashMap<String, Arc<LoginStaticUser>>,
+ user_list: PathBuf,
+ users: HashMap<String, Arc<UserEntry>>,
+ users_by_email: HashMap<String, Arc<UserEntry>>,
}
impl StaticLoginProvider {
pub fn new(config: LoginStaticConfig) -> Result<Self> {
- let users = config
+ let mut lp = Self {
+ user_list: config.user_list,
+ users: HashMap::new(),
+ users_by_email: HashMap::new(),
+ };
+
+ lp.update_user_list();
+
+ Ok(lp)
+ }
+
+ pub fn update_user_list(&mut self) -> Result<()> {
+ let ulist: UserList = read_config(self.user_list)?;
+
+ let users = ulist
.into_iter()
.map(|(k, v)| (k, Arc::new(v)))
.collect::<HashMap<_, _>>();
@@ -29,11 +45,7 @@ impl StaticLoginProvider {
users_by_email.insert(m.clone(), u.clone());
}
}
-
- Ok(Self {
- users,
- users_by_email,
- })
+ Ok(())
}
}
@@ -64,24 +76,18 @@ impl LoginProvider for StaticLoginProvider {
}),
};
- let keys = match (&user.master_key, &user.secret_key) {
- (Some(m), Some(s)) => {
+ let keys = match user.crypto_root { /*(&user.master_key, &user.secret_key) {*/
+ CryptographyRoot::InPlace { master_key: m, secret_key: s } => {
let master_key =
Key::from_slice(&base64::decode(m)?).ok_or(anyhow!("Invalid master key"))?;
let secret_key = SecretKey::from_slice(&base64::decode(s)?)
.ok_or(anyhow!("Invalid secret key"))?;
CryptoKeys::open_without_password(&storage, &master_key, &secret_key).await?
}
- (None, None) => {
- let user_secrets = UserSecrets {
- user_secret: user.user_secret.clone(),
- alternate_user_secrets: user.alternate_user_secrets.clone(),
- };
- CryptoKeys::open(&storage, &user_secrets, password).await?
+ CryptographyRoot::PasswordProtected => {
+ CryptoKeys::open(&storage, password).await?
}
- _ => bail!(
- "Either both master and secret key or none of them must be specified for user"
- ),
+ CryptographyRoot::Keyring => unimplemented!(),
};
tracing::debug!(user=%username, "logged");