From 56d9a0addaabf2cec78e1c82a9846997a3669736 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Tue, 25 Feb 2020 20:06:19 +0300 Subject: E2EE: Make building E2EE optional. Contributes to #369 Signed-off-by: Alexey Andreev --- CMakeLists.txt | 68 ++++++++++++++++++++++++++++------------------- lib/connection.cpp | 25 +++++++++++++++++ lib/connection.h | 2 ++ lib/encryptionmanager.cpp | 2 ++ lib/encryptionmanager.h | 2 ++ lib/room.cpp | 17 ++++++++++++ libquotient.pri | 11 +++++++- 7 files changed, 99 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9fc1ee6c..26394c9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,8 @@ set(API_VERSION "0.6") project(Quotient VERSION "${API_VERSION}.0" LANGUAGES CXX) option(${PROJECT_NAME}_INSTALL_TESTS "install quotest (former qmc-example) application" ON) +# https://github.com/quotient-im/libQuotient/issues/369 +option(${PROJECT_NAME}_ENABLE_E2EE "end-to-end encryption (E2EE) support" OFF) include(CheckCXXCompilerFlag) if (NOT WIN32) @@ -55,22 +57,26 @@ endif() find_package(Qt5 5.9 REQUIRED Network Gui Multimedia Test) get_filename_component(Qt5_Prefix "${Qt5_DIR}/../../../.." ABSOLUTE) -if ((NOT DEFINED USE_INTREE_LIBQOLM OR USE_INTREE_LIBQOLM) - AND EXISTS ${PROJECT_SOURCE_DIR}/3rdparty/libQtOlm/lib/utils.h) - add_subdirectory(3rdparty/libQtOlm EXCLUDE_FROM_ALL) - include_directories(3rdparty/libQtOlm) - if (NOT DEFINED USE_INTREE_LIBQOLM) - set (USE_INTREE_LIBQOLM 1) +if (${PROJECT_NAME}_ENABLE_E2EE) + if ((NOT DEFINED USE_INTREE_LIBQOLM OR USE_INTREE_LIBQOLM) + AND EXISTS ${PROJECT_SOURCE_DIR}/3rdparty/libQtOlm/lib/utils.h) + add_subdirectory(3rdparty/libQtOlm EXCLUDE_FROM_ALL) + include_directories(3rdparty/libQtOlm) + if (NOT DEFINED USE_INTREE_LIBQOLM) + set (USE_INTREE_LIBQOLM 1) + endif () endif () -endif () -if (NOT USE_INTREE_LIBQOLM) - find_package(QtOlm 0.1.0 REQUIRED) - if (NOT QtOlm_FOUND) - message( WARNING "libQtOlm not found; configuration will most likely fail.") - message( WARNING "Make sure you have installed libQtOlm development files") - message( WARNING "as a package or checked out the library sources in lib/.") - message( WARNING "See also BUILDING.md") + if (NOT USE_INTREE_LIBQOLM) + find_package(QtOlm 0.1.0 REQUIRED) + if (NOT QtOlm_FOUND) + message( WARNING "libQtOlm not found; configuration will most likely fail.") + message( WARNING "Make sure you have installed libQtOlm development files") + message( WARNING "as a package or checked out the library sources in lib/.") + message( WARNING "See also BUILDING.md") + endif () endif () +else () + message( WARNING "End-to-end encryption (E2EE) support is turned off.") endif () if (GTAD_PATH) @@ -108,18 +114,20 @@ if (ABS_API_DEF_PATH AND ABS_GTAD_PATH) endif () endif () find_package(Git) -if (USE_INTREE_LIBQOLM) - message( STATUS "Using in-tree libQtOlm") - if (GIT_FOUND) - execute_process(COMMAND - "${GIT_EXECUTABLE}" rev-parse -q HEAD - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/3rdparty/libQtOlm - OUTPUT_VARIABLE QTOLM_GIT_SHA1 - OUTPUT_STRIP_TRAILING_WHITESPACE) - message( STATUS " Library git SHA1: ${QTOLM_GIT_SHA1}") - endif (GIT_FOUND) -else () - message( STATUS "Using libQtOlm ${QtOlm_VERSION} at ${QtOlm_DIR}") +if (${PROJECT_NAME}_ENABLE_E2EE) + if (USE_INTREE_LIBQOLM) + message( STATUS "Using in-tree libQtOlm") + if (GIT_FOUND) + execute_process(COMMAND + "${GIT_EXECUTABLE}" rev-parse -q HEAD + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/3rdparty/libQtOlm + OUTPUT_VARIABLE QTOLM_GIT_SHA1 + OUTPUT_STRIP_TRAILING_WHITESPACE) + message( STATUS " Library git SHA1: ${QTOLM_GIT_SHA1}") + endif (GIT_FOUND) + else () + message( STATUS "Using libQtOlm ${QtOlm_VERSION} at ${QtOlm_DIR}") + endif () endif () message( STATUS "=============================================================================" ) message( STATUS ) @@ -224,6 +232,9 @@ endif() set(tests_SRCS tests/quotest.cpp) add_library(${PROJECT_NAME} ${lib_SRCS} ${api_SRCS}) +if (${PROJECT_NAME}_ENABLE_E2EE) + target_compile_definitions(${PROJECT_NAME} PUBLIC ${PROJECT_NAME}_E2EE_ENABLED) +endif() set_target_properties(${PROJECT_NAME} PROPERTIES VERSION "${PROJECT_VERSION}" SOVERSION ${API_VERSION} @@ -238,7 +249,10 @@ target_include_directories(${PROJECT_NAME} PUBLIC $ $ ) -target_link_libraries(${PROJECT_NAME} QtOlm Qt5::Core Qt5::Network Qt5::Gui Qt5::Multimedia) +if (${PROJECT_NAME}_ENABLE_E2EE) + target_link_libraries(${PROJECT_NAME} QtOlm) +endif() +target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Network Qt5::Gui Qt5::Multimedia) set(TEST_BINARY quotest) add_executable(${TEST_BINARY} ${tests_SRCS}) diff --git a/lib/connection.cpp b/lib/connection.cpp index 98c8a4bc..6ad24fba 100644 --- a/lib/connection.cpp +++ b/lib/connection.cpp @@ -19,7 +19,9 @@ #include "connection.h" #include "connectiondata.h" +#ifdef Quotient_E2EE_ENABLED #include "encryptionmanager.h" +#endif // Quotient_E2EE_ENABLED #include "room.h" #include "settings.h" #include "user.h" @@ -43,7 +45,9 @@ #include "jobs/mediathumbnailjob.h" #include "jobs/syncjob.h" +#ifdef Quotient_E2EE_ENABLED #include "account.h" // QtOlm +#endif // Quotient_E2EE_ENABLED #include #include @@ -107,7 +111,9 @@ public: GetCapabilitiesJob* capabilitiesJob = nullptr; GetCapabilitiesJob::Capabilities capabilities; +#ifdef Quotient_E2EE_ENABLED QScopedPointer encryptionManager; +#endif // Quotient_E2EE_ENABLED SyncJob* syncJob = nullptr; @@ -153,6 +159,10 @@ public: RoomEventPtr sessionDecryptMessage(const EncryptedEvent& encryptedEvent) { +#ifndef Quotient_E2EE_ENABLED + qCWarning(E2EE) << "End-to-end encryption (E2EE) support is turned off."; + return {}; +#else // Quotient_E2EE_ENABLED if (encryptedEvent.algorithm() != OlmV1Curve25519AesSha2AlgoKey) { return {}; @@ -208,6 +218,7 @@ public: } return decryptedEvent; +#endif // Quotient_E2EE_ENABLED } }; @@ -304,8 +315,12 @@ void Connection::doConnectToServer(const QString& user, const QString& password, connect(loginJob, &BaseJob::success, this, [this, loginJob] { d->connectWithToken(loginJob->userId(), loginJob->accessToken(), loginJob->deviceId()); +#ifndef Quotient_E2EE_ENABLED + qCWarning(E2EE) << "End-to-end encryption (E2EE) support is turned off."; +#else // Quotient_E2EE_ENABLED d->encryptionManager->uploadIdentityKeys(this); d->encryptionManager->uploadOneTimeKeys(this); +#endif // Quotient_E2EE_ENABLED }); connect(loginJob, &BaseJob::failure, this, [this, loginJob] { emit loginError(loginJob->errorString(), loginJob->rawDataSample()); @@ -362,12 +377,16 @@ void Connection::Private::connectWithToken(const QString& userId, qCDebug(MAIN) << "Using server" << data->baseUrl().toDisplayString() << "by user" << userId << "from device" << deviceId; AccountSettings accountSettings(userId); +#ifndef Quotient_E2EE_ENABLED + qCWarning(E2EE) << "End-to-end encryption (E2EE) support is turned off."; +#else // Quotient_E2EE_ENABLED encryptionManager.reset( new EncryptionManager(accountSettings.encryptionAccountPickle())); if (accountSettings.encryptionAccountPickle().isEmpty()) { accountSettings.setEncryptionAccountPickle( encryptionManager->olmAccountPickle()); } +#endif // Quotient_E2EE_ENABLED emit q->stateChanged(); emit q->connected(); q->reloadCapabilities(); @@ -594,6 +613,9 @@ void Connection::onSyncSuccess(SyncData&& data, bool fromCache) d->dcLocalAdditions.clear(); d->dcLocalRemovals.clear(); } +#ifndef Quotient_E2EE_ENABLED + qCWarning(E2EE) << "End-to-end encryption (E2EE) support is turned off."; +#else // Quotient_E2EE_ENABLED // handling m.room_key to-device encrypted event for (auto&& toDeviceEvent : data.takeToDeviceEvents()) { if (toDeviceEvent->type() == EncryptedEvent::typeId()) { @@ -645,6 +667,7 @@ void Connection::onSyncSuccess(SyncData&& data, bool fromCache) d->encryptionManager->updateOneTimeKeyCounts(this, deviceOneTimeKeysCount); } +#endif // Quotient_E2EE_ENABLED } void Connection::stopSync() @@ -1068,10 +1091,12 @@ QString Connection::deviceId() const { return d->data->deviceId(); } QByteArray Connection::accessToken() const { return d->data->accessToken(); } +#ifdef Quotient_E2EE_ENABLED QtOlm::Account* Connection::olmAccount() const { return d->encryptionManager->account(); } +#endif // Quotient_E2EE_ENABLED SyncJob* Connection::syncJob() const { return d->syncJob; } diff --git a/lib/connection.h b/lib/connection.h index e4109fd4..b57f0ca8 100644 --- a/lib/connection.h +++ b/lib/connection.h @@ -304,7 +304,9 @@ public: QString userId() const; QString deviceId() const; QByteArray accessToken() const; +#ifdef Quotient_E2EE_ENABLED QtOlm::Account* olmAccount() const; +#endif // Quotient_E2EE_ENABLED Q_INVOKABLE Quotient::SyncJob* syncJob() const; Q_INVOKABLE int millisToReconnect() const; diff --git a/lib/encryptionmanager.cpp b/lib/encryptionmanager.cpp index e2834c45..0895fae9 100644 --- a/lib/encryptionmanager.cpp +++ b/lib/encryptionmanager.cpp @@ -1,3 +1,4 @@ +#ifdef Quotient_E2EE_ENABLED #include "encryptionmanager.h" #include "connection.h" @@ -366,3 +367,4 @@ bool EncryptionManager::Private::oneTimeKeyShouldUpload() } return false; } +#endif // Quotient_E2EE_ENABLED diff --git a/lib/encryptionmanager.h b/lib/encryptionmanager.h index 8f346d37..5df15e83 100644 --- a/lib/encryptionmanager.h +++ b/lib/encryptionmanager.h @@ -1,3 +1,4 @@ +#ifdef Quotient_E2EE_ENABLED #pragma once #include @@ -43,3 +44,4 @@ private: }; } // namespace Quotient +#endif // Quotient_E2EE_ENABLED diff --git a/lib/room.cpp b/lib/room.cpp index ecb5a7ad..5a966ceb 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -69,9 +69,11 @@ #include #include +#ifdef Quotient_E2EE_ENABLED #include // QtOlm #include // QtOlm #include // QtOlm +#endif // Quotient_E2EE_ENABLED using namespace Quotient; using namespace QtOlm; @@ -342,6 +344,7 @@ public: QJsonObject toJson() const; +#ifdef Quotient_E2EE_ENABLED // A map from to QHash, QPair> groupSessionIndexRecord; // TODO: cache @@ -424,6 +427,7 @@ public: return decrypted.first; } +#endif // Quotient_E2EE_ENABLED private: using users_shortlist_t = std::array; @@ -1238,6 +1242,11 @@ const StateEventBase* Room::getCurrentState(const QString& evtType, RoomEventPtr Room::decryptMessage(const EncryptedEvent& encryptedEvent) { +#ifndef Quotient_E2EE_ENABLED + Q_UNUSED(encryptedEvent); + qCWarning(E2EE) << "End-to-end encryption (E2EE) support is turned off."; + return {}; +#else // Quotient_E2EE_ENABLED if (encryptedEvent.algorithm() == MegolmV1AesSha2AlgoKey) { QString decrypted = d->groupSessionDecryptMessage( encryptedEvent.ciphertext(), encryptedEvent.senderKey(), @@ -1252,10 +1261,17 @@ RoomEventPtr Room::decryptMessage(const EncryptedEvent& encryptedEvent) qCDebug(E2EE) << "Algorithm of the encrypted event with id" << encryptedEvent.id() << "is not for the current device"; return {}; +#endif // Quotient_E2EE_ENABLED } void Room::handleRoomKeyEvent(RoomKeyEvent* roomKeyEvent, QString senderKey) { +#ifndef Quotient_E2EE_ENABLED + Q_UNUSED(roomKeyEvent); + Q_UNUSED(senderKey); + qCWarning(E2EE) << "End-to-end encryption (E2EE) support is turned off."; + return; +#else // Quotient_E2EE_ENABLED if (roomKeyEvent->algorithm() != MegolmV1AesSha2AlgoKey) { qCWarning(E2EE) << "Ignoring unsupported algorithm" << roomKeyEvent->algorithm() << "in m.room_key event"; @@ -1265,6 +1281,7 @@ void Room::handleRoomKeyEvent(RoomKeyEvent* roomKeyEvent, QString senderKey) qCDebug(E2EE) << "added new inboundGroupSession:" << d->groupSessions.count(); } +#endif // Quotient_E2EE_ENABLED } int Room::joinedCount() const diff --git a/libquotient.pri b/libquotient.pri index 5a1aa7cc..95d8694b 100644 --- a/libquotient.pri +++ b/libquotient.pri @@ -8,7 +8,14 @@ win32-msvc* { QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter } -include(3rdparty/libQtOlm/libQtOlm.pri) +contains(DEFINES, Quotient_E2EE_ENABLED=.) { + contains(DEFINES, USE_INTREE_LIBQOLM=.) { + include(3rdparty/libQtOlm/libQtOlm.pri) + } else { + CONFIG += link_pkgconfig + PKGCONFIG += QtOlm + } +} SRCPATH = $$PWD/lib INCLUDEPATH += $$SRCPATH @@ -45,6 +52,7 @@ HEADERS += \ $$SRCPATH/events/directchatevent.h \ $$SRCPATH/events/encryptionevent.h \ $$SRCPATH/events/encryptedevent.h \ + $$SRCPATH/events/roomkeyevent.h \ $$SRCPATH/events/redactionevent.h \ $$SRCPATH/events/eventloader.h \ $$SRCPATH/events/roompowerlevelsevent.h \ @@ -93,6 +101,7 @@ SOURCES += \ $$SRCPATH/events/directchatevent.cpp \ $$SRCPATH/events/encryptionevent.cpp \ $$SRCPATH/events/encryptedevent.cpp \ + $$SRCPATH/events/roomkeyevent.cpp \ $$SRCPATH/events/roompowerlevelsevent.cpp \ $$SRCPATH/jobs/requestdata.cpp \ $$SRCPATH/jobs/basejob.cpp \ -- cgit v1.2.3