| @@ -1,26 +0,0 @@ | ||
| -if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") | ||
| - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \ | ||
| - -Wall \ | ||
| - -Wextra \ | ||
| - -Werror \ | ||
| - -pipe \ | ||
| - -Wno-unused-function \ | ||
| - -pedantic \ | ||
| - -Wunreachable-code") | ||
| - | ||
| - if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") | ||
| - execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) | ||
| - | ||
| - if (GCC_VERSION VERSION_GREATER 4.9) | ||
| - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always" ) | ||
| - endif() | ||
| - endif() | ||
| - | ||
| - if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") | ||
| - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always" ) | ||
| - endif() | ||
| -endif() | ||
| - | ||
| -if(NOT APPLE AND NOT MSVC) | ||
| - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") | ||
| -endif() |
| @@ -1,33 +0,0 @@ | ||
| -include(ExternalProject) | ||
| - | ||
| -# | ||
| -# Build matrix-structs. | ||
| -# | ||
| - | ||
| -set(THIRD_PARTY_ROOT ${CMAKE_SOURCE_DIR}/.third-party) | ||
| -set(MATRIX_STRUCTS_ROOT ${THIRD_PARTY_ROOT}/matrix_structs) | ||
| -set(MATRIX_STRUCTS_INCLUDE_DIR ${MATRIX_STRUCTS_ROOT}/include) | ||
| -set(MATRIX_STRUCTS_LIBRARY matrix_structs) | ||
| - | ||
| -link_directories(${MATRIX_STRUCTS_ROOT}) | ||
| - | ||
| -set(WINDOWS_FLAGS "") | ||
| - | ||
| -if(MSVC) | ||
| - set(WINDOWS_FLAGS "-DCMAKE_GENERATOR_PLATFORM=x64") | ||
| -endif() | ||
| - | ||
| -ExternalProject_Add( | ||
| - MatrixStructs | ||
| - | ||
| - GIT_REPOSITORY https://github.com/mujx/matrix-structs | ||
| - GIT_TAG 5e57c2385a79b6629d1998fec4a7c0baee23555e | ||
| - | ||
| - BUILD_IN_SOURCE 1 | ||
| - SOURCE_DIR ${MATRIX_STRUCTS_ROOT} | ||
| - CONFIGURE_COMMAND ${CMAKE_COMMAND} | ||
| - -DCMAKE_BUILD_TYPE=Release ${MATRIX_STRUCTS_ROOT} | ||
| - ${WINDOWS_FLAGS} | ||
| - BUILD_COMMAND ${CMAKE_COMMAND} --build ${MATRIX_STRUCTS_ROOT} --config Release | ||
| - INSTALL_COMMAND "" | ||
| -) |
| @@ -0,0 +1,82 @@ | ||
| +cmake_minimum_required(VERSION 3.1) | ||
| +project(NHEKO_DEPS) | ||
| + | ||
| +# Point CMake at any custom modules we may ship | ||
| +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") | ||
| + | ||
| +if(NOT CMAKE_BUILD_TYPE) | ||
| + set(CMAKE_BUILD_TYPE Release) | ||
| +endif() | ||
| + | ||
| +set(DEPS_INSTALL_DIR "${CMAKE_BINARY_DIR}/usr" | ||
| + CACHE PATH "Dependencies install directory.") | ||
| +set(DEPS_BIN_DIR "${DEPS_INSTALL_DIR}/bin" | ||
| + CACHE PATH "Dependencies binary install directory.") | ||
| +set(DEPS_LIB_DIR "${DEPS_INSTALL_DIR}/lib" | ||
| + CACHE PATH "Dependencies library install directory.") | ||
| +set(DEPS_BUILD_DIR "${CMAKE_BINARY_DIR}/build" | ||
| + CACHE PATH "Dependencies build directory.") | ||
| +set(DEPS_DOWNLOAD_DIR "${DEPS_BUILD_DIR}/downloads" | ||
| + CACHE PATH "Dependencies download directory.") | ||
| + | ||
| +option(USE_BUNDLED "Use bundled dependencies." ON) | ||
| + | ||
| +option(USE_BUNDLED_BOOST "Use the bundled version of Boost." ${USE_BUNDLED}) | ||
| +option(USE_BUNDLED_SPDLOG "Use the bundled version of spdlog." ${USE_BUNDLED}) | ||
| +option(USE_BUNDLED_OLM "Use the bundled version of libolm." ${USE_BUNDLED}) | ||
| +option(USE_BUNDLED_MATRIX_STRUCTS "Use the bundled version of matrix-structs." | ||
| + ${USE_BUNDLED}) | ||
| +option(USE_BUNDLED_MATRIX_CLIENT "Use the bundled version of mtxclient." | ||
| + ${USE_BUNDLED}) | ||
| + | ||
| +include(ExternalProject) | ||
| + | ||
| +set(BOOST_URL | ||
| + https://dl.bintray.com/boostorg/release/1.66.0/source/boost_1_66_0.tar.bz2) | ||
| +set(BOOST_SHA256 | ||
| + 5721818253e6a0989583192f96782c4a98eb6204965316df9f5ad75819225ca9) | ||
| + | ||
| +set(MATRIX_STRUCTS_URL https://github.com/mujx/matrix-structs) | ||
| +set(MATRIX_STRUCTS_TAG eeb7373729a1618e2b3838407863342b88b8a0de) | ||
| + | ||
| +set(MTXCLIENT_URL https://github.com/mujx/mtxclient) | ||
| +set(MTXCLIENT_TAG 68188721e042ff5b47ea9a87aa97d3a9efbca989) | ||
| + | ||
| +set(OLM_URL https://git.matrix.org/git/olm.git) | ||
| +set(OLM_TAG 4065c8e11a33ba41133a086ed3de4da94dcb6bae) | ||
| + | ||
| +set(SPDLOG_URL https://github.com/gabime/spdlog) | ||
| +set(SPDLOG_TAG 560df2878ad308b27873b3cc5e810635d69cfad6) | ||
| + | ||
| +if(USE_BUNDLED_BOOST) | ||
| + include(Boost) | ||
| +endif() | ||
| + | ||
| +if(USE_BUNDLED_SPDLOG) | ||
| + include(SpdLog) | ||
| +endif() | ||
| + | ||
| +if(USE_BUNDLED_OLM) | ||
| + include(Olm) | ||
| +endif() | ||
| + | ||
| +if(USE_BUNDLED_MATRIX_STRUCTS) | ||
| + include(MatrixStructs) | ||
| +endif() | ||
| + | ||
| +if(WIN32) | ||
| + if("${TARGET_ARCH}" STREQUAL "X86_64") | ||
| + set(TARGET_ARCH x64) | ||
| + elseif(TARGET_ARCH STREQUAL "X86") | ||
| + set(TARGET_ARCH ia32) | ||
| + endif() | ||
| +endif() | ||
| + | ||
| +add_custom_target(third-party ALL | ||
| + COMMAND ${CMAKE_COMMAND} -E touch .third-party | ||
| + DEPENDS ${THIRD_PARTY_DEPS}) | ||
| + | ||
| +if(USE_BUNDLED_MATRIX_CLIENT) | ||
| + include(MatrixClient) | ||
| + add_dependencies(MatrixClient third-party) | ||
| +endif() |
| @@ -0,0 +1,23 @@ | ||
| +if(WIN32) | ||
| + message(STATUS "Building Boost in Windows is not supported (skipping)") | ||
| + return() | ||
| +endif() | ||
| + | ||
| +ExternalProject_Add( | ||
| + Boost | ||
| + | ||
| + URL ${BOOST_URL} | ||
| + URL_HASH SHA256=${BOOST_SHA256} | ||
| + DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/boost | ||
| + DOWNLOAD_NO_PROGRESS 0 | ||
| + | ||
| + BUILD_IN_SOURCE 1 | ||
| + SOURCE_DIR ${DEPS_BUILD_DIR}/boost | ||
| + CONFIGURE_COMMAND ${DEPS_BUILD_DIR}/boost/bootstrap.sh | ||
| + --with-libraries=random,thread,system,iostreams,atomic,chrono,date_time,regex | ||
| + --prefix=${DEPS_INSTALL_DIR} | ||
| + BUILD_COMMAND ${DEPS_BUILD_DIR}/boost/b2 -d0 variant=release link=static threading=multi --layout=system | ||
| + INSTALL_COMMAND ${DEPS_BUILD_DIR}/boost/b2 -d0 install | ||
| +) | ||
| + | ||
| +list(APPEND THIRD_PARTY_DEPS Boost) |
| @@ -0,0 +1,31 @@ | ||
| +set(PLATFORM_FLAGS "") | ||
| + | ||
| +if(MSVC) | ||
| + set(PLATFORM_FLAGS "-DCMAKE_GENERATOR_PLATFORM=x64") | ||
| +endif() | ||
| + | ||
| +if(APPLE) | ||
| + set(PLATFORM_FLAGS "-DOPENSSL_ROOT_DIR=/usr/local/opt/openssl") | ||
| +endif() | ||
| + | ||
| +ExternalProject_Add( | ||
| + MatrixClient | ||
| + | ||
| + DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/mtxclient | ||
| + GIT_REPOSITORY ${MTXCLIENT_URL} | ||
| + GIT_TAG ${MTXCLIENT_TAG} | ||
| + | ||
| + BUILD_IN_SOURCE 1 | ||
| + SOURCE_DIR ${DEPS_BUILD_DIR}/mtxclient | ||
| + CONFIGURE_COMMAND ${CMAKE_COMMAND} | ||
| + -DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} | ||
| + -DCMAKE_BUILD_TYPE=Release | ||
| + -DBUILD_LIB_TESTS=OFF | ||
| + -DBUILD_LIB_EXAMPLES=OFF | ||
| + -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} | ||
| + ${PLATFORM_FLAGS} | ||
| + ${DEPS_BUILD_DIR}/mtxclient | ||
| + BUILD_COMMAND | ||
| + ${CMAKE_COMMAND} --build ${DEPS_BUILD_DIR}/mtxclient --config Release) | ||
| + | ||
| +list(APPEND THIRD_PARTY_DEPS MatrixClient) |
| @@ -0,0 +1,25 @@ | ||
| +set(WINDOWS_FLAGS "") | ||
| + | ||
| +if(MSVC) | ||
| + set(WINDOWS_FLAGS "-DCMAKE_GENERATOR_PLATFORM=x64") | ||
| +endif() | ||
| + | ||
| +ExternalProject_Add( | ||
| + MatrixStructs | ||
| + | ||
| + DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/matrix_structs | ||
| + GIT_REPOSITORY ${MATRIX_STRUCTS_URL} | ||
| + GIT_TAG ${MATRIX_STRUCTS_TAG} | ||
| + | ||
| + BUILD_IN_SOURCE 1 | ||
| + SOURCE_DIR ${DEPS_BUILD_DIR}/matrix_structs | ||
| + CONFIGURE_COMMAND ${CMAKE_COMMAND} | ||
| + -DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} | ||
| + -DCMAKE_BUILD_TYPE=Release | ||
| + ${DEPS_BUILD_DIR}/matrix_structs | ||
| + ${WINDOWS_FLAGS} | ||
| + BUILD_COMMAND ${CMAKE_COMMAND} | ||
| + --build ${DEPS_BUILD_DIR}/matrix_structs | ||
| + --config Release) | ||
| + | ||
| +list(APPEND THIRD_PARTY_DEPS MatrixStructs) |
| @@ -0,0 +1,34 @@ | ||
| +set(WINDOWS_FLAGS "") | ||
| + | ||
| +if(MSVC) | ||
| + set(WINDOWS_FLAGS "-DCMAKE_GENERATOR_PLATFORM=x64") | ||
| +endif() | ||
| + | ||
| +ExternalProject_Add( | ||
| + Olm | ||
| + | ||
| + GIT_REPOSITORY ${OLM_URL} | ||
| + GIT_TAG ${OLM_TAG} | ||
| + | ||
| + BUILD_IN_SOURCE 1 | ||
| + SOURCE_DIR ${DEPS_BUILD_DIR}/olm | ||
| + CONFIGURE_COMMAND ${CMAKE_COMMAND} -E copy | ||
| + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/OlmCMakeLists.txt | ||
| + ${DEPS_BUILD_DIR}/olm/CMakeLists.txt | ||
| + COMMAND ${CMAKE_COMMAND} -E copy | ||
| + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/OlmConfig.cmake.in | ||
| + ${DEPS_BUILD_DIR}/olm/cmake/OlmConfig.cmake.in | ||
| + COMMAND ${CMAKE_COMMAND} | ||
| + -DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} | ||
| + -DCMAKE_BUILD_TYPE=Release | ||
| + ${DEPS_BUILD_DIR}/olm | ||
| + ${WINDOWS_FLAGS} | ||
| + BUILD_COMMAND ${CMAKE_COMMAND} | ||
| + --build ${DEPS_BUILD_DIR}/olm | ||
| + --config Release | ||
| + INSTALL_COMMAND ${CMAKE_COMMAND} | ||
| + --build ${DEPS_BUILD_DIR}/olm | ||
| + --config Release | ||
| + --target install) | ||
| + | ||
| +list(APPEND THIRD_PARTY_DEPS Olm) |
| @@ -0,0 +1,107 @@ | ||
| +cmake_minimum_required(VERSION 3.1) | ||
| + | ||
| +project(olm VERSION 2.2.2 LANGUAGES CXX C) | ||
| + | ||
| +add_definitions(-DOLMLIB_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}) | ||
| +add_definitions(-DOLMLIB_VERSION_MINOR=${PROJECT_VERSION_MINOR}) | ||
| +add_definitions(-DOLMLIB_VERSION_PATCH=${PROJECT_VERSION_PATCH}) | ||
| + | ||
| +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) | ||
| +set(CMAKE_CXX_STANDARD 11) | ||
| +set(CMAKE_CXX_STANDARD_REQUIRED ON) | ||
| +set(CMAKE_C_STANDARD 99) | ||
| +set(CMAKE_C_STANDARD_REQUIRED ON) | ||
| +set(CMAKE_POSITION_INDEPENDENT_CODE ON) | ||
| + | ||
| +if(NOT CMAKE_BUILD_TYPE) | ||
| + set(CMAKE_BUILD_TYPE Release) | ||
| +endif() | ||
| + | ||
| +add_library(olm | ||
| + src/account.cpp | ||
| + src/base64.cpp | ||
| + src/cipher.cpp | ||
| + src/crypto.cpp | ||
| + src/memory.cpp | ||
| + src/message.cpp | ||
| + src/pickle.cpp | ||
| + src/ratchet.cpp | ||
| + src/session.cpp | ||
| + src/utility.cpp | ||
| + | ||
| + src/ed25519.c | ||
| + src/error.c | ||
| + src/inbound_group_session.c | ||
| + src/megolm.c | ||
| + src/olm.cpp | ||
| + src/outbound_group_session.c | ||
| + src/pickle_encoding.c | ||
| + | ||
| + lib/crypto-algorithms/aes.c | ||
| + lib/crypto-algorithms/sha256.c | ||
| + lib/curve25519-donna/curve25519-donna.c) | ||
| +add_library(Olm::Olm ALIAS olm) | ||
| + | ||
| +target_include_directories(olm | ||
| + PUBLIC | ||
| + $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include> | ||
| + $<INSTALL_INTERFACE:include> | ||
| + PRIVATE | ||
| + ${CMAKE_CURRENT_SOURCE_DIR}/lib) | ||
| + | ||
| +set_target_properties(olm PROPERTIES | ||
| + SOVERSION ${PROJECT_VERSION_MAJOR} | ||
| + VERSION ${PROJECT_VERSION}) | ||
| + | ||
| +set_target_properties(olm PROPERTIES | ||
| + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR} | ||
| + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR} | ||
| + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) | ||
| + | ||
| +# | ||
| +# Installation | ||
| +# | ||
| +include(GNUInstallDirs) | ||
| +set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/Olm) | ||
| +install(TARGETS olm | ||
| + EXPORT olm-targets | ||
| + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} | ||
| + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) | ||
| + | ||
| +# The exported target will be named Olm. | ||
| +set_target_properties(olm PROPERTIES EXPORT_NAME Olm) | ||
| +install(FILES | ||
| + ${CMAKE_SOURCE_DIR}/include/olm/olm.h | ||
| + ${CMAKE_SOURCE_DIR}/include/olm/outbound_group_session.h | ||
| + ${CMAKE_SOURCE_DIR}/include/olm/inbound_group_session.h | ||
| + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/olm) | ||
| + | ||
| +# Export the targets to a script. | ||
| +install(EXPORT olm-targets | ||
| + FILE OlmTargets.cmake | ||
| + NAMESPACE Olm:: | ||
| + DESTINATION ${INSTALL_CONFIGDIR}) | ||
| + | ||
| +# Create a ConfigVersion.cmake file. | ||
| +include(CMakePackageConfigHelpers) | ||
| +write_basic_package_version_file( | ||
| + ${CMAKE_CURRENT_BINARY_DIR}/OlmConfigVersion.cmake | ||
| + VERSION ${PROJECT_VERSION} | ||
| + COMPATIBILITY SameMajorVersion) | ||
| + | ||
| +configure_package_config_file( | ||
| + ${CMAKE_CURRENT_LIST_DIR}/cmake/OlmConfig.cmake.in | ||
| + ${CMAKE_CURRENT_BINARY_DIR}/OlmConfig.cmake | ||
| + INSTALL_DESTINATION ${INSTALL_CONFIGDIR}) | ||
| + | ||
| +#Install the config & configversion. | ||
| +install(FILES | ||
| + ${CMAKE_CURRENT_BINARY_DIR}/OlmConfig.cmake | ||
| + ${CMAKE_CURRENT_BINARY_DIR}/OlmConfigVersion.cmake | ||
| + DESTINATION ${INSTALL_CONFIGDIR}) | ||
| + | ||
| +# Register package in user's package registry | ||
| +export(EXPORT olm-targets | ||
| + FILE ${CMAKE_CURRENT_BINARY_DIR}/OlmTargets.cmake | ||
| + NAMESPACE Olm::) | ||
| +export(PACKAGE Olm) |
| @@ -0,0 +1,11 @@ | ||
| +get_filename_component(Olm_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) | ||
| +include(CMakeFindDependencyMacro) | ||
| + | ||
| +list(APPEND CMAKE_MODULE_PATH ${Olm_CMAKE_DIR}) | ||
| +list(REMOVE_AT CMAKE_MODULE_PATH -1) | ||
| + | ||
| +if(NOT TARGET Olm::Olm) | ||
| + include("${Olm_CMAKE_DIR}/OlmTargets.cmake") | ||
| +endif() | ||
| + | ||
| +set(Olm_LIBRARIES Olm::Olm) |
| @@ -0,0 +1,22 @@ | ||
| +set(WINDOWS_FLAGS "") | ||
| + | ||
| +if(MSVC) | ||
| + set(WINDOWS_FLAGS "-DCMAKE_GENERATOR_PLATFORM=x64") | ||
| +endif() | ||
| + | ||
| +ExternalProject_Add( | ||
| + SpdLog | ||
| + | ||
| + GIT_REPOSITORY ${SPDLOG_URL} | ||
| + GIT_TAG ${SPDLOG_TAG} | ||
| + | ||
| + BUILD_IN_SOURCE 1 | ||
| + SOURCE_DIR ${DEPS_BUILD_DIR}/spdlog | ||
| + CONFIGURE_COMMAND ${CMAKE_COMMAND} | ||
| + -DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} | ||
| + -DSPDLOG_BUILD_EXAMPLES=0 | ||
| + -DSPDLOG_BUILD_TESTING=0 | ||
| + ${DEPS_BUILD_DIR}/spdlog | ||
| + ${WINDOWS_FLAGS}) | ||
| + | ||
| +list(APPEND THIRD_PARTY_DEPS SpdLog) |
| @@ -0,0 +1,21 @@ | ||
| +#pragma once | ||
| + | ||
| +#include <memory> | ||
| +#include <spdlog/spdlog.h> | ||
| + | ||
| +namespace nhlog { | ||
| +void | ||
| +init(const std::string &file); | ||
| + | ||
| +std::shared_ptr<spdlog::logger> | ||
| +ui(); | ||
| + | ||
| +std::shared_ptr<spdlog::logger> | ||
| +net(); | ||
| + | ||
| +std::shared_ptr<spdlog::logger> | ||
| +db(); | ||
| + | ||
| +std::shared_ptr<spdlog::logger> | ||
| +crypto(); | ||
| +} |
| @@ -1,287 +1,28 @@ | ||
| -/* | ||
| - * nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr> | ||
| - * | ||
| - * This program is free software: you can redistribute it and/or modify | ||
| - * it under the terms of the GNU General Public License as published by | ||
| - * the Free Software Foundation, either version 3 of the License, or | ||
| - * (at your option) any later version. | ||
| - * | ||
| - * This program is distributed in the hope that it will be useful, | ||
| - * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| - * GNU General Public License for more details. | ||
| - * | ||
| - * You should have received a copy of the GNU General Public License | ||
| - * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| - */ | ||
| - | ||
| #pragma once | ||
| -#include <QFileInfo> | ||
| -#include <QJsonDocument> | ||
| -#include <QNetworkAccessManager> | ||
| -#include <QNetworkReply> | ||
| -#include <QNetworkRequest> | ||
| -#include <QUrl> | ||
| -#include <memory> | ||
| -#include <mtx.hpp> | ||
| -#include <mtx/errors.hpp> | ||
| - | ||
| -class DownloadMediaProxy : public QObject | ||
| -{ | ||
| - Q_OBJECT | ||
| - | ||
| -signals: | ||
| - void imageDownloaded(const QPixmap &data); | ||
| - void fileDownloaded(const QByteArray &data); | ||
| - void avatarDownloaded(const QImage &img); | ||
| -}; | ||
| +#include <QMetaType> | ||
| -class StateEventProxy : public QObject | ||
| -{ | ||
| - Q_OBJECT | ||
| - | ||
| -signals: | ||
| - void stateEventSent(); | ||
| - void stateEventError(const QString &msg); | ||
| -}; | ||
| +#include <mtx/responses.hpp> | ||
| +#include <mtxclient/http/client.hpp> | ||
| +Q_DECLARE_METATYPE(mtx::responses::Login) | ||
| +Q_DECLARE_METATYPE(mtx::responses::Messages) | ||
| +Q_DECLARE_METATYPE(mtx::responses::Notifications) | ||
| +Q_DECLARE_METATYPE(mtx::responses::Rooms) | ||
| Q_DECLARE_METATYPE(mtx::responses::Sync) | ||
| +Q_DECLARE_METATYPE(std::string) | ||
| +Q_DECLARE_METATYPE(std::vector<std::string>) | ||
| -/* | ||
| - * MatrixClient provides the high level API to communicate with | ||
| - * a Matrix homeserver. All the responses are returned through signals. | ||
| - */ | ||
| -class MatrixClient : public QNetworkAccessManager | ||
| -{ | ||
| - Q_OBJECT | ||
| -public: | ||
| - MatrixClient(QObject *parent = 0); | ||
| - | ||
| - // Client API. | ||
| - void initialSync() noexcept; | ||
| - void sync() noexcept; | ||
| - template<class EventBody, mtx::events::EventType EventT> | ||
| - std::shared_ptr<StateEventProxy> sendStateEvent(const EventBody &body, | ||
| - const QString &roomId, | ||
| - const QString &stateKey = ""); | ||
| - void sendRoomMessage(mtx::events::MessageType ty, | ||
| - int txnId, | ||
| - const QString &roomid, | ||
| - const QString &msg, | ||
| - const QString &mime, | ||
| - uint64_t media_size, | ||
| - const QString &url = "") noexcept; | ||
| - void login(const QString &username, const QString &password) noexcept; | ||
| - void registerUser(const QString &username, | ||
| - const QString &password, | ||
| - const QString &server, | ||
| - const QString &session = "") noexcept; | ||
| - void versions() noexcept; | ||
| - void fetchRoomAvatar(const QString &roomid, const QUrl &avatar_url); | ||
| - //! Download user's avatar. | ||
| - QSharedPointer<DownloadMediaProxy> fetchUserAvatar(const QUrl &avatarUrl); | ||
| - void fetchCommunityAvatar(const QString &communityId, const QUrl &avatarUrl); | ||
| - void fetchCommunityProfile(const QString &communityId); | ||
| - void fetchCommunityRooms(const QString &communityId); | ||
| - QSharedPointer<DownloadMediaProxy> downloadImage(const QUrl &url); | ||
| - QSharedPointer<DownloadMediaProxy> downloadFile(const QUrl &url); | ||
| - void messages(const QString &room_id, const QString &from_token, int limit = 30) noexcept; | ||
| - void uploadImage(const QString &roomid, | ||
| - const QString &filename, | ||
| - const QSharedPointer<QIODevice> data); | ||
| - void uploadFile(const QString &roomid, | ||
| - const QString &filename, | ||
| - const QSharedPointer<QIODevice> data); | ||
| - void uploadAudio(const QString &roomid, | ||
| - const QString &filename, | ||
| - const QSharedPointer<QIODevice> data); | ||
| - void uploadVideo(const QString &roomid, | ||
| - const QString &filename, | ||
| - const QSharedPointer<QIODevice> data); | ||
| - void uploadFilter(const QString &filter) noexcept; | ||
| - void joinRoom(const QString &roomIdOrAlias); | ||
| - void leaveRoom(const QString &roomId); | ||
| - void sendTypingNotification(const QString &roomid, int timeoutInMillis = 20000); | ||
| - void removeTypingNotification(const QString &roomid); | ||
| - void readEvent(const QString &room_id, const QString &event_id); | ||
| - void redactEvent(const QString &room_id, const QString &event_id); | ||
| - void inviteUser(const QString &room_id, const QString &user); | ||
| - void createRoom(const mtx::requests::CreateRoom &request); | ||
| - void getNotifications() noexcept; | ||
| - | ||
| - QUrl getHomeServer() { return server_; }; | ||
| - int transactionId() { return txn_id_; }; | ||
| - int incrementTransactionId() { return ++txn_id_; }; | ||
| - | ||
| - void reset() noexcept; | ||
| - | ||
| -public slots: | ||
| - void getOwnProfile() noexcept; | ||
| - void getOwnCommunities() noexcept; | ||
| - void logout() noexcept; | ||
| - | ||
| - void setServer(const QString &server) | ||
| - { | ||
| - server_ = QUrl(QString("%1://%2").arg(serverProtocol_).arg(server)); | ||
| - }; | ||
| - void setAccessToken(const QString &token) { token_ = token; }; | ||
| - void setNextBatchToken(const QString &next_batch) { next_batch_ = next_batch; }; | ||
| - | ||
| -signals: | ||
| - void loginError(const QString &error); | ||
| - void registerError(const QString &error); | ||
| - void registrationFlow(const QString &user, | ||
| - const QString &pass, | ||
| - const QString &server, | ||
| - const QString &session); | ||
| - void versionError(const QString &error); | ||
| - | ||
| - void loggedOut(); | ||
| - void invitedUser(const QString &room_id, const QString &user); | ||
| - void roomCreated(const QString &room_id); | ||
| - | ||
| - void loginSuccess(const QString &userid, const QString &homeserver, const QString &token); | ||
| - void registerSuccess(const QString &userid, | ||
| - const QString &homeserver, | ||
| - const QString &token); | ||
| - void versionSuccess(); | ||
| - void uploadFailed(int statusCode, const QString &msg); | ||
| - void imageUploaded(const QString &roomid, | ||
| - const QString &filename, | ||
| - const QString &url, | ||
| - const QString &mime, | ||
| - uint64_t size); | ||
| - void fileUploaded(const QString &roomid, | ||
| - const QString &filename, | ||
| - const QString &url, | ||
| - const QString &mime, | ||
| - uint64_t size); | ||
| - void audioUploaded(const QString &roomid, | ||
| - const QString &filename, | ||
| - const QString &url, | ||
| - const QString &mime, | ||
| - uint64_t size); | ||
| - void videoUploaded(const QString &roomid, | ||
| - const QString &filename, | ||
| - const QString &url, | ||
| - const QString &mime, | ||
| - uint64_t size); | ||
| - void roomAvatarRetrieved(const QString &roomid, | ||
| - const QPixmap &img, | ||
| - const QString &url, | ||
| - const QByteArray &data); | ||
| - void userAvatarRetrieved(const QString &userId, const QImage &img); | ||
| - void communityAvatarRetrieved(const QString &communityId, const QPixmap &img); | ||
| - void communityProfileRetrieved(const QString &communityId, const QJsonObject &profile); | ||
| - void communityRoomsRetrieved(const QString &communityId, const QJsonObject &rooms); | ||
| - | ||
| - // Returned profile data for the user's account. | ||
| - void getOwnProfileResponse(const QUrl &avatar_url, const QString &display_name); | ||
| - void getOwnCommunitiesResponse(const QList<QString> &own_communities); | ||
| - void initialSyncCompleted(const mtx::responses::Sync &response); | ||
| - void initialSyncFailed(int status_code = -1); | ||
| - void syncCompleted(const mtx::responses::Sync &response); | ||
| - void syncFailed(const QString &msg); | ||
| - void joinFailed(const QString &msg); | ||
| - void messageSent(const QString &event_id, const QString &roomid, int txn_id); | ||
| - void messageSendFailed(const QString &roomid, int txn_id); | ||
| - void emoteSent(const QString &event_id, const QString &roomid, int txn_id); | ||
| - void messagesRetrieved(const QString &room_id, const mtx::responses::Messages &msgs); | ||
| - void joinedRoom(const QString &room_id); | ||
| - void leftRoom(const QString &room_id); | ||
| - void roomCreationFailed(const QString &msg); | ||
| - | ||
| - void redactionFailed(const QString &error); | ||
| - void redactionCompleted(const QString &room_id, const QString &event_id); | ||
| - void invalidToken(); | ||
| - void syncError(const QString &error); | ||
| - void notificationsRetrieved(const mtx::responses::Notifications ¬ifications); | ||
| - | ||
| -private: | ||
| - QNetworkReply *makeUploadRequest(QSharedPointer<QIODevice> iodev); | ||
| - QJsonObject getUploadReply(QNetworkReply *reply); | ||
| - void setupAuth(QNetworkRequest &req) | ||
| - { | ||
| - req.setRawHeader("Authorization", QString("Bearer %1").arg(token_).toLocal8Bit()); | ||
| - } | ||
| - | ||
| - // Client API prefix. | ||
| - QString clientApiUrl_; | ||
| - | ||
| - // Media API prefix. | ||
| - QString mediaApiUrl_; | ||
| - | ||
| - // The Matrix server used for communication. | ||
| - QUrl server_; | ||
| - | ||
| - // The access token used for authentication. | ||
| - QString token_; | ||
| - | ||
| - // Increasing transaction ID. | ||
| - int txn_id_; | ||
| +namespace http { | ||
| +namespace v2 { | ||
| +mtx::http::Client * | ||
| +client(); | ||
| - //! Token to be used for the next sync. | ||
| - QString next_batch_; | ||
| - //! http or https (default). | ||
| - QString serverProtocol_; | ||
| - //! Filter to be send as filter-param for (initial) /sync requests. | ||
| - QString filter_; | ||
| -}; | ||
| +bool | ||
| +is_logged_in(); | ||
| +} | ||
| -namespace http { | ||
| //! Initialize the http module | ||
| void | ||
| init(); | ||
| - | ||
| -//! Retrieve the client instance. | ||
| -MatrixClient * | ||
| -client(); | ||
| -} | ||
| - | ||
| -template<class EventBody, mtx::events::EventType EventT> | ||
| -std::shared_ptr<StateEventProxy> | ||
| -MatrixClient::sendStateEvent(const EventBody &body, const QString &roomId, const QString &stateKey) | ||
| -{ | ||
| - QUrl endpoint(server_); | ||
| - endpoint.setPath(clientApiUrl_ + QString("/rooms/%1/state/%2/%3") | ||
| - .arg(roomId) | ||
| - .arg(QString::fromStdString(to_string(EventT))) | ||
| - .arg(stateKey)); | ||
| - | ||
| - QNetworkRequest request(QString(endpoint.toEncoded())); | ||
| - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); | ||
| - setupAuth(request); | ||
| - | ||
| - auto proxy = std::shared_ptr<StateEventProxy>(new StateEventProxy, | ||
| - [](StateEventProxy *p) { p->deleteLater(); }); | ||
| - | ||
| - auto serializedBody = nlohmann::json(body).dump(); | ||
| - auto reply = put(request, QByteArray(serializedBody.data(), serializedBody.size())); | ||
| - connect(reply, &QNetworkReply::finished, this, [reply, proxy]() { | ||
| - reply->deleteLater(); | ||
| - | ||
| - int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); | ||
| - auto data = reply->readAll(); | ||
| - | ||
| - if (status == 0 || status >= 400) { | ||
| - try { | ||
| - mtx::errors::Error res = nlohmann::json::parse(data); | ||
| - emit proxy->stateEventError(QString::fromStdString(res.error)); | ||
| - } catch (const std::exception &e) { | ||
| - emit proxy->stateEventError(QString::fromStdString(e.what())); | ||
| - } | ||
| - | ||
| - return; | ||
| - } | ||
| - | ||
| - try { | ||
| - mtx::responses::EventId res = nlohmann::json::parse(data); | ||
| - emit proxy->stateEventSent(); | ||
| - } catch (const std::exception &e) { | ||
| - emit proxy->stateEventError(QString::fromStdString(e.what())); | ||
| - } | ||
| - }); | ||
| - | ||
| - return proxy; | ||
| } |
| @@ -0,0 +1,78 @@ | ||
| +#pragma once | ||
| + | ||
| +#include <boost/optional.hpp> | ||
| + | ||
| +#include <memory> | ||
| +#include <mtx.hpp> | ||
| +#include <mtxclient/crypto/client.hpp> | ||
| + | ||
| +constexpr auto OLM_ALGO = "m.olm.v1.curve25519-aes-sha2"; | ||
| + | ||
| +namespace olm { | ||
| + | ||
| +struct OlmCipherContent | ||
| +{ | ||
| + std::string body; | ||
| + uint8_t type; | ||
| +}; | ||
| + | ||
| +inline void | ||
| +from_json(const nlohmann::json &obj, OlmCipherContent &msg) | ||
| +{ | ||
| + msg.body = obj.at("body"); | ||
| + msg.type = obj.at("type"); | ||
| +} | ||
| + | ||
| +struct OlmMessage | ||
| +{ | ||
| + std::string sender_key; | ||
| + std::string sender; | ||
| + | ||
| + using RecipientKey = std::string; | ||
| + std::map<RecipientKey, OlmCipherContent> ciphertext; | ||
| +}; | ||
| + | ||
| +inline void | ||
| +from_json(const nlohmann::json &obj, OlmMessage &msg) | ||
| +{ | ||
| + if (obj.at("type") != "m.room.encrypted") | ||
| + throw std::invalid_argument("invalid type for olm message"); | ||
| + | ||
| + if (obj.at("content").at("algorithm") != OLM_ALGO) | ||
| + throw std::invalid_argument("invalid algorithm for olm message"); | ||
| + | ||
| + msg.sender = obj.at("sender"); | ||
| + msg.sender_key = obj.at("content").at("sender_key"); | ||
| + msg.ciphertext = | ||
| + obj.at("content").at("ciphertext").get<std::map<std::string, OlmCipherContent>>(); | ||
| +} | ||
| + | ||
| +mtx::crypto::OlmClient * | ||
| +client(); | ||
| + | ||
| +void | ||
| +handle_to_device_messages(const std::vector<nlohmann::json> &msgs); | ||
| + | ||
| +boost::optional<json> | ||
| +try_olm_decryption(const std::string &sender_key, const OlmCipherContent &content); | ||
| + | ||
| +void | ||
| +handle_olm_message(const OlmMessage &msg); | ||
| + | ||
| +//! Establish a new inbound megolm session with the decrypted payload from olm. | ||
| +void | ||
| +create_inbound_megolm_session(const std::string &sender, | ||
| + const std::string &sender_key, | ||
| + const nlohmann::json &payload); | ||
| + | ||
| +void | ||
| +handle_pre_key_olm_message(const std::string &sender, | ||
| + const std::string &sender_key, | ||
| + const OlmCipherContent &content); | ||
| + | ||
| +mtx::events::msg::Encrypted | ||
| +encrypt_group_message(const std::string &room_id, | ||
| + const std::string &device_id, | ||
| + const std::string &body); | ||
| + | ||
| +} // namespace olm |
| @@ -0,0 +1,59 @@ | ||
| +#include "Logging.hpp" | ||
| + | ||
| +#include <iostream> | ||
| +#include <spdlog/sinks/file_sinks.h> | ||
| + | ||
| +namespace { | ||
| +std::shared_ptr<spdlog::logger> db_logger = nullptr; | ||
| +std::shared_ptr<spdlog::logger> net_logger = nullptr; | ||
| +std::shared_ptr<spdlog::logger> crypto_logger = nullptr; | ||
| +std::shared_ptr<spdlog::logger> ui_logger = nullptr; | ||
| + | ||
| +constexpr auto MAX_FILE_SIZE = 1024 * 1024 * 6; | ||
| +constexpr auto MAX_LOG_FILES = 3; | ||
| +} | ||
| + | ||
| +namespace nhlog { | ||
| +void | ||
| +init(const std::string &file_path) | ||
| +{ | ||
| + auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>( | ||
| + file_path, MAX_FILE_SIZE, MAX_LOG_FILES); | ||
| + | ||
| + auto console_sink = std::make_shared<spdlog::sinks::stdout_sink_mt>(); | ||
| + | ||
| + std::vector<spdlog::sink_ptr> sinks; | ||
| + sinks.push_back(file_sink); | ||
| + sinks.push_back(console_sink); | ||
| + | ||
| + net_logger = std::make_shared<spdlog::logger>("net", std::begin(sinks), std::end(sinks)); | ||
| + ui_logger = std::make_shared<spdlog::logger>("ui", std::begin(sinks), std::end(sinks)); | ||
| + db_logger = std::make_shared<spdlog::logger>("db", std::begin(sinks), std::end(sinks)); | ||
| + crypto_logger = | ||
| + std::make_shared<spdlog::logger>("crypto", std::begin(sinks), std::end(sinks)); | ||
| +} | ||
| + | ||
| +std::shared_ptr<spdlog::logger> | ||
| +ui() | ||
| +{ | ||
| + return ui_logger; | ||
| +} | ||
| + | ||
| +std::shared_ptr<spdlog::logger> | ||
| +net() | ||
| +{ | ||
| + return net_logger; | ||
| +} | ||
| + | ||
| +std::shared_ptr<spdlog::logger> | ||
| +db() | ||
| +{ | ||
| + return db_logger; | ||
| +} | ||
| + | ||
| +std::shared_ptr<spdlog::logger> | ||
| +crypto() | ||
| +{ | ||
| + return crypto_logger; | ||
| +} | ||
| +} |
| @@ -0,0 +1,228 @@ | ||
| +#include "Olm.hpp" | ||
| + | ||
| +#include "Cache.h" | ||
| +#include "Logging.hpp" | ||
| + | ||
| +using namespace mtx::crypto; | ||
| + | ||
| +namespace { | ||
| +auto client_ = std::make_unique<mtx::crypto::OlmClient>(); | ||
| +} | ||
| + | ||
| +namespace olm { | ||
| + | ||
| +mtx::crypto::OlmClient * | ||
| +client() | ||
| +{ | ||
| + return client_.get(); | ||
| +} | ||
| + | ||
| +void | ||
| +handle_to_device_messages(const std::vector<nlohmann::json> &msgs) | ||
| +{ | ||
| + if (msgs.empty()) | ||
| + return; | ||
| + | ||
| + nhlog::crypto()->info("received {} to_device messages", msgs.size()); | ||
| + | ||
| + for (const auto &msg : msgs) { | ||
| + try { | ||
| + OlmMessage olm_msg = msg; | ||
| + handle_olm_message(std::move(olm_msg)); | ||
| + } catch (const nlohmann::json::exception &e) { | ||
| + nhlog::crypto()->warn( | ||
| + "parsing error for olm message: {} {}", e.what(), msg.dump(2)); | ||
| + } catch (const std::invalid_argument &e) { | ||
| + nhlog::crypto()->warn( | ||
| + "validation error for olm message: {} {}", e.what(), msg.dump(2)); | ||
| + } | ||
| + } | ||
| +} | ||
| + | ||
| +void | ||
| +handle_olm_message(const OlmMessage &msg) | ||
| +{ | ||
| + nhlog::crypto()->info("sender : {}", msg.sender); | ||
| + nhlog::crypto()->info("sender_key: {}", msg.sender_key); | ||
| + | ||
| + const auto my_key = olm::client()->identity_keys().curve25519; | ||
| + | ||
| + for (const auto &cipher : msg.ciphertext) { | ||
| + // We skip messages not meant for the current device. | ||
| + if (cipher.first != my_key) | ||
| + continue; | ||
| + | ||
| + const auto type = cipher.second.type; | ||
| + nhlog::crypto()->info("type: {}", type == 0 ? "OLM_PRE_KEY" : "OLM_MESSAGE"); | ||
| + | ||
| + auto payload = try_olm_decryption(msg.sender_key, cipher.second); | ||
| + | ||
| + if (payload) { | ||
| + nhlog::crypto()->info("decrypted olm payload: {}", payload.value().dump(2)); | ||
| + create_inbound_megolm_session(msg.sender, msg.sender_key, payload.value()); | ||
| + return; | ||
| + } | ||
| + | ||
| + // Not a PRE_KEY message | ||
| + if (cipher.second.type != 0) { | ||
| + // TODO: log that it should have matched something | ||
| + return; | ||
| + } | ||
| + | ||
| + handle_pre_key_olm_message(msg.sender, msg.sender_key, cipher.second); | ||
| + } | ||
| +} | ||
| + | ||
| +void | ||
| +handle_pre_key_olm_message(const std::string &sender, | ||
| + const std::string &sender_key, | ||
| + const OlmCipherContent &content) | ||
| +{ | ||
| + nhlog::crypto()->info("opening olm session with {}", sender); | ||
| + | ||
| + OlmSessionPtr inbound_session = nullptr; | ||
| + try { | ||
| + inbound_session = olm::client()->create_inbound_session(content.body); | ||
| + | ||
| + // We also remove the one time key used to establish that | ||
| + // session so we'll have to update our copy of the account object. | ||
| + cache::client()->saveOlmAccount(olm::client()->save("secret")); | ||
| + } catch (const olm_exception &e) { | ||
| + nhlog::crypto()->critical( | ||
| + "failed to create inbound session with {}: {}", sender, e.what()); | ||
| + return; | ||
| + } | ||
| + | ||
| + if (!matches_inbound_session_from(inbound_session.get(), sender_key, content.body)) { | ||
| + nhlog::crypto()->warn("inbound olm session doesn't match sender's key ({})", | ||
| + sender); | ||
| + return; | ||
| + } | ||
| + | ||
| + mtx::crypto::BinaryBuf output; | ||
| + try { | ||
| + output = | ||
| + olm::client()->decrypt_message(inbound_session.get(), content.type, content.body); | ||
| + } catch (const olm_exception &e) { | ||
| + nhlog::crypto()->critical( | ||
| + "failed to decrypt olm message {}: {}", content.body, e.what()); | ||
| + return; | ||
| + } | ||
| + | ||
| + auto plaintext = json::parse(std::string((char *)output.data(), output.size())); | ||
| + nhlog::crypto()->info("decrypted message: \n {}", plaintext.dump(2)); | ||
| + | ||
| + try { | ||
| + cache::client()->saveOlmSession(sender_key, std::move(inbound_session)); | ||
| + } catch (const lmdb::error &e) { | ||
| + nhlog::db()->warn( | ||
| + "failed to save inbound olm session from {}: {}", sender, e.what()); | ||
| + } | ||
| + | ||
| + create_inbound_megolm_session(sender, sender_key, plaintext); | ||
| +} | ||
| + | ||
| +mtx::events::msg::Encrypted | ||
| +encrypt_group_message(const std::string &room_id, | ||
| + const std::string &device_id, | ||
| + const std::string &body) | ||
| +{ | ||
| + using namespace mtx::events; | ||
| + | ||
| + // Always chech before for existence. | ||
| + auto res = cache::client()->getOutboundMegolmSession(room_id); | ||
| + auto payload = olm::client()->encrypt_group_message(res.session, body); | ||
| + | ||
| + // Prepare the m.room.encrypted event. | ||
| + msg::Encrypted data; | ||
| + data.ciphertext = std::string((char *)payload.data(), payload.size()); | ||
| + data.sender_key = olm::client()->identity_keys().curve25519; | ||
| + data.session_id = res.data.session_id; | ||
| + data.device_id = device_id; | ||
| + | ||
| + auto message_index = olm_outbound_group_session_message_index(res.session); | ||
| + nhlog::crypto()->info("next message_index {}", message_index); | ||
| + | ||
| + // We need to re-pickle the session after we send a message to save the new message_index. | ||
| + cache::client()->updateOutboundMegolmSession(room_id, message_index); | ||
| + | ||
| + return data; | ||
| +} | ||
| + | ||
| +boost::optional<json> | ||
| +try_olm_decryption(const std::string &sender_key, const OlmCipherContent &msg) | ||
| +{ | ||
| + auto session_ids = cache::client()->getOlmSessions(sender_key); | ||
| + | ||
| + for (const auto &id : session_ids) { | ||
| + auto session = cache::client()->getOlmSession(sender_key, id); | ||
| + | ||
| + if (!session) | ||
| + continue; | ||
| + | ||
| + mtx::crypto::BinaryBuf text; | ||
| + | ||
| + try { | ||
| + text = olm::client()->decrypt_message(session->get(), msg.type, msg.body); | ||
| + cache::client()->saveOlmSession(id, std::move(session.value())); | ||
| + | ||
| + } catch (const olm_exception &e) { | ||
| + nhlog::crypto()->info("failed to decrypt olm message ({}, {}) with {}: {}", | ||
| + msg.type, | ||
| + sender_key, | ||
| + id, | ||
| + e.what()); | ||
| + continue; | ||
| + } catch (const lmdb::error &e) { | ||
| + nhlog::crypto()->critical("failed to save session: {}", e.what()); | ||
| + return {}; | ||
| + } | ||
| + | ||
| + try { | ||
| + return json::parse(std::string((char *)text.data(), text.size())); | ||
| + } catch (const json::exception &e) { | ||
| + nhlog::crypto()->critical("failed to parse the decrypted session msg: {}", | ||
| + e.what()); | ||
| + } | ||
| + } | ||
| + | ||
| + return {}; | ||
| +} | ||
| + | ||
| +void | ||
| +create_inbound_megolm_session(const std::string &sender, | ||
| + const std::string &sender_key, | ||
| + const nlohmann::json &payload) | ||
| +{ | ||
| + std::string room_id, session_id, session_key; | ||
| + | ||
| + try { | ||
| + room_id = payload.at("content").at("room_id"); | ||
| + session_id = payload.at("content").at("session_id"); | ||
| + session_key = payload.at("content").at("session_key"); | ||
| + } catch (const nlohmann::json::exception &e) { | ||
| + nhlog::crypto()->critical( | ||
| + "failed to parse plaintext olm message: {} {}", e.what(), payload.dump(2)); | ||
| + return; | ||
| + } | ||
| + | ||
| + MegolmSessionIndex index; | ||
| + index.room_id = room_id; | ||
| + index.session_id = session_id; | ||
| + index.sender_key = sender_key; | ||
| + | ||
| + try { | ||
| + auto megolm_session = olm::client()->init_inbound_group_session(session_key); | ||
| + cache::client()->saveInboundMegolmSession(index, std::move(megolm_session)); | ||
| + } catch (const lmdb::error &e) { | ||
| + nhlog::crypto()->critical("failed to save inbound megolm session: {}", e.what()); | ||
| + return; | ||
| + } catch (const olm_exception &e) { | ||
| + nhlog::crypto()->critical("failed to create inbound megolm session: {}", e.what()); | ||
| + return; | ||
| + } | ||
| + | ||
| + nhlog::crypto()->info("established inbound megolm session ({}, {})", room_id, sender); | ||
| +} | ||
| + | ||
| +} // namespace olm |