aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel García <[email protected]>2019-04-11 16:08:26 +0200
committerDaniel García <[email protected]>2019-04-11 16:08:26 +0200
commitcad63f97616ac4f003a65543860c49e75b32a08c (patch)
tree7678067b7cc343690eaa827d2be99edd0b044156
parentbf446f44f97a5f9df7c7c274e5d78981b6b2287c (diff)
downloadvaultwarden-cad63f97616ac4f003a65543860c49e75b32a08c.tar.gz
vaultwarden-cad63f97616ac4f003a65543860c49e75b32a08c.zip
Auto generate akey
-rw-r--r--src/api/core/two_factor.rs17
-rw-r--r--src/config.rs46
2 files changed, 44 insertions, 19 deletions
diff --git a/src/api/core/two_factor.rs b/src/api/core/two_factor.rs
index 94cbc1e7..1849f035 100644
--- a/src/api/core/two_factor.rs
+++ b/src/api/core/two_factor.rs
@@ -821,12 +821,19 @@ const APP_PREFIX: &str = "APP";
use chrono::Utc;
+// let (ik, sk, ak) = get_duo_keys();
+fn get_duo_keys() -> (String, String, String) {
+ (
+ CONFIG.duo_ikey().unwrap(),
+ CONFIG.duo_skey().unwrap(),
+ CONFIG.get_duo_akey(),
+ )
+}
+
pub fn generate_duo_signature(email: &str) -> String {
let now = Utc::now().timestamp();
- let ik = CONFIG.duo_ikey().unwrap();
- let sk = CONFIG.duo_skey().unwrap();
- let ak = CONFIG.duo_akey().unwrap();
+ let (ik, sk, ak) = get_duo_keys();
let duo_sign = sign_duo_values(&sk, email, &ik, DUO_PREFIX, now + DUO_EXPIRE);
let app_sign = sign_duo_values(&ak, email, &ik, APP_PREFIX, now + APP_EXPIRE);
@@ -852,9 +859,7 @@ pub fn validate_duo_login(email: &str, response: &str) -> EmptyResult {
let now = Utc::now().timestamp();
- let ik = CONFIG.duo_ikey().unwrap();
- let sk = CONFIG.duo_skey().unwrap();
- let ak = CONFIG.duo_akey().unwrap();
+ let (ik, sk, ak) = get_duo_keys();
let auth_user = parse_duo_values(&sk, auth_sig, &ik, AUTH_PREFIX, now)?;
let app_user = parse_duo_values(&ak, app_sig, &ik, APP_PREFIX, now)?;
diff --git a/src/config.rs b/src/config.rs
index 309b65ae..d40eecae 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -9,7 +9,7 @@ lazy_static! {
println!("Error loading config:\n\t{:?}\n", e);
exit(12)
});
- pub static ref CONFIG_FILE: String = {
+ pub static ref CONFIG_FILE: String = {
let data_folder = get_env("DATA_FOLDER").unwrap_or_else(|| String::from("data"));
get_env("CONFIG_FILE").unwrap_or_else(|| format!("{}/config.json", data_folder))
};
@@ -64,7 +64,7 @@ macro_rules! make_config {
/// Merges the values of both builders into a new builder.
/// If both have the same element, `other` wins.
- fn merge(&self, other: &Self) -> Self {
+ fn merge(&self, other: &Self, show_overrides: bool) -> Self {
let mut overrides = Vec::new();
let mut builder = self.clone();
$($(
@@ -77,7 +77,7 @@ macro_rules! make_config {
}
)+)+
- if !overrides.is_empty() {
+ if show_overrides && !overrides.is_empty() {
// We can't use warn! here because logging isn't setup yet.
println!("[WARNING] The following environment variables are being overriden by the config file,");
println!("[WARNING] please use the admin panel to make changes to them:");
@@ -315,8 +315,8 @@ make_config! {
duo_skey: Pass, true, option;
/// Host
duo_host: String, true, option;
- /// Application Key
- duo_akey: Pass, true, option;
+ /// Application Key (generated automatically)
+ _duo_akey: Pass, false, option;
},
/// SMTP Email Settings
@@ -349,10 +349,10 @@ fn validate_config(cfg: &ConfigItems) -> Result<(), Error> {
}
}
- if (cfg.duo_host.is_some() || cfg.duo_ikey.is_some() || cfg.duo_skey.is_some() || cfg.duo_akey.is_some())
- && !(cfg.duo_host.is_some() && cfg.duo_ikey.is_some() && cfg.duo_skey.is_some() && cfg.duo_akey.is_some())
+ if (cfg.duo_host.is_some() || cfg.duo_ikey.is_some() || cfg.duo_skey.is_some())
+ && !(cfg.duo_host.is_some() && cfg.duo_ikey.is_some() && cfg.duo_skey.is_some())
{
- err!("All Duo options need to be set for Duo support")
+ err!("All Duo options need to be set for global Duo support")
}
if cfg.yubico_client_id.is_some() != cfg.yubico_secret_key.is_some() {
@@ -377,7 +377,7 @@ impl Config {
let _usr = ConfigBuilder::from_file(&CONFIG_FILE).unwrap_or_default();
// Create merged config, config file overwrites env
- let builder = _env.merge(&_usr);
+ let builder = _env.merge(&_usr, true);
// Fill any missing with defaults
let config = builder.build();
@@ -406,7 +406,7 @@ impl Config {
// Prepare the combined config
let config = {
let env = &self.inner.read().unwrap()._env;
- env.merge(&builder).build()
+ env.merge(&builder, false).build()
};
validate_config(&config)?;
@@ -425,6 +425,14 @@ impl Config {
Ok(())
}
+ pub fn update_config_partial(&self, other: ConfigBuilder) -> Result<(), Error> {
+ let builder = {
+ let usr = &self.inner.read().unwrap()._usr;
+ usr.merge(&other, false)
+ };
+ self.update_config(builder)
+ }
+
pub fn delete_user_config(&self) -> Result<(), Error> {
crate::util::delete_file(&CONFIG_FILE)?;
@@ -460,9 +468,21 @@ impl Config {
let inner = &self.inner.read().unwrap().config;
inner._enable_smtp && inner.smtp_host.is_some()
}
- pub fn yubico_enabled(&self) -> bool {
- let inner = &self.inner.read().unwrap().config;
- inner._enable_yubico && inner.yubico_client_id.is_some() && inner.yubico_secret_key.is_some()
+
+ pub fn get_duo_akey(&self) -> String {
+ if let Some(akey) = self._duo_akey() {
+ akey
+ } else {
+ let akey = crate::crypto::get_random_64();
+ let akey_s = data_encoding::BASE64.encode(&akey);
+
+ // Save the new value
+ let mut builder = ConfigBuilder::default();
+ builder._duo_akey = Some(akey_s.clone());
+ self.update_config_partial(builder).ok();
+
+ akey_s
+ }
}
pub fn render_template<T: serde::ser::Serialize>(