|
|
|
@ -1,4 +1,5 @@
|
|
|
|
|
use super::crypt;
|
|
|
|
|
use crate::crypt::EncryptedValue;
|
|
|
|
|
use rusqlite::{Connection, NO_PARAMS};
|
|
|
|
|
use rustc_serialize::base64;
|
|
|
|
|
use rustc_serialize::base64::{FromBase64, ToBase64};
|
|
|
|
@ -119,6 +120,64 @@ impl DbHandle {
|
|
|
|
|
};
|
|
|
|
|
result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn write_encrypted_value(&mut self, val: EncryptedValue) -> i64 {
|
|
|
|
|
let b64ciphertext: String = val.ciphertext.to_base64(base64::STANDARD);
|
|
|
|
|
let b64iv: String = val.iv.to_base64(base64::STANDARD);
|
|
|
|
|
let b64mac: String = val.mac.code().to_base64(base64::STANDARD);
|
|
|
|
|
let tx = self.conn.transaction().unwrap();
|
|
|
|
|
tx.execute(
|
|
|
|
|
"INSERT INTO encrypted_values (iv, ciphertext, mac) VALUES ($1, $2, $3)",
|
|
|
|
|
&[&b64iv, &b64ciphertext, &b64mac],
|
|
|
|
|
)
|
|
|
|
|
.unwrap();
|
|
|
|
|
let rowid: i64 = tx.last_insert_rowid();
|
|
|
|
|
let _ = tx.commit().unwrap();
|
|
|
|
|
rowid
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn write_account(
|
|
|
|
|
&mut self,
|
|
|
|
|
host: EncryptedValue,
|
|
|
|
|
username: EncryptedValue,
|
|
|
|
|
password: EncryptedValue,
|
|
|
|
|
) -> i64 {
|
|
|
|
|
// TODO: This should be a transaction
|
|
|
|
|
let host_id = self.write_encrypted_value(host);
|
|
|
|
|
let user_id = self.write_encrypted_value(username);
|
|
|
|
|
let password_id = self.write_encrypted_value(password);
|
|
|
|
|
self.conn
|
|
|
|
|
.execute(
|
|
|
|
|
"INSERT INTO accounts (server, user, password) VALUES ($1, $2, $3)",
|
|
|
|
|
&[&host_id, &user_id, &password_id],
|
|
|
|
|
)
|
|
|
|
|
.unwrap();
|
|
|
|
|
self.conn.last_insert_rowid()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn delete_account_with_host(&mut self, master_key: [u8; 32], host: &str) {
|
|
|
|
|
let accounts: Vec<Account> = self.list_accounts(master_key);
|
|
|
|
|
let tx = self.conn.transaction().unwrap();
|
|
|
|
|
|
|
|
|
|
for account in accounts {
|
|
|
|
|
if account.host == host {
|
|
|
|
|
tx.execute(
|
|
|
|
|
"DELETE FROM encrypted_values WHERE exists \
|
|
|
|
|
(SELECT 1 FROM accounts WHERE \
|
|
|
|
|
(accounts.server = encrypted_values.id OR \
|
|
|
|
|
accounts.user = encrypted_values.id OR \
|
|
|
|
|
accounts.password = encrypted_values.id) AND \
|
|
|
|
|
accounts.id=$1);",
|
|
|
|
|
&[&account.id],
|
|
|
|
|
)
|
|
|
|
|
.unwrap();
|
|
|
|
|
tx.execute("DELETE FROM accounts WHERE id=$1;", &[&account.id])
|
|
|
|
|
.unwrap();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let _ = tx.commit().unwrap();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn decrypt_base64(iv: String, ciphertext: String, mac: String, master_key: [u8; 32]) -> Vec<u8> {
|
|
|
|
|