diff --git a/src/c-wrapper/api/c-chat-message.cpp b/src/c-wrapper/api/c-chat-message.cpp index 59bffa2d9..1bf1faee5 100644 --- a/src/c-wrapper/api/c-chat-message.cpp +++ b/src/c-wrapper/api/c-chat-message.cpp @@ -222,7 +222,7 @@ void linphone_chat_message_add_text_content(LinphoneChatMessage *msg, const char LinphonePrivate::ContentType contentType = LinphonePrivate::ContentType::PlainText; content->setContentType(contentType); content->setBody(L_C_TO_STRING(c_content)); - L_GET_CPP_PTR_FROM_C_OBJECT(msg)->addContent(*content); + L_GET_CPP_PTR_FROM_C_OBJECT(msg)->addContent(content); } bool_t linphone_chat_message_has_text_content(const LinphoneChatMessage *msg) { @@ -284,7 +284,7 @@ int linphone_chat_message_set_text(LinphoneChatMessage *msg, const char* text) { LinphoneContent *linphone_chat_message_get_file_transfer_information(LinphoneChatMessage *msg) { const LinphonePrivate::Content *content = L_GET_PRIVATE_FROM_C_OBJECT(msg)->getFileTransferInformation(); - if (content) return L_GET_C_BACK_PTR(content); + if (content) return linphone_content_ref(L_GET_C_BACK_PTR(content)); return NULL; } diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp index 7af4b4073..6691ec9da 100644 --- a/src/c-wrapper/api/c-content.cpp +++ b/src/c-wrapper/api/c-content.cpp @@ -166,27 +166,27 @@ const char * linphone_content_get_custom_header(const LinphoneContent *content, const char *linphone_content_get_key(const LinphoneContent *content) { const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - if (c->isFile()) { - const LinphonePrivate::FileContent *fc = static_cast(c); - return L_STRING_TO_C(fc->getFileKey()); + if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) { + const LinphonePrivate::FileTransferContent *ftc = static_cast(c); + return ftc->getFileKeyAsString(); } return NULL; } size_t linphone_content_get_key_size(const LinphoneContent *content) { const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - if (c->isFile()) { - const LinphonePrivate::FileContent *fc = static_cast(c); - return fc->getFileKey().length(); + if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) { + const LinphonePrivate::FileTransferContent *ftc = static_cast(c); + return ftc->getFileKey().size(); } return 0; } void linphone_content_set_key(LinphoneContent *content, const char *key, const size_t keyLength) { LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); - if (c->isFile()) { - LinphonePrivate::FileContent *fc = static_cast(c); - fc->setFileKey(L_C_TO_STRING(key)); + if (c->getContentType() == LinphonePrivate::ContentType::FileTransfer) { + LinphonePrivate::FileTransferContent *ftc = static_cast(c); + ftc->setFileKey(key, keyLength); } } diff --git a/src/chat/chat-message/chat-message.cpp b/src/chat/chat-message/chat-message.cpp index 855dbd902..2c5130802 100644 --- a/src/chat/chat-message/chat-message.cpp +++ b/src/chat/chat-message/chat-message.cpp @@ -301,7 +301,7 @@ void ChatMessagePrivate::setFileTransferInformation (Content *content) { L_Q(); if (content->isFile()) { - q->addContent(*content); + q->addContent(content); } else { // This scenario is more likely to happen because the caller is using the C API LinphoneContent *c_content = L_GET_C_BACK_PTR(content); @@ -312,7 +312,7 @@ void ChatMessagePrivate::setFileTransferInformation (Content *content) { if (!content->isEmpty()) { fileContent->setBody(content->getBody()); } - q->addContent(*fileContent); + q->addContent(fileContent); } } @@ -354,7 +354,7 @@ void ChatMessagePrivate::sendImdn (Imdn::Type imdnType, LinphoneReason reason) { Content *content = new Content(); content->setContentType("message/imdn+xml"); content->setBody(Imdn::createXml(imdnId, time, imdnType, reason)); - msg->addContent(*content); + msg->addContent(content); if (reason != LinphoneReasonNone) msg->getPrivate()->setEncryptionPrevented(true); @@ -676,7 +676,7 @@ void ChatMessagePrivate::send () { if (content->getContentType() == ContentType::FileTransfer) { FileTransferContent *fileTransferContent = (FileTransferContent *)content; it = contents.erase(it); - q->addContent(*fileTransferContent->getFileContent()); + q->addContent(fileTransferContent->getFileContent()); delete fileTransferContent; } else { it++; @@ -881,18 +881,18 @@ const list &ChatMessage::getContents () const { return d->contents; } -void ChatMessage::addContent (Content &content) { +void ChatMessage::addContent (Content *content) { L_D(); if (d->isReadOnly) return; - d->contents.push_back(&content); + d->contents.push_back(content); } -void ChatMessage::removeContent (const Content &content) { +void ChatMessage::removeContent (const Content *content) { L_D(); if (d->isReadOnly) return; - d->contents.remove(&const_cast(content)); + d->contents.remove(const_cast(content)); } const Content &ChatMessage::getInternalContent () const { diff --git a/src/chat/chat-message/chat-message.h b/src/chat/chat-message/chat-message.h index af7623b77..3b0b26417 100644 --- a/src/chat/chat-message/chat-message.h +++ b/src/chat/chat-message/chat-message.h @@ -94,8 +94,8 @@ public: void setToBeStored (bool value); const std::list &getContents () const; - void addContent (Content &content); - void removeContent (const Content &content); + void addContent (Content *content); + void removeContent (const Content *content); const Content &getInternalContent () const; void setInternalContent (const Content &content); diff --git a/src/chat/chat-room/chat-room.cpp b/src/chat/chat-room/chat-room.cpp index 03b8cd079..2c1e0054a 100644 --- a/src/chat/chat-room/chat-room.cpp +++ b/src/chat/chat-room/chat-room.cpp @@ -82,7 +82,7 @@ void ChatRoomPrivate::sendIsComposingNotification () { Content *content = new Content(); content->setContentType(ContentType::ImIsComposing); content->setBody(payload); - chatMessage->addContent(*content); + chatMessage->addContent(content); chatMessage->getPrivate()->send(); } } @@ -389,7 +389,7 @@ shared_ptr ChatRoom::createChatMessage (const string &text) { Content *content = new Content(); content->setContentType(ContentType::PlainText); content->setBody(text); - chatMessage->addContent(*content); + chatMessage->addContent(content); return chatMessage; } diff --git a/src/chat/modifier/file-transfer-chat-message-modifier.cpp b/src/chat/modifier/file-transfer-chat-message-modifier.cpp index ac99d2201..674ddb308 100644 --- a/src/chat/modifier/file-transfer-chat-message-modifier.cpp +++ b/src/chat/modifier/file-transfer-chat-message-modifier.cpp @@ -246,12 +246,6 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h } // shall we encrypt the file if (is_file_encryption_enabled && message->getChatRoom()) { - LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee); - LinphoneImEncryptionEngineCbsGenerateFileTransferKeyCb generate_file_transfer_key_cb = - linphone_im_encryption_engine_cbs_get_generate_file_transfer_key(imee_cbs); - if (generate_file_transfer_key_cb) { - generate_file_transfer_key_cb(imee, L_GET_C_BACK_PTR(message->getChatRoom()), L_GET_C_BACK_PTR(message)); - } // temporary storage for the Content-disposition header value : use a generic filename to not leak it // Actual filename stored in msg->file_transfer_information->name will be set in encrypted msg // sended to the @@ -294,9 +288,32 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h const char *body = belle_sip_message_get_body((belle_sip_message_t *)event->response); if (body && strlen(body) > 0) { FileTransferContent *fileTransferContent = new FileTransferContent(); + fileTransferContent->setContentType(ContentType::FileTransfer); + message->addContent(fileTransferContent); + + LinphoneImEncryptionEngine *imee = linphone_core_get_im_encryption_engine(message->getCore()->getCCore()); + bool_t is_file_encryption_enabled = FALSE; + if (imee && message->getChatRoom()) { + LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee); + LinphoneImEncryptionEngineCbsIsEncryptionEnabledForFileTransferCb is_encryption_enabled_for_file_transfer_cb = + linphone_im_encryption_engine_cbs_get_is_encryption_enabled_for_file_transfer(imee_cbs); + if (is_encryption_enabled_for_file_transfer_cb) { + is_file_encryption_enabled = is_encryption_enabled_for_file_transfer_cb(imee, L_GET_C_BACK_PTR(message->getChatRoom())); + } + } + if (is_file_encryption_enabled && message->getChatRoom()) { + LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee); + LinphoneImEncryptionEngineCbsGenerateFileTransferKeyCb generate_file_transfer_key_cb = + linphone_im_encryption_engine_cbs_get_generate_file_transfer_key(imee_cbs); + if (generate_file_transfer_key_cb) { + generate_file_transfer_key_cb(imee, L_GET_C_BACK_PTR(message->getChatRoom()), L_GET_C_BACK_PTR(message)); + } + } + // if we have an encryption key for the file, we must insert it into the msg and restore the correct filename - string content_key = currentFileContentToTransfer->getFileKey(); - if (!content_key.empty()) { + const char *content_key = fileTransferContent->getFileKeyAsString(); + size_t content_key_size = fileTransferContent->getFileKey().size(); + if (content_key_size > 0) { // parse the msg body xmlDocPtr xmlMessageBody = xmlParseDoc((const xmlChar *)body); @@ -309,16 +326,15 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h xmlChar *typeAttribute = xmlGetProp(cur, (const xmlChar *)"type"); // this is the node we are looking for : add a file-key children node if (!xmlStrcmp(typeAttribute, (const xmlChar *)"file")) { - size_t content_key_size = content_key.length(); // need to parse the children node to update the file-name one xmlNodePtr fileInfoNodeChildren = cur->xmlChildrenNode; // convert key to base64 size_t b64Size; - bctbx_base64_encode(nullptr, &b64Size, (unsigned char *)content_key.c_str(), content_key_size); + bctbx_base64_encode(nullptr, &b64Size, (unsigned char *)content_key, content_key_size); unsigned char *keyb64 = (unsigned char *)ms_malloc0(b64Size + 1); int xmlStringLength; - bctbx_base64_encode(keyb64, &b64Size, (unsigned char *)content_key.c_str(), content_key_size); + bctbx_base64_encode(keyb64, &b64Size, (unsigned char *)content_key, content_key_size); keyb64[b64Size] = '\0'; // libxml need a null terminated string // add the node containing the key to the file-info node @@ -354,11 +370,9 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h } FileContent *fileContent = currentFileContentToTransfer; - fileTransferContent->setContentType(ContentType::FileTransfer); fileTransferContent->setFileContent(fileContent); - message->removeContent(*fileContent); - message->addContent(*fileTransferContent); + message->removeContent(fileContent); message->updateState(ChatMessage::State::FileTransferDone); releaseHttpRequest(); @@ -566,7 +580,7 @@ ChatMessageModifier::Result FileTransferChatMessageModifier::decode (const share fileTransferContent->setContentType(internalContent.getContentType()); fileTransferContent->setBody(internalContent.getBody()); fillFileTransferContentInformationsFromVndGsmaRcsFtHttpXml(fileTransferContent); - message->addContent(*fileTransferContent); + message->addContent(fileTransferContent); return ChatMessageModifier::Result::Done; } @@ -641,8 +655,7 @@ static void createFileTransferInformationsFromVndGsmaRcsFtHttpXml (FileTransferC uint8_t *keyBuffer = (uint8_t *)malloc(keyLength); // decode the key into local key buffer bctbx_base64_decode(keyBuffer, &keyLength, (unsigned char *)keyb64, strlen((const char *)keyb64)); - string key = string((const char *)keyBuffer); - fileContent->setFileKey(key); + fileTransferContent->setFileKey((const char *)keyBuffer, keyLength); // duplicate key value into the linphone content private structure xmlFree(keyb64); free(keyBuffer); @@ -715,7 +728,6 @@ void FileTransferChatMessageModifier::onRecvBody (belle_sip_user_body_handler_t // Legacy: call back given by application level linphone_core_notify_file_transfer_recv(message->getCore()->getCCore(), msg, content, (const char *)buffer, size); } - linphone_content_unref(content); } } else { lWarning() << "File transfer decrypt failed with code " << (int)retval; @@ -763,12 +775,12 @@ void FileTransferChatMessageModifier::onRecvEnd (belle_sip_user_body_handler_t * if (retval <= 0 && message->getState() != ChatMessage::State::FileTransferError) { // Remove the FileTransferContent from the message and store the FileContent FileContent *fileContent = currentFileContentToTransfer; - message->addContent(*fileContent); + message->addContent(fileContent); for (Content *content : message->getContents()) { if (content->getContentType() == ContentType::FileTransfer) { FileTransferContent *fileTransferContent = (FileTransferContent*)content; if (fileTransferContent->getFileContent() == fileContent) { - message->removeContent(*content); + message->removeContent(content); delete fileTransferContent; break; } @@ -821,7 +833,7 @@ void FileTransferChatMessageModifier::processResponseHeadersFromGetFile (const b } else { lWarning() << "No file transfer information for msg [" << this << "]: creating..."; FileContent *content = createFileTransferInformationFromHeaders(response); - message->addContent(*content); + message->addContent(content); } size_t body_size = 0; diff --git a/src/chat/modifier/multipart-chat-message-modifier.cpp b/src/chat/modifier/multipart-chat-message-modifier.cpp index 4abf91210..97081a4d0 100644 --- a/src/chat/modifier/multipart-chat-message-modifier.cpp +++ b/src/chat/modifier/multipart-chat-message-modifier.cpp @@ -120,7 +120,7 @@ ChatMessageModifier::Result MultipartChatMessageModifier::decode (const shared_p } content->setContentType(contentType); content->setBody(contentBody); - message->addContent(*content); + message->addContent(content); lInfo() << "Parsed and added content with type " << contentType.asString(); } diff --git a/src/content/file-content.cpp b/src/content/file-content.cpp index a2d1df851..8f6425474 100644 --- a/src/content/file-content.cpp +++ b/src/content/file-content.cpp @@ -36,7 +36,6 @@ public: string fileName; string filePath; size_t fileSize = 0; - string fileKey; }; // ----------------------------------------------------------------------------- @@ -48,7 +47,6 @@ FileContent::FileContent (const FileContent &src) : Content(*new FileContentPriv d->fileName = src.getFileName(); d->filePath = src.getFilePath(); d->fileSize = src.getFileSize(); - d->fileKey = src.getFileKey(); } FileContent::FileContent (FileContent &&src) : Content(*new FileContentPrivate) { @@ -56,7 +54,6 @@ FileContent::FileContent (FileContent &&src) : Content(*new FileContentPrivate) d->fileName = move(src.getPrivate()->fileName); d->filePath = move(src.getPrivate()->filePath); d->fileSize = move(src.getPrivate()->fileSize); - d->fileKey = move(src.getPrivate()->fileKey); } FileContent &FileContent::operator= (const FileContent &src) { @@ -66,7 +63,6 @@ FileContent &FileContent::operator= (const FileContent &src) { d->fileName = src.getFileName(); d->filePath = src.getFilePath(); d->fileSize = src.getFileSize(); - d->fileKey = src.getFileKey(); } return *this; @@ -78,7 +74,6 @@ FileContent &FileContent::operator= (FileContent &&src) { d->fileName = move(src.getPrivate()->fileName); d->filePath = move(src.getPrivate()->filePath); d->fileSize = move(src.getPrivate()->fileSize); - d->fileKey = move(src.getPrivate()->fileKey); return *this; } @@ -87,8 +82,7 @@ bool FileContent::operator== (const FileContent &content) const { return Content::operator==(content) && d->fileName == content.getFileName() && d->filePath == content.getFilePath() && - d->fileSize == content.getFileSize() && - d->fileKey == content.getFileKey(); + d->fileSize == content.getFileSize(); } void FileContent::setFileSize (size_t size) { @@ -121,16 +115,6 @@ const string &FileContent::getFilePath () const { return d->filePath; } -void FileContent::setFileKey (const string &key) { - L_D(); - d->fileKey = key; -} - -const string &FileContent::getFileKey () const { - L_D(); - return d->fileKey; -} - bool FileContent::isFile () const { return true; } diff --git a/src/content/file-content.h b/src/content/file-content.h index 79dfe5629..c46786dd5 100644 --- a/src/content/file-content.h +++ b/src/content/file-content.h @@ -48,9 +48,6 @@ public: void setFilePath (const std::string &path); const std::string &getFilePath () const; - void setFileKey (const std::string &key); - const std::string &getFileKey () const; - bool isFile () const override; private: diff --git a/src/content/file-transfer-content.cpp b/src/content/file-transfer-content.cpp index 628080c7c..d1d67c00d 100644 --- a/src/content/file-transfer-content.cpp +++ b/src/content/file-transfer-content.cpp @@ -38,6 +38,7 @@ public: string filePath; FileContent *fileContent = nullptr; size_t fileSize = 0; + std::vector fileKey; }; // ----------------------------------------------------------------------------- @@ -51,6 +52,7 @@ FileTransferContent::FileTransferContent (const FileTransferContent &src) : Cont d->filePath = src.getFilePath(); d->fileContent = src.getFileContent(); d->fileSize = src.getFileSize(); + d->fileKey = src.getFileKey(); } FileTransferContent::FileTransferContent (FileTransferContent &&src) : Content(*new FileTransferContentPrivate) { @@ -60,6 +62,7 @@ FileTransferContent::FileTransferContent (FileTransferContent &&src) : Content(* d->filePath = move(src.getPrivate()->filePath); d->fileContent = move(src.getPrivate()->fileContent); d->fileSize = move(src.getPrivate()->fileSize); + d->fileKey = move(src.getPrivate()->fileKey); } FileTransferContent &FileTransferContent::operator= (const FileTransferContent &src) { @@ -71,6 +74,7 @@ FileTransferContent &FileTransferContent::operator= (const FileTransferContent & d->filePath = src.getFilePath(); d->fileContent = src.getFileContent(); d->fileSize = src.getFileSize(); + d->fileKey = src.getFileKey(); } return *this; @@ -84,6 +88,7 @@ FileTransferContent &FileTransferContent::operator= (FileTransferContent &&src) d->filePath = move(src.getPrivate()->filePath); d->fileContent = move(src.getPrivate()->fileContent); d->fileSize = move(src.getPrivate()->fileSize); + d->fileKey = move(src.getPrivate()->fileKey); return *this; } @@ -146,6 +151,21 @@ size_t FileTransferContent::getFileSize () const { return d->fileSize; } +void FileTransferContent::setFileKey (const char *key, size_t size) { + L_D(); + d->fileKey = vector(key, key + size); +} + +const vector &FileTransferContent::getFileKey () const { + L_D(); + return d->fileKey; +} + +const char *FileTransferContent::getFileKeyAsString() const { + L_D(); + return d->fileKey.data(); +} + bool FileTransferContent::isFile () const { return false; } diff --git a/src/content/file-transfer-content.h b/src/content/file-transfer-content.h index 4abc4369f..da23053cb 100644 --- a/src/content/file-transfer-content.h +++ b/src/content/file-transfer-content.h @@ -20,6 +20,8 @@ #ifndef _L_FILE_TRANSFER_CONTENT_H_ #define _L_FILE_TRANSFER_CONTENT_H_ +#include + #include "content.h" // ============================================================================= @@ -55,6 +57,10 @@ public: void setFileSize (size_t size); size_t getFileSize () const; + void setFileKey (const char *key, size_t size); + const std::vector &getFileKey () const; + const char *getFileKeyAsString () const; + bool isFile () const override; private: diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp index 1e76e96ae..943426029 100644 --- a/src/db/main-db.cpp +++ b/src/db/main-db.cpp @@ -708,7 +708,7 @@ shared_ptr MainDbPrivate::selectConferenceChatMessageEvent ( string data; fetchContentAppData(session, *content, contentId, data); } - chatMessage->addContent(*content); + chatMessage->addContent(content); } } diff --git a/tester/cpim-tester.cpp b/tester/cpim-tester.cpp index a98ca133d..54a36b568 100644 --- a/tester/cpim-tester.cpp +++ b/tester/cpim-tester.cpp @@ -426,7 +426,7 @@ static void cpim_chat_message_modifier_base(bool_t use_multipart) { Content *content = new Content(); content->setContentType(ContentType::PlainText); content->setBody("Hello Part 2"); - marieMessage->addContent(*content); + marieMessage->addContent(content); } marieMessage->send(); diff --git a/tester/multipart-tester.cpp b/tester/multipart-tester.cpp index ad5d731f3..0472df0eb 100644 --- a/tester/multipart-tester.cpp +++ b/tester/multipart-tester.cpp @@ -53,13 +53,13 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, bool content->setContentType("video/mkv"); content->setFilePath(send_filepath); content->setFileName("sintel_trailer_opus_h264.mkv"); - marieMessage->addContent(*content); + marieMessage->addContent(content); bc_free(send_filepath); } else { Content *content = new Content(); content->setContentType(ContentType::PlainText); content->setBody("Hello Part 1"); - marieMessage->addContent(*content); + marieMessage->addContent(content); } if (second_file_transfer) { @@ -68,13 +68,13 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, bool content->setContentType("file/vcf"); content->setFilePath(send_filepath); content->setFileName("vcards.vcf"); - marieMessage->addContent(*content); + marieMessage->addContent(content); bc_free(send_filepath); } else { Content *content = new Content(); content->setContentType(ContentType::PlainText); content->setBody("Hello Part 2"); - marieMessage->addContent(*content); + marieMessage->addContent(content); } linphone_core_set_file_transfer_server(marie->lc,"https://www.linphone.org:444/lft.php");