mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-22 13:48:09 +00:00
Fix merge
and make code C90 compliant
This commit is contained in:
parent
5ac8a8595d
commit
f942fdeb3b
5 changed files with 242 additions and 162 deletions
|
|
@ -105,11 +105,11 @@ void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *eve
|
|||
bool_t external_body=FALSE;
|
||||
bool_t cipher_xml=FALSE;
|
||||
bool_t rcs_filetransfer=FALSE;
|
||||
uint8_t *decryptedMessage = NULL;
|
||||
|
||||
from_header=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_from_t);
|
||||
content_type=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_content_type_t);
|
||||
/* check if we have a xml/cipher message to be decrypted */
|
||||
uint8_t *decryptedMessage = NULL;
|
||||
if (content_type && (cipher_xml=is_cipher_xml(content_type))) {
|
||||
/* access the zrtp cache to get keys needed to decipher the message */
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
|
|
@ -117,17 +117,22 @@ void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *eve
|
|||
if (CACHEFD == NULL) {
|
||||
ms_warning("Unable to access ZRTP ZID cache to decrypt message");
|
||||
} else {
|
||||
int cacheSize;
|
||||
uint8_t *cacheString;
|
||||
int retval;
|
||||
xmlDocPtr cacheXml;
|
||||
|
||||
fseek(CACHEFD, 0L, SEEK_END); /* Position to end of file */
|
||||
int cacheSize = ftell(CACHEFD); /* Get file length */
|
||||
cacheSize = ftell(CACHEFD); /* Get file length */
|
||||
rewind(CACHEFD); /* Back to start of file */
|
||||
uint8_t *cacheString = (uint8_t *)malloc(cacheSize*sizeof(uint8_t)+1); /* string must be null terminated */
|
||||
cacheString = (uint8_t *)malloc(cacheSize*sizeof(uint8_t)+1); /* string must be null terminated */
|
||||
fread(cacheString, 1, cacheSize, CACHEFD);
|
||||
cacheString[cacheSize] = '\0';
|
||||
cacheSize += 1;
|
||||
fclose(CACHEFD);
|
||||
xmlDocPtr cacheXml = xmlParseDoc(cacheString);
|
||||
cacheXml = xmlParseDoc(cacheString);
|
||||
free(cacheString);
|
||||
int retval = lime_decryptMultipartMessage(cacheXml, (uint8_t *)belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)), &decryptedMessage);
|
||||
retval = lime_decryptMultipartMessage(cacheXml, (uint8_t *)belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)), &decryptedMessage);
|
||||
if (retval != 0) {
|
||||
ms_warning("Unable to decrypt message, reason : %s - op [%p]", lime_error_code_to_string(retval), op);
|
||||
free(decryptedMessage);
|
||||
|
|
@ -254,17 +259,22 @@ int sal_message_send(SalOp *op, const char *from, const char *to, const char* co
|
|||
op->base.root->callbacks.text_delivery_update(op,SalTextDeliveryFailed);
|
||||
return 0;
|
||||
} else {
|
||||
int cacheSize;
|
||||
uint8_t *cacheString;
|
||||
xmlDocPtr cacheXml;
|
||||
int retval;
|
||||
|
||||
fseek(CACHEFD, 0L, SEEK_END); /* Position to end of file */
|
||||
int cacheSize = ftell(CACHEFD); /* Get file length */
|
||||
cacheSize = ftell(CACHEFD); /* Get file length */
|
||||
rewind(CACHEFD); /* Back to start of file */
|
||||
uint8_t *cacheString = (uint8_t *)malloc(cacheSize*sizeof(uint8_t)+1); /* string must be null terminated */
|
||||
cacheString = (uint8_t *)malloc(cacheSize*sizeof(uint8_t)+1); /* string must be null terminated */
|
||||
fread(cacheString, 1, cacheSize, CACHEFD);
|
||||
cacheString[cacheSize] = '\0';
|
||||
cacheSize += 1;
|
||||
fclose(CACHEFD);
|
||||
xmlDocPtr cacheXml = xmlParseDoc(cacheString);
|
||||
cacheXml = xmlParseDoc(cacheString);
|
||||
free(cacheString);
|
||||
int retval = lime_createMultipartMessage(cacheXml, (uint8_t *)msg, (uint8_t *)peer_uri, &multipartEncryptedMessage);
|
||||
retval = lime_createMultipartMessage(cacheXml, (uint8_t *)msg, (uint8_t *)peer_uri, &multipartEncryptedMessage);
|
||||
if (retval != 0) {
|
||||
ms_warning("Unable to encrypt message for %s : %s - op [%p]", peer_uri, lime_error_code_to_string(retval), op);
|
||||
xmlFreeDoc(cacheXml);
|
||||
|
|
|
|||
|
|
@ -99,35 +99,30 @@ static int linphone_chat_message_file_transfer_on_send_body(belle_sip_user_body_
|
|||
LinphoneChatMessage* chatMsg=(LinphoneChatMessage *)data;
|
||||
LinphoneCore *lc = chatMsg->chat_room->lc;
|
||||
char *buf = (char *)buffer;
|
||||
char *content_type=belle_sip_strdup_printf("%s/%s", chatMsg->file_transfer_information->type, chatMsg->file_transfer_information->subtype);
|
||||
size_t end_of_file=linphone_chat_message_compute_filepart_header_size(chatMsg->file_transfer_information->name, content_type)+chatMsg->file_transfer_information->size;
|
||||
|
||||
/* if we've not reach the end of file yet, ask for more data*/
|
||||
if (offset<chatMsg->file_transfer_information->size){
|
||||
|
||||
if (chatMsg->file_transfer_information->key != NULL) { /* if we have a key to cipher the message, use it! */
|
||||
char *plainBuffer;
|
||||
/* get data from callback to a plainBuffer */
|
||||
/* if this chunk is not the last one, the lenght must be a multiple of block cipher size(16 bytes)*/
|
||||
if (offset+*size<end_of_file) {
|
||||
if (offset+*size<chatMsg->file_transfer_information->size) {
|
||||
*size -=(*size%16);
|
||||
}
|
||||
char *plainBuffer = (char *)malloc(*size);
|
||||
linphone_core_notify_file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, buf, size);
|
||||
plainBuffer = (char *)malloc(*size);
|
||||
linphone_core_notify_file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, plainBuffer, size);
|
||||
lime_encryptFile(&(chatMsg->file_transfer_information->cryptoContext), chatMsg->file_transfer_information->key, *size, plainBuffer, (char*)buffer);
|
||||
free(plainBuffer);
|
||||
/* check if we reach the end of file */
|
||||
if (offset+*size>=chatMsg->file_transfer_information->size) {
|
||||
/* conclude file ciphering by calling it context with a zero size */
|
||||
lime_encryptFile(&(chatMsg->file_transfer_information->cryptoContext), NULL, 0, NULL, NULL);
|
||||
}
|
||||
} else {
|
||||
/* get data from call back directly to the output buffer */
|
||||
linphone_core_notify_file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, buf, size);
|
||||
}
|
||||
/* DEBUG DEBUG : THIS SHALL NEVER HAPPEND */
|
||||
if (*size == 0) {
|
||||
exit(1);
|
||||
}
|
||||
}else{
|
||||
/* conclude the file ciphering if needed */
|
||||
if (chatMsg->file_transfer_information->key != NULL) {
|
||||
lime_encryptFile(&(chatMsg->file_transfer_information->cryptoContext), NULL, 0, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return BELLE_SIP_CONTINUE;
|
||||
|
|
@ -148,12 +143,6 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co
|
|||
if (event->response){
|
||||
int code=belle_http_response_get_status_code(event->response);
|
||||
if (code == 204) { /* this is the reply to the first post to the server - an empty message */
|
||||
/* shall we encrypt the file */
|
||||
if (msg->chat_room->lc->lime == 1) {
|
||||
/* generate a random 192 bits key + 64 bits of initial vector and store it into the file_transfer_information->key field of the message */
|
||||
msg->file_transfer_information->key = (unsigned char *)malloc(FILE_TRANSFER_KEY_SIZE);
|
||||
sal_get_random_bytes(msg->file_transfer_information->key, FILE_TRANSFER_KEY_SIZE);
|
||||
}
|
||||
/* start uploading the file */
|
||||
belle_http_request_listener_callbacks_t cbs={0};
|
||||
belle_http_request_listener_t *l;
|
||||
|
|
@ -165,6 +154,13 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co
|
|||
char *first_part_header;
|
||||
belle_sip_user_body_handler_t *first_part_bh;
|
||||
|
||||
/* shall we encrypt the file */
|
||||
if (msg->chat_room->lc->lime == 1) {
|
||||
/* generate a random 192 bits key + 64 bits of initial vector and store it into the file_transfer_information->key field of the message */
|
||||
msg->file_transfer_information->key = (unsigned char *)malloc(FILE_TRANSFER_KEY_SIZE);
|
||||
sal_get_random_bytes(msg->file_transfer_information->key, FILE_TRANSFER_KEY_SIZE);
|
||||
}
|
||||
|
||||
/* temporary storage for the Content-disposition header value */
|
||||
first_part_header = belle_sip_strdup_printf("form-data; name=\"File\"; filename=\"%s\"", msg->file_transfer_information->name);
|
||||
|
||||
|
|
@ -220,6 +216,8 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co
|
|||
/* convert key to base64 */
|
||||
int b64Size = b64_encode(NULL, FILE_TRANSFER_KEY_SIZE, NULL, 0);
|
||||
char *keyb64 = (char *)malloc(b64Size+1);
|
||||
int xmlStringLength;
|
||||
|
||||
b64Size = b64_encode(msg->file_transfer_information->key, FILE_TRANSFER_KEY_SIZE, keyb64, b64Size);
|
||||
keyb64[b64Size] = '\0'; /* libxml need a null terminated string */
|
||||
|
||||
|
|
@ -228,7 +226,6 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co
|
|||
xmlFree(typeAttribute);
|
||||
|
||||
/* dump the xml into msg->message */
|
||||
int xmlStringLength;
|
||||
xmlDocDumpFormatMemoryEnc(xmlMessageBody, (xmlChar **)&msg->message, &xmlStringLength, "UTF-8", 0);
|
||||
|
||||
break;
|
||||
|
|
@ -1106,12 +1103,13 @@ const LinphoneContent *linphone_chat_message_get_file_transfer_information(const
|
|||
}
|
||||
|
||||
static void on_recv_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t *msg, void *data, size_t offset, const uint8_t *buffer, size_t size){
|
||||
LinphoneChatMessage* chatMsg=(LinphoneChatMessage *)data;
|
||||
LinphoneCore *lc = chatMsg->chat_room->lc;
|
||||
|
||||
/* first call may be with a zero size, ignore it */
|
||||
if (size == 0) {
|
||||
return;
|
||||
}
|
||||
LinphoneChatMessage* chatMsg=(LinphoneChatMessage *)data;
|
||||
LinphoneCore *lc = chatMsg->chat_room->lc;
|
||||
/* TODO: while belle sip doesn't implement the cancel http request method, test if a request is still linked to the message before forwarding the data to callback */
|
||||
if (chatMsg->http_request == NULL) {
|
||||
return;
|
||||
|
|
|
|||
124
coreapi/lime.c
124
coreapi/lime.c
|
|
@ -90,17 +90,20 @@ void lime_int8ToStr(uint8_t *outputString, uint8_t *inputBytes, uint16_t inputBy
|
|||
|
||||
|
||||
int lime_getSelfZid(xmlDocPtr cacheBuffer, uint8_t selfZid[25]) {
|
||||
xmlNodePtr cur;
|
||||
xmlChar *selfZidHex;
|
||||
|
||||
if (cacheBuffer == NULL ) {
|
||||
return LIME_INVALID_CACHE;
|
||||
}
|
||||
|
||||
xmlNodePtr cur = xmlDocGetRootElement(cacheBuffer);
|
||||
cur = xmlDocGetRootElement(cacheBuffer);
|
||||
/* if we found a root element, parse its children node */
|
||||
if (cur!=NULL)
|
||||
{
|
||||
cur = cur->xmlChildrenNode;
|
||||
}
|
||||
xmlChar *selfZidHex = NULL;
|
||||
selfZidHex = NULL;
|
||||
while (cur!=NULL) {
|
||||
if ((!xmlStrcmp(cur->name, (const xmlChar *)"selfZID"))){ /* self ZID found, extract it */
|
||||
selfZidHex = xmlNodeListGetString(cacheBuffer, cur->xmlChildrenNode, 1);
|
||||
|
|
@ -122,6 +125,7 @@ int lime_getSelfZid(xmlDocPtr cacheBuffer, uint8_t selfZid[25]) {
|
|||
}
|
||||
|
||||
int lime_getCachedSndKeysByURI(xmlDocPtr cacheBuffer, limeURIKeys_t *associatedKeys) {
|
||||
xmlNodePtr cur;
|
||||
|
||||
/* parse the file to get all peer matching the sipURI given in associatedKeys*/
|
||||
if (cacheBuffer == NULL ) { /* there is no cache return error */
|
||||
|
|
@ -132,7 +136,7 @@ int lime_getCachedSndKeysByURI(xmlDocPtr cacheBuffer, limeURIKeys_t *associatedK
|
|||
associatedKeys->associatedZIDNumber = 0;
|
||||
associatedKeys->peerKeys = NULL;
|
||||
|
||||
xmlNodePtr cur = xmlDocGetRootElement(cacheBuffer);
|
||||
cur = xmlDocGetRootElement(cacheBuffer);
|
||||
/* if we found a root element, parse its children node */
|
||||
if (cur!=NULL)
|
||||
{
|
||||
|
|
@ -141,8 +145,8 @@ int lime_getCachedSndKeysByURI(xmlDocPtr cacheBuffer, limeURIKeys_t *associatedK
|
|||
while (cur!=NULL) { /* loop on all peer nodes */
|
||||
uint8_t matchingURIFlag = 0; /* this flag is set to one if we found the requested sipURI in the current peer node */
|
||||
if ((!xmlStrcmp(cur->name, (const xmlChar *)"peer"))) { /* found a peer node, check if there is a matching sipURI node in it */
|
||||
matchingURIFlag = 0;
|
||||
xmlNodePtr peerNodeChildren = cur->xmlChildrenNode;
|
||||
matchingURIFlag = 0;
|
||||
|
||||
/* loop on children nodes until the end or we found the matching sipURI */
|
||||
while (peerNodeChildren!=NULL && matchingURIFlag==0) {
|
||||
|
|
@ -182,8 +186,8 @@ int lime_getCachedSndKeysByURI(xmlDocPtr cacheBuffer, limeURIKeys_t *associatedK
|
|||
itemFound++;
|
||||
}
|
||||
if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"sndIndex")) {
|
||||
nodeContent = xmlNodeListGetString(cacheBuffer, peerNodeChildren->xmlChildrenNode, 1);
|
||||
uint8_t sessionIndexBuffer[4]; /* session index is a uint32_t but we first retrieved it as an hexa string, convert it to a 4 uint8_t buffer */
|
||||
nodeContent = xmlNodeListGetString(cacheBuffer, peerNodeChildren->xmlChildrenNode, 1);
|
||||
lime_strToUint8(sessionIndexBuffer, nodeContent, 8);
|
||||
/* convert it back to a uint32_t (MSByte first)*/
|
||||
currentPeerKeys->sessionIndex = sessionIndexBuffer[3] + (sessionIndexBuffer[2]<<8) + (sessionIndexBuffer[1]<<16) + (sessionIndexBuffer[0]<<24);
|
||||
|
|
@ -219,16 +223,21 @@ int lime_getCachedSndKeysByURI(xmlDocPtr cacheBuffer, limeURIKeys_t *associatedK
|
|||
}
|
||||
|
||||
int lime_getCachedRcvKeyByZid(xmlDocPtr cacheBuffer, limeKey_t *associatedKey) {
|
||||
uint8_t peerZidHex[25];
|
||||
/* to check we collect all the information needed from the cache and that pvs(boolean for previously verified Sas) is set in cache */
|
||||
uint8_t itemFound = 0;
|
||||
uint8_t pvs = 0;
|
||||
xmlNodePtr cur;
|
||||
|
||||
if (cacheBuffer == NULL ) { /* there is no cache return error */
|
||||
return LIME_INVALID_CACHE;
|
||||
}
|
||||
|
||||
/* get the given ZID into hex format */
|
||||
uint8_t peerZidHex[25];
|
||||
lime_int8ToStr(peerZidHex, associatedKey->peerZID, 12);
|
||||
peerZidHex[24]='\0'; /* must be a null terminated string */
|
||||
|
||||
xmlNodePtr cur = xmlDocGetRootElement(cacheBuffer);
|
||||
cur = xmlDocGetRootElement(cacheBuffer);
|
||||
/* if we found a root element, parse its children node */
|
||||
if (cur!=NULL)
|
||||
{
|
||||
|
|
@ -236,10 +245,6 @@ int lime_getCachedRcvKeyByZid(xmlDocPtr cacheBuffer, limeKey_t *associatedKey) {
|
|||
|
||||
}
|
||||
|
||||
/* to check we collect all the information needed from the cache and that pvs(boolean for previously verified Sas) is set in cache */
|
||||
uint8_t itemFound = 0;
|
||||
uint8_t pvs = 0;
|
||||
|
||||
while (cur!=NULL) { /* loop on all peer nodes */
|
||||
if ((!xmlStrcmp(cur->name, (const xmlChar *)"peer"))){ /* found a peer, check his ZID element */
|
||||
xmlChar *currentZidHex = xmlNodeListGetString(cacheBuffer, cur->xmlChildrenNode->xmlChildrenNode, 1); /* ZID is the first element of peer */
|
||||
|
|
@ -258,8 +263,8 @@ int lime_getCachedRcvKeyByZid(xmlDocPtr cacheBuffer, limeKey_t *associatedKey) {
|
|||
itemFound++;
|
||||
}
|
||||
if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"rcvIndex")) {
|
||||
nodeContent = xmlNodeListGetString(cacheBuffer, peerNodeChildren->xmlChildrenNode, 1);
|
||||
uint8_t sessionIndexBuffer[4]; /* session index is a uint32_t but we first retrieved it as an hexa string, convert it to a 4 uint8_t buffer */
|
||||
nodeContent = xmlNodeListGetString(cacheBuffer, peerNodeChildren->xmlChildrenNode, 1);
|
||||
lime_strToUint8(sessionIndexBuffer, nodeContent, 8);
|
||||
/* convert it back to a uint32_t (MSByte first)*/
|
||||
associatedKey->sessionIndex = sessionIndexBuffer[3] + (sessionIndexBuffer[2]<<8) + (sessionIndexBuffer[1]<<16) + (sessionIndexBuffer[0]<<24);
|
||||
|
|
@ -291,16 +296,22 @@ int lime_getCachedRcvKeyByZid(xmlDocPtr cacheBuffer, limeKey_t *associatedKey) {
|
|||
}
|
||||
|
||||
int lime_setCachedKey(xmlDocPtr cacheBuffer, limeKey_t *associatedKey, uint8_t role) {
|
||||
xmlNodePtr cur;
|
||||
uint8_t peerZidHex[25];
|
||||
uint8_t keyHex[65]; /* key is 32 bytes long -> 64 bytes string + null termination */
|
||||
uint8_t sessionIdHex[65]; /* sessionId is 32 bytes long -> 64 bytes string + null termination */
|
||||
uint8_t sessionIndexHex[9]; /* sessionInedx is an uint32_t : 4 bytes long -> 8 bytes string + null termination */
|
||||
uint8_t itemFound = 0;
|
||||
|
||||
if (cacheBuffer == NULL ) { /* there is no cache return error */
|
||||
return LIME_INVALID_CACHE;
|
||||
}
|
||||
|
||||
/* get the given ZID into hex format */
|
||||
uint8_t peerZidHex[25];
|
||||
lime_int8ToStr(peerZidHex, associatedKey->peerZID, 12);
|
||||
peerZidHex[24]='\0'; /* must be a null terminated string */
|
||||
|
||||
xmlNodePtr cur = xmlDocGetRootElement(cacheBuffer);
|
||||
cur = xmlDocGetRootElement(cacheBuffer);
|
||||
/* if we found a root element, parse its children node */
|
||||
if (cur!=NULL)
|
||||
{
|
||||
|
|
@ -309,13 +320,10 @@ int lime_setCachedKey(xmlDocPtr cacheBuffer, limeKey_t *associatedKey, uint8_t r
|
|||
}
|
||||
|
||||
/* convert the given tag content to null terminated Hexadecimal strings */
|
||||
uint8_t keyHex[65]; /* key is 32 bytes long -> 64 bytes string + null termination */
|
||||
lime_int8ToStr(keyHex, associatedKey->key, 32);
|
||||
keyHex[64] = '\0';
|
||||
uint8_t sessionIdHex[65]; /* sessionId is 32 bytes long -> 64 bytes string + null termination */
|
||||
lime_int8ToStr(sessionIdHex, associatedKey->sessionId, 32);
|
||||
sessionIdHex[64] = '\0';
|
||||
uint8_t sessionIndexHex[9]; /* sessionInedx is an uint32_t : 4 bytes long -> 8 bytes string + null termination */
|
||||
sessionIndexHex[0] = lime_byteToChar((uint8_t)((associatedKey->sessionIndex>>28)&0x0F));
|
||||
sessionIndexHex[1] = lime_byteToChar((uint8_t)((associatedKey->sessionIndex>>24)&0x0F));
|
||||
sessionIndexHex[2] = lime_byteToChar((uint8_t)((associatedKey->sessionIndex>>20)&0x0F));
|
||||
|
|
@ -326,7 +334,6 @@ int lime_setCachedKey(xmlDocPtr cacheBuffer, limeKey_t *associatedKey, uint8_t r
|
|||
sessionIndexHex[7] = lime_byteToChar((uint8_t)((associatedKey->sessionIndex)&0x0F));
|
||||
sessionIndexHex[8] = '\0';
|
||||
|
||||
uint8_t itemFound = 0;
|
||||
while (cur!=NULL && itemFound<3) { /* loop on all peer nodes */
|
||||
if ((!xmlStrcmp(cur->name, (const xmlChar *)"peer"))){ /* found a peer, check his ZID element */
|
||||
xmlChar *currentZidHex = xmlNodeListGetString(cacheBuffer, cur->xmlChildrenNode->xmlChildrenNode, 1); /* ZID is the first element of peer */
|
||||
|
|
@ -373,6 +380,9 @@ int lime_setCachedKey(xmlDocPtr cacheBuffer, limeKey_t *associatedKey, uint8_t r
|
|||
}
|
||||
|
||||
int lime_deriveKey(limeKey_t *key) {
|
||||
uint8_t inputData[55];
|
||||
uint8_t derivedKey[32];
|
||||
|
||||
if (key == NULL) {
|
||||
return LIME_UNABLE_TO_DERIVE_KEY;
|
||||
}
|
||||
|
|
@ -383,7 +393,6 @@ int lime_deriveKey(limeKey_t *key) {
|
|||
|
||||
/* Derivation is made derived Key = HMAC_SHA256(Key, 0x0000001||"MessageKey"||0x00||SessionId||SessionIndex||0x00000100)*/
|
||||
/* total data to be hashed is 55 bytes : 4 + 10 + 1 + 32 + 4 + 4 */
|
||||
uint8_t inputData[55];
|
||||
inputData[0] = 0x00;
|
||||
inputData[1] = 0x00;
|
||||
inputData[2] = 0x00;
|
||||
|
|
@ -406,7 +415,6 @@ int lime_deriveKey(limeKey_t *key) {
|
|||
inputData[54] = 0x00;
|
||||
|
||||
/* derive the key in a temp buffer */
|
||||
uint8_t derivedKey[32];
|
||||
#if POLARSSL_VERSION_NUMBER >= 0x01030000 /* for Polarssl version 1.3 */
|
||||
sha256_hmac(key->key, 32, inputData, 55, derivedKey, 0); /* last param to zero to select SHA256 and not SHA224 */
|
||||
#else /* for Polarssl version 1.2 */
|
||||
|
|
@ -439,8 +447,9 @@ void lime_freeKeys(limeURIKeys_t associatedKeys) {
|
|||
}
|
||||
|
||||
int lime_encryptMessage(limeKey_t *key, uint8_t *plainMessage, uint32_t messageLength, uint8_t selfZID[12], uint8_t *encryptedMessage) {
|
||||
/* Authenticated data is senderZID(12 bytes)||receiverZID(12 bytes)||sessionIndex(4 bytes) */
|
||||
uint8_t authenticatedData[28];
|
||||
gcm_context gcmContext;
|
||||
/* Authenticated data is senderZID(12 bytes)||receiverZID(12 bytes)||sessionIndex(4 bytes) */
|
||||
memcpy(authenticatedData, selfZID, 12);
|
||||
memcpy(authenticatedData+12, key->peerZID, 12);
|
||||
authenticatedData[24] = (uint8_t)((key->sessionIndex>>24)&0x000000FF);
|
||||
|
|
@ -450,7 +459,6 @@ int lime_encryptMessage(limeKey_t *key, uint8_t *plainMessage, uint32_t messageL
|
|||
|
||||
/* AES-GCM : key is 192 bits long, Init Vector 64 bits. 256 bits key given is AES key||IV */
|
||||
/* tag is 16 bytes long and is set in the 16 first bytes of the encrypted message */
|
||||
gcm_context gcmContext;
|
||||
gcm_init(&gcmContext, POLARSSL_CIPHER_ID_AES, key->key, 192);
|
||||
gcm_crypt_and_tag(&gcmContext, GCM_ENCRYPT, messageLength, key->key+24, 8, authenticatedData, 28, plainMessage, encryptedMessage+16, 16, encryptedMessage);
|
||||
gcm_free(&gcmContext);
|
||||
|
|
@ -458,7 +466,6 @@ int lime_encryptMessage(limeKey_t *key, uint8_t *plainMessage, uint32_t messageL
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int lime_encryptFile(void **cryptoContext, unsigned char *key, size_t length, char *plain, char *cipher) {
|
||||
gcm_context *gcmContext;
|
||||
|
||||
|
|
@ -509,8 +516,11 @@ int lime_decryptFile(void **cryptoContext, unsigned char *key, size_t length, ch
|
|||
|
||||
|
||||
int lime_decryptMessage(limeKey_t *key, uint8_t *encryptedMessage, uint32_t messageLength, uint8_t selfZID[12], uint8_t *plainMessage) {
|
||||
/* Authenticated data is senderZID(12 bytes)||receiverZID(12 bytes)||sessionIndex(4 bytes) */
|
||||
uint8_t authenticatedData[28];
|
||||
gcm_context gcmContext;
|
||||
int retval;
|
||||
|
||||
/* Authenticated data is senderZID(12 bytes)||receiverZID(12 bytes)||sessionIndex(4 bytes) */
|
||||
memcpy(authenticatedData, key->peerZID, 12);
|
||||
memcpy(authenticatedData+12, selfZID, 12);
|
||||
authenticatedData[24] = (uint8_t)((key->sessionIndex>>24)&0x000000FF);
|
||||
|
|
@ -520,10 +530,9 @@ int lime_decryptMessage(limeKey_t *key, uint8_t *encryptedMessage, uint32_t mess
|
|||
|
||||
/* AES-GCM : key is 192 bits long, Init Vector 64 bits. 256 bits key given is AES key||IV */
|
||||
/* tag is 16 bytes long and is the 16 first bytes of the encrypted message */
|
||||
gcm_context gcmContext;
|
||||
gcm_init(&gcmContext, POLARSSL_CIPHER_ID_AES, key->key, 192);
|
||||
/* messageLength-16 is the length of encrypted data, messageLength include the 16 bytes tag included at the begining of encryptedMessage */
|
||||
int retval = gcm_auth_decrypt(&gcmContext, messageLength-16, key->key+24, 8, authenticatedData, 28, encryptedMessage, 16, encryptedMessage+16, plainMessage);
|
||||
retval = gcm_auth_decrypt(&gcmContext, messageLength-16, key->key+24, 8, authenticatedData, 28, encryptedMessage, 16, encryptedMessage+16, plainMessage);
|
||||
gcm_free(&gcmContext);
|
||||
/* add the null termination char */
|
||||
plainMessage[messageLength-16] = '\0';
|
||||
|
|
@ -532,20 +541,25 @@ int lime_decryptMessage(limeKey_t *key, uint8_t *encryptedMessage, uint32_t mess
|
|||
}
|
||||
|
||||
int lime_createMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_t *peerURI, uint8_t **output) {
|
||||
/* retrieve selfZIDHex from cache(return a 24 char hexa string + null termination) */
|
||||
uint8_t selfZidHex[25];
|
||||
uint8_t selfZid[12]; /* same data but in byte buffer */
|
||||
uint32_t encryptedMessageLength;
|
||||
limeURIKeys_t associatedKeys;
|
||||
xmlDocPtr xmlOutputMessage;
|
||||
xmlNodePtr rootNode;
|
||||
int i;
|
||||
int xmlStringLength;
|
||||
|
||||
/* retrieve selfZIDHex from cache(return a 24 char hexa string + null termination) */
|
||||
if (lime_getSelfZid(cacheBuffer, selfZidHex) != 0) {
|
||||
return LIME_UNABLE_TO_ENCRYPT_MESSAGE;
|
||||
}
|
||||
uint8_t selfZid[12]; /* same data but in byte buffer */
|
||||
lime_strToUint8(selfZid, selfZidHex, 24);
|
||||
|
||||
/* encrypted message length is plaintext + 16 for tag */
|
||||
uint32_t encryptedMessageLength = strlen((char *)message) + 16;
|
||||
|
||||
encryptedMessageLength = strlen((char *)message) + 16;
|
||||
|
||||
/* retrieve keys associated to the peer URI */
|
||||
limeURIKeys_t associatedKeys;
|
||||
associatedKeys.peerURI = (uint8_t *)malloc(strlen((char *)peerURI)+1);
|
||||
strcpy((char *)(associatedKeys.peerURI), (char *)peerURI);
|
||||
associatedKeys.associatedZIDNumber = 0;
|
||||
|
|
@ -562,16 +576,21 @@ int lime_createMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_t
|
|||
}
|
||||
|
||||
/* create an xml doc to hold the multipart message */
|
||||
xmlDocPtr xmlOutputMessage = xmlNewDoc((const xmlChar *)"1.0");
|
||||
xmlOutputMessage = xmlNewDoc((const xmlChar *)"1.0");
|
||||
/* root tag is "doc" */
|
||||
xmlNodePtr rootNode = xmlNewDocNode(xmlOutputMessage, NULL, (const xmlChar *)"doc", NULL);
|
||||
rootNode = xmlNewDocNode(xmlOutputMessage, NULL, (const xmlChar *)"doc", NULL);
|
||||
xmlDocSetRootElement(xmlOutputMessage, rootNode);
|
||||
/* add the self ZID child */
|
||||
xmlNewTextChild(rootNode, NULL, (const xmlChar *)"ZID", selfZidHex);
|
||||
|
||||
/* loop on all keys found */
|
||||
int i;
|
||||
for (i=0; i<associatedKeys.associatedZIDNumber; i++) {
|
||||
uint8_t peerZidHex[25];
|
||||
uint8_t sessionIndexHex[9];
|
||||
xmlNodePtr msgNode;
|
||||
int b64Size;
|
||||
char *encryptedMessageb64;
|
||||
|
||||
/* encrypt message with current key */
|
||||
limeKey_t *currentKey = associatedKeys.peerKeys[i];
|
||||
/* encrypted message include a 16 bytes tag */
|
||||
|
|
@ -583,11 +602,9 @@ int lime_createMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_t
|
|||
* <index>session index</index>
|
||||
* <text>ciphertext</text>
|
||||
* </msg> */
|
||||
xmlNodePtr msgNode = xmlNewDocNode(xmlOutputMessage, NULL, (const xmlChar *)"msg", NULL);
|
||||
uint8_t peerZidHex[25];
|
||||
msgNode = xmlNewDocNode(xmlOutputMessage, NULL, (const xmlChar *)"msg", NULL);
|
||||
lime_int8ToStr(peerZidHex, currentKey->peerZID, 12);
|
||||
peerZidHex[24] = '\0';
|
||||
uint8_t sessionIndexHex[9];
|
||||
sessionIndexHex[0] = lime_byteToChar((uint8_t)((currentKey->sessionIndex>>28)&0x0F));
|
||||
sessionIndexHex[1] = lime_byteToChar((uint8_t)((currentKey->sessionIndex>>24)&0x0F));
|
||||
sessionIndexHex[2] = lime_byteToChar((uint8_t)((currentKey->sessionIndex>>20)&0x0F));
|
||||
|
|
@ -602,8 +619,8 @@ int lime_createMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_t
|
|||
xmlNewTextChild(msgNode, NULL, (const xmlChar *)"index", sessionIndexHex);
|
||||
|
||||
/* convert the cipherText to base 64 */
|
||||
int b64Size = b64_encode(NULL, encryptedMessageLength, NULL, 0);
|
||||
char *encryptedMessageb64 = (char *)malloc(b64Size+1);
|
||||
b64Size = b64_encode(NULL, encryptedMessageLength, NULL, 0);
|
||||
encryptedMessageb64 = (char *)malloc(b64Size+1);
|
||||
b64Size = b64_encode(encryptedMessage, encryptedMessageLength, encryptedMessageb64, b64Size);
|
||||
encryptedMessageb64[b64Size] = '\0'; /* libxml need a null terminated string */
|
||||
xmlNewTextChild(msgNode, NULL, (const xmlChar *)"text", (const xmlChar *)encryptedMessageb64);
|
||||
|
|
@ -619,7 +636,6 @@ int lime_createMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_t
|
|||
}
|
||||
|
||||
/* dump the whole message doc into the output */
|
||||
int xmlStringLength;
|
||||
xmlDocDumpFormatMemoryEnc(xmlOutputMessage, output, &xmlStringLength, "UTF-8", 0);
|
||||
xmlFreeDoc(xmlOutputMessage);
|
||||
|
||||
|
|
@ -630,16 +646,23 @@ int lime_createMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_t
|
|||
|
||||
int lime_decryptMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_t **output) {
|
||||
int retval;
|
||||
uint8_t selfZidHex[25];
|
||||
uint8_t selfZid[12]; /* same data but in byte buffer */
|
||||
limeKey_t associatedKey;
|
||||
xmlChar *peerZidHex = NULL;
|
||||
xmlNodePtr cur;
|
||||
uint8_t *encryptedMessage = NULL;
|
||||
uint32_t encryptedMessageLength = 0;
|
||||
uint32_t usedSessionIndex = 0;
|
||||
xmlDocPtr xmlEncryptedMessage;
|
||||
|
||||
if (cacheBuffer == NULL) {
|
||||
return LIME_INVALID_CACHE;
|
||||
}
|
||||
/* retrieve selfZIDHex from cache(return a 24 char hexa string + null termination) */
|
||||
uint8_t selfZidHex[25];
|
||||
if (lime_getSelfZid(cacheBuffer, selfZidHex) != 0) {
|
||||
return LIME_UNABLE_TO_DECRYPT_MESSAGE;
|
||||
}
|
||||
uint8_t selfZid[12]; /* same data but in byte buffer */
|
||||
lime_strToUint8(selfZid, selfZidHex, 24);
|
||||
|
||||
/* parse the message into an xml doc */
|
||||
|
|
@ -647,15 +670,13 @@ int lime_decryptMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_
|
|||
if (memcmp(message, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>", 38) != 0 ) {
|
||||
return LIME_INVALID_ENCRYPTED_MESSAGE;
|
||||
}
|
||||
xmlDocPtr xmlEncryptedMessage = xmlParseDoc((const xmlChar *)message);
|
||||
xmlEncryptedMessage = xmlParseDoc((const xmlChar *)message);
|
||||
if (xmlEncryptedMessage == NULL) {
|
||||
return LIME_INVALID_ENCRYPTED_MESSAGE;
|
||||
}
|
||||
|
||||
/* retrieve the sender ZID which is the first child of root */
|
||||
limeKey_t associatedKey;
|
||||
xmlChar *peerZidHex = NULL;
|
||||
xmlNodePtr cur = xmlDocGetRootElement(xmlEncryptedMessage);
|
||||
cur = xmlDocGetRootElement(xmlEncryptedMessage);
|
||||
if (cur != NULL) {
|
||||
cur = cur->xmlChildrenNode;
|
||||
if ((!xmlStrcmp(cur->name, (const xmlChar *)"ZID"))){ /* sender ZID found, extract it */
|
||||
|
|
@ -666,10 +687,6 @@ int lime_decryptMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t *encryptedMessage = NULL;
|
||||
uint32_t encryptedMessageLength = 0;
|
||||
uint32_t usedSessionIndex = 0;
|
||||
|
||||
if (peerZidHex != NULL) {
|
||||
/* get from cache the matching key */
|
||||
retval = lime_getCachedRcvKeyByZid(cacheBuffer, &associatedKey);
|
||||
|
|
@ -686,8 +703,11 @@ int lime_decryptMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_
|
|||
xmlChar *currentZidHex = xmlNodeListGetString(cacheBuffer, msgChildrenNode->xmlChildrenNode, 1); /* pZID is the first element of msg */
|
||||
if (!xmlStrcmp(currentZidHex, (const xmlChar *)selfZidHex)) { /* we found the msg node we are looking for */
|
||||
/* get the index (second node in the msg one) */
|
||||
xmlChar *sessionIndexHex;
|
||||
xmlChar *encryptedMessageb64;
|
||||
|
||||
msgChildrenNode = msgChildrenNode->next;
|
||||
xmlChar *sessionIndexHex = xmlNodeListGetString(cacheBuffer, msgChildrenNode->xmlChildrenNode, 1);
|
||||
sessionIndexHex = xmlNodeListGetString(cacheBuffer, msgChildrenNode->xmlChildrenNode, 1);
|
||||
usedSessionIndex = (((uint32_t)lime_charToByte(sessionIndexHex[0]))<<28)
|
||||
| (((uint32_t)lime_charToByte(sessionIndexHex[1]))<<24)
|
||||
| (((uint32_t)lime_charToByte(sessionIndexHex[2]))<<20)
|
||||
|
|
@ -700,7 +720,7 @@ int lime_decryptMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_
|
|||
/* get the encrypted message */
|
||||
msgChildrenNode = msgChildrenNode->next;
|
||||
/* convert the cipherText from base 64 */
|
||||
xmlChar *encryptedMessageb64 = xmlNodeListGetString(cacheBuffer, msgChildrenNode->xmlChildrenNode, 1);
|
||||
encryptedMessageb64 = xmlNodeListGetString(cacheBuffer, msgChildrenNode->xmlChildrenNode, 1);
|
||||
encryptedMessageLength = b64_decode((char *)encryptedMessageb64, strlen((char *)encryptedMessageb64), NULL, 0);
|
||||
encryptedMessage = (uint8_t *)malloc(encryptedMessageLength);
|
||||
encryptedMessageLength = b64_decode((char *)encryptedMessageb64, strlen((char *)encryptedMessageb64), encryptedMessage, encryptedMessageLength);
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<cache><selfZID>ef7692d0792a67491ae2d44e</selfZID><peer><ZID>005dbe0399643d953a2202dd</ZID><rs1>9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899</rs2><uri>pipo1@pipo.com</uri><sndKey>963c57bb28e62068d2df23e8f9b771932d3c57bb28e62068d2df23e8f9b77193</sndKey><rcvKey>e9d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193</rcvKey><sndSId>5f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193</sndSId><rcvSId>e6ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b77193</rcvSId><sndIndex>00000069</sndIndex><rcvIndex>000001cc</rcvIndex></peer><peer><ZID>1234567889643d953a2202ee</ZID><rs1>9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899</rs2><uri>pipo1@pipo.com</uri><sndKey>123456789012345678901234567890123456765431262068d2df23e8f9b77193</sndKey><rcvKey>25d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193</rcvKey><sndSId>f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193</sndSId><rcvSId>22ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b77193</rcvSId><sndIndex>00000001</sndIndex><rcvIndex>00000000</rcvIndex></peer></cache>
|
||||
<cache><selfZID>ef7692d0792a67491ae2d44e</selfZID><peer><ZID>005dbe0399643d953a2202dd</ZID><rs1>9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899</rs2><uri>pipo1@pipo.com</uri><sndKey>963c57bb28e62068d2df23e8f9b771932d3c57bb28e62068d2df23e8f9b77193</sndKey><rcvKey>fcd9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193</rcvKey><sndSId>5f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193</sndSId><rcvSId>f9ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b77193</rcvSId><sndIndex>00000069</sndIndex><rcvIndex>000001df</rcvIndex><pvs>01</pvs></peer><peer><ZID>1234567889643d953a2202ee</ZID><rs1>9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899</rs2><uri>pipo1@pipo.com</uri><sndKey>123456789012345678901234567890123456765431262068d2df23e8f9b77193</sndKey><rcvKey>25d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193</rcvKey><sndSId>f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193</sndSId><rcvSId>22ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b77193</rcvSId><sndIndex>00000001</sndIndex><rcvIndex>00000000</rcvIndex><pvs>01</pvs></peer></cache>
|
||||
|
|
|
|||
|
|
@ -74,15 +74,15 @@ void file_transfer_received(LinphoneCore *lc, LinphoneChatMessage *message, cons
|
|||
} else {
|
||||
/*next chunk*/
|
||||
file = (FILE*)linphone_chat_message_get_user_data(message);
|
||||
}
|
||||
|
||||
if (size==0) { /* tranfer complete */
|
||||
stats* counters = get_stats(lc);
|
||||
counters->number_of_LinphoneMessageExtBodyReceived++;
|
||||
fclose(file);
|
||||
} else { /* store content on a file*/
|
||||
if (fwrite(buff,size,1,file)==-1){
|
||||
ms_error("file_transfer_received(): write() failed: %s",strerror(errno));
|
||||
}
|
||||
if (size==0) { /* tranfer complete */
|
||||
stats* counters = get_stats(lc);
|
||||
counters->number_of_LinphoneMessageExtBodyReceived++;
|
||||
fclose(file);
|
||||
} else { /* store content on a file*/
|
||||
if (fwrite(buff,size,1,file)==-1){
|
||||
ms_error("file_transfer_received(): write() failed: %s",strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -167,13 +167,15 @@ void liblinphone_tester_chat_message_state_change(LinphoneChatMessage* msg,Linph
|
|||
static void text_message(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
char* to;
|
||||
LinphoneChatRoom* chat_room;
|
||||
|
||||
/* make sure lime is not enabled */
|
||||
linphone_core_set_lime(marie->lc, 0);
|
||||
linphone_core_set_lime(pauline->lc, 0);
|
||||
|
||||
char* to = linphone_address_as_string(marie->identity);
|
||||
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to);
|
||||
to = linphone_address_as_string(marie->identity);
|
||||
chat_room = linphone_core_create_chat_room(pauline->lc,to);
|
||||
ms_free(to);
|
||||
{
|
||||
int dummy=0;
|
||||
|
|
@ -269,6 +271,10 @@ static void text_message_with_credential_from_auth_cb(void) {
|
|||
}
|
||||
|
||||
static void text_message_with_privacy(void) {
|
||||
char *to;
|
||||
LinphoneChatRoom* chat_room;
|
||||
|
||||
LinphoneProxyConfig* pauline_proxy;
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
|
|
@ -276,9 +282,8 @@ static void text_message_with_privacy(void) {
|
|||
linphone_core_set_lime(marie->lc, 0);
|
||||
linphone_core_set_lime(pauline->lc, 0);
|
||||
|
||||
LinphoneProxyConfig* pauline_proxy;
|
||||
char* to = linphone_address_as_string(marie->identity);
|
||||
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to);
|
||||
to = linphone_address_as_string(marie->identity);
|
||||
chat_room = linphone_core_create_chat_room(pauline->lc,to);
|
||||
ms_free(to);
|
||||
|
||||
/*test proxy config privacy*/
|
||||
|
|
@ -352,18 +357,19 @@ static void text_message_compatibility_mode(void) {
|
|||
static void text_message_with_ack(void) {
|
||||
int leaked_objects;
|
||||
int begin;
|
||||
LinphoneCoreManager* marie;
|
||||
LinphoneCoreManager* pauline;
|
||||
|
||||
belle_sip_object_enable_leak_detector(TRUE);
|
||||
begin=belle_sip_object_get_object_count();
|
||||
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
marie = linphone_core_manager_new( "marie_rc");
|
||||
pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
/* make sure lime is not enabled */
|
||||
linphone_core_set_lime(marie->lc, 0);
|
||||
linphone_core_set_lime(pauline->lc, 0);
|
||||
{
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
char* to = linphone_address_as_string(marie->identity);
|
||||
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to);
|
||||
LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
|
||||
|
|
@ -388,6 +394,10 @@ static void text_message_with_ack(void) {
|
|||
}
|
||||
|
||||
static void text_message_with_external_body(void) {
|
||||
char* to;
|
||||
LinphoneChatRoom* chat_room;
|
||||
LinphoneChatMessage* message;
|
||||
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
|
|
@ -395,9 +405,9 @@ static void text_message_with_external_body(void) {
|
|||
linphone_core_set_lime(marie->lc, 0);
|
||||
linphone_core_set_lime(pauline->lc, 0);
|
||||
|
||||
char* to = linphone_address_as_string(marie->identity);
|
||||
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to);
|
||||
LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
|
||||
to = linphone_address_as_string(marie->identity);
|
||||
chat_room = linphone_core_create_chat_room(pauline->lc,to);
|
||||
message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
|
||||
linphone_chat_message_set_external_body_url(message,message_external_body_url="http://www.linphone.org");
|
||||
{
|
||||
int dummy=0;
|
||||
|
|
@ -424,37 +434,35 @@ static void text_message_with_external_body(void) {
|
|||
}
|
||||
|
||||
static void file_transfer_message(void) {
|
||||
int i;
|
||||
LinphoneCoreManager *marie, *pauline;
|
||||
LinphoneChatRoom *chat_room;
|
||||
int i;
|
||||
char* to;
|
||||
LinphoneChatRoom* chat_room;
|
||||
LinphoneChatMessage* message;
|
||||
LinphoneContent content;
|
||||
LinphoneChatMessage *message;
|
||||
/* setting dummy file content to something */
|
||||
const char* big_file_content="big file";
|
||||
for (i=0;i<=sizeof(big_file)-strlen(big_file_content);i+=strlen(big_file_content))
|
||||
memcpy(big_file+i, big_file_content, strlen(big_file_content));
|
||||
|
||||
if (i<sizeof(big_file)) {
|
||||
memcpy(big_file+i, big_file_content, sizeof(big_file)-i);
|
||||
}
|
||||
|
||||
big_file[0]=*"S";
|
||||
big_file[sizeof(big_file)-1]=*"E";
|
||||
|
||||
marie = linphone_core_manager_new( "marie_rc");
|
||||
pauline = linphone_core_manager_new( "pauline_rc");
|
||||
const char* big_file_content="big file"; /* setting dummy file content to something */
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
/* make sure lime is not enabled */
|
||||
linphone_core_set_lime(marie->lc, 0);
|
||||
linphone_core_set_lime(pauline->lc, 0);
|
||||
|
||||
reset_counters(&marie->stat);
|
||||
reset_counters(&pauline->stat);
|
||||
|
||||
for (i=0;i<sizeof(big_file);i+=strlen(big_file_content))
|
||||
memcpy(big_file+i, big_file_content, strlen(big_file_content));
|
||||
|
||||
big_file[0]=*"S";
|
||||
big_file[sizeof(big_file)-1]=*"E";
|
||||
|
||||
/* Globally configure an http file transfer server. */
|
||||
linphone_core_set_file_transfer_server(pauline->lc,"https://www.linphone.org:444/lft.php");
|
||||
|
||||
/* create a chatroom on pauline's side */
|
||||
char* to = linphone_address_as_string(marie->identity);
|
||||
to = linphone_address_as_string(marie->identity);
|
||||
chat_room = linphone_core_create_chat_room(pauline->lc,to);
|
||||
|
||||
ms_free(to);
|
||||
/* create a file transfer message */
|
||||
memset(&content,0,sizeof(content));
|
||||
content.type="text";
|
||||
|
|
@ -462,12 +470,21 @@ static void file_transfer_message(void) {
|
|||
content.size=sizeof(big_file); /*total size to be transfered*/
|
||||
content.name = "bigfile.txt";
|
||||
message = linphone_chat_room_create_file_transfer_message(chat_room, &content);
|
||||
|
||||
{
|
||||
int dummy=0;
|
||||
wait_for_until(marie->lc,pauline->lc,&dummy,1,100); /*just to have time to purge message stored in the server*/
|
||||
reset_counters(&marie->stat);
|
||||
reset_counters(&pauline->stat);
|
||||
}
|
||||
linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc);
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1));
|
||||
if (marie->stat.last_received_chat_message ) {
|
||||
linphone_chat_message_start_file_download(marie->stat.last_received_chat_message, liblinphone_tester_chat_message_state_change);
|
||||
}
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageExtBodyReceived,1));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDelivered,1));
|
||||
|
||||
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
|
||||
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1);
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,1);
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
|
|
@ -545,6 +562,10 @@ static void file_transfer_message_io_error_upload(void) {
|
|||
const char* big_file_content="big file"; /* setting dummy file content to something */
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
/* make sure lime is not enabled */
|
||||
linphone_core_set_lime(marie->lc, 0);
|
||||
linphone_core_set_lime(pauline->lc, 0);
|
||||
|
||||
reset_counters(&marie->stat);
|
||||
reset_counters(&pauline->stat);
|
||||
|
||||
|
|
@ -606,6 +627,10 @@ static void file_transfer_message_io_error_download(void) {
|
|||
const char* big_file_content="big file"; /* setting dummy file content to something */
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
/* make sure lime is not enabled */
|
||||
linphone_core_set_lime(marie->lc, 0);
|
||||
linphone_core_set_lime(pauline->lc, 0);
|
||||
|
||||
reset_counters(&marie->stat);
|
||||
reset_counters(&pauline->stat);
|
||||
|
||||
|
|
@ -670,6 +695,10 @@ static void file_transfer_message_upload_cancelled(void) {
|
|||
const char* big_file_content="big file"; /* setting dummy file content to something */
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
/* make sure lime is not enabled */
|
||||
linphone_core_set_lime(marie->lc, 0);
|
||||
linphone_core_set_lime(pauline->lc, 0);
|
||||
|
||||
reset_counters(&marie->stat);
|
||||
reset_counters(&pauline->stat);
|
||||
|
||||
|
|
@ -725,6 +754,10 @@ static void file_transfer_message_download_cancelled(void) {
|
|||
const char* big_file_content="big file"; /* setting dummy file content to something */
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
/* make sure lime is not enabled */
|
||||
linphone_core_set_lime(marie->lc, 0);
|
||||
linphone_core_set_lime(pauline->lc, 0);
|
||||
|
||||
reset_counters(&marie->stat);
|
||||
reset_counters(&pauline->stat);
|
||||
|
||||
|
|
@ -781,6 +814,10 @@ static void file_transfer_message_download_cancelled(void) {
|
|||
}
|
||||
|
||||
static void text_message_with_send_error(void) {
|
||||
char* to;
|
||||
LinphoneChatRoom* chat_room;
|
||||
LinphoneChatMessage* message;
|
||||
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
|
|
@ -788,9 +825,9 @@ static void text_message_with_send_error(void) {
|
|||
linphone_core_set_lime(marie->lc, 0);
|
||||
linphone_core_set_lime(pauline->lc, 0);
|
||||
|
||||
char* to = linphone_address_as_string(pauline->identity);
|
||||
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(marie->lc,to);
|
||||
LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
|
||||
to = linphone_address_as_string(pauline->identity);
|
||||
chat_room = linphone_core_create_chat_room(marie->lc,to);
|
||||
message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
|
||||
reset_counters(&marie->stat);
|
||||
reset_counters(&pauline->stat);
|
||||
|
||||
|
|
@ -822,6 +859,10 @@ static void text_message_with_send_error(void) {
|
|||
}
|
||||
|
||||
static void text_message_denied(void) {
|
||||
char* to;
|
||||
LinphoneChatRoom* chat_room;
|
||||
LinphoneChatMessage* message;
|
||||
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
|
|
@ -829,9 +870,9 @@ static void text_message_denied(void) {
|
|||
linphone_core_set_lime(marie->lc, 0);
|
||||
linphone_core_set_lime(pauline->lc, 0);
|
||||
|
||||
char* to = linphone_address_as_string(pauline->identity);
|
||||
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(marie->lc,to);
|
||||
LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
|
||||
to = linphone_address_as_string(pauline->identity);
|
||||
chat_room = linphone_core_create_chat_room(marie->lc,to);
|
||||
message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
|
||||
|
||||
/*pauline doesn't want to be disturbed*/
|
||||
linphone_core_disable_chat(pauline->lc,LinphoneReasonDoNotDisturb);
|
||||
|
|
@ -865,6 +906,10 @@ void info_message_received(LinphoneCore *lc, LinphoneCall* call, const LinphoneI
|
|||
|
||||
|
||||
static void info_message_with_args(bool_t with_content) {
|
||||
LinphoneInfoMessage *info;
|
||||
const LinphoneContent *content;
|
||||
const char *hvalue;
|
||||
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
|
|
@ -872,10 +917,6 @@ static void info_message_with_args(bool_t with_content) {
|
|||
linphone_core_set_lime(marie->lc, 0);
|
||||
linphone_core_set_lime(pauline->lc, 0);
|
||||
|
||||
LinphoneInfoMessage *info;
|
||||
const LinphoneContent *content;
|
||||
const char *hvalue;
|
||||
|
||||
CU_ASSERT_TRUE(call(pauline,marie));
|
||||
|
||||
info=linphone_core_create_info_message(marie->lc);
|
||||
|
|
@ -932,6 +973,10 @@ static void info_message_with_body(){
|
|||
}
|
||||
|
||||
static void is_composing_notification(void) {
|
||||
char* to;
|
||||
LinphoneChatRoom* chat_room;
|
||||
int dummy = 0;
|
||||
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
|
|
@ -939,9 +984,8 @@ static void is_composing_notification(void) {
|
|||
linphone_core_set_lime(marie->lc, 0);
|
||||
linphone_core_set_lime(pauline->lc, 0);
|
||||
|
||||
char* to = linphone_address_as_string(marie->identity);
|
||||
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc, to);
|
||||
int dummy = 0;
|
||||
to = linphone_address_as_string(marie->identity);
|
||||
chat_room = linphone_core_create_chat_room(pauline->lc, to);
|
||||
|
||||
ms_free(to);
|
||||
{
|
||||
|
|
@ -961,8 +1005,8 @@ static void is_composing_notification(void) {
|
|||
}
|
||||
|
||||
void printHex(char *title, uint8_t *data, uint32_t length) {
|
||||
printf ("%s : ", title);
|
||||
int i;
|
||||
printf ("%s : ", title);
|
||||
for (i=0; i<length; i++) {
|
||||
printf ("0x%02x, ", data[i]);
|
||||
}
|
||||
|
|
@ -971,17 +1015,35 @@ void printHex(char *title, uint8_t *data, uint32_t length) {
|
|||
|
||||
static void lime_unit(void) {
|
||||
int retval;
|
||||
int size;
|
||||
uint8_t *cacheBufferString;
|
||||
xmlDocPtr cacheBufferAlice;
|
||||
xmlDocPtr cacheBufferBob;
|
||||
uint8_t *multipartMessage = NULL;
|
||||
uint8_t *decryptedMessage = NULL;
|
||||
xmlChar *xmlStringOutput;
|
||||
int xmlStringLength;
|
||||
limeURIKeys_t associatedKeys;
|
||||
int i;
|
||||
limeKey_t associatedKey;
|
||||
uint8_t targetZID[12] = {0x00, 0x5d, 0xbe, 0x03, 0x99, 0x64, 0x3d, 0x95, 0x3a, 0x22, 0x02, 0xdd};
|
||||
uint8_t senderZID[12] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x70, 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0};
|
||||
uint8_t encryptedMessage[48];
|
||||
uint8_t plainMessage[48];
|
||||
uint8_t receiverZID[12];
|
||||
xmlDocPtr cacheBuffer;
|
||||
|
||||
/* Load Alice cache file */
|
||||
FILE *CACHE = fopen("ZIDCacheAlice.xml", "r+");
|
||||
fseek(CACHE, 0L, SEEK_END); /* Position to end of file */
|
||||
int size = ftell(CACHE); /* Get file length */
|
||||
size = ftell(CACHE); /* Get file length */
|
||||
rewind(CACHE); /* Back to start of file */
|
||||
uint8_t *cacheBufferString = (uint8_t *)malloc(size*sizeof(uint8_t)+1);
|
||||
cacheBufferString = (uint8_t *)malloc(size*sizeof(uint8_t)+1);
|
||||
fread(cacheBufferString, 1, size, CACHE);
|
||||
*(cacheBufferString+size) = '\0';
|
||||
fclose(CACHE);
|
||||
/* parse it to an xmlDoc */
|
||||
xmlDocPtr cacheBufferAlice = xmlParseDoc(cacheBufferString);
|
||||
cacheBufferAlice = xmlParseDoc(cacheBufferString);
|
||||
free(cacheBufferString);
|
||||
|
||||
/* Load Bob cache file */
|
||||
|
|
@ -994,13 +1056,12 @@ static void lime_unit(void) {
|
|||
*(cacheBufferString+size) = '\0';
|
||||
fclose(CACHE);
|
||||
/* parse it to an xmlDoc */
|
||||
xmlDocPtr cacheBufferBob = xmlParseDoc(cacheBufferString);
|
||||
cacheBufferBob = xmlParseDoc(cacheBufferString);
|
||||
free(cacheBufferString);
|
||||
|
||||
|
||||
|
||||
/* encrypt a message */
|
||||
uint8_t *multipartMessage = NULL;
|
||||
retval = lime_createMultipartMessage(cacheBufferAlice, (uint8_t *)"Bonjour les petits lapins,ca va? éh oui oui", (uint8_t *)"sip:pauline@sip.example.org", &multipartMessage);
|
||||
|
||||
printf("create message return %d\n", retval);
|
||||
|
|
@ -1009,7 +1070,6 @@ static void lime_unit(void) {
|
|||
}
|
||||
|
||||
/* decrypt the multipart message */
|
||||
uint8_t *decryptedMessage = NULL;
|
||||
retval = lime_decryptMultipartMessage(cacheBufferBob, multipartMessage, &decryptedMessage);
|
||||
|
||||
printf("decrypt message return %d\n", retval);
|
||||
|
|
@ -1021,8 +1081,6 @@ static void lime_unit(void) {
|
|||
|
||||
/* update ZID files */
|
||||
/* dump the xml document into a string */
|
||||
xmlChar *xmlStringOutput;
|
||||
int xmlStringLength;
|
||||
xmlDocDumpFormatMemoryEnc(cacheBufferAlice, &xmlStringOutput, &xmlStringLength, "UTF-8", 0);
|
||||
/* write it to the file */
|
||||
CACHE = fopen("ZIDCacheAlice.xml", "w+");
|
||||
|
|
@ -1051,18 +1109,16 @@ static void lime_unit(void) {
|
|||
*(cacheBufferString+size) = '\0';
|
||||
fclose(CACHE);
|
||||
/* parse it to an xmlDoc */
|
||||
xmlDocPtr cacheBuffer = xmlParseDoc(cacheBufferString);
|
||||
cacheBuffer = xmlParseDoc(cacheBufferString);
|
||||
free(cacheBufferString);
|
||||
|
||||
/* get data from cache : sender */
|
||||
limeURIKeys_t associatedKeys;
|
||||
associatedKeys.peerURI = (uint8_t *)malloc(15);
|
||||
memcpy(associatedKeys.peerURI, "pipo1@pipo.com", 15);
|
||||
associatedKeys.associatedZIDNumber = 0;
|
||||
retval = lime_getCachedSndKeysByURI(cacheBuffer, &associatedKeys);
|
||||
printf("getCachedKeys returns %d, number of key found %d\n", retval, associatedKeys.associatedZIDNumber);
|
||||
|
||||
int i;
|
||||
for (i=0; i<associatedKeys.associatedZIDNumber; i++) {
|
||||
printHex("ZID", associatedKeys.peerKeys[i]->peerZID, 12);
|
||||
printHex("key", associatedKeys.peerKeys[i]->key, 32);
|
||||
|
|
@ -1071,8 +1127,6 @@ static void lime_unit(void) {
|
|||
}
|
||||
|
||||
/* get data from cache : receiver */
|
||||
limeKey_t associatedKey;
|
||||
uint8_t targetZID[12] = {0x00, 0x5d, 0xbe, 0x03, 0x99, 0x64, 0x3d, 0x95, 0x3a, 0x22, 0x02, 0xdd};
|
||||
memcpy(associatedKey.peerZID, targetZID, 12);
|
||||
retval = lime_getCachedRcvKeyByZid(cacheBuffer, &associatedKey);
|
||||
printf("getCachedKey by ZID return %d\n", retval);
|
||||
|
|
@ -1082,13 +1136,9 @@ static void lime_unit(void) {
|
|||
printf("session index %d\n", associatedKey.sessionIndex);
|
||||
|
||||
/* encrypt/decrypt a message */
|
||||
uint8_t senderZID[12] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x70, 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0};
|
||||
uint8_t encryptedMessage[48];
|
||||
uint8_t plainMessage[48];
|
||||
lime_encryptMessage(associatedKeys.peerKeys[0], (uint8_t *)"bla Bla bla b! Pipo", 20, senderZID, encryptedMessage);
|
||||
printHex("Ciphered", encryptedMessage, 32);
|
||||
/* invert sender and receiverZID to decrypt/authenticate */
|
||||
uint8_t receiverZID[12];
|
||||
memcpy(receiverZID, associatedKeys.peerKeys[0]->peerZID, 12);
|
||||
memcpy(associatedKeys.peerKeys[0]->peerZID, senderZID, 12);
|
||||
retval = lime_decryptMessage(associatedKeys.peerKeys[0], encryptedMessage, 36, receiverZID, plainMessage);
|
||||
|
|
@ -1123,6 +1173,8 @@ static void lime_unit(void) {
|
|||
}
|
||||
|
||||
static void lime_text_message(void) {
|
||||
char* to;
|
||||
LinphoneChatRoom* chat_room;
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
|
|
@ -1134,8 +1186,8 @@ static void lime_text_message(void) {
|
|||
linphone_core_set_zrtp_secrets_file(marie->lc, "ZIDCacheAlice.xml");
|
||||
linphone_core_set_zrtp_secrets_file(pauline->lc, "ZIDCacheBob.xml");
|
||||
|
||||
char* to = linphone_address_as_string(marie->identity);
|
||||
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to);
|
||||
to = linphone_address_as_string(marie->identity);
|
||||
chat_room = linphone_core_create_chat_room(pauline->lc,to);
|
||||
ms_free(to);
|
||||
|
||||
linphone_chat_room_send_message(chat_room,"Bla bla bla bla");
|
||||
|
|
@ -1277,6 +1329,7 @@ static void history_messages_count() {
|
|||
#endif
|
||||
|
||||
test_t message_tests[] = {
|
||||
{ "Lime Text Message", lime_text_message },
|
||||
{ "Text message", text_message },
|
||||
{ "Text message within call's dialog", text_message_within_dialog},
|
||||
{ "Text message with credentials from auth info cb", text_message_with_credential_from_auth_cb},
|
||||
|
|
@ -1295,8 +1348,7 @@ test_t message_tests[] = {
|
|||
{ "Info message", info_message },
|
||||
{ "Info message with body", info_message_with_body },
|
||||
{ "IsComposing notification", is_composing_notification },
|
||||
{ "Lime Unitary", lime_unit },
|
||||
{ "Lime Text Message", lime_text_message }
|
||||
{ "Lime Unitary", lime_unit }
|
||||
#ifdef MSG_STORAGE_ENABLED
|
||||
,{ "Database migration", message_storage_migration }
|
||||
,{ "History count", history_messages_count }
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue