mirror of
https://github.com/chatmail/core.git
synced 2026-04-21 15:36:30 +03:00
559 lines
22 KiB
Rust
559 lines
22 KiB
Rust
use c2rust_bitfields::BitfieldStruct;
|
|
use libc;
|
|
|
|
use crate::dc_aheader::*;
|
|
use crate::dc_chat::*;
|
|
use crate::dc_context::dc_context_t;
|
|
use crate::dc_hash::*;
|
|
use crate::dc_key::*;
|
|
use crate::dc_lot::dc_lot_t;
|
|
use crate::dc_sqlite3::*;
|
|
use crate::dc_tools::*;
|
|
use crate::types::*;
|
|
use crate::x::*;
|
|
|
|
/* prefer-encrypt states */
|
|
/* *
|
|
* @class dc_apeerstate_t
|
|
* Library-internal.
|
|
*/
|
|
#[derive(Copy, Clone)]
|
|
#[repr(C)]
|
|
pub struct dc_apeerstate_t {
|
|
pub context: *mut dc_context_t,
|
|
pub addr: *mut libc::c_char,
|
|
pub last_seen: time_t,
|
|
pub last_seen_autocrypt: time_t,
|
|
pub prefer_encrypt: libc::c_int,
|
|
pub public_key: *mut dc_key_t,
|
|
pub public_key_fingerprint: *mut libc::c_char,
|
|
pub gossip_key: *mut dc_key_t,
|
|
pub gossip_timestamp: time_t,
|
|
pub gossip_key_fingerprint: *mut libc::c_char,
|
|
pub verified_key: *mut dc_key_t,
|
|
pub verified_key_fingerprint: *mut libc::c_char,
|
|
pub to_save: libc::c_int,
|
|
pub degrade_event: libc::c_int,
|
|
}
|
|
|
|
/* the returned pointer is ref'd and must be unref'd after usage */
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_apeerstate_new(mut context: *mut dc_context_t) -> *mut dc_apeerstate_t {
|
|
let mut peerstate: *mut dc_apeerstate_t = 0 as *mut dc_apeerstate_t;
|
|
peerstate = calloc(
|
|
1i32 as libc::c_ulong,
|
|
::std::mem::size_of::<dc_apeerstate_t>() as libc::c_ulong,
|
|
) as *mut dc_apeerstate_t;
|
|
if peerstate.is_null() {
|
|
exit(43i32);
|
|
}
|
|
(*peerstate).context = context;
|
|
return peerstate;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_apeerstate_unref(mut peerstate: *mut dc_apeerstate_t) {
|
|
dc_apeerstate_empty(peerstate);
|
|
free(peerstate as *mut libc::c_void);
|
|
}
|
|
/* ******************************************************************************
|
|
* dc_apeerstate_t represents the state of an Autocrypt peer - Load/save
|
|
******************************************************************************/
|
|
unsafe extern "C" fn dc_apeerstate_empty(mut peerstate: *mut dc_apeerstate_t) {
|
|
if peerstate.is_null() {
|
|
return;
|
|
}
|
|
(*peerstate).last_seen = 0i32 as time_t;
|
|
(*peerstate).last_seen_autocrypt = 0i32 as time_t;
|
|
(*peerstate).prefer_encrypt = 0i32;
|
|
(*peerstate).to_save = 0i32;
|
|
free((*peerstate).addr as *mut libc::c_void);
|
|
(*peerstate).addr = 0 as *mut libc::c_char;
|
|
free((*peerstate).public_key_fingerprint as *mut libc::c_void);
|
|
(*peerstate).public_key_fingerprint = 0 as *mut libc::c_char;
|
|
free((*peerstate).gossip_key_fingerprint as *mut libc::c_void);
|
|
(*peerstate).gossip_key_fingerprint = 0 as *mut libc::c_char;
|
|
free((*peerstate).verified_key_fingerprint as *mut libc::c_void);
|
|
(*peerstate).verified_key_fingerprint = 0 as *mut libc::c_char;
|
|
dc_key_unref((*peerstate).public_key);
|
|
(*peerstate).public_key = 0 as *mut dc_key_t;
|
|
(*peerstate).gossip_timestamp = 0i32 as time_t;
|
|
dc_key_unref((*peerstate).gossip_key);
|
|
(*peerstate).gossip_key = 0 as *mut dc_key_t;
|
|
dc_key_unref((*peerstate).verified_key);
|
|
(*peerstate).verified_key = 0 as *mut dc_key_t;
|
|
(*peerstate).degrade_event = 0i32;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_apeerstate_init_from_header(
|
|
mut peerstate: *mut dc_apeerstate_t,
|
|
mut header: *const dc_aheader_t,
|
|
mut message_time: time_t,
|
|
) -> libc::c_int {
|
|
if peerstate.is_null() || header.is_null() {
|
|
return 0i32;
|
|
}
|
|
dc_apeerstate_empty(peerstate);
|
|
(*peerstate).addr = dc_strdup((*header).addr);
|
|
(*peerstate).last_seen = message_time;
|
|
(*peerstate).last_seen_autocrypt = message_time;
|
|
(*peerstate).to_save |= 0x2i32;
|
|
(*peerstate).prefer_encrypt = (*header).prefer_encrypt;
|
|
(*peerstate).public_key = dc_key_new();
|
|
dc_key_set_from_key((*peerstate).public_key, (*header).public_key);
|
|
dc_apeerstate_recalc_fingerprint(peerstate);
|
|
return 1i32;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_apeerstate_recalc_fingerprint(
|
|
mut peerstate: *mut dc_apeerstate_t,
|
|
) -> libc::c_int {
|
|
let mut success: libc::c_int = 0i32;
|
|
let mut old_public_fingerprint: *mut libc::c_char = 0 as *mut libc::c_char;
|
|
let mut old_gossip_fingerprint: *mut libc::c_char = 0 as *mut libc::c_char;
|
|
if !peerstate.is_null() {
|
|
if !(*peerstate).public_key.is_null() {
|
|
old_public_fingerprint = (*peerstate).public_key_fingerprint;
|
|
(*peerstate).public_key_fingerprint = dc_key_get_fingerprint((*peerstate).public_key);
|
|
if old_public_fingerprint.is_null()
|
|
|| *old_public_fingerprint.offset(0isize) as libc::c_int == 0i32
|
|
|| (*peerstate).public_key_fingerprint.is_null()
|
|
|| *(*peerstate).public_key_fingerprint.offset(0isize) as libc::c_int == 0i32
|
|
|| strcasecmp(old_public_fingerprint, (*peerstate).public_key_fingerprint) != 0i32
|
|
{
|
|
(*peerstate).to_save |= 0x2i32;
|
|
if !old_public_fingerprint.is_null()
|
|
&& 0 != *old_public_fingerprint.offset(0isize) as libc::c_int
|
|
{
|
|
(*peerstate).degrade_event |= 0x2i32
|
|
}
|
|
}
|
|
}
|
|
if !(*peerstate).gossip_key.is_null() {
|
|
old_gossip_fingerprint = (*peerstate).gossip_key_fingerprint;
|
|
(*peerstate).gossip_key_fingerprint = dc_key_get_fingerprint((*peerstate).gossip_key);
|
|
if old_gossip_fingerprint.is_null()
|
|
|| *old_gossip_fingerprint.offset(0isize) as libc::c_int == 0i32
|
|
|| (*peerstate).gossip_key_fingerprint.is_null()
|
|
|| *(*peerstate).gossip_key_fingerprint.offset(0isize) as libc::c_int == 0i32
|
|
|| strcasecmp(old_gossip_fingerprint, (*peerstate).gossip_key_fingerprint) != 0i32
|
|
{
|
|
(*peerstate).to_save |= 0x2i32;
|
|
if !old_gossip_fingerprint.is_null()
|
|
&& 0 != *old_gossip_fingerprint.offset(0isize) as libc::c_int
|
|
{
|
|
(*peerstate).degrade_event |= 0x2i32
|
|
}
|
|
}
|
|
}
|
|
success = 1i32
|
|
}
|
|
free(old_public_fingerprint as *mut libc::c_void);
|
|
free(old_gossip_fingerprint as *mut libc::c_void);
|
|
return success;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_apeerstate_init_from_gossip(
|
|
mut peerstate: *mut dc_apeerstate_t,
|
|
mut gossip_header: *const dc_aheader_t,
|
|
mut message_time: time_t,
|
|
) -> libc::c_int {
|
|
if peerstate.is_null() || gossip_header.is_null() {
|
|
return 0i32;
|
|
}
|
|
dc_apeerstate_empty(peerstate);
|
|
(*peerstate).addr = dc_strdup((*gossip_header).addr);
|
|
(*peerstate).gossip_timestamp = message_time;
|
|
(*peerstate).to_save |= 0x2i32;
|
|
(*peerstate).gossip_key = dc_key_new();
|
|
dc_key_set_from_key((*peerstate).gossip_key, (*gossip_header).public_key);
|
|
dc_apeerstate_recalc_fingerprint(peerstate);
|
|
return 1i32;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_apeerstate_degrade_encryption(
|
|
mut peerstate: *mut dc_apeerstate_t,
|
|
mut message_time: time_t,
|
|
) -> libc::c_int {
|
|
if peerstate.is_null() {
|
|
return 0i32;
|
|
}
|
|
if (*peerstate).prefer_encrypt == 1i32 {
|
|
(*peerstate).degrade_event |= 0x1i32
|
|
}
|
|
(*peerstate).prefer_encrypt = 20i32;
|
|
(*peerstate).last_seen = message_time;
|
|
(*peerstate).to_save |= 0x2i32;
|
|
return 1i32;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_apeerstate_apply_header(
|
|
mut peerstate: *mut dc_apeerstate_t,
|
|
mut header: *const dc_aheader_t,
|
|
mut message_time: time_t,
|
|
) {
|
|
if peerstate.is_null()
|
|
|| header.is_null()
|
|
|| (*peerstate).addr.is_null()
|
|
|| (*header).addr.is_null()
|
|
|| (*(*header).public_key).binary.is_null()
|
|
|| strcasecmp((*peerstate).addr, (*header).addr) != 0i32
|
|
{
|
|
return;
|
|
}
|
|
if message_time > (*peerstate).last_seen_autocrypt {
|
|
(*peerstate).last_seen = message_time;
|
|
(*peerstate).last_seen_autocrypt = message_time;
|
|
(*peerstate).to_save |= 0x1i32;
|
|
if ((*header).prefer_encrypt == 1i32 || (*header).prefer_encrypt == 0i32)
|
|
&& (*header).prefer_encrypt != (*peerstate).prefer_encrypt
|
|
{
|
|
if (*peerstate).prefer_encrypt == 1i32 && (*header).prefer_encrypt != 1i32 {
|
|
(*peerstate).degrade_event |= 0x1i32
|
|
}
|
|
(*peerstate).prefer_encrypt = (*header).prefer_encrypt;
|
|
(*peerstate).to_save |= 0x2i32
|
|
}
|
|
if (*peerstate).public_key.is_null() {
|
|
(*peerstate).public_key = dc_key_new()
|
|
}
|
|
if 0 == dc_key_equals((*peerstate).public_key, (*header).public_key) {
|
|
dc_key_set_from_key((*peerstate).public_key, (*header).public_key);
|
|
dc_apeerstate_recalc_fingerprint(peerstate);
|
|
(*peerstate).to_save |= 0x2i32
|
|
}
|
|
};
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_apeerstate_apply_gossip(
|
|
mut peerstate: *mut dc_apeerstate_t,
|
|
mut gossip_header: *const dc_aheader_t,
|
|
mut message_time: time_t,
|
|
) {
|
|
if peerstate.is_null()
|
|
|| gossip_header.is_null()
|
|
|| (*peerstate).addr.is_null()
|
|
|| (*gossip_header).addr.is_null()
|
|
|| (*(*gossip_header).public_key).binary.is_null()
|
|
|| strcasecmp((*peerstate).addr, (*gossip_header).addr) != 0i32
|
|
{
|
|
return;
|
|
}
|
|
if message_time > (*peerstate).gossip_timestamp {
|
|
(*peerstate).gossip_timestamp = message_time;
|
|
(*peerstate).to_save |= 0x1i32;
|
|
if (*peerstate).gossip_key.is_null() {
|
|
(*peerstate).gossip_key = dc_key_new()
|
|
}
|
|
if 0 == dc_key_equals((*peerstate).gossip_key, (*gossip_header).public_key) {
|
|
dc_key_set_from_key((*peerstate).gossip_key, (*gossip_header).public_key);
|
|
dc_apeerstate_recalc_fingerprint(peerstate);
|
|
(*peerstate).to_save |= 0x2i32
|
|
}
|
|
};
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_apeerstate_render_gossip_header(
|
|
mut peerstate: *const dc_apeerstate_t,
|
|
mut min_verified: libc::c_int,
|
|
) -> *mut libc::c_char {
|
|
let mut ret: *mut libc::c_char = 0 as *mut libc::c_char;
|
|
let mut autocryptheader: *mut dc_aheader_t = dc_aheader_new();
|
|
if !(peerstate.is_null() || (*peerstate).addr.is_null()) {
|
|
(*autocryptheader).prefer_encrypt = 0i32;
|
|
(*autocryptheader).addr = dc_strdup((*peerstate).addr);
|
|
(*autocryptheader).public_key = dc_key_ref(dc_apeerstate_peek_key(peerstate, min_verified));
|
|
ret = dc_aheader_render(autocryptheader)
|
|
}
|
|
dc_aheader_unref(autocryptheader);
|
|
return ret;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_apeerstate_peek_key(
|
|
mut peerstate: *const dc_apeerstate_t,
|
|
mut min_verified: libc::c_int,
|
|
) -> *mut dc_key_t {
|
|
if peerstate.is_null()
|
|
|| !(*peerstate).public_key.is_null()
|
|
&& ((*(*peerstate).public_key).binary.is_null()
|
|
|| (*(*peerstate).public_key).bytes <= 0i32)
|
|
|| !(*peerstate).gossip_key.is_null()
|
|
&& ((*(*peerstate).gossip_key).binary.is_null()
|
|
|| (*(*peerstate).gossip_key).bytes <= 0i32)
|
|
|| !(*peerstate).verified_key.is_null()
|
|
&& ((*(*peerstate).verified_key).binary.is_null()
|
|
|| (*(*peerstate).verified_key).bytes <= 0i32)
|
|
{
|
|
return 0 as *mut dc_key_t;
|
|
}
|
|
if 0 != min_verified {
|
|
return (*peerstate).verified_key;
|
|
}
|
|
if !(*peerstate).public_key.is_null() {
|
|
return (*peerstate).public_key;
|
|
}
|
|
return (*peerstate).gossip_key;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_apeerstate_set_verified(
|
|
mut peerstate: *mut dc_apeerstate_t,
|
|
mut which_key: libc::c_int,
|
|
mut fingerprint: *const libc::c_char,
|
|
mut verified: libc::c_int,
|
|
) -> libc::c_int {
|
|
let mut success: libc::c_int = 0i32;
|
|
if !(peerstate.is_null() || which_key != 0i32 && which_key != 1i32 || verified != 2i32) {
|
|
if which_key == 1i32
|
|
&& !(*peerstate).public_key_fingerprint.is_null()
|
|
&& *(*peerstate).public_key_fingerprint.offset(0isize) as libc::c_int != 0i32
|
|
&& *fingerprint.offset(0isize) as libc::c_int != 0i32
|
|
&& strcasecmp((*peerstate).public_key_fingerprint, fingerprint) == 0i32
|
|
{
|
|
(*peerstate).to_save |= 0x2i32;
|
|
(*peerstate).verified_key = dc_key_ref((*peerstate).public_key);
|
|
(*peerstate).verified_key_fingerprint = dc_strdup((*peerstate).public_key_fingerprint);
|
|
success = 1i32
|
|
}
|
|
if which_key == 0i32
|
|
&& !(*peerstate).gossip_key_fingerprint.is_null()
|
|
&& *(*peerstate).gossip_key_fingerprint.offset(0isize) as libc::c_int != 0i32
|
|
&& *fingerprint.offset(0isize) as libc::c_int != 0i32
|
|
&& strcasecmp((*peerstate).gossip_key_fingerprint, fingerprint) == 0i32
|
|
{
|
|
(*peerstate).to_save |= 0x2i32;
|
|
(*peerstate).verified_key = dc_key_ref((*peerstate).gossip_key);
|
|
(*peerstate).verified_key_fingerprint = dc_strdup((*peerstate).gossip_key_fingerprint);
|
|
success = 1i32
|
|
}
|
|
}
|
|
return success;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_apeerstate_load_by_addr(
|
|
mut peerstate: *mut dc_apeerstate_t,
|
|
mut sql: *mut dc_sqlite3_t,
|
|
mut addr: *const libc::c_char,
|
|
) -> libc::c_int {
|
|
let mut success: libc::c_int = 0i32;
|
|
let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt;
|
|
if !(peerstate.is_null() || sql.is_null() || addr.is_null()) {
|
|
dc_apeerstate_empty(peerstate);
|
|
stmt =
|
|
dc_sqlite3_prepare(sql,
|
|
b"SELECT addr, last_seen, last_seen_autocrypt, prefer_encrypted, public_key, gossip_timestamp, gossip_key, public_key_fingerprint, gossip_key_fingerprint, verified_key, verified_key_fingerprint FROM acpeerstates WHERE addr=? COLLATE NOCASE;\x00"
|
|
as *const u8 as *const libc::c_char);
|
|
sqlite3_bind_text(stmt, 1i32, addr, -1i32, None);
|
|
if !(sqlite3_step(stmt) != 100i32) {
|
|
dc_apeerstate_set_from_stmt(peerstate, stmt);
|
|
success = 1i32
|
|
}
|
|
}
|
|
sqlite3_finalize(stmt);
|
|
return success;
|
|
}
|
|
unsafe extern "C" fn dc_apeerstate_set_from_stmt(
|
|
mut peerstate: *mut dc_apeerstate_t,
|
|
mut stmt: *mut sqlite3_stmt,
|
|
) {
|
|
(*peerstate).addr = dc_strdup(sqlite3_column_text(stmt, 0i32) as *mut libc::c_char);
|
|
(*peerstate).last_seen = sqlite3_column_int64(stmt, 1i32) as time_t;
|
|
(*peerstate).last_seen_autocrypt = sqlite3_column_int64(stmt, 2i32) as time_t;
|
|
(*peerstate).prefer_encrypt = sqlite3_column_int(stmt, 3i32);
|
|
(*peerstate).gossip_timestamp = sqlite3_column_int(stmt, 5i32) as time_t;
|
|
(*peerstate).public_key_fingerprint =
|
|
dc_strdup(sqlite3_column_text(stmt, 7i32) as *mut libc::c_char);
|
|
(*peerstate).gossip_key_fingerprint =
|
|
dc_strdup(sqlite3_column_text(stmt, 8i32) as *mut libc::c_char);
|
|
(*peerstate).verified_key_fingerprint =
|
|
dc_strdup(sqlite3_column_text(stmt, 10i32) as *mut libc::c_char);
|
|
if sqlite3_column_type(stmt, 4i32) != 5i32 {
|
|
(*peerstate).public_key = dc_key_new();
|
|
dc_key_set_from_stmt((*peerstate).public_key, stmt, 4i32, 0i32);
|
|
}
|
|
if sqlite3_column_type(stmt, 6i32) != 5i32 {
|
|
(*peerstate).gossip_key = dc_key_new();
|
|
dc_key_set_from_stmt((*peerstate).gossip_key, stmt, 6i32, 0i32);
|
|
}
|
|
if sqlite3_column_type(stmt, 9i32) != 5i32 {
|
|
(*peerstate).verified_key = dc_key_new();
|
|
dc_key_set_from_stmt((*peerstate).verified_key, stmt, 9i32, 0i32);
|
|
};
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_apeerstate_load_by_fingerprint(
|
|
mut peerstate: *mut dc_apeerstate_t,
|
|
mut sql: *mut dc_sqlite3_t,
|
|
mut fingerprint: *const libc::c_char,
|
|
) -> libc::c_int {
|
|
let mut success: libc::c_int = 0i32;
|
|
let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt;
|
|
if !(peerstate.is_null() || sql.is_null() || fingerprint.is_null()) {
|
|
dc_apeerstate_empty(peerstate);
|
|
stmt =
|
|
dc_sqlite3_prepare(sql,
|
|
b"SELECT addr, last_seen, last_seen_autocrypt, prefer_encrypted, public_key, gossip_timestamp, gossip_key, public_key_fingerprint, gossip_key_fingerprint, verified_key, verified_key_fingerprint FROM acpeerstates WHERE public_key_fingerprint=? COLLATE NOCASE OR gossip_key_fingerprint=? COLLATE NOCASE ORDER BY public_key_fingerprint=? DESC;\x00"
|
|
as *const u8 as *const libc::c_char);
|
|
sqlite3_bind_text(stmt, 1i32, fingerprint, -1i32, None);
|
|
sqlite3_bind_text(stmt, 2i32, fingerprint, -1i32, None);
|
|
sqlite3_bind_text(stmt, 3i32, fingerprint, -1i32, None);
|
|
if !(sqlite3_step(stmt) != 100i32) {
|
|
dc_apeerstate_set_from_stmt(peerstate, stmt);
|
|
success = 1i32
|
|
}
|
|
}
|
|
sqlite3_finalize(stmt);
|
|
return success;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_apeerstate_save_to_db(
|
|
mut peerstate: *const dc_apeerstate_t,
|
|
mut sql: *mut dc_sqlite3_t,
|
|
mut create: libc::c_int,
|
|
) -> libc::c_int {
|
|
let mut current_block: u64;
|
|
let mut success: libc::c_int = 0i32;
|
|
let mut stmt: *mut sqlite3_stmt = 0 as *mut sqlite3_stmt;
|
|
if peerstate.is_null() || sql.is_null() || (*peerstate).addr.is_null() {
|
|
return 0i32;
|
|
}
|
|
if 0 != create {
|
|
stmt = dc_sqlite3_prepare(
|
|
sql,
|
|
b"INSERT INTO acpeerstates (addr) VALUES(?);\x00" as *const u8 as *const libc::c_char,
|
|
);
|
|
sqlite3_bind_text(stmt, 1i32, (*peerstate).addr, -1i32, None);
|
|
sqlite3_step(stmt);
|
|
sqlite3_finalize(stmt);
|
|
stmt = 0 as *mut sqlite3_stmt
|
|
}
|
|
if 0 != (*peerstate).to_save & 0x2i32 || 0 != create {
|
|
stmt =
|
|
dc_sqlite3_prepare(sql,
|
|
b"UPDATE acpeerstates SET last_seen=?, last_seen_autocrypt=?, prefer_encrypted=?, public_key=?, gossip_timestamp=?, gossip_key=?, public_key_fingerprint=?, gossip_key_fingerprint=?, verified_key=?, verified_key_fingerprint=? WHERE addr=?;\x00"
|
|
as *const u8 as *const libc::c_char);
|
|
sqlite3_bind_int64(stmt, 1i32, (*peerstate).last_seen as sqlite3_int64);
|
|
sqlite3_bind_int64(
|
|
stmt,
|
|
2i32,
|
|
(*peerstate).last_seen_autocrypt as sqlite3_int64,
|
|
);
|
|
sqlite3_bind_int64(stmt, 3i32, (*peerstate).prefer_encrypt as sqlite3_int64);
|
|
sqlite3_bind_blob(
|
|
stmt,
|
|
4i32,
|
|
if !(*peerstate).public_key.is_null() {
|
|
(*(*peerstate).public_key).binary
|
|
} else {
|
|
0 as *mut libc::c_void
|
|
},
|
|
if !(*peerstate).public_key.is_null() {
|
|
(*(*peerstate).public_key).bytes
|
|
} else {
|
|
0i32
|
|
},
|
|
None,
|
|
);
|
|
sqlite3_bind_int64(stmt, 5i32, (*peerstate).gossip_timestamp as sqlite3_int64);
|
|
sqlite3_bind_blob(
|
|
stmt,
|
|
6i32,
|
|
if !(*peerstate).gossip_key.is_null() {
|
|
(*(*peerstate).gossip_key).binary
|
|
} else {
|
|
0 as *mut libc::c_void
|
|
},
|
|
if !(*peerstate).gossip_key.is_null() {
|
|
(*(*peerstate).gossip_key).bytes
|
|
} else {
|
|
0i32
|
|
},
|
|
None,
|
|
);
|
|
sqlite3_bind_text(stmt, 7i32, (*peerstate).public_key_fingerprint, -1i32, None);
|
|
sqlite3_bind_text(stmt, 8i32, (*peerstate).gossip_key_fingerprint, -1i32, None);
|
|
sqlite3_bind_blob(
|
|
stmt,
|
|
9i32,
|
|
if !(*peerstate).verified_key.is_null() {
|
|
(*(*peerstate).verified_key).binary
|
|
} else {
|
|
0 as *mut libc::c_void
|
|
},
|
|
if !(*peerstate).verified_key.is_null() {
|
|
(*(*peerstate).verified_key).bytes
|
|
} else {
|
|
0i32
|
|
},
|
|
None,
|
|
);
|
|
sqlite3_bind_text(
|
|
stmt,
|
|
10i32,
|
|
(*peerstate).verified_key_fingerprint,
|
|
-1i32,
|
|
None,
|
|
);
|
|
sqlite3_bind_text(stmt, 11i32, (*peerstate).addr, -1i32, None);
|
|
if sqlite3_step(stmt) != 101i32 {
|
|
current_block = 7258450500457619456;
|
|
} else {
|
|
sqlite3_finalize(stmt);
|
|
stmt = 0 as *mut sqlite3_stmt;
|
|
current_block = 11913429853522160501;
|
|
}
|
|
} else if 0 != (*peerstate).to_save & 0x1i32 {
|
|
stmt =
|
|
dc_sqlite3_prepare(sql,
|
|
b"UPDATE acpeerstates SET last_seen=?, last_seen_autocrypt=?, gossip_timestamp=? WHERE addr=?;\x00"
|
|
as *const u8 as *const libc::c_char);
|
|
sqlite3_bind_int64(stmt, 1i32, (*peerstate).last_seen as sqlite3_int64);
|
|
sqlite3_bind_int64(
|
|
stmt,
|
|
2i32,
|
|
(*peerstate).last_seen_autocrypt as sqlite3_int64,
|
|
);
|
|
sqlite3_bind_int64(stmt, 3i32, (*peerstate).gossip_timestamp as sqlite3_int64);
|
|
sqlite3_bind_text(stmt, 4i32, (*peerstate).addr, -1i32, None);
|
|
if sqlite3_step(stmt) != 101i32 {
|
|
current_block = 7258450500457619456;
|
|
} else {
|
|
sqlite3_finalize(stmt);
|
|
stmt = 0 as *mut sqlite3_stmt;
|
|
current_block = 11913429853522160501;
|
|
}
|
|
} else {
|
|
current_block = 11913429853522160501;
|
|
}
|
|
match current_block {
|
|
11913429853522160501 => {
|
|
if 0 != (*peerstate).to_save & 0x2i32 || 0 != create {
|
|
dc_reset_gossiped_timestamp((*peerstate).context, 0i32 as uint32_t);
|
|
}
|
|
success = 1i32
|
|
}
|
|
_ => {}
|
|
}
|
|
sqlite3_finalize(stmt);
|
|
return success;
|
|
}
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_apeerstate_has_verified_key(
|
|
mut peerstate: *const dc_apeerstate_t,
|
|
mut fingerprints: *const dc_hash_t,
|
|
) -> libc::c_int {
|
|
if peerstate.is_null() || fingerprints.is_null() {
|
|
return 0i32;
|
|
}
|
|
if !(*peerstate).verified_key.is_null()
|
|
&& !(*peerstate).verified_key_fingerprint.is_null()
|
|
&& !dc_hash_find(
|
|
fingerprints,
|
|
(*peerstate).verified_key_fingerprint as *const libc::c_void,
|
|
strlen((*peerstate).verified_key_fingerprint) as libc::c_int,
|
|
)
|
|
.is_null()
|
|
{
|
|
return 1i32;
|
|
}
|
|
return 0i32;
|
|
}
|