mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2025-11-20 18:06:15 -05:00
Fix KDF Change with new web-vault (#6458)
The newer web-vault's use a different json to update the KDF settings. This commit fixes this by updating the struct and adjust the validation settings. Fixes #6457 Signed-off-by: BlackDex <black.dex@gmail.com>
This commit is contained in:
committed by
GitHub
parent
0182567a62
commit
2ee40d6105
@@ -75,12 +75,16 @@ pub fn routes() -> Vec<rocket::Route> {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize, Eq, PartialEq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct KDFData {
|
pub struct KDFData {
|
||||||
|
#[serde(alias = "kdfType")]
|
||||||
kdf: i32,
|
kdf: i32,
|
||||||
|
#[serde(alias = "iterations")]
|
||||||
kdf_iterations: i32,
|
kdf_iterations: i32,
|
||||||
|
#[serde(alias = "memory")]
|
||||||
kdf_memory: Option<i32>,
|
kdf_memory: Option<i32>,
|
||||||
|
#[serde(alias = "parallelism")]
|
||||||
kdf_parallelism: Option<i32>,
|
kdf_parallelism: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -545,17 +549,6 @@ async fn post_password(data: Json<ChangePassData>, headers: Headers, conn: DbCon
|
|||||||
save_result
|
save_result
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
struct ChangeKdfData {
|
|
||||||
#[serde(flatten)]
|
|
||||||
kdf: KDFData,
|
|
||||||
|
|
||||||
master_password_hash: String,
|
|
||||||
new_master_password_hash: String,
|
|
||||||
key: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_kdf_data(user: &mut User, data: &KDFData) -> EmptyResult {
|
fn set_kdf_data(user: &mut User, data: &KDFData) -> EmptyResult {
|
||||||
if data.kdf == UserKdfType::Pbkdf2 as i32 && data.kdf_iterations < 100_000 {
|
if data.kdf == UserKdfType::Pbkdf2 as i32 && data.kdf_iterations < 100_000 {
|
||||||
err!("PBKDF2 KDF iterations must be at least 100000.")
|
err!("PBKDF2 KDF iterations must be at least 100000.")
|
||||||
@@ -591,18 +584,61 @@ fn set_kdf_data(user: &mut User, data: &KDFData) -> EmptyResult {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct AuthenticationData {
|
||||||
|
salt: String,
|
||||||
|
kdf: KDFData,
|
||||||
|
master_password_authentication_hash: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct UnlockData {
|
||||||
|
salt: String,
|
||||||
|
kdf: KDFData,
|
||||||
|
master_key_wrapped_user_key: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct ChangeKdfData {
|
||||||
|
new_master_password_hash: String,
|
||||||
|
key: String,
|
||||||
|
authentication_data: AuthenticationData,
|
||||||
|
unlock_data: UnlockData,
|
||||||
|
master_password_hash: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[post("/accounts/kdf", data = "<data>")]
|
#[post("/accounts/kdf", data = "<data>")]
|
||||||
async fn post_kdf(data: Json<ChangeKdfData>, headers: Headers, conn: DbConn, nt: Notify<'_>) -> EmptyResult {
|
async fn post_kdf(data: Json<ChangeKdfData>, headers: Headers, conn: DbConn, nt: Notify<'_>) -> EmptyResult {
|
||||||
let data: ChangeKdfData = data.into_inner();
|
let data: ChangeKdfData = data.into_inner();
|
||||||
let mut user = headers.user;
|
|
||||||
|
|
||||||
if !user.check_valid_password(&data.master_password_hash) {
|
if !headers.user.check_valid_password(&data.master_password_hash) {
|
||||||
err!("Invalid password")
|
err!("Invalid password")
|
||||||
}
|
}
|
||||||
|
|
||||||
set_kdf_data(&mut user, &data.kdf)?;
|
if data.authentication_data.kdf != data.unlock_data.kdf {
|
||||||
|
err!("KDF settings must be equal for authentication and unlock")
|
||||||
|
}
|
||||||
|
|
||||||
user.set_password(&data.new_master_password_hash, Some(data.key), true, None);
|
if headers.user.email != data.authentication_data.salt || headers.user.email != data.unlock_data.salt {
|
||||||
|
err!("Invalid master password salt")
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut user = headers.user;
|
||||||
|
|
||||||
|
set_kdf_data(&mut user, &data.unlock_data.kdf)?;
|
||||||
|
|
||||||
|
user.set_password(
|
||||||
|
&data.authentication_data.master_password_authentication_hash,
|
||||||
|
Some(data.unlock_data.master_key_wrapped_user_key),
|
||||||
|
true,
|
||||||
|
None,
|
||||||
|
);
|
||||||
let save_result = user.save(&conn).await;
|
let save_result = user.save(&conn).await;
|
||||||
|
|
||||||
nt.send_logout(&user, Some(headers.device.uuid.clone()), &conn).await;
|
nt.send_logout(&user, Some(headers.device.uuid.clone()), &conn).await;
|
||||||
|
|||||||
Reference in New Issue
Block a user