lime.c: implement "preferred" mode

This commit is contained in:
Gautier Pelloux-Prayer 2016-05-31 16:08:35 +02:00
parent 7876118643
commit cb9816e9fb
4 changed files with 61 additions and 18 deletions

View file

@ -27,6 +27,7 @@
#include "lpconfig.h"
#include "belle-sip/belle-sip.h"
#include "ortp/b64.h"
#include "lime.h"
#include <libxml/parser.h>
#include <libxml/tree.h>
@ -264,8 +265,50 @@ LinphoneChatRoom *linphone_core_get_chat_room_from_uri(LinphoneCore *lc, const c
return _linphone_core_get_or_create_chat_room(lc, to);
}
bool_t linphone_chat_room_lime_enabled(LinphoneChatRoom *cr) {
return linphone_core_lime_enabled(cr->lc) != LinphoneLimeDisabled/*&& TODO: check that cr->peer_url has a verified token */;
bool_t linphone_chat_room_lime_available(LinphoneChatRoom *cr) {
if (cr) {
switch (linphone_core_lime_enabled(cr->lc)) {
case LinphoneLimeDisabled: return FALSE;
case LinphoneLimeMandatory: return TRUE;
case LinphoneLimePreferred: {
FILE *CACHEFD = NULL;
if (cr->lc->zrtp_secrets_cache != NULL) {
CACHEFD = fopen(cr->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 to decrypt message");
return FALSE;
}
cacheString[cacheSize] = '\0';
cacheSize += 1;
fclose(CACHEFD);
cacheXml = xmlParseDoc((xmlChar*)cacheString);
ms_free(cacheString);
if (cacheXml) {
limeURIKeys_t associatedKeys;
/* retrieve keys associated to the peer URI */
associatedKeys.peerURI = (uint8_t *)malloc(strlen(cr->peer)+1);
strcpy((char *)(associatedKeys.peerURI), cr->peer);
associatedKeys.associatedZIDNumber = 0;
associatedKeys.peerKeys = NULL;
if (lime_getCachedSndKeysByURI(cacheXml, &associatedKeys) != 0) {
lime_freeKeys(associatedKeys);
return FALSE;
}
xmlFreeDoc(cacheXml);
return TRUE;
}
}
}
}
}
}
return FALSE;
}
static void linphone_chat_room_delete_composing_idle_timer(LinphoneChatRoom *cr) {
@ -380,7 +423,7 @@ void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage
char *peer_uri = linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr));
const char *content_type;
if (linphone_chat_room_lime_enabled(cr)) {
if (linphone_chat_room_lime_available(cr)) {
/* ref the msg or it may be destroyed by callback if the encryption failed */
if (msg->content_type && strcmp(msg->content_type, "application/vnd.gsma.rcs-ft-http+xml") == 0) {
/* it's a file transfer, content type shall be set to
@ -877,7 +920,7 @@ void linphone_core_real_time_text_received(LinphoneCore *lc, LinphoneChatRoom *c
msg->state = LinphoneChatMessageStateDelivered;
msg->is_read = FALSE;
msg->dir = LinphoneChatMessageIncoming;
if (lp_config_get_int(lc->config, "misc", "store_rtt_messages", 1) == 1) {
msg->storage_id = linphone_chat_message_store(msg);
}
@ -924,7 +967,7 @@ int linphone_chat_message_put_char(LinphoneChatMessage *msg, uint32_t character)
if (!call || !call->textstream) {
return -1;
}
if (character == new_line || character == crlf || character == lf) {
if (lc && lp_config_get_int(lc->config, "misc", "store_rtt_messages", 1) == 1) {
ms_debug("New line sent, forge a message with content %s", msg->message);
@ -944,7 +987,7 @@ int linphone_chat_message_put_char(LinphoneChatMessage *msg, uint32_t character)
ms_debug("Sent RTT character: %s (%lu), pending text is %s", value, (unsigned long)character, msg->message);
ms_free(value);
}
text_stream_putchar32(call->textstream, character);
return 0;
}

View file

@ -155,7 +155,7 @@ static int linphone_chat_message_file_transfer_on_send_body(belle_sip_user_body_
static void linphone_chat_message_process_response_from_post_file(void *data,
const belle_http_response_event_t *event) {
LinphoneChatMessage *msg = (LinphoneChatMessage *)data;
if (msg->http_request && !file_transfer_in_progress_and_valid(msg)) {
ms_warning("Cancelled request for %s msg [%p], ignoring %s", msg->chat_room?"":"ORPHAN", msg, __FUNCTION__);
_release_http_request(msg);
@ -172,7 +172,7 @@ static void linphone_chat_message_process_response_from_post_file(void *data,
belle_sip_body_handler_t *first_part_bh;
/* shall we encrypt the file */
if (linphone_chat_room_lime_enabled(msg->chat_room) &&
if (linphone_chat_room_lime_available(msg->chat_room) &&
linphone_core_lime_for_file_sharing_enabled(msg->chat_room->lc)) {
char keyBuffer
[FILE_TRANSFER_KEY_SIZE]; /* temporary storage of generated key: 192 bits of key + 64 bits of
@ -317,22 +317,22 @@ static void on_recv_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t
const uint8_t *buffer, size_t size) {
LinphoneChatMessage *msg = (LinphoneChatMessage *)data;
LinphoneCore *lc;
if (!msg->chat_room) {
linphone_chat_message_cancel_file_transfer(msg);
return;
}
lc = msg->chat_room->lc;
if (lc == NULL){
return; /*might happen during linphone_core_destroy()*/
}
if (!msg->http_request || belle_http_request_is_cancelled(msg->http_request)) {
ms_warning("Cancelled request for msg [%p], ignoring %s", msg, __FUNCTION__);
return;
}
/* first call may be with a zero size, ignore it */
if (size == 0) {
return;

View file

@ -69,7 +69,7 @@ LINPHONE_PUBLIC int lime_getCachedRcvKeyByZid(xmlDocPtr cacheBuffer, limeKey_t *
*
* @param[out] cacheBuffer The xmlDoc containing current cache to be updated
* @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] role Can be LIME_SENDER or LIME_RECEIVER, specify which key we want to update
*
* @return 0 on success, error code otherwise
*/
@ -87,7 +87,7 @@ LINPHONE_PUBLIC void lime_freeKeys(limeURIKeys_t associatedKeys);
/**
* @brief encrypt a message with the given key
*
*
* @param[in] key Key to use: first 192 bits are used as key, last 64 bits as init vector
* @param[in] message The string to be encrypted
* @param[in] messageLength The length in bytes of the message to be encrypted
@ -96,7 +96,7 @@ LINPHONE_PUBLIC void lime_freeKeys(limeURIKeys_t associatedKeys);
* Authentication tag is set at the begining of the encrypted Message
*
* @return 0 on success, error code otherwise
*
*
*/
LINPHONE_PUBLIC int lime_encryptMessage(limeKey_t *key, uint8_t *plainMessage, uint32_t messageLength, uint8_t selfZID[12], uint8_t *encryptedMessage);
@ -130,7 +130,7 @@ LINPHONE_PUBLIC int lime_decryptFile(void **cryptoContext, unsigned char *key, s
/**
* @brief decrypt and authentify a message with the given key
*
*
* @param[in] key Key to use: first 192 bits are used as key, last 64 bits as init vector
* @param[in] message The string to be decrypted
* @param[in] messageLength The length in bytes of the message to be decrypted (this include the 16 bytes tag at the begining of the message)
@ -139,7 +139,7 @@ LINPHONE_PUBLIC int lime_decryptFile(void **cryptoContext, unsigned char *key, s
* Authentication tag is retrieved at the begining of the encrypted Message
*
* @return 0 on success, error code otherwise
*
*
*/
LINPHONE_PUBLIC int lime_decryptMessage(limeKey_t *key, uint8_t *encryptedMessage, uint32_t messageLength, uint8_t selfZID[12], uint8_t *plainMessage);

View file

@ -591,7 +591,7 @@ int linphone_chat_room_upload_file(LinphoneChatMessage *msg);
void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
LinphoneChatMessageCbs *linphone_chat_message_cbs_new(void);
LinphoneChatRoom *_linphone_core_create_chat_room_from_call(LinphoneCall *call);
bool_t linphone_chat_room_lime_enabled(LinphoneChatRoom *cr);
bool_t linphone_chat_room_lime_available(LinphoneChatRoom *cr);
/**/
struct _LinphoneProxyConfig