diff --git a/CHANGELOG.md b/CHANGELOG.md index e13a59199..81c5e107e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ## Changes ## Fixes +- do not reset our database if imported backup cannot be decrypted #3397 ## 1.85.0 diff --git a/src/imex.rs b/src/imex.rs index 699a46540..5b0021fb3 100644 --- a/src/imex.rs +++ b/src/imex.rs @@ -931,6 +931,17 @@ mod tests { // import to context2 let backup = has_backup(&context2, backup_dir.path().as_ref()).await?; + + // Import of unencrypted backup with incorrect "foobar" backup passphrase fails. + assert!(imex( + &context2, + ImexMode::ImportBackup, + backup.as_ref(), + Some("foobar".to_string()) + ) + .await + .is_err()); + assert!( imex(&context2, ImexMode::ImportBackup, backup.as_ref(), None) .await diff --git a/src/sql.rs b/src/sql.rs index e88410887..345a0cffa 100644 --- a/src/sql.rs +++ b/src/sql.rs @@ -146,6 +146,21 @@ impl Sql { .with_context(|| format!("path {:?} is not valid unicode", path))?; let conn = self.get_conn().await?; + // Check that backup passphrase is correct before resetting our database. + conn.execute( + "ATTACH DATABASE ? AS backup KEY ?", + paramsv![path_str, passphrase], + ) + .context("failed to attach backup database")?; + if let Err(err) = conn + .query_row("SELECT count(*) FROM sqlite_master", [], |_row| Ok(())) + .context("backup passphrase is not correct") + { + conn.execute("DETACH DATABASE backup", []) + .context("failed to detach backup database")?; + return Err(err); + } + // Reset the database without reopening it. We don't want to reopen the database because we // don't have main database passphrase at this point. // See for documentation. @@ -156,12 +171,6 @@ impl Sql { .context("failed to vacuum the database")?; conn.set_db_config(DbConfig::SQLITE_DBCONFIG_RESET_DATABASE, false) .context("failed to unset SQLITE_DBCONFIG_RESET_DATABASE")?; - - conn.execute( - "ATTACH DATABASE ? AS backup KEY ?", - paramsv![path_str, passphrase], - ) - .context("failed to attach backup database")?; let res = conn .query_row("SELECT sqlcipher_export('main', 'backup')", [], |_row| { Ok(())