From cb9816e9fb0cdb8f91ac64f1e65b7fce7b05db20 Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Tue, 31 May 2016 16:08:35 +0200 Subject: [PATCH] lime.c: implement "preferred" mode --- coreapi/chat.c | 55 ++++++++++++++++++++++++++++++++---- coreapi/chat_file_transfer.c | 12 ++++---- coreapi/lime.h | 10 +++---- coreapi/private.h | 2 +- 4 files changed, 61 insertions(+), 18 deletions(-) diff --git a/coreapi/chat.c b/coreapi/chat.c index 061e14fc6..3e6d374e2 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -27,6 +27,7 @@ #include "lpconfig.h" #include "belle-sip/belle-sip.h" #include "ortp/b64.h" +#include "lime.h" #include #include @@ -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; } diff --git a/coreapi/chat_file_transfer.c b/coreapi/chat_file_transfer.c index e64839e35..21d003450 100644 --- a/coreapi/chat_file_transfer.c +++ b/coreapi/chat_file_transfer.c @@ -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; diff --git a/coreapi/lime.h b/coreapi/lime.h index a5da93e34..1b5101018 100644 --- a/coreapi/lime.h +++ b/coreapi/lime.h @@ -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); diff --git a/coreapi/private.h b/coreapi/private.h index 4cf2ef61d..20a4c5b73 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -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