Commit 6f3270f4 authored by jehan's avatar jehan
Browse files

Merge remote-tracking branch 'origin/sqlzidcache'

parents bcc13058 10090bd6
......@@ -172,6 +172,11 @@ if(ENABLE_NLS)
find_package(Intl REQUIRED)
endif()
if(ENABLE_LIME)
if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)
include("${EP_bzrtp_CONFIG_DIR}/BZRTPConfig.cmake")
else()
find_package(BZRTP)
endif()
set(HAVE_LIME 1)
endif()
if(ENABLE_CXX_WRAPPER)
......@@ -199,6 +204,7 @@ include_directories(
set(LINPHONE_INCLUDE_DIRS
${BELLESIP_INCLUDE_DIRS}
${MEDIASTREAMER2_INCLUDE_DIRS}
${BZRTP_INCLUDE_DIRS}
${BCTOOLBOX_CORE_INCLUDE_DIRS}
)
if(ANDROID)
......
......@@ -161,6 +161,9 @@ set(LIBS
if(WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
list(APPEND LIBS "Ws2_32")
endif()
if(ENABLE_LIME)
list(APPEND LIBS ${BZRTP_LIBRARIES})
endif()
if(ZLIB_FOUND)
list(APPEND LIBS ${ZLIB_LIBRARIES})
endif()
......
This diff is collapsed.
......@@ -45,6 +45,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
/**
* @brief Structure holding all needed material to encrypt/decrypt Messages */
typedef struct limeKey_struct {
int zuid; /**< the internal cache id for this key, zuid is a binding on local uri and zid <-> peer uri and zid */
uint8_t key[32]; /**< a 256 bit key used to encrypt/decrypt message */
uint8_t sessionId[32]; /**< a session id used to derive key */
uint32_t sessionIndex; /**< an index to count number of derivation */
......@@ -56,7 +57,8 @@ typedef struct limeKey_struct {
typedef struct limeURIKeys_struct {
limeKey_t **peerKeys; /**< an array of all the key material associated to each ZID matching the specified URI */
uint16_t associatedZIDNumber; /**< previous array length */
uint8_t *peerURI; /**< the sip URI associated to all the keys, must be a null terminated string */
char *peerURI; /**< the peer sip URI associated to all the keys, must be a null terminated string */
char *selfURI; /**< the local sip URI used to send messages, must be a null terminated string */
} limeURIKeys_t;
/**
......@@ -64,35 +66,36 @@ typedef struct limeURIKeys_struct {
* peerKeys field from associatedKeys param must be NULL when calling this function.
* Structure content must then be freed using lime_freeKeys function
*
* @param[in] cacheBuffer The xmlDoc containing current cache
* @param[in,out] associatedKeys Structure containing the peerURI. After this call contains all key material associated to the given URI. Must be then freed through lime_freeKeys function
* @param[in] cachedb Pointer to the sqlite3 DB
* @param[in,out] associatedKeys Structure containing the self and peer URI. After this call contains all key material associated to the given URI. Must be then freed through lime_freeKeys function
*
* @return 0 on success(at least one valid key found), error code otherwise
*/
LINPHONE_PUBLIC int lime_getCachedSndKeysByURI(xmlDocPtr cacheBuffer, limeURIKeys_t *associatedKeys);
LINPHONE_PUBLIC int lime_getCachedSndKeysByURI(void *cachedb, limeURIKeys_t *associatedKeys);
/**
* @brief Get the receiver key associated to the ZID given in the associatedKey parameter
*
* @param[in] cacheBuffer The xmlDoc containing current cache
* @param[in,out] associatedKey Structure containing the peerZID and will store the retrieved key
* @param[in] cachedb Pointer to the sqlite3 DB
* @param[in,out] associatedKey Structure containing the peerZID and will store the retrieved key
* @param[in] selfURI The source URI
* @param[in] peerURI The destination URI
*
* @return 0 on success, error code otherwise
*/
LINPHONE_PUBLIC int lime_getCachedRcvKeyByZid(xmlDocPtr cacheBuffer, limeKey_t *associatedKey);
LINPHONE_PUBLIC int lime_getCachedRcvKeyByZid(void *cachedb, limeKey_t *associatedKey, const char *selfURI, const char *peerURI);
/**
* @brief Set in cache the given key material, association is made by ZID contained in the associatedKey parameter
*
* @param[out] cacheBuffer The xmlDoc containing current cache to be updated
* @param[in/out] cachedb Pointer to the sqlite3 DB
* @param[in,out] associatedKey Structure containing the key and ZID to identify the peer node to be updated
* @param[in] role Can be LIME_SENDER or LIME_RECEIVER, specify which key we want to update
* @param[in] validityTimeSpan If not 0, set the <valid> tag to now+validityTimeSpan (in seconds)
*
* @return 0 on success, error code otherwise
*/
LINPHONE_PUBLIC int lime_setCachedKey(xmlDocPtr cacheBuffer, limeKey_t *associatedKey, uint8_t role, uint64_t validityTimeSpan);
LINPHONE_PUBLIC int lime_setCachedKey(void *cachedb, limeKey_t *associatedKey, uint8_t role, uint64_t validityTimeSpan);
/**
* @brief Free all allocated data in the associated keys structure
......@@ -167,28 +170,31 @@ LINPHONE_PUBLIC int lime_decryptMessage(limeKey_t *key, uint8_t *encryptedMessag
* @brief create the encrypted multipart xml message from plain text and destination URI
* Retrieve in cache the needed keys which are then updated. Output buffer is allocated and must be freed by caller
*
* @param[in,out] cacheBuffer The xmlDoc containing current cache, get the keys and selfZID from it, updated by this function with derivated keys
* @param[in] content_type The content type of the message to encrypt
* @param[in,out] cachedb Pointer to the sqlite DB holding zrtp/lime cache, get the keys and selfZID from it, updated by this function with derivated keys
* @param[in] content_type The content type of the message to encrypt
* @param[in] message The message content to be encrypted
* @param[in] selfURI The source URI
* @param[in] peerURI The destination URI, associated keys will be found in cache
* @param[out] output The output buffer, allocated and set with the encrypted message xml body(null terminated string). Must be freed by caller
*
* @return 0 on success, error code otherwise
*/
LINPHONE_PUBLIC int lime_createMultipartMessage(xmlDocPtr cacheBuffer, const char *content_type, uint8_t *message, uint8_t *peerURI, uint8_t **output);
LINPHONE_PUBLIC int lime_createMultipartMessage(void *cachedb, const char *contentType, uint8_t *message, const char *selfURI, const char *peerURI, uint8_t **output);
/**
* @brief decrypt a multipart xml message
* Retrieve in cache the needed key which is then updated. Output buffer is allocated and must be freed by caller
*
* @param[in,out] cacheBuffer The xmlDoc containing current cache, get the key and selfZID from it, updated by this function with derivated keys
* @param[in,out] cachedb Pointer to the sqlite DB holding zrtp/lime cache, get the keys and selfZID from it, updated by this function with derivated keys
* @param[in] message The multipart message, contain one or several part identified by destination ZID, one shall match the self ZID retrieved from cache
* @param[in] selfURI The source URI
* @param[in] peerURI The destination URI, associated keys will be found in cache
* @param[out] output The output buffer, allocated and set with the decrypted message(null terminated string). Must be freed by caller
* @param[out] content_type The content type of the decrypted message
* @param[in] validityTimeSpan If not 0, update the <valid> tag associated to sender to now+validityTimeSpan (in seconds)
* @return 0 on success, error code otherwise
*/
LINPHONE_PUBLIC int lime_decryptMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_t **output, char **content_type, uint64_t validityTimeSpan);
LINPHONE_PUBLIC int lime_decryptMultipartMessage(void *cachedb, uint8_t *message, const char *selfURI, const char *peerURI, uint8_t **output, char **content_type, uint64_t validityTimeSpan);
/**
* @brief given a readable version of error code generated by Lime functions
......
......@@ -2608,16 +2608,19 @@ void linphone_call_init_audio_stream(LinphoneCall *call){
/* init zrtp even if we didn't explicitely set it, just in case peer offers it */
if (linphone_core_media_encryption_supported(lc, LinphoneMediaEncryptionZRTP)) {
char *uri = linphone_address_as_string_uri_only((call->dir==LinphoneCallIncoming) ? call->log->from : call->log->to);
char *peerUri = linphone_address_as_string_uri_only((call->dir==LinphoneCallIncoming) ? call->log->from : call->log->to);
char *selfUri = linphone_address_as_string_uri_only((call->dir==LinphoneCallIncoming) ? call->log->to : call->log->from);
MSZrtpParams params;
memset(&params,0,sizeof(MSZrtpParams));
/*call->current_params.media_encryption will be set later when zrtp is activated*/
params.zid_file=lc->zrtp_secrets_cache;
params.uri=uri;
params.zidCacheDB = linphone_core_get_zrtp_cache_db(lc);
params.peerUri=peerUri;
params.selfUri=selfUri;
params.limeKeyTimeSpan = bctbx_time_string_to_sec(lp_config_get_string(lc->config, "sip", "lime_key_validity", "0")); /* get key lifespan from config file, default is 0:forever valid */
setZrtpCryptoTypesParameters(&params,call->core);
audio_stream_enable_zrtp(call->audiostream,&params);
if (uri != NULL) ms_free(uri);
if (peerUri != NULL) ms_free(peerUri);
if (selfUri != NULL) ms_free(selfUri);
}
media_stream_reclaim_sessions(&audiostream->ms, &call->sessions[call->main_audio_stream_index]);
......
......@@ -28,6 +28,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifdef SQLITE_STORAGE_ENABLED
#include "sqlite3_bctbx_vfs.h"
/* we need bzrtp.h to setup the zrtp cache only when SQLITE is enabled */
#include "bzrtp/bzrtp.h"
#endif
#include <math.h>
......@@ -104,6 +106,7 @@ static void set_sip_network_reachable(LinphoneCore* lc,bool_t isReachable, time_
static void set_media_network_reachable(LinphoneCore* lc,bool_t isReachable);
static void linphone_core_run_hooks(LinphoneCore *lc);
static void linphone_core_uninit(LinphoneCore *lc);
static void linphone_core_zrtp_cache_close(LinphoneCore *lc);
#include "enum.h"
#include "contact_providers_priv.h"
......@@ -5786,6 +5789,11 @@ static void linphone_core_uninit(LinphoneCore *lc)
if(lc->zrtp_secrets_cache != NULL) {
ms_free(lc->zrtp_secrets_cache);
}
if(lc->zrtp_cache_db_file != NULL) {
ms_free(lc->zrtp_cache_db_file);
}
if(lc->user_certificates_path != NULL) {
ms_free(lc->user_certificates_path);
}
......@@ -5819,6 +5827,7 @@ static void linphone_core_uninit(LinphoneCore *lc)
linphone_core_message_storage_close(lc);
linphone_core_call_log_storage_close(lc);
linphone_core_friends_storage_close(lc);
linphone_core_zrtp_cache_close(lc);
linphone_core_set_state(lc,LinphoneGlobalOff,"Off");
linphone_core_deactivate_log_serialization_if_needed();
......@@ -6215,6 +6224,268 @@ const char *linphone_core_get_zrtp_secrets_file(LinphoneCore *lc){
return lc->zrtp_secrets_cache;
}
void *linphone_core_get_zrtp_cache_db(LinphoneCore *lc){
#ifdef SQLITE_STORAGE_ENABLED
return (void *)lc->zrtp_cache_db;
#else /* SQLITE_STORAGE_ENABLED */
return NULL;
#endif /* SQLITE_STORAGE_ENABLED */
}
static void linphone_core_zrtp_cache_close(LinphoneCore *lc) {
#ifdef SQLITE_STORAGE_ENABLED
if (lc->zrtp_cache_db) {
sqlite3_close(lc->zrtp_cache_db);
lc->zrtp_cache_db = NULL;
}
#endif /* SQLITE_STORAGE_ENABLED */
}
#ifdef SQLITE_STORAGE_ENABLED
/* this function is called only when the sqlite cache is newly created but still empty(contains tables structures but no data)
* and we have an xml cache
* SQL zid cache associate each local sip:uri its own ZID while XML version used one ZID for the whole device-> use the XML provided ZID
* for the default local sipUri retrieved using linphone_core_get_identity
*/
static void linphone_core_zrtp_cache_migration(LinphoneCore *lc) {
FILE *CACHEFD = NULL;
/* load the xml cache */
if (lc->zrtp_secrets_cache != NULL) {
CACHEFD = fopen(lc->zrtp_secrets_cache, "rb+");
if (CACHEFD) {
size_t cacheSize;
xmlDocPtr cacheXml;
char *cacheString = ms_load_file_content(CACHEFD, &cacheSize);
if (!cacheString) {
ms_warning("Unable to load content of ZRTP ZID cache");
return;
}
cacheString[cacheSize] = '\0';
cacheSize += 1;
fclose(CACHEFD);
cacheXml = xmlParseDoc((xmlChar*)cacheString);
ms_free(cacheString);
if (cacheXml) {
xmlNodePtr cur;
xmlChar *selfZidHex=NULL;
uint8_t selfZID[12];
sqlite3 *db = (sqlite3 *)linphone_core_get_zrtp_cache_db(lc);
sqlite3_stmt *sqlStmt = NULL;
const char *selfURI = linphone_core_get_identity(lc);
int ret;
/* parse the cache to get the selfZID and insert it in sqlcache */
cur = xmlDocGetRootElement(cacheXml);
/* if we found a root element, parse its children node */
if (cur!=NULL)
{
cur = cur->xmlChildrenNode;
}
selfZidHex = NULL;
while (cur!=NULL) {
if ((!xmlStrcmp(cur->name, (const xmlChar *)"selfZID"))){ /* self ZID found, extract it */
selfZidHex = xmlNodeListGetString(cacheXml, cur->xmlChildrenNode, 1);
bctbx_strToUint8(selfZID, selfZidHex, 24);
break;
}
cur = cur->next;
}
/* did we found a self ZID? */
if (selfZidHex == NULL) {
ms_warning("ZRTP/LIME cache migration: Failed to parse selfZID");
return;
}
/* insert the selfZID in cache, associate it to default local sip:uri in case we have more than one */
ms_message("ZRTP/LIME cache migration: found selfZID %.24s link it to default URI %s in SQL cache", selfZidHex, selfURI);
xmlFree(selfZidHex);
ret = sqlite3_prepare_v2(db, "INSERT INTO ziduri (zid,selfuri,peeruri) VALUES(?,?,?);", -1, &sqlStmt, NULL);
if (ret != SQLITE_OK) {
ms_warning("ZRTP/LIME cache migration: Failed to insert selfZID");
return;
}
sqlite3_bind_blob(sqlStmt, 1, selfZID, 12, SQLITE_TRANSIENT);
sqlite3_bind_text(sqlStmt, 2, selfURI,-1,SQLITE_TRANSIENT);
sqlite3_bind_text(sqlStmt, 3, "self",-1,SQLITE_TRANSIENT);
ret = sqlite3_step(sqlStmt);
if (ret!=SQLITE_DONE) {
ms_warning("ZRTP/LIME cache migration: Failed to insert selfZID");
return;
}
sqlite3_finalize(sqlStmt);
/* loop over all the peer node in the xml cache and get from them : uri(can be more than one), ZID, rs1, rs2, pvs, sndKey, rcvKey, sndSId, rcvSId, sndIndex, rcvIndex, valid */
/* some of these may be missing(pvs, valid, rs2) but we'll consider them NULL */
/* aux and pbx secrets were not used, so don't even bother looking for them */
cur = xmlDocGetRootElement(cacheXml)->xmlChildrenNode;
while (cur!=NULL) { /* loop on all peer nodes */
if ((!xmlStrcmp(cur->name, (const xmlChar *)"peer"))) { /* found a peer node, check if there is a sipURI node in it (other nodes are just ignored) */
int i;
xmlNodePtr peerNodeChildren = cur->xmlChildrenNode;
xmlChar *nodeContent = NULL;
xmlChar *peerZIDString = NULL;
uint8_t peerZID[12];
uint8_t peerZIDFound=0;
xmlChar *peerUri[128]; /* array to contain all the peer uris found in one node */
/* hopefully they won't be more than 128(it would mean some peer has more than 128 accounts and we called all of them...) */
int peerUriIndex=0; /* index of previous array */
char *zrtpColNames[] = {"rs1", "rs2", "pvs"};
uint8_t *zrtpColValues[] = {NULL, NULL, NULL};
size_t zrtpColExpectedLengths[] = {32,32,1};
size_t zrtpColLengths[] = {0,0,0};
char *limeColNames[] = {"sndKey", "rcvKey", "sndSId", "rcvSId", "sndIndex", "rcvIndex", "valid"};
uint8_t *limeColValues[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
size_t limeColExpectedLengths[] = {32,32,32,32,4,4,8};
size_t limeColLengths[] = {0,0,0,0,0,0,0};
/* check all the children nodes to retrieve all information we may get */
while (peerNodeChildren!=NULL && peerUriIndex<128) {
if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"uri")) { /* found a peer an URI node, get the content */
peerUri[peerUriIndex] = xmlNodeListGetString(cacheXml, peerNodeChildren->xmlChildrenNode, 1);
peerUriIndex++;
}
if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"ZID")) {
peerZIDString = xmlNodeListGetString(cacheXml, peerNodeChildren->xmlChildrenNode, 1);
bctbx_strToUint8(peerZID, peerZIDString, 24);
peerZIDFound=1;
}
for (i=0; i<3; i++) {
if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)zrtpColNames[i])) {
nodeContent = xmlNodeListGetString(cacheXml, peerNodeChildren->xmlChildrenNode, 1);
zrtpColValues[i] = (uint8_t *)bctbx_malloc(zrtpColExpectedLengths[i]);
bctbx_strToUint8(zrtpColValues[i], nodeContent, 2*zrtpColExpectedLengths[i]);
zrtpColLengths[i]=zrtpColExpectedLengths[i];
}
}
for (i=0; i<7; i++) {
if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)limeColNames[i])) {
nodeContent = xmlNodeListGetString(cacheXml, peerNodeChildren->xmlChildrenNode, 1);
limeColValues[i] = (uint8_t *)bctbx_malloc(limeColExpectedLengths[i]);
bctbx_strToUint8(limeColValues[i], nodeContent, 2*limeColExpectedLengths[i]);
limeColLengths[i]=limeColExpectedLengths[i];
}
}
peerNodeChildren = peerNodeChildren->next;
xmlFree(nodeContent);
nodeContent=NULL;
}
if (peerUriIndex>0 && peerZIDFound==1) { /* we found at least an uri in this peer node, extract the keys all other informations */
/* retrieve all the informations */
/* loop over all the uri founds */
for (i=0; i<peerUriIndex; i++) {
char *stmt = NULL;
int zuid;
/* create the entry in the ziduri table (it will give us the zuid to be used to insert infos in lime and zrtp tables) */
/* we could use directly the bzrtp_cache_getZuid function, but avoid useless query by directly inserting the data */
stmt = sqlite3_mprintf("INSERT INTO ziduri (zid,selfuri,peeruri) VALUES(?,?,?);");
ret = sqlite3_prepare_v2(db, stmt, -1, &sqlStmt, NULL);
if (ret != SQLITE_OK) {
ms_warning("ZRTP/LIME cache migration: Failed to insert peer ZID %s", peerUri[i]);
return;
}
sqlite3_free(stmt);
sqlite3_bind_blob(sqlStmt, 1, peerZID, 12, SQLITE_TRANSIENT);
sqlite3_bind_text(sqlStmt, 2, selfURI, -1, SQLITE_TRANSIENT);
sqlite3_bind_text(sqlStmt, 3, (const char *)(peerUri[i]), -1, SQLITE_TRANSIENT);
ret = sqlite3_step(sqlStmt);
if (ret!=SQLITE_DONE) {
ms_warning("ZRTP/LIME cache migration: Failed to insert peer ZID %s", peerUri[i]);
return;
}
sqlite3_finalize(sqlStmt);
/* get the zuid created */
zuid = (int)sqlite3_last_insert_rowid(db);
ms_message("ZRTP/LIME cache migration: Inserted self %s peer %s ZID %s sucessfully with zuid %d\n", selfURI, peerUri[i], peerZIDString, zuid);
xmlFree(peerUri[i]);
peerUri[i]=NULL;
/* now insert data in the zrtp and lime table, keep going even if it fails */
if ((ret=bzrtp_cache_write(db, zuid, "zrtp", zrtpColNames, zrtpColValues, zrtpColLengths, 3)) != 0) {
ms_error("ZRTP/LIME cache migration: could not insert data in zrtp table, return value %x", ret);
}
if ((ret=bzrtp_cache_write(db, zuid, "lime", limeColNames, limeColValues, limeColLengths, 7)) != 0) {
ms_error("ZRTP/LIME cache migration: could not insert data in lime table, return value %x", ret);
}
}
}
bctbx_free(zrtpColValues[0]);
bctbx_free(zrtpColValues[1]);
bctbx_free(zrtpColValues[2]);
for (i=0; i<7; i++) {
bctbx_free(limeColValues[i]);
}
xmlFree(peerZIDString);
}
cur = cur->next;
}
}
}
}
}
static void linphone_core_zrtp_cache_db_init(LinphoneCore *lc) {
int ret;
const char *errmsg;
sqlite3 *db;
linphone_core_zrtp_cache_close(lc);
ret = _linphone_sqlite3_open(lc->zrtp_cache_db_file, &db);
if (ret != SQLITE_OK) {
errmsg = sqlite3_errmsg(db);
ms_error("Error in the opening zrtp_cache_db_file(%s): %s.\n", lc->zrtp_cache_db_file, errmsg);
sqlite3_close(db);
lc->zrtp_cache_db=NULL;
return;
}
ret = bzrtp_initCache((void *)db); /* this may perform an update, check return value */
if (ret == BZRTP_CACHE_SETUP || ret == BZRTP_CACHE_UPDATE) {
/* After updating schema, database need to be closed/reopenned */
sqlite3_close(db);
_linphone_sqlite3_open(lc->zrtp_cache_db_file, &db);
}
lc->zrtp_cache_db = db;
if (ret == BZRTP_CACHE_SETUP && lc->zrtp_secrets_cache != NULL) {
/* we just created the db and we have an old XML version of the cache : migrate */
linphone_core_zrtp_cache_migration(lc);
}
}
#else /* SQLITE_STORAGE_ENABLED */
static void linphone_core_zrtp_cache_db_init(LinphoneCore *lc) {
ms_warning("Tried to open %s as zrtp_cache_db_file, but SQLITE_STORAGE is not enabled", lc->zrtp_cache_db_file);
}
#endif /* SQLITE_STORAGE_ENABLED */
void linphone_core_set_zrtp_cache_database_path(LinphoneCore *lc, const char *path) {
if (lc->zrtp_cache_db_file){
ms_free(lc->zrtp_cache_db_file);
lc->zrtp_cache_db_file = NULL;
}
if (path) {
lc->zrtp_cache_db_file = ms_strdup(path);
linphone_core_zrtp_cache_db_init(lc);
}
}
void linphone_core_set_user_certificates_path(LinphoneCore *lc, const char* path){
char* new_value;
new_value = path?ms_strdup(path):NULL;
......
......@@ -1054,7 +1054,7 @@ struct _LinphoneCore
struct _EchoTester *ect;
LinphoneTaskList hooks; /*tasks periodically executed in linphone_core_iterate()*/
LinphoneConference *conf_ctx;
char* zrtp_secrets_cache;
char* zrtp_secrets_cache; /**< zrtp xml filename cache : obsolete, use zrtp_cache_db now, kept to allow cache migration */
char* user_certificates_path;
LinphoneVideoPolicy video_policy;
time_t network_last_check;
......@@ -1089,7 +1089,9 @@ struct _LinphoneCore
char *chat_db_file;
char *logs_db_file;
char *friends_db_file;
char *zrtp_cache_db_file;
#ifdef SQLITE_STORAGE_ENABLED
sqlite3 *zrtp_cache_db; /**< zrtp sqlite cache, used by both zrtp and lime */
sqlite3 *db;
sqlite3 *logs_db;
sqlite3 *friends_db;
......
......@@ -253,7 +253,8 @@ gboolean linphone_gtk_get_audio_assistant_option(void){
static void linphone_gtk_init_liblinphone(const char *config_file,
const char *factory_config_file, const char *chat_messages_db_file,
const char *call_logs_db_file, const char *friends_db_file) {
const char *call_logs_db_file, const char *friends_db_file,
const char *zrtp_cache_db_file) {
LinphoneCoreVTable vtable={0};
gchar *secrets_file=linphone_gtk_get_config_file(SECRETS_FILE);
gchar *user_certificates_dir=linphone_gtk_get_config_file(CERTIFICATES_PATH);
......@@ -289,7 +290,8 @@ static void linphone_gtk_init_liblinphone(const char *config_file,
linphone_core_set_user_agent(the_core,"Linphone", LINPHONE_VERSION);
linphone_core_set_waiting_callback(the_core,linphone_gtk_wait,NULL);
linphone_core_set_zrtp_secrets_file(the_core,secrets_file);
linphone_core_set_zrtp_secrets_file(the_core,secrets_file); /* XML cache is superseeded by the sqlite one, keep it for migration purpose but it shall be removed in future version */
if (zrtp_cache_db_file) linphone_core_set_zrtp_cache_database_path(the_core, zrtp_cache_db_file);
g_free(secrets_file);
linphone_core_set_user_certificates_path(the_core,user_certificates_dir);
g_free(user_certificates_dir);
......@@ -2153,6 +2155,33 @@ static void populate_xdg_data_dirs_envvar(void) {
g_strfreev(paths);
#endif
}
#define ZRTP_CACHE_CONFIG_FILE ".linphone-zidcache.db"
static char *linphone_gtk_zrtp_cache_get_db_file(const char *filename){
const int path_max=1024;
char *db_file=NULL;
db_file=(char *)g_malloc(path_max*sizeof(char));
if (filename==NULL) filename=ZRTP_CACHE_CONFIG_FILE;
/*try accessing a local file first if exists*/
if (bctbx_file_exist(ZRTP_CACHE_CONFIG_FILE)==0){
snprintf(db_file,path_max,"%s",filename);
}else{
#ifdef _WIN32
const char *appdata=getenv("APPDATA");
if (appdata){
snprintf(db_file,path_max,"%s\\%s",appdata,LINPHONE_CONFIG_DIR);
CreateDirectory(db_file,NULL);
snprintf(db_file,path_max,"%s\\%s\\%s",appdata,LINPHONE_CONFIG_DIR,filename);
}
#else
const char *home=getenv("HOME");
if (home==NULL) home=".";
snprintf(db_file,path_max,"%s/%s",home,filename);
#endif
}
return db_file;
}
int main(int argc, char *argv[]){
char *config_file;
......@@ -2162,7 +2191,7 @@ int main(int argc, char *argv[]){
const char *icon_name=LINPHONE_ICON_NAME;
const char *app_name="Linphone";
LpConfig *factory_config;
char *chat_messages_db_file, *call_logs_db_file, *friends_db_file;
char *chat_messages_db_file, *call_logs_db_file, *friends_db_file, *zrtp_cache_db_file;
GError *error=NULL;
const char *tmp;
const char *resources_dir;
......@@ -2310,7 +2339,8 @@ core_start:
chat_messages_db_file=linphone_gtk_message_storage_get_db_file(NULL);
call_logs_db_file = linphone_gtk_call_logs_storage_get_db_file(NULL);
friends_db_file = linphone_gtk_friends_storage_get_db_file(NULL);
linphone_gtk_init_liblinphone(config_file, factory_config_file, chat_messages_db_file, call_logs_db_file, friends_db_file);
zrtp_cache_db_file = linphone_gtk_zrtp_cache_get_db_file(NULL);
linphone_gtk_init_liblinphone(config_file, factory_config_file, chat_messages_db_file, call_logs_db_file, friends_db_file, zrtp_cache_db_file);
g_free(chat_messages_db_file);
g_free(call_logs_db_file);
g_free(friends_db_file);
......
......@@ -3654,16 +3654,35 @@ LINPHONE_PUBLIC void linphone_core_refresh_registers(LinphoneCore* lc);
* @param[in] lc #LinphoneCore object
* @param[in] file The path to the file to use to store the zrtp secrets cache.
* @ingroup initializing
* @deprecated cache is now hold as sqlite db, use linphone_core_set_zrtp_cache_database_path to set path to the db and open it
*/
LINPHONE_PUBLIC void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file);
LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file);
/**
* Get the path to the file storing the zrtp secrets cache.
* @param[in] lc #LinphoneCore object.
* @return The path to the file storing the zrtp secrets cache.
* @ingroup initializing
* @deprecated cache is now hold as sqlite db, use linphone_core_get_zrtp_cache_db to get a pointer to it
*/
LINPHONE_PUBLIC const char *linphone_core_get_zrtp_secrets_file(LinphoneCore *lc);
LINPHONE_PUBLIC LINPHONE_DEPRECATED const char *linphone_core_get_zrtp_secrets_file(LinphoneCore *lc);
/**
* Get a pointer to the sqlite db holding zrtp/lime cache
* @param[in] lc #LinphoneCore object.
* @return An sqlite3 pointer cast to a void one or NULL if cache is not available(not enabled at compile or access failed)
* @ingroup initializing
*/
LINPHONE_PUBLIC void *linphone_core_get_zrtp_cache_db(LinphoneCore *lc);
/**
* Sets the database filename where zrtp cache will be stored.
* If the file does not exist, it will be created.
* @ingroup initializing
* @param lc the linphone core
* @param path filesystem path
**/
LINPHONE_PUBLIC void linphone_core_set_zrtp_cache_database_path(LinphoneCore *lc, const char *path);
/**
* Set the path to the directory storing the user's x509 certificates (used by dtls)
......
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment