aboutsummaryrefslogtreecommitdiff
path: root/src/login
diff options
context:
space:
mode:
Diffstat (limited to 'src/login')
-rw-r--r--src/login/ldap_provider.rs3
-rw-r--r--src/login/mod.rs76
-rw-r--r--src/login/static_provider.rs37
3 files changed, 98 insertions, 18 deletions
diff --git a/src/login/ldap_provider.rs b/src/login/ldap_provider.rs
index 6108e6e..54ddbd5 100644
--- a/src/login/ldap_provider.rs
+++ b/src/login/ldap_provider.rs
@@ -1,5 +1,6 @@
use anyhow::Result;
use async_trait::async_trait;
+use rusoto_signature::Region;
use crate::config::*;
use crate::login::*;
@@ -9,7 +10,7 @@ pub struct LdapLoginProvider {
}
impl LdapLoginProvider {
- pub fn new(_config: LoginLdapConfig) -> Result<Self> {
+ pub fn new(_config: LoginLdapConfig, _k2v_region: Region, _s3_region: Region) -> Result<Self> {
unimplemented!()
}
}
diff --git a/src/login/mod.rs b/src/login/mod.rs
index 0845371..4022962 100644
--- a/src/login/mod.rs
+++ b/src/login/mod.rs
@@ -9,7 +9,7 @@ use rusoto_credential::{AwsCredentials, StaticProvider};
use rusoto_s3::S3Client;
use rusoto_signature::Region;
-use crate::cryptoblob::Key as SymmetricKey;
+use crate::cryptoblob::*;
#[async_trait]
pub trait LoginProvider {
@@ -18,14 +18,51 @@ pub trait LoginProvider {
#[derive(Clone, Debug)]
pub struct Credentials {
+ pub storage: StorageCredentials,
+ pub keys: CryptoKeys,
+}
+
+#[derive(Clone, Debug)]
+pub struct StorageCredentials {
+ pub s3_region: Region,
+ pub k2v_region: Region,
+
pub aws_access_key_id: String,
pub aws_secret_access_key: String,
pub bucket: String,
- pub master_key: SymmetricKey,
}
+#[derive(Clone, Debug)]
+pub struct CryptoKeys {
+ // Master key for symmetric encryption of mailbox data
+ pub master: Key,
+ // Public/private keypair for encryption of incomming emails
+ pub secret: SecretKey,
+ pub public: PublicKey,
+}
+
+// ----
+
impl Credentials {
- pub fn k2v_client(&self, k2v_region: &Region) -> Result<K2vClient> {
+ pub fn k2v_client(&self) -> Result<K2vClient> {
+ self.storage.k2v_client()
+ }
+ pub fn s3_client(&self) -> Result<S3Client> {
+ self.storage.s3_client()
+ }
+ pub fn bucket(&self) -> &str {
+ self.storage.bucket.as_str()
+ }
+ pub fn dump_config(&self) {
+ println!("aws_access_key_id = \"{}\"", self.storage.aws_access_key_id);
+ println!("aws_secret_access_key = \"{}\"", self.storage.aws_secret_access_key);
+ println!("master_key = \"{}\"", base64::encode(&self.keys.master));
+ println!("secret_key = \"{}\"", base64::encode(&self.keys.secret));
+ }
+}
+
+impl StorageCredentials {
+ pub fn k2v_client(&self) -> Result<K2vClient> {
let aws_creds = AwsCredentials::new(
self.aws_access_key_id.clone(),
self.aws_secret_access_key.clone(),
@@ -34,14 +71,14 @@ impl Credentials {
);
Ok(K2vClient::new(
- k2v_region.clone(),
+ self.k2v_region.clone(),
self.bucket.clone(),
aws_creds,
None,
)?)
}
- pub fn s3_client(&self, s3_region: &Region) -> Result<S3Client> {
+ pub fn s3_client(&self) -> Result<S3Client> {
let aws_creds_provider = StaticProvider::new_minimal(
self.aws_access_key_id.clone(),
self.aws_secret_access_key.clone(),
@@ -50,7 +87,34 @@ impl Credentials {
Ok(S3Client::new_with(
HttpClient::new()?,
aws_creds_provider,
- s3_region.clone(),
+ self.s3_region.clone(),
))
}
}
+
+impl CryptoKeys {
+ pub fn init(storage: &StorageCredentials) -> Result<Self> {
+ unimplemented!()
+ }
+
+ pub fn init_without_password(storage: &StorageCredentials, master_key: &Key, secret_key: &SecretKey) -> Result<Self> {
+ unimplemented!()
+ }
+
+ pub fn open(storage: &StorageCredentials, password: &str) -> Result<Self> {
+ unimplemented!()
+ }
+
+ pub fn open_without_password(storage: &StorageCredentials, master_key: &Key, secret_key: &SecretKey) -> Result<Self> {
+ unimplemented!()
+ }
+
+ pub fn add_password(&self, storage: &StorageCredentials, password: &str) -> Result<()> {
+ unimplemented!()
+ }
+
+ pub fn remove_password(&self, storage: &StorageCredentials, password: &str, allow_remove_all: bool) -> Result<()> {
+ unimplemented!()
+ }
+}
+
diff --git a/src/login/static_provider.rs b/src/login/static_provider.rs
index 037948a..d7d791a 100644
--- a/src/login/static_provider.rs
+++ b/src/login/static_provider.rs
@@ -5,21 +5,23 @@ use async_trait::async_trait;
use rusoto_signature::Region;
use crate::config::*;
-use crate::cryptoblob::Key;
+use crate::cryptoblob::{Key, SecretKey};
use crate::login::*;
pub struct StaticLoginProvider {
default_bucket: Option<String>,
users: HashMap<String, LoginStaticUser>,
k2v_region: Region,
+ s3_region: Region,
}
impl StaticLoginProvider {
- pub fn new(config: LoginStaticConfig, k2v_region: Region) -> Result<Self> {
+ pub fn new(config: LoginStaticConfig, k2v_region: Region, s3_region: Region) -> Result<Self> {
Ok(Self {
default_bucket: config.default_bucket,
users: config.users,
k2v_region,
+ s3_region,
})
}
}
@@ -42,18 +44,31 @@ impl LoginProvider for StaticLoginProvider {
"No bucket configured and no default bucket specieid"
))?;
- // TODO if master key is not specified, retrieve it from K2V key storage
- let master_key_str = u.master_key.as_ref().ok_or(anyhow!(
- "Master key must be specified in config file for now, this will change"
- ))?;
- let master_key = Key::from_slice(&base64::decode(master_key_str)?)
- .ok_or(anyhow!("Invalid master key"))?;
-
- Ok(Credentials {
+ let storage = StorageCredentials {
+ k2v_region: self.k2v_region.clone(),
+ s3_region: self.s3_region.clone(),
aws_access_key_id: u.aws_access_key_id.clone(),
aws_secret_access_key: u.aws_secret_access_key.clone(),
bucket,
- master_key,
+ };
+
+ let keys = match (&u.master_key, &u.secret_key) {
+ (Some(m), Some(s)) => {
+ let master_key = Key::from_slice(&base64::decode(m)?)
+ .ok_or(anyhow!("Invalid master key"))?;
+ let secret_key = SecretKey::from_slice(&base64::decode(m)?)
+ .ok_or(anyhow!("Invalid secret key"))?;
+ CryptoKeys::open_without_password(&storage, &master_key, &secret_key)?
+ }
+ (None, None) => {
+ CryptoKeys::open(&storage, password)?
+ }
+ _ => bail!("Either both master and secret key or none of them must be specified for user"),
+ };
+
+ Ok(Credentials {
+ storage,
+ keys,
})
}
}