Skip to content

Commit

Permalink
Merge pull request #77 from MutinyWallet/db-password-chec
Browse files Browse the repository at this point in the history
Properly check database password
  • Loading branch information
TonyGiorgio authored May 31, 2024
2 parents 1635e70 + 4f69f37 commit 78f77a7
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 13 deletions.
26 changes: 21 additions & 5 deletions src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use tokio::task::spawn_blocking;
use uuid::Uuid;

use crate::components::FederationItem;
use crate::db::check_password;
use crate::fedimint_client::{
spawn_onchain_payment_subscription, spawn_onchain_receive_subscription, FederationInviteOrId,
};
Expand Down Expand Up @@ -390,12 +391,9 @@ pub fn run_core() -> Subscription<Message> {

// attempting to unlock
let db_path = path.join("harbor.sqlite");
let db =
spawn_blocking(move || setup_db(db_path.to_str().unwrap(), password))
.await
.expect("Could not create join handle");

if let Err(e) = db {
let db_path = db_path.to_str().unwrap().to_string();
if let Err(e) = check_password(&db_path, &password) {
// probably invalid password
error!("error using password: {e}");

Expand All @@ -407,6 +405,24 @@ pub fn run_core() -> Subscription<Message> {
.expect("should send");
continue;
}

log::info!("Correct password");

let db = spawn_blocking(move || setup_db(&db_path, password))
.await
.expect("Could not create join handle");

if let Err(e) = db {
error!("error opening database: {e}");

tx.send(Message::core_msg(
id,
CoreUIMsg::UnlockFailed(e.to_string()),
))
.await
.expect("should send");
continue;
}
let db = db.expect("no error");

let mnemonic = get_mnemonic(db.clone()).expect("should get seed");
Expand Down
39 changes: 31 additions & 8 deletions src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,41 @@ use fedimint_core::config::FederationId;
use fedimint_core::core::OperationId;
use fedimint_core::Amount;
use fedimint_ln_common::lightning_invoice::Bolt11Invoice;
use rusqlite::{Connection, OpenFlags};
use std::{sync::Arc, time::Duration};

pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!();

pub(crate) fn check_password(url: &str, password: &str) -> anyhow::Result<()> {
let conn = Connection::open_with_flags(
url,
OpenFlags::SQLITE_OPEN_READ_ONLY | OpenFlags::SQLITE_OPEN_URI,
)?;

// Set the key for the encrypted database
let password = normalize_password(password);
conn.execute_batch(&format!("PRAGMA key = '{password}';"))?;

// Try to prepare a query to verify if the key is correct
let res = conn.prepare("SELECT name FROM sqlite_master WHERE type='table';");

match res {
Ok(_) => Ok(()),
Err(e) => {
if e.to_string() == "file is not a database" {
Err(anyhow::anyhow!("Invalid password"))
} else {
Err(anyhow::anyhow!("Could not open database: {e}"))
}
}
}
}

pub(crate) fn setup_db(url: &str, password: String) -> anyhow::Result<Arc<SQLConnection>> {
let manager = ConnectionManager::<SqliteConnection>::new(url);

// tests can be slow, make timeout longer
#[cfg(test)]
let timeout = Duration::from_secs(30);
#[cfg(not(test))]
let timeout = Duration::from_secs(5);

let pool = Pool::builder()
.max_size(50)
.connection_timeout(timeout)
.connection_customizer(Box::new(ConnectionOptions {
key: password,
enable_wal: true,
Expand Down Expand Up @@ -364,6 +383,10 @@ impl DBConnection for SQLConnection {
}
}

fn normalize_password(password: &str) -> String {
password.replace("'", "''")
}

#[derive(Debug)]
pub struct ConnectionOptions {
pub key: String,
Expand All @@ -377,7 +400,7 @@ impl diesel::r2d2::CustomizeConnection<SqliteConnection, diesel::r2d2::Error>
{
fn on_acquire(&self, conn: &mut SqliteConnection) -> Result<(), diesel::r2d2::Error> {
(|| {
let password = self.key.as_str().replace("'", "''");
let password = normalize_password(&self.key);
conn.batch_execute(&format!("PRAGMA key='{password}'"))?;
if self.enable_wal {
conn.batch_execute("PRAGMA journal_mode = WAL; PRAGMA synchronous = NORMAL;")?;
Expand Down

0 comments on commit 78f77a7

Please sign in to comment.