Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package lime for openSUSE:Factory checked in at 2023-01-04 17:53:28 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/lime (Old) and /work/SRC/openSUSE:Factory/.lime.new.1563 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "lime" Wed Jan 4 17:53:28 2023 rev:17 rq:1055796 version:5.2.6 Changes: -------- --- /work/SRC/openSUSE:Factory/lime/lime.changes 2022-10-24 11:13:39.479266828 +0200 +++ /work/SRC/openSUSE:Factory/.lime.new.1563/lime.changes 2023-01-04 17:53:42.598573186 +0100 @@ -1,0 +2,5 @@ +Wed Jan 4 11:26:06 UTC 2023 - Paolo Stivanin <i...@paolostivanin.com> + +- Update to 5.2.6 (no changelog). + +------------------------------------------------------------------- Old: ---- lime-5.1.64.tar.bz2 New: ---- lime-5.2.6.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ lime.spec ++++++ --- /var/tmp/diff_new_pack.gE6T58/_old 2023-01-04 17:53:43.094576110 +0100 +++ /var/tmp/diff_new_pack.gE6T58/_new 2023-01-04 17:53:43.102576156 +0100 @@ -1,7 +1,7 @@ # # spec file for package lime # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,7 +19,7 @@ %define soname liblime %define sover 0 Name: lime -Version: 5.1.64 +Version: 5.2.6 Release: 0 Summary: Instant Message End-to-End Encryption Library License: GPL-3.0-or-later @@ -37,8 +37,8 @@ BuildRequires: soci-sqlite3-devel = 4.0.2 %endif BuildRequires: chrpath -BuildRequires: pkgconfig(bctoolbox) >= 5.0.0 -BuildRequires: pkgconfig(belle-sip) >= 5.0.0 +BuildRequires: pkgconfig(bctoolbox) >= 5.2.0 +BuildRequires: pkgconfig(belle-sip) >= 5.2.0 %description LIME is an encryption library for one-to-one and group instant ++++++ lime-5.1.64.tar.bz2 -> lime-5.2.6.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-5.1.64/.github/ISSUE_TEMPLATE/bug_report.yml new/lime-5.2.6/.github/ISSUE_TEMPLATE/bug_report.yml --- old/lime-5.1.64/.github/ISSUE_TEMPLATE/bug_report.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/lime-5.2.6/.github/ISSUE_TEMPLATE/bug_report.yml 2022-11-09 23:33:57.000000000 +0100 @@ -0,0 +1,131 @@ +--- +name: Bug report +description: File a bug/issue +title: "[Bug]: " +labels: ["bug"] + +body: +- type: markdown + attributes: + value: '# Reminder' +- type: markdown + attributes: + value: | + The responses are provided by the **community** and, on a **best effort** basis, by some Belledonne Communications SARL engineers working on Linphone and its related projects. + The community means any people all around the world simply willing to participate to the discussions. + + Belledonne Communications SARL **disclaims any WARRANTY** that the content posted on github issues or mailing lists is technically correct. + Responses from Belledonne Communications SARL engineers shall be considered as individual contributions and shall not be seen as Belledonne Communications's official point of view or commitment. + + The Github issue tracker must be seen as a place for **collaboration**. Issues submitted should be of general interest, in the goal of improving the software. Consider that a **well documented** issue (with precise reproduction procedure, logs, stack trace if relevant, possibly a corrective patch) has a higher chance to receive interest and feedback from community members and Belledonne Communications' engineers. + + __Issues poorly documented, with no facts, or asking for debugging assistance for a custom app using Linphone's libraries, or for a modified version of Linphone are unlikely to receive any kind of response.__ + + People using Linphone or its related projects within the scope of their company job are invited to contact [Belledonne Communications](https://linphone.org/contact#content-bottom3) in order to obtain commercial support. + +- type: markdown + attributes: + value: | + # Well ordered issues are treated issues + **In our apps, the [Linphone-SDK](https://github.com/BelledonneCommunications/linphone-sdk) is used.** + Please report your issue here **ONLY** if you are sure that the origin of the error is in this module. + Otherwise, open an issue in the repository of the app you are using or in the Linphone-SDK, and we will move it to the related module. + +- type: markdown + attributes: + value: | + # Useful links + [Linphone.org](https://linphone.org) + [Linphone commercial contact](https://linphone.org/contact#content-bottom3) + Linphone Vulnerability/Security contact: vulnerabilit...@linphone.org + [Contributor agreement (to sign and to return to sa...@belledonne-communications.com for a pull request)](https://linphone.org/sites/default/files/bc-contributor-agreement_0.pdf) + +- type: textarea + attributes: + label: | + Context + description: | + - For which purpose do you use the project ? + - With which software/hardware it is integrated ? + - Did you use sip.linphone.org or a different SIP service (in this case specify which one and which version) ? + value: | + I use this project in a custom app running on Linux with the sip.linphone.org service for my company. I want to do a simple call between an Android phone and a Linux client. There is an error with a method of this project and I'm sure that I followed the documentation and double checked before posting. + validations: + required: true + +- type: textarea + attributes: + label: General information + description: | + Complete it multiple time if there are multiple devices involved. + Please note that the issue has more chances to be read if you report a bug seen in the latest version of the module. + + Ex: + - Device: [e.g. Samsung Note 20 Ultra] + - OS: [e.g. Android 11] + - Version of the App [e.g. 4.3.1] + - Version of the SDK [e.g 4.4.16] + value: | + - Device: + - OS: + - Version of the App: + - Version of the SDK: + validations: + required: true + +- type: textarea + attributes: + label: Expected behaviour + description: "A clear and concise description of what you expected to happen." + value: | + I wanted to do a simple call with the Linux client calling the Android phone. However, the phone doesn't ring when it is asleep. + validations: + required: true + +- type: textarea + attributes: + label: To Reproduce + description: "Steps to reproduce the behavior:" + value: | + 1. Go to '...' + 2. Click on '....' + 3. Scroll down to '....' + 4. See error + validations: + required: true + +- type: textarea + attributes: + label: 'Additional context' + value: Add any other context about the problem here. + +- type: markdown + attributes: + value: | + # Logs + ## Module logs + Enable debug logs in advanced section of the settings, restart the app, reproduce the issue and then go to About page, click on "Send logs" and copy/paste the link here. + If you doesn't have such an option, just provide the logs in attachments. + +- type: input + attributes: + label: 'SDK logs URL' + +- type: markdown + attributes: + value: | + ## Module crash logs + In case of a crash related to this module, please also provide the backtrace of the crash in attachments using adb logcat (Android) or the device console (iOS). + For desktop versions, you can get the backtrace from a core dump. + +- type: markdown + attributes: + value: | + # Screenshots + Please add screenshots in attachments to help us to understand your problem. + +- type: markdown + attributes: + value: | + # Pcap file + If this is a network issue, join a pcap file of your attempt in attachments (done with Wireshark or TCPDump, for example) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-5.1.64/CMakeLists.txt new/lime-5.2.6/CMakeLists.txt --- old/lime-5.1.64/CMakeLists.txt 2022-08-31 10:18:23.000000000 +0200 +++ new/lime-5.2.6/CMakeLists.txt 2022-11-09 23:33:57.000000000 +0100 @@ -27,6 +27,12 @@ cmake_minimum_required(VERSION 3.1) +# CMP0077 policy is required by Flexisip build. Remove it once the CMake required +# version is higer or equal to 3.13. +if (NOT CMAKE_VERSION VERSION_LESS 3.13) + cmake_policy(SET CMP0077 NEW) +endif () + option(ENABLE_SHARED "Build shared library." YES) option(ENABLE_STATIC "Build static library." YES) option(ENABLE_STRICT "Build with strict compile options." YES) @@ -39,6 +45,10 @@ option(ENABLE_JNI "Enable support of Java foreign function interface" NO) option(ENABLE_PACKAGE_SOURCE "Create 'package_source' target for source archive making (CMake >= 3.11)" OFF) +# Hidden non-cache options: +# * DISABLE_BC_PACKAGE_SEARCH: skip find_package() for every BC package (bctoolbox, ortp, etc.) +# * DISABLE_SOCI_PACKAGE_SEARCH: skip find_package() for Soci. + set (LANGUAGES_LIST CXX) if (ENABLE_C_INTERFACE) set (LANGUAGES_LIST ${LANGUAGES_LIST} C) @@ -47,7 +57,7 @@ set (LANGUAGES_LIST ${LANGUAGES_LIST} Java) endif() -project(lime VERSION 5.1.0 LANGUAGES ${LANGUAGES_LIST}) +project(lime VERSION 5.2.0 LANGUAGES ${LANGUAGES_LIST}) set(LIME_SO_VERSION "0") set(LIME_VERSION ${PROJECT_VERSION}) @@ -60,9 +70,19 @@ message(STATUS "Setting install rpath to ${CMAKE_INSTALL_RPATH}") endif() -find_package(bctoolbox 0.5.1 REQUIRED OPTIONAL_COMPONENTS tester) +if (NOT DISABLE_BC_PACKAGE_SEARCH) + find_package(bctoolbox 0.5.1 REQUIRED OPTIONAL_COMPONENTS tester) +endif () -find_package(Soci REQUIRED) +if (NOT DISABLE_SOCI_PACKAGE_SEARCH) + find_package(Soci REQUIRED) +else() + set(SOCI_FOUND YES) + set(SOCI_LIBRARIES soci_core) + if (APPLE OR ANDROID) + set(SOCI_sqlite3_PLUGIN soci_sqlite3) + endif() +endif() include_directories( include/ @@ -162,9 +182,11 @@ set(ConfigPackageLocation "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/cmake") -export(EXPORT ${EXPORT_TARGETS_NAME}Targets - FILE "${CMAKE_CURRENT_BINARY_DIR}/${EXPORT_TARGETS_NAME}Targets.cmake" -) +if (LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS) + export(EXPORT ${EXPORT_TARGETS_NAME}Targets + FILE "${CMAKE_CURRENT_BINARY_DIR}/${EXPORT_TARGETS_NAME}Targets.cmake" + ) +endif () configure_package_config_file(cmake/LimeConfig.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/${EXPORT_TARGETS_NAME}Config.cmake" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-5.1.64/docker/Belledonne.repo new/lime-5.2.6/docker/Belledonne.repo --- old/lime-5.1.64/docker/Belledonne.repo 2022-08-31 10:18:23.000000000 +0200 +++ new/lime-5.2.6/docker/Belledonne.repo 2022-11-09 23:33:57.000000000 +0100 @@ -1,6 +1,5 @@ [Belledonne] name=Belledonne -baseurl=https://linphone.org/snapshots/centos7 +baseurl=https://download.linphone.org/snapshots/centos7 enabled=1 gpgcheck=0 - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-5.1.64/include/lime/lime.hpp new/lime-5.2.6/include/lime/lime.hpp --- old/lime-5.1.64/include/lime/lime.hpp 2022-08-31 10:18:23.000000000 +0200 +++ new/lime-5.2.6/include/lime/lime.hpp 2022-11-09 23:33:57.000000000 +0100 @@ -22,6 +22,7 @@ #include <memory> //smart ptrs #include <unordered_map> #include <vector> +#include <list> #include <functional> #include <string> #include <mutex> @@ -324,6 +325,7 @@ /** * @brief get the status of a peer device: unknown, untrusted, trusted, unsafe + * device's Id matching a local account are always considered as trusted * * @param[in] peerDeviceId The device Id of peer, shall be its GRUU * @@ -332,6 +334,17 @@ lime::PeerDeviceStatus get_peerDeviceStatus(const std::string &peerDeviceId); /** + * @brief get the lowest status of a list of peer device + * The order, from low to up, is : unsafe, unknown, untrusted, trusted + * device's Id matching a local account are always considered as trusted + * + * @param[in] peerDeviceIds The list of device Ids to consider, shall be a list of GRUUs + * + * @return the lowest status from the list of these devices + */ + lime::PeerDeviceStatus get_peerDeviceStatus(const std::list<std::string> &peerDeviceIds); + + /** * @brief checks if a device iD exists in the local users * * @param[in] deviceId The device Id to check diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-5.1.64/src/CMakeLists.txt new/lime-5.2.6/src/CMakeLists.txt --- old/lime-5.1.64/src/CMakeLists.txt 2022-08-31 10:18:23.000000000 +0200 +++ new/lime-5.2.6/src/CMakeLists.txt 2022-11-09 23:33:57.000000000 +0100 @@ -81,7 +81,7 @@ set_target_properties(lime PROPERTIES FRAMEWORK TRUE MACOSX_FRAMEWORK_IDENTIFIER com.belledonne-communications.lime - MACOSX_FRAMEWORK_INFO_PLIST "${CMAKE_SOURCE_DIR}/build/osx/Info.plist.in" + MACOSX_FRAMEWORK_INFO_PLIST "${PROJECT_SOURCE_DIR}/build/osx/Info.plist.in" PUBLIC_HEADER "${LIME_HEADER_FILES}" ) endif() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-5.1.64/src/lime.cpp new/lime-5.2.6/src/lime.cpp --- old/lime-5.1.64/src/lime.cpp 2022-08-31 10:18:23.000000000 +0200 +++ new/lime-5.2.6/src/lime.cpp 2022-11-09 23:33:57.000000000 +0100 @@ -277,7 +277,7 @@ std::vector<std::shared_ptr<DR<Curve>>> DRSessions{}; // load in DRSessions all the session found in cache for this peer device, except the one with id db_sessionIdInCache(is ignored if 0) as we already tried it get_DRSessions(senderDeviceId, db_sessionIdInCache, DRSessions); - LIME_LOGD<<"decrypt from "<<senderDeviceId<<" to "<<recipientUserId<<" : found "<<DRSessions.size()<<" sessions in DB"; + LIME_LOGI<<"decrypt from "<<senderDeviceId<<" to "<<recipientUserId<<" : found "<<DRSessions.size()<<" sessions in DB"; auto usedDRSession = decryptMessage<Curve>(senderDeviceId, m_selfDeviceId, recipientUserId, DRSessions, DRmessage, cipherMessage, plainMessage); if (usedDRSession != nullptr) { // we manage to decrypt with a session m_DR_sessions_cache[senderDeviceId] = std::move(usedDRSession); // store it in cache @@ -287,6 +287,7 @@ // No luck yet, is this message holds a X3DH header - if no we must give up std::vector<uint8_t> X3DH_initMessage{}; if (!double_ratchet_protocol::parseMessage_get_X3DHinit<Curve>(DRmessage, X3DH_initMessage)) { + LIME_LOGE<<"Fail to decrypt: No DR session found and no X3DH init message"; return lime::PeerDeviceStatus::fail; } @@ -305,6 +306,7 @@ m_DR_sessions_cache[senderDeviceId] = std::move(DRSessions.front()); return senderDeviceStatus; } + LIME_LOGE<<"Fail to decrypt: Newly created DR session failed to decrypt the message"; return lime::PeerDeviceStatus::fail; } @@ -405,37 +407,33 @@ /* open DB */ auto localStorage = std::unique_ptr<lime::Db>(new lime::Db(dbFilename, db_mutex)); // create as unique ptr, ownership is then passed to the Lime structure when instanciated - try { - //instanciate the correct Lime object - switch (curve) { - case lime::CurveId::c25519 : + //instanciate the correct Lime object + switch (curve) { + case lime::CurveId::c25519 : #ifdef EC25519_ENABLED - { - /* constructor will insert user in Db, if already present, raise an exception*/ - auto lime_ptr = std::make_shared<Lime<C255>>(std::move(localStorage), deviceId, url, X3DH_post_data); - lime_ptr->publish_user(callback, OPkInitialBatchSize); - return lime_ptr; - } + { + /* constructor will insert user in Db, if already present, raise an exception*/ + auto lime_ptr = std::make_shared<Lime<C255>>(std::move(localStorage), deviceId, url, X3DH_post_data); + lime_ptr->publish_user(callback, OPkInitialBatchSize); + return lime_ptr; + } #endif - break; + break; - case lime::CurveId::c448 : + case lime::CurveId::c448 : #ifdef EC448_ENABLED - { - auto lime_ptr = std::make_shared<Lime<C448>>(std::move(localStorage), deviceId, url, X3DH_post_data); - lime_ptr->publish_user(callback, OPkInitialBatchSize); - return lime_ptr; - } + { + auto lime_ptr = std::make_shared<Lime<C448>>(std::move(localStorage), deviceId, url, X3DH_post_data); + lime_ptr->publish_user(callback, OPkInitialBatchSize); + return lime_ptr; + } #endif - break; + break; - case lime::CurveId::unset : - default: // asking for an unsupported type - throw BCTBX_EXCEPTION << "Cannot create lime user "<<deviceId;//<<". Unsupported curve (id <<"static_cast<uint8_t>(curve)") requested"; + case lime::CurveId::unset : + default: // asking for an unsupported type + throw BCTBX_EXCEPTION << "Cannot create lime user "<<deviceId;//<<". Unsupported curve (id <<"static_cast<uint8_t>(curve)") requested"; break; - } - } catch (BctbxException &) { - throw; // just forward the exceptions raised by constructor } return nullptr; }; @@ -478,28 +476,23 @@ #endif - try { - switch (curve) { - case lime::CurveId::c25519 : + switch (curve) { + case lime::CurveId::c25519 : #ifdef EC25519_ENABLED - return std::make_shared<Lime<C255>>(std::move(localStorage), deviceId, x3dh_server_url, X3DH_post_data, Uid); + return std::make_shared<Lime<C255>>(std::move(localStorage), deviceId, x3dh_server_url, X3DH_post_data, Uid); #endif - break; + break; - case lime::CurveId::c448 : + case lime::CurveId::c448 : #ifdef EC448_ENABLED - - return std::make_shared<Lime<C448>>(std::move(localStorage), deviceId, x3dh_server_url, X3DH_post_data, Uid); + return std::make_shared<Lime<C448>>(std::move(localStorage), deviceId, x3dh_server_url, X3DH_post_data, Uid); #endif - break; + break; - case lime::CurveId::unset : - default: // asking for an unsupported type - throw BCTBX_EXCEPTION << "Cannot create load user "<<deviceId; - break; - } - } catch (BctbxException &) { - throw; + case lime::CurveId::unset : + default: // asking for an unsupported type + throw BCTBX_EXCEPTION << "Cannot create load user "<<deviceId; + break; } return nullptr; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-5.1.64/src/lime_double_ratchet.cpp new/lime-5.2.6/src/lime_double_ratchet.cpp --- old/lime-5.1.64/src/lime_double_ratchet.cpp 2022-08-31 10:18:23.000000000 +0200 +++ new/lime-5.2.6/src/lime_double_ratchet.cpp 2022-11-09 23:33:57.000000000 +0100 @@ -575,9 +575,12 @@ recipients[i].DRSession->ratchetEncrypt(randomSeed, std::move(recipientAD), recipients[i].DRmessage, payloadDirectEncryption); } } - } catch (...) { + } catch (BctbxException const &e) { localStorage->rollback_transaction(); - throw; + throw BCTBX_EXCEPTION << "Encryption to recipients failed : "<<e.str(); + } catch (exception const &e) { + localStorage->rollback_transaction(); + throw BCTBX_EXCEPTION << "Encryption to recipients failed : "<<e.what(); } // ratchet encrypt write to the db, to avoid a serie of transaction, manage it outside of the loop diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-5.1.64/src/lime_localStorage.cpp new/lime-5.2.6/src/lime_localStorage.cpp --- old/lime-5.1.64/src/lime_localStorage.cpp 2022-08-31 10:18:23.000000000 +0200 +++ new/lime-5.2.6/src/lime_localStorage.cpp 2022-11-09 23:33:57.000000000 +0100 @@ -350,7 +350,7 @@ return; } - LIME_LOGD << "Set status trusted for peer device "<<peerDeviceId; + LIME_LOGI << "Set status trusted for peer device "<<peerDeviceId; const uint8_t statusInteger = static_cast<uint8_t>(lime::PeerDeviceStatus::trusted); @@ -393,7 +393,7 @@ LIME_LOGE << "Trying to set a status for peer device "<<peerDeviceId<<" without providing a Ik which is not acceptable (differs from unsafe or untrusted)"; return; } - LIME_LOGD << "Set status "<<((status==lime::PeerDeviceStatus::unsafe)?"unsafe":"untrusted")<<" for peer device "<<peerDeviceId; + LIME_LOGI << "Set status "<<((status==lime::PeerDeviceStatus::unsafe)?"unsafe":"untrusted")<<" for peer device "<<peerDeviceId; uint8_t statusInteger = static_cast<uint8_t>(status); @@ -436,6 +436,7 @@ /** * @brief get the status of a peer device: unknown, untrusted, trusted, unsafe + * device's Id matching a local account are always considered as trusted * * @param[in] peerDeviceId The device Id of peer, shall be its GRUU * @@ -443,6 +444,9 @@ */ lime::PeerDeviceStatus Db::get_peerDeviceStatus(const std::string &peerDeviceId) { std::lock_guard<std::recursive_mutex> lock(*m_db_mutex); + if (is_localUser(peerDeviceId)) { + return lime::PeerDeviceStatus::trusted; + } int status; sql<<"SELECT Status FROM Lime_PeerDevices WHERE DeviceId = :peerDeviceId LIMIT 1;", into(status), use(peerDeviceId); if (sql.got_data()) { // Found it @@ -463,6 +467,83 @@ } /** + * @brief get the status of a list of peer device: unknown, untrusted, trusted, unsafe + * and return the lowest found, crescent order being unsafe, unknown, untrusted, trusted + * device's Id matching a local account are always considered as trusted + * + * @param[in] peerDeviceIds A list of devices Id, shall be their GRUUs + * + * @return the lowest status found in the list + */ +lime::PeerDeviceStatus Db::get_peerDeviceStatus(const std::list<std::string> &peerDeviceIds) { + + // If there is nothing to search, just return unknown + if (peerDeviceIds.empty()) return lime::PeerDeviceStatus::unknown; + + std::lock_guard<std::recursive_mutex> lock(*m_db_mutex); + bool have_untrusted=false; + size_t found_devices_count = 0; + + // create a comma separated list of device id for the IN parameter in the SQL query as SOCI does not handle a list of it + std::string sqlString_allDevicesId{""}; + for (const auto &peerDeviceId : peerDeviceIds) { + sqlString_allDevicesId.append("'").append(peerDeviceId).append("',"); + } + sqlString_allDevicesId.pop_back(); // remove the last ',' + // Get local devices among the list + rowset<std::string> rs_localDevices = (sql.prepare << "SELECT l.UserId FROM lime_LocalUsers as l WHERE l.UserId IN ("<<sqlString_allDevicesId<<");"); + std::string sqlString_peerDeviceQuery{"SELECT d.Status FROM lime_PeerDevices as d WHERE d.DeviceId IN ("}; + + std::list<std::string> nolocalDevices = peerDeviceIds; // copy original list + // remove local users from the list: they are all considered as trusted + for (const std::string &localDevice : rs_localDevices) { + nolocalDevices.remove(localDevice); + found_devices_count++; + } + + if (found_devices_count > 0) { + // there are local devices, we must use the list without local ones as they can be present both in localUser and PeerDevices + // but in that case they must be ignored in the second list as they always are considered as trusted + std::string sqlString_peerDevicesId{""}; + for (const auto &peerDeviceId : nolocalDevices) { + sqlString_peerDevicesId.append("'").append(peerDeviceId).append("',"); + } + if (!sqlString_peerDevicesId.empty()) { + sqlString_peerDevicesId.pop_back(); // remove the last ',' + } + sqlString_peerDeviceQuery.append(sqlString_peerDevicesId); + } else { + // there is no local device in the list, fetch using the whole list + sqlString_peerDeviceQuery.append(sqlString_allDevicesId); + } + + rowset<int> rs_devicesStatus = (sql.prepare << sqlString_peerDeviceQuery << ");"); + for (const int status : rs_devicesStatus) { + found_devices_count++; + switch (status) { + case static_cast<uint8_t>(lime::PeerDeviceStatus::trusted) : + // Do nothing for trusted as it is the higher status we can get + break; + case static_cast<uint8_t>(lime::PeerDeviceStatus::untrusted) : + have_untrusted=true; + break; + case static_cast<uint8_t>(lime::PeerDeviceStatus::unsafe) : + return lime::PeerDeviceStatus::unsafe; // if unsafe is found, it can't get worse, return it + default : // something is wrong with the local storage + throw BCTBX_EXCEPTION << "Trying to get the status for peer devices "<<sqlString_allDevicesId<<" but get an unexpected value "<<status<<" from local storage"; + } + } + + if (found_devices_count != peerDeviceIds.size()) { + return lime::PeerDeviceStatus::unknown; // we are missing some, return unknown + } + + if (have_untrusted) return lime::PeerDeviceStatus::untrusted; + return lime::PeerDeviceStatus::trusted; +} + + +/** * @brief checks if a device Id exists in the local users table * * @param[in] deviceId The device Id @@ -792,11 +873,11 @@ m_localStorage->sql<<"DELETE from DR_MSk_DHr WHERE DHid = :DHid;", use(m_usedDHid); } } - } catch (...) { + } catch (exception const &e) { if (commit) { m_localStorage->sql.rollback(); } - throw; + throw BCTBX_EXCEPTION << "Lime save session in DB failed. DB backend says : "<<e.what(); } if (commit) { @@ -1233,7 +1314,6 @@ break; default : // something is wrong with the local storage throw BCTBX_EXCEPTION << "Trying to get the status for peer device "<<deviceId<<" but get an unexpected value "<<status<<" from local storage"; - } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-5.1.64/src/lime_localStorage.hpp new/lime-5.2.6/src/lime_localStorage.hpp --- old/lime-5.1.64/src/lime_localStorage.hpp 2022-08-31 10:18:23.000000000 +0200 +++ new/lime-5.2.6/src/lime_localStorage.hpp 2022-11-09 23:33:57.000000000 +0100 @@ -57,6 +57,7 @@ void set_peerDeviceStatus(const std::string &peerDeviceId, const std::vector<uint8_t> &Ik, lime::PeerDeviceStatus status); void set_peerDeviceStatus(const std::string &peerDeviceId, lime::PeerDeviceStatus status); lime::PeerDeviceStatus get_peerDeviceStatus(const std::string &peerDeviceId); + lime::PeerDeviceStatus get_peerDeviceStatus(const std::list<std::string> &peerDeviceIds); bool is_localUser(const std::string &deviceId); void delete_peerDevice(const std::string &peerDeviceId); template <typename Curve> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-5.1.64/src/lime_manager.cpp new/lime-5.2.6/src/lime_manager.cpp --- old/lime-5.1.64/src/lime_manager.cpp 2022-08-31 10:18:23.000000000 +0200 +++ new/lime-5.2.6/src/lime_manager.cpp 2022-11-09 23:33:57.000000000 +0100 @@ -221,6 +221,13 @@ return localStorage->get_peerDeviceStatus(peerDeviceId); } + lime::PeerDeviceStatus LimeManager::get_peerDeviceStatus(const std::list<std::string> &peerDeviceIds) { + // open local DB + auto localStorage = std::unique_ptr<lime::Db>(new lime::Db(m_db_access, m_db_mutex)); + + return localStorage->get_peerDeviceStatus(peerDeviceIds); + } + bool LimeManager::is_localUser(const std::string &deviceId) { // open local DB auto localStorage = std::unique_ptr<lime::Db>(new lime::Db(m_db_access, m_db_mutex)); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-5.1.64/src/lime_x3dh_protocol.cpp new/lime-5.2.6/src/lime_x3dh_protocol.cpp --- old/lime-5.1.64/src/lime_x3dh_protocol.cpp 2022-08-31 10:18:23.000000000 +0200 +++ new/lime-5.2.6/src/lime_x3dh_protocol.cpp 2022-11-09 23:33:57.000000000 +0100 @@ -158,7 +158,7 @@ * @return a vector holding the well formed header ready to be expanded to include the message body */ static std::vector<uint8_t> X3DH_makeHeader(const x3dh_message_type message_type, const lime::CurveId curve) noexcept{ - LIME_LOGD<<hex<<setfill('0')<<"Build outgoing X3DH message:"<<endl + LIME_LOGI<<hex<<setfill('0')<<"Build outgoing X3DH message:"<<endl <<" Protocol Version is 0x"<<setw(2)<<static_cast<unsigned int>(X3DH_protocolVersion)<<endl <<" Message Type is "<<x3dh_messageTypeString(message_type)<<" (0x"<<setw(2)<<static_cast<unsigned int>(message_type)<<")"<<endl <<" CurveId is 0x"<<setw(2)<<static_cast<unsigned int>(curve); @@ -234,7 +234,7 @@ }); } - LIME_LOGD<<message_trace.str(); + LIME_LOGI<<message_trace.str(); } /** @@ -286,7 +286,7 @@ message_trace << setw(2) << i << ", "; }); message_trace << endl <<" SPk Id: 0x"<< setw(8) << static_cast<unsigned int>(SPk_id); - LIME_LOGD<<message_trace.str(); + LIME_LOGI<<message_trace.str(); } /** @@ -336,7 +336,7 @@ } //debug trace - LIME_LOGD<<message_trace.str(); + LIME_LOGI<<message_trace.str(); } /** @@ -382,7 +382,7 @@ } //debug trace - LIME_LOGD<<message_trace.str(); + LIME_LOGI<<message_trace.str(); } /** @@ -544,7 +544,7 @@ error_code = x3dh_error_code::unknown_error_code; } } - LIME_LOGD<<message_trace.str()<<endl<<" Valid Incoming X3DH message"; + LIME_LOGI<<message_trace.str()<<endl<<" Valid Incoming X3DH message"; return true; } @@ -699,7 +699,7 @@ peersBundle.emplace_back(std::move(deviceId), Ik, SPk, SPk_id, SPk_sig); } } - LIME_LOGD<<message_trace.str(); + LIME_LOGI<<message_trace.str(); return true; } @@ -747,7 +747,7 @@ selfOPkIds.push_back(OPk_id); message_trace <<" OPk Id: 0x"<< setw(8) << static_cast<unsigned int>(OPk_id)<<endl; } - LIME_LOGD<<message_trace.str(); + LIME_LOGI<<message_trace.str(); return true; } @@ -811,7 +811,7 @@ lime::x3dh_protocol::x3dh_error_code error_code{x3dh_protocol::x3dh_error_code::unset_error_code}; // check message validity, extract type and error code(if any) - LIME_LOGD<<"Parse incoming X3DH message for user "<< this->m_selfDeviceId; + LIME_LOGI<<"Parse incoming X3DH message for user "<< this->m_selfDeviceId; if (!x3dh_protocol::parseMessage_getType<Curve>(responseBody, message_type, error_code, callback)) { cleanUserData(userData); return; @@ -973,7 +973,7 @@ */ template <typename Curve> void Lime<Curve>::postToX3DHServer(std::shared_ptr<callbackUserData<Curve>> userData, const std::vector<uint8_t> &message) { - LIME_LOGD<<"Post outgoing X3DH message from user "<<this->m_selfDeviceId; + LIME_LOGI<<"Post outgoing X3DH message from user "<<this->m_selfDeviceId; // copy capture the shared_ptr to userData m_X3DH_post_data(m_X3DH_Server_URL, m_selfDeviceId, message, [userData](int responseCode, const std::vector<uint8_t> &responseBody) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lime-5.1.64/tester/lime_lime-tester.cpp new/lime-5.2.6/tester/lime_lime-tester.cpp --- old/lime-5.1.64/tester/lime_lime-tester.cpp 2022-08-31 10:18:23.000000000 +0200 +++ new/lime-5.2.6/tester/lime_lime-tester.cpp 2022-11-09 23:33:57.000000000 +0100 @@ -1072,6 +1072,9 @@ auto daveDeviceId = lime_tester::makeRandomDeviceName("dave."); daveManager->create_user(*daveDeviceId, x3dh_server_url, curve, lime_tester::OPkInitialBatchSize, callback); + // This is a list of all device's id to test getting status of a device list + std::list<std::string> allDevicesId{*aliceDeviceId, *bobDeviceId, *carolDeviceId, *daveDeviceId}; + expected_success += 4; BC_ASSERT_TRUE(lime_tester::wait_for(bc_stack,&counters.operation_success, expected_success,lime_tester::wait_for_timeout)); @@ -1109,6 +1112,10 @@ BC_ASSERT_TRUE(daveManager->get_peerDeviceStatus(*aliceDeviceId) == lime::PeerDeviceStatus::unknown); BC_ASSERT_TRUE(aliceManager->get_peerDeviceStatus(*daveDeviceId) == lime::PeerDeviceStatus::unknown); + // Now Alice's storage has Bob as trusted and Carol as untrusted and does not know Dave + // Getting status for all of them as a list shall return unknown (alice considers herself as trusted) + BC_ASSERT_TRUE(aliceManager->get_peerDeviceStatus(allDevicesId) == lime::PeerDeviceStatus::unknown); + // Alice encrypts a message for Bob, Carol and Dave auto aliceRecipients = make_shared<std::vector<RecipientData>>(); aliceRecipients->emplace_back(*bobDeviceId); @@ -1124,6 +1131,10 @@ BC_ASSERT_TRUE((*aliceRecipients)[1].peerStatus == lime::PeerDeviceStatus::untrusted); // recipient 1 is Carol: untrusted BC_ASSERT_TRUE((*aliceRecipients)[2].peerStatus == lime::PeerDeviceStatus::unknown); // recipient 2 is Dave: unknown + // Now Alice's storage has Bob as trusted and Carol as untrusted and Dave untrusted + // Getting status for all of them as a list shall return untrusted + BC_ASSERT_TRUE(aliceManager->get_peerDeviceStatus(allDevicesId) == lime::PeerDeviceStatus::untrusted); + // recipients decrypt std::vector<uint8_t> receivedMessage{}; // bob shall return trusted @@ -1182,6 +1193,25 @@ receivedMessageString = std::string{receivedMessage.begin(), receivedMessage.end()}; BC_ASSERT_TRUE(receivedMessageString == lime_tester::messages_pattern[1]); + // set Dave's status to trusted in Alice's cache and query the group status, it still shall be untrusted + aliceManager->set_peerDeviceStatus(*daveDeviceId, daveIk, lime::PeerDeviceStatus::trusted); + BC_ASSERT_TRUE(aliceManager->get_peerDeviceStatus(allDevicesId) == lime::PeerDeviceStatus::untrusted); + + // now also set Carol as trusted, the group status shall be trusted + aliceManager->set_peerDeviceStatus(*carolDeviceId, carolIk, lime::PeerDeviceStatus::trusted); + BC_ASSERT_TRUE(aliceManager->get_peerDeviceStatus(allDevicesId) == lime::PeerDeviceStatus::trusted); + + // Turn Dave to unsafe, the group status shall be unsafe + aliceManager->set_peerDeviceStatus(*daveDeviceId, daveIk, lime::PeerDeviceStatus::unsafe); + BC_ASSERT_TRUE(aliceManager->get_peerDeviceStatus(allDevicesId) == lime::PeerDeviceStatus::unsafe); + + // Remove Carol from Alice cache, Alice is unknown but the group is still unsafe + aliceManager->delete_peerDevice(*carolDeviceId); + BC_ASSERT_TRUE(aliceManager->get_peerDeviceStatus(*carolDeviceId) == lime::PeerDeviceStatus::unknown); + BC_ASSERT_TRUE(aliceManager->get_peerDeviceStatus(*aliceDeviceId) == lime::PeerDeviceStatus::trusted); // query herself as peer, should be trusted + BC_ASSERT_TRUE(aliceManager->get_peerDeviceStatus(std::list<std::string>{*aliceDeviceId}) == lime::PeerDeviceStatus::trusted); // query herself as peer, should be trusted + BC_ASSERT_TRUE(aliceManager->get_peerDeviceStatus(allDevicesId) == lime::PeerDeviceStatus::unsafe); + if (cleanDatabase) { aliceManager->delete_user(*aliceDeviceId, callback); bobManager->delete_user(*bobDeviceId, callback); @@ -2913,7 +2943,8 @@ BC_ASSERT_TRUE(receivedMessageStringAlice == lime_tester::messages_pattern[3]); receivedMessage.clear(); BC_ASSERT_FALSE(lime_tester::DR_message_holdsX3DHInit((*recipients)[1].DRmessage)); // bob.d1 to bob.d2 already set up the DR Session, we shall not have any X3DH message here - BC_ASSERT_TRUE(bobManager->decrypt(*bobDevice1, "alice", *bobDevice2, (*recipients)[1].DRmessage, *cipherMessage, receivedMessage) == lime::PeerDeviceStatus::untrusted); + // bob.d1 and bob.d2 share the same db, like two accounts on the same device, so for bob.d1, bob.d2 status is always trusted. + BC_ASSERT_TRUE(bobManager->decrypt(*bobDevice1, "alice", *bobDevice2, (*recipients)[1].DRmessage, *cipherMessage, receivedMessage) == lime::PeerDeviceStatus::trusted); receivedMessageStringBob = std::string{receivedMessage.begin(), receivedMessage.end()}; BC_ASSERT_TRUE(receivedMessageStringBob == lime_tester::messages_pattern[3]);