mirror of
https://github.com/chatmail/core.git
synced 2026-04-21 15:36:30 +03:00
The big sqlite refactor
* refactor: safe sql access * Clean up the worst rebase mistakes * Some more progress on the rebase fallout and this branch * upgrade and compile again * cleanup from rebase * example of how to prepare now * rebase fixes * add sql.query_map * less preparation * more improvements in sql code * fix string truncation * more prepare conversions * most prep done * fix tests * fix ffi * fix last prepares * fix segfaults and some queries * use r2d2 pool * fix dc_job sql call, to reduce contention * try newer rust * No more vararg printing (drop dc_log_) * ignore expected errors * fix: uses exists instead of execute where needed * fix: get_contacts logic was broken * fix: contact creation * test on 32bit linux * ci: try running 32bit without cross * undo 32bit tests * refactor: rename dc_sqlite3 to sql * fix: safer string conversions * more string fixes * try fixing appveyor build to 64bit * chore(ci): hardcode target * chore(ci): appveyor * some cleanup work * try fix darwin * fix and improve sql escaping * fix various bugs * fix chat deletion * refactor: cleanup config values and move to their own file * refactor: move more methods onto the sql struct * dont panic on failed state loading * first round of cr * one more cr fix * stop using strange defaults * remove unused escapes
This commit is contained in:
committed by
GitHub
parent
3e3403d3d7
commit
8a0fc609e6
142
src/key.rs
142
src/key.rs
@@ -10,9 +10,8 @@ use pgp::types::{KeyTrait, SecretKeyTrait};
|
||||
|
||||
use crate::constants::*;
|
||||
use crate::context::Context;
|
||||
use crate::dc_sqlite3::*;
|
||||
use crate::dc_tools::*;
|
||||
use crate::types::*;
|
||||
use crate::sql::{self, Sql};
|
||||
use crate::x::*;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
@@ -113,19 +112,6 @@ impl Key {
|
||||
Self::from_slice(bytes, key_type)
|
||||
}
|
||||
|
||||
pub fn from_stmt(
|
||||
stmt: *mut sqlite3_stmt,
|
||||
index: libc::c_int,
|
||||
key_type: KeyType,
|
||||
) -> Option<Self> {
|
||||
assert!(!stmt.is_null(), "missing statement");
|
||||
|
||||
let data = unsafe { sqlite3_column_blob(stmt, index) as *const u8 };
|
||||
let len = unsafe { sqlite3_column_bytes(stmt, index) };
|
||||
|
||||
Self::from_binary(data, len, key_type)
|
||||
}
|
||||
|
||||
pub fn from_armored_string(
|
||||
data: &str,
|
||||
key_type: KeyType,
|
||||
@@ -158,61 +144,32 @@ impl Key {
|
||||
|
||||
pub fn from_self_public(
|
||||
context: &Context,
|
||||
self_addr: *const libc::c_char,
|
||||
sql: &SQLite,
|
||||
self_addr: impl AsRef<str>,
|
||||
sql: &Sql,
|
||||
) -> Option<Self> {
|
||||
if self_addr.is_null() {
|
||||
return None;
|
||||
}
|
||||
let addr = self_addr.as_ref();
|
||||
|
||||
let stmt = unsafe {
|
||||
dc_sqlite3_prepare(
|
||||
context,
|
||||
sql,
|
||||
b"SELECT public_key FROM keypairs WHERE addr=? AND is_default=1;\x00" as *const u8
|
||||
as *const libc::c_char,
|
||||
)
|
||||
};
|
||||
unsafe { sqlite3_bind_text(stmt, 1, self_addr, -1, None) };
|
||||
|
||||
let key = if unsafe { sqlite3_step(stmt) } == 100 {
|
||||
Self::from_stmt(stmt, 0, KeyType::Public)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
unsafe { sqlite3_finalize(stmt) };
|
||||
|
||||
key
|
||||
sql.query_row_col(
|
||||
context,
|
||||
"SELECT public_key FROM keypairs WHERE addr=? AND is_default=1;",
|
||||
&[addr],
|
||||
0,
|
||||
)
|
||||
.and_then(|blob: Vec<u8>| Self::from_slice(&blob, KeyType::Public))
|
||||
}
|
||||
|
||||
pub fn from_self_private(
|
||||
context: &Context,
|
||||
self_addr: *const libc::c_char,
|
||||
sql: &SQLite,
|
||||
self_addr: impl AsRef<str>,
|
||||
sql: &Sql,
|
||||
) -> Option<Self> {
|
||||
if self_addr.is_null() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let stmt = unsafe {
|
||||
dc_sqlite3_prepare(
|
||||
context,
|
||||
sql,
|
||||
b"SELECT private_key FROM keypairs WHERE addr=? AND is_default=1;\x00" as *const u8
|
||||
as *const libc::c_char,
|
||||
)
|
||||
};
|
||||
unsafe { sqlite3_bind_text(stmt, 1, self_addr, -1, None) };
|
||||
|
||||
let key = if unsafe { sqlite3_step(stmt) } == 100 {
|
||||
Self::from_stmt(stmt, 0, KeyType::Private)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
unsafe { sqlite3_finalize(stmt) };
|
||||
|
||||
key
|
||||
sql.query_row_col(
|
||||
context,
|
||||
"SELECT private_key FROM keypairs WHERE addr=? AND is_default=1;",
|
||||
&[self_addr.as_ref()],
|
||||
0,
|
||||
)
|
||||
.and_then(|blob: Vec<u8>| Self::from_slice(&blob, KeyType::Private))
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
@@ -340,57 +297,16 @@ pub fn dc_key_save_self_keypair(
|
||||
context: &Context,
|
||||
public_key: &Key,
|
||||
private_key: &Key,
|
||||
addr: *const libc::c_char,
|
||||
addr: impl AsRef<str>,
|
||||
is_default: libc::c_int,
|
||||
sql: &SQLite,
|
||||
sql: &Sql,
|
||||
) -> bool {
|
||||
if addr.is_null() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let stmt = unsafe {
|
||||
dc_sqlite3_prepare(
|
||||
sql::execute(
|
||||
context,
|
||||
sql,
|
||||
b"INSERT INTO keypairs (addr, is_default, public_key, private_key, created) VALUES (?,?,?,?,?);\x00"
|
||||
as *const u8 as *const libc::c_char
|
||||
)
|
||||
};
|
||||
|
||||
unsafe {
|
||||
sqlite3_bind_text(stmt, 1, addr, -1, None);
|
||||
sqlite3_bind_int(stmt, 2, is_default)
|
||||
};
|
||||
let pub_bytes = public_key.to_bytes();
|
||||
let sec_bytes = private_key.to_bytes();
|
||||
unsafe {
|
||||
sqlite3_bind_blob(
|
||||
stmt,
|
||||
3,
|
||||
pub_bytes.as_ptr() as *const _,
|
||||
pub_bytes.len() as libc::c_int,
|
||||
None,
|
||||
)
|
||||
};
|
||||
unsafe {
|
||||
sqlite3_bind_blob(
|
||||
stmt,
|
||||
4,
|
||||
sec_bytes.as_ptr() as *const _,
|
||||
sec_bytes.len() as libc::c_int,
|
||||
None,
|
||||
)
|
||||
};
|
||||
unsafe { sqlite3_bind_int64(stmt, 5, time() as sqlite3_int64) };
|
||||
let success = if unsafe { sqlite3_step(stmt) } == 101 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
unsafe { sqlite3_finalize(stmt) };
|
||||
|
||||
success
|
||||
"INSERT INTO keypairs (addr, is_default, public_key, private_key, created) VALUES (?,?,?,?,?);",
|
||||
params![addr.as_ref(), is_default, public_key.to_bytes(), private_key.to_bytes(), time()],
|
||||
).is_ok()
|
||||
}
|
||||
|
||||
/// Make a fingerprint human-readable, in hex format.
|
||||
@@ -526,8 +442,7 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD
|
||||
#[test]
|
||||
#[ignore] // is too expensive
|
||||
fn test_from_slice_roundtrip() {
|
||||
let (public_key, private_key) =
|
||||
crate::pgp::dc_pgp_create_keypair(CString::new("hello").unwrap().as_ptr()).unwrap();
|
||||
let (public_key, private_key) = crate::pgp::dc_pgp_create_keypair("hello").unwrap();
|
||||
|
||||
let binary = public_key.to_bytes();
|
||||
let public_key2 = Key::from_slice(&binary, KeyType::Public).expect("invalid public key");
|
||||
@@ -541,8 +456,7 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD
|
||||
#[test]
|
||||
#[ignore] // is too expensive
|
||||
fn test_ascii_roundtrip() {
|
||||
let (public_key, private_key) =
|
||||
crate::pgp::dc_pgp_create_keypair(CString::new("hello").unwrap().as_ptr()).unwrap();
|
||||
let (public_key, private_key) = crate::pgp::dc_pgp_create_keypair("hello").unwrap();
|
||||
|
||||
let s = public_key.to_armored_string(None).unwrap();
|
||||
let (public_key2, _) =
|
||||
|
||||
Reference in New Issue
Block a user