parent
be03cdc27a
commit
e8a376a87f
|
@ -34,8 +34,8 @@ extern "C"
|
|||
*/
|
||||
typedef uint8_t zrtp_cache_id_t[24];
|
||||
|
||||
#define ZRTP_MITMCACHE_ELEM_LENGTH (sizeof(zrtp_cache_id_t) + sizeof(zrtp_string64_t))
|
||||
#define ZRTP_CACHE_ELEM_LENGTH (sizeof(zrtp_cache_elem_t) - sizeof(mlist_t))
|
||||
#define ZRTP_MITMCACHE_ELEM_LENGTH ( sizeof(zrtp_cache_id_t) + sizeof(zrtp_string64_t) )
|
||||
#define ZRTP_CACHE_ELEM_LENGTH ( sizeof(zrtp_cache_elem_t) - sizeof(mlist_t) - (sizeof(uint32_t)*2) )
|
||||
#define ZFONE_CACHE_NAME_LENGTH 256
|
||||
|
||||
/**
|
||||
|
@ -51,10 +51,12 @@ typedef struct zrtp_cache_elem
|
|||
uint32_t verified; /** Verified flag for the cache value */
|
||||
uint32_t lastused_at; /** Last usage time-stamp in seconds */
|
||||
uint32_t ttl; /** Cache TTL since lastused_at in seconds */
|
||||
uint32_t secure_since; /** Secure since date in seconds. Utility field. Doen't required by libzrtp. */
|
||||
uint32_t secure_since; /** Secure since date in seconds. Utility field. Don't required by libzrtp. */
|
||||
char name[ZFONE_CACHE_NAME_LENGTH]; /** name of the user associated with this cache entry */
|
||||
uint32_t name_length; /** cache name lengths */
|
||||
uint32_t presh_counter; /** number of Preshared streams made since last DH echange */
|
||||
uint32_t presh_counter; /** number of Preshared streams made since last DH exchange */
|
||||
uint32_t _index; /** cache element index in the cache file */
|
||||
uint32_t _is_dirty; /** dirty flag means the entry has unsaved changes */
|
||||
mlist_t _mlist;
|
||||
} zrtp_cache_elem_t;
|
||||
|
||||
|
|
|
@ -359,6 +359,7 @@ struct zrtp_global_t
|
|||
/** RNG unit initialization flag. */
|
||||
uint8_t rand_initialized;
|
||||
|
||||
/** Full path to ZRTP cache file. */
|
||||
zrtp_string256_t def_cache_path;
|
||||
|
||||
/** This object is used to protect the shared RNG hash zrtp#rand_ctx */
|
||||
|
|
|
@ -11,33 +11,47 @@ TOP_SRCDIR=$(top_srcdir)/../..
|
|||
INCLUDES = -I$(TOP_SRCDIR)/include \
|
||||
-I$(TOP_SRCDIR)/include/enterprise \
|
||||
-I$(TOP_SRCDIR)/. \
|
||||
-I$(TOP_SRCDIR)/test \
|
||||
-I$(TOP_SRCDIR)/test/cmockery \
|
||||
-I$(TOP_SRCDIR)/third_party/bgaes \
|
||||
-I$(TOP_SRCDIR)/third_party/bnlib
|
||||
|
||||
|
||||
check_PROGRAMS = libzrtp_test
|
||||
#check_PROGRAMS = cache_test libzrtp_test
|
||||
check_PROGRAMS = cache_test
|
||||
|
||||
### ZRTP Cache testing
|
||||
|
||||
cache_test_SOURCES = $(TOP_SRCDIR)/test/cmockery/cmockery.c \
|
||||
$(TOP_SRCDIR)/test/cache_test.c
|
||||
cache_test_LDADD = ../libzrtp.a $(TOP_SRCDIR)/third_party/bnlib/libbn.a -lpthread
|
||||
|
||||
|
||||
### ZRTP high-level test-case
|
||||
|
||||
libzrtp_test_SOURCES = $(TOP_SRCDIR)/test/pc/zrtp_test_core.c \
|
||||
$(TOP_SRCDIR)/test/pc/zrtp_test_crypto.c \
|
||||
$(TOP_SRCDIR)/test/pc/zrtp_test_queue.c \
|
||||
$(TOP_SRCDIR)/test/pc/zrtp_test_ui.c
|
||||
|
||||
libzrtp_test_LDADD = ../libzrtp.a \
|
||||
$(TOP_SRCDIR)/third_party/bnlib/libbn.a -lpthread
|
||||
libzrtp_test_LDADD = ../libzrtp.a $(TOP_SRCDIR)/third_party/bnlib/libbn.a -lpthread
|
||||
|
||||
SUBDIRS = .
|
||||
|
||||
check:
|
||||
@echo ""
|
||||
@echo "*========================================================================*"
|
||||
@echo "* starting libZRTP tests *"
|
||||
@echo "*========================================================================*"
|
||||
@echo ""
|
||||
@./libzrtp_test
|
||||
check:
|
||||
# @ ./cache_test
|
||||
|
||||
@echo ""
|
||||
@echo "*========================================================================*"
|
||||
@echo "* In case you have a test FAILED send the generated log file *"
|
||||
@echo "* with your comment to <zrtp_support@zfoneproject.com>. *"
|
||||
@echo "*========================================================================*"
|
||||
@echo ""
|
||||
# check:
|
||||
# @echo ""
|
||||
# @echo "*========================================================================*"
|
||||
# @echo "* starting libZRTP tests *"
|
||||
# @echo "*========================================================================*"
|
||||
# @echo ""
|
||||
# @./libzrtp_test
|
||||
#
|
||||
# @echo ""
|
||||
# @echo "*========================================================================*"
|
||||
# @echo "* In case you have a test FAILED send the generated log file *"
|
||||
# @echo "* with your comment to <zrtp_support@zfoneproject.com>. *"
|
||||
# @echo "*========================================================================*"
|
||||
# @echo ""
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
#if (ZRTP_PLATFORM != ZP_WIN32_KERNEL)
|
||||
|
||||
static mlist_t cache_head;
|
||||
static uint32_t g_cache_elems_counter = 0;
|
||||
static mlist_t mitmcache_head;
|
||||
static uint32_t g_mitmcache_elems_counter = 0;
|
||||
static uint8_t inited = 0;
|
||||
|
||||
static zrtp_global_t* zrtp;
|
||||
|
@ -95,6 +97,7 @@ void zrtp_def_cache_down()
|
|||
zrtp_mutex_destroy(def_cache_protector);
|
||||
|
||||
inited = 0;
|
||||
zrtp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,7 +161,7 @@ static zrtp_status_t cache_put( const zrtp_stringn_t* one_ZID,
|
|||
new_elem = get_elem(id, is_mitm);
|
||||
if (!new_elem)
|
||||
{
|
||||
/* If cache doesn't exist - create ne one */
|
||||
/* If cache doesn't exist - create new one */
|
||||
if (!( new_elem = (zrtp_cache_elem_t*) zrtp_sys_alloc(sizeof(zrtp_cache_elem_t)) )) {
|
||||
break;
|
||||
}
|
||||
|
@ -171,9 +174,15 @@ static zrtp_status_t cache_put( const zrtp_stringn_t* one_ZID,
|
|||
|
||||
mlist_add_tail(is_mitm ? &mitmcache_head : &cache_head, &new_elem->_mlist);
|
||||
zrtp_memcpy(new_elem->id, id, sizeof(zrtp_cache_id_t));
|
||||
|
||||
if (is_mitm) {
|
||||
new_elem->_index = g_mitmcache_elems_counter++;
|
||||
} else {
|
||||
new_elem->_index = g_cache_elems_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Save current cache value as previous one and new as a current */
|
||||
/* Save current cache value as previous one and new as a current */
|
||||
if (!is_mitm) {
|
||||
if (new_elem->curr_cache.length > 0) {
|
||||
zrtp_zstrcpy(ZSTR_GV(new_elem->prev_cache), ZSTR_GV(new_elem->curr_cache));
|
||||
|
@ -185,6 +194,8 @@ static zrtp_status_t cache_put( const zrtp_stringn_t* one_ZID,
|
|||
if (!is_mitm) {
|
||||
new_elem->ttl = rss->ttl;
|
||||
}
|
||||
|
||||
new_elem->_is_dirty = 1;
|
||||
} while (0);
|
||||
zrtp_mutex_unlock(def_cache_protector);
|
||||
|
||||
|
@ -193,7 +204,7 @@ static zrtp_status_t cache_put( const zrtp_stringn_t* one_ZID,
|
|||
|
||||
zrtp_status_t zrtp_def_cache_put( const zrtp_stringn_t* one_ZID,
|
||||
const zrtp_stringn_t* another_ZID,
|
||||
zrtp_shared_secret_t *rss) {
|
||||
zrtp_shared_secret_t *rss) {
|
||||
return cache_put(one_ZID, another_ZID, rss, 0);
|
||||
}
|
||||
|
||||
|
@ -270,6 +281,8 @@ zrtp_status_t zrtp_def_cache_set_presh_counter( const zrtp_stringn_t* one_zid,
|
|||
if (new_elem) {
|
||||
ZRTP_LOG(3,(_ZTU_,"\tTEST! Update counter to %u.\n", counter));
|
||||
new_elem->presh_counter = counter;
|
||||
|
||||
new_elem->_is_dirty = 1;
|
||||
}
|
||||
zrtp_mutex_unlock(def_cache_protector);
|
||||
|
||||
|
@ -394,6 +407,7 @@ zrtp_status_t zrtp_cache_user_init()
|
|||
uint32_t i = 0;
|
||||
unsigned is_unsupported = 0;
|
||||
|
||||
ZRTP_LOG(3,(_ZTU_,"\tLoad ZRTP cache from <%s>...\n", zrtp->def_cache_path.buffer));
|
||||
|
||||
/* Try to open existing file. If ther is no cache file - start with empty cache */
|
||||
#if (ZRTP_PLATFORM == ZP_WIN32)
|
||||
|
@ -402,6 +416,7 @@ zrtp_status_t zrtp_cache_user_init()
|
|||
}
|
||||
#else
|
||||
if (0 == (cache_file = fopen(zrtp->def_cache_path.buffer, "rb"))) {
|
||||
ZRTP_LOG(3,(_ZTU_,"\tCan't open file for reading.\n"));
|
||||
return zrtp_status_ok;
|
||||
}
|
||||
#endif
|
||||
|
@ -413,43 +428,50 @@ zrtp_status_t zrtp_cache_user_init()
|
|||
*/
|
||||
do {
|
||||
char version_buff[256];
|
||||
memset(version_buff, 0, sizeof(version_buff));
|
||||
|
||||
if (fread(version_buff, strlen(ZRTP_DEF_CACHE_VERSION_STR)+strlen(ZRTP_DEF_CACHE_VERSION_VAL), 1, cache_file) <= 0) {
|
||||
ZRTP_LOG(3,(_ZTU_,"Cache file is too small.\n"));
|
||||
ZRTP_LOG(3,(_ZTU_,"\tCache Error: Cache file is too small.\n"));
|
||||
is_unsupported = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (0 != zrtp_memcmp(version_buff, ZRTP_DEF_CACHE_VERSION_STR, strlen(ZRTP_DEF_CACHE_VERSION_STR))) {
|
||||
ZRTP_LOG(3,(_ZTU_,"Can't find ZRTP Version tag in the cache file.\n"));
|
||||
ZRTP_LOG(3,(_ZTU_,"\tCache Error: Can't find ZRTP Version tag in the cache file.\n"));
|
||||
is_unsupported = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
ZRTP_LOG(3,(_ZTU_,"\tZRTP cache file has version=%s\n", version_buff+strlen(ZRTP_DEF_CACHE_VERSION_STR)));
|
||||
|
||||
if (0 != zrtp_memcmp(version_buff+strlen(ZRTP_DEF_CACHE_VERSION_STR), ZRTP_DEF_CACHE_VERSION_VAL, strlen(ZRTP_DEF_CACHE_VERSION_VAL))) {
|
||||
ZRTP_LOG(3,(_ZTU_,"Usupported ZRTP cache version.\n"));
|
||||
ZRTP_LOG(3,(_ZTU_,"\tCache Error: Unsupported ZRTP cache version.\n"));
|
||||
is_unsupported = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (is_unsupported) {
|
||||
ZRTP_LOG(3,(_ZTU_,"Unsupported version of ZRTP cache file detected - white-out the cache.\n"));
|
||||
ZRTP_LOG(3,(_ZTU_,"\tCache Error: Unsupported version of ZRTP cache file detected - white-out the cache.\n"));
|
||||
fclose(cache_file);
|
||||
return zrtp_status_ok;
|
||||
}
|
||||
|
||||
g_mitmcache_elems_counter = 0;
|
||||
|
||||
/*
|
||||
* Load MitM caches: first 32 bits is a mitm secrets counter. Read it and then
|
||||
* Load MitM caches: first 32 bits is a MiTM secrets counter. Read it and then
|
||||
* upload appropriate number of MitM secrets.
|
||||
*/
|
||||
do {
|
||||
cache_elems_count = 0;
|
||||
if (fread(&mitmcache_elems_count, 4, 1, cache_file) <= 0) {
|
||||
ZRTP_INT_CACHE_BREAK(s, zrtp_status_read_fail);
|
||||
}
|
||||
mitmcache_elems_count = zrtp_ntoh32(mitmcache_elems_count);
|
||||
|
||||
ZRTP_LOG(3,(_ZTU_,"\tZRTP cache file contains %u MiTM secrets.\n", mitmcache_elems_count));
|
||||
|
||||
mitmcache_elems_count = zrtp_ntoh32(mitmcache_elems_count);
|
||||
for (i=0; i<mitmcache_elems_count; i++)
|
||||
{
|
||||
new_elem = (zrtp_cache_elem_t*) zrtp_sys_alloc(sizeof(zrtp_cache_elem_t));
|
||||
|
@ -458,11 +480,17 @@ zrtp_status_t zrtp_cache_user_init()
|
|||
}
|
||||
|
||||
if (fread(new_elem, ZRTP_MITMCACHE_ELEM_LENGTH, 1, cache_file) <= 0) {
|
||||
ZRTP_LOG(3,(_ZTU_,"\tERROR! MiTM cache element read fail (id=%u).\n", i));
|
||||
|
||||
zrtp_sys_free(new_elem);
|
||||
ZRTP_INT_CACHE_BREAK(s, zrtp_status_read_fail);
|
||||
}
|
||||
|
||||
cache_make_cross(NULL, new_elem, 1);
|
||||
|
||||
new_elem->_index = g_mitmcache_elems_counter++;
|
||||
new_elem->_is_dirty = 0;
|
||||
|
||||
mlist_add_tail(&mitmcache_head, &new_elem->_mlist);
|
||||
}
|
||||
|
||||
|
@ -474,18 +502,25 @@ zrtp_status_t zrtp_cache_user_init()
|
|||
zrtp_def_cache_down();
|
||||
return s;
|
||||
}
|
||||
|
||||
ZRTP_LOG(3,(_ZTU_,"\tAll %u MiTM Cache entries have been uploaded.\n", g_mitmcache_elems_counter));
|
||||
|
||||
/*
|
||||
* Load regular caches: first 32 bits is a secrets counter. Read it and then
|
||||
* upload appropriate number of regular secrets.
|
||||
*/
|
||||
cache_elems_count = 0;
|
||||
if (fread(&cache_elems_count, 4, 1, cache_file) <= 0) {
|
||||
fclose(cache_file);
|
||||
zrtp_def_cache_down();
|
||||
return zrtp_status_read_fail;
|
||||
}
|
||||
|
||||
}
|
||||
cache_elems_count = zrtp_ntoh32(cache_elems_count);
|
||||
|
||||
g_cache_elems_counter = 0;
|
||||
|
||||
ZRTP_LOG(3,(_ZTU_,"\tZRTP cache file contains %u RS secrets.\n", cache_elems_count));
|
||||
|
||||
for (i=0; i<cache_elems_count; i++)
|
||||
{
|
||||
new_elem = (zrtp_cache_elem_t*) zrtp_sys_alloc(sizeof(zrtp_cache_elem_t));
|
||||
|
@ -494,11 +529,16 @@ zrtp_status_t zrtp_cache_user_init()
|
|||
}
|
||||
|
||||
if (fread(new_elem, ZRTP_CACHE_ELEM_LENGTH, 1, cache_file) <= 0) {
|
||||
ZRTP_LOG(3,(_ZTU_,"\tERROR! RS cache element read fail (id=%u).\n", i));
|
||||
zrtp_sys_free(new_elem);
|
||||
ZRTP_INT_CACHE_BREAK(s, zrtp_status_read_fail);
|
||||
}
|
||||
|
||||
cache_make_cross(NULL, new_elem, 1);
|
||||
|
||||
new_elem->_index = g_cache_elems_counter++;
|
||||
new_elem->_is_dirty = 0;
|
||||
|
||||
mlist_add_tail(&cache_head, &new_elem->_mlist);
|
||||
}
|
||||
if (i != cache_elems_count) {
|
||||
|
@ -510,6 +550,8 @@ zrtp_status_t zrtp_cache_user_init()
|
|||
return zrtp_status_fail;
|
||||
}
|
||||
|
||||
ZRTP_LOG(3,(_ZTU_,"\tAll of %u RS Cache entries have been uploaded.\n", g_cache_elems_counter));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -525,15 +567,65 @@ zrtp_status_t zrtp_cache_user_init()
|
|||
return s;\
|
||||
};
|
||||
|
||||
static zrtp_status_t flush_elem_(zrtp_cache_elem_t *elem, FILE *cache_file, unsigned is_mitm) {
|
||||
zrtp_cache_elem_t tmp_elem;
|
||||
uint32_t pos = 0;
|
||||
|
||||
/*
|
||||
* Let's calculate cache element position in the file
|
||||
*/
|
||||
printf("flush_elem_(): calculate Element offset for %s..\n", is_mitm?"MiTM":"RS");
|
||||
|
||||
/* Skip the header */
|
||||
pos += strlen(ZRTP_DEF_CACHE_VERSION_STR)+strlen(ZRTP_DEF_CACHE_VERSION_VAL);
|
||||
|
||||
pos += sizeof(uint32_t); /* Skip MiTM secretes count. */
|
||||
|
||||
printf("flush_elem_(): \t pos=%u (Header, MiTM Count).\n", pos);
|
||||
|
||||
if (is_mitm) {
|
||||
/* position within MiTM secrets block. */
|
||||
pos += (elem->_index * ZRTP_MITMCACHE_ELEM_LENGTH);
|
||||
printf("flush_elem_(): \t pos=%u (Header, MiTM Count + %u MiTM Secrets).\n", pos, elem->_index);
|
||||
} else {
|
||||
/* Skip MiTM Secrets block */
|
||||
pos += (g_mitmcache_elems_counter * ZRTP_MITMCACHE_ELEM_LENGTH);
|
||||
|
||||
pos += sizeof(uint32_t); /* Skip RS elements count. */
|
||||
|
||||
pos += (elem->_index * ZRTP_CACHE_ELEM_LENGTH); /* Skip previous RS elements */
|
||||
|
||||
printf("flush_elem_(): \t pos=%u (Header, MiTM Count + ALL %u Secrets, RS counter and %u prev. RS).\n", pos, g_mitmcache_elems_counter, elem->_index);
|
||||
}
|
||||
|
||||
fseek(cache_file, pos, SEEK_SET);
|
||||
|
||||
/* Prepare element for storing, convert all fields to the network byte-order. */
|
||||
cache_make_cross(elem, &tmp_elem, 0);
|
||||
|
||||
printf("flush_elem_(): write to offset=%lu\n", ftell(cache_file));
|
||||
|
||||
/* Flush the element. */
|
||||
if (fwrite(&tmp_elem, (is_mitm ? ZRTP_MITMCACHE_ELEM_LENGTH : ZRTP_CACHE_ELEM_LENGTH), 1, cache_file) != 1) {
|
||||
printf("flush_elem_(): ERROR!!! write failed!\n");
|
||||
return zrtp_status_write_fail;
|
||||
} else {
|
||||
elem->_is_dirty = 0;
|
||||
|
||||
printf("flush_elem_(): OK! %lu bytes were written\n", (is_mitm ? ZRTP_MITMCACHE_ELEM_LENGTH : ZRTP_CACHE_ELEM_LENGTH));
|
||||
return zrtp_status_ok;
|
||||
}
|
||||
}
|
||||
|
||||
zrtp_status_t zrtp_cache_user_down()
|
||||
{
|
||||
FILE* cache_file = 0;
|
||||
zrtp_cache_elem_t tmp_elem;
|
||||
mlist_t *node = 0;
|
||||
uint32_t count = 0;
|
||||
uint32_t pos = 0;
|
||||
|
||||
ZRTP_LOG(3,(_ZTU_,"\tStoring ZRTP cache to the file...\n"));
|
||||
ZRTP_LOG(3,(_ZTU_,"\tStoring ZRTP cache to <%s>...\n", zrtp->def_cache_path.buffer));
|
||||
|
||||
/* Open/create file for writing */
|
||||
#if (ZRTP_PLATFORM == ZP_WIN32)
|
||||
if (0 != fopen_s(&cache_file, zrtp->def_cache_path.buffer, "wb+")) {
|
||||
|
@ -550,53 +642,81 @@ zrtp_status_t zrtp_cache_user_down()
|
|||
|
||||
/* Store version string first. Format: &ZRTP_DEF_CACHE_VERSION_STR&ZRTP_DEF_CACHE_VERSION_VAL */
|
||||
if (1 != fwrite(ZRTP_DEF_CACHE_VERSION_STR, strlen(ZRTP_DEF_CACHE_VERSION_STR), 1, cache_file)) {
|
||||
ZRTP_LOG(2,(_ZTU_,"\tERROR! unable to write header to the cache file\n"));
|
||||
ZRTP_DOWN_CACHE_RETURN(zrtp_status_write_fail, cache_file);
|
||||
}
|
||||
if (1 != fwrite(ZRTP_DEF_CACHE_VERSION_VAL, strlen(ZRTP_DEF_CACHE_VERSION_VAL), 1, cache_file)) {
|
||||
ZRTP_LOG(2,(_ZTU_,"\tERROR! unable to write header to the cache file\n"));
|
||||
ZRTP_DOWN_CACHE_RETURN(zrtp_status_write_fail, cache_file);
|
||||
}
|
||||
|
||||
/* Store PBX secrets first. Format: <secrets count>, <secrets' data> */
|
||||
/*
|
||||
* Store PBX secrets first. Format: <secrets count>, <secrets' data>
|
||||
*
|
||||
* NOTE!!! It's IMPORTANT to store PBX secrets before the Regular secrets!!!
|
||||
*/
|
||||
pos = ftell(cache_file);
|
||||
|
||||
count = 0;
|
||||
fwrite(&count, sizeof(count), 1, cache_file);
|
||||
|
||||
mlist_for_each(node, &mitmcache_head) {
|
||||
zrtp_cache_elem_t* elem = mlist_get_struct(zrtp_cache_elem_t, _mlist, node);
|
||||
cache_make_cross(elem, &tmp_elem, 0);
|
||||
if (fwrite(&tmp_elem, ZRTP_MITMCACHE_ELEM_LENGTH, 1, cache_file) != 1) {
|
||||
ZRTP_DOWN_CACHE_RETURN(zrtp_status_write_fail, cache_file);
|
||||
/* Store dirty values only. */
|
||||
if (elem->_is_dirty) {
|
||||
printf("zrtp_cache_user_down: Store MiTM elem index=%u, not modified.\n", elem->_index);
|
||||
if (zrtp_status_ok != flush_elem_(elem, cache_file, 1)) {
|
||||
ZRTP_DOWN_CACHE_RETURN(zrtp_status_write_fail, cache_file);
|
||||
}
|
||||
} else {
|
||||
printf("zrtp_cache_user_down: Skip MiTM elem index=%u, not modified.\n", elem->_index);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
fseek(cache_file, pos, SEEK_SET);
|
||||
count = zrtp_hton32(count);
|
||||
|
||||
count = zrtp_hton32(g_mitmcache_elems_counter);
|
||||
if (fwrite(&count, sizeof(count), 1, cache_file) != 1) {
|
||||
ZRTP_DOWN_CACHE_RETURN(zrtp_status_write_fail, cache_file);
|
||||
}
|
||||
|
||||
fseek(cache_file, 0L, SEEK_END);
|
||||
ZRTP_LOG(3,(_ZTU_,"\t%u MiTM cache entries have been stored sucessfully.\n",zrtp_ntoh32(count)));
|
||||
ZRTP_LOG(3,(_ZTU_,"\t%u MiTM cache entries have been stored successfully.\n",zrtp_ntoh32(count)));
|
||||
|
||||
/*
|
||||
* Store regular secrets. Format: <secrets count>, <secrets' data>
|
||||
*/
|
||||
|
||||
/* Seek to the beginning of the Regular secrets block */
|
||||
pos = strlen(ZRTP_DEF_CACHE_VERSION_STR)+strlen(ZRTP_DEF_CACHE_VERSION_VAL);
|
||||
pos += sizeof(uint32_t); /* Skip MiTM secrets count. */
|
||||
pos += (g_mitmcache_elems_counter * ZRTP_MITMCACHE_ELEM_LENGTH); /* Skip MiTM Secrets block */
|
||||
|
||||
fseek(cache_file, pos, SEEK_SET);
|
||||
|
||||
/* Store reqular secrets. Format: <secrets count>, <secrets' data> */
|
||||
pos = ftell(cache_file);
|
||||
count = 0;
|
||||
fwrite(&count, sizeof(count), 1, cache_file);
|
||||
|
||||
mlist_for_each(node, &cache_head) {
|
||||
zrtp_cache_elem_t* elem = mlist_get_struct(zrtp_cache_elem_t, _mlist, node);
|
||||
cache_make_cross(elem, &tmp_elem, 0);
|
||||
if (fwrite(&tmp_elem, ZRTP_CACHE_ELEM_LENGTH, 1, cache_file) != 1) {
|
||||
ZRTP_DOWN_CACHE_RETURN(zrtp_status_write_fail, cache_file);
|
||||
|
||||
/* Store dirty values only. */
|
||||
if (elem->_is_dirty) {
|
||||
printf("zrtp_cache_user_down: Store RS elem index=%u, not modified.\n", elem->_index);
|
||||
if (zrtp_status_ok != flush_elem_(elem, cache_file, 0)) {
|
||||
ZRTP_DOWN_CACHE_RETURN(zrtp_status_write_fail, cache_file);
|
||||
}
|
||||
} else {
|
||||
printf("zrtp_cache_user_down: Skip RS elem index=%u, not modified.\n", elem->_index);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
fseek(cache_file, pos, SEEK_SET);
|
||||
count = zrtp_hton32(count);
|
||||
|
||||
count = zrtp_hton32(g_cache_elems_counter);
|
||||
if (fwrite(&count, sizeof(count), 1, cache_file) != 1) {
|
||||
ZRTP_DOWN_CACHE_RETURN(zrtp_status_write_fail, cache_file);
|
||||
}
|
||||
ZRTP_LOG(3,(_ZTU_,"\t%u regular cache entries have been stored sucessfully.\n", zrtp_ntoh32(count)));
|
||||
ZRTP_LOG(3,(_ZTU_,"\t%u regular cache entries have been stored successfully.\n", zrtp_ntoh32(count)));
|
||||
|
||||
ZRTP_DOWN_CACHE_RETURN(zrtp_status_ok, cache_file);
|
||||
}
|
||||
|
@ -633,6 +753,8 @@ static zrtp_status_t put_name( const zrtp_stringn_t* one_ZID,
|
|||
new_elem->name_length = ZRTP_MIN(name->length, ZFONE_CACHE_NAME_LENGTH-1);
|
||||
zrtp_memset(new_elem->name, 0, sizeof(new_elem->name));
|
||||
zrtp_memcpy(new_elem->name, name->buffer, new_elem->name_length);
|
||||
|
||||
new_elem->_is_dirty = 1;
|
||||
} while (0);
|
||||
zrtp_mutex_unlock(def_cache_protector);
|
||||
|
||||
|
@ -720,6 +842,8 @@ zrtp_status_t zrtp_def_cache_reset_since( const zrtp_stringn_t* one_zid,
|
|||
new_elem = get_elem(id, 0);
|
||||
if (new_elem) {
|
||||
new_elem->secure_since = (uint32_t)(zrtp_time_now()/1000);
|
||||
|
||||
new_elem->_is_dirty = 1;
|
||||
}
|
||||
zrtp_mutex_unlock(def_cache_protector);
|
||||
|
||||
|
@ -743,6 +867,14 @@ void zrtp_def_cache_foreach( zrtp_global_t *global,
|
|||
result = callback(elem, is_mitm, data, &delete);
|
||||
if (delete) {
|
||||
mlist_del(&elem->_mlist);
|
||||
|
||||
if (is_mitm)
|
||||
g_mitmcache_elems_counter--;
|
||||
else
|
||||
g_cache_elems_counter--;
|
||||
|
||||
// TODO: rearrange INDEXES here!
|
||||
|
||||
}
|
||||
if (!result) {
|
||||
break;
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "zrtp.h"
|
||||
#include "cmockery/cmockery.h"
|
||||
|
||||
#define TEST_CACHE_PATH "./zrtp_cache_test.dat"
|
||||
|
||||
static zrtp_global_t g_zrtp_cfg;
|
||||
|
||||
void cache_setup() {
|
||||
remove(TEST_CACHE_PATH);
|
||||
|
||||
ZSTR_SET_EMPTY(g_zrtp_cfg.def_cache_path);
|
||||
/* Configure and Initialize ZRTP cache */
|
||||
zrtp_zstrcpyc(ZSTR_GV(g_zrtp_cfg.def_cache_path), TEST_CACHE_PATH);
|
||||
}
|
||||
|
||||
void cache_teardown() {
|
||||
zrtp_def_cache_down();
|
||||
}
|
||||
|
||||
static void init_rs_secret_(zrtp_shared_secret_t *sec) {
|
||||
ZSTR_SET_EMPTY(sec->value);
|
||||
|
||||
sec->_cachedflag = 0;
|
||||
sec->ttl = 0;
|
||||
sec->lastused_at = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Simply init ZRTP cache with empty or non-existing filer and close it.
|
||||
* The app should not crash and trigger no errors.
|
||||
*/
|
||||
void cache_init_store_empty_test() {
|
||||
zrtp_status_t status;
|
||||
|
||||
/* It should NOT crash and return OK. */
|
||||
status = zrtp_def_cache_init(&g_zrtp_cfg);
|
||||
assert_int_equal(status, zrtp_status_ok);
|
||||
|
||||
zrtp_def_cache_down();
|
||||
}
|
||||
|
||||
/*
|
||||
* Add few entries to the empty cache, flush it and then load again. Check if
|
||||
* all the entries were restored successfully.
|
||||
*/
|
||||
void cache_add2empty_test() {
|
||||
zrtp_status_t status;
|
||||
|
||||
int intres;
|
||||
|
||||
zrtp_string16_t zid_my = ZSTR_INIT_WITH_CONST_CSTRING("000000000_01");
|
||||
zrtp_string16_t zid_a = ZSTR_INIT_WITH_CONST_CSTRING("000000000_02");
|
||||
zrtp_string16_t zid_b = ZSTR_INIT_WITH_CONST_CSTRING("000000000_03");
|
||||
zrtp_string16_t zid_c = ZSTR_INIT_WITH_CONST_CSTRING("000000000_04");
|
||||
zrtp_string16_t zid_mitm1 = ZSTR_INIT_WITH_CONST_CSTRING("000000000_04");
|
||||
|
||||
zrtp_shared_secret_t rs_my4a, rs_my4b, rs_my4c, rs_my4mitm1;
|
||||
zrtp_shared_secret_t rs_my4a_r, rs_my4b_r, rs_my4c_r, rs_my4mitm1_r;
|
||||
|
||||
init_rs_secret_(&rs_my4a); init_rs_secret_(&rs_my4b);
|
||||
init_rs_secret_(&rs_my4c); init_rs_secret_(&rs_my4mitm1);
|
||||
|
||||
init_rs_secret_(&rs_my4a_r); init_rs_secret_(&rs_my4b_r);
|
||||
init_rs_secret_(&rs_my4c_r); init_rs_secret_(&rs_my4mitm1_r);
|
||||
|
||||
printf("Open empty cache file for.\n");
|
||||
status = zrtp_def_cache_init(&g_zrtp_cfg);
|
||||
assert_int_equal(status, zrtp_status_ok);
|
||||
|
||||
/* Test if cache-init does bot corrupt config. */
|
||||
assert_false(strncmp(g_zrtp_cfg.def_cache_path.buffer, TEST_CACHE_PATH, strlen(TEST_CACHE_PATH)));
|
||||
|
||||
/* Add few values into it */
|
||||
printf("Add few test entries.\n");
|
||||
|
||||
status = zrtp_def_cache_put(ZSTR_GV(zid_my), ZSTR_GV(zid_a), &rs_my4a);
|
||||
assert_int_equal(status, zrtp_status_ok);
|
||||
|
||||
status = zrtp_def_cache_put(ZSTR_GV(zid_my), ZSTR_GV(zid_b), &rs_my4b);
|
||||
assert_int_equal(status, zrtp_status_ok);
|
||||
|
||||
status = zrtp_def_cache_put_mitm(ZSTR_GV(zid_my), ZSTR_GV(zid_mitm1), &rs_my4mitm1);
|
||||
assert_int_equal(status, zrtp_status_ok);
|
||||
|
||||
status = zrtp_def_cache_put(ZSTR_GV(zid_my), ZSTR_GV(zid_c), &rs_my4c);
|
||||
assert_int_equal(status, zrtp_status_ok);
|
||||
|
||||
/* Close the cache, it should be flushed to the file. */
|
||||
printf("Close the cache.\n");
|
||||
|
||||
zrtp_def_cache_down();
|
||||
|
||||
/* Test if cache-close does bot corrupt config. */
|
||||
assert_false(strncmp(g_zrtp_cfg.def_cache_path.buffer, TEST_CACHE_PATH, strlen(TEST_CACHE_PATH)));
|
||||
|
||||
/* Now, let's open the cache again and check if all the previously added values were restored successfully */
|
||||
printf("And open it again, it should contain all the stored values.\n");
|
||||
|
||||
status = zrtp_def_cache_init(&g_zrtp_cfg);
|
||||
assert_int_equal(status, zrtp_status_ok);
|
||||
|
||||
status = zrtp_def_cache_get(ZSTR_GV(zid_my), ZSTR_GV(zid_a), &rs_my4a_r, 0);
|
||||
assert_int_equal(status, zrtp_status_ok);
|
||||
|
||||
assert_false(zrtp_zstrcmp(ZSTR_GV(rs_my4a_r.value), ZSTR_GV(rs_my4a.value)));
|
||||
|
||||
/* Test if cache-close does bot corrupt config. */
|
||||
assert_false(strncmp(g_zrtp_cfg.def_cache_path.buffer, TEST_CACHE_PATH, strlen(TEST_CACHE_PATH)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(void) {
|
||||
const UnitTest tests[] = {
|
||||
//unit_test_setup_teardown(cache_init_store_empty_test, cache_setup, cache_teardown),
|
||||
unit_test_setup_teardown(cache_add2empty_test, cache_setup, cache_teardown),
|
||||
};
|
||||
|
||||
return run_tests(tests);
|
||||
}
|
Loading…
Reference in New Issue