From 615762d7b31b4ff0450136b063c7c0c5f33f6a05 Mon Sep 17 00:00:00 2001 From: aspen Date: Thu, 13 May 2021 11:41:29 -0400 Subject: [PATCH 001/113] Fix compilation on M1 macOS --- CMakeLists.txt | 23 ++++++++++++++++++++++- clean_build.sh | 2 +- dist/macos/bundle/build_dist.sh.in | 4 ++-- osx_environment.sh | 15 ++++++--------- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c56b30be..1b7cb545 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -317,10 +317,21 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") ${OPENSSL_ROOT}/lib/ssleay32.lib ) elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + find_program(APT_PROGRAM "apt") find_program(BREW_PROGRAM "brew") find_program(PORT_PROGRAM "port") - if (IS_DIRECTORY /opt/local AND PORT_PROGRAM) + if (IS_DIRECTORY /opt/procursus AND APT_PROGRAM) + # procursus/apt + set (OPENSSL_ROOT /opt/procursus) + + include_directories (BEFORE SYSTEM ${OPENSSL_ROOT}/include) + + set (OPENSSL_LIBS + ${OPENSSL_ROOT}/lib/libssl.a + ${OPENSSL_ROOT}/lib/libcrypto.a + ) + elseif (IS_DIRECTORY /opt/local AND PORT_PROGRAM) # macports set (OPENSSL_ROOT /opt/local) @@ -335,6 +346,16 @@ elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") include_directories (BEFORE SYSTEM ${OPENSSL_ROOT}/include) + set (OPENSSL_LIBS + ${OPENSSL_ROOT}/lib/libssl.a + ${OPENSSL_ROOT}/lib/libcrypto.a + ) + elseif (IS_DIRECTORY /opt/homebrew/opt/openssl AND BREW_PROGRAM) + # brew + set (OPENSSL_ROOT /opt/homebrew/opt/openssl) + + include_directories (BEFORE SYSTEM ${OPENSSL_ROOT}/include) + set (OPENSSL_LIBS ${OPENSSL_ROOT}/lib/libssl.a ${OPENSSL_ROOT}/lib/libcrypto.a diff --git a/clean_build.sh b/clean_build.sh index 3a92d8b9..f78bc463 100755 --- a/clean_build.sh +++ b/clean_build.sh @@ -14,7 +14,7 @@ if [ "$(uname)" = "Darwin" ]; then # OSX needs a lot of extra help, poor thing # run the osx_environment.sh script to fix paths . ./osx_environment.sh - B_CMAKE_FLAGS="-DCMAKE_OSX_SYSROOT=$(xcode-select --print-path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 $B_CMAKE_FLAGS" + B_CMAKE_FLAGS="-DCMAKE_OSX_SYSROOT=$(xcode-select --print-path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 $B_CMAKE_FLAGS" fi # allow local customizations to build environment [ -r ./build_env.sh ] && . ./build_env.sh diff --git a/dist/macos/bundle/build_dist.sh.in b/dist/macos/bundle/build_dist.sh.in index c96da790..0db08286 100755 --- a/dist/macos/bundle/build_dist.sh.in +++ b/dist/macos/bundle/build_dist.sh.in @@ -48,7 +48,7 @@ fi # Check for macdeployqt on Homebrew if which -s brew ; then info "Homebrew found, searching for macdeployqt" - DEPLOYQT="$(brew list qt | grep --only '/.*macdeployqt' | head -1)" + DEPLOYQT="$(brew list qt5 | grep --only '/.*macdeployqt' | head -1)" if [ ! -x "$DEPLOYQT" ]; then error Please install package qt exit 1 @@ -70,4 +70,4 @@ else -executable="$B_BARRIERC" \ -executable="$B_BARRIERS" || exit 1 success "Bundle created successfully" -fi \ No newline at end of file +fi diff --git a/osx_environment.sh b/osx_environment.sh index 09fa3479..04f41c17 100644 --- a/osx_environment.sh +++ b/osx_environment.sh @@ -29,18 +29,15 @@ if [ ! $BARRIER_BUILD_ENV ]; then elif command -v brew; then printf "Detected Homebrew\n" - QT_PATH=$(brew --prefix qt) - OPENSSL_PATH=$(brew --prefix openssl) + QT_PATH=$(brew --prefix qt5) - check_dir_exists "$QT_PATH" 'qt' - check_dir_exists "$OPENSSL_PATH" 'openssl' + check_dir_exists "$QT_PATH" 'qt5' export BARRIER_BUILD_BREW=1 - export CMAKE_PREFIX_PATH="$QT_PATH:$CMAKE_PREFIX_PATH" - export LD_LIBRARY_PATH="$OPENSSL_PATH/lib:$LD_LIBRARY_PATH" - export CPATH="$OPENSSL_PATH/include:$CPATH" - export PKG_CONFIG_PATH="$OPENSSL_PATH/lib/pkgconfig:$PKG_CONFIG_PATH" - + export CMAKE_PREFIX_PATH="/opt/procursus:$QT_PATH:$CMAKE_PREFIX_PATH" + export LD_LIBRARY_PATH="/opt/procursus/lib:$LD_LIBRARY_PATH" + export CPATH="/opt/procursus/include:$CPATH" + export PKG_CONFIG_PATH="/opt/procursus/lib/pkgconfig:$PKG_CONFIG_PATH" else printf "Neither Homebrew nor Macports is installed. Can't get dependency paths\n" exit 1 From 5f6456b36e020ac6d824bd2f59845f6e174f455a Mon Sep 17 00:00:00 2001 From: aspen Date: Thu, 13 May 2021 12:01:33 -0400 Subject: [PATCH 002/113] Whoops, I didn't mean to commit that! --- clean_build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clean_build.sh b/clean_build.sh index f78bc463..3a92d8b9 100755 --- a/clean_build.sh +++ b/clean_build.sh @@ -14,7 +14,7 @@ if [ "$(uname)" = "Darwin" ]; then # OSX needs a lot of extra help, poor thing # run the osx_environment.sh script to fix paths . ./osx_environment.sh - B_CMAKE_FLAGS="-DCMAKE_OSX_SYSROOT=$(xcode-select --print-path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 $B_CMAKE_FLAGS" + B_CMAKE_FLAGS="-DCMAKE_OSX_SYSROOT=$(xcode-select --print-path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 $B_CMAKE_FLAGS" fi # allow local customizations to build environment [ -r ./build_env.sh ] && . ./build_env.sh From c32ca2195de7280371f054259f457a34c95eaf23 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 8 Dec 2020 13:46:56 +1000 Subject: [PATCH 003/113] barrier: split the platform-specific argument parsing Instead of one function with several ifdefs, split into several functions to make the code more readable. No functional changes. --- src/lib/barrier/ArgParser.cpp | 41 ++++++++++++++++++++++++++--------- src/lib/barrier/ArgParser.h | 3 +++ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/lib/barrier/ArgParser.cpp b/src/lib/barrier/ArgParser.cpp index 5bf08b6c..9cd1b8da 100644 --- a/src/lib/barrier/ArgParser.cpp +++ b/src/lib/barrier/ArgParser.cpp @@ -133,10 +133,10 @@ ArgParser::parseClientArgs(ClientArgs& args, int argc, const char* const* argv) return true; } -bool -ArgParser::parsePlatformArg(ArgsBase& argsBase, const int& argc, const char* const* argv, int& i) -{ #if WINAPI_MSWINDOWS +bool +ArgParser::parseMSWindowsArg(ArgsBase& argsBase, const int& argc, const char* const* argv, int& i) +{ if (isArg(i, argc, argv, NULL, "--service")) { LOG((CLOG_WARN "obsolete argument --service, use barrierd instead.")); argsBase.m_shouldExit = true; @@ -153,25 +153,46 @@ ArgParser::parsePlatformArg(ArgsBase& argsBase, const int& argc, const char* con } return true; -#elif WINAPI_XWINDOWS +} +#endif + +#if WINAPI_CARBON +bool +ArgParser::parseCarbonArg(ArgsBase& argsBase, const int& argc, const char* const* argv, int& i) +{ + // no options for carbon + return false; +} +#endif + +#if WINAPI_XWINDOWS +bool +ArgParser::parseXWindowsArg(ArgsBase& argsBase, const int& argc, const char* const* argv, int& i) +{ if (isArg(i, argc, argv, "-display", "--display", 1)) { // use alternative display argsBase.m_display = argv[++i]; } - else if (isArg(i, argc, argv, NULL, "--no-xinitthreads")) { argsBase.m_disableXInitThreads = true; - } - - else { + } else { // option not supported here return false; } return true; +} +#endif + +bool +ArgParser::parsePlatformArg(ArgsBase& argsBase, const int& argc, const char* const* argv, int& i) +{ +#if WINAPI_MSWINDOWS + return parseMSWindowsArg(argsBase, argc, argv, i); #elif WINAPI_CARBON - // no options for carbon - return false; + return parseCarbonArg(argsBase, argc, argv, i); +#elif WINAPI_XWINDOWS + return parseXWindowsArg(argsBase, argc, argv, i); #endif } diff --git a/src/lib/barrier/ArgParser.h b/src/lib/barrier/ArgParser.h index 239a20cd..c8e9e68d 100644 --- a/src/lib/barrier/ArgParser.h +++ b/src/lib/barrier/ArgParser.h @@ -53,6 +53,9 @@ private: bool checkUnexpectedArgs(); static ArgsBase& argsBase() { return *m_argsBase; } + bool parseMSWindowsArg(ArgsBase& argsBase, const int& argc, const char* const* argv, int& i); + bool parseCarbonArg(ArgsBase& argsBase, const int& argc, const char* const* argv, int& i); + bool parseXWindowsArg(ArgsBase& argsBase, const int& argc, const char* const* argv, int& i); private: App* m_app; From dec895e8d3a0838272e694d392416e59c058938c Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 10 Dec 2020 10:10:36 +1000 Subject: [PATCH 004/113] cmake: move two windows #defines to the main cmake file We have a check for windows here anyway, let's move the defines here and we can drop it in the common header file. And since on Unix HAVE_CONFIG_H is always defined, we can drop the else condition too. --- CMakeLists.txt | 2 ++ src/lib/common/common.h | 7 +------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c56b30be..b90e790b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -292,6 +292,8 @@ elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows") list (APPEND libs Wtsapi32 Userenv Wininet comsuppw Shlwapi) add_definitions ( + /DSYSAPI_WIN32=1 + /DWINAPI_MSWINDOWS=1 /DWIN32 /D_WINDOWS /D_CRT_SECURE_NO_WARNINGS diff --git a/src/lib/common/common.h b/src/lib/common/common.h index 5eac5684..2feea235 100644 --- a/src/lib/common/common.h +++ b/src/lib/common/common.h @@ -18,13 +18,8 @@ #pragma once -#if defined(_WIN32) -# define SYSAPI_WIN32 1 -# define WINAPI_MSWINDOWS 1 -#elif HAVE_CONFIG_H +#if HAVE_CONFIG_H # include "config.h" -#else -# error "config.h missing" #endif // VC++ has built-in sized types From 962d5e1c133457f0ac909f4a9b469c1ca4bac25b Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Tue, 31 Aug 2021 19:59:27 +0100 Subject: [PATCH 005/113] Replace (Markdown) template for bug reports with a GitHub issue form This will make bug reports more structured, and easier for triagers and maintainers to work with. Signed-off-by: Dom Rodriguez --- .github/ISSUE_TEMPLATE/bug_report.md | 36 ------------- .github/ISSUE_TEMPLATE/bug_report.yaml | 70 ++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 36 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yaml diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 8ea04d7f..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -name: Bug report -about: Please fill in this template as much as you can, to help us, help you. -title: '' -labels: '' -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** - -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -Please do not link to image hosting sites, as these can be ephemeral. Instead, attach them to the issue. - -**Desktop (please complete the following information):** - - - OS: [e.g. Windows] -- Barrier version [e.g 2.3.3] - -**Additional context** - -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml new file mode 100644 index 00000000..ff47b93f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -0,0 +1,70 @@ +name: Bug Report +description: File a bug report (ideally refrain from questions, please use IRC or Matrix for those) +title: "[Bug]: " +labels: [bug, triage] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! + - type: textarea + id: what-happened + attributes: + label: What happened? + description: Also tell us, what did you expect to happen? + placeholder: Tell us what you see! Screenshots are also helpful - please attach to the issue. + value: "A bug happened!" + validations: + required: true + - type: dropdown + id: version + attributes: + label: Version + description: What version of Barrier are you runnning? + options: + - v2.0.0-RC1 + - v2.0.0-RC2 + - v2.0.0 + - v2.1.1 + - v2.1.2 + - v2.3.0 + - v2.3.1 + - v2.3.2-alpha + - v2.3.2 + - v2.3.3 + - From Git HEAD or commit (specify below) + validations: + required: true + - type: input + id: git-commit-if + attributes: + label: Git commit hash (if applicable) + description: "When building Barrier from Git, what commit hash did you checkout from?" + placeholder: b0c0b42b + validations: + required: false + - type: dropdown + id: os + attributes: + label: What OSes are you seeing the problem on? (Check all that apply). + multiple: true + options: + - Linux + - Windows + - macOS + validations: + required: true + - type: textarea + id: os-version + attributes: + label: What OS versions are you using? + description: This applies to both client(s) and the server. + validations: + required: true +- type: textarea + id: logs + attributes: + label: Relevant log output + description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. + render: shell + From 2f6aa21bfe99a94822bcd3a2837e44ff096854f7 Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Thu, 2 Sep 2021 17:28:38 +0100 Subject: [PATCH 006/113] Description changed to new approach for Barrier support Signed-off-by: Dom Rodriguez --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index ff47b93f..eeb0dcd1 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -1,5 +1,5 @@ name: Bug Report -description: File a bug report (ideally refrain from questions, please use IRC or Matrix for those) +description: File a bug report (for questions, ideas & support, use the Discussions tab, or IRC for quick answers, but make sure to stay on the channel!) title: "[Bug]: " labels: [bug, triage] body: From e26a5c376e3985f2419d908eb00af3959541cef2 Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Thu, 2 Sep 2021 17:30:45 +0100 Subject: [PATCH 007/113] Screenshots to be avoided on imgur Signed-off-by: Dom Rodriguez --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index eeb0dcd1..99fb8fe6 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -12,7 +12,7 @@ body: attributes: label: What happened? description: Also tell us, what did you expect to happen? - placeholder: Tell us what you see! Screenshots are also helpful - please attach to the issue. + placeholder: Tell us what you see! Screenshots are also helpful - please attach to the issue, rather than linking to image hosting sites. value: "A bug happened!" validations: required: true From eb3f2741d9f38ec47001e00fc018b53d00bd451f Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Thu, 2 Sep 2021 17:34:10 +0100 Subject: [PATCH 008/113] Adjust YML indentation Signed-off-by: Dom Rodriguez --- .github/ISSUE_TEMPLATE/bug_report.yaml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 99fb8fe6..2c2d772c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -38,11 +38,11 @@ body: - type: input id: git-commit-if attributes: - label: Git commit hash (if applicable) - description: "When building Barrier from Git, what commit hash did you checkout from?" - placeholder: b0c0b42b + label: Git commit hash (if applicable) + description: "When building Barrier from Git, what commit hash did you checkout from?" + placeholder: b0c0b42b validations: - required: false + required: false - type: dropdown id: os attributes: @@ -53,18 +53,17 @@ body: - Windows - macOS validations: - required: true + required: true - type: textarea id: os-version attributes: - label: What OS versions are you using? - description: This applies to both client(s) and the server. + label: What OS versions are you using? + description: This applies to both client(s) and the server. validations: - required: true -- type: textarea + required: true + - type: textarea id: logs attributes: label: Relevant log output description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. render: shell - From 85d995ff23673aedbe342f49ae77e890bcc43c46 Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Thu, 2 Sep 2021 17:34:26 +0100 Subject: [PATCH 009/113] Add package manager question Signed-off-by: Dom Rodriguez --- .github/ISSUE_TEMPLATE/bug_report.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 2c2d772c..d4fb12c7 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -43,6 +43,13 @@ body: placeholder: b0c0b42b validations: required: false + - type: textarea + id: pkg-mgr-origin + attributes: + label: If applicable, where did you install Barrier from? + description: This includes Snaps, Flatpaks, and self-built executables. + validations: + required: false - type: dropdown id: os attributes: From b3d4da9c0de45854a4c591ffca3a298ed5f7a0da Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Thu, 2 Sep 2021 17:35:46 +0100 Subject: [PATCH 010/113] Add misc information question (not required) Signed-off-by: Dom Rodriguez --- .github/ISSUE_TEMPLATE/bug_report.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index d4fb12c7..f1849a13 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -74,3 +74,8 @@ body: label: Relevant log output description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. render: shell + - type: textarea + id: misc-info + attributes: + label: Any other information + description: Please enter any other information we should know, if applicable. From 163fe9b329d3cdee6d581b4523f970d33ef9762c Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Thu, 2 Sep 2021 17:38:56 +0100 Subject: [PATCH 011/113] Remove value key for What Happened Signed-off-by: Dom Rodriguez --- .github/ISSUE_TEMPLATE/bug_report.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index f1849a13..10323c97 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -13,7 +13,6 @@ body: label: What happened? description: Also tell us, what did you expect to happen? placeholder: Tell us what you see! Screenshots are also helpful - please attach to the issue, rather than linking to image hosting sites. - value: "A bug happened!" validations: required: true - type: dropdown From 87bdfd4e98c348de658c96c243ce9c2d1f5f2c17 Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Thu, 2 Sep 2021 17:44:01 +0100 Subject: [PATCH 012/113] Add configuration for new issue chooser Signed-off-by: Dom Rodriguez --- .github/ISSUE_TEMPLATE/config.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..380870d2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Discussions: + url: https://github.com/debauchee/barrier/discussions + about: Please use the discussions tab for support and ideas/suggestions. + - name: Pull requests: + url: https://github.com/debauchee/barrier/pulls + about: Please submit pull requests here. From a75da358547ffa811916a0f8a7d4463e4633ed9f Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Thu, 2 Sep 2021 17:45:17 +0100 Subject: [PATCH 013/113] Remove external links - maybe that's the issue? Signed-off-by: Dom Rodriguez --- .github/ISSUE_TEMPLATE/config.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 380870d2..3ba13e0c 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,8 +1 @@ blank_issues_enabled: false -contact_links: - - name: Discussions: - url: https://github.com/debauchee/barrier/discussions - about: Please use the discussions tab for support and ideas/suggestions. - - name: Pull requests: - url: https://github.com/debauchee/barrier/pulls - about: Please submit pull requests here. From 690cd8b534d0fb2c4e7950c8cbf8df388f9fe46f Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Thu, 2 Sep 2021 17:50:39 +0100 Subject: [PATCH 014/113] Rename bug_report.yaml -> .yml Signed-off-by: Dom Rodriguez --- .github/ISSUE_TEMPLATE/{bug_report.yaml => bug_report.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{bug_report.yaml => bug_report.yml} (100%) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yml similarity index 100% rename from .github/ISSUE_TEMPLATE/bug_report.yaml rename to .github/ISSUE_TEMPLATE/bug_report.yml From 2ca88cbfa1676503df654f67b7ac390643efe3d0 Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Thu, 2 Sep 2021 17:51:13 +0100 Subject: [PATCH 015/113] Remove prepended title, unnecessary Signed-off-by: Dom Rodriguez --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 10323c97..c83e261e 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,6 +1,6 @@ name: Bug Report description: File a bug report (for questions, ideas & support, use the Discussions tab, or IRC for quick answers, but make sure to stay on the channel!) -title: "[Bug]: " +title: "" labels: [bug, triage] body: - type: markdown From 3a7439525416bebd01a8842c28fdcc8655f52f62 Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Thu, 2 Sep 2021 20:20:17 +0100 Subject: [PATCH 016/113] Fix string error - bug_report.yml Signed-off-by: Dom Rodriguez --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index c83e261e..727fd5b3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,6 +1,5 @@ name: Bug Report description: File a bug report (for questions, ideas & support, use the Discussions tab, or IRC for quick answers, but make sure to stay on the channel!) -title: "" labels: [bug, triage] body: - type: markdown From bf388b907e016a9c9ae421ce2d4aa28ae09ff7a4 Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Sat, 4 Sep 2021 16:15:07 +0100 Subject: [PATCH 017/113] Clarify screenshot attachment to issue Signed-off-by: Dom Rodriguez --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 727fd5b3..eb680af6 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -11,7 +11,7 @@ body: attributes: label: What happened? description: Also tell us, what did you expect to happen? - placeholder: Tell us what you see! Screenshots are also helpful - please attach to the issue, rather than linking to image hosting sites. + placeholder: Tell us what you see! Screenshots are also helpful - please attach to the issue (when created), rather than linking to image hosting sites. validations: required: true - type: dropdown From 9432743cea2a489f17dd0add513dafc4cfe9d944 Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Sat, 4 Sep 2021 16:15:22 +0100 Subject: [PATCH 018/113] Fix typo in template question Signed-off-by: Dom Rodriguez --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index eb680af6..c633103a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -51,7 +51,7 @@ body: - type: dropdown id: os attributes: - label: What OSes are you seeing the problem on? (Check all that apply). + label: What OSes are you seeing the problem on? (Check all that apply) multiple: true options: - Linux From 9bb25d8887ef24797d1893ce3ad2b38479e17d1e Mon Sep 17 00:00:00 2001 From: a1346054 <36859588+a1346054@users.noreply.github.com> Date: Wed, 22 Sep 2021 21:24:31 +0000 Subject: [PATCH 019/113] Use complete license file from gnu.org The current file is missing the 'How to Apply These Terms to Your New Programs' section, which is an integral part of the GPL. More info here: https://www.gnu.org/licenses/old-licenses/gpl-2.0-faq.html#GPLOmitPreamble File downloaded from: https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt --- LICENSE | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index acfef1bb..42498a45 100644 --- a/LICENSE +++ b/LICENSE @@ -3,7 +3,7 @@ Copyright (C) 2012-2016 Symless Ltd. Copyright (C) 2008-2014 Nick Bolton Copyright (C) 2002-2014 Chris Schoeneman -This program is released under the GPL with the additional exemption +This program is released under the GPL with the additional exemption that compiling, linking, and/or using OpenSSL is allowed. GNU GENERAL PUBLIC LICENSE @@ -286,3 +286,62 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 2 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, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. From 486545527bc8466a79ef4c9a5e12d29c7073a5d5 Mon Sep 17 00:00:00 2001 From: a1346054 <36859588+a1346054@users.noreply.github.com> Date: Wed, 22 Sep 2021 21:46:52 +0000 Subject: [PATCH 020/113] Fix shellcheck warnings --- clean_build.sh | 6 +++--- dist/macos/bundle/build_dist.sh.in | 16 ++++++++-------- dist/macos/bundle/build_installer.sh.in | 18 +++++++++--------- dist/macos/bundle/reref_dylibs.sh | 22 +++++++++++----------- osx_environment.sh | 4 ++-- res/makeicon.sh | 6 +++--- 6 files changed, 36 insertions(+), 36 deletions(-) diff --git a/clean_build.sh b/clean_build.sh index 3a92d8b9..585ca88b 100755 --- a/clean_build.sh +++ b/clean_build.sh @@ -1,10 +1,10 @@ #!/bin/sh -cd "$(dirname $0)" || exit 1 +cd "$(dirname "$0")" || exit 1 # some environments have cmake v2 as 'cmake' and v3 as 'cmake3' # check for cmake3 first then fallback to just cmake B_CMAKE=`type cmake3 2>/dev/null` if [ $? -eq 0 ]; then - B_CMAKE=`echo $B_CMAKE | cut -d' ' -f3` + B_CMAKE=`echo "$B_CMAKE" | cut -d' ' -f3` else B_CMAKE=cmake fi @@ -26,7 +26,7 @@ B_CMAKE_FLAGS="-DCMAKE_BUILD_TYPE=$B_BUILD_TYPE $B_CMAKE_FLAGS" rm -rf build mkdir build || exit 1 cd build || exit 1 -echo Starting Barrier $B_BUILD_TYPE build... +echo "Starting Barrier $B_BUILD_TYPE build..." $B_CMAKE $B_CMAKE_FLAGS .. || exit 1 make || exit 1 echo "Build completed successfully" diff --git a/dist/macos/bundle/build_dist.sh.in b/dist/macos/bundle/build_dist.sh.in index 3d5c333f..26a93201 100755 --- a/dist/macos/bundle/build_dist.sh.in +++ b/dist/macos/bundle/build_dist.sh.in @@ -1,7 +1,7 @@ #!/bin/sh # Use the same verbose variable as CMake -[ "$VERBOSE" == "1" ] && set -x +[ "$VERBOSE" = "1" ] && set -x # Exit on unset variables or pipe errors set -uo pipefail @@ -14,10 +14,10 @@ B_BARRIERC="Barrier.app/Contents/MacOS/barrierc" B_BARRIERS="Barrier.app/Contents/MacOS/barriers" # Colorized output -function info() { tput bold; echo "$@" ; tput sgr0 ;} -function error() { tput bold; tput setaf 1; echo "$@"; tput sgr0 ; } -function success() { tput bold; tput setaf 2; echo "$@"; tput sgr0 ; } -function warn() { tput bold; tput setaf 3; echo "$@"; tput sgr0 ; } +info() { tput bold; echo "$@"; tput sgr0 ; } +error() { tput bold; tput setaf 1; echo "$@"; tput sgr0 ; } +success() { tput bold; tput setaf 2; echo "$@"; tput sgr0 ; } +warn() { tput bold; tput setaf 3; echo "$@"; tput sgr0 ; } info "Checking for bundle contents" if [ ! -d "Barrier.app/Contents" ]; then @@ -40,7 +40,7 @@ if which -s port ; then info "MacPorts found, searching for macdeployqt" DEPLOYQT="$(port contents qt5-qttools | grep --only --max-count 1 '/.*macdeployqt')" if [ ! -x "$DEPLOYQT" ]; then - error Please install package qt5-qttools + error "Please install package qt5-qttools" exit 1 fi fi @@ -50,13 +50,13 @@ if which -s brew ; then info "Homebrew found, searching for macdeployqt" DEPLOYQT="$(brew list qt@5 | grep --only '/.*macdeployqt' | head -1)" if [ ! -x "$DEPLOYQT" ]; then - error Please install package qt + error "Please install package qt" exit 1 fi fi # Use macdeployqt to include libraries and create dmg -if [ "$B_BUILDTYPE" == "Release" ]; then +if [ "$B_BUILDTYPE" = "Release" ]; then info "Building Release disk image (dmg)" "$DEPLOYQT" Barrier.app -dmg \ -executable="$B_BARRIERC" \ diff --git a/dist/macos/bundle/build_installer.sh.in b/dist/macos/bundle/build_installer.sh.in index 0d2ccfc7..c1fd3fc2 100755 --- a/dist/macos/bundle/build_installer.sh.in +++ b/dist/macos/bundle/build_installer.sh.in @@ -1,30 +1,30 @@ #!/bin/sh # add warning for users running manually -function warn() { tput bold; tput setaf 3; echo "$@"; tput sgr0 ; } +warn() { tput bold; tput setaf 3; echo "$@"; tput sgr0 ; } warn "The scripts build_installer.sh and reref_dylibs.sh have been deprecated." warn "Please use build_dist.sh instead to deploy using macdeployqt" # change this to rename the installer package B_DMG="Barrier-@BARRIER_VERSION@.dmg" -cd "$( dirname '$0' )" +cd "$( dirname "$0" )" OWNDIR="$( pwd )" B_REREF_SCRIPT="$OWNDIR/reref_dylibs.sh" -if [ ! -x $B_REREF_SCRIPT ]; then - echo Missing script: $B_REREF_SCRIPT +if [ ! -x "$B_REREF_SCRIPT" ]; then + echo "Missing script: $B_REREF_SCRIPT" exit 1 fi # remove any old copies so there's no confusion about whether this # process completes successfully or not -rm -rf temp.dmg $B_DMG +rm -rf temp.dmg "$B_DMG" cd Barrier.app/Contents 2>/dev/null if [ $? -ne 0 ]; then - echo Please make sure that the build completed successfully - echo before trying to create the installer. + echo "Please make sure that the build completed successfully" + echo "before trying to create the installer." exit 1 fi @@ -77,7 +77,7 @@ hdiutil create -size 64m -fs HFS+ -volname "Barrier" temp.dmg || exit 1 hdiutil attach temp.dmg -mountpoint mnt || exit 1 cp -r Barrier.app mnt/ || exit 1 hdiutil detach mnt || exit 1 -hdiutil convert temp.dmg -format UDZO -o $B_DMG || exit 1 +hdiutil convert temp.dmg -format UDZO -o "$B_DMG" || exit 1 rm temp.dmg -echo "dmg $B_DMB created successfully" +echo "dmg $B_DMG created successfully" diff --git a/dist/macos/bundle/reref_dylibs.sh b/dist/macos/bundle/reref_dylibs.sh index 029ca4ae..71a9ba03 100755 --- a/dist/macos/bundle/reref_dylibs.sh +++ b/dist/macos/bundle/reref_dylibs.sh @@ -5,28 +5,28 @@ B_TARGET=$1 if [ "x$B_TARGET" = "x" ]; then # add warning for users running manually - function warn() { tput bold; tput setaf 3; echo "$@"; tput sgr0 ; } + warn() { tput bold; tput setaf 3; echo "$@"; tput sgr0 ; } warn "The scripts build_installer.sh and reref_dylibs.sh have been deprecated." warn "Please use build_dist.sh instead to deploy using macdeployqt" - echo Which binary needs to be re-referenced? + echo "Which binary needs to be re-referenced?" exit 1 fi -cd $(dirname $B_TARGET) || exit 1 +cd "$(dirname "$B_TARGET")" || exit 1 # where to find non-system libraries relative to target's directory. # the vast majority of the time this should be empty B_REL_PATH=$2 # we're in target's directory now. trim off the path -B_TARGET=$(basename $B_TARGET) +B_TARGET=$(basename "$B_TARGET") # get a list of non-system libraries and make local copies -B_LIBS=$(otool -XL $B_TARGET | awk '{ print $1 }' | grep -Ev '^(/usr/lib|/System)') +B_LIBS=$(otool -XL "$B_TARGET" | awk '{ print $1 }' | grep -Ev '^(/usr/lib|/System)') [ $? -ne 0 ] && exit 1 for B_LIB in $B_LIBS; do - B_LIB_NAME=$(basename $B_LIB) + B_LIB_NAME=$(basename "$B_LIB") # otool reports barrier as "barrier:" which fails self-reference test below B_LIB_NAME=${B_LIB_NAME//:} @@ -34,16 +34,16 @@ for B_LIB in $B_LIBS; do [ "$B_TARGET" = "$B_LIB_NAME" ] && continue B_DST=${B_REL_PATH}${B_LIB_NAME} - if [ ! -e $B_DST ]; then - cp $B_LIB $B_DST || exit 1 - chmod u+rw $B_DST || exit 1 + if [ ! -e "$B_DST" ]; then + cp "$B_LIB" "$B_DST" || exit 1 + chmod u+rw "$B_DST" || exit 1 # recursively call this script on libraries purposefully not passing # $B_REL_PATH so that it is only used explicitly - $0 $B_DST + $0 "$B_DST" fi # adjust the target's metadata to point to the local copy # rather than the system-wide copy which would only exist on # a development machine - install_name_tool -change $B_LIB @loader_path/$B_DST $B_TARGET || exit 1 + install_name_tool -change "$B_LIB" "@loader_path/$B_DST" "$B_TARGET" || exit 1 done diff --git a/osx_environment.sh b/osx_environment.sh index 0c725fb1..137eb8ba 100644 --- a/osx_environment.sh +++ b/osx_environment.sh @@ -1,7 +1,7 @@ #!/bin/bash # Checks if directory exists, otherwise asks to install package. -function check_dir_exists() { +check_dir_exists() { local path=$1 local package=$2 @@ -11,7 +11,7 @@ function check_dir_exists() { fi } -if [ ! $BARRIER_BUILD_ENV ]; then +if [ -z "$BARRIER_BUILD_ENV" ]; then check_dir_exists '/Applications/Xcode.app' 'Xcode' printf "Modifying environment for Barrier build...\n" diff --git a/res/makeicon.sh b/res/makeicon.sh index 2883755c..4ef87682 100755 --- a/res/makeicon.sh +++ b/res/makeicon.sh @@ -4,7 +4,7 @@ if ! which magick >/dev/null 2>&1; then echo "Need ImageMagic for this" exit 10 fi -cd $(dirname $0) || exit $? +cd "$(dirname "$0")" || exit $? if [ ! -r barrier.png ]; then echo "Use inkscape (or another vector graphics editor) to create barrier.png from barrier.svg first" exit 10 @@ -12,11 +12,11 @@ fi rm -rf work || exit $? mkdir -p work || exit $? for s in 16 24 32 48 64 128 256 512 1024; do - magick convert barrier.png -resize ${s}x${s} -depth 8 work/${s}.png || exit $? + magick convert barrier.png -resize "${s}x${s}" -depth 8 "work/${s}.png" || exit $? done # windows icon magick convert work/{16,24,32,48,64,128}.png barrier.png barrier.ico || exit $? # macos icon -png2icns $ICNS_BASE/Barrier.icns work/{16,32,256,512,1024}.png || exit $? +png2icns "$ICNS_BASE/Barrier.icns" work/{16,32,256,512,1024}.png || exit $? rm -rf work echo Done From 3aee8dd3418e0748118ea71c381d879f451cd67b Mon Sep 17 00:00:00 2001 From: a1346054 <36859588+a1346054@users.noreply.github.com> Date: Wed, 22 Sep 2021 20:38:57 +0000 Subject: [PATCH 021/113] Add missing final newline --- _config.yml | 2 +- doc/newsfragments/gui-keyboard-enabled-screen-layout.feature | 2 +- src/lib/arch/ArchConsoleStd.cpp | 2 +- src/lib/arch/win32/ArchTaskBarWindows.cpp | 2 +- src/lib/platform/IMSWindowsClipboardFacade.h | 2 +- src/lib/platform/ImmuneKeysReader.cpp | 2 +- src/lib/platform/MSWindowsHookResource.cpp | 2 +- src/lib/platform/MSWindowsHookResource.h | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/_config.yml b/_config.yml index c7418817..f980e760 100644 --- a/_config.yml +++ b/_config.yml @@ -1 +1 @@ -theme: jekyll-theme-slate \ No newline at end of file +theme: jekyll-theme-slate diff --git a/doc/newsfragments/gui-keyboard-enabled-screen-layout.feature b/doc/newsfragments/gui-keyboard-enabled-screen-layout.feature index 5ca3019e..7e495376 100644 --- a/doc/newsfragments/gui-keyboard-enabled-screen-layout.feature +++ b/doc/newsfragments/gui-keyboard-enabled-screen-layout.feature @@ -1 +1 @@ -Made it possible to use keyboard instead of mouse to modify screen layout. \ No newline at end of file +Made it possible to use keyboard instead of mouse to modify screen layout. diff --git a/src/lib/arch/ArchConsoleStd.cpp b/src/lib/arch/ArchConsoleStd.cpp index adb2d010..2e188bb5 100644 --- a/src/lib/arch/ArchConsoleStd.cpp +++ b/src/lib/arch/ArchConsoleStd.cpp @@ -30,4 +30,4 @@ ArchConsoleStd::writeConsole(ELevel level, const char* str) std::cout << str << std::endl; std::cout.flush(); -} \ No newline at end of file +} diff --git a/src/lib/arch/win32/ArchTaskBarWindows.cpp b/src/lib/arch/win32/ArchTaskBarWindows.cpp index c406124a..1d8eac18 100644 --- a/src/lib/arch/win32/ArchTaskBarWindows.cpp +++ b/src/lib/arch/win32/ArchTaskBarWindows.cpp @@ -511,4 +511,4 @@ ArchTaskBarWindows::threadEntry(void* self) HINSTANCE ArchTaskBarWindows::instanceWin32() { return ArchMiscWindows::instanceWin32(); -} \ No newline at end of file +} diff --git a/src/lib/platform/IMSWindowsClipboardFacade.h b/src/lib/platform/IMSWindowsClipboardFacade.h index 1c314736..d848184a 100644 --- a/src/lib/platform/IMSWindowsClipboardFacade.h +++ b/src/lib/platform/IMSWindowsClipboardFacade.h @@ -33,4 +33,4 @@ public: virtual ~IMSWindowsClipboardFacade() { } }; -#endif \ No newline at end of file +#endif diff --git a/src/lib/platform/ImmuneKeysReader.cpp b/src/lib/platform/ImmuneKeysReader.cpp index 72baed3c..eaeedc17 100644 --- a/src/lib/platform/ImmuneKeysReader.cpp +++ b/src/lib/platform/ImmuneKeysReader.cpp @@ -50,4 +50,4 @@ static void add_key(const char * const buffer, std::vector &keys) } } return true; -} \ No newline at end of file +} diff --git a/src/lib/platform/MSWindowsHookResource.cpp b/src/lib/platform/MSWindowsHookResource.cpp index ced5ff12..c6349ab3 100644 --- a/src/lib/platform/MSWindowsHookResource.cpp +++ b/src/lib/platform/MSWindowsHookResource.cpp @@ -30,4 +30,4 @@ bool WindowsHookResource::unset() } bool WindowsHookResource::is_set() const { return _hook != NULL; } -WindowsHookResource::operator HHOOK() const { return _hook; } \ No newline at end of file +WindowsHookResource::operator HHOOK() const { return _hook; } diff --git a/src/lib/platform/MSWindowsHookResource.h b/src/lib/platform/MSWindowsHookResource.h index b66c4b8c..a3c9d836 100644 --- a/src/lib/platform/MSWindowsHookResource.h +++ b/src/lib/platform/MSWindowsHookResource.h @@ -17,4 +17,4 @@ public: private: HHOOK _hook; -}; \ No newline at end of file +}; From 8c014b4bb6bbf365f27277c53d783245dd21b4b0 Mon Sep 17 00:00:00 2001 From: a1346054 <36859588+a1346054@users.noreply.github.com> Date: Wed, 22 Sep 2021 20:43:29 +0000 Subject: [PATCH 022/113] Fix spelling --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- README.md | 2 +- clean_build.bat | 2 +- doc/barrier.conf.example-advanced | 2 +- res/Readme.txt | 2 +- res/makeicon.sh | 2 +- src/cmd/barrierd/barrierd.rc | 2 +- src/gui/src/MainWindow.cpp | 4 +- src/gui/src/ServerConfigDialog.cpp | 2 +- src/gui/src/SetupWizard.cpp | 2 +- src/gui/src/SslCertificate.cpp | 2 +- src/lib/arch/win32/ArchInternetWindows.cpp | 2 +- src/lib/arch/win32/XArchWindows.cpp | 4 +- src/lib/barrier/IScreenSaver.h | 2 +- src/lib/barrier/protocol_types.h | 4 +- src/lib/base/Log.cpp | 2 +- src/lib/client/Client.h | 2 +- src/lib/common/win32/DataDirectories.cpp | 2 +- src/lib/mt/Thread.h | 4 +- src/lib/net/NetworkAddress.h | 2 +- src/lib/net/SecureSocket.cpp | 6 +- src/lib/platform/MSWindowsDesks.cpp | 2 +- src/lib/platform/MSWindowsKeyState.cpp | 2 +- src/lib/platform/MSWindowsWatchdog.h | 2 +- src/lib/platform/OSXClipboard.cpp | 2 +- src/lib/platform/OSXDragSimulator.m | 24 +-- src/lib/platform/OSXScreen.mm | 198 ++++++++++----------- src/lib/platform/XWindowsScreenSaver.h | 2 +- src/lib/server/Server.cpp | 4 +- src/lib/server/Server.h | 4 +- 30 files changed, 147 insertions(+), 147 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index c633103a..208e7058 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -18,7 +18,7 @@ body: id: version attributes: label: Version - description: What version of Barrier are you runnning? + description: What version of Barrier are you running? options: - v2.0.0-RC1 - v2.0.0-RC2 diff --git a/README.md b/README.md index 3ec09b62..0c49fbb5 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ A: Start the binary with the argument `--config ` Q: After loading my configuration on the client the field 'Server IP' is still empty! -A: Edit your configuration to include the servers ip adress manually with +A: Edit your configuration to include the server's ip address manually with (...) section: options serverhostname= diff --git a/clean_build.bat b/clean_build.bat index 4416a7e9..79fce047 100644 --- a/clean_build.bat +++ b/clean_build.bat @@ -65,7 +65,7 @@ if exist bin\Debug ( mkdir bin\Release\platforms copy %B_QT_FULLPATH%\plugins\platforms\qwindows.dll bin\Release\platforms\ > NUL ) else ( - echo Remember to copy supporting binaries and confiuration files! + echo Remember to copy supporting binaries and configuration files! ) echo Build completed successfully diff --git a/doc/barrier.conf.example-advanced b/doc/barrier.conf.example-advanced index b3d6ad69..e1b23924 100644 --- a/doc/barrier.conf.example-advanced +++ b/doc/barrier.conf.example-advanced @@ -47,7 +47,7 @@ section: links end # The aliases section is to map the full names of the computers to their logical names used in the screens section -# One way to find the actual name of a comptuer is to run hostname from a command window +# One way to find the actual name of a computer is to run hostname from a command window section: aliases # Laptop is actually known as John-Smiths-MacBook-3.local John-Smiths-MacBook-3.local: diff --git a/res/Readme.txt b/res/Readme.txt index 0b2802bd..9cfcf3c3 100644 --- a/res/Readme.txt +++ b/res/Readme.txt @@ -1,4 +1,4 @@ -Thank you for chosing Barrier! +Thank you for choosing Barrier! https://github.com/debauchee/barrier/ Barrier allows you to share your keyboard and mouse between computers over a network. diff --git a/res/makeicon.sh b/res/makeicon.sh index 4ef87682..cfebe308 100755 --- a/res/makeicon.sh +++ b/res/makeicon.sh @@ -1,7 +1,7 @@ #!/bin/sh ICNS_BASE=../dist/macos/bundle/Barrier.app/Contents/Resources if ! which magick >/dev/null 2>&1; then - echo "Need ImageMagic for this" + echo "Need ImageMagick for this" exit 10 fi cd "$(dirname "$0")" || exit $? diff --git a/src/cmd/barrierd/barrierd.rc b/src/cmd/barrierd/barrierd.rc index df31e5f6..c5ad5022 100644 --- a/src/cmd/barrierd/barrierd.rc +++ b/src/cmd/barrierd/barrierd.rc @@ -73,7 +73,7 @@ BEGIN VALUE "ProductName", "Barrier" VALUE "ProductVersion", BARRIER_VERSION VALUE "OriginalFilename", "barrierd.exe" - VALUE "FileDescription", "Open source KVM software deamon" + VALUE "FileDescription", "Open source KVM software daemon" VALUE "InternalName", "barrierd" END END diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index a3962aa8..d74bb66a 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -624,7 +624,7 @@ QString MainWindow::configFilename() if (m_pRadioInternalConfig->isChecked()) { // TODO: no need to use a temporary file, since we need it to - // be permenant (since it'll be used for Windows services, etc). + // be permanent (since it'll be used for Windows services, etc). m_pTempConfigFile = new QTemporaryFile(); if (!m_pTempConfigFile->open()) { @@ -729,7 +729,7 @@ void MainWindow::stopBarrier() void MainWindow::stopService() { - // send empty command to stop service from laucning anything. + // send empty command to stop service from launching anything. m_IpcClient.sendCommand("", appConfig().elevateMode()); } diff --git a/src/gui/src/ServerConfigDialog.cpp b/src/gui/src/ServerConfigDialog.cpp index a727f331..84c20470 100644 --- a/src/gui/src/ServerConfigDialog.cpp +++ b/src/gui/src/ServerConfigDialog.cpp @@ -76,7 +76,7 @@ void ServerConfigDialog::showEvent(QShowEvent* event) if (!m_Message.isEmpty()) { - // TODO: ideally this massage box should pop up after the dialog is shown + // TODO: ideally this message box should pop up after the dialog is shown QMessageBox::information(this, tr("Configure server"), m_Message); } } diff --git a/src/gui/src/SetupWizard.cpp b/src/gui/src/SetupWizard.cpp index cd13c7c4..262d63c8 100644 --- a/src/gui/src/SetupWizard.cpp +++ b/src/gui/src/SetupWizard.cpp @@ -37,7 +37,7 @@ SetupWizard::SetupWizard(MainWindow& mainWindow, bool startMain) : #elif defined(Q_OS_WIN) - // when areo is disabled on windows, the next/back buttons + // when aero is disabled on windows, the next/back buttons // are hidden (must be a qt bug) -- resizing the window // to +1 of the original height seems to fix this. // NOTE: calling setMinimumSize after this will break diff --git a/src/gui/src/SslCertificate.cpp b/src/gui/src/SslCertificate.cpp index de3eea67..84ce5459 100644 --- a/src/gui/src/SslCertificate.cpp +++ b/src/gui/src/SslCertificate.cpp @@ -106,7 +106,7 @@ void SslCertificate::generateCertificate() arguments.append("-x509"); arguments.append("-nodes"); - // valide duration + // valid duration arguments.append("-days"); arguments.append(kCertificateLifetime); diff --git a/src/lib/arch/win32/ArchInternetWindows.cpp b/src/lib/arch/win32/ArchInternetWindows.cpp index df08afa7..fb75e7df 100644 --- a/src/lib/arch/win32/ArchInternetWindows.cpp +++ b/src/lib/arch/win32/ArchInternetWindows.cpp @@ -72,7 +72,7 @@ std::string ArchInternetWindows::urlEncode(const std::string& url) std::string result(buffer); - // the win32 url encoding funcitons are pretty useless (to us) and only + // the win32 url encoding functions are pretty useless (to us) and only // escape "unsafe" chars, but not + or =, so we need to replace these // manually (and probably many other chars). barrier::string::findReplaceAll(result, "+", "%2B"); diff --git a/src/lib/arch/win32/XArchWindows.cpp b/src/lib/arch/win32/XArchWindows.cpp index 9391a375..b7361ab6 100644 --- a/src/lib/arch/win32/XArchWindows.cpp +++ b/src/lib/arch/win32/XArchWindows.cpp @@ -83,7 +83,7 @@ XArchEvalWinsock::eval() const noexcept /* 10052 */{WSAENETRESET, "The connection must be reset because the Windows Sockets implementation dropped it"}, /* 10053 */{WSAECONNABORTED, "The virtual circuit was aborted due to timeout or other failure"}, /* 10054 */{WSAECONNRESET, "The virtual circuit was reset by the remote side"}, - /* 10055 */{WSAENOBUFS, "No buffer space is available or a buffer deadlock has occured. The socket cannot be created"}, + /* 10055 */{WSAENOBUFS, "No buffer space is available or a buffer deadlock has occurred. The socket cannot be created"}, /* 10056 */{WSAEISCONN, "The socket is already connected"}, /* 10057 */{WSAENOTCONN, "The socket is not connected"}, /* 10058 */{WSAESHUTDOWN, "The socket has been shutdown"}, @@ -100,7 +100,7 @@ XArchEvalWinsock::eval() const noexcept /* 10069 */{WSAEDQUOT, "Undocumented WinSock error code"}, /* 10070 */{WSAESTALE, "Undocumented WinSock error code"}, /* 10071 */{WSAEREMOTE, "Undocumented WinSock error code"}, - /* 10091 */{WSASYSNOTREADY, "Underlying network subsytem is not ready for network communication"}, + /* 10091 */{WSASYSNOTREADY, "Underlying network subsystem is not ready for network communication"}, /* 10092 */{WSAVERNOTSUPPORTED, "The version of WinSock API support requested is not provided in this implementation"}, /* 10093 */{WSANOTINITIALISED, "WinSock subsystem not properly initialized"}, /* 10101 */{WSAEDISCON, "Virtual circuit has gracefully terminated connection"}, diff --git a/src/lib/barrier/IScreenSaver.h b/src/lib/barrier/IScreenSaver.h index 475f9f83..2099f6d1 100644 --- a/src/lib/barrier/IScreenSaver.h +++ b/src/lib/barrier/IScreenSaver.h @@ -56,7 +56,7 @@ public: //! Deactivate screen saver /*! - Deactivate (i.e. hide) the screen saver, reseting the screen saver + Deactivate (i.e. hide) the screen saver, resetting the screen saver timer. */ virtual void deactivate() = 0; diff --git a/src/lib/barrier/protocol_types.h b/src/lib/barrier/protocol_types.h index 7ed0d070..ccc1c3ea 100644 --- a/src/lib/barrier/protocol_types.h +++ b/src/lib/barrier/protocol_types.h @@ -267,8 +267,8 @@ extern const char* kMsgDSetOptions; // 2 means the file transfer is finished. extern const char* kMsgDFileTransfer; -// drag infomation: primary <-> secondary -// transfer drag infomation. The first 2 bytes are used for storing +// drag information: primary <-> secondary +// transfer drag information. The first 2 bytes are used for storing // the number of dragging objects. Then the following string consists // of each object's directory. extern const char* kMsgDDragInfo; diff --git a/src/lib/base/Log.cpp b/src/lib/base/Log.cpp index 6a43521d..66a5364b 100644 --- a/src/lib/base/Log.cpp +++ b/src/lib/base/Log.cpp @@ -62,7 +62,7 @@ Log::Log() { assert(s_log == NULL); - // other initalization + // other initialization m_maxPriority = g_defaultMaxPriority; m_maxNewlineLength = 0; insert(new ConsoleLogOutputter); diff --git a/src/lib/client/Client.h b/src/lib/client/Client.h index 6979fc3a..ea9af253 100644 --- a/src/lib/client/Client.h +++ b/src/lib/client/Client.h @@ -119,7 +119,7 @@ public: */ NetworkAddress getServerAddress() const; - //! Return true if recieved file size is valid + //! Return true if received file size is valid bool isReceivedFileSizeValid(); //! Return expected file size diff --git a/src/lib/common/win32/DataDirectories.cpp b/src/lib/common/win32/DataDirectories.cpp index 3e86c59b..62250b10 100644 --- a/src/lib/common/win32/DataDirectories.cpp +++ b/src/lib/common/win32/DataDirectories.cpp @@ -45,7 +45,7 @@ const std::string& DataDirectories::global(const std::string& path) const std::string& DataDirectories::systemconfig() { // systemconfig() is a special case in that it will track the current value - // of global() unless and until it is explictly set otherwise + // of global() unless and until it is explicitly set otherwise // previously it would default to the windows folder which was horrible! if (_systemconfig.empty()) return global(); diff --git a/src/lib/mt/Thread.h b/src/lib/mt/Thread.h index dbde3afc..8179aea0 100644 --- a/src/lib/mt/Thread.h +++ b/src/lib/mt/Thread.h @@ -25,7 +25,7 @@ class IJob; //! Thread handle /*! Creating a Thread creates a new context of execution (i.e. thread) that -runs simulatenously with the calling thread. A Thread is only a handle +runs simultaneously with the calling thread. A Thread is only a handle to a thread; deleting a Thread does not cancel or destroy the thread it refers to and multiple Thread objects can refer to the same thread. @@ -122,7 +122,7 @@ public: /*! Change the priority of the thread. Normal priority is 0, 1 is the next lower, etc. -1 is the next higher, etc. but boosting - the priority may not be permitted and will be silenty ignored. + the priority may not be permitted and will be silently ignored. */ void setPriority(int n); diff --git a/src/lib/net/NetworkAddress.h b/src/lib/net/NetworkAddress.h index b572d757..3a006af5 100644 --- a/src/lib/net/NetworkAddress.h +++ b/src/lib/net/NetworkAddress.h @@ -43,7 +43,7 @@ public: If \c hostname can be parsed as a numerical address then that's how it's used, otherwise it's used as a host name. If \c hostname ends in ":[0-9]+" then that suffix is extracted and used as the port, - overridding the port parameter. The resulting port must be a valid + overriding the port parameter. The resulting port must be a valid port number (zero is not a valid port number) otherwise \c XSocketAddress is thrown with an error of \c XSocketAddress::kBadPort. The hostname is not resolved by the c'tor; use \c resolve to do that. diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index d84f3461..6982d0f1 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -658,7 +658,7 @@ SecureSocket::disconnect() void SecureSocket::formatFingerprint(std::string& fingerprint, bool hex, bool separator) { if (hex) { - // to hexidecimal + // to hexadecimal barrier::string::toHex(fingerprint, 2); } @@ -666,7 +666,7 @@ void SecureSocket::formatFingerprint(std::string& fingerprint, bool hex, bool se barrier::string::uppercase(fingerprint); if (separator) { - // add colon to separate each 2 charactors + // add colon to separate each 2 characters size_t separators = fingerprint.size() / 2; for (size_t i = 1; i < separators; i++) { fingerprint.insert(i * 3 - 1, ":"); @@ -830,7 +830,7 @@ SecureSocket::showSecureCipherInfo() } #if OPENSSL_VERSION_NUMBER < 0x10100000L - // m_ssl->m_ssl->session->ciphers is not forward compatable, + // m_ssl->m_ssl->session->ciphers is not forward compatible, // In future release of OpenSSL, it's not visible, STACK_OF(SSL_CIPHER) * cStack = m_ssl->m_ssl->session->ciphers; #else diff --git a/src/lib/platform/MSWindowsDesks.cpp b/src/lib/platform/MSWindowsDesks.cpp index be9a28d1..848ded78 100644 --- a/src/lib/platform/MSWindowsDesks.cpp +++ b/src/lib/platform/MSWindowsDesks.cpp @@ -803,7 +803,7 @@ MSWindowsDesks::checkDesk() // if active desktop changed then tell the old and new desk threads // about the change. don't switch desktops when the screensaver is - // active becaue we'd most likely switch to the screensaver desktop + // active because we'd most likely switch to the screensaver desktop // which would have the side effect of forcing the screensaver to // stop. if (name != m_activeDeskName && !m_screensaver->isActive()) { diff --git a/src/lib/platform/MSWindowsKeyState.cpp b/src/lib/platform/MSWindowsKeyState.cpp index e1072c40..05d0dde0 100644 --- a/src/lib/platform/MSWindowsKeyState.cpp +++ b/src/lib/platform/MSWindowsKeyState.cpp @@ -1330,7 +1330,7 @@ MSWindowsKeyState::getKeyID(UINT virtualKey, KeyButton button) const if ((LOWORD(m_keyLayout) & 0xffffu) == 0x0412u) { // 0x0412 : Korean Locale ID if (virtualKey == VK_HANGUL || virtualKey == VK_HANJA) { // If shift-space is used to change the input mode, - // the extented bit is not set. So add it to get right key id. + // the extended bit is not set. So add it to get right key id. button |= 0x100u; } } diff --git a/src/lib/platform/MSWindowsWatchdog.h b/src/lib/platform/MSWindowsWatchdog.h index 4e752c0c..d3741619 100644 --- a/src/lib/platform/MSWindowsWatchdog.h +++ b/src/lib/platform/MSWindowsWatchdog.h @@ -81,7 +81,7 @@ private: //! Relauncher error /*! -An error occured in the process watchdog. +An error occurred in the process watchdog. */ class XMSWindowsWatchdogError : public XBarrier { public: diff --git a/src/lib/platform/OSXClipboard.cpp b/src/lib/platform/OSXClipboard.cpp index ed995d0b..ff1779ce 100644 --- a/src/lib/platform/OSXClipboard.cpp +++ b/src/lib/platform/OSXClipboard.cpp @@ -52,7 +52,7 @@ OSXClipboard::OSXClipboard() : OSStatus syncErr = PasteboardSynchronize(m_pboard); if (syncErr != noErr) { - LOG((CLOG_DEBUG "failed to syncronize clipboard: error %i", syncErr)); + LOG((CLOG_DEBUG "failed to synchronize clipboard: error %i", syncErr)); } } diff --git a/src/lib/platform/OSXDragSimulator.m b/src/lib/platform/OSXDragSimulator.m index affed383..735aa4a1 100644 --- a/src/lib/platform/OSXDragSimulator.m +++ b/src/lib/platform/OSXDragSimulator.m @@ -30,9 +30,9 @@ void runCocoaApp() { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - + [NSApplication sharedApplication]; - + NSWindow* window = [[NSWindow alloc] initWithContentRect: NSMakeRect(0, 0, 3, 3) styleMask: NSBorderlessWindowMask @@ -41,16 +41,16 @@ runCocoaApp() [window setTitle: @""]; [window setAlphaValue:0.1]; [window makeKeyAndOrderFront:nil]; - + OSXDragView* dragView = [[OSXDragView alloc] initWithFrame:NSMakeRect(0, 0, 3, 3)]; - + g_dragWindow = window; g_dragView = dragView; [window setContentView: dragView]; - + NSLog(@"starting cocoa loop"); [NSApp run]; - + NSLog(@"cocoa: release"); [pool release]; } @@ -65,25 +65,25 @@ void fakeDragging(const char* str, int cursorX, int cursorY) { g_ext = [NSString stringWithUTF8String:str]; - + dispatch_async(dispatch_get_main_queue(), ^{ NSRect screen = [[NSScreen mainScreen] frame]; - NSLog ( @"screen size: witdh = %f height = %f", screen.size.width, screen.size.height); + NSLog ( @"screen size: width = %f height = %f", screen.size.width, screen.size.height); NSLog ( @"mouseLocation: %d %d", cursorX, cursorY); - + int newPosX = 0; int newPosY = 0; newPosX = cursorX - 1; newPosY = screen.size.height - cursorY - 1; - + NSRect rect = NSMakeRect(newPosX, newPosY, 3, 3); NSLog ( @"newPosX: %d", newPosX); NSLog ( @"newPosY: %d", newPosY); - + [g_dragWindow setFrame:rect display:NO]; [g_dragWindow makeKeyAndOrderFront:nil]; [NSApp activateIgnoringOtherApps:YES]; - + [g_dragView setFileExt:g_ext]; CGEventRef down = CGEventCreateMouseEvent(CGEventSourceCreate(kCGEventSourceStateHIDSystemState), kCGEventLeftMouseDown, CGPointMake(cursorX, cursorY), kCGMouseButtonLeft); diff --git a/src/lib/platform/OSXScreen.mm b/src/lib/platform/OSXScreen.mm index 2b4594ff..73e5b4ad 100644 --- a/src/lib/platform/OSXScreen.mm +++ b/src/lib/platform/OSXScreen.mm @@ -2,11 +2,11 @@ * barrier -- mouse and keyboard sharing utility * Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2004 Chris Schoeneman - * + * * This package is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * found in the file LICENSE that should have accompanied this file. - * + * * This package 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 @@ -110,10 +110,10 @@ OSXScreen::OSXScreen(IEventQueue* events, bool isPrimary, bool autoShowHideCurso updateScreenShape(m_displayID, 0); m_screensaver = new OSXScreenSaver(m_events, getEventTarget()); m_keyState = new OSXKeyState(m_events); - + // only needed when running as a server. if (m_isPrimary) { - + #if defined(MAC_OS_X_VERSION_10_9) // we can't pass options to show the dialog, this must be done by the gui. if (!AXIsProcessTrusted()) { @@ -126,7 +126,7 @@ OSXScreen::OSXScreen(IEventQueue* events, bool isPrimary, bool autoShowHideCurso } #endif } - + // install display manager notification handler CGDisplayRegisterReconfigurationCallback(displayReconfigurationCallback, this); @@ -166,7 +166,7 @@ OSXScreen::OSXScreen(IEventQueue* events, bool isPrimary, bool autoShowHideCurso if (m_switchEventHandlerRef != 0) { RemoveEventHandler(m_switchEventHandlerRef); } - + CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallback, this); delete m_keyState; @@ -217,7 +217,7 @@ OSXScreen::~OSXScreen() delete m_keyState; delete m_screensaver; - + #if defined(MAC_OS_X_VERSION_10_7) delete m_carbonLoopMutex; delete m_carbonLoopReady; @@ -273,7 +273,7 @@ OSXScreen::warpCursor(SInt32 x, SInt32 y) pos.x = x; pos.y = y; CGWarpMouseCursorPosition(pos); - + // save new cursor position m_xCursor = x; m_yCursor = y; @@ -325,7 +325,7 @@ OSXScreen::registerHotKey(KeyID key, KeyModifierMask mask) LOG((CLOG_DEBUG "could not map hotkey id=%04x mask=%04x", key, mask)); return 0; } - + // choose hotkey id UInt32 id; if (!m_oldHotKeyIDs.empty()) { @@ -351,7 +351,7 @@ OSXScreen::registerHotKey(KeyID key, KeyModifierMask mask) } else { EventHotKeyID hkid = { 'SNRG', (UInt32)id }; - OSStatus status = RegisterEventHotKey(macKey, macMask, hkid, + OSStatus status = RegisterEventHotKey(macKey, macMask, hkid, GetApplicationEventTarget(), 0, &ref); okay = (status == noErr); @@ -366,7 +366,7 @@ OSXScreen::registerHotKey(KeyID key, KeyModifierMask mask) } m_hotKeys.insert(std::make_pair(id, HotKeyItem(ref, macKey, macMask))); - + LOG((CLOG_DEBUG "registered hotkey %s (id=%04x mask=%04x) as id=%d", barrier::KeyMap::formatKey(key, mask).c_str(), key, mask, id)); return id; } @@ -468,7 +468,7 @@ OSXScreen::postMouseEvent(CGPoint& pos) const } } } - + CGEventType type = kCGEventMouseMoved; SInt8 button = m_buttonState.getFirstButtonDown(); @@ -478,10 +478,10 @@ OSXScreen::postMouseEvent(CGPoint& pos) const } CGEventRef event = CGEventCreateMouseEvent(NULL, type, pos, static_cast(button)); - + // Dragging events also need the click state CGEventSetIntegerValueField(event, kCGMouseEventClickState, m_clickState); - + // Fix for sticky keys CGEventFlags modifiers = m_keyState->getModifierStateAsOSXFlags(); CGEventSetFlags(event, modifiers); @@ -503,7 +503,7 @@ OSXScreen::postMouseEvent(CGPoint& pos) const CGEventSetDoubleValueField(event, kCGMouseEventDeltaY, deltaFY); CGEventPost(kCGHIDEventTap, event); - + CFRelease(event); } @@ -515,7 +515,7 @@ OSXScreen::fakeMouseButton(ButtonID id, bool press) if (index >= NumButtonIDs) { return; } - + CGPoint pos; if (!m_cursorPosValid) { SInt32 x, y; @@ -533,12 +533,12 @@ OSXScreen::fakeMouseButton(ButtonID id, bool press) // since we don't have double click distance in NX APIs // we define our own defaults. const double maxDiff = sqrt(2) + 0.0001; - + double clickTime = [NSEvent doubleClickInterval]; - + // As long as the click is within the time window and distance window // increase clickState (double click, triple click, etc) - // This will allow for higher than triple click but the quartz documenation + // This will allow for higher than triple click but the quartz documentation // does not specify that this should be limited to triple click if (press) { if ((ARCH->time() - m_lastClickTime) <= clickTime && diff <= maxDiff){ @@ -547,41 +547,41 @@ OSXScreen::fakeMouseButton(ButtonID id, bool press) else { m_clickState = 1; } - + m_lastClickTime = ARCH->time(); } - + if (m_clickState == 1){ m_lastSingleClickXCursor = m_xCursor; m_lastSingleClickYCursor = m_yCursor; } - + EMouseButtonState state = press ? kMouseButtonDown : kMouseButtonUp; - + LOG((CLOG_DEBUG1 "faking mouse button id: %d press: %s", index, press ? "pressed" : "released")); - + MouseButtonEventMapType thisButtonMap = MouseButtonEventMap[index]; CGEventType type = thisButtonMap[state]; CGEventRef event = CGEventCreateMouseEvent(NULL, type, pos, static_cast(index)); - + CGEventSetIntegerValueField(event, kCGMouseEventClickState, m_clickState); - + // Fix for sticky keys CGEventFlags modifiers = m_keyState->getModifierStateAsOSXFlags(); CGEventSetFlags(event, modifiers); - + m_buttonState.set(index, state); CGEventPost(kCGHIDEventTap, event); - + CFRelease(event); - + if (!press && (id == kButtonLeft)) { if (m_fakeDraggingStarted) { m_getDropTargetThread = new Thread(new TMethodJob( this, &OSXScreen::getDropTargetThread)); } - + m_draggingStarted = false; } } @@ -591,21 +591,21 @@ OSXScreen::getDropTargetThread(void*) { #if defined(MAC_OS_X_VERSION_10_7) char* cstr = NULL; - + // wait for 5 secs for the drop destinaiton string to be filled. UInt32 timeout = ARCH->time() + 5; - + while (ARCH->time() < timeout) { CFStringRef cfstr = getCocoaDropTarget(); cstr = CFStringRefToUTF8String(cfstr); CFRelease(cfstr); - + if (cstr != NULL) { break; } ARCH->sleep(.1f); } - + if (cstr != NULL) { LOG((CLOG_DEBUG "drop target: %s", cstr)); m_dropTarget = cstr; @@ -626,12 +626,12 @@ OSXScreen::fakeMouseMove(SInt32 x, SInt32 y) if (m_fakeDraggingStarted) { m_buttonState.set(0, kMouseButtonDown); } - + // index 0 means left mouse button if (m_buttonState.test(0)) { m_draggingStarted = true; } - + // synthesize event CGPoint pos; pos.x = x; @@ -679,11 +679,11 @@ OSXScreen::fakeMouseWheel(SInt32 xDelta, SInt32 yDelta) const NULL, kCGScrollEventUnitLine, 2, mapScrollWheelFromBarrier(yDelta), -mapScrollWheelFromBarrier(xDelta)); - + // Fix for sticky keys CGEventFlags modifiers = m_keyState->getModifierStateAsOSXFlags(); CGEventSetFlags(scrollEvent, modifiers); - + CGEventPost(kCGHIDEventTap, scrollEvent); CFRelease(scrollEvent); } @@ -754,11 +754,11 @@ OSXScreen::enable() if (m_isPrimary) { // FIXME -- start watching jump zones - + // kCGEventTapOptionDefault = 0x00000000 (Missing in 10.4, so specified literally) m_eventTapPort = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault, - kCGEventMaskForAllEvents, - handleCGInputEvent, + kCGEventMaskForAllEvents, + handleCGInputEvent, this); } else { @@ -773,10 +773,10 @@ OSXScreen::enable() // there may be a better way to do this, but we register an event handler even if we're // not on the primary display (acting as a client). This way, if a local event comes in - // (either keyboard or mouse), we can make sure to show the cursor if we've hidden it. + // (either keyboard or mouse), we can make sure to show the cursor if we've hidden it. m_eventTapPort = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault, - kCGEventMaskForAllEvents, - handleCGInputEventSecondary, + kCGEventMaskForAllEvents, + handleCGInputEventSecondary, this); } @@ -798,9 +798,9 @@ OSXScreen::disable() if (m_autoShowHideCursor) { showCursor(); } - + // FIXME -- stop watching jump zones, stop capturing input - + if (m_eventTapRLSR) { CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m_eventTapRLSR, kCFRunLoopDefaultMode); CFRelease(m_eventTapRLSR); @@ -846,7 +846,7 @@ OSXScreen::enter() io_registry_entry_t entry = IORegistryEntryFromPath( kIOMasterPortDefault, "IOService:/IOResources/IODisplayWrangler"); - + if (entry != MACH_PORT_NULL) { IORegistryEntrySetCFProperty(entry, CFSTR("IORequestIdle"), kCFBooleanFalse); IOObjectRelease(entry); @@ -863,15 +863,15 @@ bool OSXScreen::leave() { hideCursor(); - + if (isDraggingStarted()) { String& fileList = getDraggingFilename(); - + if (!m_isPrimary) { if (fileList.empty() == false) { ClientApp& app = ClientApp::instance(); Client* client = app.getClientPtr(); - + DragInformation di; di.setFilename(fileList); DragFileList dragFileList; @@ -881,7 +881,7 @@ OSXScreen::leave() dragFileList, info); client->sendDragInfo(fileCount, info, info.size()); LOG((CLOG_DEBUG "send dragging file to server")); - + // TODO: what to do with multiple file or even // a folder client->sendFileToServer(fileList.c_str()); @@ -889,7 +889,7 @@ OSXScreen::leave() } m_draggingStarted = false; } - + if (m_isPrimary) { avoidHesitatingCursor(); @@ -906,8 +906,8 @@ OSXScreen::setClipboard(ClipboardID, const IClipboard* src) { if (src != NULL) { LOG((CLOG_DEBUG "setting clipboard")); - Clipboard::copy(&m_pasteboard, src); - } + Clipboard::copy(&m_pasteboard, src); + } return true; } @@ -1036,16 +1036,16 @@ OSXScreen::handleSystemEvent(const Event& event, void*) } break; - case kEventClassKeyboard: + case kEventClassKeyboard: switch (GetEventKind(*carbonEvent)) { case kEventHotKeyPressed: case kEventHotKeyReleased: onHotKey(*carbonEvent); break; } - + break; - + case kEventClassWindow: // 2nd param was formerly GetWindowEventTarget(m_userInputWindow) which is 32-bit only, // however as m_userInputWindow is never initialized to anything we can take advantage of @@ -1076,7 +1076,7 @@ OSXScreen::handleSystemEvent(const Event& event, void*) } } -bool +bool OSXScreen::onMouseMove(CGFloat mx, CGFloat my) { LOG((CLOG_DEBUG2 "mouse move %+f,%+f", mx, my)); @@ -1140,7 +1140,7 @@ OSXScreen::onMouseMove(CGFloat mx, CGFloat my) return true; } -bool +bool OSXScreen::onMouseButton(bool pressed, UInt16 macButton) { // Buttons 2 and 3 are inverted on the mac @@ -1176,7 +1176,7 @@ OSXScreen::onMouseButton(bool pressed, UInt16 macButton) } } } - + if (macButton == kButtonLeft) { EMouseButtonState state = pressed ? kMouseButtonDown : kMouseButtonUp; m_buttonState.set(kButtonLeft - 1, state); @@ -1189,7 +1189,7 @@ OSXScreen::onMouseButton(bool pressed, UInt16 macButton) m_getDropTargetThread = new Thread(new TMethodJob( this, &OSXScreen::getDropTargetThread)); } - + m_draggingStarted = false; } } @@ -1218,16 +1218,16 @@ OSXScreen::displayReconfigurationCallback(CGDirectDisplayID displayID, CGDisplay // Closing or opening the lid when an external monitor is // connected causes an kCGDisplayBeginConfigurationFlag event - CGDisplayChangeSummaryFlags mask = kCGDisplayBeginConfigurationFlag | kCGDisplayMovedFlag | - kCGDisplaySetModeFlag | kCGDisplayAddFlag | kCGDisplayRemoveFlag | - kCGDisplayEnabledFlag | kCGDisplayDisabledFlag | - kCGDisplayMirrorFlag | kCGDisplayUnMirrorFlag | + CGDisplayChangeSummaryFlags mask = kCGDisplayBeginConfigurationFlag | kCGDisplayMovedFlag | + kCGDisplaySetModeFlag | kCGDisplayAddFlag | kCGDisplayRemoveFlag | + kCGDisplayEnabledFlag | kCGDisplayDisabledFlag | + kCGDisplayMirrorFlag | kCGDisplayUnMirrorFlag | kCGDisplayDesktopShapeChangedFlag; - + LOG((CLOG_DEBUG1 "event: display was reconfigured: %x %x %x", flags, mask, flags & mask)); if (flags & mask) { /* Something actually did change */ - + LOG((CLOG_DEBUG1 "event: screen changed shape; refreshing dimensions")); screen->updateScreenShape(displayID, flags); } @@ -1274,7 +1274,7 @@ OSXScreen::onKey(CGEventRef event) m_activeModifierHotKeyMask = 0; } } - + return true; } @@ -1342,7 +1342,7 @@ OSXScreen::onKey(CGEventRef event) } void -OSXScreen::onMediaKey(CGEventRef event) +OSXScreen::onMediaKey(CGEventRef event) { KeyID keyID; bool down; @@ -1405,7 +1405,7 @@ OSXScreen::mapBarrierButtonToMac(UInt16 button) const return static_cast(button); } -ButtonID +ButtonID OSXScreen::mapMacButtonToBarrier(UInt16 macButton) const { switch (macButton) { @@ -1418,7 +1418,7 @@ OSXScreen::mapMacButtonToBarrier(UInt16 macButton) const case 3: return kButtonMiddle; } - + return static_cast(macButton); } @@ -1445,8 +1445,8 @@ OSXScreen::getScrollSpeed() const double scaling = 0.0; CFPropertyListRef pref = ::CFPreferencesCopyValue( - CFSTR("com.apple.scrollwheel.scaling") , - kCFPreferencesAnyApplication, + CFSTR("com.apple.scrollwheel.scaling") , + kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); if (pref != NULL) { @@ -1535,7 +1535,7 @@ OSXScreen::updateScreenShape() if (CGGetActiveDisplayList(0, NULL, &displayCount) != CGDisplayNoErr) { return; } - + if (displayCount == 0) { return; } @@ -1579,13 +1579,13 @@ OSXScreen::updateScreenShape() (displayCount == 1) ? "display" : "displays")); } -#pragma mark - +#pragma mark - // // FAST USER SWITCH NOTIFICATION SUPPORT // // OSXScreen::userSwitchCallback(void*) -// +// // gets called if a fast user switch occurs // @@ -1611,14 +1611,14 @@ OSXScreen::userSwitchCallback(EventHandlerCallRef nextHandler, return (CallNextEventHandler(nextHandler, theEvent)); } -#pragma mark - +#pragma mark - // // SLEEP/WAKEUP NOTIFICATION SUPPORT // // OSXScreen::watchSystemPowerThread(void*) -// -// main of thread monitoring system power (sleep/wakup) using a CFRunLoop +// +// main of thread monitoring system power (sleep/wakeup) using a CFRunLoop // void @@ -1641,7 +1641,7 @@ OSXScreen::watchSystemPowerThread(void*) CFRunLoopAddSource(m_pmRunloop, runloopSourceRef, kCFRunLoopCommonModes); } - + // thread is ready { Lock lock(m_pmMutex); @@ -1658,15 +1658,15 @@ OSXScreen::watchSystemPowerThread(void*) } LOG((CLOG_DEBUG "started watchSystemPowerThread")); - + LOG((CLOG_DEBUG "waiting for event loop")); m_events->waitForReady(); - + #if defined(MAC_OS_X_VERSION_10_7) { Lock lockCarbon(m_carbonLoopMutex); if (*m_carbonLoopReady == false) { - + // we signalling carbon loop ready before starting // unless we know how to do it within the loop LOG((CLOG_DEBUG "signalling carbon loop ready")); @@ -1676,12 +1676,12 @@ OSXScreen::watchSystemPowerThread(void*) } } #endif - + // start the run loop LOG((CLOG_DEBUG "starting carbon loop")); CFRunLoopRun(); LOG((CLOG_DEBUG "carbon loop has stopped")); - + // cleanup if (notificationPortRef) { CFRunLoopRemoveSource(m_pmRunloop, @@ -1716,7 +1716,7 @@ OSXScreen::handlePowerChangeRequest(natural_t messageType, void* messageArg) getEventTarget(), messageArg, Event::kDontFreeData)); return; - + case kIOMessageSystemHasPoweredOn: LOG((CLOG_DEBUG "system wakeup")); m_events->addEvent(Event(m_events->forIScreen().resume(), @@ -1742,16 +1742,16 @@ OSXScreen::handleConfirmSleep(const Event& event, void*) if (m_pmRootPort != 0) { // deliver suspend event immediately. m_events->addEvent(Event(m_events->forIScreen().suspend(), - getEventTarget(), NULL, + getEventTarget(), NULL, Event::kDeliverImmediately)); - + LOG((CLOG_DEBUG "system will sleep")); IOAllowPowerChange(m_pmRootPort, messageArg); } } } -#pragma mark - +#pragma mark - // // GLOBAL HOTKEY OPERATING MODE SUPPORT (10.3) @@ -1941,7 +1941,7 @@ OSXScreen::handleCGInputEvent(CGEventTapProxy proxy, case kCGEventMouseMoved: pos = CGEventGetLocation(event); screen->onMouseMove(pos.x, pos.y); - + // The system ignores our cursor-centering calls if // we don't return the event. This should be harmless, // but might register as slight movement to other apps @@ -1980,10 +1980,10 @@ OSXScreen::handleCGInputEvent(CGEventTapProxy proxy, } break; } - + LOG((CLOG_DEBUG3 "unknown quartz event type: 0x%02x", type)); } - + if (screen->m_isOnScreen) { return event; } else { @@ -1992,38 +1992,38 @@ OSXScreen::handleCGInputEvent(CGEventTapProxy proxy, } void -OSXScreen::MouseButtonState::set(UInt32 button, EMouseButtonState state) +OSXScreen::MouseButtonState::set(UInt32 button, EMouseButtonState state) { bool newState = (state == kMouseButtonDown); m_buttons.set(button, newState); } bool -OSXScreen::MouseButtonState::any() +OSXScreen::MouseButtonState::any() { return m_buttons.any(); } void -OSXScreen::MouseButtonState::reset() +OSXScreen::MouseButtonState::reset() { m_buttons.reset(); } void -OSXScreen::MouseButtonState::overwrite(UInt32 buttons) +OSXScreen::MouseButtonState::overwrite(UInt32 buttons) { m_buttons = std::bitset(buttons); } bool -OSXScreen::MouseButtonState::test(UInt32 button) const +OSXScreen::MouseButtonState::test(UInt32 button) const { return m_buttons.test(button); } SInt8 -OSXScreen::MouseButtonState::getFirstButtonDown() const +OSXScreen::MouseButtonState::getFirstButtonDown() const { if (m_buttons.any()) { for (unsigned short button = 0; button < m_buttons.size(); button++) { @@ -2041,7 +2041,7 @@ OSXScreen::CFStringRefToUTF8String(CFStringRef aString) if (aString == NULL) { return NULL; } - + CFIndex length = CFStringGetLength(aString); CFIndex maxSize = CFStringGetMaximumSizeForEncoding( length, diff --git a/src/lib/platform/XWindowsScreenSaver.h b/src/lib/platform/XWindowsScreenSaver.h index cce337fe..00285ec2 100644 --- a/src/lib/platform/XWindowsScreenSaver.h +++ b/src/lib/platform/XWindowsScreenSaver.h @@ -115,7 +115,7 @@ private: // the X display Display* m_display; - // window to receive xscreensaver repsonses + // window to receive xscreensaver responses Window m_xscreensaverSink; // the target for the events we generate diff --git a/src/lib/server/Server.cpp b/src/lib/server/Server.cpp index 334049cf..2eff0029 100644 --- a/src/lib/server/Server.cpp +++ b/src/lib/server/Server.cpp @@ -1136,9 +1136,9 @@ Server::processOptions() return; } - m_switchNeedsShift = false; // it seems if i don't add these + m_switchNeedsShift = false; // it seems if I don't add these m_switchNeedsControl = false; // lines, the 'reload config' option - m_switchNeedsAlt = false; // doesnt' work correct. + m_switchNeedsAlt = false; // doesn't work correct. bool newRelativeMoves = m_relativeMoves; for (Config::ScreenOptions::const_iterator index = options->begin(); diff --git a/src/lib/server/Server.h b/src/lib/server/Server.h index 38bbbd8e..cb71ec3d 100644 --- a/src/lib/server/Server.h +++ b/src/lib/server/Server.h @@ -167,7 +167,7 @@ public: */ void getClients(std::vector& list) const; - //! Return true if recieved file size is valid + //! Return true if received file size is valid bool isReceivedFileSizeValid(); //! Return expected file data size @@ -357,7 +357,7 @@ private: // force the cursor off of \p client void forceLeaveClient(BaseClientProxy* client); - // thread funciton for sending file + // thread function for sending file void sendFileThread(void*); // thread function for writing file to drop directory From 9549352a10a4dbec9a867b319ba4e637f875af5e Mon Sep 17 00:00:00 2001 From: a1346054 <36859588+a1346054@users.noreply.github.com> Date: Wed, 22 Sep 2021 23:29:39 +0000 Subject: [PATCH 023/113] Fix codestyle deviations --- src/gui/src/AppConfig.cpp | 2 +- src/gui/src/IpcClient.h | 2 +- src/gui/src/MainWindow.cpp | 2 +- src/gui/src/ScreenSetupModel.cpp | 2 +- src/gui/src/SslCertificate.h | 2 +- src/lib/arch/win32/ArchMiscWindows.cpp | 2 +- src/lib/barrier/App.h | 2 +- src/lib/barrier/ArgParser.cpp | 2 +- src/lib/net/SecureListenSocket.h | 2 +- src/lib/platform/MSWindowsSession.cpp | 2 +- src/lib/platform/OSXScreen.mm | 4 ++-- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/gui/src/AppConfig.cpp b/src/gui/src/AppConfig.cpp index c7878afe..63943267 100644 --- a/src/gui/src/AppConfig.cpp +++ b/src/gui/src/AppConfig.cpp @@ -211,7 +211,7 @@ void AppConfig::setElevateMode(ElevateMode em) { m_ElevateMode = em; } void AppConfig::setAutoConfig(bool autoConfig) { m_AutoConfig = autoConfig; } -bool AppConfig::autoConfigPrompted() { return m_AutoConfigPrompted; } +bool AppConfig::autoConfigPrompted() { return m_AutoConfigPrompted; } void AppConfig::setAutoConfigPrompted(bool prompted) { m_AutoConfigPrompted = prompted; } diff --git a/src/gui/src/IpcClient.h b/src/gui/src/IpcClient.h index cd398b3d..6040029c 100644 --- a/src/gui/src/IpcClient.h +++ b/src/gui/src/IpcClient.h @@ -28,7 +28,7 @@ class IpcReader; class IpcClient : public QObject { - Q_OBJECT + Q_OBJECT public: IpcClient(); diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index d74bb66a..5d4ee8fe 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -1001,7 +1001,7 @@ bool MainWindow::on_m_pButtonBrowseConfigFile_clicked() return false; } -bool MainWindow::on_m_pActionSave_triggered() +bool MainWindow::on_m_pActionSave_triggered() { QString fileName = QFileDialog::getSaveFileName(this, tr("Save configuration as..."), QString(), barrierConfigSaveFilter); diff --git a/src/gui/src/ScreenSetupModel.cpp b/src/gui/src/ScreenSetupModel.cpp index 405ba227..5b709547 100644 --- a/src/gui/src/ScreenSetupModel.cpp +++ b/src/gui/src/ScreenSetupModel.cpp @@ -110,7 +110,7 @@ bool ScreenSetupModel::dropMimeData(const QMimeData* data, Qt::DropAction action return false; if (!parent.isValid() || row != -1 || column != -1) - return false; + return false; QByteArray encodedData = data->data(m_MimeType); QDataStream stream(&encodedData, QIODevice::ReadOnly); diff --git a/src/gui/src/SslCertificate.h b/src/gui/src/SslCertificate.h index 3ff3ff5c..e8ae2738 100644 --- a/src/gui/src/SslCertificate.h +++ b/src/gui/src/SslCertificate.h @@ -22,7 +22,7 @@ class SslCertificate : public QObject { -Q_OBJECT + Q_OBJECT public: explicit SslCertificate(QObject *parent = 0); diff --git a/src/lib/arch/win32/ArchMiscWindows.cpp b/src/lib/arch/win32/ArchMiscWindows.cpp index 6ee01fc1..ab16daad 100644 --- a/src/lib/arch/win32/ArchMiscWindows.cpp +++ b/src/lib/arch/win32/ArchMiscWindows.cpp @@ -443,7 +443,7 @@ ArchMiscWindows::wasLaunchedAsService() bool ArchMiscWindows::getParentProcessName(std::string &name) { PROCESSENTRY32 parentEntry; - if (!getParentProcessEntry(parentEntry)){ + if (!getParentProcessEntry(parentEntry)) { LOG((CLOG_ERR "could not get entry for parent process")); return false; } diff --git a/src/lib/barrier/App.h b/src/lib/barrier/App.h index ed034b62..749ca85d 100644 --- a/src/lib/barrier/App.h +++ b/src/lib/barrier/App.h @@ -90,7 +90,7 @@ public: ARCH_APP_UTIL& appUtil() { return m_appUtil; } - virtual IArchTaskBarReceiver* taskBarReceiver() const { return m_taskBarReceiver; } + virtual IArchTaskBarReceiver* taskBarReceiver() const { return m_taskBarReceiver; } virtual void setByeFunc(void(*bye)(int)) { m_bye = bye; } virtual void bye(int error) { m_bye(error); } diff --git a/src/lib/barrier/ArgParser.cpp b/src/lib/barrier/ArgParser.cpp index 9cd1b8da..1ac4baff 100644 --- a/src/lib/barrier/ArgParser.cpp +++ b/src/lib/barrier/ArgParser.cpp @@ -373,7 +373,7 @@ ArgParser::splitCommandString(String& command, std::vector& argv) if (space > leftDoubleQuote && space < rightDoubleQuote) { ignoreThisSpace = true; } - else if (space > rightDoubleQuote){ + else if (space > rightDoubleQuote) { searchDoubleQuotes(command, leftDoubleQuote, rightDoubleQuote, rightDoubleQuote + 1); } diff --git a/src/lib/net/SecureListenSocket.h b/src/lib/net/SecureListenSocket.h index 11456879..fab92bf5 100644 --- a/src/lib/net/SecureListenSocket.h +++ b/src/lib/net/SecureListenSocket.h @@ -24,7 +24,7 @@ class IEventQueue; class SocketMultiplexer; class IDataSocket; -class SecureListenSocket : public TCPListenSocket{ +class SecureListenSocket : public TCPListenSocket { public: SecureListenSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, diff --git a/src/lib/platform/MSWindowsSession.cpp b/src/lib/platform/MSWindowsSession.cpp index 90b8c142..daa92768 100644 --- a/src/lib/platform/MSWindowsSession.cpp +++ b/src/lib/platform/MSWindowsSession.cpp @@ -94,7 +94,7 @@ MSWindowsSession::isProcessInSession(const char* name, PHANDLE process = NULL) } std::string nameListJoin; - for(std::list::iterator it = nameList.begin(); + for (std::list::iterator it = nameList.begin(); it != nameList.end(); it++) { nameListJoin.append(*it); nameListJoin.append(", "); diff --git a/src/lib/platform/OSXScreen.mm b/src/lib/platform/OSXScreen.mm index 73e5b4ad..693ae45c 100644 --- a/src/lib/platform/OSXScreen.mm +++ b/src/lib/platform/OSXScreen.mm @@ -541,7 +541,7 @@ OSXScreen::fakeMouseButton(ButtonID id, bool press) // This will allow for higher than triple click but the quartz documentation // does not specify that this should be limited to triple click if (press) { - if ((ARCH->time() - m_lastClickTime) <= clickTime && diff <= maxDiff){ + if ((ARCH->time() - m_lastClickTime) <= clickTime && diff <= maxDiff) { m_clickState++; } else { @@ -551,7 +551,7 @@ OSXScreen::fakeMouseButton(ButtonID id, bool press) m_lastClickTime = ARCH->time(); } - if (m_clickState == 1){ + if (m_clickState == 1) { m_lastSingleClickXCursor = m_xCursor; m_lastSingleClickYCursor = m_yCursor; } From ab3bdad5ab9047b1571b0a3b1874f9b487cc7f8f Mon Sep 17 00:00:00 2001 From: a1346054 <36859588+a1346054@users.noreply.github.com> Date: Wed, 22 Sep 2021 22:21:59 +0000 Subject: [PATCH 024/113] Use correct barrier.desktop category from https://specifications.freedesktop.org/menu-spec/latest/apas02.html --- res/barrier.desktop | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/res/barrier.desktop b/res/barrier.desktop index 6bb60e13..a47fd8ef 100644 --- a/res/barrier.desktop +++ b/res/barrier.desktop @@ -5,6 +5,5 @@ Comment=Keyboard and mouse sharing solution Exec=barrier Icon=barrier Terminal=false -Categories=Utility;DesktopUtility; +Categories=Utility;RemoteAccess; Keywords=keyboard;mouse;sharing;network;share; - From 9c4144186155da8c5241f825af45fdba6f46d240 Mon Sep 17 00:00:00 2001 From: a1346054 <36859588+a1346054@users.noreply.github.com> Date: Wed, 22 Sep 2021 21:03:19 +0000 Subject: [PATCH 025/113] Fix whitespace alignment --- README.md | 7 +- doc/org.barrier-foss.org.barrierc.plist | 18 ++--- doc/org.barrier-foss.org.barriers.plist | 12 ++-- src/gui/res/lang/Languages.xml | 92 ++++++++++++------------- src/lib/arch/win32/XArchWindows.cpp | 76 ++++++++++---------- 5 files changed, 103 insertions(+), 102 deletions(-) diff --git a/README.md b/README.md index 0c49fbb5..3c545e93 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,7 @@ A: Start the binary with the argument `--config ` Q: After loading my configuration on the client the field 'Server IP' is still empty! A: Edit your configuration to include the server's ip address manually with - (...) - section: options - serverhostname= + + (...) + section: options + serverhostname= diff --git a/doc/org.barrier-foss.org.barrierc.plist b/doc/org.barrier-foss.org.barrierc.plist index 31e10ba5..90345c88 100644 --- a/doc/org.barrier-foss.org.barrierc.plist +++ b/doc/org.barrier-foss.org.barrierc.plist @@ -4,17 +4,17 @@ - Label - org.debauchee.com.barrierc.plist - OnDemand - - ProgramArguments - + Label + org.debauchee.com.barrierc.plist + OnDemand + + ProgramArguments + /usr/bin/barrierc 192.168.0.2 - - RunAtLoad - + + RunAtLoad + diff --git a/doc/org.barrier-foss.org.barriers.plist b/doc/org.barrier-foss.org.barriers.plist index f1ab5bf9..fed7b47a 100644 --- a/doc/org.barrier-foss.org.barriers.plist +++ b/doc/org.barrier-foss.org.barriers.plist @@ -4,12 +4,12 @@ - Label - org.debauchee.com.barriers.plist - OnDemand - - ProgramArguments - + Label + org.debauchee.com.barriers.plist + OnDemand + + ProgramArguments + /usr/bin/barriers --no-daemon --config diff --git a/src/gui/res/lang/Languages.xml b/src/gui/res/lang/Languages.xml index 5948f9c6..723d667c 100644 --- a/src/gui/res/lang/Languages.xml +++ b/src/gui/res/lang/Languages.xml @@ -1,46 +1,46 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/lib/arch/win32/XArchWindows.cpp b/src/lib/arch/win32/XArchWindows.cpp index b7361ab6..eb3c1513 100644 --- a/src/lib/arch/win32/XArchWindows.cpp +++ b/src/lib/arch/win32/XArchWindows.cpp @@ -57,58 +57,58 @@ XArchEvalWinsock::eval() const noexcept // may not look up network error messages correctly. we'll have // to do it ourself. static const struct { int m_code; const char* m_msg; } s_netErrorCodes[] = { - /* 10004 */{WSAEINTR, "The (blocking) call was canceled via WSACancelBlockingCall"}, - /* 10009 */{WSAEBADF, "Bad file handle"}, - /* 10013 */{WSAEACCES, "The requested address is a broadcast address, but the appropriate flag was not set"}, - /* 10014 */{WSAEFAULT, "WSAEFAULT"}, - /* 10022 */{WSAEINVAL, "WSAEINVAL"}, - /* 10024 */{WSAEMFILE, "No more file descriptors available"}, - /* 10035 */{WSAEWOULDBLOCK, "Socket is marked as non-blocking and no connections are present or the receive operation would block"}, - /* 10036 */{WSAEINPROGRESS, "A blocking Windows Sockets operation is in progress"}, + /* 10004 */{WSAEINTR, "The (blocking) call was canceled via WSACancelBlockingCall"}, + /* 10009 */{WSAEBADF, "Bad file handle"}, + /* 10013 */{WSAEACCES, "The requested address is a broadcast address, but the appropriate flag was not set"}, + /* 10014 */{WSAEFAULT, "WSAEFAULT"}, + /* 10022 */{WSAEINVAL, "WSAEINVAL"}, + /* 10024 */{WSAEMFILE, "No more file descriptors available"}, + /* 10035 */{WSAEWOULDBLOCK, "Socket is marked as non-blocking and no connections are present or the receive operation would block"}, + /* 10036 */{WSAEINPROGRESS, "A blocking Windows Sockets operation is in progress"}, /* 10037 */{WSAEALREADY, "The asynchronous routine being canceled has already completed"}, /* 10038 */{WSAENOTSOCK, "At least on descriptor is not a socket"}, /* 10039 */{WSAEDESTADDRREQ, "A destination address is required"}, /* 10040 */{WSAEMSGSIZE, "The datagram was too large to fit into the specified buffer and was truncated"}, - /* 10041 */{WSAEPROTOTYPE, "The specified protocol is the wrong type for this socket"}, - /* 10042 */{WSAENOPROTOOPT, "The option is unknown or unsupported"}, - /* 10043 */{WSAEPROTONOSUPPORT,"The specified protocol is not supported"}, - /* 10044 */{WSAESOCKTNOSUPPORT,"The specified socket type is not supported by this address family"}, - /* 10045 */{WSAEOPNOTSUPP, "The referenced socket is not a type that supports that operation"}, + /* 10041 */{WSAEPROTOTYPE, "The specified protocol is the wrong type for this socket"}, + /* 10042 */{WSAENOPROTOOPT, "The option is unknown or unsupported"}, + /* 10043 */{WSAEPROTONOSUPPORT, "The specified protocol is not supported"}, + /* 10044 */{WSAESOCKTNOSUPPORT, "The specified socket type is not supported by this address family"}, + /* 10045 */{WSAEOPNOTSUPP, "The referenced socket is not a type that supports that operation"}, /* 10046 */{WSAEPFNOSUPPORT, "BSD: Protocol family not supported"}, /* 10047 */{WSAEAFNOSUPPORT, "The specified address family is not supported"}, - /* 10048 */{WSAEADDRINUSE, "The specified address is already in use"}, - /* 10049 */{WSAEADDRNOTAVAIL, "The specified address is not available from the local machine"}, + /* 10048 */{WSAEADDRINUSE, "The specified address is already in use"}, + /* 10049 */{WSAEADDRNOTAVAIL, "The specified address is not available from the local machine"}, /* 10050 */{WSAENETDOWN, "The Windows Sockets implementation has detected that the network subsystem has failed"}, - /* 10051 */{WSAENETUNREACH, "The network can't be reached from this host at this time"}, - /* 10052 */{WSAENETRESET, "The connection must be reset because the Windows Sockets implementation dropped it"}, + /* 10051 */{WSAENETUNREACH, "The network can't be reached from this host at this time"}, + /* 10052 */{WSAENETRESET, "The connection must be reset because the Windows Sockets implementation dropped it"}, /* 10053 */{WSAECONNABORTED, "The virtual circuit was aborted due to timeout or other failure"}, - /* 10054 */{WSAECONNRESET, "The virtual circuit was reset by the remote side"}, - /* 10055 */{WSAENOBUFS, "No buffer space is available or a buffer deadlock has occurred. The socket cannot be created"}, - /* 10056 */{WSAEISCONN, "The socket is already connected"}, + /* 10054 */{WSAECONNRESET, "The virtual circuit was reset by the remote side"}, + /* 10055 */{WSAENOBUFS, "No buffer space is available or a buffer deadlock has occurred. The socket cannot be created"}, + /* 10056 */{WSAEISCONN, "The socket is already connected"}, /* 10057 */{WSAENOTCONN, "The socket is not connected"}, - /* 10058 */{WSAESHUTDOWN, "The socket has been shutdown"}, + /* 10058 */{WSAESHUTDOWN, "The socket has been shutdown"}, /* 10059 */{WSAETOOMANYREFS, "BSD: Too many references"}, - /* 10060 */{WSAETIMEDOUT, "Attempt to connect timed out without establishing a connection"}, + /* 10060 */{WSAETIMEDOUT, "Attempt to connect timed out without establishing a connection"}, /* 10061 */{WSAECONNREFUSED, "Connection was refused"}, - /* 10062 */{WSAELOOP, "Undocumented WinSock error code used in BSD"}, + /* 10062 */{WSAELOOP, "Undocumented WinSock error code used in BSD"}, /* 10063 */{WSAENAMETOOLONG, "Undocumented WinSock error code used in BSD"}, - /* 10064 */{WSAEHOSTDOWN, "Undocumented WinSock error code used in BSD"}, + /* 10064 */{WSAEHOSTDOWN, "Undocumented WinSock error code used in BSD"}, /* 10065 */{WSAEHOSTUNREACH, "No route to host"}, - /* 10066 */{WSAENOTEMPTY, "Undocumented WinSock error code"}, + /* 10066 */{WSAENOTEMPTY, "Undocumented WinSock error code"}, /* 10067 */{WSAEPROCLIM, "Undocumented WinSock error code"}, - /* 10068 */{WSAEUSERS, "Undocumented WinSock error code"}, - /* 10069 */{WSAEDQUOT, "Undocumented WinSock error code"}, - /* 10070 */{WSAESTALE, "Undocumented WinSock error code"}, - /* 10071 */{WSAEREMOTE, "Undocumented WinSock error code"}, - /* 10091 */{WSASYSNOTREADY, "Underlying network subsystem is not ready for network communication"}, - /* 10092 */{WSAVERNOTSUPPORTED, "The version of WinSock API support requested is not provided in this implementation"}, - /* 10093 */{WSANOTINITIALISED, "WinSock subsystem not properly initialized"}, - /* 10101 */{WSAEDISCON, "Virtual circuit has gracefully terminated connection"}, - /* 11001 */{WSAHOST_NOT_FOUND, "The specified host is unknown"}, - /* 11002 */{WSATRY_AGAIN, "A temporary error occurred on an authoritative name server"}, - /* 11003 */{WSANO_RECOVERY, "A non-recoverable name server error occurred"}, - /* 11004 */{WSANO_DATA, "The requested name is valid but does not have an IP address"}, - /* end */{0, NULL} + /* 10068 */{WSAEUSERS, "Undocumented WinSock error code"}, + /* 10069 */{WSAEDQUOT, "Undocumented WinSock error code"}, + /* 10070 */{WSAESTALE, "Undocumented WinSock error code"}, + /* 10071 */{WSAEREMOTE, "Undocumented WinSock error code"}, + /* 10091 */{WSASYSNOTREADY, "Underlying network subsystem is not ready for network communication"}, + /* 10092 */{WSAVERNOTSUPPORTED, "The version of WinSock API support requested is not provided in this implementation"}, + /* 10093 */{WSANOTINITIALISED, "WinSock subsystem not properly initialized"}, + /* 10101 */{WSAEDISCON, "Virtual circuit has gracefully terminated connection"}, + /* 11001 */{WSAHOST_NOT_FOUND, "The specified host is unknown"}, + /* 11002 */{WSATRY_AGAIN, "A temporary error occurred on an authoritative name server"}, + /* 11003 */{WSANO_RECOVERY, "A non-recoverable name server error occurred"}, + /* 11004 */{WSANO_DATA, "The requested name is valid but does not have an IP address"}, + /* end */{0, NULL} }; for (unsigned int i = 0; s_netErrorCodes[i].m_code != 0; ++i) { From 872e78d342465944f94d48c92e8953e8d83bcfb7 Mon Sep 17 00:00:00 2001 From: a1346054 <36859588+a1346054@users.noreply.github.com> Date: Wed, 22 Sep 2021 23:07:36 +0000 Subject: [PATCH 026/113] Trim excess whitespace --- src/cmd/CMakeLists.txt | 1 - src/cmd/barrierc/CMakeLists.txt | 1 - src/cmd/barrierc/OSXClientTaskBarReceiver.cpp | 1 - src/cmd/barriers/CMakeLists.txt | 2 -- src/gui/res/lang/gui_ca-AD.ts | 6 +++--- src/gui/res/lang/gui_da.ts | 2 +- src/gui/res/lang/gui_nl-NL.ts | 2 +- src/gui/res/lang/gui_pl-PL.ts | 4 ++-- src/gui/res/lang/gui_ru.ts | 4 ++-- src/gui/res/lang/gui_tr-TR.ts | 4 ++-- src/gui/src/AboutDialog.h | 1 - src/gui/src/Action.cpp | 1 - src/gui/src/BaseConfig.cpp | 1 - src/gui/src/KeySequence.h | 1 - src/gui/src/KeySequenceWidget.h | 1 - src/gui/src/MainWindow.h | 1 - src/gui/src/NewScreenWidget.cpp | 3 +-- src/gui/src/NewScreenWidget.h | 1 - src/gui/src/QBarrierApplication.h | 1 - src/gui/src/Screen.h | 1 - src/gui/src/ScreenSettingsDialog.cpp | 1 - src/gui/src/ScreenSettingsDialog.h | 1 - src/gui/src/ScreenSetupModel.cpp | 1 - src/gui/src/ScreenSetupModel.h | 1 - src/gui/src/ScreenSetupView.cpp | 1 - src/gui/src/ScreenSetupView.h | 1 - src/gui/src/ServerConfig.h | 1 - src/gui/src/ServerConfigDialog.h | 1 - src/gui/src/ShutdownCh.h | 1 - src/gui/src/TrashScreenWidget.cpp | 1 - src/gui/src/TrashScreenWidget.h | 1 - 31 files changed, 12 insertions(+), 38 deletions(-) diff --git a/src/cmd/CMakeLists.txt b/src/cmd/CMakeLists.txt index 0534d0fb..946b19a2 100644 --- a/src/cmd/CMakeLists.txt +++ b/src/cmd/CMakeLists.txt @@ -20,4 +20,3 @@ add_subdirectory(barriers) if (WIN32) add_subdirectory(barrierd) endif() - diff --git a/src/cmd/barrierc/CMakeLists.txt b/src/cmd/barrierc/CMakeLists.txt index c78ac6a4..45e9ab0e 100644 --- a/src/cmd/barrierc/CMakeLists.txt +++ b/src/cmd/barrierc/CMakeLists.txt @@ -46,4 +46,3 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") install (TARGETS barrierc DESTINATION bin) endif() - diff --git a/src/cmd/barrierc/OSXClientTaskBarReceiver.cpp b/src/cmd/barrierc/OSXClientTaskBarReceiver.cpp index 1a2bf56e..e273f998 100644 --- a/src/cmd/barrierc/OSXClientTaskBarReceiver.cpp +++ b/src/cmd/barrierc/OSXClientTaskBarReceiver.cpp @@ -66,4 +66,3 @@ createTaskBarReceiver(const BufferedLogOutputter* logBuffer, IEventQueue* events { return new OSXClientTaskBarReceiver(logBuffer, events); } - diff --git a/src/cmd/barriers/CMakeLists.txt b/src/cmd/barriers/CMakeLists.txt index e92334a6..c9fa7508 100644 --- a/src/cmd/barriers/CMakeLists.txt +++ b/src/cmd/barriers/CMakeLists.txt @@ -46,5 +46,3 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") install (TARGETS barriers DESTINATION bin) endif() - - diff --git a/src/gui/res/lang/gui_ca-AD.ts b/src/gui/res/lang/gui_ca-AD.ts index 7d7d8738..3cd78957 100644 --- a/src/gui/res/lang/gui_ca-AD.ts +++ b/src/gui/res/lang/gui_ca-AD.ts @@ -905,8 +905,8 @@ To automatically trust this fingerprint for future connections, click Yes. To re Drag new screens to the grid or move existing ones around. Drag a screen to the trashcan to delete it. Double click on a screen to edit its settings. - Arrossega noves pantalles a la graella o mou les actuals al voltant. -Arrossega una pantalla a la paperera per eliminar-la. + Arrossega noves pantalles a la graella o mou les actuals al voltant. +Arrossega una pantalla a la paperera per eliminar-la. Fes doble clic a una pantalla per editar la seva configuració. @@ -1335,7 +1335,7 @@ p, li { white-space: pre-wrap; } Server response: %1 - Error inici de sessió, hi ha hagut un error. + Error inici de sessió, hi ha hagut un error. Resposta del servidor: %1 diff --git a/src/gui/res/lang/gui_da.ts b/src/gui/res/lang/gui_da.ts index 77c4c2b2..7bec5184 100644 --- a/src/gui/res/lang/gui_da.ts +++ b/src/gui/res/lang/gui_da.ts @@ -1334,7 +1334,7 @@ p, li { white-space: pre-wrap; } Server response: %1 - Fejl i login, en fejl opstod. + Fejl i login, en fejl opstod. Server svar: %1 diff --git a/src/gui/res/lang/gui_nl-NL.ts b/src/gui/res/lang/gui_nl-NL.ts index d666189c..4ea0ee8a 100644 --- a/src/gui/res/lang/gui_nl-NL.ts +++ b/src/gui/res/lang/gui_nl-NL.ts @@ -1334,7 +1334,7 @@ p, li { white-space: pre-wrap; } Server response: %1 - Inloggen mislukt, er is een fout opgetreden. + Inloggen mislukt, er is een fout opgetreden. Foutmelding: %1 diff --git a/src/gui/res/lang/gui_pl-PL.ts b/src/gui/res/lang/gui_pl-PL.ts index 6d357fdc..7262a2ae 100644 --- a/src/gui/res/lang/gui_pl-PL.ts +++ b/src/gui/res/lang/gui_pl-PL.ts @@ -1325,7 +1325,7 @@ p, li { white-space: pre-wrap; } Login failed, an error occurred. %1 - Logowanie nie powiodło się, wystąpił błąd. + Logowanie nie powiodło się, wystąpił błąd. %1 @@ -1335,7 +1335,7 @@ p, li { white-space: pre-wrap; } Server response: %1 - Logowanie nie powiodło się, wystąpił błąd. + Logowanie nie powiodło się, wystąpił błąd. Odpowiedź serwera: %1 diff --git a/src/gui/res/lang/gui_ru.ts b/src/gui/res/lang/gui_ru.ts index 07a94254..f9842400 100644 --- a/src/gui/res/lang/gui_ru.ts +++ b/src/gui/res/lang/gui_ru.ts @@ -1325,7 +1325,7 @@ p, li { white-space: pre-wrap; } Login failed, an error occurred. %1 - Войти не удалось, произошла ошибка. + Войти не удалось, произошла ошибка. %1 @@ -1336,7 +1336,7 @@ p, li { white-space: pre-wrap; } Server response: %1 - Войти не удалось, произошла ошибка. + Войти не удалось, произошла ошибка. Ответ сервера: diff --git a/src/gui/res/lang/gui_tr-TR.ts b/src/gui/res/lang/gui_tr-TR.ts index 95946555..924662f9 100644 --- a/src/gui/res/lang/gui_tr-TR.ts +++ b/src/gui/res/lang/gui_tr-TR.ts @@ -905,8 +905,8 @@ To automatically trust this fingerprint for future connections, click Yes. To re Drag new screens to the grid or move existing ones around. Drag a screen to the trashcan to delete it. Double click on a screen to edit its settings. - Izgaraya yeni ekranları sürükleyin veya çevresinde mevcut olanları taşıyın. -Silmek için çöp tenekesine ekranı sürükleyin. + Izgaraya yeni ekranları sürükleyin veya çevresinde mevcut olanları taşıyın. +Silmek için çöp tenekesine ekranı sürükleyin. Kendi ayarlarınızı düzenlemek için bir ekran üzerine çift tıklayın. diff --git a/src/gui/src/AboutDialog.h b/src/gui/src/AboutDialog.h index bd85c9d4..6fdb0a24 100644 --- a/src/gui/src/AboutDialog.h +++ b/src/gui/src/AboutDialog.h @@ -40,4 +40,3 @@ class AboutDialog : public QDialog, public Ui::AboutDialogBase }; #endif - diff --git a/src/gui/src/Action.cpp b/src/gui/src/Action.cpp index 2882afb1..f34d1e8f 100644 --- a/src/gui/src/Action.cpp +++ b/src/gui/src/Action.cpp @@ -164,4 +164,3 @@ QTextStream& operator<<(QTextStream& outStream, const Action& action) return outStream; } - diff --git a/src/gui/src/BaseConfig.cpp b/src/gui/src/BaseConfig.cpp index c61b4c5b..0f31493d 100644 --- a/src/gui/src/BaseConfig.cpp +++ b/src/gui/src/BaseConfig.cpp @@ -44,4 +44,3 @@ const char* BaseConfig::m_SwitchCornerNames[] = "bottom-left", "bottom-right" }; - diff --git a/src/gui/src/KeySequence.h b/src/gui/src/KeySequence.h index 9c73029a..03310918 100644 --- a/src/gui/src/KeySequence.h +++ b/src/gui/src/KeySequence.h @@ -54,4 +54,3 @@ class KeySequence }; #endif - diff --git a/src/gui/src/KeySequenceWidget.h b/src/gui/src/KeySequenceWidget.h index 42dc746d..636375b3 100644 --- a/src/gui/src/KeySequenceWidget.h +++ b/src/gui/src/KeySequenceWidget.h @@ -78,4 +78,3 @@ class KeySequenceWidget : public QPushButton }; #endif - diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h index c115b912..131b31ce 100644 --- a/src/gui/src/MainWindow.h +++ b/src/gui/src/MainWindow.h @@ -211,4 +211,3 @@ private slots: }; #endif - diff --git a/src/gui/src/NewScreenWidget.cpp b/src/gui/src/NewScreenWidget.cpp index 7543bd3d..28e99fa4 100644 --- a/src/gui/src/NewScreenWidget.cpp +++ b/src/gui/src/NewScreenWidget.cpp @@ -1,4 +1,4 @@ -/* +/* * barrier -- mouse and keyboard sharing utility * Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2008 Volker Lanz (vl@fidra.de) @@ -45,4 +45,3 @@ void NewScreenWidget::mousePressEvent(QMouseEvent* event) pDrag->exec(Qt::CopyAction, Qt::CopyAction); } - diff --git a/src/gui/src/NewScreenWidget.h b/src/gui/src/NewScreenWidget.h index 03b41abd..6e527952 100644 --- a/src/gui/src/NewScreenWidget.h +++ b/src/gui/src/NewScreenWidget.h @@ -37,4 +37,3 @@ class NewScreenWidget : public QLabel }; #endif - diff --git a/src/gui/src/QBarrierApplication.h b/src/gui/src/QBarrierApplication.h index 1b06ba08..bd348b3a 100644 --- a/src/gui/src/QBarrierApplication.h +++ b/src/gui/src/QBarrierApplication.h @@ -44,4 +44,3 @@ class QBarrierApplication : public QApplication }; #endif - diff --git a/src/gui/src/Screen.h b/src/gui/src/Screen.h index e06056f7..64962214 100644 --- a/src/gui/src/Screen.h +++ b/src/gui/src/Screen.h @@ -105,4 +105,3 @@ QDataStream& operator<<(QDataStream& outStream, const Screen& screen); QDataStream& operator>>(QDataStream& inStream, Screen& screen); #endif - diff --git a/src/gui/src/ScreenSettingsDialog.cpp b/src/gui/src/ScreenSettingsDialog.cpp index 899881ed..9055e356 100644 --- a/src/gui/src/ScreenSettingsDialog.cpp +++ b/src/gui/src/ScreenSettingsDialog.cpp @@ -152,4 +152,3 @@ void ScreenSettingsDialog::on_m_pListAliases_itemSelectionChanged() { m_pButtonRemoveAlias->setEnabled(!m_pListAliases->selectedItems().isEmpty()); } - diff --git a/src/gui/src/ScreenSettingsDialog.h b/src/gui/src/ScreenSettingsDialog.h index ae1181b8..953d1f89 100644 --- a/src/gui/src/ScreenSettingsDialog.h +++ b/src/gui/src/ScreenSettingsDialog.h @@ -50,4 +50,3 @@ class ScreenSettingsDialog : public QDialog, public Ui::ScreenSettingsDialogBase }; #endif - diff --git a/src/gui/src/ScreenSetupModel.cpp b/src/gui/src/ScreenSetupModel.cpp index 5b709547..5c933f81 100644 --- a/src/gui/src/ScreenSetupModel.cpp +++ b/src/gui/src/ScreenSetupModel.cpp @@ -141,4 +141,3 @@ bool ScreenSetupModel::dropMimeData(const QMimeData* data, Qt::DropAction action return true; } - diff --git a/src/gui/src/ScreenSetupModel.h b/src/gui/src/ScreenSetupModel.h index 8a1a9820..0f558b42 100644 --- a/src/gui/src/ScreenSetupModel.h +++ b/src/gui/src/ScreenSetupModel.h @@ -68,4 +68,3 @@ class ScreenSetupModel : public QAbstractTableModel }; #endif - diff --git a/src/gui/src/ScreenSetupView.cpp b/src/gui/src/ScreenSetupView.cpp index 15795092..5459f23a 100644 --- a/src/gui/src/ScreenSetupView.cpp +++ b/src/gui/src/ScreenSetupView.cpp @@ -225,4 +225,3 @@ QStyleOptionViewItem ScreenSetupView::viewOptions() const option.textElideMode = Qt::ElideMiddle; return option; } - diff --git a/src/gui/src/ScreenSetupView.h b/src/gui/src/ScreenSetupView.h index 55981c78..64968a0b 100644 --- a/src/gui/src/ScreenSetupView.h +++ b/src/gui/src/ScreenSetupView.h @@ -58,4 +58,3 @@ class ScreenSetupView : public QTableView }; #endif - diff --git a/src/gui/src/ServerConfig.h b/src/gui/src/ServerConfig.h index 161b00d7..9f3e2db1 100644 --- a/src/gui/src/ServerConfig.h +++ b/src/gui/src/ServerConfig.h @@ -138,4 +138,3 @@ enum { }; #endif - diff --git a/src/gui/src/ServerConfigDialog.h b/src/gui/src/ServerConfigDialog.h index de2472ea..91da51ae 100644 --- a/src/gui/src/ServerConfigDialog.h +++ b/src/gui/src/ServerConfigDialog.h @@ -63,4 +63,3 @@ class ServerConfigDialog : public QDialog, public Ui::ServerConfigDialogBase }; #endif - diff --git a/src/gui/src/ShutdownCh.h b/src/gui/src/ShutdownCh.h index 2462cae7..54ec84d4 100644 --- a/src/gui/src/ShutdownCh.h +++ b/src/gui/src/ShutdownCh.h @@ -19,4 +19,3 @@ // included in both the GUI and the child apps (server & client) const char ShutdownCh = 'S'; - diff --git a/src/gui/src/TrashScreenWidget.cpp b/src/gui/src/TrashScreenWidget.cpp index 4e81d4da..6f2abad7 100644 --- a/src/gui/src/TrashScreenWidget.cpp +++ b/src/gui/src/TrashScreenWidget.cpp @@ -40,4 +40,3 @@ void TrashScreenWidget::dropEvent(QDropEvent* event) else event->ignore(); } - diff --git a/src/gui/src/TrashScreenWidget.h b/src/gui/src/TrashScreenWidget.h index 676b44fb..967f73d5 100644 --- a/src/gui/src/TrashScreenWidget.h +++ b/src/gui/src/TrashScreenWidget.h @@ -39,4 +39,3 @@ class TrashScreenWidget : public QLabel }; #endif - From 547a2dd413d3d1b26a8efd6faa374007d1396e09 Mon Sep 17 00:00:00 2001 From: Andrew Shark Date: Sat, 2 Oct 2021 03:21:04 +0300 Subject: [PATCH 027/113] Add warning on wayland, fix #247 --- src/gui/src/main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/src/main.cpp b/src/gui/src/main.cpp index 73251d52..776b44de 100644 --- a/src/gui/src/main.cpp +++ b/src/gui/src/main.cpp @@ -97,6 +97,12 @@ int main(int argc, char* argv[]) QApplication::setQuitOnLastWindowClosed(false); + if (QGuiApplication::platformName() == "wayland") { + QMessageBox::warning( + NULL, "Barrier", + "You are using wayland session, which is currently not fully supported by Barrier."); + } + QSettings settings; AppConfig appConfig (&settings); From 59d076988f5bb894c64a993ba8dc3aa7984243b4 Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Sat, 23 Oct 2021 18:43:36 +0100 Subject: [PATCH 028/113] Initial test of multi-macOS builds This is an initial test of building Barrier for multiple macOS versions. For: - Big Sur - Moja\ve - Catalina I think there's an indentation issue somewhere, but VS Code isn't 'seeing' it... let's hope this works. If it does, we can proceed to merge. Signed-off-by: Dom Rodriguez --- azure-pipelines.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1ef9a7e0..30f0319b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -83,11 +83,18 @@ jobs: - job: MacBuild displayName: Mac Build - pool: - vmImage: 'macOS-10.14' strategy: matrix: - Release: + big-sur-Release: + imageName: "macOS-11" + B_BUILD_TYPE: Release + BARRIER_VERSION_STAGE: Release + catalina-Release: + imageName: "macOS-10.15" + B_BUILD_TYPE: Release + BARRIER_VERSION_STAGE: Release + mojave-Release: + imageName: "macOS-10.14" B_BUILD_TYPE: Release BARRIER_VERSION_STAGE: Release variables: From 907bcdcfea9d952868eddb3021ac50431f89c0a2 Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Sat, 23 Oct 2021 18:50:18 +0100 Subject: [PATCH 029/113] Fix indentation on macOS matrix Turns out VS Code handled the YAML indentation.... badly. This should fix it. Signed-off-by: Dom Rodriguez --- azure-pipelines.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 30f0319b..21105f8c 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -85,18 +85,18 @@ jobs: displayName: Mac Build strategy: matrix: - big-sur-Release: - imageName: "macOS-11" - B_BUILD_TYPE: Release - BARRIER_VERSION_STAGE: Release - catalina-Release: - imageName: "macOS-10.15" - B_BUILD_TYPE: Release - BARRIER_VERSION_STAGE: Release - mojave-Release: - imageName: "macOS-10.14" - B_BUILD_TYPE: Release - BARRIER_VERSION_STAGE: Release + big-sur-Release: + imageName: "macOS-11" + B_BUILD_TYPE: Release + BARRIER_VERSION_STAGE: Release + catalina-Release: + imageName: "macOS-10.15" + B_BUILD_TYPE: Release + BARRIER_VERSION_STAGE: Release + mojave-Release: + imageName: "macOS-10.14" + B_BUILD_TYPE: Release + BARRIER_VERSION_STAGE: Release variables: VERBOSE: 1 TERM: xterm-256color From a53380de4fcf62f9cd89a0e1398d0c6e0f44540f Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Sat, 23 Oct 2021 19:04:10 +0100 Subject: [PATCH 030/113] Fix missing VM parameter, matrix doesn't select automatically Signed-off-by: Dom Rodriguez --- azure-pipelines.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 21105f8c..3b2d7226 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -97,6 +97,8 @@ jobs: imageName: "macOS-10.14" B_BUILD_TYPE: Release BARRIER_VERSION_STAGE: Release + pool: + vmImage: $(imageName) variables: VERBOSE: 1 TERM: xterm-256color From 2877e6cb174b980258dd5866fe333f187ee7b905 Mon Sep 17 00:00:00 2001 From: Dom Rodriguez Date: Sat, 23 Oct 2021 19:27:00 +0100 Subject: [PATCH 031/113] Pipelines: Remove Ubuntu 16.04 agent Azure Pipelines no longer supports Ubuntu 16.04, so to remove the error, this commit removes it from the cross-platform matrix. Signed-off-by: Dom Rodriguez --- azure-pipelines.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 3b2d7226..2b42fc1d 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -65,8 +65,6 @@ jobs: - job: LinuxBuild strategy: matrix: - ubuntu-16.04: - imageName: 'ubuntu-16.04' ubuntu-18.04: imageName: 'ubuntu-18.04' ubuntu-20.04: From 15a955ff2139c2cc94f382135f8d412c50b74b75 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Sat, 30 Oct 2021 00:52:55 +0300 Subject: [PATCH 032/113] Revert "Use ansi codepage for internal multibyte strings on windows" This reverts commit 402801e0a66a902475723c13f3a03bac2b7fd503. We should use UTF8 throughout the application and convert to platform encodings only at the edge. Otherwise it's not clear which data uses which encoding and we result in extremele brittle system. --- src/gui/src/CommandProcess.cpp | 21 ++++---- src/gui/src/Fingerprint.cpp | 7 ++- src/gui/src/IpcClient.cpp | 8 +-- src/gui/src/MainWindow.cpp | 3 +- src/gui/src/QUtility.cpp | 9 ---- src/gui/src/QUtility.h | 1 - src/gui/src/SslCertificate.cpp | 49 ++++++++++-------- src/gui/src/SslCertificate.h | 8 +-- src/lib/barrier/win32/DaemonApp.cpp | 3 +- src/lib/common/win32/DataDirectories.cpp | 28 ++++++++-- src/lib/common/win32/KnownFolderPaths.cpp | 63 ----------------------- src/lib/common/win32/KnownFolderPaths.h | 24 --------- src/lib/ipc/IpcLogOutputter.cpp | 3 +- src/lib/platform/MSWindowsScreen.cpp | 12 +++-- 14 files changed, 87 insertions(+), 152 deletions(-) delete mode 100644 src/lib/common/win32/KnownFolderPaths.cpp delete mode 100644 src/lib/common/win32/KnownFolderPaths.h diff --git a/src/gui/src/CommandProcess.cpp b/src/gui/src/CommandProcess.cpp index 57397ae7..c85e847b 100644 --- a/src/gui/src/CommandProcess.cpp +++ b/src/gui/src/CommandProcess.cpp @@ -30,35 +30,34 @@ CommandProcess::CommandProcess(QString cmd, QStringList arguments, QString input QString CommandProcess::run() { QProcess process; - QString standardOutput, standardError; process.setReadChannel(QProcess::StandardOutput); process.start(m_Command, m_Arguments); bool success = process.waitForStarted(); + QString output, error; if (success) { if (!m_Input.isEmpty()) { - process.write(m_Input.toLocal8Bit()); + process.write(m_Input.toStdString().c_str()); } if (process.waitForFinished()) { - standardOutput = QString::fromLocal8Bit(process.readAllStandardOutput().trimmed()); - standardError = QString::fromLocal8Bit(process.readAllStandardError().trimmed()); + output = process.readAllStandardOutput().trimmed(); + error = process.readAllStandardError().trimmed(); } } int code = process.exitCode(); - if (!standardError.isEmpty() || !success || code != 0) + if (!error.isEmpty() || !success || code != 0) { throw std::runtime_error( - std::string( - QString("Code: %1\nError: %2") - .arg(process.exitCode()) - .arg(standardError.isEmpty() ? "Unknown" : standardError) - .toLocal8Bit().constData())); + QString("Code: %1\nError: %2") + .arg(process.exitCode()) + .arg(error.isEmpty() ? "Unknown" : error) + .toStdString()); } emit finished(); - return standardOutput; + return output; } diff --git a/src/gui/src/Fingerprint.cpp b/src/gui/src/Fingerprint.cpp index 0e4588f8..cc1ce3bf 100644 --- a/src/gui/src/Fingerprint.cpp +++ b/src/gui/src/Fingerprint.cpp @@ -16,7 +16,8 @@ */ #include "Fingerprint.h" -#include "QUtility.h" + +#include "common/DataDirectories.h" #include #include @@ -123,8 +124,10 @@ void Fingerprint::persistDirectory() QString Fingerprint::directoryPath() { + auto profileDir = QString::fromStdString(DataDirectories::profile()); + return QString("%1/%2") - .arg(profilePath()) + .arg(profileDir) .arg(kDirName); } diff --git a/src/gui/src/IpcClient.cpp b/src/gui/src/IpcClient.cpp index b8b1bcb1..1b0e147a 100644 --- a/src/gui/src/IpcClient.cpp +++ b/src/gui/src/IpcClient.cpp @@ -104,12 +104,14 @@ void IpcClient::sendCommand(const QString& command, ElevateMode const elevate) stream.writeRawData(kIpcMsgCommand, 4); - QByteArray utf8Command = command.toUtf8(); + std::string stdStringCommand = command.toStdString(); + const char* charCommand = stdStringCommand.c_str(); + int length = (int)strlen(charCommand); char lenBuf[4]; - intToBytes(utf8Command.size(), lenBuf, 4); + intToBytes(length, lenBuf, 4); stream.writeRawData(lenBuf, 4); - stream.writeRawData(utf8Command.constData(), utf8Command.size()); + stream.writeRawData(charCommand, length); char elevateBuf[1]; // Refer to enum ElevateMode documentation for why this flag is mapped this way diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 5d4ee8fe..40050782 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -31,6 +31,7 @@ #include "ProcessorArch.h" #include "SslCertificate.h" #include "ShutdownCh.h" +#include "common/DataDirectories.h" #include #include @@ -524,7 +525,7 @@ void MainWindow::startBarrier() // launched the process (e.g. when launched with elevation). setting the // profile dir on launch ensures it uses the same profile dir is used // no matter how its relaunched. - args << "--profile-dir" << QString("\"%1\"").arg(profilePath()); + args << "--profile-dir" << QString::fromStdString("\"" + DataDirectories::profile() + "\""); #endif if ((barrierType() == barrierClient && !clientArgs(args, app)) diff --git a/src/gui/src/QUtility.cpp b/src/gui/src/QUtility.cpp index 932bf146..2d05fc36 100644 --- a/src/gui/src/QUtility.cpp +++ b/src/gui/src/QUtility.cpp @@ -19,7 +19,6 @@ #include "ProcessorArch.h" #include "CommandProcess.h" -#include "common/DataDirectories.h" #if defined(Q_OS_LINUX) #include @@ -113,11 +112,3 @@ QString getOSInformation() return result; } - -QString profilePath() -{ - // Get path to current profile directory, properly converted - // from an OS locale std::string to Unicode QString. - auto localePath = DataDirectories::profile(); - return QString::fromLocal8Bit(localePath.c_str(), localePath.size()); -} diff --git a/src/gui/src/QUtility.h b/src/gui/src/QUtility.h index 7c05fd00..62a60825 100644 --- a/src/gui/src/QUtility.h +++ b/src/gui/src/QUtility.h @@ -29,4 +29,3 @@ QString hash(const QString& string); QString getFirstMacAddress(); qProcessorArch getProcessorArch(); QString getOSInformation(); -QString profilePath(); diff --git a/src/gui/src/SslCertificate.cpp b/src/gui/src/SslCertificate.cpp index 84ce5459..9dc93ce8 100644 --- a/src/gui/src/SslCertificate.cpp +++ b/src/gui/src/SslCertificate.cpp @@ -17,7 +17,7 @@ #include "SslCertificate.h" #include "Fingerprint.h" -#include "QUtility.h" +#include "common/DataDirectories.h" #include #include @@ -43,13 +43,13 @@ static const char kConfigFile[] = "barrier.conf"; SslCertificate::SslCertificate(QObject *parent) : QObject(parent) { - m_ProfileDir = profilePath(); - if (m_ProfileDir.isEmpty()) { + m_ProfileDir = DataDirectories::profile(); + if (m_ProfileDir.empty()) { emit error(tr("Failed to get profile directory.")); } } -std::pair SslCertificate::runTool(const QStringList& args) +std::pair SslCertificate::runTool(const QStringList& args) { QString program; #if defined(Q_OS_WIN) @@ -68,15 +68,17 @@ std::pair SslCertificate::runTool(const QStringList& args) #endif QProcess process; - QString standardOutput, standardError; process.setEnvironment(environment); process.start(program, args); - bool success = process.waitForStarted(); + bool success = process.waitForStarted(); + std::string output; + + QString standardError; if (success && process.waitForFinished()) { - standardOutput = QString::fromLocal8Bit(process.readAllStandardOutput().trimmed()); - standardError = QString::fromLocal8Bit(process.readAllStandardError().trimmed()); + output = process.readAllStandardOutput().trimmed().toStdString(); + standardError = process.readAllStandardError().trimmed(); } int code = process.exitCode(); @@ -87,15 +89,15 @@ std::pair SslCertificate::runTool(const QStringList& args) .arg(program) .arg(process.exitCode()) .arg(standardError.isEmpty() ? "Unknown" : standardError)); - return {false, standardOutput}; + return {false, output}; } - return {true, standardOutput}; + return {true, output}; } void SslCertificate::generateCertificate() { - auto filename = getCertificatePath(); + auto filename = QString::fromStdString(getCertificatePath()); QFile file(filename); if (!file.exists() || !isCertificateValid(filename)) { @@ -120,7 +122,7 @@ void SslCertificate::generateCertificate() arguments.append("-newkey"); arguments.append("rsa:2048"); - QDir sslDir(getCertificateDirectory()); + QDir sslDir(QString::fromStdString(getCertificateDirectory())); if (!sslDir.exists()) { sslDir.mkpath("."); } @@ -157,17 +159,20 @@ void SslCertificate::generateFingerprint(const QString& certificateFilename) auto ret = runTool(arguments); bool success = ret.first; + std::string output = ret.second; + if (!success) { return; } // find the fingerprint from the tool output - QString fingerprint = ret.second; - auto i = fingerprint.indexOf('='); - if (i != -1) { - fingerprint.remove(0, i+1); + auto i = output.find_first_of('='); + if (i != std::string::npos) { + i++; + auto fingerprint = output.substr( + i, output.size() - i); - Fingerprint::local().trust(fingerprint, false); + Fingerprint::local().trust(QString::fromStdString(fingerprint), false); emit info(tr("SSL fingerprint generated.")); } else { @@ -175,14 +180,14 @@ void SslCertificate::generateFingerprint(const QString& certificateFilename) } } -QString SslCertificate::getCertificatePath() +std::string SslCertificate::getCertificatePath() { - return getCertificateDirectory() + QDir::separator() + kCertificateFilename; + return getCertificateDirectory() + QDir::separator().toLatin1() + kCertificateFilename; } -QString SslCertificate::getCertificateDirectory() +std::string SslCertificate::getCertificateDirectory() { - return m_ProfileDir + QDir::separator() + kSslDir; + return m_ProfileDir + QDir::separator().toLatin1() + kSslDir; } bool SslCertificate::isCertificateValid(const QString& path) @@ -193,7 +198,7 @@ bool SslCertificate::isCertificateValid(const QString& path) BIO* bio = BIO_new(BIO_s_file()); - auto ret = BIO_read_filename(bio, path.toLocal8Bit().constData()); + auto ret = BIO_read_filename(bio, path.toStdString().c_str()); if (!ret) { emit info(tr("Could not read from default certificate file.")); BIO_free_all(bio); diff --git a/src/gui/src/SslCertificate.h b/src/gui/src/SslCertificate.h index e8ae2738..2fe807a2 100644 --- a/src/gui/src/SslCertificate.h +++ b/src/gui/src/SslCertificate.h @@ -36,13 +36,13 @@ signals: void generateFinished(); private: - std::pair runTool(const QStringList& args); + std::pair runTool(const QStringList& args); void generateFingerprint(const QString& certificateFilename); - QString getCertificatePath(); - QString getCertificateDirectory(); + std::string getCertificatePath(); + std::string getCertificateDirectory(); bool isCertificateValid(const QString& path); private: - QString m_ProfileDir; + std::string m_ProfileDir; }; diff --git a/src/lib/barrier/win32/DaemonApp.cpp b/src/lib/barrier/win32/DaemonApp.cpp index f8cf591a..88e6b4ef 100644 --- a/src/lib/barrier/win32/DaemonApp.cpp +++ b/src/lib/barrier/win32/DaemonApp.cpp @@ -34,7 +34,6 @@ #include "base/log_outputters.h" #include "base/Log.h" #include "common/DataDirectories.h" -#include "base/Unicode.h" #include "arch/win32/ArchMiscWindows.h" #include "arch/win32/XArchWindows.h" @@ -258,7 +257,7 @@ DaemonApp::handleIpcMessage(const Event& e, void*) switch (m->type()) { case kIpcCommand: { IpcCommandMessage* cm = static_cast(m); - String command = Unicode::UTF8ToText(cm->command()); + String command = cm->command(); // if empty quotes, clear. if (command == "\"\"") { diff --git a/src/lib/common/win32/DataDirectories.cpp b/src/lib/common/win32/DataDirectories.cpp index 62250b10..b6d77be5 100644 --- a/src/lib/common/win32/DataDirectories.cpp +++ b/src/lib/common/win32/DataDirectories.cpp @@ -16,12 +16,34 @@ */ #include "../DataDirectories.h" -#include "KnownFolderPaths.h" + +#include + +std::string unicode_to_mb(const WCHAR* utfStr) +{ + int utfLength = lstrlenW(utfStr); + int mbLength = WideCharToMultiByte(CP_UTF8, 0, utfStr, utfLength, NULL, 0, NULL, NULL); + std::string mbStr(mbLength, 0); + WideCharToMultiByte(CP_UTF8, 0, utfStr, utfLength, &mbStr[0], mbLength, NULL, NULL); + return mbStr; +} + +std::string known_folder_path(const KNOWNFOLDERID& id) +{ + std::string path; + WCHAR* buffer; + HRESULT result = SHGetKnownFolderPath(id, 0, NULL, &buffer); + if (result == S_OK) { + path = unicode_to_mb(buffer); + CoTaskMemFree(buffer); + } + return path; +} const std::string& DataDirectories::profile() { if (_profile.empty()) - _profile = localAppDataPath() + "\\Barrier"; + _profile = known_folder_path(FOLDERID_LocalAppData) + "\\Barrier"; return _profile; } const std::string& DataDirectories::profile(const std::string& path) @@ -33,7 +55,7 @@ const std::string& DataDirectories::profile(const std::string& path) const std::string& DataDirectories::global() { if (_global.empty()) - _global = programDataPath() + "\\Barrier"; + _global = known_folder_path(FOLDERID_ProgramData) + "\\Barrier"; return _global; } const std::string& DataDirectories::global(const std::string& path) diff --git a/src/lib/common/win32/KnownFolderPaths.cpp b/src/lib/common/win32/KnownFolderPaths.cpp deleted file mode 100644 index 23ccc84a..00000000 --- a/src/lib/common/win32/KnownFolderPaths.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* -* barrier -- mouse and keyboard sharing utility -* Copyright (C) 2018 Debauchee Open Source Group -* -* This package is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* found in the file LICENSE that should have accompanied this file. -* -* This package 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 . -*/ - -#include "KnownFolderPaths.h" - -#define WIN32_LEAN_AND_MEAN -#include -#include - -static std::string wide_to_mb(const wchar_t* source, int length) -{ - int ansiLength = WideCharToMultiByte(CP_ACP, 0, source, length, NULL, 0, NULL, NULL); - if (ansiLength > 0) { - std::string ansiString(ansiLength, 0); - ansiLength = WideCharToMultiByte(CP_ACP, 0, source, length, &ansiString[0], ansiLength, NULL, NULL); - if (ansiLength > 0) { - return ansiString; - } - } - return {}; -} - -static std::string known_folder_path(const KNOWNFOLDERID& id) -{ - std::string path; - WCHAR* buffer; - HRESULT result = SHGetKnownFolderPath(id, 0, NULL, &buffer); - if (result == S_OK) { - auto length = lstrlenW(buffer); - path = wide_to_mb(buffer, length); - CoTaskMemFree(buffer); - } - return path; -} - -std::string desktopPath() -{ - return known_folder_path(FOLDERID_Desktop); -} - -std::string localAppDataPath() -{ - return known_folder_path(FOLDERID_LocalAppData); -} - -std::string programDataPath() -{ - return known_folder_path(FOLDERID_ProgramData); -} diff --git a/src/lib/common/win32/KnownFolderPaths.h b/src/lib/common/win32/KnownFolderPaths.h deleted file mode 100644 index 81b650ec..00000000 --- a/src/lib/common/win32/KnownFolderPaths.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -* barrier -- mouse and keyboard sharing utility -* Copyright (C) 2018 Debauchee Open Source Group -* -* This package is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* found in the file LICENSE that should have accompanied this file. -* -* This package 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 . -*/ - -#pragma once - -#include - -std::string desktopPath(); -std::string localAppDataPath(); -std::string programDataPath(); diff --git a/src/lib/ipc/IpcLogOutputter.cpp b/src/lib/ipc/IpcLogOutputter.cpp index c895dc12..223f52f7 100644 --- a/src/lib/ipc/IpcLogOutputter.cpp +++ b/src/lib/ipc/IpcLogOutputter.cpp @@ -29,7 +29,6 @@ #include "base/EventQueue.h" #include "base/TMethodEventJob.h" #include "base/TMethodJob.h" -#include "base/Unicode.h" enum EIpcLogOutputter { kBufferMaxSize = 1000, @@ -197,7 +196,7 @@ IpcLogOutputter::sendBuffer() return; } - IpcLogLineMessage message(Unicode::textToUTF8(getChunk(kMaxSendLines))); + IpcLogLineMessage message(getChunk(kMaxSendLines)); m_sending = true; m_ipcServer.send(message, kIpcClientGui); m_sending = false; diff --git a/src/lib/platform/MSWindowsScreen.cpp b/src/lib/platform/MSWindowsScreen.cpp index 739a1e25..2449ba7c 100644 --- a/src/lib/platform/MSWindowsScreen.cpp +++ b/src/lib/platform/MSWindowsScreen.cpp @@ -41,9 +41,9 @@ #include "base/IEventQueue.h" #include "base/TMethodEventJob.h" #include "base/TMethodJob.h" -#include "common/win32/KnownFolderPaths.h" #include +#include #include #include @@ -1916,12 +1916,14 @@ const std::string& MSWindowsScreen::getDropTarget() const { if (m_dropTargetPath.empty()) { - m_dropTargetPath = desktopPath(); - if (!m_dropTargetPath.empty()) { - LOG((CLOG_DEBUG "using desktop for drop target: %s", m_dropTargetPath.c_str())); + // SHGetFolderPath is deprecated in vista, but use it for xp support. + char desktopPath[MAX_PATH]; + if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, 0, desktopPath))) { + m_dropTargetPath = std::string(desktopPath); + LOG((CLOG_INFO "using desktop for drop target: %s", m_dropTargetPath.c_str())); } else { - LOG((CLOG_ERR "failed to get desktop path, no drop target available")); + LOG((CLOG_ERR "failed to get desktop path, no drop target available, error=%d", GetLastError())); } } return m_dropTargetPath; From 8286c85dc0722e99273f7f2d7a2375cbc830cc84 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Sat, 30 Oct 2021 00:52:56 +0300 Subject: [PATCH 033/113] lib/common/win32: Extract unicode_to_mb() to separate file --- src/lib/common/win32/DataDirectories.cpp | 12 ++------- src/lib/common/win32/encoding_utilities.cpp | 27 +++++++++++++++++++++ src/lib/common/win32/encoding_utilities.h | 25 +++++++++++++++++++ 3 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 src/lib/common/win32/encoding_utilities.cpp create mode 100644 src/lib/common/win32/encoding_utilities.h diff --git a/src/lib/common/win32/DataDirectories.cpp b/src/lib/common/win32/DataDirectories.cpp index b6d77be5..32bc2136 100644 --- a/src/lib/common/win32/DataDirectories.cpp +++ b/src/lib/common/win32/DataDirectories.cpp @@ -16,25 +16,17 @@ */ #include "../DataDirectories.h" +#include "encoding_utilities.h" #include -std::string unicode_to_mb(const WCHAR* utfStr) -{ - int utfLength = lstrlenW(utfStr); - int mbLength = WideCharToMultiByte(CP_UTF8, 0, utfStr, utfLength, NULL, 0, NULL, NULL); - std::string mbStr(mbLength, 0); - WideCharToMultiByte(CP_UTF8, 0, utfStr, utfLength, &mbStr[0], mbLength, NULL, NULL); - return mbStr; -} - std::string known_folder_path(const KNOWNFOLDERID& id) { std::string path; WCHAR* buffer; HRESULT result = SHGetKnownFolderPath(id, 0, NULL, &buffer); if (result == S_OK) { - path = unicode_to_mb(buffer); + path = win_wchar_to_utf8(buffer); CoTaskMemFree(buffer); } return path; diff --git a/src/lib/common/win32/encoding_utilities.cpp b/src/lib/common/win32/encoding_utilities.cpp new file mode 100644 index 00000000..16379316 --- /dev/null +++ b/src/lib/common/win32/encoding_utilities.cpp @@ -0,0 +1,27 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . +*/ + +#include "encoding_utilities.h" + +std::string win_wchar_to_utf8(const WCHAR* utfStr) +{ + int utfLength = lstrlenW(utfStr); + int mbLength = WideCharToMultiByte(CP_UTF8, 0, utfStr, utfLength, NULL, 0, NULL, NULL); + std::string mbStr(mbLength, 0); + WideCharToMultiByte(CP_UTF8, 0, utfStr, utfLength, &mbStr[0], mbLength, NULL, NULL); + return mbStr; +} diff --git a/src/lib/common/win32/encoding_utilities.h b/src/lib/common/win32/encoding_utilities.h new file mode 100644 index 00000000..f09cf531 --- /dev/null +++ b/src/lib/common/win32/encoding_utilities.h @@ -0,0 +1,25 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . +*/ + +#ifndef BARRIER_LIB_COMMON_WIN32_ENCODING_UTILITIES_H +#define BARRIER_LIB_COMMON_WIN32_ENCODING_UTILITIES_H + +#include + +std::string win_wchar_to_utf8(const WCHAR* utfStr); + +#endif From d24f368efe9a1b4edb6a56f4ee53bdc817edde91 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Sat, 30 Oct 2021 00:52:57 +0300 Subject: [PATCH 034/113] Correctly open files with non-ASCII paths on Windows This fixes #976, fixes #974, fixes #444. On Windows the standard stream open() functions expect bytes encoded in current system encoding, not UTF8. Since we're dealing with UTF8 throughout the application this results in wrong paths being passed and failure to open files. As a solution, we convert the paths to UTF16 via the WCHAR character type and use the special Windows-specific overloads of open() functions. --- src/lib/barrier/DropHelper.cpp | 3 +- src/lib/base/log_outputters.cpp | 4 +- src/lib/common/win32/encoding_utilities.cpp | 10 ++++ src/lib/common/win32/encoding_utilities.h | 3 ++ src/lib/io/fstream.cpp | 57 +++++++++++++++++++++ src/lib/io/fstream.h | 35 +++++++++++++ src/lib/net/SecureSocket.cpp | 3 +- 7 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 src/lib/io/fstream.cpp create mode 100644 src/lib/io/fstream.h diff --git a/src/lib/barrier/DropHelper.cpp b/src/lib/barrier/DropHelper.cpp index e3e15939..32f20cfc 100644 --- a/src/lib/barrier/DropHelper.cpp +++ b/src/lib/barrier/DropHelper.cpp @@ -18,6 +18,7 @@ #include "barrier/DropHelper.h" #include "base/Log.h" +#include "io/fstream.h" #include @@ -35,7 +36,7 @@ DropHelper::writeToDir(const String& destination, DragFileList& fileList, String dropTarget.append("/"); #endif dropTarget.append(fileList.at(0).getFilename()); - file.open(dropTarget.c_str(), std::ios::out | std::ios::binary); + barrier::open_utf8_path(file, dropTarget, std::ios::out | std::ios::binary); if (!file.is_open()) { LOG((CLOG_ERR "drop file failed: can not open %s", dropTarget.c_str())); } diff --git a/src/lib/base/log_outputters.cpp b/src/lib/base/log_outputters.cpp index 1d43f605..6d3374b5 100644 --- a/src/lib/base/log_outputters.cpp +++ b/src/lib/base/log_outputters.cpp @@ -20,7 +20,7 @@ #include "base/TMethodJob.h" #include "arch/Arch.h" #include "base/String.h" - +#include "io/fstream.h" #include enum EFileLogOutputter { @@ -260,7 +260,7 @@ FileLogOutputter::write(ELevel level, const char *message) bool moveFile = false; std::ofstream m_handle; - m_handle.open(m_fileName.c_str(), std::fstream::app); + barrier::open_utf8_path(m_handle, m_fileName, std::fstream::app); if (m_handle.is_open() && m_handle.fail() != true) { m_handle << message << std::endl; diff --git a/src/lib/common/win32/encoding_utilities.cpp b/src/lib/common/win32/encoding_utilities.cpp index 16379316..11781d36 100644 --- a/src/lib/common/win32/encoding_utilities.cpp +++ b/src/lib/common/win32/encoding_utilities.cpp @@ -16,6 +16,7 @@ */ #include "encoding_utilities.h" +#include std::string win_wchar_to_utf8(const WCHAR* utfStr) { @@ -25,3 +26,12 @@ std::string win_wchar_to_utf8(const WCHAR* utfStr) WideCharToMultiByte(CP_UTF8, 0, utfStr, utfLength, &mbStr[0], mbLength, NULL, NULL); return mbStr; } + +std::vector utf8_to_win_char(const std::string& str) +{ + int result_len = MultiByteToWideChar(CP_UTF8, 0, str.data(), str.size(), NULL, 0); + std::vector result; + result.resize(result_len + 1, 0); + MultiByteToWideChar(CP_UTF8, 0, str.data(), str.size(), result.data(), result_len); + return result; +} diff --git a/src/lib/common/win32/encoding_utilities.h b/src/lib/common/win32/encoding_utilities.h index f09cf531..747371e8 100644 --- a/src/lib/common/win32/encoding_utilities.h +++ b/src/lib/common/win32/encoding_utilities.h @@ -18,8 +18,11 @@ #ifndef BARRIER_LIB_COMMON_WIN32_ENCODING_UTILITIES_H #define BARRIER_LIB_COMMON_WIN32_ENCODING_UTILITIES_H +#include #include +#include std::string win_wchar_to_utf8(const WCHAR* utfStr); +std::vector utf8_to_win_char(const std::string& str); #endif diff --git a/src/lib/io/fstream.cpp b/src/lib/io/fstream.cpp new file mode 100644 index 00000000..4aef9073 --- /dev/null +++ b/src/lib/io/fstream.cpp @@ -0,0 +1,57 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . +*/ + +#include "fstream.h" +#if SYSAPI_WIN32 +#include "common/win32/encoding_utilities.h" +#endif +#include + +namespace barrier { + +namespace { + +template +void open_utf8_path_impl(Stream& stream, const std::string& path, std::ios_base::openmode mode) +{ +#if SYSAPI_WIN32 + // on Windows we need to use a private constructor from wchar_t* string. + auto wchar_path = utf8_to_win_char(path); + stream.open(wchar_path.data(), mode); +#else + stream.open(path.c_str(), mode); +#endif +} + +} // namespace + +void open_utf8_path(std::ifstream& stream, const std::string& path, std::ios_base::openmode mode) +{ + open_utf8_path_impl(stream, path, mode); +} + +void open_utf8_path(std::ofstream& stream, const std::string& path, std::ios_base::openmode mode) +{ + open_utf8_path_impl(stream, path, mode); +} + +void open_utf8_path(std::fstream& stream, const std::string& path, std::ios_base::openmode mode) +{ + open_utf8_path_impl(stream, path, mode); +} + +} // namespace barrier diff --git a/src/lib/io/fstream.h b/src/lib/io/fstream.h new file mode 100644 index 00000000..26288373 --- /dev/null +++ b/src/lib/io/fstream.h @@ -0,0 +1,35 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . +*/ + +#ifndef BARRIER_LIB_IO_FSTREAM_H +#define BARRIER_LIB_IO_FSTREAM_H + +#include +#include + +namespace barrier { + +void open_utf8_path(std::ifstream& stream, const std::string& path, + std::ios_base::openmode mode = std::ios_base::in); +void open_utf8_path(std::ofstream& stream, const std::string& path, + std::ios_base::openmode mode = std::ios_base::out); +void open_utf8_path(std::fstream& stream, const std::string& path, + std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out); + +} // namespace barrier + +#endif diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 6982d0f1..c3c1a064 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -25,6 +25,7 @@ #include "base/Log.h" #include "base/String.h" #include "common/DataDirectories.h" +#include "io/fstream.h" #include #include @@ -708,7 +709,7 @@ SecureSocket::verifyCertFingerprint() // check if this fingerprint exist std::string fileLine; std::ifstream file; - file.open(trustedServersFilename.c_str()); + barrier::open_utf8_path(file, trustedServersFilename); if (!file.is_open()) { LOG((CLOG_NOTE "Unable to open trustedServersFile: %s", trustedServersFilename.c_str() )); From a4ff91a9914a94d62769017313be2cbb4d777208 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Thu, 28 Oct 2021 04:00:43 -0700 Subject: [PATCH 035/113] azure-pipelines: Use Invoke-WebRequest to download files When running System.Net.WebClient locally it results in a non-descriptive "An exception occurred during a WebClient request" error message. Invoke-WebRequest is an alternative that works so switch to that. --- azure-pipelines/download_install_bonjour_sdk_like.ps1 | 3 +-- azure-pipelines/download_install_qt.ps1 | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/azure-pipelines/download_install_bonjour_sdk_like.ps1 b/azure-pipelines/download_install_bonjour_sdk_like.ps1 index 97bfa832..7f5fcb96 100644 --- a/azure-pipelines/download_install_bonjour_sdk_like.ps1 +++ b/azure-pipelines/download_install_bonjour_sdk_like.ps1 @@ -1,8 +1,7 @@ $ErrorActionPreference = "Stop" New-Item -Force -ItemType Directory -Path ".\deps\" -$Wc = New-Object System.Net.WebClient -$Wc.DownloadFile('https://github.com/nelsonjchen/mDNSResponder/releases/download/v2019.05.08.1/x64_RelWithDebInfo.zip', 'deps\BonjourSDKLike.zip') ; +Invoke-WebRequest 'https://github.com/nelsonjchen/mDNSResponder/releases/download/v2019.05.08.1/x64_RelWithDebInfo.zip' -OutFile 'deps\BonjourSDKLike.zip' ; Write-Output 'Downloaded BonjourSDKLike Zip' Write-Output 'Unzipping BonjourSDKLike Zip' Remove-Item -Recurse -Force -ErrorAction Ignore .\deps\BonjourSDKLike diff --git a/azure-pipelines/download_install_qt.ps1 b/azure-pipelines/download_install_qt.ps1 index e31b9b7a..a4b51d2c 100644 --- a/azure-pipelines/download_install_qt.ps1 +++ b/azure-pipelines/download_install_qt.ps1 @@ -6,8 +6,7 @@ $qt_version = '5.13.0' New-Item -Force -ItemType Directory -Path ".\deps\" Write-Output 'Downloading QLI Installer' -$Wc = New-Object System.Net.WebClient -$Wc.DownloadFile("https://github.com/nelsonjchen/qli-installer/archive/v$qli_install_version.zip", '.\deps\qli-installer.zip') ; +Invoke-WebRequest "https://github.com/nelsonjchen/qli-installer/archive/v$qli_install_version.zip" -OutFile '.\deps\qli-installer.zip' ; Write-Output 'Downloaded QLI Installer' Write-Output 'Extracting QLI Installer' From bfa8964305386901b682830e278bd009adb52b49 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Thu, 28 Oct 2021 14:19:22 +0300 Subject: [PATCH 036/113] Enable encryption by default --- doc/newsfragments/enable-crypto-by-default.feature | 2 ++ src/gui/src/MainWindow.cpp | 4 ++-- src/lib/barrier/App.h | 3 ++- src/lib/barrier/ArgParser.cpp | 5 ++++- src/lib/barrier/ArgsBase.cpp | 2 +- 5 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 doc/newsfragments/enable-crypto-by-default.feature diff --git a/doc/newsfragments/enable-crypto-by-default.feature b/doc/newsfragments/enable-crypto-by-default.feature new file mode 100644 index 00000000..0c633ee6 --- /dev/null +++ b/doc/newsfragments/enable-crypto-by-default.feature @@ -0,0 +1,2 @@ +The `--enable-crypto` command line option has been made the default to reduce chances of accidental security mishaps when configuring Barrier from command line. +A new `--disable-crypto` command line option has been added to explicitly disable encryption. diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 40050782..9072b864 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -516,8 +516,8 @@ void MainWindow::startBarrier() #endif - if (m_AppConfig->getCryptoEnabled()) { - args << "--enable-crypto"; + if (!m_AppConfig->getCryptoEnabled()) { + args << "--disable-crypto"; } #if defined(Q_OS_WIN) diff --git a/src/lib/barrier/App.h b/src/lib/barrier/App.h index 749ca85d..d747b5c6 100644 --- a/src/lib/barrier/App.h +++ b/src/lib/barrier/App.h @@ -166,7 +166,8 @@ private: " -l --log write log messages to file.\n" \ " --no-tray disable the system tray icon.\n" \ " --enable-drag-drop enable file drag & drop.\n" \ - " --enable-crypto enable the crypto (ssl) plugin.\n" \ + " --enable-crypto enable the crypto (ssl) plugin (default, deprecated).\n" \ + " --disable-crypto disable the crypto (ssl) plugin.\n" \ " --profile-dir use named profile directory instead.\n" \ " --drop-dir use named drop target directory instead.\n" diff --git a/src/lib/barrier/ArgParser.cpp b/src/lib/barrier/ArgParser.cpp index 1ac4baff..4c57e798 100644 --- a/src/lib/barrier/ArgParser.cpp +++ b/src/lib/barrier/ArgParser.cpp @@ -282,7 +282,10 @@ ArgParser::parseGenericArgs(int argc, const char* const* argv, int& i) argsBase().m_dropTarget = argv[++i]; } else if (isArg(i, argc, argv, NULL, "--enable-crypto")) { - argsBase().m_enableCrypto = true; + LOG((CLOG_INFO "--enable-crypto is used by default. The option is deprecated.")); + } + else if (isArg(i, argc, argv, NULL, "--disable-crypto")) { + argsBase().m_enableCrypto = false; } else if (isArg(i, argc, argv, NULL, "--profile-dir", 1)) { argsBase().m_profileDirectory = argv[++i]; diff --git a/src/lib/barrier/ArgsBase.cpp b/src/lib/barrier/ArgsBase.cpp index dd983c6f..b392339a 100644 --- a/src/lib/barrier/ArgsBase.cpp +++ b/src/lib/barrier/ArgsBase.cpp @@ -42,7 +42,7 @@ m_enableDragDrop(false), m_dropTarget(""), m_shouldExit(false), m_barrierAddress(), -m_enableCrypto(false), + m_enableCrypto(true), m_profileDirectory(""), m_pluginDirectory("") { From 0e406d491823bfc9dfed0fcc7934cdece8db7dd0 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:29 +0200 Subject: [PATCH 037/113] lib/net: Extract fingerprint formatting out of SecureSocket --- src/lib/net/SecureSocket.cpp | 22 ++------------------- src/lib/net/SecureSocket.h | 1 - src/lib/net/SecureUtils.cpp | 38 ++++++++++++++++++++++++++++++++++++ src/lib/net/SecureUtils.h | 25 ++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 21 deletions(-) create mode 100644 src/lib/net/SecureUtils.cpp create mode 100644 src/lib/net/SecureUtils.h diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index c3c1a064..f6ed0194 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -16,6 +16,7 @@ */ #include "SecureSocket.h" +#include "SecureUtils.h" #include "net/TSocketMultiplexerMethodJob.h" #include "base/TMethodEventJob.h" @@ -656,25 +657,6 @@ SecureSocket::disconnect() sendEvent(getEvents()->forIStream().inputShutdown()); } -void SecureSocket::formatFingerprint(std::string& fingerprint, bool hex, bool separator) -{ - if (hex) { - // to hexadecimal - barrier::string::toHex(fingerprint, 2); - } - - // all uppercase - barrier::string::uppercase(fingerprint); - - if (separator) { - // add colon to separate each 2 characters - size_t separators = fingerprint.size() / 2; - for (size_t i = 1; i < separators; i++) { - fingerprint.insert(i * 3 - 1, ":"); - } - } -} - bool SecureSocket::verifyCertFingerprint() { @@ -693,7 +675,7 @@ SecureSocket::verifyCertFingerprint() // format fingerprint into hexdecimal format with colon separator std::string fingerprint(reinterpret_cast(tempFingerprint), tempFingerprintLen); - formatFingerprint(fingerprint); + format_ssl_fingerprint(fingerprint); LOG((CLOG_NOTE "server fingerprint: %s", fingerprint.c_str())); std::string trustedServersFilename; diff --git a/src/lib/net/SecureSocket.h b/src/lib/net/SecureSocket.h index f861d662..24653b6f 100644 --- a/src/lib/net/SecureSocket.h +++ b/src/lib/net/SecureSocket.h @@ -68,7 +68,6 @@ private: void showError(const std::string& reason); std::string getError(); void disconnect(); - void formatFingerprint(std::string& fingerprint, bool hex = true, bool separator = true); bool verifyCertFingerprint(); MultiplexerJobStatus serviceConnect(ISocketMultiplexerJob*, bool, bool, bool); diff --git a/src/lib/net/SecureUtils.cpp b/src/lib/net/SecureUtils.cpp new file mode 100644 index 00000000..c796e9c7 --- /dev/null +++ b/src/lib/net/SecureUtils.cpp @@ -0,0 +1,38 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . +*/ + +#include "SecureUtils.h" +#include "base/String.h" + +void format_ssl_fingerprint(std::string& fingerprint, bool hex, bool separator) +{ + if (hex) { + // to hexadecimal + barrier::string::toHex(fingerprint, 2); + } + + // all uppercase + barrier::string::uppercase(fingerprint); + + if (separator) { + // add colon to separate each 2 characters + size_t separators = fingerprint.size() / 2; + for (size_t i = 1; i < separators; i++) { + fingerprint.insert(i * 3 - 1, ":"); + } + } +} diff --git a/src/lib/net/SecureUtils.h b/src/lib/net/SecureUtils.h new file mode 100644 index 00000000..7b6d09bc --- /dev/null +++ b/src/lib/net/SecureUtils.h @@ -0,0 +1,25 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . +*/ + +#ifndef BARRIER_LIB_NET_SECUREUTILS_H +#define BARRIER_LIB_NET_SECUREUTILS_H + +#include + +void format_ssl_fingerprint(std::string& fingerprint, bool hex = true, bool separator = true); + +#endif // BARRIER_LIB_NET_SECUREUTILS_H From 7f71924a862f64b984688b0c6eb3c14c64f60e2c Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:30 +0200 Subject: [PATCH 038/113] lib/net: Make format_ssl_fingerprint() easier to use --- src/lib/net/SecureSocket.cpp | 2 +- src/lib/net/SecureUtils.cpp | 11 ++++++----- src/lib/net/SecureUtils.h | 3 ++- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index f6ed0194..3d5e2be0 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -675,7 +675,7 @@ SecureSocket::verifyCertFingerprint() // format fingerprint into hexdecimal format with colon separator std::string fingerprint(reinterpret_cast(tempFingerprint), tempFingerprintLen); - format_ssl_fingerprint(fingerprint); + fingerprint = format_ssl_fingerprint(fingerprint); LOG((CLOG_NOTE "server fingerprint: %s", fingerprint.c_str())); std::string trustedServersFilename; diff --git a/src/lib/net/SecureUtils.cpp b/src/lib/net/SecureUtils.cpp index c796e9c7..72d4fbf0 100644 --- a/src/lib/net/SecureUtils.cpp +++ b/src/lib/net/SecureUtils.cpp @@ -18,21 +18,22 @@ #include "SecureUtils.h" #include "base/String.h" -void format_ssl_fingerprint(std::string& fingerprint, bool hex, bool separator) +std::string format_ssl_fingerprint(const std::string& fingerprint, bool hex, bool separator) { + std::string result = fingerprint; if (hex) { // to hexadecimal - barrier::string::toHex(fingerprint, 2); + barrier::string::toHex(result, 2); } // all uppercase - barrier::string::uppercase(fingerprint); + barrier::string::uppercase(result); if (separator) { // add colon to separate each 2 characters - size_t separators = fingerprint.size() / 2; + size_t separators = result.size() / 2; for (size_t i = 1; i < separators; i++) { - fingerprint.insert(i * 3 - 1, ":"); + result.insert(i * 3 - 1, ":"); } } } diff --git a/src/lib/net/SecureUtils.h b/src/lib/net/SecureUtils.h index 7b6d09bc..7c94fe92 100644 --- a/src/lib/net/SecureUtils.h +++ b/src/lib/net/SecureUtils.h @@ -20,6 +20,7 @@ #include -void format_ssl_fingerprint(std::string& fingerprint, bool hex = true, bool separator = true); +std::string format_ssl_fingerprint(const std::string& fingerprint, + bool hex = true, bool separator = true); #endif // BARRIER_LIB_NET_SECUREUTILS_H From 96e002157213bd127ab4a9c3ea4cab8e97cbbd5a Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:31 +0200 Subject: [PATCH 039/113] lib/base: Make to_hex() easier to use --- src/lib/base/String.cpp | 5 ++--- src/lib/base/String.h | 2 +- src/lib/net/SecureUtils.cpp | 3 ++- src/test/unittests/base/StringTests.cpp | 4 +--- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/lib/base/String.cpp b/src/lib/base/String.cpp index 389ca8aa..dcf7318a 100644 --- a/src/lib/base/String.cpp +++ b/src/lib/base/String.cpp @@ -185,8 +185,7 @@ removeFileExt(std::string filename) return filename.substr(0, dot); } -void -toHex(std::string& subject, int width, const char fill) +std::string to_hex(const std::string& subject, int width, const char fill) { std::stringstream ss; ss << std::hex; @@ -194,7 +193,7 @@ toHex(std::string& subject, int width, const char fill) ss << std::setw(width) << std::setfill(fill) << (int)(unsigned char)subject[i]; } - subject = ss.str(); + return ss.str(); } void diff --git a/src/lib/base/String.h b/src/lib/base/String.h index 047b6e16..a543cf86 100644 --- a/src/lib/base/String.h +++ b/src/lib/base/String.h @@ -75,7 +75,7 @@ std::string removeFileExt(std::string filename); /*! Convert each character in \c subject into hexdecimal form with \c width */ -void toHex(std::string& subject, int width, const char fill = '0'); +std::string to_hex(const std::string& subject, int width, const char fill = '0'); //! Convert to all uppercase /*! diff --git a/src/lib/net/SecureUtils.cpp b/src/lib/net/SecureUtils.cpp index 72d4fbf0..7c4a52da 100644 --- a/src/lib/net/SecureUtils.cpp +++ b/src/lib/net/SecureUtils.cpp @@ -23,7 +23,7 @@ std::string format_ssl_fingerprint(const std::string& fingerprint, bool hex, boo std::string result = fingerprint; if (hex) { // to hexadecimal - barrier::string::toHex(result, 2); + result = barrier::string::to_hex(result, 2); } // all uppercase @@ -36,4 +36,5 @@ std::string format_ssl_fingerprint(const std::string& fingerprint, bool hex, boo result.insert(i * 3 - 1, ":"); } } + return result; } diff --git a/src/test/unittests/base/StringTests.cpp b/src/test/unittests/base/StringTests.cpp index 5643aa53..fd771f42 100644 --- a/src/test/unittests/base/StringTests.cpp +++ b/src/test/unittests/base/StringTests.cpp @@ -59,9 +59,7 @@ TEST(StringTests, toHex_plaintext_hexString) String subject = "foobar"; int width = 2; - string::toHex(subject, width); - - EXPECT_EQ("666f6f626172", subject); + EXPECT_EQ("666f6f626172", string::to_hex(subject, width)); } TEST(StringTests, uppercase_lowercaseInput_uppercaseOutput) From 9d8e1faf59bbbc0360adc52b964d71a510f4e8a2 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:32 +0200 Subject: [PATCH 040/113] test: Add test for format_ssl_fingerprint() --- src/test/unittests/net/SecureUtilsTests.cpp | 47 +++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/test/unittests/net/SecureUtilsTests.cpp diff --git a/src/test/unittests/net/SecureUtilsTests.cpp b/src/test/unittests/net/SecureUtilsTests.cpp new file mode 100644 index 00000000..a77f158f --- /dev/null +++ b/src/test/unittests/net/SecureUtilsTests.cpp @@ -0,0 +1,47 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) 2021 Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . + */ + +#include "net/SecureUtils.h" + +#include "test/global/gtest.h" +#include + +namespace { + +std::string generate_pseudo_random_bytes(std::size_t seed, std::size_t size) +{ + std::mt19937_64 engine{seed}; + std::uniform_int_distribution dist{0, 255}; + std::vector bytes; + + bytes.reserve(size); + for (std::size_t i = 0; i < size; ++i) { + bytes.push_back(dist(engine)); + } + + return std::string{bytes.data(), bytes.size()}; +} + +} // namespace + +TEST(SecureUtilsTest, FormatSslFingerprintHexWithSeparators) +{ + std::string fingerprint = generate_pseudo_random_bytes(0, 32); + ASSERT_EQ(format_ssl_fingerprint(fingerprint, true, true), + "28:FD:0A:98:8A:0E:A1:6C:D7:E8:6C:A7:EE:58:41:71:" + "CA:B2:8E:49:25:94:90:25:26:05:8D:AF:63:ED:2E:30"); +} From 767f3d37ec71b13ed72ea07c9b0b3ff476af3307 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:33 +0200 Subject: [PATCH 041/113] test: Extract common test utilities to separate file --- src/test/global/TestUtils.cpp | 37 +++++++++++++++++++++ src/test/global/TestUtils.h | 30 +++++++++++++++++ src/test/unittests/net/SecureUtilsTests.cpp | 22 +++--------- 3 files changed, 71 insertions(+), 18 deletions(-) create mode 100644 src/test/global/TestUtils.cpp create mode 100644 src/test/global/TestUtils.h diff --git a/src/test/global/TestUtils.cpp b/src/test/global/TestUtils.cpp new file mode 100644 index 00000000..2aa7ca18 --- /dev/null +++ b/src/test/global/TestUtils.cpp @@ -0,0 +1,37 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . +*/ + +#include "TestUtils.h" +#include + +namespace barrier { + +std::string generate_pseudo_random_bytes(std::size_t seed, std::size_t size) +{ + std::mt19937_64 engine{seed}; + std::uniform_int_distribution dist{0, 255}; + std::vector bytes; + + bytes.reserve(size); + for (std::size_t i = 0; i < size; ++i) { + bytes.push_back(dist(engine)); + } + + return std::string{bytes.data(), bytes.size()}; +} + +} // namespace barrier diff --git a/src/test/global/TestUtils.h b/src/test/global/TestUtils.h new file mode 100644 index 00000000..b27e2c6e --- /dev/null +++ b/src/test/global/TestUtils.h @@ -0,0 +1,30 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . +*/ + +#ifndef BARRIER_TEST_GLOBAL_TEST_UTILS_H +#define BARRIER_TEST_GLOBAL_TEST_UTILS_H + +#include +#include + +namespace barrier { + +std::string generate_pseudo_random_bytes(std::size_t seed, std::size_t size); + +} // namespace barrier + +#endif // BARRIER_TEST_GLOBAL_TEST_UTILS_H diff --git a/src/test/unittests/net/SecureUtilsTests.cpp b/src/test/unittests/net/SecureUtilsTests.cpp index a77f158f..eb5ae498 100644 --- a/src/test/unittests/net/SecureUtilsTests.cpp +++ b/src/test/unittests/net/SecureUtilsTests.cpp @@ -18,25 +18,9 @@ #include "net/SecureUtils.h" #include "test/global/gtest.h" -#include +#include "test/global/TestUtils.h" -namespace { - -std::string generate_pseudo_random_bytes(std::size_t seed, std::size_t size) -{ - std::mt19937_64 engine{seed}; - std::uniform_int_distribution dist{0, 255}; - std::vector bytes; - - bytes.reserve(size); - for (std::size_t i = 0; i < size; ++i) { - bytes.push_back(dist(engine)); - } - - return std::string{bytes.data(), bytes.size()}; -} - -} // namespace +namespace barrier { TEST(SecureUtilsTest, FormatSslFingerprintHexWithSeparators) { @@ -45,3 +29,5 @@ TEST(SecureUtilsTest, FormatSslFingerprintHexWithSeparators) "28:FD:0A:98:8A:0E:A1:6C:D7:E8:6C:A7:EE:58:41:71:" "CA:B2:8E:49:25:94:90:25:26:05:8D:AF:63:ED:2E:30"); } + +} // namespace barrier From a9b30951ce6762353e28e9068af5364778f1fcb2 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:34 +0200 Subject: [PATCH 042/113] lib: Add utility function to convert from hex to binary --- src/lib/base/String.cpp | 56 +++++++++++++++++++++++++ src/lib/base/String.h | 3 ++ src/test/unittests/base/StringTests.cpp | 14 +++++++ 3 files changed, 73 insertions(+) diff --git a/src/lib/base/String.cpp b/src/lib/base/String.cpp index dcf7318a..416b1ec9 100644 --- a/src/lib/base/String.cpp +++ b/src/lib/base/String.cpp @@ -35,6 +35,42 @@ namespace barrier { namespace string { +namespace { + +// returns negative in case of non-matching character +int hex_to_number(char ch) +{ + switch (ch) { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + + case 'a': return 10; + case 'b': return 11; + case 'c': return 12; + case 'd': return 13; + case 'e': return 14; + case 'f': return 15; + + case 'A': return 10; + case 'B': return 11; + case 'C': return 12; + case 'D': return 13; + case 'E': return 14; + case 'F': return 15; + } + return -1; +} + +} // namespace + std::string format(const char* fmt, ...) { @@ -196,6 +232,26 @@ std::string to_hex(const std::string& subject, int width, const char fill) return ss.str(); } +std::vector from_hex(const std::string& data) +{ + if ((data.size() % 2) != 0) { + return {}; + } + + std::vector result; + result.reserve(data.size() / 2); + + for (std::size_t i = 0; i < data.size(); i += 2) { + auto high = hex_to_number(data[i]); + auto low = hex_to_number(data[i + 1]); + if (high < 0 || low < 0) { + return {}; + } + result.push_back(high * 16 + low); + } + return result; +} + void uppercase(std::string& subject) { diff --git a/src/lib/base/String.h b/src/lib/base/String.h index a543cf86..4a2e43bf 100644 --- a/src/lib/base/String.h +++ b/src/lib/base/String.h @@ -77,6 +77,9 @@ Convert each character in \c subject into hexdecimal form with \c width */ std::string to_hex(const std::string& subject, int width, const char fill = '0'); +/// Convert binary data from hexadecimal +std::vector from_hex(const std::string& data); + //! Convert to all uppercase /*! Convert each character in \c subject to uppercase diff --git a/src/test/unittests/base/StringTests.cpp b/src/test/unittests/base/StringTests.cpp index fd771f42..c9c4732b 100644 --- a/src/test/unittests/base/StringTests.cpp +++ b/src/test/unittests/base/StringTests.cpp @@ -62,6 +62,20 @@ TEST(StringTests, toHex_plaintext_hexString) EXPECT_EQ("666f6f626172", string::to_hex(subject, width)); } +TEST(StringTests, fromhex_plaintext_string) +{ + auto result = string::from_hex("666f6f626172"); + std::string expected = "foobar"; + EXPECT_EQ(result, std::vector(expected.begin(), expected.end())); +} + +TEST(StringTests, fromhex_binary_string) +{ + auto result = string::from_hex("01020304050600fff9"); + auto expected = std::vector{1, 2, 3, 4, 5, 6, 0, 0xff, 0xf9}; + EXPECT_EQ(result, expected); +} + TEST(StringTests, uppercase_lowercaseInput_uppercaseOutput) { String subject = "12foo3BaR"; From b793675ef8cbf7f69fe8ba7cbdf3689e7f60c657 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:35 +0200 Subject: [PATCH 043/113] lib/net: Put secure utils into barrier namespace --- src/lib/net/SecureSocket.cpp | 2 +- src/lib/net/SecureUtils.cpp | 4 ++++ src/lib/net/SecureUtils.h | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 3d5e2be0..7186f249 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -675,7 +675,7 @@ SecureSocket::verifyCertFingerprint() // format fingerprint into hexdecimal format with colon separator std::string fingerprint(reinterpret_cast(tempFingerprint), tempFingerprintLen); - fingerprint = format_ssl_fingerprint(fingerprint); + fingerprint = barrier::format_ssl_fingerprint(fingerprint); LOG((CLOG_NOTE "server fingerprint: %s", fingerprint.c_str())); std::string trustedServersFilename; diff --git a/src/lib/net/SecureUtils.cpp b/src/lib/net/SecureUtils.cpp index 7c4a52da..d45d694f 100644 --- a/src/lib/net/SecureUtils.cpp +++ b/src/lib/net/SecureUtils.cpp @@ -18,6 +18,8 @@ #include "SecureUtils.h" #include "base/String.h" +namespace barrier { + std::string format_ssl_fingerprint(const std::string& fingerprint, bool hex, bool separator) { std::string result = fingerprint; @@ -38,3 +40,5 @@ std::string format_ssl_fingerprint(const std::string& fingerprint, bool hex, boo } return result; } + +} // namespace barrier diff --git a/src/lib/net/SecureUtils.h b/src/lib/net/SecureUtils.h index 7c94fe92..7dd680ed 100644 --- a/src/lib/net/SecureUtils.h +++ b/src/lib/net/SecureUtils.h @@ -20,7 +20,11 @@ #include +namespace barrier { + std::string format_ssl_fingerprint(const std::string& fingerprint, bool hex = true, bool separator = true); +} // namespace barrier + #endif // BARRIER_LIB_NET_SECUREUTILS_H From ef08470286fc95be69a8f6307797fc7502064235 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:36 +0200 Subject: [PATCH 044/113] src/lib: Use standard std::vsnprintf() instead of hacking our own --- CMakeLists.txt | 1 - res/config.h.in | 3 -- src/lib/arch/IArchString.h | 10 ---- src/lib/arch/unix/ArchStringUnix.cpp | 1 - src/lib/arch/vsnprintf.h | 67 ------------------------ src/lib/arch/win32/ArchStringWindows.cpp | 5 -- src/lib/base/Log.cpp | 2 +- src/lib/base/String.cpp | 2 +- 8 files changed, 2 insertions(+), 89 deletions(-) delete mode 100644 src/lib/arch/vsnprintf.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f4d7edac..1588ad7a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,7 +91,6 @@ if (UNIX) check_function_exists (poll HAVE_POLL) check_function_exists (sigwait HAVE_POSIX_SIGWAIT) check_function_exists (strftime HAVE_STRFTIME) - check_function_exists (vsnprintf HAVE_VSNPRINTF) check_function_exists (inet_aton HAVE_INET_ATON) # For some reason, the check_function_exists macro doesn't detect diff --git a/res/config.h.in b/res/config.h.in index a2216875..53d3a3ec 100644 --- a/res/config.h.in +++ b/res/config.h.in @@ -94,9 +94,6 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_UNISTD_H ${HAVE_UNISTD_H} -/* Define to 1 if you have the `vsnprintf` function. */ -#cmakedefine HAVE_VSNPRINTF ${HAVE_VSNPRINTF} - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_WCHAR_H ${HAVE_WCHAR_H} diff --git a/src/lib/arch/IArchString.h b/src/lib/arch/IArchString.h index ad16fbea..f1803d8d 100644 --- a/src/lib/arch/IArchString.h +++ b/src/lib/arch/IArchString.h @@ -46,16 +46,6 @@ public: //! @name manipulators //@{ - //! printf() to limited size buffer with va_list - /*! - This method is equivalent to vsprintf() except it will not write - more than \c n bytes to the buffer, returning -1 if the output - was truncated and the number of bytes written not including the - trailing NUL otherwise. - */ - virtual int vsnprintf(char* str, - int size, const char* fmt, va_list ap); - //! Convert multibyte string to wide character string virtual int convStringMBToWC(wchar_t*, const char*, UInt32 n, bool* errors); diff --git a/src/lib/arch/unix/ArchStringUnix.cpp b/src/lib/arch/unix/ArchStringUnix.cpp index cddb8bd8..dbb91c1e 100644 --- a/src/lib/arch/unix/ArchStringUnix.cpp +++ b/src/lib/arch/unix/ArchStringUnix.cpp @@ -25,7 +25,6 @@ // #include "arch/multibyte.h" -#include "arch/vsnprintf.h" ArchStringUnix::ArchStringUnix() { diff --git a/src/lib/arch/vsnprintf.h b/src/lib/arch/vsnprintf.h deleted file mode 100644 index 5422f270..00000000 --- a/src/lib/arch/vsnprintf.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * barrier -- mouse and keyboard sharing utility - * Copyright (C) 2012-2016 Symless Ltd. - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file LICENSE that should have accompanied this file. - * - * This package 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 . - */ - -#include "arch/IArchString.h" - -#if HAVE_VSNPRINTF - -#if !defined(ARCH_VSNPRINTF) -# define ARCH_VSNPRINTF vsnprintf -#endif - -int -IArchString::vsnprintf(char* str, int size, const char* fmt, va_list ap) -{ - int n = ::ARCH_VSNPRINTF(str, size, fmt, ap); - if (n > size) { - n = -1; - } - return n; -} - -#elif SYSAPI_UNIX // !HAVE_VSNPRINTF - -#include - -int -IArchString::vsnprintf(char* str, int size, const char* fmt, va_list ap) -{ - static FILE* bitbucket = fopen("/dev/null", "w"); - if (bitbucket == NULL) { - // uh oh - if (size > 0) { - str[0] = '\0'; - } - return 0; - } - else { - // count the characters using the bitbucket - int n = vfprintf(bitbucket, fmt, ap); - if (n + 1 <= size) { - // it'll fit so print it into str - vsprintf(str, fmt, ap); - } - return n; - } -} - -#else // !HAVE_VSNPRINTF && !SYSAPI_UNIX - -#error vsnprintf not implemented - -#endif // !HAVE_VSNPRINTF diff --git a/src/lib/arch/win32/ArchStringWindows.cpp b/src/lib/arch/win32/ArchStringWindows.cpp index c570d1be..00336590 100644 --- a/src/lib/arch/win32/ArchStringWindows.cpp +++ b/src/lib/arch/win32/ArchStringWindows.cpp @@ -26,11 +26,6 @@ // ArchStringWindows // -#include "arch/multibyte.h" -#define HAVE_VSNPRINTF 1 -#define ARCH_VSNPRINTF _vsnprintf -#include "arch/vsnprintf.h" - ArchStringWindows::ArchStringWindows() { } diff --git a/src/lib/base/Log.cpp b/src/lib/base/Log.cpp index 66a5364b..8f52a805 100644 --- a/src/lib/base/Log.cpp +++ b/src/lib/base/Log.cpp @@ -145,7 +145,7 @@ Log::print(const char* file, int line, const char* fmt, ...) // try printing into the buffer va_list args; va_start(args, fmt); - int n = ARCH->vsnprintf(buffer, len - sPad, fmt, args); + int n = std::vsnprintf(buffer, len - sPad, fmt, args); va_end(args); // if the buffer wasn't big enough then make it bigger and try again diff --git a/src/lib/base/String.cpp b/src/lib/base/String.cpp index 416b1ec9..19ee8f62 100644 --- a/src/lib/base/String.cpp +++ b/src/lib/base/String.cpp @@ -171,7 +171,7 @@ sprintf(const char* fmt, ...) // try printing into the buffer va_list args; va_start(args, fmt); - int n = ARCH->vsnprintf(buffer, len, fmt, args); + int n = std::vsnprintf(buffer, len, fmt, args); va_end(args); // if the buffer wasn't big enough then make it bigger and try again From cd7e731cb730e912f512ea8b5821aa7b10f90b52 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:37 +0200 Subject: [PATCH 045/113] lib: Switch to std::vector for fingerprint data --- src/lib/base/String.cpp | 6 +++--- src/lib/base/String.h | 2 +- src/lib/net/SecureSocket.cpp | 6 ++++-- src/lib/net/SecureUtils.cpp | 8 ++------ src/lib/net/SecureUtils.h | 5 +++-- src/test/global/TestUtils.cpp | 6 +++--- src/test/global/TestUtils.h | 4 ++-- src/test/unittests/base/StringTests.cpp | 2 +- src/test/unittests/net/SecureUtilsTests.cpp | 4 ++-- 9 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/lib/base/String.cpp b/src/lib/base/String.cpp index 19ee8f62..413ad449 100644 --- a/src/lib/base/String.cpp +++ b/src/lib/base/String.cpp @@ -221,12 +221,12 @@ removeFileExt(std::string filename) return filename.substr(0, dot); } -std::string to_hex(const std::string& subject, int width, const char fill) +std::string to_hex(const std::vector& subject, int width, const char fill) { std::stringstream ss; ss << std::hex; - for (unsigned int i = 0; i < subject.length(); i++) { - ss << std::setw(width) << std::setfill(fill) << (int)(unsigned char)subject[i]; + for (unsigned int i = 0; i < subject.size(); i++) { + ss << std::setw(width) << std::setfill(fill) << static_cast(subject[i]); } return ss.str(); diff --git a/src/lib/base/String.h b/src/lib/base/String.h index 4a2e43bf..9c5a53ba 100644 --- a/src/lib/base/String.h +++ b/src/lib/base/String.h @@ -75,7 +75,7 @@ std::string removeFileExt(std::string filename); /*! Convert each character in \c subject into hexdecimal form with \c width */ -std::string to_hex(const std::string& subject, int width, const char fill = '0'); +std::string to_hex(const std::vector& subject, int width, const char fill = '0'); /// Convert binary data from hexadecimal std::vector from_hex(const std::string& data); diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 7186f249..39f2a1fd 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -674,8 +674,10 @@ SecureSocket::verifyCertFingerprint() } // format fingerprint into hexdecimal format with colon separator - std::string fingerprint(reinterpret_cast(tempFingerprint), tempFingerprintLen); - fingerprint = barrier::format_ssl_fingerprint(fingerprint); + std::vector fingerprint_raw; + fingerprint_raw.assign(reinterpret_cast(tempFingerprint), + reinterpret_cast(tempFingerprint) + tempFingerprintLen); + auto fingerprint = barrier::format_ssl_fingerprint(fingerprint_raw); LOG((CLOG_NOTE "server fingerprint: %s", fingerprint.c_str())); std::string trustedServersFilename; diff --git a/src/lib/net/SecureUtils.cpp b/src/lib/net/SecureUtils.cpp index d45d694f..000c56ed 100644 --- a/src/lib/net/SecureUtils.cpp +++ b/src/lib/net/SecureUtils.cpp @@ -20,13 +20,9 @@ namespace barrier { -std::string format_ssl_fingerprint(const std::string& fingerprint, bool hex, bool separator) +std::string format_ssl_fingerprint(const std::vector& fingerprint, bool separator) { - std::string result = fingerprint; - if (hex) { - // to hexadecimal - result = barrier::string::to_hex(result, 2); - } + std::string result = barrier::string::to_hex(fingerprint, 2); // all uppercase barrier::string::uppercase(result); diff --git a/src/lib/net/SecureUtils.h b/src/lib/net/SecureUtils.h index 7dd680ed..50e944e1 100644 --- a/src/lib/net/SecureUtils.h +++ b/src/lib/net/SecureUtils.h @@ -19,11 +19,12 @@ #define BARRIER_LIB_NET_SECUREUTILS_H #include +#include namespace barrier { -std::string format_ssl_fingerprint(const std::string& fingerprint, - bool hex = true, bool separator = true); +std::string format_ssl_fingerprint(const std::vector& fingerprint, + bool separator = true); } // namespace barrier diff --git a/src/test/global/TestUtils.cpp b/src/test/global/TestUtils.cpp index 2aa7ca18..6a3193bf 100644 --- a/src/test/global/TestUtils.cpp +++ b/src/test/global/TestUtils.cpp @@ -20,18 +20,18 @@ namespace barrier { -std::string generate_pseudo_random_bytes(std::size_t seed, std::size_t size) +std::vector generate_pseudo_random_bytes(std::size_t seed, std::size_t size) { std::mt19937_64 engine{seed}; std::uniform_int_distribution dist{0, 255}; - std::vector bytes; + std::vector bytes; bytes.reserve(size); for (std::size_t i = 0; i < size; ++i) { bytes.push_back(dist(engine)); } - return std::string{bytes.data(), bytes.size()}; + return bytes; } } // namespace barrier diff --git a/src/test/global/TestUtils.h b/src/test/global/TestUtils.h index b27e2c6e..31050ece 100644 --- a/src/test/global/TestUtils.h +++ b/src/test/global/TestUtils.h @@ -19,11 +19,11 @@ #define BARRIER_TEST_GLOBAL_TEST_UTILS_H #include -#include +#include namespace barrier { -std::string generate_pseudo_random_bytes(std::size_t seed, std::size_t size); +std::vector generate_pseudo_random_bytes(std::size_t seed, std::size_t size); } // namespace barrier diff --git a/src/test/unittests/base/StringTests.cpp b/src/test/unittests/base/StringTests.cpp index c9c4732b..ad5d5157 100644 --- a/src/test/unittests/base/StringTests.cpp +++ b/src/test/unittests/base/StringTests.cpp @@ -56,7 +56,7 @@ TEST(StringTests, sprintf_formatWithArgument_formatedString) TEST(StringTests, toHex_plaintext_hexString) { - String subject = "foobar"; + std::vector subject{'f', 'o', 'o', 'b', 'a', 'r'}; int width = 2; EXPECT_EQ("666f6f626172", string::to_hex(subject, width)); diff --git a/src/test/unittests/net/SecureUtilsTests.cpp b/src/test/unittests/net/SecureUtilsTests.cpp index eb5ae498..c2394bf9 100644 --- a/src/test/unittests/net/SecureUtilsTests.cpp +++ b/src/test/unittests/net/SecureUtilsTests.cpp @@ -24,8 +24,8 @@ namespace barrier { TEST(SecureUtilsTest, FormatSslFingerprintHexWithSeparators) { - std::string fingerprint = generate_pseudo_random_bytes(0, 32); - ASSERT_EQ(format_ssl_fingerprint(fingerprint, true, true), + auto fingerprint = generate_pseudo_random_bytes(0, 32); + ASSERT_EQ(format_ssl_fingerprint(fingerprint, true), "28:FD:0A:98:8A:0E:A1:6C:D7:E8:6C:A7:EE:58:41:71:" "CA:B2:8E:49:25:94:90:25:26:05:8D:AF:63:ED:2E:30"); } From 85486927b342cd7eceb5d1fd8315a95d5f09f9fd Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:38 +0200 Subject: [PATCH 046/113] lib/base: Implement pattern to execute something at function exit --- src/lib/base/finally.h | 61 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/lib/base/finally.h diff --git a/src/lib/base/finally.h b/src/lib/base/finally.h new file mode 100644 index 00000000..f3be617c --- /dev/null +++ b/src/lib/base/finally.h @@ -0,0 +1,61 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . +*/ + +#ifndef BARRIER_LIB_BASE_FINALLY_H +#define BARRIER_LIB_BASE_FINALLY_H + +#include + +namespace barrier { + +// this implements a common pattern of executing an action at the end of function + +template +class final_action { +public: + final_action() noexcept {} + final_action(Callable callable) noexcept : callable_{callable} {} + + ~final_action() noexcept + { + if (!invoked_) { + callable_(); + } + } + + final_action(final_action&& other) noexcept : + callable_{std::move(other.callable_)} + { + std::swap(invoked_, other.invoked_); + } + + final_action(const final_action&) = delete; + final_action& operator=(const final_action&) = delete; +private: + bool invoked_ = false; + Callable callable_; +}; + +template +inline final_action finally(Callable&& callable) noexcept +{ + return final_action(std::forward(callable)); +} + +} // namespace barrier + +#endif // BARRIER_LIB_BASE_FINALLY_H From 089b8e474978d1e8df9b0a0fc9e172a862409401 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:39 +0200 Subject: [PATCH 047/113] lib/net: Extract SSL fingerprint generation to reusable function --- src/lib/net/SecureSocket.cpp | 19 ++++++------------ src/lib/net/SecureUtils.cpp | 39 ++++++++++++++++++++++++++++++++++++ src/lib/net/SecureUtils.h | 9 +++++++++ 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 39f2a1fd..286394c4 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -661,22 +661,15 @@ bool SecureSocket::verifyCertFingerprint() { // calculate received certificate fingerprint - X509 *cert = cert = SSL_get_peer_certificate(m_ssl->m_ssl); - EVP_MD* tempDigest; - unsigned char tempFingerprint[EVP_MAX_MD_SIZE]; - unsigned int tempFingerprintLen; - tempDigest = (EVP_MD*)EVP_sha1(); - int digestResult = X509_digest(cert, tempDigest, tempFingerprint, &tempFingerprintLen); - - if (digestResult <= 0) { - LOG((CLOG_ERR "failed to calculate fingerprint, digest result: %d", digestResult)); + std::vector fingerprint_raw; + try { + fingerprint_raw = barrier::get_ssl_cert_fingerprint(SSL_get_peer_certificate(m_ssl->m_ssl), + barrier::FingerprintType::SHA1); + } catch (const std::exception& e) { + LOG((CLOG_ERR "%s", e.what())); return false; } - // format fingerprint into hexdecimal format with colon separator - std::vector fingerprint_raw; - fingerprint_raw.assign(reinterpret_cast(tempFingerprint), - reinterpret_cast(tempFingerprint) + tempFingerprintLen); auto fingerprint = barrier::format_ssl_fingerprint(fingerprint_raw); LOG((CLOG_NOTE "server fingerprint: %s", fingerprint.c_str())); diff --git a/src/lib/net/SecureUtils.cpp b/src/lib/net/SecureUtils.cpp index 000c56ed..c9222432 100644 --- a/src/lib/net/SecureUtils.cpp +++ b/src/lib/net/SecureUtils.cpp @@ -18,8 +18,26 @@ #include "SecureUtils.h" #include "base/String.h" +#include +#include +#include +#include + namespace barrier { +namespace { + +const EVP_MD* get_digest_for_type(FingerprintType type) +{ + switch (type) { + case FingerprintType::SHA1: return EVP_sha1(); + case FingerprintType::SHA256: return EVP_sha256(); + } + throw std::runtime_error("Unknown fingerprint type " + std::to_string(static_cast(type))); +} + +} // namespace + std::string format_ssl_fingerprint(const std::vector& fingerprint, bool separator) { std::string result = barrier::string::to_hex(fingerprint, 2); @@ -37,4 +55,25 @@ std::string format_ssl_fingerprint(const std::vector& fingerprint, bool return result; } +std::vector get_ssl_cert_fingerprint(X509* cert, FingerprintType type) +{ + if (!cert) { + throw std::runtime_error("certificate is null"); + } + + unsigned char digest[EVP_MAX_MD_SIZE]; + unsigned int digest_length = 0; + int result = X509_digest(cert, get_digest_for_type(type), digest, &digest_length); + + if (result <= 0) { + throw std::runtime_error("failed to calculate fingerprint, digest result: " + + std::to_string(result)); + } + + std::vector digest_vec; + digest_vec.assign(reinterpret_cast(digest), + reinterpret_cast(digest) + digest_length); + return digest_vec; +} + } // namespace barrier diff --git a/src/lib/net/SecureUtils.h b/src/lib/net/SecureUtils.h index 50e944e1..a35c1db7 100644 --- a/src/lib/net/SecureUtils.h +++ b/src/lib/net/SecureUtils.h @@ -18,14 +18,23 @@ #ifndef BARRIER_LIB_NET_SECUREUTILS_H #define BARRIER_LIB_NET_SECUREUTILS_H +#include +#include #include #include namespace barrier { +enum FingerprintType { + SHA1, // deprecated + SHA256, +}; + std::string format_ssl_fingerprint(const std::vector& fingerprint, bool separator = true); +std::vector get_ssl_cert_fingerprint(X509* cert, FingerprintType type); + } // namespace barrier #endif // BARRIER_LIB_NET_SECUREUTILS_H From cf732aba37422898c43e5b1ab50c0d1969390320 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:48 +0200 Subject: [PATCH 048/113] lib/io: Add a replacement for fopen() which works on Windows fopen() does not correctly handle non-ASCII paths on Windows. --- src/lib/io/fstream.cpp | 12 ++++++++++++ src/lib/io/fstream.h | 3 +++ 2 files changed, 15 insertions(+) diff --git a/src/lib/io/fstream.cpp b/src/lib/io/fstream.cpp index 4aef9073..ea91859d 100644 --- a/src/lib/io/fstream.cpp +++ b/src/lib/io/fstream.cpp @@ -54,4 +54,16 @@ void open_utf8_path(std::fstream& stream, const std::string& path, std::ios_base open_utf8_path_impl(stream, path, mode); } +std::FILE* fopen_utf8_path(const std::string& path, const std::string& mode) +{ +#if SYSAPI_WIN32 + auto wchar_path = utf8_to_win_char(path); + auto wchar_mode = utf8_to_win_char(mode); + return _wfopen(reinterpret_cast(wchar_path.data()), + reinterpret_cast(wchar_mode.data())); +#else + return std::fopen(path.c_str(), mode.c_str()); +#endif +} + } // namespace barrier diff --git a/src/lib/io/fstream.h b/src/lib/io/fstream.h index 26288373..2b327f18 100644 --- a/src/lib/io/fstream.h +++ b/src/lib/io/fstream.h @@ -18,6 +18,7 @@ #ifndef BARRIER_LIB_IO_FSTREAM_H #define BARRIER_LIB_IO_FSTREAM_H +#include #include #include @@ -30,6 +31,8 @@ void open_utf8_path(std::ofstream& stream, const std::string& path, void open_utf8_path(std::fstream& stream, const std::string& path, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out); +std::FILE* fopen_utf8_path(const std::string& path, const std::string& mode); + } // namespace barrier #endif From dbf56a937544c341bbe0cec5160c8d45863c539a Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:40 +0200 Subject: [PATCH 049/113] gui: Use openssl library instead of CLI tool to generate fingerprints --- src/gui/CMakeLists.txt | 2 +- src/gui/src/SslCertificate.cpp | 35 ++++++++-------------------------- src/lib/net/SecureUtils.cpp | 21 ++++++++++++++++++++ src/lib/net/SecureUtils.h | 3 +++ 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 2875adf4..49557352 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -131,7 +131,7 @@ add_executable (barrier WIN32 include_directories (./src) -target_link_libraries (barrier Qt5::Core Qt5::Widgets Qt5::Network ${OPENSSL_LIBS}) +target_link_libraries(barrier net base io Qt5::Core Qt5::Widgets Qt5::Network ${OPENSSL_LIBS}) target_compile_definitions (barrier PRIVATE -DBARRIER_VERSION_STAGE="${BARRIER_VERSION_STAGE}") target_compile_definitions (barrier PRIVATE -DBARRIER_REVISION="${BARRIER_REVISION}") diff --git a/src/gui/src/SslCertificate.cpp b/src/gui/src/SslCertificate.cpp index 9dc93ce8..99af4d44 100644 --- a/src/gui/src/SslCertificate.cpp +++ b/src/gui/src/SslCertificate.cpp @@ -18,6 +18,7 @@ #include "SslCertificate.h" #include "Fingerprint.h" #include "common/DataDirectories.h" +#include "net/SecureUtils.h" #include #include @@ -149,34 +150,14 @@ void SslCertificate::generateCertificate() void SslCertificate::generateFingerprint(const QString& certificateFilename) { - QStringList arguments; - arguments.append("x509"); - arguments.append("-fingerprint"); - arguments.append("-sha1"); - arguments.append("-noout"); - arguments.append("-in"); - arguments.append(certificateFilename); - - auto ret = runTool(arguments); - bool success = ret.first; - std::string output = ret.second; - - if (!success) { - return; - } - - // find the fingerprint from the tool output - auto i = output.find_first_of('='); - if (i != std::string::npos) { - i++; - auto fingerprint = output.substr( - i, output.size() - i); - - Fingerprint::local().trust(QString::fromStdString(fingerprint), false); + try { + auto fingerprint = barrier::get_pem_file_cert_fingerprint(certificateFilename.toStdString(), + barrier::FingerprintType::SHA1); + Fingerprint::local().trust(QString::fromStdString( + barrier::format_ssl_fingerprint(fingerprint)), false); emit info(tr("SSL fingerprint generated.")); - } - else { - emit error(tr("Failed to find SSL fingerprint.")); + } catch (const std::exception& e) { + emit error(tr("Failed to find SSL fingerprint.") + e.what()); } } diff --git a/src/lib/net/SecureUtils.cpp b/src/lib/net/SecureUtils.cpp index c9222432..97c9cf9a 100644 --- a/src/lib/net/SecureUtils.cpp +++ b/src/lib/net/SecureUtils.cpp @@ -17,10 +17,13 @@ #include "SecureUtils.h" #include "base/String.h" +#include "base/finally.h" +#include "io/fstream.h" #include #include #include +#include #include namespace barrier { @@ -76,4 +79,22 @@ std::vector get_ssl_cert_fingerprint(X509* cert, FingerprintType t return digest_vec; } +std::vector get_pem_file_cert_fingerprint(const std::string& path, + FingerprintType type) +{ + auto fp = fopen_utf8_path(path, "r"); + if (!fp) { + throw std::runtime_error("Could not open certificate path"); + } + auto file_close = finally([fp]() { std::fclose(fp); }); + + X509* cert = PEM_read_X509(fp, nullptr, nullptr, nullptr); + if (!cert) { + throw std::runtime_error("Certificate could not be parsed"); + } + auto cert_free = finally([cert]() { X509_free(cert); }); + + return get_ssl_cert_fingerprint(cert, type); +} + } // namespace barrier diff --git a/src/lib/net/SecureUtils.h b/src/lib/net/SecureUtils.h index a35c1db7..6a6343c8 100644 --- a/src/lib/net/SecureUtils.h +++ b/src/lib/net/SecureUtils.h @@ -35,6 +35,9 @@ std::string format_ssl_fingerprint(const std::vector& fingerprint, std::vector get_ssl_cert_fingerprint(X509* cert, FingerprintType type); +std::vector get_pem_file_cert_fingerprint(const std::string& path, + FingerprintType type); + } // namespace barrier #endif // BARRIER_LIB_NET_SECUREUTILS_H From aa3afa9062f71253c80e34e00d06860939c9b432 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:41 +0200 Subject: [PATCH 050/113] Use openssl library instead of CLI to generate certificates --- doc/newsfragments/dont-use-openssl-cli.bugfix | 1 + res/openssl/barrier.conf | 65 -------------- src/gui/src/SslCertificate.cpp | 88 +------------------ src/lib/net/SecureUtils.cpp | 45 ++++++++++ src/lib/net/SecureUtils.h | 2 + 5 files changed, 52 insertions(+), 149 deletions(-) create mode 100644 doc/newsfragments/dont-use-openssl-cli.bugfix delete mode 100644 res/openssl/barrier.conf diff --git a/doc/newsfragments/dont-use-openssl-cli.bugfix b/doc/newsfragments/dont-use-openssl-cli.bugfix new file mode 100644 index 00000000..316d6abf --- /dev/null +++ b/doc/newsfragments/dont-use-openssl-cli.bugfix @@ -0,0 +1 @@ +Barrier no longer uses openssl CLI tool for any operations and hooks into the openssl library directly. diff --git a/res/openssl/barrier.conf b/res/openssl/barrier.conf deleted file mode 100644 index a29abfd5..00000000 --- a/res/openssl/barrier.conf +++ /dev/null @@ -1,65 +0,0 @@ -# -# Barrier OpenSSL configuration file. -# Used for generation of certificate requests. -# - -dir = . - -[ca] -default_ca = CA_default - -[CA_default] -serial = $dir/serial -database = $dir/certindex.txt -new_certs_dir = $dir/certs -certificate = $dir/cacert.pem -private_key = $dir/private/cakey.pem -default_days = 365 -default_md = md5 -preserve = no -email_in_dn = no -nameopt = default_ca -certopt = default_ca -policy = policy_match - -[policy_match] -countryName = match -stateOrProvinceName = match -organizationName = match -organizationalUnitName = optional -commonName = supplied -emailAddress = optional - -[req] -default_bits = 2048 # Size of keys -default_keyfile = key.pem # name of generated keys -default_md = md5 # message digest algorithm -string_mask = nombstr # permitted characters -distinguished_name = req_distinguished_name -req_extensions = v3_req - -[req_distinguished_name] -0.organizationName = Organization Name (company) -organizationalUnitName = Organizational Unit Name (department, division) -emailAddress = Email Address -emailAddress_max = 40 -localityName = Locality Name (city, district) -stateOrProvinceName = State or Province Name (full name) -countryName = Country Name (2 letter code) -countryName_min = 2 -countryName_max = 2 -commonName = Common Name (hostname, IP, or your name) -commonName_max = 64 -0.organizationName_default = My Company -localityName_default = My Town -stateOrProvinceName_default = State or Providence -countryName_default = US - -[v3_ca] -basicConstraints = CA:TRUE -subjectKeyIdentifier = hash -authorityKeyIdentifier = keyid:always,issuer:always - -[v3_req] -basicConstraints = CA:FALSE -subjectKeyIdentifier = hash diff --git a/src/gui/src/SslCertificate.cpp b/src/gui/src/SslCertificate.cpp index 99af4d44..ac70d01a 100644 --- a/src/gui/src/SslCertificate.cpp +++ b/src/gui/src/SslCertificate.cpp @@ -30,16 +30,8 @@ #include #include -static const char kCertificateLifetime[] = "365"; -static const char kCertificateSubjectInfo[] = "/CN=Barrier"; static const char kCertificateFilename[] = "Barrier.pem"; static const char kSslDir[] = "SSL"; -static const char kUnixOpenSslCommand[] = "openssl"; - -#if defined(Q_OS_WIN) -static const char kWinOpenSslBinary[] = "openssl.exe"; -static const char kConfigFile[] = "barrier.conf"; -#endif SslCertificate::SslCertificate(QObject *parent) : QObject(parent) @@ -50,93 +42,21 @@ SslCertificate::SslCertificate(QObject *parent) : } } -std::pair SslCertificate::runTool(const QStringList& args) -{ - QString program; -#if defined(Q_OS_WIN) - program = QCoreApplication::applicationDirPath(); - program.append("\\").append(kWinOpenSslBinary); -#else - program = kUnixOpenSslCommand; -#endif - - - QStringList environment; -#if defined(Q_OS_WIN) - environment << QString("OPENSSL_CONF=%1\\%2") - .arg(QCoreApplication::applicationDirPath()) - .arg(kConfigFile); -#endif - - QProcess process; - process.setEnvironment(environment); - process.start(program, args); - - bool success = process.waitForStarted(); - std::string output; - - QString standardError; - if (success && process.waitForFinished()) - { - output = process.readAllStandardOutput().trimmed().toStdString(); - standardError = process.readAllStandardError().trimmed(); - } - - int code = process.exitCode(); - if (!success || code != 0) - { - emit error( - QString("SSL tool failed: %1\n\nCode: %2\nError: %3") - .arg(program) - .arg(process.exitCode()) - .arg(standardError.isEmpty() ? "Unknown" : standardError)); - return {false, output}; - } - - return {true, output}; -} - void SslCertificate::generateCertificate() { auto filename = QString::fromStdString(getCertificatePath()); QFile file(filename); if (!file.exists() || !isCertificateValid(filename)) { - QStringList arguments; - - // self signed certificate - arguments.append("req"); - arguments.append("-x509"); - arguments.append("-nodes"); - - // valid duration - arguments.append("-days"); - arguments.append(kCertificateLifetime); - - // subject information - arguments.append("-subj"); - - QString subInfo(kCertificateSubjectInfo); - arguments.append(subInfo); - - // private key - arguments.append("-newkey"); - arguments.append("rsa:2048"); - QDir sslDir(QString::fromStdString(getCertificateDirectory())); if (!sslDir.exists()) { sslDir.mkpath("."); } - // key output filename - arguments.append("-keyout"); - arguments.append(filename); - - // certificate output filename - arguments.append("-out"); - arguments.append(filename); - - if (!runTool(arguments).first) { + try { + barrier::generate_pem_self_signed_cert(filename.toStdString()); + } catch (const std::exception& e) { + emit error(QString("SSL tool failed: %1").arg(e.what())); return; } diff --git a/src/lib/net/SecureUtils.cpp b/src/lib/net/SecureUtils.cpp index 97c9cf9a..4b081f66 100644 --- a/src/lib/net/SecureUtils.cpp +++ b/src/lib/net/SecureUtils.cpp @@ -20,6 +20,7 @@ #include "base/finally.h" #include "io/fstream.h" +#include #include #include #include @@ -97,4 +98,48 @@ std::vector get_pem_file_cert_fingerprint(const std::string& path, return get_ssl_cert_fingerprint(cert, type); } +void generate_pem_self_signed_cert(const std::string& path) +{ + auto expiration_days = 365; + + auto* private_key = EVP_PKEY_new(); + if (!private_key) { + throw std::runtime_error("Could not allocate private key for certificate"); + } + auto private_key_free = finally([private_key](){ EVP_PKEY_free(private_key); }); + + auto* rsa = RSA_generate_key(2048, RSA_F4, nullptr, nullptr); + if (!rsa) { + throw std::runtime_error("Failed to generate RSA key"); + } + EVP_PKEY_assign_RSA(private_key, rsa); + + auto* cert = X509_new(); + if (!cert) { + throw std::runtime_error("Could not allocate certificate"); + } + auto cert_free = finally([cert]() { X509_free(cert); }); + + ASN1_INTEGER_set(X509_get_serialNumber(cert), 1); + X509_gmtime_adj(X509_get_notBefore(cert), 0); + X509_gmtime_adj(X509_get_notAfter(cert), expiration_days * 24 * 3600); + X509_set_pubkey(cert, private_key); + + auto* name = X509_get_subject_name(cert); + X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, + reinterpret_cast("Barrier"), -1, -1, 0); + X509_set_issuer_name(cert, name); + + X509_sign(cert, private_key, EVP_sha256()); + + auto fp = fopen_utf8_path(path.c_str(), "r"); + if (!fp) { + throw std::runtime_error("Could not open certificate output path"); + } + auto file_close = finally([fp]() { std::fclose(fp); }); + + PEM_write_PrivateKey(fp, private_key, nullptr, nullptr, 0, nullptr, nullptr); + PEM_write_X509(fp, cert); +} + } // namespace barrier diff --git a/src/lib/net/SecureUtils.h b/src/lib/net/SecureUtils.h index 6a6343c8..df450136 100644 --- a/src/lib/net/SecureUtils.h +++ b/src/lib/net/SecureUtils.h @@ -38,6 +38,8 @@ std::vector get_ssl_cert_fingerprint(X509* cert, FingerprintType t std::vector get_pem_file_cert_fingerprint(const std::string& path, FingerprintType type); +void generate_pem_self_signed_cert(const std::string& path); + } // namespace barrier #endif // BARRIER_LIB_NET_SECUREUTILS_H From 8f88dc2585fcd03084c6296bbb5e73a540c94e23 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:42 +0200 Subject: [PATCH 051/113] lib/base: Support colons in from_hex() --- src/lib/base/String.cpp | 17 ++++++++++++----- src/test/unittests/base/StringTests.cpp | 14 ++++++++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/lib/base/String.cpp b/src/lib/base/String.cpp index 413ad449..adbb11db 100644 --- a/src/lib/base/String.cpp +++ b/src/lib/base/String.cpp @@ -234,20 +234,27 @@ std::string to_hex(const std::vector& subject, int width, const ch std::vector from_hex(const std::string& data) { - if ((data.size() % 2) != 0) { - return {}; - } - std::vector result; result.reserve(data.size() / 2); - for (std::size_t i = 0; i < data.size(); i += 2) { + std::size_t i = 0; + while (i < data.size()) { + if (data[i] == ':') { + i++; + continue; + } + + if (i + 2 > data.size()) { + return {}; // uneven character count follows, it's unclear how to interpret it + } + auto high = hex_to_number(data[i]); auto low = hex_to_number(data[i + 1]); if (high < 0 || low < 0) { return {}; } result.push_back(high * 16 + low); + i += 2; } return result; } diff --git a/src/test/unittests/base/StringTests.cpp b/src/test/unittests/base/StringTests.cpp index ad5d5157..cc8e4fc6 100644 --- a/src/test/unittests/base/StringTests.cpp +++ b/src/test/unittests/base/StringTests.cpp @@ -69,6 +69,13 @@ TEST(StringTests, fromhex_plaintext_string) EXPECT_EQ(result, std::vector(expected.begin(), expected.end())); } +TEST(StringTests, fromhex_plaintext_string_colons) +{ + auto result = string::from_hex("66:6f:6f:62:61:72"); + std::string expected = "foobar"; + EXPECT_EQ(result, std::vector(expected.begin(), expected.end())); +} + TEST(StringTests, fromhex_binary_string) { auto result = string::from_hex("01020304050600fff9"); @@ -76,6 +83,13 @@ TEST(StringTests, fromhex_binary_string) EXPECT_EQ(result, expected); } +TEST(StringTests, fromhex_invalid_string) +{ + EXPECT_TRUE(string::from_hex("66:6").empty()); + EXPECT_TRUE(string::from_hex("66:612").empty()); + EXPECT_TRUE(string::from_hex("66:WW").empty()); +} + TEST(StringTests, uppercase_lowercaseInput_uppercaseOutput) { String subject = "12foo3BaR"; From 3e71b468f6dfd7b01752b551bddee3d9a8bc58dd Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:43 +0200 Subject: [PATCH 052/113] lib: Remove useless empty constructors --- src/lib/common/DataDirectories.h | 3 --- src/lib/common/PathUtilities.h | 4 ---- src/lib/platform/ImmuneKeysReader.h | 4 ---- 3 files changed, 11 deletions(-) diff --git a/src/lib/common/DataDirectories.h b/src/lib/common/DataDirectories.h index 6b990c20..783ff138 100644 --- a/src/lib/common/DataDirectories.h +++ b/src/lib/common/DataDirectories.h @@ -32,9 +32,6 @@ public: static const std::string& systemconfig(const std::string& path); private: - // static class - DataDirectories() {} - static std::string _profile; static std::string _global; static std::string _systemconfig; diff --git a/src/lib/common/PathUtilities.h b/src/lib/common/PathUtilities.h index 70b85b4c..30313243 100644 --- a/src/lib/common/PathUtilities.h +++ b/src/lib/common/PathUtilities.h @@ -24,8 +24,4 @@ class PathUtilities public: static std::string basename(const std::string& path); static std::string concat(const std::string& left, const std::string& right); - -private: - // static class - PathUtilities() {} }; diff --git a/src/lib/platform/ImmuneKeysReader.h b/src/lib/platform/ImmuneKeysReader.h index b46cbbe8..536dd45f 100644 --- a/src/lib/platform/ImmuneKeysReader.h +++ b/src/lib/platform/ImmuneKeysReader.h @@ -27,8 +27,4 @@ class ImmuneKeysReader { public: static bool get_list(const char * const path, std::vector &keys, std::string &badLine); - -private: - // static class - explicit ImmuneKeysReader() {} }; From 9cac96b4afa4e5f14145f2444af7d65852ff6254 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:44 +0200 Subject: [PATCH 053/113] lib/net: Implement a reusable fingerprint database --- src/lib/net/FingerprintDatabase.cpp | 140 ++++++++++++++++++ src/lib/net/FingerprintDatabase.h | 61 ++++++++ src/lib/net/FingerprintType.h | 54 +++++++ src/lib/net/SecureUtils.h | 6 +- .../net/FingerprintDatabaseTests.cpp | 95 ++++++++++++ 5 files changed, 351 insertions(+), 5 deletions(-) create mode 100644 src/lib/net/FingerprintDatabase.cpp create mode 100644 src/lib/net/FingerprintDatabase.h create mode 100644 src/lib/net/FingerprintType.h create mode 100644 src/test/unittests/net/FingerprintDatabaseTests.cpp diff --git a/src/lib/net/FingerprintDatabase.cpp b/src/lib/net/FingerprintDatabase.cpp new file mode 100644 index 00000000..cdc3ad32 --- /dev/null +++ b/src/lib/net/FingerprintDatabase.cpp @@ -0,0 +1,140 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . +*/ + +#include "base/String.h" +#include "FingerprintDatabase.h" +#include "io/fstream.h" +#include +#include + +namespace barrier { + +bool FingerprintData::operator==(const FingerprintData& other) const +{ + return algorithm == other.algorithm && data == other.data; +} + +void FingerprintDatabase::read(const std::string& path) +{ + std::ifstream file; + open_utf8_path(file, path, std::ios_base::in); + read_stream(file); +} + +void FingerprintDatabase::write(const std::string& path) +{ + std::ofstream file; + open_utf8_path(file, path, std::ios_base::out); + write_stream(file); +} + +void FingerprintDatabase::read_stream(std::istream& stream) +{ + if (!stream.good()) { + return; + } + + std::string line; + while (std::getline(stream, line)) { + if (line.empty()) { + continue; + } + + auto fingerprint = parse_db_line(line); + if (!fingerprint.valid()) { + continue; + } + + fingerprints_.push_back(fingerprint); + } +} + +void FingerprintDatabase::write_stream(std::ostream& stream) +{ + if (!stream.good()) { + return; + } + + for (const auto& fingerprint : fingerprints_) { + stream << to_db_line(fingerprint) << "\n"; + } +} + +void FingerprintDatabase::clear() +{ + fingerprints_.clear(); +} + +void FingerprintDatabase::add_trusted(const FingerprintData& fingerprint) +{ + if (is_trusted(fingerprint)) { + return; + } + fingerprints_.push_back(fingerprint); +} + +bool FingerprintDatabase::is_trusted(const FingerprintData& fingerprint) +{ + auto found_it = std::find(fingerprints_.begin(), fingerprints_.end(), fingerprint); + return found_it != fingerprints_.end(); +} + +FingerprintData FingerprintDatabase::parse_db_line(const std::string& line) +{ + FingerprintData result; + + // legacy v1 certificate handling + if (std::count(line.begin(), line.end(), ':') == 19 && line.size() == 40 + 19) { + auto data = string::from_hex(line); + if (data.empty()) { + return result; + } + result.algorithm = fingerprint_type_to_string(FingerprintType::SHA1); + result.data = data; + return result; + } + + auto version_end_pos = line.find(':'); + if (version_end_pos == std::string::npos) { + return result; + } + if (line.substr(0, version_end_pos) != "v2") { + return result; + } + auto algo_start_pos = version_end_pos + 1; + auto algo_end_pos = line.find(':', algo_start_pos); + if (algo_end_pos == std::string::npos) { + return result; + } + auto algorithm = line.substr(algo_start_pos, algo_end_pos - algo_start_pos); + auto data = string::from_hex(line.substr(algo_end_pos + 1)); + + if (data.empty()) { + return result; + } + + result.algorithm = algorithm; + result.data = data; + return result; +} + +std::string FingerprintDatabase::to_db_line(const FingerprintData& fingerprint) +{ + return "v2:" + fingerprint.algorithm + ":" + string::to_hex(fingerprint.data, 2); +} + +} // namespace barrier diff --git a/src/lib/net/FingerprintDatabase.h b/src/lib/net/FingerprintDatabase.h new file mode 100644 index 00000000..36ab39ce --- /dev/null +++ b/src/lib/net/FingerprintDatabase.h @@ -0,0 +1,61 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . +*/ + +#ifndef BARRIER_LIB_NET_FINGERPRINT_DATABASE_H +#define BARRIER_LIB_NET_FINGERPRINT_DATABASE_H + +#include "FingerprintType.h" +#include +#include +#include + +namespace barrier { + +struct FingerprintData { + std::string algorithm; + std::vector data; + + bool valid() const { return !algorithm.empty(); } + + bool operator==(const FingerprintData& other) const; +}; + +class FingerprintDatabase { +public: + void read(const std::string& path); + void write(const std::string& path); + + void read_stream(std::istream& stream); + void write_stream(std::ostream& stream); + + void clear(); + void add_trusted(const FingerprintData& fingerprint); + bool is_trusted(const FingerprintData& fingerprint); + + const std::vector& fingerprints() const { return fingerprints_; } + + static FingerprintData parse_db_line(const std::string& line); + static std::string to_db_line(const FingerprintData& fingerprint); + +private: + + std::vector fingerprints_; +}; + +} // namespace barrier + +#endif // BARRIER_LIB_NET_FINGERPRINT_DATABASE_H diff --git a/src/lib/net/FingerprintType.h b/src/lib/net/FingerprintType.h new file mode 100644 index 00000000..4e58e9f6 --- /dev/null +++ b/src/lib/net/FingerprintType.h @@ -0,0 +1,54 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . +*/ + +#ifndef BARRIER_LIB_NET_FINGERPRINT_TYPE_H +#define BARRIER_LIB_NET_FINGERPRINT_TYPE_H + +#include + +namespace barrier { + +enum FingerprintType { + INVALID, + SHA1, // deprecated + SHA256, +}; + +inline const char* fingerprint_type_to_string(FingerprintType type) +{ + switch (type) { + case FingerprintType::INVALID: return "invalid"; + case FingerprintType::SHA1: return "sha1"; + case FingerprintType::SHA256: return "sha256"; + } + return "invalid"; +} + +inline FingerprintType fingerprint_type_from_string(const std::string& type) +{ + if (type == "sha1") { + return FingerprintType::SHA1; + } + if (type == "sha256") { + return FingerprintType::SHA256; + } + return FingerprintType::INVALID; +} + +} // namespace barrier + +#endif // BARRIER_LIB_NET_FINGERPRINT_TYPE_H diff --git a/src/lib/net/SecureUtils.h b/src/lib/net/SecureUtils.h index df450136..ace0d45a 100644 --- a/src/lib/net/SecureUtils.h +++ b/src/lib/net/SecureUtils.h @@ -18,6 +18,7 @@ #ifndef BARRIER_LIB_NET_SECUREUTILS_H #define BARRIER_LIB_NET_SECUREUTILS_H +#include "FingerprintType.h" #include #include #include @@ -25,11 +26,6 @@ namespace barrier { -enum FingerprintType { - SHA1, // deprecated - SHA256, -}; - std::string format_ssl_fingerprint(const std::vector& fingerprint, bool separator = true); diff --git a/src/test/unittests/net/FingerprintDatabaseTests.cpp b/src/test/unittests/net/FingerprintDatabaseTests.cpp new file mode 100644 index 00000000..61bed0ea --- /dev/null +++ b/src/test/unittests/net/FingerprintDatabaseTests.cpp @@ -0,0 +1,95 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . +*/ + +#include "net/FingerprintDatabase.h" +#include "test/global/gtest.h" + +namespace barrier { + +TEST(FingerprintDatabase, parse_db_line) +{ + ASSERT_FALSE(FingerprintDatabase::parse_db_line("").valid()); + ASSERT_FALSE(FingerprintDatabase::parse_db_line("abcd").valid()); + ASSERT_FALSE(FingerprintDatabase::parse_db_line("v1:algo:something").valid()); + ASSERT_FALSE(FingerprintDatabase::parse_db_line("v2:algo:something").valid()); + ASSERT_FALSE(FingerprintDatabase::parse_db_line("v2:algo:01020304abc").valid()); + ASSERT_FALSE(FingerprintDatabase::parse_db_line("v2:algo:01020304ZZ").valid()); + ASSERT_EQ(FingerprintDatabase::parse_db_line("v2:algo:01020304ab"), + (FingerprintData{"algo", {1, 2, 3, 4, 0xab}})); +} + +TEST(FingerprintDatabase, read) +{ + std::istringstream stream; + stream.str(R"( +v2:algo1:01020304ab +v2:algo2:03040506ab +AB:CD:EF:00:01:02:03:04:05:06:07:08:09:10:11:12:13:14:15:16 +)"); + FingerprintDatabase db; + db.read_stream(stream); + + std::vector expected = { + { "algo1", { 1, 2, 3, 4, 0xab } }, + { "algo2", { 3, 4, 5, 6, 0xab } }, + { "sha1", { 0xab, 0xcd, 0xef, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 } }, + }; + ASSERT_EQ(db.fingerprints(), expected); +} + +TEST(FingerprintDatabase, write) +{ + std::ostringstream stream; + + FingerprintDatabase db; + db.add_trusted({ "algo1", { 1, 2, 3, 4, 0xab } }); + db.add_trusted({ "algo2", { 3, 4, 5, 6, 0xab } }); + db.write_stream(stream); + + ASSERT_EQ(stream.str(), R"(v2:algo1:01020304ab +v2:algo2:03040506ab +)"); +} + +TEST(FingerprintDatabase, clear) +{ + FingerprintDatabase db; + db.add_trusted({ "algo1", { 1, 2, 3, 4, 0xab } }); + db.clear(); + ASSERT_TRUE(db.fingerprints().empty()); +} + +TEST(FingerprintDatabase, add_trusted_no_duplicates) +{ + FingerprintDatabase db; + db.add_trusted({ "algo1", { 1, 2, 3, 4, 0xab } }); + db.add_trusted({ "algo2", { 3, 4, 5, 6, 0xab } }); + db.add_trusted({ "algo1", { 1, 2, 3, 4, 0xab } }); + ASSERT_EQ(db.fingerprints().size(), 2); +} + +TEST(FingerprintDatabase, is_trusted) +{ + FingerprintDatabase db; + db.add_trusted({ "algo1", { 1, 2, 3, 4, 0xab } }); + ASSERT_TRUE(db.is_trusted({ "algo1", { 1, 2, 3, 4, 0xab } })); + ASSERT_FALSE(db.is_trusted({ "algo2", { 1, 2, 3, 4, 0xab } })); + ASSERT_FALSE(db.is_trusted({ "algo1", { 1, 2, 3, 4, 0xac } })); +} + +} // namespace barrier From be8ba0d13248fd6d51382f524b1992c380d21887 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:45 +0200 Subject: [PATCH 054/113] gui: Use new FingerprintDatabase to handle fingerprints --- src/gui/CMakeLists.txt | 2 - src/gui/src/Fingerprint.cpp | 147 ---------------------- src/gui/src/Fingerprint.h | 42 ------- src/gui/src/MainWindow.cpp | 50 ++++++-- src/gui/src/SslCertificate.cpp | 28 +++-- src/gui/src/SslCertificate.h | 4 +- src/lib/common/DataDirectories.h | 4 + src/lib/common/DataDirectories_static.cpp | 25 ++++ 8 files changed, 87 insertions(+), 215 deletions(-) delete mode 100644 src/gui/src/Fingerprint.cpp delete mode 100644 src/gui/src/Fingerprint.h diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 49557352..fb7678f2 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -29,7 +29,6 @@ set(GUI_SOURCE_FILES src/CommandProcess.cpp src/DataDownloader.cpp src/DisplayIsValid.cpp - src/Fingerprint.cpp src/HotkeyDialog.cpp src/IpcClient.cpp src/Ipc.cpp @@ -70,7 +69,6 @@ set(GUI_HEADER_FILES src/DataDownloader.h src/DisplayIsValid.h src/ElevateMode.h - src/Fingerprint.h src/HotkeyDialog.h src/IpcClient.h src/Ipc.h diff --git a/src/gui/src/Fingerprint.cpp b/src/gui/src/Fingerprint.cpp deleted file mode 100644 index cc1ce3bf..00000000 --- a/src/gui/src/Fingerprint.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - * barrier -- mouse and keyboard sharing utility - * Copyright (C) 2015-2016 Symless Ltd. - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file LICENSE that should have accompanied this file. - * - * This package 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 . - */ - -#include "Fingerprint.h" - -#include "common/DataDirectories.h" - -#include -#include - -static const char kDirName[] = "SSL/Fingerprints"; -static const char kLocalFilename[] = "Local.txt"; -static const char kTrustedServersFilename[] = "TrustedServers.txt"; -static const char kTrustedClientsFilename[] = "TrustedClients.txt"; - -Fingerprint::Fingerprint(const QString& filename) -{ - m_Filename = filename; -} - -void Fingerprint::trust(const QString& fingerprintText, bool append) -{ - Fingerprint::persistDirectory(); - - QIODevice::OpenMode openMode; - if (append) { - openMode = QIODevice::Append; - } - else { - openMode = QIODevice::WriteOnly; - } - - QFile file(filePath()); - if (file.open(openMode)) - { - QTextStream out(&file); - out << fingerprintText << "\n"; - file.close(); - } -} - -bool Fingerprint::fileExists() const -{ - QString dirName = Fingerprint::directoryPath(); - if (!QDir(dirName).exists()) { - return false; - } - - QFile file(filePath()); - return file.exists(); -} - -bool Fingerprint::isTrusted(const QString& fingerprintText) -{ - QStringList list = readList(); - for (QString trusted : list) { - if (trusted == fingerprintText) { - return true; - } - } - return false; -} - -QStringList Fingerprint::readList(const int readTo) -{ - QStringList list; - - QString dirName = Fingerprint::directoryPath(); - if (!QDir(dirName).exists()) { - return list; - } - - QFile file(filePath()); - - if (file.open(QIODevice::ReadOnly)) - { - QTextStream in(&file); - while (!in.atEnd()) - { - list.append(in.readLine()); - if (list.size() == readTo) { - break; - } - } - file.close(); - } - - return list; -} - -QString Fingerprint::readFirst() -{ - QStringList list = readList(1); - return list.at(0); -} - -QString Fingerprint::filePath() const -{ - QString dir = Fingerprint::directoryPath(); - return QString("%1/%2").arg(dir).arg(m_Filename); -} - -void Fingerprint::persistDirectory() -{ - QDir dir(Fingerprint::directoryPath()); - if (!dir.exists()) { - dir.mkpath("."); - } -} - -QString Fingerprint::directoryPath() -{ - auto profileDir = QString::fromStdString(DataDirectories::profile()); - - return QString("%1/%2") - .arg(profileDir) - .arg(kDirName); -} - -Fingerprint Fingerprint::local() -{ - return Fingerprint(kLocalFilename); -} - -Fingerprint Fingerprint::trustedServers() -{ - return Fingerprint(kTrustedServersFilename); -} - -Fingerprint Fingerprint::trustedClients() -{ - return Fingerprint(kTrustedClientsFilename); -} diff --git a/src/gui/src/Fingerprint.h b/src/gui/src/Fingerprint.h deleted file mode 100644 index 5a38d201..00000000 --- a/src/gui/src/Fingerprint.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * barrier -- mouse and keyboard sharing utility - * Copyright (C) 2015-2016 Symless Ltd. - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file LICENSE that should have accompanied this file. - * - * This package 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 . - */ - -#pragma once - -#include - -class Fingerprint -{ -public: - void trust(const QString& fingerprintText, bool append = true); - bool isTrusted(const QString& fingerprintText); - QStringList readList(const int readTo = -1); - QString readFirst(); - QString filePath() const; - bool fileExists() const; - - static Fingerprint local(); - static Fingerprint trustedServers(); - static Fingerprint trustedClients(); - static QString directoryPath(); - static void persistDirectory(); - -private: - Fingerprint(const QString& filename); - - QString m_Filename; -}; diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 9072b864..02499a12 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -20,7 +20,6 @@ #include "MainWindow.h" -#include "Fingerprint.h" #include "AboutDialog.h" #include "ServerConfigDialog.h" #include "SettingsDialog.h" @@ -31,7 +30,10 @@ #include "ProcessorArch.h" #include "SslCertificate.h" #include "ShutdownCh.h" +#include "base/String.h" #include "common/DataDirectories.h" +#include "net/FingerprintDatabase.h" +#include "net/SecureUtils.h" #include #include @@ -417,11 +419,21 @@ void MainWindow::checkFingerprint(const QString& line) return; } - QString fingerprint = fingerprintRegex.cap(1); - if (Fingerprint::trustedServers().isTrusted(fingerprint)) { + barrier::FingerprintData fingerprint = { + barrier::fingerprint_type_to_string(barrier::FingerprintType::SHA1), + barrier::string::from_hex(fingerprintRegex.cap(1).toStdString()) + }; + + auto db_path = DataDirectories::trusted_servers_ssl_fingerprints_path(); + + barrier::FingerprintDatabase db; + db.read(db_path); + if (db.is_trusted(fingerprint)) { return; } + auto formatted_fingerprint = barrier::format_ssl_fingerprint(fingerprint.data); + static bool messageBoxAlreadyShown = false; if (!messageBoxAlreadyShown) { @@ -440,12 +452,13 @@ void MainWindow::checkFingerprint(const QString& line) "To automatically trust this fingerprint for future " "connections, click Yes. To reject this fingerprint and " "disconnect from the server, click No.") - .arg(fingerprint), + .arg(QString::fromStdString(formatted_fingerprint)), QMessageBox::Yes | QMessageBox::No); if (fingerprintReply == QMessageBox::Yes) { // restart core process after trusting fingerprint. - Fingerprint::trustedServers().trust(fingerprint); + db.add_trusted(fingerprint); + db.write(db_path); startBarrier(); } @@ -965,12 +978,29 @@ void MainWindow::updateSSLFingerprint() }); m_pSslCertificate->generateCertificate(); } - if (m_AppConfig->getCryptoEnabled() && Fingerprint::local().fileExists()) { - m_pLabelLocalFingerprint->setText(Fingerprint::local().readFirst()); - m_pLabelLocalFingerprint->setTextInteractionFlags(Qt::TextSelectableByMouse); - } else { - m_pLabelLocalFingerprint->setText("Disabled"); + + m_pLabelLocalFingerprint->setText("Disabled"); + + if (!m_AppConfig->getCryptoEnabled()) { + return; } + + auto local_path = DataDirectories::local_ssl_fingerprints_path(); + if (!QFile::exists(QString::fromStdString(local_path))) { + return; + } + + barrier::FingerprintDatabase db; + db.read(local_path); + if (db.fingerprints().empty()) { + return; + } + + const auto& fingerprint = db.fingerprints().front(); + auto formatted_fingerprint = barrier::format_ssl_fingerprint(fingerprint.data); + + m_pLabelLocalFingerprint->setText(QString::fromStdString(formatted_fingerprint)); + m_pLabelLocalFingerprint->setTextInteractionFlags(Qt::TextSelectableByMouse); } void MainWindow::on_m_pGroupClient_toggled(bool on) diff --git a/src/gui/src/SslCertificate.cpp b/src/gui/src/SslCertificate.cpp index ac70d01a..4242df56 100644 --- a/src/gui/src/SslCertificate.cpp +++ b/src/gui/src/SslCertificate.cpp @@ -16,8 +16,8 @@ */ #include "SslCertificate.h" -#include "Fingerprint.h" #include "common/DataDirectories.h" +#include "net/FingerprintDatabase.h" #include "net/SecureUtils.h" #include @@ -44,17 +44,17 @@ SslCertificate::SslCertificate(QObject *parent) : void SslCertificate::generateCertificate() { - auto filename = QString::fromStdString(getCertificatePath()); + auto cert_path = getCertificatePath(); - QFile file(filename); - if (!file.exists() || !isCertificateValid(filename)) { + QFile file(QString::fromStdString(cert_path)); + if (!file.exists() || !isCertificateValid(cert_path)) { QDir sslDir(QString::fromStdString(getCertificateDirectory())); if (!sslDir.exists()) { sslDir.mkpath("."); } try { - barrier::generate_pem_self_signed_cert(filename.toStdString()); + barrier::generate_pem_self_signed_cert(cert_path); } catch (const std::exception& e) { emit error(QString("SSL tool failed: %1").arg(e.what())); return; @@ -63,18 +63,22 @@ void SslCertificate::generateCertificate() emit info(tr("SSL certificate generated.")); } - generateFingerprint(filename); + generateFingerprint(cert_path); emit generateFinished(); } -void SslCertificate::generateFingerprint(const QString& certificateFilename) +void SslCertificate::generateFingerprint(const std::string& cert_path) { try { - auto fingerprint = barrier::get_pem_file_cert_fingerprint(certificateFilename.toStdString(), + auto fingerprint = barrier::get_pem_file_cert_fingerprint(cert_path, barrier::FingerprintType::SHA1); - Fingerprint::local().trust(QString::fromStdString( - barrier::format_ssl_fingerprint(fingerprint)), false); + + auto local_path = DataDirectories::local_ssl_fingerprints_path(); + barrier::FingerprintDatabase db; + db.add_trusted(barrier::FingerprintData{"sha1", fingerprint}); + db.write(local_path); + emit info(tr("SSL fingerprint generated.")); } catch (const std::exception& e) { emit error(tr("Failed to find SSL fingerprint.") + e.what()); @@ -91,7 +95,7 @@ std::string SslCertificate::getCertificateDirectory() return m_ProfileDir + QDir::separator().toLatin1() + kSslDir; } -bool SslCertificate::isCertificateValid(const QString& path) +bool SslCertificate::isCertificateValid(const std::string& path) { OpenSSL_add_all_algorithms(); ERR_load_BIO_strings(); @@ -99,7 +103,7 @@ bool SslCertificate::isCertificateValid(const QString& path) BIO* bio = BIO_new(BIO_s_file()); - auto ret = BIO_read_filename(bio, path.toStdString().c_str()); + auto ret = BIO_read_filename(bio, path.c_str()); if (!ret) { emit info(tr("Could not read from default certificate file.")); BIO_free_all(bio); diff --git a/src/gui/src/SslCertificate.h b/src/gui/src/SslCertificate.h index 2fe807a2..7f77771a 100644 --- a/src/gui/src/SslCertificate.h +++ b/src/gui/src/SslCertificate.h @@ -37,12 +37,12 @@ signals: private: std::pair runTool(const QStringList& args); - void generateFingerprint(const QString& certificateFilename); + void generateFingerprint(const std::string& cert_path); std::string getCertificatePath(); std::string getCertificateDirectory(); - bool isCertificateValid(const QString& path); + bool isCertificateValid(const std::string& path); private: std::string m_ProfileDir; }; diff --git a/src/lib/common/DataDirectories.h b/src/lib/common/DataDirectories.h index 783ff138..4489ac24 100644 --- a/src/lib/common/DataDirectories.h +++ b/src/lib/common/DataDirectories.h @@ -31,6 +31,10 @@ public: static const std::string& systemconfig(); static const std::string& systemconfig(const std::string& path); + static std::string ssl_fingerprints_path(); + static std::string local_ssl_fingerprints_path(); + static std::string trusted_servers_ssl_fingerprints_path(); + static std::string trusted_clients_ssl_fingerprints_path(); private: static std::string _profile; static std::string _global; diff --git a/src/lib/common/DataDirectories_static.cpp b/src/lib/common/DataDirectories_static.cpp index 48dccb68..5e28e055 100644 --- a/src/lib/common/DataDirectories_static.cpp +++ b/src/lib/common/DataDirectories_static.cpp @@ -21,3 +21,28 @@ std::string DataDirectories::_profile; std::string DataDirectories::_global; std::string DataDirectories::_systemconfig; + +static const char kFingerprintsDirName[] = "SSL/Fingerprints"; +static const char kFingerprintsLocalFilename[] = "Local.txt"; +static const char kFingerprintsTrustedServersFilename[] = "TrustedServers.txt"; +static const char kFingerprintsTrustedClientsFilename[] = "TrustedClients.txt"; + +std::string DataDirectories::ssl_fingerprints_path() +{ + return profile() + "/" + kFingerprintsDirName; +} + +std::string DataDirectories::local_ssl_fingerprints_path() +{ + return ssl_fingerprints_path() + "/" + kFingerprintsLocalFilename; +} + +std::string DataDirectories::trusted_servers_ssl_fingerprints_path() +{ + return ssl_fingerprints_path() + "/" + kFingerprintsTrustedServersFilename; +} + +std::string DataDirectories::trusted_clients_ssl_fingerprints_path() +{ + return ssl_fingerprints_path() + "/" + kFingerprintsTrustedClientsFilename; +} From 50534ecb43e7cf0ff827e296b7b3784bff3a0bd5 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:46 +0200 Subject: [PATCH 055/113] lib/net: Use new FingerprintDatabase to handle fingerprints --- src/lib/net/SecureSocket.cpp | 55 +++++++++++++----------------------- 1 file changed, 19 insertions(+), 36 deletions(-) diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 286394c4..c38c5315 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -27,6 +27,7 @@ #include "base/String.h" #include "common/DataDirectories.h" #include "io/fstream.h" +#include "net/FingerprintDatabase.h" #include #include @@ -48,11 +49,6 @@ enum { kMsgSize = 128 }; -static const char kFingerprintDirName[] = "SSL/Fingerprints"; -//static const char kFingerprintLocalFilename[] = "Local.txt"; -static const char kFingerprintTrustedServersFilename[] = "TrustedServers.txt"; -//static const char kFingerprintTrustedClientsFilename[] = "TrustedClients.txt"; - struct Ssl { SSL_CTX* m_context; SSL* m_ssl; @@ -670,46 +666,33 @@ SecureSocket::verifyCertFingerprint() return false; } - auto fingerprint = barrier::format_ssl_fingerprint(fingerprint_raw); - LOG((CLOG_NOTE "server fingerprint: %s", fingerprint.c_str())); + LOG((CLOG_NOTE "server fingerprint: %s", + barrier::format_ssl_fingerprint(fingerprint_raw).c_str())); - std::string trustedServersFilename; - trustedServersFilename = barrier::string::sprintf( - "%s/%s/%s", - DataDirectories::profile().c_str(), - kFingerprintDirName, - kFingerprintTrustedServersFilename); + auto fingerprint_db_path = DataDirectories::trusted_servers_ssl_fingerprints_path(); // Provide debug hint as to what file is being used to verify fingerprint trust - LOG((CLOG_NOTE "trustedServersFilename: %s", trustedServersFilename.c_str() )); + LOG((CLOG_NOTE "fingerprint_db_path: %s", fingerprint_db_path.c_str())); - // check if this fingerprint exist - std::string fileLine; - std::ifstream file; - barrier::open_utf8_path(file, trustedServersFilename); + barrier::FingerprintDatabase db; + db.read(fingerprint_db_path); - if (!file.is_open()) { - LOG((CLOG_NOTE "Unable to open trustedServersFile: %s", trustedServersFilename.c_str() )); + if (!db.fingerprints().empty()) { + LOG((CLOG_NOTE "Read %d fingerprints from: %s", db.fingerprints().size(), + fingerprint_db_path.c_str())); } else { - LOG((CLOG_NOTE "Opened trustedServersFilename: %s", trustedServersFilename.c_str() )); + LOG((CLOG_NOTE "Could not read fingerprints from: %s", + fingerprint_db_path.c_str())); } - bool isValid = false; - while (!file.eof() && file.is_open()) { - getline(file,fileLine); - if (!fileLine.empty()) { - if (fileLine.compare(fingerprint) == 0) { - LOG((CLOG_NOTE "Fingerprint matches trusted fingerprint")); - isValid = true; - break; - } else { - LOG((CLOG_NOTE "Fingerprint does not match trusted fingerprint")); - } - } + barrier::FingerprintData fingerprint{"sha1", fingerprint_raw}; + if (db.is_trusted(fingerprint)) { + LOG((CLOG_NOTE "Fingerprint matches trusted fingerprint")); + return true; + } else { + LOG((CLOG_NOTE "Fingerprint does not match trusted fingerprint")); + return false; } - - file.close(); - return isValid; } MultiplexerJobStatus SecureSocket::serviceConnect(ISocketMultiplexerJob* job, From 7cced74119fc2f4e96f4a894132090057d28455a Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:47 +0200 Subject: [PATCH 056/113] lib/net: Use FingerprintData to represent fingerprints --- src/gui/src/SslCertificate.cpp | 2 +- ...{FingerprintType.h => FingerprintData.cpp} | 24 +++++----- src/lib/net/FingerprintData.h | 46 +++++++++++++++++++ src/lib/net/FingerprintDatabase.cpp | 5 -- src/lib/net/FingerprintDatabase.h | 11 +---- src/lib/net/SecureSocket.cpp | 9 ++-- src/lib/net/SecureUtils.cpp | 8 ++-- src/lib/net/SecureUtils.h | 7 ++- 8 files changed, 70 insertions(+), 42 deletions(-) rename src/lib/net/{FingerprintType.h => FingerprintData.cpp} (74%) create mode 100644 src/lib/net/FingerprintData.h diff --git a/src/gui/src/SslCertificate.cpp b/src/gui/src/SslCertificate.cpp index 4242df56..a96a3e30 100644 --- a/src/gui/src/SslCertificate.cpp +++ b/src/gui/src/SslCertificate.cpp @@ -76,7 +76,7 @@ void SslCertificate::generateFingerprint(const std::string& cert_path) auto local_path = DataDirectories::local_ssl_fingerprints_path(); barrier::FingerprintDatabase db; - db.add_trusted(barrier::FingerprintData{"sha1", fingerprint}); + db.add_trusted(fingerprint); db.write(local_path); emit info(tr("SSL fingerprint generated.")); diff --git a/src/lib/net/FingerprintType.h b/src/lib/net/FingerprintData.cpp similarity index 74% rename from src/lib/net/FingerprintType.h rename to src/lib/net/FingerprintData.cpp index 4e58e9f6..f7acbd28 100644 --- a/src/lib/net/FingerprintType.h +++ b/src/lib/net/FingerprintData.cpp @@ -15,20 +15,20 @@ along with this program. If not, see . */ -#ifndef BARRIER_LIB_NET_FINGERPRINT_TYPE_H -#define BARRIER_LIB_NET_FINGERPRINT_TYPE_H - -#include +#include "base/String.h" +#include "FingerprintDatabase.h" +#include "io/fstream.h" +#include +#include namespace barrier { -enum FingerprintType { - INVALID, - SHA1, // deprecated - SHA256, -}; +bool FingerprintData::operator==(const FingerprintData& other) const +{ + return algorithm == other.algorithm && data == other.data; +} -inline const char* fingerprint_type_to_string(FingerprintType type) +const char* fingerprint_type_to_string(FingerprintType type) { switch (type) { case FingerprintType::INVALID: return "invalid"; @@ -38,7 +38,7 @@ inline const char* fingerprint_type_to_string(FingerprintType type) return "invalid"; } -inline FingerprintType fingerprint_type_from_string(const std::string& type) +FingerprintType fingerprint_type_from_string(const std::string& type) { if (type == "sha1") { return FingerprintType::SHA1; @@ -50,5 +50,3 @@ inline FingerprintType fingerprint_type_from_string(const std::string& type) } } // namespace barrier - -#endif // BARRIER_LIB_NET_FINGERPRINT_TYPE_H diff --git a/src/lib/net/FingerprintData.h b/src/lib/net/FingerprintData.h new file mode 100644 index 00000000..938a6953 --- /dev/null +++ b/src/lib/net/FingerprintData.h @@ -0,0 +1,46 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . +*/ + +#ifndef BARRIER_LIB_NET_FINGERPRINT_DATA_H +#define BARRIER_LIB_NET_FINGERPRINT_DATA_H + +#include +#include + +namespace barrier { + +enum FingerprintType { + INVALID, + SHA1, // deprecated + SHA256, +}; + +struct FingerprintData { + std::string algorithm; + std::vector data; + + bool valid() const { return !algorithm.empty(); } + + bool operator==(const FingerprintData& other) const; +}; + +const char* fingerprint_type_to_string(FingerprintType type); +FingerprintType fingerprint_type_from_string(const std::string& type); + +} // namespace barrier + +#endif // BARRIER_LIB_NET_FINGERPRINT_TYPE_H diff --git a/src/lib/net/FingerprintDatabase.cpp b/src/lib/net/FingerprintDatabase.cpp index cdc3ad32..3dcbaee6 100644 --- a/src/lib/net/FingerprintDatabase.cpp +++ b/src/lib/net/FingerprintDatabase.cpp @@ -23,11 +23,6 @@ namespace barrier { -bool FingerprintData::operator==(const FingerprintData& other) const -{ - return algorithm == other.algorithm && data == other.data; -} - void FingerprintDatabase::read(const std::string& path) { std::ifstream file; diff --git a/src/lib/net/FingerprintDatabase.h b/src/lib/net/FingerprintDatabase.h index 36ab39ce..4a17696e 100644 --- a/src/lib/net/FingerprintDatabase.h +++ b/src/lib/net/FingerprintDatabase.h @@ -18,22 +18,13 @@ #ifndef BARRIER_LIB_NET_FINGERPRINT_DATABASE_H #define BARRIER_LIB_NET_FINGERPRINT_DATABASE_H -#include "FingerprintType.h" +#include "FingerprintData.h" #include #include #include namespace barrier { -struct FingerprintData { - std::string algorithm; - std::vector data; - - bool valid() const { return !algorithm.empty(); } - - bool operator==(const FingerprintData& other) const; -}; - class FingerprintDatabase { public: void read(const std::string& path); diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index c38c5315..245f5287 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -657,17 +657,17 @@ bool SecureSocket::verifyCertFingerprint() { // calculate received certificate fingerprint - std::vector fingerprint_raw; + barrier::FingerprintData fingerprint; try { - fingerprint_raw = barrier::get_ssl_cert_fingerprint(SSL_get_peer_certificate(m_ssl->m_ssl), - barrier::FingerprintType::SHA1); + fingerprint = barrier::get_ssl_cert_fingerprint(SSL_get_peer_certificate(m_ssl->m_ssl), + barrier::FingerprintType::SHA1); } catch (const std::exception& e) { LOG((CLOG_ERR "%s", e.what())); return false; } LOG((CLOG_NOTE "server fingerprint: %s", - barrier::format_ssl_fingerprint(fingerprint_raw).c_str())); + barrier::format_ssl_fingerprint(fingerprint.data).c_str())); auto fingerprint_db_path = DataDirectories::trusted_servers_ssl_fingerprints_path(); @@ -685,7 +685,6 @@ SecureSocket::verifyCertFingerprint() fingerprint_db_path.c_str())); } - barrier::FingerprintData fingerprint{"sha1", fingerprint_raw}; if (db.is_trusted(fingerprint)) { LOG((CLOG_NOTE "Fingerprint matches trusted fingerprint")); return true; diff --git a/src/lib/net/SecureUtils.cpp b/src/lib/net/SecureUtils.cpp index 4b081f66..a9852558 100644 --- a/src/lib/net/SecureUtils.cpp +++ b/src/lib/net/SecureUtils.cpp @@ -15,6 +15,7 @@ along with this program. If not, see . */ +#include "FingerprintDatabase.h" #include "SecureUtils.h" #include "base/String.h" #include "base/finally.h" @@ -59,7 +60,7 @@ std::string format_ssl_fingerprint(const std::vector& fingerprint, bool return result; } -std::vector get_ssl_cert_fingerprint(X509* cert, FingerprintType type) +FingerprintData get_ssl_cert_fingerprint(X509* cert, FingerprintType type) { if (!cert) { throw std::runtime_error("certificate is null"); @@ -77,11 +78,10 @@ std::vector get_ssl_cert_fingerprint(X509* cert, FingerprintType t std::vector digest_vec; digest_vec.assign(reinterpret_cast(digest), reinterpret_cast(digest) + digest_length); - return digest_vec; + return {fingerprint_type_to_string(type), digest_vec}; } -std::vector get_pem_file_cert_fingerprint(const std::string& path, - FingerprintType type) +FingerprintData get_pem_file_cert_fingerprint(const std::string& path, FingerprintType type) { auto fp = fopen_utf8_path(path, "r"); if (!fp) { diff --git a/src/lib/net/SecureUtils.h b/src/lib/net/SecureUtils.h index ace0d45a..c6361419 100644 --- a/src/lib/net/SecureUtils.h +++ b/src/lib/net/SecureUtils.h @@ -18,7 +18,7 @@ #ifndef BARRIER_LIB_NET_SECUREUTILS_H #define BARRIER_LIB_NET_SECUREUTILS_H -#include "FingerprintType.h" +#include "FingerprintData.h" #include #include #include @@ -29,10 +29,9 @@ namespace barrier { std::string format_ssl_fingerprint(const std::vector& fingerprint, bool separator = true); -std::vector get_ssl_cert_fingerprint(X509* cert, FingerprintType type); +FingerprintData get_ssl_cert_fingerprint(X509* cert, FingerprintType type); -std::vector get_pem_file_cert_fingerprint(const std::string& path, - FingerprintType type); +FingerprintData get_pem_file_cert_fingerprint(const std::string& path, FingerprintType type); void generate_pem_self_signed_cert(const std::string& path); From a238b27879229407cbb08fc4201dbe8533bf64b8 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:49 +0200 Subject: [PATCH 057/113] gui: Simplify isCertificateValid() --- src/gui/src/SslCertificate.cpp | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/src/gui/src/SslCertificate.cpp b/src/gui/src/SslCertificate.cpp index a96a3e30..39c63674 100644 --- a/src/gui/src/SslCertificate.cpp +++ b/src/gui/src/SslCertificate.cpp @@ -17,6 +17,8 @@ #include "SslCertificate.h" #include "common/DataDirectories.h" +#include "base/finally.h" +#include "io/fstream.h" #include "net/FingerprintDatabase.h" #include "net/SecureUtils.h" @@ -98,39 +100,32 @@ std::string SslCertificate::getCertificateDirectory() bool SslCertificate::isCertificateValid(const std::string& path) { OpenSSL_add_all_algorithms(); - ERR_load_BIO_strings(); ERR_load_crypto_strings(); - BIO* bio = BIO_new(BIO_s_file()); - - auto ret = BIO_read_filename(bio, path.c_str()); - if (!ret) { + auto fp = barrier::fopen_utf8_path(path, "r"); + if (!fp) { emit info(tr("Could not read from default certificate file.")); - BIO_free_all(bio); return false; } + auto file_close = barrier::finally([fp]() { std::fclose(fp); }); - X509* cert = PEM_read_bio_X509(bio, NULL, 0, NULL); + auto* cert = PEM_read_X509(fp, nullptr, nullptr, nullptr); if (!cert) { emit info(tr("Error loading default certificate file to memory.")); - BIO_free_all(bio); return false; } + auto cert_free = barrier::finally([cert]() { X509_free(cert); }); - EVP_PKEY* pubkey = X509_get_pubkey(cert); + auto* pubkey = X509_get_pubkey(cert); if (!pubkey) { emit info(tr("Default certificate key file does not contain valid public key")); - X509_free(cert); - BIO_free_all(bio); return false; } + auto pubkey_free = barrier::finally([pubkey]() { EVP_PKEY_free(pubkey); }); auto type = EVP_PKEY_type(EVP_PKEY_id(pubkey)); if (type != EVP_PKEY_RSA && type != EVP_PKEY_DSA) { emit info(tr("Public key in default certificate key file is not RSA or DSA")); - EVP_PKEY_free(pubkey); - X509_free(cert); - BIO_free_all(bio); return false; } @@ -138,14 +133,8 @@ bool SslCertificate::isCertificateValid(const std::string& path) if (bits < 2048) { // We could have small keys in old barrier installations emit info(tr("Public key in default certificate key file is too small.")); - EVP_PKEY_free(pubkey); - X509_free(cert); - BIO_free_all(bio); return false; } - EVP_PKEY_free(pubkey); - X509_free(cert); - BIO_free_all(bio); return true; } From b7757fbd688cc9db70be5bbb590f5fa075b1700c Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:50 +0200 Subject: [PATCH 058/113] lib/net: Implement a way to generate fingerprint randomart The code has been copied from OpenSSH. --- src/lib/net/SecureUtils.cpp | 140 +++++++++++++++++++- src/lib/net/SecureUtils.h | 2 + src/test/unittests/net/SecureUtilsTests.cpp | 40 ++++++ 3 files changed, 181 insertions(+), 1 deletion(-) diff --git a/src/lib/net/SecureUtils.cpp b/src/lib/net/SecureUtils.cpp index a9852558..c7e0a82d 100644 --- a/src/lib/net/SecureUtils.cpp +++ b/src/lib/net/SecureUtils.cpp @@ -13,9 +13,36 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . + + ----------------------------------------------------------------------- + create_fingerprint_randomart() has been taken from the OpenSSH project. + Copyright information follows. + + Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. + Copyright (c) 2008 Alexander von Gernler. All rights reserved. + Copyright (c) 2010,2011 Damien Miller. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "FingerprintDatabase.h" #include "SecureUtils.h" #include "base/String.h" #include "base/finally.h" @@ -25,7 +52,9 @@ #include #include #include +#include #include +#include #include namespace barrier { @@ -142,4 +171,113 @@ void generate_pem_self_signed_cert(const std::string& path) PEM_write_X509(fp, cert); } +/* + Draw an ASCII-Art representing the fingerprint so human brain can + profit from its built-in pattern recognition ability. + This technique is called "random art" and can be found in some + scientific publications like this original paper: + + "Hash Visualization: a New Technique to improve Real-World Security", + Perrig A. and Song D., 1999, International Workshop on Cryptographic + Techniques and E-Commerce (CrypTEC '99) + sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf + + The subject came up in a talk by Dan Kaminsky, too. + + If you see the picture is different, the key is different. + If the picture looks the same, you still know nothing. + + The algorithm used here is a worm crawling over a discrete plane, + leaving a trace (augmenting the field) everywhere it goes. + Movement is taken from dgst_raw 2bit-wise. Bumping into walls + makes the respective movement vector be ignored for this turn. + Graphs are not unambiguous, because circles in graphs can be +walked in either direction. + */ + +/* + Field sizes for the random art. Have to be odd, so the starting point + can be in the exact middle of the picture, and FLDBASE should be >=8 . + Else pictures would be too dense, and drawing the frame would + fail, too, because the key type would not fit in anymore. +*/ +#define FLDBASE 8 +#define FLDSIZE_Y (FLDBASE + 1) +#define FLDSIZE_X (FLDBASE * 2 + 1) + +std::string create_fingerprint_randomart(const std::vector& dgst_raw) +{ + /* + * Chars to be used after each other every time the worm + * intersects with itself. Matter of taste. + */ + const char* augmentation_string = " .o+=*BOX@%&#/^SE"; + char *p; + std::uint8_t field[FLDSIZE_X][FLDSIZE_Y]; + std::size_t i; + std::uint32_t b; + int x, y; + std::size_t len = strlen(augmentation_string) - 1; + + std::vector retval; + retval.reserve((FLDSIZE_X + 3) * (FLDSIZE_Y + 2)); + + auto add_char = [&retval](char ch) { retval.push_back(ch); }; + + /* initialize field */ + std::memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char)); + x = FLDSIZE_X / 2; + y = FLDSIZE_Y / 2; + + /* process raw key */ + for (i = 0; i < dgst_raw.size(); i++) { + /* each byte conveys four 2-bit move commands */ + int input = dgst_raw[i]; + for (b = 0; b < 4; b++) { + /* evaluate 2 bit, rest is shifted later */ + x += (input & 0x1) ? 1 : -1; + y += (input & 0x2) ? 1 : -1; + + /* assure we are still in bounds */ + x = std::max(x, 0); + y = std::max(y, 0); + x = std::min(x, FLDSIZE_X - 1); + y = std::min(y, FLDSIZE_Y - 1); + + /* augment the field */ + if (field[x][y] < len - 2) + field[x][y]++; + input = input >> 2; + } + } + + /* mark starting point and end point*/ + field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1; + field[x][y] = len; + + /* output upper border */ + add_char('+'); + for (i = 0; i < FLDSIZE_X; i++) + add_char('-'); + add_char('+'); + add_char('\n'); + + /* output content */ + for (y = 0; y < FLDSIZE_Y; y++) { + add_char('|'); + for (x = 0; x < FLDSIZE_X; x++) + add_char(augmentation_string[std::min(field[x][y], len)]); + add_char('|'); + add_char('\n'); + } + + /* output lower border */ + add_char('+'); + for (i = 0; i < FLDSIZE_X; i++) + add_char('-'); + add_char('+'); + + return std::string{retval.data(), retval.size()}; +} + } // namespace barrier diff --git a/src/lib/net/SecureUtils.h b/src/lib/net/SecureUtils.h index c6361419..7525381f 100644 --- a/src/lib/net/SecureUtils.h +++ b/src/lib/net/SecureUtils.h @@ -35,6 +35,8 @@ FingerprintData get_pem_file_cert_fingerprint(const std::string& path, Fingerpri void generate_pem_self_signed_cert(const std::string& path); +std::string create_fingerprint_randomart(const std::vector& dgst_raw); + } // namespace barrier #endif // BARRIER_LIB_NET_SECUREUTILS_H diff --git a/src/test/unittests/net/SecureUtilsTests.cpp b/src/test/unittests/net/SecureUtilsTests.cpp index c2394bf9..0cce693a 100644 --- a/src/test/unittests/net/SecureUtilsTests.cpp +++ b/src/test/unittests/net/SecureUtilsTests.cpp @@ -30,4 +30,44 @@ TEST(SecureUtilsTest, FormatSslFingerprintHexWithSeparators) "CA:B2:8E:49:25:94:90:25:26:05:8D:AF:63:ED:2E:30"); } +TEST(SecureUtilsTest, CreateFingerprintRandomArt) +{ + ASSERT_EQ(create_fingerprint_randomart(generate_pseudo_random_bytes(0, 32)), + "+-----------------+\n" + "|*X+. . |\n" + "|*oo + |\n" + "| + = |\n" + "| B . . |\n" + "|.+... o S |\n" + "|E+ ++. . |\n" + "|B*++.. . |\n" + "|+o*o o . |\n" + "|+o*Bo . |\n" + "+-----------------+"); + ASSERT_EQ(create_fingerprint_randomart(generate_pseudo_random_bytes(1, 32)), + "+-----------------+\n" + "| .oo+ . .B=. |\n" + "| .o.+ . o o.= |\n" + "|o..+.. o . E * |\n" + "|oo..+ . * * |\n" + "|B o.....S. o . |\n" + "|+=o..... |\n" + "| + + . |\n" + "|o. .. |\n" + "|..o.. |\n" + "+-----------------+"); + ASSERT_EQ(create_fingerprint_randomart(generate_pseudo_random_bytes(2, 32)), + "+-----------------+\n" + "| ... .o.o.|\n" + "| o .=.E|\n" + "| . + o ...+.|\n" + "| * o = o ... |\n" + "| * + S & . |\n" + "| = + % @ |\n" + "| . . = X o |\n" + "| . . O . |\n" + "| . + |\n" + "+-----------------+"); +} + } // namespace barrier From c7e6fc6c7e51877fa0b98c396e1240d7d7ccd4c2 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:51 +0200 Subject: [PATCH 059/113] gui: Set the size of the window to the size of the contents --- src/gui/src/MainWindow.cpp | 8 ++++++++ src/gui/src/MainWindow.h | 1 + src/gui/src/MainWindowBase.ui | 17 +++-------------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 02499a12..b1d6fc83 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -938,6 +938,14 @@ void MainWindow::changeEvent(QEvent* event) QMainWindow::changeEvent(event); } +bool MainWindow::event(QEvent* event) +{ + if (event->type() == QEvent::LayoutRequest) { + setFixedSize(sizeHint()); + } + return QMainWindow::event(event); +} + void MainWindow::updateZeroconfService() { QMutexLocker locker(&m_UpdateZeroconfMutex); diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h index 131b31ce..9a6c615d 100644 --- a/src/gui/src/MainWindow.h +++ b/src/gui/src/MainWindow.h @@ -157,6 +157,7 @@ public slots: void stopService(); void stopDesktop(); void changeEvent(QEvent* event); + bool event(QEvent* event); void retranslateMenuBar(); #if defined(Q_OS_WIN) bool isServiceRunning(QString name); diff --git a/src/gui/src/MainWindowBase.ui b/src/gui/src/MainWindowBase.ui index 117405ca..3e31ac9f 100644 --- a/src/gui/src/MainWindowBase.ui +++ b/src/gui/src/MainWindowBase.ui @@ -2,31 +2,20 @@ MainWindowBase - - - 0 - 0 - 600 - 550 - - 0 0 - - - 600 - 0 - - Barrier + + QLayout::SetFixedSize + From a428b61c7dfbd120f00f97c6a656ea3e858736ea Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:52:52 +0200 Subject: [PATCH 060/113] gui: Add support for SHA256 fingerprints For the time being both SHA1 and SHA256 fingerprints will be shown in the UI. This allows users to verify new connections between old and new versions of Barrier. After the initial verification we use SHA256 fingerprints. The issue has been reported by Matthias Gerstner . --- .../fingerprint-randomart.feature | 3 + doc/newsfragments/sha256-fingerprints.bugfix | 4 + src/gui/src/MainWindow.cpp | 70 +++++++++++++--- src/gui/src/MainWindow.h | 2 + src/gui/src/MainWindowBase.ui | 83 ++++++++++++++++++- src/gui/src/SslCertificate.cpp | 8 +- src/lib/net/SecureSocket.cpp | 17 ++-- src/lib/net/SecureUtils.cpp | 23 +++++ src/lib/net/SecureUtils.h | 1 + 9 files changed, 185 insertions(+), 26 deletions(-) create mode 100644 doc/newsfragments/fingerprint-randomart.feature create mode 100644 doc/newsfragments/sha256-fingerprints.bugfix diff --git a/doc/newsfragments/fingerprint-randomart.feature b/doc/newsfragments/fingerprint-randomart.feature new file mode 100644 index 00000000..9ffced93 --- /dev/null +++ b/doc/newsfragments/fingerprint-randomart.feature @@ -0,0 +1,3 @@ +Added support for randomart images for easier comparison of SSL +certificate fingerprints. The algorithm is identical to what +OpenSSH uses. diff --git a/doc/newsfragments/sha256-fingerprints.bugfix b/doc/newsfragments/sha256-fingerprints.bugfix new file mode 100644 index 00000000..a724c3b5 --- /dev/null +++ b/doc/newsfragments/sha256-fingerprints.bugfix @@ -0,0 +1,4 @@ +Barrier now uses SHA256 fingerprints for establishing security of encrypted SSL connections. +After upgrading client to new version the existing server fingerprint will need to be approved again. +Client and server will show both SHA1 and SHA256 server fingerprints to allow interoperability +with older versions of Barrier. diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index b1d6fc83..ccb5c196 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -158,9 +158,22 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) : m_pComboServerList->hide(); m_pLabelPadlock->hide(); + frame_fingerprint_details->hide(); updateSSLFingerprint(); + connect(toolbutton_show_fingerprint, &QToolButton::clicked, [this](bool checked) + { + m_fingerprint_expanded = !m_fingerprint_expanded; + if (m_fingerprint_expanded) { + frame_fingerprint_details->show(); + toolbutton_show_fingerprint->setArrowType(Qt::ArrowType::UpArrow); + } else { + frame_fingerprint_details->hide(); + toolbutton_show_fingerprint->setArrowType(Qt::ArrowType::DownArrow); + } + }); + // resize window to smallest reasonable size resize(0, 0); } @@ -414,26 +427,32 @@ void MainWindow::checkConnected(const QString& line) void MainWindow::checkFingerprint(const QString& line) { - QRegExp fingerprintRegex(".*server fingerprint: ([A-F0-9:]+)"); + QRegExp fingerprintRegex(".*server fingerprint \\(SHA1\\): ([A-F0-9:]+) \\(SHA256\\): ([A-F0-9:]+)"); if (!fingerprintRegex.exactMatch(line)) { return; } - barrier::FingerprintData fingerprint = { + barrier::FingerprintData fingerprint_sha1 = { barrier::fingerprint_type_to_string(barrier::FingerprintType::SHA1), barrier::string::from_hex(fingerprintRegex.cap(1).toStdString()) }; + barrier::FingerprintData fingerprint_sha256 = { + barrier::fingerprint_type_to_string(barrier::FingerprintType::SHA256), + barrier::string::from_hex(fingerprintRegex.cap(2).toStdString()) + }; + auto db_path = DataDirectories::trusted_servers_ssl_fingerprints_path(); + // We compare only SHA256 fingerprints, but show both SHA1 and SHA256 so that the users can + // still verify fingerprints on old Barrier servers. This way the only time when we are exposed + // to SHA1 vulnerabilities is when the user is reconnecting again. barrier::FingerprintDatabase db; db.read(db_path); - if (db.is_trusted(fingerprint)) { + if (db.is_trusted(fingerprint_sha256)) { return; } - auto formatted_fingerprint = barrier::format_ssl_fingerprint(fingerprint.data); - static bool messageBoxAlreadyShown = false; if (!messageBoxAlreadyShown) { @@ -444,7 +463,11 @@ void MainWindow::checkFingerprint(const QString& line) QMessageBox::information( this, tr("Security question"), tr("Do you trust this fingerprint?\n\n" - "%1\n\n" + "SHA256:\n" + "%1\n" + "%2\n\n" + "SHA1 (obsolete, when using old Barrier server):\n" + "%3\n\n" "This is a server fingerprint. You should compare this " "fingerprint to the one on your server's screen. If the " "two don't match exactly, then it's probably not the server " @@ -452,12 +475,15 @@ void MainWindow::checkFingerprint(const QString& line) "To automatically trust this fingerprint for future " "connections, click Yes. To reject this fingerprint and " "disconnect from the server, click No.") - .arg(QString::fromStdString(formatted_fingerprint)), + .arg(QString::fromStdString(barrier::format_ssl_fingerprint(fingerprint_sha256.data))) + .arg(QString::fromStdString( + barrier::create_fingerprint_randomart(fingerprint_sha256.data))) + .arg(QString::fromStdString(barrier::format_ssl_fingerprint(fingerprint_sha1.data))), QMessageBox::Yes | QMessageBox::No); if (fingerprintReply == QMessageBox::Yes) { // restart core process after trusting fingerprint. - db.add_trusted(fingerprint); + db.add_trusted(fingerprint_sha256); db.write(db_path); startBarrier(); } @@ -987,6 +1013,7 @@ void MainWindow::updateSSLFingerprint() m_pSslCertificate->generateCertificate(); } + toolbutton_show_fingerprint->setEnabled(false); m_pLabelLocalFingerprint->setText("Disabled"); if (!m_AppConfig->getCryptoEnabled()) { @@ -1000,15 +1027,32 @@ void MainWindow::updateSSLFingerprint() barrier::FingerprintDatabase db; db.read(local_path); - if (db.fingerprints().empty()) { + if (db.fingerprints().size() != 2) { return; } - const auto& fingerprint = db.fingerprints().front(); - auto formatted_fingerprint = barrier::format_ssl_fingerprint(fingerprint.data); + for (const auto& fingerprint : db.fingerprints()) { + if (fingerprint.algorithm == "sha1") { + auto fingerprint_str = barrier::format_ssl_fingerprint(fingerprint.data); + label_sha1_fingerprint_full->setText(QString::fromStdString(fingerprint_str)); + continue; + } - m_pLabelLocalFingerprint->setText(QString::fromStdString(formatted_fingerprint)); - m_pLabelLocalFingerprint->setTextInteractionFlags(Qt::TextSelectableByMouse); + if (fingerprint.algorithm == "sha256") { + auto fingerprint_str = barrier::format_ssl_fingerprint(fingerprint.data); + fingerprint_str.resize(40); + fingerprint_str += " ..."; + + auto fingerprint_str_cols = barrier::format_ssl_fingerprint_columns(fingerprint.data); + auto fingerprint_randomart = barrier::create_fingerprint_randomart(fingerprint.data); + + m_pLabelLocalFingerprint->setText(QString::fromStdString(fingerprint_str)); + label_sha256_fingerprint_full->setText(QString::fromStdString(fingerprint_str_cols)); + label_sha256_randomart->setText(QString::fromStdString(fingerprint_randomart)); + } + } + + toolbutton_show_fingerprint->setEnabled(true); } void MainWindow::on_m_pGroupClient_toggled(bool on) diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h index 9a6c615d..59a0e0db 100644 --- a/src/gui/src/MainWindow.h +++ b/src/gui/src/MainWindow.h @@ -203,6 +203,8 @@ public slots: QStringList m_PendingClientNames; LogWindow *m_pLogWindow; + bool m_fingerprint_expanded = false; + private slots: void on_m_pCheckBoxAutoConfig_toggled(bool checked); void on_m_pComboServerList_currentIndexChanged(QString ); diff --git a/src/gui/src/MainWindowBase.ui b/src/gui/src/MainWindowBase.ui index 3e31ac9f..9f8d4896 100644 --- a/src/gui/src/MainWindowBase.ui +++ b/src/gui/src/MainWindowBase.ui @@ -75,10 +75,87 @@ + + Qt::PlainText + + + + + + + ... + + + Qt::DownArrow + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + QLayout::SetMinimumSize + + + + + + Courier + + + + + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + SHA1 (deprecated, compare to old clients only): + + + + + + + + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + SHA256: + + + + + + + + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + @@ -242,7 +319,7 @@ - :/res/icons/16x16/padlock.png + :/res/icons/16x16/padlock.png @@ -377,7 +454,7 @@ - Show &Log + Show &Log Show Log @@ -388,7 +465,7 @@ - + diff --git a/src/gui/src/SslCertificate.cpp b/src/gui/src/SslCertificate.cpp index 39c63674..ea770503 100644 --- a/src/gui/src/SslCertificate.cpp +++ b/src/gui/src/SslCertificate.cpp @@ -73,12 +73,12 @@ void SslCertificate::generateCertificate() void SslCertificate::generateFingerprint(const std::string& cert_path) { try { - auto fingerprint = barrier::get_pem_file_cert_fingerprint(cert_path, - barrier::FingerprintType::SHA1); - auto local_path = DataDirectories::local_ssl_fingerprints_path(); barrier::FingerprintDatabase db; - db.add_trusted(fingerprint); + db.add_trusted(barrier::get_pem_file_cert_fingerprint(cert_path, + barrier::FingerprintType::SHA1)); + db.add_trusted(barrier::get_pem_file_cert_fingerprint(cert_path, + barrier::FingerprintType::SHA256)); db.write(local_path); emit info(tr("SSL fingerprint generated.")); diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 245f5287..3c65d9ac 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -657,17 +657,22 @@ bool SecureSocket::verifyCertFingerprint() { // calculate received certificate fingerprint - barrier::FingerprintData fingerprint; + barrier::FingerprintData fingerprint_sha1, fingerprint_sha256; try { - fingerprint = barrier::get_ssl_cert_fingerprint(SSL_get_peer_certificate(m_ssl->m_ssl), - barrier::FingerprintType::SHA1); + auto* cert = SSL_get_peer_certificate(m_ssl->m_ssl); + fingerprint_sha1 = barrier::get_ssl_cert_fingerprint(cert, + barrier::FingerprintType::SHA1); + fingerprint_sha256 = barrier::get_ssl_cert_fingerprint(cert, + barrier::FingerprintType::SHA256); } catch (const std::exception& e) { LOG((CLOG_ERR "%s", e.what())); return false; } - LOG((CLOG_NOTE "server fingerprint: %s", - barrier::format_ssl_fingerprint(fingerprint.data).c_str())); + // note: the GUI parses the following two lines of logs, don't change unnecessarily + LOG((CLOG_NOTE "server fingerprint (SHA1): %s (SHA256): %s", + barrier::format_ssl_fingerprint(fingerprint_sha1.data).c_str(), + barrier::format_ssl_fingerprint(fingerprint_sha256.data).c_str())); auto fingerprint_db_path = DataDirectories::trusted_servers_ssl_fingerprints_path(); @@ -685,7 +690,7 @@ SecureSocket::verifyCertFingerprint() fingerprint_db_path.c_str())); } - if (db.is_trusted(fingerprint)) { + if (db.is_trusted(fingerprint_sha256)) { LOG((CLOG_NOTE "Fingerprint matches trusted fingerprint")); return true; } else { diff --git a/src/lib/net/SecureUtils.cpp b/src/lib/net/SecureUtils.cpp index c7e0a82d..b99dd38c 100644 --- a/src/lib/net/SecureUtils.cpp +++ b/src/lib/net/SecureUtils.cpp @@ -89,6 +89,29 @@ std::string format_ssl_fingerprint(const std::vector& fingerprint, bool return result; } +std::string format_ssl_fingerprint_columns(const std::vector& fingerprint) +{ + auto max_columns = 8; + + std::string hex = barrier::string::to_hex(fingerprint, 2); + barrier::string::uppercase(hex); + if (hex.empty() || hex.size() % 2 != 0) { + return hex; + } + + std::string separated; + for (std::size_t i = 0; i < hex.size(); i += max_columns * 2) { + for (std::size_t j = i; j < i + 16 && j < hex.size() - 1; j += 2) { + separated.push_back(hex[j]); + separated.push_back(hex[j + 1]); + separated.push_back(':'); + } + separated.push_back('\n'); + } + separated.pop_back(); // we don't need last newline character + return separated; +} + FingerprintData get_ssl_cert_fingerprint(X509* cert, FingerprintType type) { if (!cert) { diff --git a/src/lib/net/SecureUtils.h b/src/lib/net/SecureUtils.h index 7525381f..c4d51f33 100644 --- a/src/lib/net/SecureUtils.h +++ b/src/lib/net/SecureUtils.h @@ -28,6 +28,7 @@ namespace barrier { std::string format_ssl_fingerprint(const std::vector& fingerprint, bool separator = true); +std::string format_ssl_fingerprint_columns(const std::vector& fingerprint); FingerprintData get_ssl_cert_fingerprint(X509* cert, FingerprintType type); From 801a5a7084b20e2548af0e8645bf3b0bea490585 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:29:44 +0200 Subject: [PATCH 061/113] ext: Add https://github.com/gulrak/filesystem for filesystem operations --- .gitmodules | 3 +++ ext/gulrak-filesystem | 1 + 2 files changed, 4 insertions(+) create mode 160000 ext/gulrak-filesystem diff --git a/.gitmodules b/.gitmodules index ad9a3025..9a58a7e9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "ext/gmock"] path = ext/gmock url = https://github.com/google/googlemock.git +[submodule "ext/gulrak-filesystem"] + path = ext/gulrak-filesystem + url = https://github.com/gulrak/filesystem diff --git a/ext/gulrak-filesystem b/ext/gulrak-filesystem new file mode 160000 index 00000000..614bbe87 --- /dev/null +++ b/ext/gulrak-filesystem @@ -0,0 +1 @@ +Subproject commit 614bbe87b80435d87ab8791564370e0c1d13627d From a987605513a0f99c2964b0850d43264f41117a2b Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:29:45 +0200 Subject: [PATCH 062/113] lib/io: Rename fstream.h to filesystem.h --- src/lib/barrier/DropHelper.cpp | 2 +- src/lib/base/log_outputters.cpp | 2 +- src/lib/io/{fstream.cpp => filesystem.cpp} | 2 +- src/lib/io/{fstream.h => filesystem.h} | 6 +++--- src/lib/net/FingerprintData.cpp | 2 +- src/lib/net/SecureUtils.cpp | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) rename src/lib/io/{fstream.cpp => filesystem.cpp} (98%) rename src/lib/io/{fstream.h => filesystem.h} (92%) diff --git a/src/lib/barrier/DropHelper.cpp b/src/lib/barrier/DropHelper.cpp index 32f20cfc..af22b523 100644 --- a/src/lib/barrier/DropHelper.cpp +++ b/src/lib/barrier/DropHelper.cpp @@ -18,7 +18,7 @@ #include "barrier/DropHelper.h" #include "base/Log.h" -#include "io/fstream.h" +#include "io/filesystem.h" #include diff --git a/src/lib/base/log_outputters.cpp b/src/lib/base/log_outputters.cpp index 6d3374b5..a1193c78 100644 --- a/src/lib/base/log_outputters.cpp +++ b/src/lib/base/log_outputters.cpp @@ -20,7 +20,7 @@ #include "base/TMethodJob.h" #include "arch/Arch.h" #include "base/String.h" -#include "io/fstream.h" +#include "io/filesystem.h" #include enum EFileLogOutputter { diff --git a/src/lib/io/fstream.cpp b/src/lib/io/filesystem.cpp similarity index 98% rename from src/lib/io/fstream.cpp rename to src/lib/io/filesystem.cpp index ea91859d..3a50edc9 100644 --- a/src/lib/io/fstream.cpp +++ b/src/lib/io/filesystem.cpp @@ -15,7 +15,7 @@ along with this program. If not, see . */ -#include "fstream.h" +#include "filesystem.h" #if SYSAPI_WIN32 #include "common/win32/encoding_utilities.h" #endif diff --git a/src/lib/io/fstream.h b/src/lib/io/filesystem.h similarity index 92% rename from src/lib/io/fstream.h rename to src/lib/io/filesystem.h index 2b327f18..9747ffe5 100644 --- a/src/lib/io/fstream.h +++ b/src/lib/io/filesystem.h @@ -15,8 +15,8 @@ along with this program. If not, see . */ -#ifndef BARRIER_LIB_IO_FSTREAM_H -#define BARRIER_LIB_IO_FSTREAM_H +#ifndef BARRIER_LIB_IO_FILESYSTEM_H +#define BARRIER_LIB_IO_FILESYSTEM_H #include #include @@ -35,4 +35,4 @@ std::FILE* fopen_utf8_path(const std::string& path, const std::string& mode); } // namespace barrier -#endif +#endif // BARRIER_LIB_IO_FILESYSTEM_H diff --git a/src/lib/net/FingerprintData.cpp b/src/lib/net/FingerprintData.cpp index f7acbd28..460b39bd 100644 --- a/src/lib/net/FingerprintData.cpp +++ b/src/lib/net/FingerprintData.cpp @@ -17,7 +17,7 @@ #include "base/String.h" #include "FingerprintDatabase.h" -#include "io/fstream.h" +#include "io/filesystem.h" #include #include diff --git a/src/lib/net/SecureUtils.cpp b/src/lib/net/SecureUtils.cpp index b99dd38c..3dd2a6a8 100644 --- a/src/lib/net/SecureUtils.cpp +++ b/src/lib/net/SecureUtils.cpp @@ -46,7 +46,7 @@ #include "SecureUtils.h" #include "base/String.h" #include "base/finally.h" -#include "io/fstream.h" +#include "io/filesystem.h" #include #include From bcafdc6783fe7a9c5d5bd0c4ec3297f5c1eb2626 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:29:46 +0200 Subject: [PATCH 063/113] src/lib: Switch to ghc::filesystem in path utilities --- CMakeLists.txt | 2 ++ src/gui/src/SslCertificate.cpp | 2 +- src/lib/io/filesystem.cpp | 26 ++++++++++++++------------ src/lib/io/filesystem.h | 11 +++++++---- src/lib/net/FingerprintDatabase.cpp | 2 +- src/lib/net/SecureSocket.cpp | 2 +- 6 files changed, 26 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1588ad7a..8653a2c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -301,6 +301,8 @@ elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows") ) endif() +include_directories("${CMAKE_SOURCE_DIR}/ext/gulrak-filesystem/include") + # # OpenSSL # diff --git a/src/gui/src/SslCertificate.cpp b/src/gui/src/SslCertificate.cpp index ea770503..57fb5f1b 100644 --- a/src/gui/src/SslCertificate.cpp +++ b/src/gui/src/SslCertificate.cpp @@ -18,7 +18,7 @@ #include "SslCertificate.h" #include "common/DataDirectories.h" #include "base/finally.h" -#include "io/fstream.h" +#include "io/filesystem.h" #include "net/FingerprintDatabase.h" #include "net/SecureUtils.h" diff --git a/src/lib/io/filesystem.cpp b/src/lib/io/filesystem.cpp index 3a50edc9..46ae06db 100644 --- a/src/lib/io/filesystem.cpp +++ b/src/lib/io/filesystem.cpp @@ -15,6 +15,9 @@ along with this program. If not, see . */ +// this header must come first so that it picks up the filesystem implementation +#include + #include "filesystem.h" #if SYSAPI_WIN32 #include "common/win32/encoding_utilities.h" @@ -26,43 +29,42 @@ namespace barrier { namespace { template -void open_utf8_path_impl(Stream& stream, const std::string& path, std::ios_base::openmode mode) +void open_utf8_path_impl(Stream& stream, const fs::path& path, std::ios_base::openmode mode) { #if SYSAPI_WIN32 - // on Windows we need to use a private constructor from wchar_t* string. - auto wchar_path = utf8_to_win_char(path); - stream.open(wchar_path.data(), mode); + // on Windows we need to use a non-standard constructor from wchar_t* string + // which fs::path::native() returns + stream.open(path.native().c_str(), mode); #else - stream.open(path.c_str(), mode); + stream.open(path.native().c_str(), mode); #endif } } // namespace -void open_utf8_path(std::ifstream& stream, const std::string& path, std::ios_base::openmode mode) +void open_utf8_path(std::ifstream& stream, const fs::path& path, std::ios_base::openmode mode) { open_utf8_path_impl(stream, path, mode); } -void open_utf8_path(std::ofstream& stream, const std::string& path, std::ios_base::openmode mode) +void open_utf8_path(std::ofstream& stream, const fs::path& path, std::ios_base::openmode mode) { open_utf8_path_impl(stream, path, mode); } -void open_utf8_path(std::fstream& stream, const std::string& path, std::ios_base::openmode mode) +void open_utf8_path(std::fstream& stream, const fs::path& path, std::ios_base::openmode mode) { open_utf8_path_impl(stream, path, mode); } -std::FILE* fopen_utf8_path(const std::string& path, const std::string& mode) +std::FILE* fopen_utf8_path(const fs::path& path, const std::string& mode) { #if SYSAPI_WIN32 - auto wchar_path = utf8_to_win_char(path); auto wchar_mode = utf8_to_win_char(mode); - return _wfopen(reinterpret_cast(wchar_path.data()), + return _wfopen(path.native().c_str(), reinterpret_cast(wchar_mode.data())); #else - return std::fopen(path.c_str(), mode.c_str()); + return std::fopen(path.native().c_str(), mode.c_str()); #endif } diff --git a/src/lib/io/filesystem.h b/src/lib/io/filesystem.h index 9747ffe5..78e34230 100644 --- a/src/lib/io/filesystem.h +++ b/src/lib/io/filesystem.h @@ -21,17 +21,20 @@ #include #include #include +#include namespace barrier { -void open_utf8_path(std::ifstream& stream, const std::string& path, +namespace fs = ghc::filesystem; + +void open_utf8_path(std::ifstream& stream, const fs::path& path, std::ios_base::openmode mode = std::ios_base::in); -void open_utf8_path(std::ofstream& stream, const std::string& path, +void open_utf8_path(std::ofstream& stream, const fs::path& path, std::ios_base::openmode mode = std::ios_base::out); -void open_utf8_path(std::fstream& stream, const std::string& path, +void open_utf8_path(std::fstream& stream, const fs::path& path, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out); -std::FILE* fopen_utf8_path(const std::string& path, const std::string& mode); +std::FILE* fopen_utf8_path(const fs::path& path, const std::string& mode); } // namespace barrier diff --git a/src/lib/net/FingerprintDatabase.cpp b/src/lib/net/FingerprintDatabase.cpp index 3dcbaee6..020f19b6 100644 --- a/src/lib/net/FingerprintDatabase.cpp +++ b/src/lib/net/FingerprintDatabase.cpp @@ -17,7 +17,7 @@ #include "base/String.h" #include "FingerprintDatabase.h" -#include "io/fstream.h" +#include "io/filesystem.h" #include #include diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 3c65d9ac..9ac674d6 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -26,7 +26,7 @@ #include "base/Log.h" #include "base/String.h" #include "common/DataDirectories.h" -#include "io/fstream.h" +#include "io/filesystem.h" #include "net/FingerprintDatabase.h" #include From e7d936b5d7aada43d6f0a55b620c9573ad31f3e4 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:29:47 +0200 Subject: [PATCH 064/113] lib/common: Replace PathUtilities::concat with barrier::fs equivalent --- src/lib/barrier/App.cpp | 2 +- src/lib/barrier/ArgParser.cpp | 4 ++-- src/lib/barrier/ArgsBase.cpp | 2 +- src/lib/barrier/ArgsBase.h | 5 +++-- src/lib/barrier/ServerApp.cpp | 31 +++++++++++++++++-------------- src/lib/common/PathUtilities.cpp | 29 ----------------------------- src/lib/common/PathUtilities.h | 1 - 7 files changed, 24 insertions(+), 50 deletions(-) diff --git a/src/lib/barrier/App.cpp b/src/lib/barrier/App.cpp index f0aea6a5..dd0e6197 100644 --- a/src/lib/barrier/App.cpp +++ b/src/lib/barrier/App.cpp @@ -164,7 +164,7 @@ App::initApp(int argc, const char** argv) // parse command line parseArgs(argc, argv); - DataDirectories::profile(argsBase().m_profileDirectory); + DataDirectories::profile(argsBase().m_profileDirectory.u8string()); // set log filter if (!CLOG->setFilter(argsBase().m_logFilter)) { diff --git a/src/lib/barrier/ArgParser.cpp b/src/lib/barrier/ArgParser.cpp index 4c57e798..08395d86 100644 --- a/src/lib/barrier/ArgParser.cpp +++ b/src/lib/barrier/ArgParser.cpp @@ -288,10 +288,10 @@ ArgParser::parseGenericArgs(int argc, const char* const* argv, int& i) argsBase().m_enableCrypto = false; } else if (isArg(i, argc, argv, NULL, "--profile-dir", 1)) { - argsBase().m_profileDirectory = argv[++i]; + argsBase().m_profileDirectory = barrier::fs::u8path(argv[++i]); } else if (isArg(i, argc, argv, NULL, "--plugin-dir", 1)) { - argsBase().m_pluginDirectory = argv[++i]; + argsBase().m_pluginDirectory = barrier::fs::u8path(argv[++i]); } else { // option not supported here diff --git a/src/lib/barrier/ArgsBase.cpp b/src/lib/barrier/ArgsBase.cpp index b392339a..e3e38031 100644 --- a/src/lib/barrier/ArgsBase.cpp +++ b/src/lib/barrier/ArgsBase.cpp @@ -43,7 +43,7 @@ m_dropTarget(""), m_shouldExit(false), m_barrierAddress(), m_enableCrypto(true), -m_profileDirectory(""), +m_profileDirectory(), m_pluginDirectory("") { } diff --git a/src/lib/barrier/ArgsBase.h b/src/lib/barrier/ArgsBase.h index ad442dc9..cdb50928 100644 --- a/src/lib/barrier/ArgsBase.h +++ b/src/lib/barrier/ArgsBase.h @@ -19,6 +19,7 @@ #pragma once #include "base/String.h" +#include "io/filesystem.h" class ArgsBase { public: @@ -50,6 +51,6 @@ public: bool m_shouldExit; String m_barrierAddress; bool m_enableCrypto; - String m_profileDirectory; - String m_pluginDirectory; + barrier::fs::path m_profileDirectory; + barrier::fs::path m_pluginDirectory; }; diff --git a/src/lib/barrier/ServerApp.cpp b/src/lib/barrier/ServerApp.cpp index 599bde70..1e76b58a 100644 --- a/src/lib/barrier/ServerApp.cpp +++ b/src/lib/barrier/ServerApp.cpp @@ -40,7 +40,6 @@ #include "base/TMethodEventJob.h" #include "common/Version.h" #include "common/DataDirectories.h" -#include "common/PathUtilities.h" #if SYSAPI_WIN32 #include "arch/win32/ArchMiscWindows.h" @@ -129,11 +128,15 @@ ServerApp::help() #endif // refer to custom profile directory even if not saved yet - String profilePath = argsBase().m_profileDirectory; - if (profilePath.empty()) { - profilePath = DataDirectories::profile(); + barrier::fs::path profile_path = argsBase().m_profileDirectory; + if (profile_path.empty()) { + profile_path = barrier::fs::u8path(DataDirectories::profile()); } + auto usr_config_path = (profile_path / barrier::fs::u8path(USR_CONFIG_NAME)).u8string(); + auto sys_config_path = (barrier::fs::u8path(DataDirectories::systemconfig()) / + barrier::fs::u8path(SYS_CONFIG_NAME)).u8string(); + std::ostringstream buffer; buffer << "Start the barrier server component.\n" << "\n" @@ -156,8 +159,8 @@ ServerApp::help() << "\n" << "If no configuration file pathname is provided then the first of the\n" << "following to load successfully sets the configuration:\n" - << " " << PathUtilities::concat(profilePath, USR_CONFIG_NAME) << "\n" - << " " << PathUtilities::concat(DataDirectories::systemconfig(), SYS_CONFIG_NAME) << "\n"; + << " " << usr_config_path << "\n" + << " " << sys_config_path << "\n"; LOG((CLOG_PRINT "%s", buffer.str().c_str())); } @@ -194,25 +197,25 @@ ServerApp::loadConfig() // load the default configuration if no explicit file given else { - String path = DataDirectories::profile(); + auto path = barrier::fs::u8path(DataDirectories::profile()); if (!path.empty()) { // complete path - path = PathUtilities::concat(path, USR_CONFIG_NAME); + path /= barrier::fs::u8path(USR_CONFIG_NAME); // now try loading the user's configuration - if (loadConfig(path)) { + if (loadConfig(path.u8string())) { loaded = true; - args().m_configFile = path; + args().m_configFile = path.u8string(); } } if (!loaded) { // try the system-wide config file - path = DataDirectories::systemconfig(); + path = barrier::fs::u8path(DataDirectories::systemconfig()); if (!path.empty()) { - path = PathUtilities::concat(path, SYS_CONFIG_NAME); - if (loadConfig(path)) { + path /= barrier::fs::u8path(SYS_CONFIG_NAME); + if (loadConfig(path.u8string())) { loaded = true; - args().m_configFile = path; + args().m_configFile = path.u8string(); } } } diff --git a/src/lib/common/PathUtilities.cpp b/src/lib/common/PathUtilities.cpp index a2ab38a2..8b273446 100644 --- a/src/lib/common/PathUtilities.cpp +++ b/src/lib/common/PathUtilities.cpp @@ -44,32 +44,3 @@ std::string PathUtilities::basename(const std::string& path) return path.substr(path.find_last_of(Delimiters) + 1); } -std::string PathUtilities::concat(const std::string& left, const std::string& right) -{ - // although npos is usually (-1) we can't count on that so handle it explicitly - auto leftEnd = left.find_last_not_of(Delimiters); - if (leftEnd == std::string::npos) - leftEnd = 0; - else - ++leftEnd; - auto rightStart = right.find_first_not_of(Delimiters, 0); - if (rightStart == std::string::npos) { - // both left/right are empty - if (left.size() == 0 && right.size() == 0) - return ""; - // right is full of delims, left is okay - if (leftEnd > 0) - return left.substr(0, leftEnd); - // both left/right useless but at least one has delims - return std::string(1, DefaultDelimiter); - } - if (leftEnd == 0) { - // right is okay and not prefixed with delims, left is empty - if (left.size() == 0 && rightStart == 0) - return right.substr(rightStart); - // (right is okay and prefixed with delims) OR left is full of delims - return DefaultDelimiter + right.substr(rightStart); - } - // concatenation using both left and right - return left.substr(0, leftEnd) + DefaultDelimiter + right.substr(rightStart); -} diff --git a/src/lib/common/PathUtilities.h b/src/lib/common/PathUtilities.h index 30313243..ea12af63 100644 --- a/src/lib/common/PathUtilities.h +++ b/src/lib/common/PathUtilities.h @@ -23,5 +23,4 @@ class PathUtilities { public: static std::string basename(const std::string& path); - static std::string concat(const std::string& left, const std::string& right); }; From 677612d3429c8e37deeaea960584c7ac9b326def Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:29:48 +0200 Subject: [PATCH 065/113] lib/common: Replace PathUtilities::basename with barrier::fs equivalent --- src/lib/barrier/ArgParser.cpp | 10 +++++-- src/lib/barrier/ArgParser.h | 3 +++ src/lib/barrier/ClientApp.cpp | 3 +-- src/lib/barrier/ServerApp.cpp | 2 +- src/lib/common/PathUtilities.cpp | 46 -------------------------------- src/lib/common/PathUtilities.h | 26 ------------------ 6 files changed, 13 insertions(+), 77 deletions(-) delete mode 100644 src/lib/common/PathUtilities.cpp delete mode 100644 src/lib/common/PathUtilities.h diff --git a/src/lib/barrier/ArgParser.cpp b/src/lib/barrier/ArgParser.cpp index 08395d86..44e29491 100644 --- a/src/lib/barrier/ArgParser.cpp +++ b/src/lib/barrier/ArgParser.cpp @@ -24,7 +24,7 @@ #include "barrier/ArgsBase.h" #include "base/Log.h" #include "base/String.h" -#include "common/PathUtilities.h" +#include "io/filesystem.h" #ifdef WINAPI_MSWINDOWS #include @@ -487,7 +487,13 @@ void ArgParser::updateCommonArgs(const char* const* argv) { argsBase().m_name = ARCH->getHostName(); - argsBase().m_exename = PathUtilities::basename(argv[0]); + argsBase().m_exename = parse_exename(argv[0]); +} + +std::string ArgParser::parse_exename(const char* arg) +{ + // FIXME: we assume UTF-8 encoding, but on Windows this is not correct + return barrier::fs::u8path(arg).filename().u8string(); } bool diff --git a/src/lib/barrier/ArgParser.h b/src/lib/barrier/ArgParser.h index c8e9e68d..472d93a1 100644 --- a/src/lib/barrier/ArgParser.h +++ b/src/lib/barrier/ArgParser.h @@ -48,11 +48,14 @@ public: static String assembleCommand(std::vector& argsArray, String ignoreArg = "", int parametersRequired = 0); + static std::string parse_exename(const char* arg); + private: void updateCommonArgs(const char* const* argv); bool checkUnexpectedArgs(); static ArgsBase& argsBase() { return *m_argsBase; } + bool parseMSWindowsArg(ArgsBase& argsBase, const int& argc, const char* const* argv, int& i); bool parseCarbonArg(ArgsBase& argsBase, const int& argc, const char* const* argv, int& i); bool parseXWindowsArg(ArgsBase& argsBase, const int& argc, const char* const* argv, int& i); diff --git a/src/lib/barrier/ClientApp.cpp b/src/lib/barrier/ClientApp.cpp index ec687e1e..a466f30e 100644 --- a/src/lib/barrier/ClientApp.cpp +++ b/src/lib/barrier/ClientApp.cpp @@ -40,7 +40,6 @@ #include "base/TMethodJob.h" #include "base/Log.h" #include "common/Version.h" -#include "common/PathUtilities.h" #if WINAPI_MSWINDOWS #include "platform/MSWindowsScreen.h" @@ -522,7 +521,7 @@ ClientApp::runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc { // general initialization m_serverAddress = new NetworkAddress; - args().m_exename = PathUtilities::basename(argv[0]); + argsBase().m_exename = ArgParser::parse_exename(argv[0]); // install caller's output filter if (outputter != NULL) { diff --git a/src/lib/barrier/ServerApp.cpp b/src/lib/barrier/ServerApp.cpp index 1e76b58a..3ecfd912 100644 --- a/src/lib/barrier/ServerApp.cpp +++ b/src/lib/barrier/ServerApp.cpp @@ -835,7 +835,7 @@ ServerApp::runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc // general initialization m_barrierAddress = new NetworkAddress; args().m_config = new Config(m_events); - args().m_exename = PathUtilities::basename(argv[0]); + args().m_exename = ArgParser::parse_exename(argv[0]); // install caller's output filter if (outputter != NULL) { diff --git a/src/lib/common/PathUtilities.cpp b/src/lib/common/PathUtilities.cpp deleted file mode 100644 index 8b273446..00000000 --- a/src/lib/common/PathUtilities.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* -* barrier -- mouse and keyboard sharing utility -* Copyright (C) 2018 Debauchee Open Source Group -* -* This package is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* found in the file LICENSE that should have accompanied this file. -* -* This package 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 . -*/ - -/* - -These functions cover the vast majority of cases for different paths across -windows and unixes. They are not, however, fullproof and probably don't cover -fringe cases very well. The library below might be used as an alternative if -these implementations prove to be insufficient. As the library's readme states -it is simply a temporary band-aid until std::filesystem is integrated (C++17 -has it in std::experimental) and this class should also be treated as such. - -https://github.com/wjakob/filesystem/ - -*/ - -#include "PathUtilities.h" - -// keep the default platform delimiter as the first in the list -#ifdef _WIN32 -static const char *Delimiters = "\\/"; -#else -static const char *Delimiters = "/"; -#endif - -static const char DefaultDelimiter = Delimiters[0]; - -std::string PathUtilities::basename(const std::string& path) -{ - return path.substr(path.find_last_of(Delimiters) + 1); -} - diff --git a/src/lib/common/PathUtilities.h b/src/lib/common/PathUtilities.h deleted file mode 100644 index ea12af63..00000000 --- a/src/lib/common/PathUtilities.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -* barrier -- mouse and keyboard sharing utility -* Copyright (C) 2018 Debauchee Open Source Group -* -* This package is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* found in the file LICENSE that should have accompanied this file. -* -* This package 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 . -*/ - -#pragma once - -#include - -class PathUtilities -{ -public: - static std::string basename(const std::string& path); -}; From 298980fa863c0630cfbd4c42f84460fa36595d2f Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:29:49 +0200 Subject: [PATCH 066/113] lib/common: Move DataDirectories to barrier namespace --- src/gui/src/MainWindow.cpp | 6 +++--- src/gui/src/SslCertificate.cpp | 4 ++-- src/lib/barrier/App.cpp | 2 +- src/lib/barrier/ServerApp.cpp | 8 ++++---- src/lib/barrier/win32/DaemonApp.cpp | 2 +- src/lib/common/DataDirectories.h | 9 ++++++++- src/lib/common/DataDirectories_static.cpp | 5 ++++- src/lib/common/unix/DataDirectories.cpp | 4 ++++ src/lib/common/win32/DataDirectories.cpp | 4 ++++ src/lib/net/SecureListenSocket.cpp | 2 +- src/lib/net/SecureSocket.cpp | 2 +- src/lib/platform/MSWindowsHook.cpp | 2 +- 12 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index ccb5c196..55052efe 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -442,7 +442,7 @@ void MainWindow::checkFingerprint(const QString& line) barrier::string::from_hex(fingerprintRegex.cap(2).toStdString()) }; - auto db_path = DataDirectories::trusted_servers_ssl_fingerprints_path(); + auto db_path = barrier::DataDirectories::trusted_servers_ssl_fingerprints_path(); // We compare only SHA256 fingerprints, but show both SHA1 and SHA256 so that the users can // still verify fingerprints on old Barrier servers. This way the only time when we are exposed @@ -564,7 +564,7 @@ void MainWindow::startBarrier() // launched the process (e.g. when launched with elevation). setting the // profile dir on launch ensures it uses the same profile dir is used // no matter how its relaunched. - args << "--profile-dir" << QString::fromStdString("\"" + DataDirectories::profile() + "\""); + args << "--profile-dir" << QString::fromStdString("\"" + barrier::DataDirectories::profile() + "\""); #endif if ((barrierType() == barrierClient && !clientArgs(args, app)) @@ -1020,7 +1020,7 @@ void MainWindow::updateSSLFingerprint() return; } - auto local_path = DataDirectories::local_ssl_fingerprints_path(); + auto local_path = barrier::DataDirectories::local_ssl_fingerprints_path(); if (!QFile::exists(QString::fromStdString(local_path))) { return; } diff --git a/src/gui/src/SslCertificate.cpp b/src/gui/src/SslCertificate.cpp index 57fb5f1b..910e0a8d 100644 --- a/src/gui/src/SslCertificate.cpp +++ b/src/gui/src/SslCertificate.cpp @@ -38,7 +38,7 @@ static const char kSslDir[] = "SSL"; SslCertificate::SslCertificate(QObject *parent) : QObject(parent) { - m_ProfileDir = DataDirectories::profile(); + m_ProfileDir = barrier::DataDirectories::profile(); if (m_ProfileDir.empty()) { emit error(tr("Failed to get profile directory.")); } @@ -73,7 +73,7 @@ void SslCertificate::generateCertificate() void SslCertificate::generateFingerprint(const std::string& cert_path) { try { - auto local_path = DataDirectories::local_ssl_fingerprints_path(); + auto local_path = barrier::DataDirectories::local_ssl_fingerprints_path(); barrier::FingerprintDatabase db; db.add_trusted(barrier::get_pem_file_cert_fingerprint(cert_path, barrier::FingerprintType::SHA1)); diff --git a/src/lib/barrier/App.cpp b/src/lib/barrier/App.cpp index dd0e6197..9216470a 100644 --- a/src/lib/barrier/App.cpp +++ b/src/lib/barrier/App.cpp @@ -164,7 +164,7 @@ App::initApp(int argc, const char** argv) // parse command line parseArgs(argc, argv); - DataDirectories::profile(argsBase().m_profileDirectory.u8string()); + barrier::DataDirectories::profile(argsBase().m_profileDirectory.u8string()); // set log filter if (!CLOG->setFilter(argsBase().m_logFilter)) { diff --git a/src/lib/barrier/ServerApp.cpp b/src/lib/barrier/ServerApp.cpp index 3ecfd912..d11f960e 100644 --- a/src/lib/barrier/ServerApp.cpp +++ b/src/lib/barrier/ServerApp.cpp @@ -130,11 +130,11 @@ ServerApp::help() // refer to custom profile directory even if not saved yet barrier::fs::path profile_path = argsBase().m_profileDirectory; if (profile_path.empty()) { - profile_path = barrier::fs::u8path(DataDirectories::profile()); + profile_path = barrier::fs::u8path(barrier::DataDirectories::profile()); } auto usr_config_path = (profile_path / barrier::fs::u8path(USR_CONFIG_NAME)).u8string(); - auto sys_config_path = (barrier::fs::u8path(DataDirectories::systemconfig()) / + auto sys_config_path = (barrier::fs::u8path(barrier::DataDirectories::systemconfig()) / barrier::fs::u8path(SYS_CONFIG_NAME)).u8string(); std::ostringstream buffer; @@ -197,7 +197,7 @@ ServerApp::loadConfig() // load the default configuration if no explicit file given else { - auto path = barrier::fs::u8path(DataDirectories::profile()); + auto path = barrier::fs::u8path(barrier::DataDirectories::profile()); if (!path.empty()) { // complete path path /= barrier::fs::u8path(USR_CONFIG_NAME); @@ -210,7 +210,7 @@ ServerApp::loadConfig() } if (!loaded) { // try the system-wide config file - path = barrier::fs::u8path(DataDirectories::systemconfig()); + path = barrier::fs::u8path(barrier::DataDirectories::systemconfig()); if (!path.empty()) { path /= barrier::fs::u8path(SYS_CONFIG_NAME); if (loadConfig(path.u8string())) { diff --git a/src/lib/barrier/win32/DaemonApp.cpp b/src/lib/barrier/win32/DaemonApp.cpp index 88e6b4ef..a3638d86 100644 --- a/src/lib/barrier/win32/DaemonApp.cpp +++ b/src/lib/barrier/win32/DaemonApp.cpp @@ -245,7 +245,7 @@ DaemonApp::logFilename() { string logFilename = ARCH->setting("LogFilename"); if (logFilename.empty()) - logFilename = DataDirectories::global() + "\\" + LOG_FILENAME; + logFilename = barrier::DataDirectories::global() + "\\" + LOG_FILENAME; MSWindowsUtil::createDirectory(logFilename, true); return logFilename; } diff --git a/src/lib/common/DataDirectories.h b/src/lib/common/DataDirectories.h index 4489ac24..5b7b0f51 100644 --- a/src/lib/common/DataDirectories.h +++ b/src/lib/common/DataDirectories.h @@ -15,10 +15,13 @@ * along with this program. If not, see . */ -#pragma once +#ifndef BARRIER_LIB_COMMON_DATA_DIRECTORIES_H +#define BARRIER_LIB_COMMON_DATA_DIRECTORIES_H #include +namespace barrier { + class DataDirectories { public: @@ -40,3 +43,7 @@ private: static std::string _global; static std::string _systemconfig; }; + +} // namespace barrier + +#endif diff --git a/src/lib/common/DataDirectories_static.cpp b/src/lib/common/DataDirectories_static.cpp index 5e28e055..5c3615eb 100644 --- a/src/lib/common/DataDirectories_static.cpp +++ b/src/lib/common/DataDirectories_static.cpp @@ -17,7 +17,8 @@ #include "DataDirectories.h" -// static member +namespace barrier { + std::string DataDirectories::_profile; std::string DataDirectories::_global; std::string DataDirectories::_systemconfig; @@ -46,3 +47,5 @@ std::string DataDirectories::trusted_clients_ssl_fingerprints_path() { return ssl_fingerprints_path() + "/" + kFingerprintsTrustedClientsFilename; } + +} // namespace barrier diff --git a/src/lib/common/unix/DataDirectories.cpp b/src/lib/common/unix/DataDirectories.cpp index 608db05c..ee4947c6 100644 --- a/src/lib/common/unix/DataDirectories.cpp +++ b/src/lib/common/unix/DataDirectories.cpp @@ -22,6 +22,8 @@ #include // getpwuid(_r) #include // getpwuid(_r) +namespace barrier { + const std::string ProfileSubdir = "/barrier"; static std::string pw_dir(struct passwd* pwentp) @@ -112,3 +114,5 @@ const std::string& DataDirectories::systemconfig(const std::string& path) _systemconfig = path; return _systemconfig; } + +} // namespace barrier diff --git a/src/lib/common/win32/DataDirectories.cpp b/src/lib/common/win32/DataDirectories.cpp index 32bc2136..0eeb6a20 100644 --- a/src/lib/common/win32/DataDirectories.cpp +++ b/src/lib/common/win32/DataDirectories.cpp @@ -20,6 +20,8 @@ #include +namespace barrier { + std::string known_folder_path(const KNOWNFOLDERID& id) { std::string path; @@ -71,3 +73,5 @@ const std::string& DataDirectories::systemconfig(const std::string& path) _systemconfig = path; return _systemconfig; } + +} // namespace barrier diff --git a/src/lib/net/SecureListenSocket.cpp b/src/lib/net/SecureListenSocket.cpp index 2a9f84cb..bfaa4be0 100644 --- a/src/lib/net/SecureListenSocket.cpp +++ b/src/lib/net/SecureListenSocket.cpp @@ -56,7 +56,7 @@ SecureListenSocket::accept() } std::string certificateFilename = barrier::string::sprintf("%s/%s/%s", - DataDirectories::profile().c_str(), + barrier::DataDirectories::profile().c_str(), s_certificateDir, s_certificateFilename); diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 9ac674d6..1a190381 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -674,7 +674,7 @@ SecureSocket::verifyCertFingerprint() barrier::format_ssl_fingerprint(fingerprint_sha1.data).c_str(), barrier::format_ssl_fingerprint(fingerprint_sha256.data).c_str())); - auto fingerprint_db_path = DataDirectories::trusted_servers_ssl_fingerprints_path(); + auto fingerprint_db_path = barrier::DataDirectories::trusted_servers_ssl_fingerprints_path(); // Provide debug hint as to what file is being used to verify fingerprint trust LOG((CLOG_NOTE "fingerprint_db_path: %s", fingerprint_db_path.c_str())); diff --git a/src/lib/platform/MSWindowsHook.cpp b/src/lib/platform/MSWindowsHook.cpp index b10d5c63..fce9020f 100644 --- a/src/lib/platform/MSWindowsHook.cpp +++ b/src/lib/platform/MSWindowsHook.cpp @@ -574,7 +574,7 @@ MSWindowsHook::install() g_fakeServerInput = false; // setup immune keys - g_immuneKeysPath = DataDirectories::profile() + "\\ImmuneKeys.txt"; + g_immuneKeysPath = barrier::DataDirectories::profile() + "\\ImmuneKeys.txt"; g_immuneKeys = immune_keys_list(); LOG((CLOG_DEBUG "Found %u immune keys in %s", g_immuneKeys.size(), g_immuneKeysPath.c_str())); From a2ca7e29f5fdfa2e668f028412b7e716816f7517 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:29:50 +0200 Subject: [PATCH 067/113] lib/common: Switch data directories to fs::path --- src/gui/src/MainWindow.cpp | 4 +-- src/lib/barrier/App.cpp | 2 +- src/lib/barrier/ServerApp.cpp | 8 +++--- src/lib/barrier/win32/DaemonApp.cpp | 2 +- src/lib/common/DataDirectories.h | 28 ++++++++++---------- src/lib/common/DataDirectories_static.cpp | 22 ++++++++-------- src/lib/common/unix/DataDirectories.cpp | 32 +++++++++++------------ src/lib/common/win32/DataDirectories.cpp | 22 ++++++++-------- src/lib/net/FingerprintDatabase.cpp | 4 +-- src/lib/net/FingerprintDatabase.h | 5 ++-- src/lib/net/SecureSocket.cpp | 6 ++--- src/lib/platform/MSWindowsHook.cpp | 2 +- 12 files changed, 68 insertions(+), 69 deletions(-) diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 55052efe..87f31eb2 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -564,7 +564,7 @@ void MainWindow::startBarrier() // launched the process (e.g. when launched with elevation). setting the // profile dir on launch ensures it uses the same profile dir is used // no matter how its relaunched. - args << "--profile-dir" << QString::fromStdString("\"" + barrier::DataDirectories::profile() + "\""); + args << "--profile-dir" << QString::fromStdString("\"" + barrier::DataDirectories::profile().u8string() + "\""); #endif if ((barrierType() == barrierClient && !clientArgs(args, app)) @@ -1021,7 +1021,7 @@ void MainWindow::updateSSLFingerprint() } auto local_path = barrier::DataDirectories::local_ssl_fingerprints_path(); - if (!QFile::exists(QString::fromStdString(local_path))) { + if (!barrier::fs::exists(local_path)) { return; } diff --git a/src/lib/barrier/App.cpp b/src/lib/barrier/App.cpp index 9216470a..67e58aba 100644 --- a/src/lib/barrier/App.cpp +++ b/src/lib/barrier/App.cpp @@ -164,7 +164,7 @@ App::initApp(int argc, const char** argv) // parse command line parseArgs(argc, argv); - barrier::DataDirectories::profile(argsBase().m_profileDirectory.u8string()); + barrier::DataDirectories::profile(argsBase().m_profileDirectory); // set log filter if (!CLOG->setFilter(argsBase().m_logFilter)) { diff --git a/src/lib/barrier/ServerApp.cpp b/src/lib/barrier/ServerApp.cpp index d11f960e..bbb35dd5 100644 --- a/src/lib/barrier/ServerApp.cpp +++ b/src/lib/barrier/ServerApp.cpp @@ -130,11 +130,11 @@ ServerApp::help() // refer to custom profile directory even if not saved yet barrier::fs::path profile_path = argsBase().m_profileDirectory; if (profile_path.empty()) { - profile_path = barrier::fs::u8path(barrier::DataDirectories::profile()); + profile_path = barrier::DataDirectories::profile(); } auto usr_config_path = (profile_path / barrier::fs::u8path(USR_CONFIG_NAME)).u8string(); - auto sys_config_path = (barrier::fs::u8path(barrier::DataDirectories::systemconfig()) / + auto sys_config_path = (barrier::DataDirectories::systemconfig() / barrier::fs::u8path(SYS_CONFIG_NAME)).u8string(); std::ostringstream buffer; @@ -197,7 +197,7 @@ ServerApp::loadConfig() // load the default configuration if no explicit file given else { - auto path = barrier::fs::u8path(barrier::DataDirectories::profile()); + auto path = barrier::DataDirectories::profile(); if (!path.empty()) { // complete path path /= barrier::fs::u8path(USR_CONFIG_NAME); @@ -210,7 +210,7 @@ ServerApp::loadConfig() } if (!loaded) { // try the system-wide config file - path = barrier::fs::u8path(barrier::DataDirectories::systemconfig()); + path = barrier::DataDirectories::systemconfig(); if (!path.empty()) { path /= barrier::fs::u8path(SYS_CONFIG_NAME); if (loadConfig(path.u8string())) { diff --git a/src/lib/barrier/win32/DaemonApp.cpp b/src/lib/barrier/win32/DaemonApp.cpp index a3638d86..6ea6a4fa 100644 --- a/src/lib/barrier/win32/DaemonApp.cpp +++ b/src/lib/barrier/win32/DaemonApp.cpp @@ -245,7 +245,7 @@ DaemonApp::logFilename() { string logFilename = ARCH->setting("LogFilename"); if (logFilename.empty()) - logFilename = barrier::DataDirectories::global() + "\\" + LOG_FILENAME; + logFilename = (barrier::DataDirectories::global() / LOG_FILENAME).u8string(); MSWindowsUtil::createDirectory(logFilename, true); return logFilename; } diff --git a/src/lib/common/DataDirectories.h b/src/lib/common/DataDirectories.h index 5b7b0f51..bb264480 100644 --- a/src/lib/common/DataDirectories.h +++ b/src/lib/common/DataDirectories.h @@ -18,30 +18,30 @@ #ifndef BARRIER_LIB_COMMON_DATA_DIRECTORIES_H #define BARRIER_LIB_COMMON_DATA_DIRECTORIES_H -#include +#include "io/filesystem.h" namespace barrier { class DataDirectories { public: - static const std::string& profile(); - static const std::string& profile(const std::string& path); + static const fs::path& profile(); + static const fs::path& profile(const fs::path& path); - static const std::string& global(); - static const std::string& global(const std::string& path); + static const fs::path& global(); + static const fs::path& global(const fs::path& path); - static const std::string& systemconfig(); - static const std::string& systemconfig(const std::string& path); + static const fs::path& systemconfig(); + static const fs::path& systemconfig(const fs::path& path); - static std::string ssl_fingerprints_path(); - static std::string local_ssl_fingerprints_path(); - static std::string trusted_servers_ssl_fingerprints_path(); - static std::string trusted_clients_ssl_fingerprints_path(); + static fs::path ssl_fingerprints_path(); + static fs::path local_ssl_fingerprints_path(); + static fs::path trusted_servers_ssl_fingerprints_path(); + static fs::path trusted_clients_ssl_fingerprints_path(); private: - static std::string _profile; - static std::string _global; - static std::string _systemconfig; + static fs::path _profile; + static fs::path _global; + static fs::path _systemconfig; }; } // namespace barrier diff --git a/src/lib/common/DataDirectories_static.cpp b/src/lib/common/DataDirectories_static.cpp index 5c3615eb..40c0ebf7 100644 --- a/src/lib/common/DataDirectories_static.cpp +++ b/src/lib/common/DataDirectories_static.cpp @@ -19,33 +19,33 @@ namespace barrier { -std::string DataDirectories::_profile; -std::string DataDirectories::_global; -std::string DataDirectories::_systemconfig; +fs::path DataDirectories::_profile; +fs::path DataDirectories::_global; +fs::path DataDirectories::_systemconfig; static const char kFingerprintsDirName[] = "SSL/Fingerprints"; static const char kFingerprintsLocalFilename[] = "Local.txt"; static const char kFingerprintsTrustedServersFilename[] = "TrustedServers.txt"; static const char kFingerprintsTrustedClientsFilename[] = "TrustedClients.txt"; -std::string DataDirectories::ssl_fingerprints_path() +fs::path DataDirectories::ssl_fingerprints_path() { - return profile() + "/" + kFingerprintsDirName; + return profile() / kFingerprintsDirName; } -std::string DataDirectories::local_ssl_fingerprints_path() +fs::path DataDirectories::local_ssl_fingerprints_path() { - return ssl_fingerprints_path() + "/" + kFingerprintsLocalFilename; + return ssl_fingerprints_path() / kFingerprintsLocalFilename; } -std::string DataDirectories::trusted_servers_ssl_fingerprints_path() +fs::path DataDirectories::trusted_servers_ssl_fingerprints_path() { - return ssl_fingerprints_path() + "/" + kFingerprintsTrustedServersFilename; + return ssl_fingerprints_path() / kFingerprintsTrustedServersFilename; } -std::string DataDirectories::trusted_clients_ssl_fingerprints_path() +fs::path DataDirectories::trusted_clients_ssl_fingerprints_path() { - return ssl_fingerprints_path() + "/" + kFingerprintsTrustedClientsFilename; + return ssl_fingerprints_path() / kFingerprintsTrustedClientsFilename; } } // namespace barrier diff --git a/src/lib/common/unix/DataDirectories.cpp b/src/lib/common/unix/DataDirectories.cpp index ee4947c6..cf3ca243 100644 --- a/src/lib/common/unix/DataDirectories.cpp +++ b/src/lib/common/unix/DataDirectories.cpp @@ -24,8 +24,6 @@ namespace barrier { -const std::string ProfileSubdir = "/barrier"; - static std::string pw_dir(struct passwd* pwentp) { if (pwentp != NULL && pwentp->pw_dir != NULL) @@ -35,7 +33,7 @@ static std::string pw_dir(struct passwd* pwentp) #ifdef HAVE_GETPWUID_R -static std::string unix_home() +static fs::path unix_home() { long size = -1; #if defined(_SC_GETPW_R_SIZE_MAX) @@ -48,47 +46,47 @@ static std::string unix_home() struct passwd* pwentp; std::string buffer(size, 0); getpwuid_r(getuid(), &pwent, &buffer[0], size, &pwentp); - return pw_dir(pwentp); + return fs::u8path(pw_dir(pwentp)); } #else // not HAVE_GETPWUID_R -static std::string unix_home() +static fs::path unix_home() { - return pw_dir(getpwuid(getuid())); + return fs::u8path(pw_dir(getpwuid(getuid()))); } #endif // HAVE_GETPWUID_R -static std::string profile_basedir() +static fs::path profile_basedir() { #ifdef WINAPI_XWINDOWS // linux/bsd adheres to freedesktop standards // https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html const char* dir = std::getenv("XDG_DATA_HOME"); if (dir != NULL) - return dir; - return unix_home() + "/.local/share"; + return fs::u8path(dir); + return unix_home() / ".local/share"; #else // macos has its own standards // https://developer.apple.com/library/content/documentation/General/Conceptual/MOSXAppProgrammingGuide/AppRuntime/AppRuntime.html - return unix_home() + "/Library/Application Support"; + return unix_home() / "Library/Application Support"; #endif } -const std::string& DataDirectories::profile() +const fs::path& DataDirectories::profile() { if (_profile.empty()) - _profile = profile_basedir() + ProfileSubdir; + _profile = profile_basedir() / "barrier"; return _profile; } -const std::string& DataDirectories::profile(const std::string& path) +const fs::path& DataDirectories::profile(const fs::path& path) { _profile = path; return _profile; } -const std::string& DataDirectories::global() +const fs::path& DataDirectories::global() { if (_global.empty()) // TODO: where on a unix system should public/global shared data go? @@ -96,20 +94,20 @@ const std::string& DataDirectories::global() _global = "/tmp"; return _global; } -const std::string& DataDirectories::global(const std::string& path) +const fs::path& DataDirectories::global(const fs::path& path) { _global = path; return _global; } -const std::string& DataDirectories::systemconfig() +const fs::path& DataDirectories::systemconfig() { if (_systemconfig.empty()) _systemconfig = "/etc"; return _systemconfig; } -const std::string& DataDirectories::systemconfig(const std::string& path) +const fs::path& DataDirectories::systemconfig(const fs::path& path) { _systemconfig = path; return _systemconfig; diff --git a/src/lib/common/win32/DataDirectories.cpp b/src/lib/common/win32/DataDirectories.cpp index 0eeb6a20..31a428fd 100644 --- a/src/lib/common/win32/DataDirectories.cpp +++ b/src/lib/common/win32/DataDirectories.cpp @@ -22,43 +22,43 @@ namespace barrier { -std::string known_folder_path(const KNOWNFOLDERID& id) +fs::path known_folder_path(const KNOWNFOLDERID& id) { - std::string path; + fs::path path; WCHAR* buffer; HRESULT result = SHGetKnownFolderPath(id, 0, NULL, &buffer); if (result == S_OK) { - path = win_wchar_to_utf8(buffer); + path = fs::path(std::wstring(buffer)); CoTaskMemFree(buffer); } return path; } -const std::string& DataDirectories::profile() +const fs::path& DataDirectories::profile() { if (_profile.empty()) - _profile = known_folder_path(FOLDERID_LocalAppData) + "\\Barrier"; + _profile = known_folder_path(FOLDERID_LocalAppData) / "Barrier"; return _profile; } -const std::string& DataDirectories::profile(const std::string& path) +const fs::path& DataDirectories::profile(const fs::path& path) { _profile = path; return _profile; } -const std::string& DataDirectories::global() +const fs::path& DataDirectories::global() { if (_global.empty()) - _global = known_folder_path(FOLDERID_ProgramData) + "\\Barrier"; + _global = known_folder_path(FOLDERID_ProgramData) / "Barrier"; return _global; } -const std::string& DataDirectories::global(const std::string& path) +const fs::path& DataDirectories::global(const fs::path& path) { _global = path; return _global; } -const std::string& DataDirectories::systemconfig() +const fs::path& DataDirectories::systemconfig() { // systemconfig() is a special case in that it will track the current value // of global() unless and until it is explicitly set otherwise @@ -68,7 +68,7 @@ const std::string& DataDirectories::systemconfig() return _systemconfig; } -const std::string& DataDirectories::systemconfig(const std::string& path) +const fs::path& DataDirectories::systemconfig(const fs::path& path) { _systemconfig = path; return _systemconfig; diff --git a/src/lib/net/FingerprintDatabase.cpp b/src/lib/net/FingerprintDatabase.cpp index 020f19b6..def0de91 100644 --- a/src/lib/net/FingerprintDatabase.cpp +++ b/src/lib/net/FingerprintDatabase.cpp @@ -23,14 +23,14 @@ namespace barrier { -void FingerprintDatabase::read(const std::string& path) +void FingerprintDatabase::read(const fs::path& path) { std::ifstream file; open_utf8_path(file, path, std::ios_base::in); read_stream(file); } -void FingerprintDatabase::write(const std::string& path) +void FingerprintDatabase::write(const fs::path& path) { std::ofstream file; open_utf8_path(file, path, std::ios_base::out); diff --git a/src/lib/net/FingerprintDatabase.h b/src/lib/net/FingerprintDatabase.h index 4a17696e..49272650 100644 --- a/src/lib/net/FingerprintDatabase.h +++ b/src/lib/net/FingerprintDatabase.h @@ -19,6 +19,7 @@ #define BARRIER_LIB_NET_FINGERPRINT_DATABASE_H #include "FingerprintData.h" +#include "io/filesystem.h" #include #include #include @@ -27,8 +28,8 @@ namespace barrier { class FingerprintDatabase { public: - void read(const std::string& path); - void write(const std::string& path); + void read(const fs::path& path); + void write(const fs::path& path); void read_stream(std::istream& stream); void write_stream(std::ostream& stream); diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 1a190381..b70b98cf 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -677,17 +677,17 @@ SecureSocket::verifyCertFingerprint() auto fingerprint_db_path = barrier::DataDirectories::trusted_servers_ssl_fingerprints_path(); // Provide debug hint as to what file is being used to verify fingerprint trust - LOG((CLOG_NOTE "fingerprint_db_path: %s", fingerprint_db_path.c_str())); + LOG((CLOG_NOTE "fingerprint_db_path: %s", fingerprint_db_path.u8string().c_str())); barrier::FingerprintDatabase db; db.read(fingerprint_db_path); if (!db.fingerprints().empty()) { LOG((CLOG_NOTE "Read %d fingerprints from: %s", db.fingerprints().size(), - fingerprint_db_path.c_str())); + fingerprint_db_path.u8string().c_str())); } else { LOG((CLOG_NOTE "Could not read fingerprints from: %s", - fingerprint_db_path.c_str())); + fingerprint_db_path.u8string().c_str())); } if (db.is_trusted(fingerprint_sha256)) { diff --git a/src/lib/platform/MSWindowsHook.cpp b/src/lib/platform/MSWindowsHook.cpp index fce9020f..3230d24c 100644 --- a/src/lib/platform/MSWindowsHook.cpp +++ b/src/lib/platform/MSWindowsHook.cpp @@ -574,7 +574,7 @@ MSWindowsHook::install() g_fakeServerInput = false; // setup immune keys - g_immuneKeysPath = barrier::DataDirectories::profile() + "\\ImmuneKeys.txt"; + g_immuneKeysPath = (barrier::DataDirectories::profile() / "ImmuneKeys.txt").u8string(); g_immuneKeys = immune_keys_list(); LOG((CLOG_DEBUG "Found %u immune keys in %s", g_immuneKeys.size(), g_immuneKeysPath.c_str())); From 220f9e8274e7dc5aa96ada210f030794fe262392 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:29:51 +0200 Subject: [PATCH 068/113] lib/common: Remove unused file --- src/lib/common/MacOSXPrecomp.h | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 src/lib/common/MacOSXPrecomp.h diff --git a/src/lib/common/MacOSXPrecomp.h b/src/lib/common/MacOSXPrecomp.h deleted file mode 100644 index 53ecc83c..00000000 --- a/src/lib/common/MacOSXPrecomp.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * barrier -- mouse and keyboard sharing utility - * Copyright (C) 2012-2016 Symless Ltd. - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file LICENSE that should have accompanied this file. - * - * This package 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 . - */ - - // -// Prefix header for all source files of the 'deleteme' target in the 'deleteme' project. -// - -#include From d033ffa3d8b04fa103b8020c0a2927d5f7d5d16f Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:29:52 +0200 Subject: [PATCH 069/113] lib/net: Use fs::is_regular_file() to check for path existence --- src/lib/net/SecureSocket.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index b70b98cf..39b40fd7 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -334,11 +334,7 @@ bool SecureSocket::loadCertificates(const std::string& filename) return false; } else { - std::ifstream file(filename.c_str()); - bool exist = file.good(); - file.close(); - - if (!exist) { + if (!barrier::fs::is_regular_file(barrier::fs::u8path(filename))) { showError("ssl certificate doesn't exist: " + filename); return false; } From b76b332f2f40ed46c639ec178965743fc0ef0d03 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:29:53 +0200 Subject: [PATCH 070/113] lib/common: Move SSL certificate path definition to common location --- src/lib/common/DataDirectories.h | 1 + src/lib/common/DataDirectories_static.cpp | 5 +++++ src/lib/net/SecureListenSocket.cpp | 14 +------------- src/lib/net/SecureSocket.cpp | 18 +++++++++--------- src/lib/net/SecureSocket.h | 3 ++- 5 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/lib/common/DataDirectories.h b/src/lib/common/DataDirectories.h index bb264480..45502116 100644 --- a/src/lib/common/DataDirectories.h +++ b/src/lib/common/DataDirectories.h @@ -38,6 +38,7 @@ public: static fs::path local_ssl_fingerprints_path(); static fs::path trusted_servers_ssl_fingerprints_path(); static fs::path trusted_clients_ssl_fingerprints_path(); + static fs::path ssl_certificate_path(); private: static fs::path _profile; static fs::path _global; diff --git a/src/lib/common/DataDirectories_static.cpp b/src/lib/common/DataDirectories_static.cpp index 40c0ebf7..47f88e70 100644 --- a/src/lib/common/DataDirectories_static.cpp +++ b/src/lib/common/DataDirectories_static.cpp @@ -48,4 +48,9 @@ fs::path DataDirectories::trusted_clients_ssl_fingerprints_path() return ssl_fingerprints_path() / kFingerprintsTrustedClientsFilename; } +fs::path DataDirectories::ssl_certificate_path() +{ + return profile() / "SSL" / "Barrier.pem"; +} + } // namespace barrier diff --git a/src/lib/net/SecureListenSocket.cpp b/src/lib/net/SecureListenSocket.cpp index bfaa4be0..71e09ce5 100644 --- a/src/lib/net/SecureListenSocket.cpp +++ b/src/lib/net/SecureListenSocket.cpp @@ -25,13 +25,6 @@ #include "common/DataDirectories.h" #include "base/String.h" -static const char s_certificateDir[] = { "SSL" }; -static const char s_certificateFilename[] = { "Barrier.pem" }; - -// -// SecureListenSocket -// - SecureListenSocket::SecureListenSocket( IEventQueue* events, SocketMultiplexer* socketMultiplexer, @@ -55,12 +48,7 @@ SecureListenSocket::accept() setListeningJob(); } - std::string certificateFilename = barrier::string::sprintf("%s/%s/%s", - barrier::DataDirectories::profile().c_str(), - s_certificateDir, - s_certificateFilename); - - bool loaded = socket->loadCertificates(certificateFilename); + bool loaded = socket->load_certificates(barrier::DataDirectories::ssl_certificate_path()); if (!loaded) { delete socket; return NULL; diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 39b40fd7..6a658db1 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -327,35 +327,35 @@ SecureSocket::initSsl(bool server) initContext(server); } -bool SecureSocket::loadCertificates(const std::string& filename) +bool SecureSocket::load_certificates(const barrier::fs::path& path) { - if (filename.empty()) { + if (path.empty()) { showError("ssl certificate is not specified"); return false; } else { - if (!barrier::fs::is_regular_file(barrier::fs::u8path(filename))) { - showError("ssl certificate doesn't exist: " + filename); + if (!barrier::fs::is_regular_file(path)) { + showError("ssl certificate doesn't exist: " + path.u8string()); return false; } } int r = 0; - r = SSL_CTX_use_certificate_file(m_ssl->m_context, filename.c_str(), SSL_FILETYPE_PEM); + r = SSL_CTX_use_certificate_file(m_ssl->m_context, path.u8string().c_str(), SSL_FILETYPE_PEM); if (r <= 0) { - showError("could not use ssl certificate: " + filename); + showError("could not use ssl certificate: " + path.u8string()); return false; } - r = SSL_CTX_use_PrivateKey_file(m_ssl->m_context, filename.c_str(), SSL_FILETYPE_PEM); + r = SSL_CTX_use_PrivateKey_file(m_ssl->m_context, path.u8string().c_str(), SSL_FILETYPE_PEM); if (r <= 0) { - showError("could not use ssl private key: " + filename); + showError("could not use ssl private key: " + path.u8string()); return false; } r = SSL_CTX_check_private_key(m_ssl->m_context); if (!r) { - showError("could not verify ssl private key: " + filename); + showError("could not verify ssl private key: " + path.u8string()); return false; } diff --git a/src/lib/net/SecureSocket.h b/src/lib/net/SecureSocket.h index 24653b6f..6e355008 100644 --- a/src/lib/net/SecureSocket.h +++ b/src/lib/net/SecureSocket.h @@ -19,6 +19,7 @@ #include "net/TCPSocket.h" #include "net/XSocket.h" +#include "io/filesystem.h" class IEventQueue; class SocketMultiplexer; @@ -55,7 +56,7 @@ public: EJobResult doRead() override; EJobResult doWrite() override; void initSsl(bool server); - bool loadCertificates(const std::string& filename); + bool load_certificates(const barrier::fs::path& path); private: // SSL From 0f3afed6640cc545b4db09b6318617bd5cc4facd Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:29:54 +0200 Subject: [PATCH 071/113] gui: Switch SSL certificate handler to barrier::fs paths --- src/gui/src/SslCertificate.cpp | 47 ++++++++++------------------------ src/gui/src/SslCertificate.h | 11 +++----- 2 files changed, 17 insertions(+), 41 deletions(-) diff --git a/src/gui/src/SslCertificate.cpp b/src/gui/src/SslCertificate.cpp index 910e0a8d..26f3b3ee 100644 --- a/src/gui/src/SslCertificate.cpp +++ b/src/gui/src/SslCertificate.cpp @@ -22,41 +22,32 @@ #include "net/FingerprintDatabase.h" #include "net/SecureUtils.h" -#include -#include -#include - #include #include #include #include #include -static const char kCertificateFilename[] = "Barrier.pem"; -static const char kSslDir[] = "SSL"; - SslCertificate::SslCertificate(QObject *parent) : QObject(parent) { - m_ProfileDir = barrier::DataDirectories::profile(); - if (m_ProfileDir.empty()) { + if (barrier::DataDirectories::profile().empty()) { emit error(tr("Failed to get profile directory.")); } } void SslCertificate::generateCertificate() { - auto cert_path = getCertificatePath(); - - QFile file(QString::fromStdString(cert_path)); - if (!file.exists() || !isCertificateValid(cert_path)) { - QDir sslDir(QString::fromStdString(getCertificateDirectory())); - if (!sslDir.exists()) { - sslDir.mkpath("."); - } + auto cert_path = barrier::DataDirectories::ssl_certificate_path(); + if (!barrier::fs::exists(cert_path) || !is_certificate_valid(cert_path)) { try { - barrier::generate_pem_self_signed_cert(cert_path); + auto cert_dir = cert_path.parent_path(); + if (!barrier::fs::exists(cert_dir)) { + barrier::fs::create_directories(cert_dir); + } + + barrier::generate_pem_self_signed_cert(cert_path.u8string()); } catch (const std::exception& e) { emit error(QString("SSL tool failed: %1").arg(e.what())); return; @@ -65,19 +56,19 @@ void SslCertificate::generateCertificate() emit info(tr("SSL certificate generated.")); } - generateFingerprint(cert_path); + generate_fingerprint(cert_path); emit generateFinished(); } -void SslCertificate::generateFingerprint(const std::string& cert_path) +void SslCertificate::generate_fingerprint(const barrier::fs::path& cert_path) { try { auto local_path = barrier::DataDirectories::local_ssl_fingerprints_path(); barrier::FingerprintDatabase db; - db.add_trusted(barrier::get_pem_file_cert_fingerprint(cert_path, + db.add_trusted(barrier::get_pem_file_cert_fingerprint(cert_path.u8string(), barrier::FingerprintType::SHA1)); - db.add_trusted(barrier::get_pem_file_cert_fingerprint(cert_path, + db.add_trusted(barrier::get_pem_file_cert_fingerprint(cert_path.u8string(), barrier::FingerprintType::SHA256)); db.write(local_path); @@ -87,17 +78,7 @@ void SslCertificate::generateFingerprint(const std::string& cert_path) } } -std::string SslCertificate::getCertificatePath() -{ - return getCertificateDirectory() + QDir::separator().toLatin1() + kCertificateFilename; -} - -std::string SslCertificate::getCertificateDirectory() -{ - return m_ProfileDir + QDir::separator().toLatin1() + kSslDir; -} - -bool SslCertificate::isCertificateValid(const std::string& path) +bool SslCertificate::is_certificate_valid(const barrier::fs::path& path) { OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); diff --git a/src/gui/src/SslCertificate.h b/src/gui/src/SslCertificate.h index 7f77771a..eae7fd6c 100644 --- a/src/gui/src/SslCertificate.h +++ b/src/gui/src/SslCertificate.h @@ -19,6 +19,7 @@ #include #include +#include "io/filesystem.h" class SslCertificate : public QObject { @@ -36,13 +37,7 @@ signals: void generateFinished(); private: - std::pair runTool(const QStringList& args); - void generateFingerprint(const std::string& cert_path); + void generate_fingerprint(const barrier::fs::path& cert_path); - std::string getCertificatePath(); - std::string getCertificateDirectory(); - - bool isCertificateValid(const std::string& path); -private: - std::string m_ProfileDir; + bool is_certificate_valid(const barrier::fs::path& path); }; From f9c051fc8232ae44bc49538284a01f36820846b9 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:28:12 +0200 Subject: [PATCH 072/113] Use cmake --build to build on Windows --- clean_build.bat | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clean_build.bat b/clean_build.bat index 79fce047..6f042326 100644 --- a/clean_build.bat +++ b/clean_build.bat @@ -41,8 +41,7 @@ if ERRORLEVEL 1 goto failed cd build cmake -G "%cmake_gen%" -A x64 -D CMAKE_BUILD_TYPE=%B_BUILD_TYPE% -D CMAKE_PREFIX_PATH="%B_QT_FULLPATH%" -D DNSSD_LIB="%B_BONJOUR%\Lib\x64\dnssd.lib" -D QT_VERSION=%B_QT_VER% .. if ERRORLEVEL 1 goto failed -echo @msbuild barrier.sln /p:Platform="x64" /p:Configuration=%B_BUILD_TYPE% /m %B_BUILD_OPTIONS% > make.bat -call make.bat +cmake --build . --config %B_BUILD_TYPE% if ERRORLEVEL 1 goto failed if exist bin\Debug ( copy %B_QT_FULLPATH%\bin\Qt5Cored.dll bin\Debug\ > NUL From cb0480fe848242b6e282d956d8d49b1eb7b3318a Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:28:13 +0200 Subject: [PATCH 073/113] cmake: Silence tr1 deprecation warning on MSVC --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8653a2c8..86deb4b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -293,6 +293,7 @@ elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows") add_definitions ( /DSYSAPI_WIN32=1 /DWINAPI_MSWINDOWS=1 + /D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 # tr1 is used from gtest and gmock /DWIN32 /D_WINDOWS /D_CRT_SECURE_NO_WARNINGS From c0ce893711eb5e504e3bf6b376c84b4616d4241e Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:50:05 +0200 Subject: [PATCH 074/113] lib/net: Load client SSL certificates when connecting --- src/lib/net/SecureSocket.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 6a658db1..093dcb98 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -464,6 +464,8 @@ SecureSocket::secureConnect(int socket) { createSSL(); + load_certificates(barrier::DataDirectories::ssl_certificate_path()); + // attach the socket descriptor SSL_set_fd(m_ssl->m_ssl, socket); From 92ba6f61e69dcc88ef7cea4ed74bc42883f263ed Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:50:06 +0200 Subject: [PATCH 075/113] gui: Move SSL fingerprint labels out of server frame SSL fingerprints will be used to auth both server and client. --- src/gui/src/MainWindowBase.ui | 202 +++++++++++++++++----------------- 1 file changed, 101 insertions(+), 101 deletions(-) diff --git a/src/gui/src/MainWindowBase.ui b/src/gui/src/MainWindowBase.ui index 9f8d4896..88994cf9 100644 --- a/src/gui/src/MainWindowBase.ui +++ b/src/gui/src/MainWindowBase.ui @@ -55,107 +55,6 @@ - - - - - - - 0 - 0 - - - - SSL Fingerprint: - - - - - - - - - - Qt::PlainText - - - - - - - ... - - - Qt::DownArrow - - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - QLayout::SetMinimumSize - - - - - - Courier - - - - - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - - - - - SHA1 (deprecated, compare to old clients only): - - - - - - - - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - - - - - SHA256: - - - - - - - - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - - - - @@ -305,6 +204,107 @@ + + + + + + + 0 + 0 + + + + SSL Fingerprint: + + + + + + + + + + Qt::PlainText + + + + + + + ... + + + Qt::DownArrow + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + QLayout::SetMinimumSize + + + + + + Courier + + + + + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + SHA1 (deprecated, compare to old clients and servers only): + + + + + + + + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + SHA256: + + + + + + + + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + From 4d73ed9fddedba63b91935799c6f7ae22d9ea989 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:50:07 +0200 Subject: [PATCH 076/113] lib/net: Present client certificate when connecting to server --- doc/newsfragments/client-send-certificate.feature | 1 + src/lib/net/SecureSocket.cpp | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 doc/newsfragments/client-send-certificate.feature diff --git a/doc/newsfragments/client-send-certificate.feature b/doc/newsfragments/client-send-certificate.feature new file mode 100644 index 00000000..b5584290 --- /dev/null +++ b/doc/newsfragments/client-send-certificate.feature @@ -0,0 +1 @@ +Barrier client now sends certificate that the server can verify. diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 093dcb98..1004bb39 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -462,9 +462,13 @@ SecureSocket::secureAccept(int socket) int SecureSocket::secureConnect(int socket) { - createSSL(); + if (!load_certificates(barrier::DataDirectories::ssl_certificate_path())) { + LOG((CLOG_ERR "could not load client certificates")); + // FIXME: this is fatal error, but we current don't disconnect because whole logic in this + // function needs to be cleaned up + } - load_certificates(barrier::DataDirectories::ssl_certificate_path()); + createSSL(); // attach the socket descriptor SSL_set_fd(m_ssl->m_ssl, socket); From ed32e2e326fa6a28129a597b6cdc7d0b01122562 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:50:08 +0200 Subject: [PATCH 077/113] gui: Expand checkboxes in settings dialog through both grid columns --- src/gui/src/SettingsDialogBase.ui | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/gui/src/SettingsDialogBase.ui b/src/gui/src/SettingsDialogBase.ui index 719a84bc..144daf3c 100644 --- a/src/gui/src/SettingsDialogBase.ui +++ b/src/gui/src/SettingsDialogBase.ui @@ -142,6 +142,16 @@ Networking + + + + &Address: + + + m_pLineEditInterface + + + @@ -171,16 +181,6 @@ - - - - &Address: - - - m_pLineEditInterface - - - @@ -188,7 +188,7 @@ - + Enable &SSL From 8bc280e0dd6dd95952cecb4b810b9f034de53927 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:50:09 +0200 Subject: [PATCH 078/113] gui: Add configuration for requiring client certificates --- src/gui/src/AppConfig.cpp | 7 ++++ src/gui/src/AppConfig.h | 4 +++ src/gui/src/SettingsDialog.cpp | 2 ++ src/gui/src/SettingsDialogBase.ui | 55 +++++++++++++++++-------------- 4 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/gui/src/AppConfig.cpp b/src/gui/src/AppConfig.cpp index 63943267..894ce49a 100644 --- a/src/gui/src/AppConfig.cpp +++ b/src/gui/src/AppConfig.cpp @@ -158,6 +158,8 @@ void AppConfig::loadSettings() m_ElevateMode = static_cast(elevateMode.toInt()); m_AutoConfigPrompted = settings().value("autoConfigPrompted", false).toBool(); m_CryptoEnabled = settings().value("cryptoEnabled", true).toBool(); + // TODO: set default value of requireClientCertificate to true on Barrier 2.5.0 + m_RequireClientCertificate = settings().value("requireClientCertificate", false).toBool(); m_AutoHide = settings().value("autoHide", false).toBool(); m_AutoStart = settings().value("autoStart", false).toBool(); m_MinimizeToTray = settings().value("minimizeToTray", false).toBool(); @@ -181,6 +183,7 @@ void AppConfig::saveSettings() settings().setValue("elevateModeEnum", static_cast(m_ElevateMode)); settings().setValue("autoConfigPrompted", m_AutoConfigPrompted); settings().setValue("cryptoEnabled", m_CryptoEnabled); + settings().setValue("requireClientCertificate", m_RequireClientCertificate); settings().setValue("autoHide", m_AutoHide); settings().setValue("autoStart", m_AutoStart); settings().setValue("minimizeToTray", m_MinimizeToTray); @@ -225,6 +228,10 @@ void AppConfig::setCryptoEnabled(bool e) { m_CryptoEnabled = e; } bool AppConfig::getCryptoEnabled() const { return m_CryptoEnabled; } +void AppConfig::setRequireClientCertificate(bool e) { m_RequireClientCertificate = e; } + +bool AppConfig::getRequireClientCertificate() const { return m_RequireClientCertificate; } + void AppConfig::setAutoHide(bool b) { m_AutoHide = b; } bool AppConfig::getAutoHide() { return m_AutoHide; } diff --git a/src/gui/src/AppConfig.h b/src/gui/src/AppConfig.h index 124ee85f..0dabb182 100644 --- a/src/gui/src/AppConfig.h +++ b/src/gui/src/AppConfig.h @@ -91,6 +91,9 @@ class AppConfig: public QObject void setCryptoEnabled(bool e); bool getCryptoEnabled() const; + void setRequireClientCertificate(bool e); + bool getRequireClientCertificate() const; + void setAutoHide(bool b); bool getAutoHide(); @@ -132,6 +135,7 @@ protected: ElevateMode m_ElevateMode; bool m_AutoConfigPrompted; bool m_CryptoEnabled; + bool m_RequireClientCertificate = false; bool m_AutoHide; bool m_AutoStart; bool m_MinimizeToTray; diff --git a/src/gui/src/SettingsDialog.cpp b/src/gui/src/SettingsDialog.cpp index 1caeae5d..8d01c777 100644 --- a/src/gui/src/SettingsDialog.cpp +++ b/src/gui/src/SettingsDialog.cpp @@ -51,6 +51,7 @@ SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) : m_pCheckBoxAutoStart->setChecked(appConfig().getAutoStart()); m_pCheckBoxMinimizeToTray->setChecked(appConfig().getMinimizeToTray()); m_pCheckBoxEnableCrypto->setChecked(m_appConfig.getCryptoEnabled()); + checkbox_require_client_certificate->setChecked(m_appConfig.getRequireClientCertificate()); #if defined(Q_OS_WIN) m_pComboElevate->setCurrentIndex(static_cast(appConfig().elevateMode())); @@ -67,6 +68,7 @@ void SettingsDialog::accept() m_appConfig.setPort(m_pSpinBoxPort->value()); m_appConfig.setNetworkInterface(m_pLineEditInterface->text()); m_appConfig.setCryptoEnabled(m_pCheckBoxEnableCrypto->isChecked()); + m_appConfig.setRequireClientCertificate(checkbox_require_client_certificate->isChecked()); m_appConfig.setLogLevel(m_pComboLogLevel->currentIndex()); m_appConfig.setLogToFile(m_pCheckBoxLogToFile->isChecked()); m_appConfig.setLogFilename(m_pLineEditLogFilename->text()); diff --git a/src/gui/src/SettingsDialogBase.ui b/src/gui/src/SettingsDialogBase.ui index 144daf3c..44ed98cb 100644 --- a/src/gui/src/SettingsDialogBase.ui +++ b/src/gui/src/SettingsDialogBase.ui @@ -195,6 +195,13 @@ + + + + Require client certificate + + + @@ -216,19 +223,20 @@ false - - - - - 75 - 0 - + + + + Log to file: + + + + + + + false - &Logging level: - - - m_pComboLogLevel + Browse... @@ -271,10 +279,19 @@ - - + + + + + 75 + 0 + + - Log to file: + &Logging level: + + + m_pComboLogLevel @@ -285,16 +302,6 @@ - - - - false - - - Browse... - - - From 133e447fb67d558d52309da80bfa1b0d10e6173b Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:50:10 +0200 Subject: [PATCH 079/113] lib/net: Don't hardcode fingerprint DB path in verify_cert_fingerprint() --- src/lib/net/SecureSocket.cpp | 7 ++----- src/lib/net/SecureSocket.h | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 1004bb39..640740d1 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -497,7 +497,7 @@ SecureSocket::secureConnect(int socket) retry = 0; // No error, set ready, process and return ok m_secureReady = true; - if (verifyCertFingerprint()) { + if (verify_cert_fingerprint(barrier::DataDirectories::trusted_servers_ssl_fingerprints_path())) { LOG((CLOG_INFO "connected to secure socket")); if (!showCertificate()) { disconnect(); @@ -655,8 +655,7 @@ SecureSocket::disconnect() sendEvent(getEvents()->forIStream().inputShutdown()); } -bool -SecureSocket::verifyCertFingerprint() +bool SecureSocket::verify_cert_fingerprint(const barrier::fs::path& fingerprint_db_path) { // calculate received certificate fingerprint barrier::FingerprintData fingerprint_sha1, fingerprint_sha256; @@ -676,8 +675,6 @@ SecureSocket::verifyCertFingerprint() barrier::format_ssl_fingerprint(fingerprint_sha1.data).c_str(), barrier::format_ssl_fingerprint(fingerprint_sha256.data).c_str())); - auto fingerprint_db_path = barrier::DataDirectories::trusted_servers_ssl_fingerprints_path(); - // Provide debug hint as to what file is being used to verify fingerprint trust LOG((CLOG_NOTE "fingerprint_db_path: %s", fingerprint_db_path.u8string().c_str())); diff --git a/src/lib/net/SecureSocket.h b/src/lib/net/SecureSocket.h index 6e355008..2e11097b 100644 --- a/src/lib/net/SecureSocket.h +++ b/src/lib/net/SecureSocket.h @@ -69,7 +69,7 @@ private: void showError(const std::string& reason); std::string getError(); void disconnect(); - bool verifyCertFingerprint(); + bool verify_cert_fingerprint(const barrier::fs::path& fingerprint_db_path); MultiplexerJobStatus serviceConnect(ISocketMultiplexerJob*, bool, bool, bool); MultiplexerJobStatus serviceAccept(ISocketMultiplexerJob*, bool, bool, bool); From 82b8fa905eb31b0291bfe2ca4adffaa764292c4e Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:50:11 +0200 Subject: [PATCH 080/113] lib/net: Improve name of showCertificate() to reflect what it does --- src/lib/net/SecureSocket.cpp | 8 ++++---- src/lib/net/SecureSocket.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 640740d1..2bb117ab 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -499,7 +499,7 @@ SecureSocket::secureConnect(int socket) m_secureReady = true; if (verify_cert_fingerprint(barrier::DataDirectories::trusted_servers_ssl_fingerprints_path())) { LOG((CLOG_INFO "connected to secure socket")); - if (!showCertificate()) { + if (!ensure_peer_certificate()) { disconnect(); return -1;// Cert fail, error } @@ -518,7 +518,7 @@ SecureSocket::secureConnect(int socket) } bool -SecureSocket::showCertificate() +SecureSocket::ensure_peer_certificate() { X509* cert; char* line; @@ -527,12 +527,12 @@ SecureSocket::showCertificate() cert = SSL_get_peer_certificate(m_ssl->m_ssl); if (cert != NULL) { line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); - LOG((CLOG_INFO "server ssl certificate info: %s", line)); + LOG((CLOG_INFO "peer ssl certificate info: %s", line)); OPENSSL_free(line); X509_free(cert); } else { - showError("server has no ssl certificate"); + showError("peer has no ssl certificate"); return false; } diff --git a/src/lib/net/SecureSocket.h b/src/lib/net/SecureSocket.h index 2e11097b..3c35b8e0 100644 --- a/src/lib/net/SecureSocket.h +++ b/src/lib/net/SecureSocket.h @@ -64,7 +64,7 @@ private: void createSSL(); int secureAccept(int s); int secureConnect(int s); - bool showCertificate(); + bool ensure_peer_certificate(); void checkResult(int n, int& retry); void showError(const std::string& reason); std::string getError(); From 5c7d7194d5cb8589b2d12a89fa0c678887da51d4 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:50:12 +0200 Subject: [PATCH 081/113] lib/net: Use enum for connection security level instead of boolean --- src/lib/barrier/ServerApp.cpp | 8 ++++++-- src/lib/client/Client.cpp | 10 ++++++--- src/lib/net/ConnectionSecurityLevel.h | 26 ++++++++++++++++++++++++ src/lib/net/ISocketFactory.h | 11 +++++----- src/lib/net/TCPSocketFactory.cpp | 12 +++++------ src/lib/net/TCPSocketFactory.h | 11 +++++----- src/lib/server/ClientListener.cpp | 11 +++++----- src/lib/server/ClientListener.h | 9 ++++---- src/test/integtests/net/NetworkTests.cpp | 12 +++++++---- 9 files changed, 72 insertions(+), 38 deletions(-) create mode 100644 src/lib/net/ConnectionSecurityLevel.h diff --git a/src/lib/barrier/ServerApp.cpp b/src/lib/barrier/ServerApp.cpp index bbb35dd5..8870e0de 100644 --- a/src/lib/barrier/ServerApp.cpp +++ b/src/lib/barrier/ServerApp.cpp @@ -655,11 +655,15 @@ ServerApp::handleResume(const Event&, void*) ClientListener* ServerApp::openClientListener(const NetworkAddress& address) { + auto security_level = ConnectionSecurityLevel::PLAINTEXT; + if (args().m_enableCrypto) { + security_level = ConnectionSecurityLevel::ENCRYPTED; + } + ClientListener* listen = new ClientListener( address, new TCPSocketFactory(m_events, getSocketMultiplexer()), - m_events, - args().m_enableCrypto); + m_events, security_level); m_events->adoptHandler( m_events->forClientListener().connected(), listen, diff --git a/src/lib/client/Client.cpp b/src/lib/client/Client.cpp index b0dbbc37..b000575c 100644 --- a/src/lib/client/Client.cpp +++ b/src/lib/client/Client.cpp @@ -127,6 +127,11 @@ Client::connect() return; } + auto security_level = ConnectionSecurityLevel::PLAINTEXT; + if (m_useSecureNetwork) { + security_level = ConnectionSecurityLevel::ENCRYPTED; + } + try { // resolve the server hostname. do this every time we connect // in case we couldn't resolve the address earlier or the address @@ -145,9 +150,8 @@ Client::connect() } // create the socket - IDataSocket* socket = m_socketFactory->create( - ARCH->getAddrFamily(m_serverAddress.getAddress()), - m_useSecureNetwork); + IDataSocket* socket = m_socketFactory->create(ARCH->getAddrFamily(m_serverAddress.getAddress()), + security_level); m_socket = dynamic_cast(socket); // filter socket messages, including a packetizing filter diff --git a/src/lib/net/ConnectionSecurityLevel.h b/src/lib/net/ConnectionSecurityLevel.h new file mode 100644 index 00000000..d597bd67 --- /dev/null +++ b/src/lib/net/ConnectionSecurityLevel.h @@ -0,0 +1,26 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . +*/ + +#ifndef BARRIER_LIB_NET_CONNECTION_SECURITY_LEVEL_H +#define BARRIER_LIB_NET_CONNECTION_SECURITY_LEVEL_H + +enum class ConnectionSecurityLevel { + PLAINTEXT, + ENCRYPTED, +}; + +#endif // BARRIER_LIB_NET_CONNECTION_SECURITY_LEVEL_H diff --git a/src/lib/net/ISocketFactory.h b/src/lib/net/ISocketFactory.h index a98ddd4f..edfc8c90 100644 --- a/src/lib/net/ISocketFactory.h +++ b/src/lib/net/ISocketFactory.h @@ -20,6 +20,7 @@ #include "common/IInterface.h" #include "arch/IArchNetwork.h" +#include "net/ConnectionSecurityLevel.h" class IDataSocket; class IListenSocket; @@ -35,14 +36,12 @@ public: //@{ //! Create data socket - virtual IDataSocket* create( - IArchNetwork::EAddressFamily family, - bool secure) const = 0; + virtual IDataSocket* create(IArchNetwork::EAddressFamily family, + ConnectionSecurityLevel security_level) const = 0; //! Create listen socket - virtual IListenSocket* createListen( - IArchNetwork::EAddressFamily family, - bool secure) const = 0; + virtual IListenSocket* createListen(IArchNetwork::EAddressFamily family, + ConnectionSecurityLevel security_level) const = 0; //@} }; diff --git a/src/lib/net/TCPSocketFactory.cpp b/src/lib/net/TCPSocketFactory.cpp index fe24e97f..6f5f40be 100644 --- a/src/lib/net/TCPSocketFactory.cpp +++ b/src/lib/net/TCPSocketFactory.cpp @@ -40,10 +40,10 @@ TCPSocketFactory::~TCPSocketFactory() // do nothing } -IDataSocket* -TCPSocketFactory::create(IArchNetwork::EAddressFamily family, bool secure) const +IDataSocket* TCPSocketFactory::create(IArchNetwork::EAddressFamily family, + ConnectionSecurityLevel security_level) const { - if (secure) { + if (security_level != ConnectionSecurityLevel::PLAINTEXT) { SecureSocket* secureSocket = new SecureSocket(m_events, m_socketMultiplexer, family); secureSocket->initSsl (false); return secureSocket; @@ -53,11 +53,11 @@ TCPSocketFactory::create(IArchNetwork::EAddressFamily family, bool secure) const } } -IListenSocket* -TCPSocketFactory::createListen(IArchNetwork::EAddressFamily family, bool secure) const +IListenSocket* TCPSocketFactory::createListen(IArchNetwork::EAddressFamily family, + ConnectionSecurityLevel security_level) const { IListenSocket* socket = NULL; - if (secure) { + if (security_level != ConnectionSecurityLevel::PLAINTEXT) { socket = new SecureListenSocket(m_events, m_socketMultiplexer, family); } else { diff --git a/src/lib/net/TCPSocketFactory.h b/src/lib/net/TCPSocketFactory.h index 202366e0..ac21cab0 100644 --- a/src/lib/net/TCPSocketFactory.h +++ b/src/lib/net/TCPSocketFactory.h @@ -31,12 +31,11 @@ public: virtual ~TCPSocketFactory(); // ISocketFactory overrides - virtual IDataSocket* create( - IArchNetwork::EAddressFamily family, - bool secure) const; - virtual IListenSocket* createListen( - IArchNetwork::EAddressFamily family, - bool secure) const; + virtual IDataSocket* create(IArchNetwork::EAddressFamily family, + ConnectionSecurityLevel security_level) const; + + virtual IListenSocket* createListen(IArchNetwork::EAddressFamily family, + ConnectionSecurityLevel security_level) const; private: IEventQueue* m_events; diff --git a/src/lib/server/ClientListener.cpp b/src/lib/server/ClientListener.cpp index 04d8a596..a9b3a700 100644 --- a/src/lib/server/ClientListener.cpp +++ b/src/lib/server/ClientListener.cpp @@ -36,18 +36,17 @@ ClientListener::ClientListener(const NetworkAddress& address, ISocketFactory* socketFactory, IEventQueue* events, - bool enableCrypto) : + ConnectionSecurityLevel security_level) : m_socketFactory(socketFactory), m_server(NULL), m_events(events), - m_useSecureNetwork(enableCrypto) + security_level_{security_level} { assert(m_socketFactory != NULL); try { - m_listen = m_socketFactory->createListen( - ARCH->getAddrFamily(address.getAddress()), - m_useSecureNetwork); + m_listen = m_socketFactory->createListen(ARCH->getAddrFamily(address.getAddress()), + security_level); // setup event handler m_events->adoptHandler(m_events->forIListenSocket().connecting(), @@ -140,7 +139,7 @@ ClientListener::handleClientConnecting(const Event&, void*) // When using non SSL, server accepts clients immediately, while SSL // has to call secure accept which may require retry - if (!m_useSecureNetwork) { + if (security_level_ == ConnectionSecurityLevel::PLAINTEXT) { m_events->addEvent(Event(m_events->forClientListener().accepted(), socket->getEventTarget())); } diff --git a/src/lib/server/ClientListener.h b/src/lib/server/ClientListener.h index 86d962ef..1debc2b9 100644 --- a/src/lib/server/ClientListener.h +++ b/src/lib/server/ClientListener.h @@ -23,6 +23,7 @@ #include "base/Event.h" #include "common/stddeque.h" #include "common/stdset.h" +#include "net/ConnectionSecurityLevel.h" class ClientProxy; class ClientProxyUnknown; @@ -36,10 +37,8 @@ class IDataSocket; class ClientListener { public: // The factories are adopted. - ClientListener(const NetworkAddress&, - ISocketFactory*, - IEventQueue* events, - bool enableCrypto); + ClientListener(const NetworkAddress&, ISocketFactory*, IEventQueue* events, + ConnectionSecurityLevel security_level); ~ClientListener(); //! @name manipulators @@ -86,6 +85,6 @@ private: WaitingClients m_waitingClients; Server* m_server; IEventQueue* m_events; - bool m_useSecureNetwork; + ConnectionSecurityLevel security_level_; ClientSockets m_clientSockets; }; diff --git a/src/test/integtests/net/NetworkTests.cpp b/src/test/integtests/net/NetworkTests.cpp index 4bd19354..1e843867 100644 --- a/src/test/integtests/net/NetworkTests.cpp +++ b/src/test/integtests/net/NetworkTests.cpp @@ -115,7 +115,8 @@ TEST_F(NetworkTests, sendToClient_mockData) // server SocketMultiplexer serverSocketMultiplexer; TCPSocketFactory* serverSocketFactory = new TCPSocketFactory(&m_events, &serverSocketMultiplexer); - ClientListener listener(serverAddress, serverSocketFactory, &m_events, false); + ClientListener listener(serverAddress, serverSocketFactory, &m_events, + ConnectionSecurityLevel::PLAINTEXT); NiceMock serverScreen; NiceMock primaryClient; NiceMock serverConfig; @@ -173,7 +174,8 @@ TEST_F(NetworkTests, sendToClient_mockFile) // server SocketMultiplexer serverSocketMultiplexer; TCPSocketFactory* serverSocketFactory = new TCPSocketFactory(&m_events, &serverSocketMultiplexer); - ClientListener listener(serverAddress, serverSocketFactory, &m_events, false); + ClientListener listener(serverAddress, serverSocketFactory, &m_events, + ConnectionSecurityLevel::PLAINTEXT); NiceMock serverScreen; NiceMock primaryClient; NiceMock serverConfig; @@ -230,7 +232,8 @@ TEST_F(NetworkTests, sendToServer_mockData) // server SocketMultiplexer serverSocketMultiplexer; TCPSocketFactory* serverSocketFactory = new TCPSocketFactory(&m_events, &serverSocketMultiplexer); - ClientListener listener(serverAddress, serverSocketFactory, &m_events, false); + ClientListener listener(serverAddress, serverSocketFactory, &m_events, + ConnectionSecurityLevel::PLAINTEXT); NiceMock serverScreen; NiceMock primaryClient; NiceMock serverConfig; @@ -287,7 +290,8 @@ TEST_F(NetworkTests, sendToServer_mockFile) // server SocketMultiplexer serverSocketMultiplexer; TCPSocketFactory* serverSocketFactory = new TCPSocketFactory(&m_events, &serverSocketMultiplexer); - ClientListener listener(serverAddress, serverSocketFactory, &m_events, false); + ClientListener listener(serverAddress, serverSocketFactory, &m_events, + ConnectionSecurityLevel::PLAINTEXT); NiceMock serverScreen; NiceMock primaryClient; NiceMock serverConfig; From 57769cffdae571298671f828ee681c153f098d4d Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:50:13 +0200 Subject: [PATCH 082/113] lib/net: Pass connection security level to within socket classes --- src/lib/net/SecureListenSocket.cpp | 16 +++++++--------- src/lib/net/SecureListenSocket.h | 9 ++++++--- src/lib/net/SecureSocket.cpp | 19 +++++++++---------- src/lib/net/SecureSocket.h | 10 ++++++---- src/lib/net/TCPSocketFactory.cpp | 5 +++-- 5 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/lib/net/SecureListenSocket.cpp b/src/lib/net/SecureListenSocket.cpp index 71e09ce5..27b84635 100644 --- a/src/lib/net/SecureListenSocket.cpp +++ b/src/lib/net/SecureListenSocket.cpp @@ -25,11 +25,11 @@ #include "common/DataDirectories.h" #include "base/String.h" -SecureListenSocket::SecureListenSocket( - IEventQueue* events, - SocketMultiplexer* socketMultiplexer, - IArchNetwork::EAddressFamily family) : - TCPListenSocket(events, socketMultiplexer, family) +SecureListenSocket::SecureListenSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, + IArchNetwork::EAddressFamily family, + ConnectionSecurityLevel security_level) : + TCPListenSocket(events, socketMultiplexer, family), + security_level_{security_level} { } @@ -38,10 +38,8 @@ SecureListenSocket::accept() { SecureSocket* socket = NULL; try { - socket = new SecureSocket( - m_events, - m_socketMultiplexer, - ARCH->acceptSocket(m_socket, NULL)); + socket = new SecureSocket(m_events, m_socketMultiplexer, + ARCH->acceptSocket(m_socket, NULL), security_level_); socket->initSsl(true); if (socket != NULL) { diff --git a/src/lib/net/SecureListenSocket.h b/src/lib/net/SecureListenSocket.h index fab92bf5..a0e792ac 100644 --- a/src/lib/net/SecureListenSocket.h +++ b/src/lib/net/SecureListenSocket.h @@ -19,6 +19,7 @@ #include "net/TCPListenSocket.h" #include "common/stdset.h" +#include "ConnectionSecurityLevel.h" class IEventQueue; class SocketMultiplexer; @@ -26,11 +27,13 @@ class IDataSocket; class SecureListenSocket : public TCPListenSocket { public: - SecureListenSocket(IEventQueue* events, - SocketMultiplexer* socketMultiplexer, - IArchNetwork::EAddressFamily family); + SecureListenSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, + IArchNetwork::EAddressFamily family, + ConnectionSecurityLevel security_level); // IListenSocket overrides virtual IDataSocket* accept(); +private: + ConnectionSecurityLevel security_level_; }; diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 2bb117ab..41d6a7bb 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -54,25 +54,24 @@ struct Ssl { SSL* m_ssl; }; -SecureSocket::SecureSocket( - IEventQueue* events, - SocketMultiplexer* socketMultiplexer, - IArchNetwork::EAddressFamily family) : +SecureSocket::SecureSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, + IArchNetwork::EAddressFamily family, + ConnectionSecurityLevel security_level) : TCPSocket(events, socketMultiplexer, family), m_ssl(nullptr), m_secureReady(false), - m_fatal(false) + m_fatal(false), + security_level_{security_level} { } -SecureSocket::SecureSocket( - IEventQueue* events, - SocketMultiplexer* socketMultiplexer, - ArchSocket socket) : +SecureSocket::SecureSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, + ArchSocket socket, ConnectionSecurityLevel security_level) : TCPSocket(events, socketMultiplexer, socket), m_ssl(nullptr), m_secureReady(false), - m_fatal(false) + m_fatal(false), + security_level_{security_level} { } diff --git a/src/lib/net/SecureSocket.h b/src/lib/net/SecureSocket.h index 3c35b8e0..496a3656 100644 --- a/src/lib/net/SecureSocket.h +++ b/src/lib/net/SecureSocket.h @@ -17,6 +17,7 @@ #pragma once +#include "ConnectionSecurityLevel.h" #include "net/TCPSocket.h" #include "net/XSocket.h" #include "io/filesystem.h" @@ -33,10 +34,10 @@ A secure socket using SSL. */ class SecureSocket : public TCPSocket { public: - SecureSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, IArchNetwork::EAddressFamily family); - SecureSocket(IEventQueue* events, - SocketMultiplexer* socketMultiplexer, - ArchSocket socket); + SecureSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, + IArchNetwork::EAddressFamily family, ConnectionSecurityLevel security_level); + SecureSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, + ArchSocket socket, ConnectionSecurityLevel security_level); ~SecureSocket(); // ISocket overrides @@ -86,4 +87,5 @@ private: Ssl* m_ssl; bool m_secureReady; bool m_fatal; + ConnectionSecurityLevel security_level_ = ConnectionSecurityLevel::ENCRYPTED; }; diff --git a/src/lib/net/TCPSocketFactory.cpp b/src/lib/net/TCPSocketFactory.cpp index 6f5f40be..30e930e3 100644 --- a/src/lib/net/TCPSocketFactory.cpp +++ b/src/lib/net/TCPSocketFactory.cpp @@ -44,7 +44,8 @@ IDataSocket* TCPSocketFactory::create(IArchNetwork::EAddressFamily family, ConnectionSecurityLevel security_level) const { if (security_level != ConnectionSecurityLevel::PLAINTEXT) { - SecureSocket* secureSocket = new SecureSocket(m_events, m_socketMultiplexer, family); + SecureSocket* secureSocket = new SecureSocket(m_events, m_socketMultiplexer, family, + security_level); secureSocket->initSsl (false); return secureSocket; } @@ -58,7 +59,7 @@ IListenSocket* TCPSocketFactory::createListen(IArchNetwork::EAddressFamily famil { IListenSocket* socket = NULL; if (security_level != ConnectionSecurityLevel::PLAINTEXT) { - socket = new SecureListenSocket(m_events, m_socketMultiplexer, family); + socket = new SecureListenSocket(m_events, m_socketMultiplexer, family, security_level); } else { socket = new TCPListenSocket(m_events, m_socketMultiplexer, family); From e79bdf333c47952b9f18972f782bc3b4b75ad204 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:50:14 +0200 Subject: [PATCH 083/113] gui: Fix fingerprint database being not populated due to missing dirs --- src/gui/src/MainWindow.cpp | 5 +++++ src/gui/src/SslCertificate.cpp | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 87f31eb2..7d4a9a5e 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -444,6 +444,11 @@ void MainWindow::checkFingerprint(const QString& line) auto db_path = barrier::DataDirectories::trusted_servers_ssl_fingerprints_path(); + auto db_dir = db_path.parent_path(); + if (!barrier::fs::exists(db_dir)) { + barrier::fs::create_directories(db_dir); + } + // We compare only SHA256 fingerprints, but show both SHA1 and SHA256 so that the users can // still verify fingerprints on old Barrier servers. This way the only time when we are exposed // to SHA1 vulnerabilities is when the user is reconnecting again. diff --git a/src/gui/src/SslCertificate.cpp b/src/gui/src/SslCertificate.cpp index 26f3b3ee..65ac08a6 100644 --- a/src/gui/src/SslCertificate.cpp +++ b/src/gui/src/SslCertificate.cpp @@ -65,6 +65,11 @@ void SslCertificate::generate_fingerprint(const barrier::fs::path& cert_path) { try { auto local_path = barrier::DataDirectories::local_ssl_fingerprints_path(); + auto local_dir = local_path.parent_path(); + if (!barrier::fs::exists(local_dir)) { + barrier::fs::create_directories(local_dir); + } + barrier::FingerprintDatabase db; db.add_trusted(barrier::get_pem_file_cert_fingerprint(cert_path.u8string(), barrier::FingerprintType::SHA1)); From 229abab99f39f11624e5651f819e7f1f8eddedcc Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:50:15 +0200 Subject: [PATCH 084/113] Implement client identity verification This commit fixes two security vulnerabilities: CVE-2021-42072 and CVE-2021-42073. The issues have been reported by Matthias Gerstner . --- .../client-certificate-checking.bugfix | 7 +++ src/gui/src/MainWindow.cpp | 54 +++++++++++++++---- src/lib/barrier/ArgParser.cpp | 4 +- src/lib/barrier/ServerApp.cpp | 8 ++- src/lib/barrier/ServerArgs.h | 1 + src/lib/client/Client.cpp | 3 +- src/lib/net/ConnectionSecurityLevel.h | 1 + src/lib/net/SecureSocket.cpp | 33 +++++++++++- 8 files changed, 96 insertions(+), 15 deletions(-) create mode 100644 doc/newsfragments/client-certificate-checking.bugfix diff --git a/doc/newsfragments/client-certificate-checking.bugfix b/doc/newsfragments/client-certificate-checking.bugfix new file mode 100644 index 00000000..01d4d03d --- /dev/null +++ b/doc/newsfragments/client-certificate-checking.bugfix @@ -0,0 +1,7 @@ +SECURITY ISSUE + +Barrier now supports client identity verification (fixes CVE-2021-42072, CVE-2021-42073). + +To support seamless upgrades from older versions of Barrier this is currently disabled by default. +The feature can be enabled in the settings dialog. If enabled, older clients of Barrier will be +rejected. diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 7d4a9a5e..2172507b 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -427,7 +427,7 @@ void MainWindow::checkConnected(const QString& line) void MainWindow::checkFingerprint(const QString& line) { - QRegExp fingerprintRegex(".*server fingerprint \\(SHA1\\): ([A-F0-9:]+) \\(SHA256\\): ([A-F0-9:]+)"); + QRegExp fingerprintRegex(".*peer fingerprint \\(SHA1\\): ([A-F0-9:]+) \\(SHA256\\): ([A-F0-9:]+)"); if (!fingerprintRegex.exactMatch(line)) { return; } @@ -442,7 +442,11 @@ void MainWindow::checkFingerprint(const QString& line) barrier::string::from_hex(fingerprintRegex.cap(2).toStdString()) }; - auto db_path = barrier::DataDirectories::trusted_servers_ssl_fingerprints_path(); + bool is_client = barrierType() == barrierClient; + + auto db_path = is_client + ? barrier::DataDirectories::trusted_servers_ssl_fingerprints_path() + : barrier::DataDirectories::trusted_clients_ssl_fingerprints_path(); auto db_dir = db_path.parent_path(); if (!barrier::fs::exists(db_dir)) { @@ -461,17 +465,17 @@ void MainWindow::checkFingerprint(const QString& line) static bool messageBoxAlreadyShown = false; if (!messageBoxAlreadyShown) { - stopBarrier(); + if (is_client) { + stopBarrier(); + } - messageBoxAlreadyShown = true; - QMessageBox::StandardButton fingerprintReply = - QMessageBox::information( - this, tr("Security question"), - tr("Do you trust this fingerprint?\n\n" + QString message; + if (is_client) { + message = tr("Do you trust this fingerprint?\n\n" "SHA256:\n" "%1\n" "%2\n\n" - "SHA1 (obsolete, when using old Barrier server):\n" + "SHA1 (obsolete, when using old Barrier client):\n" "%3\n\n" "This is a server fingerprint. You should compare this " "fingerprint to the one on your server's screen. If the " @@ -483,14 +487,38 @@ void MainWindow::checkFingerprint(const QString& line) .arg(QString::fromStdString(barrier::format_ssl_fingerprint(fingerprint_sha256.data))) .arg(QString::fromStdString( barrier::create_fingerprint_randomart(fingerprint_sha256.data))) - .arg(QString::fromStdString(barrier::format_ssl_fingerprint(fingerprint_sha1.data))), + .arg(QString::fromStdString(barrier::format_ssl_fingerprint(fingerprint_sha1.data))); + } else { + message = tr("Do you trust this fingerprint?\n\n" + "SHA256:\n" + "%1\n" + "%2\n\n" + "This is a client fingerprint. You should compare this " + "fingerprint to the one on your client's screen. If the " + "two don't match exactly, then it's probably not the client " + "you're expecting (it could be a malicious user).\n\n" + "To automatically trust this fingerprint for future " + "connections, click Yes. To reject this fingerprint and " + "disconnect the client, click No.") + .arg(QString::fromStdString(barrier::format_ssl_fingerprint(fingerprint_sha256.data))) + .arg(QString::fromStdString( + barrier::create_fingerprint_randomart(fingerprint_sha256.data))); + } + + messageBoxAlreadyShown = true; + QMessageBox::StandardButton fingerprintReply = + QMessageBox::information( + this, tr("Security question"), + message, QMessageBox::Yes | QMessageBox::No); if (fingerprintReply == QMessageBox::Yes) { // restart core process after trusting fingerprint. db.add_trusted(fingerprint_sha256); db.write(db_path); - startBarrier(); + if (is_client) { + startBarrier(); + } } messageBoxAlreadyShown = false; @@ -734,6 +762,10 @@ bool MainWindow::serverArgs(QStringList& args, QString& app) args << "--log" << appConfig().logFilenameCmd(); } + if (!appConfig().getRequireClientCertificate()) { + args << "--disable-client-cert-checking"; + } + QString configFilename = this->configFilename(); #if defined(Q_OS_WIN) // wrap in quotes in case username contains spaces. diff --git a/src/lib/barrier/ArgParser.cpp b/src/lib/barrier/ArgParser.cpp index 44e29491..99cd803b 100644 --- a/src/lib/barrier/ArgParser.cpp +++ b/src/lib/barrier/ArgParser.cpp @@ -65,7 +65,9 @@ ArgParser::parseServerArgs(ServerArgs& args, int argc, const char* const* argv) // save screen change script path args.m_screenChangeScript = argv[++i]; } - else { + else if (isArg(i, argc, argv, nullptr, "--disable-client-cert-checking")) { + args.check_client_certificates = false; + } else { LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_exename.c_str(), argv[i], args.m_exename.c_str())); return false; } diff --git a/src/lib/barrier/ServerApp.cpp b/src/lib/barrier/ServerApp.cpp index 8870e0de..4810b8a5 100644 --- a/src/lib/barrier/ServerApp.cpp +++ b/src/lib/barrier/ServerApp.cpp @@ -148,7 +148,10 @@ ServerApp::help() << "Options:\n" << " -a, --address
listen for clients on the given address.\n" << " -c, --config use the named configuration file instead.\n" - << HELP_COMMON_INFO_1 << WINAPI_INFO << HELP_SYS_INFO << HELP_COMMON_INFO_2 << "\n" + << HELP_COMMON_INFO_1 + << " --disable-client-cert-checking disable client SSL certificate \n" + " checking (deprecated)\n" + << WINAPI_INFO << HELP_SYS_INFO << HELP_COMMON_INFO_2 << "\n" << "Default options are marked with a *\n" << "\n" << "The argument for --address is of the form: [][:]. The\n" @@ -658,6 +661,9 @@ ServerApp::openClientListener(const NetworkAddress& address) auto security_level = ConnectionSecurityLevel::PLAINTEXT; if (args().m_enableCrypto) { security_level = ConnectionSecurityLevel::ENCRYPTED; + if (args().check_client_certificates) { + security_level = ConnectionSecurityLevel::ENCRYPTED_AUTHENTICATED; + } } ClientListener* listen = new ClientListener( diff --git a/src/lib/barrier/ServerArgs.h b/src/lib/barrier/ServerArgs.h index 6d912331..6323705d 100644 --- a/src/lib/barrier/ServerArgs.h +++ b/src/lib/barrier/ServerArgs.h @@ -30,4 +30,5 @@ public: String m_configFile; Config* m_config; String m_screenChangeScript; + bool check_client_certificates = true; }; diff --git a/src/lib/client/Client.cpp b/src/lib/client/Client.cpp index b000575c..4f1fe73a 100644 --- a/src/lib/client/Client.cpp +++ b/src/lib/client/Client.cpp @@ -129,7 +129,8 @@ Client::connect() auto security_level = ConnectionSecurityLevel::PLAINTEXT; if (m_useSecureNetwork) { - security_level = ConnectionSecurityLevel::ENCRYPTED; + // client always authenticates server + security_level = ConnectionSecurityLevel::ENCRYPTED_AUTHENTICATED; } try { diff --git a/src/lib/net/ConnectionSecurityLevel.h b/src/lib/net/ConnectionSecurityLevel.h index d597bd67..913c2fd7 100644 --- a/src/lib/net/ConnectionSecurityLevel.h +++ b/src/lib/net/ConnectionSecurityLevel.h @@ -21,6 +21,7 @@ enum class ConnectionSecurityLevel { PLAINTEXT, ENCRYPTED, + ENCRYPTED_AUTHENTICATED }; #endif // BARRIER_LIB_NET_CONNECTION_SECURITY_LEVEL_H diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 41d6a7bb..f096729d 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -361,6 +361,11 @@ bool SecureSocket::load_certificates(const barrier::fs::path& path) return true; } +static int cert_verify_ignore_callback(X509_STORE_CTX*, void*) +{ + return 1; +} + void SecureSocket::initContext(bool server) { @@ -396,6 +401,14 @@ SecureSocket::initContext(bool server) if (m_ssl->m_context == NULL) { showError(""); } + + if (security_level_ == ConnectionSecurityLevel::ENCRYPTED_AUTHENTICATED) { + // We want to ask for peer certificate, but not verify it. If we don't ask for peer + // certificate, e.g. client won't send it. + SSL_CTX_set_verify(m_ssl->m_context, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + nullptr); + SSL_CTX_set_cert_verify_callback(m_ssl->m_context, cert_verify_ignore_callback, nullptr); + } } void @@ -436,6 +449,24 @@ SecureSocket::secureAccept(int socket) // If not fatal and no retry, state is good if (retry == 0) { + if (security_level_ == ConnectionSecurityLevel::ENCRYPTED_AUTHENTICATED) { + if (verify_cert_fingerprint( + barrier::DataDirectories::trusted_clients_ssl_fingerprints_path())) { + LOG((CLOG_INFO "accepted secure socket")); + if (!ensure_peer_certificate()) { + retry = 0; + disconnect(); + return -1;// Cert fail, error + } + } + else { + LOG((CLOG_ERR "failed to verify server certificate fingerprint")); + retry = 0; + disconnect(); + return -1; // Fingerprint failed, error + } + } + m_secureReady = true; LOG((CLOG_INFO "accepted secure socket")); if (CLOG->getFilter() >= kDEBUG1) { @@ -670,7 +701,7 @@ bool SecureSocket::verify_cert_fingerprint(const barrier::fs::path& fingerprint_ } // note: the GUI parses the following two lines of logs, don't change unnecessarily - LOG((CLOG_NOTE "server fingerprint (SHA1): %s (SHA256): %s", + LOG((CLOG_NOTE "peer fingerprint (SHA1): %s (SHA256): %s", barrier::format_ssl_fingerprint(fingerprint_sha1.data).c_str(), barrier::format_ssl_fingerprint(fingerprint_sha256.data).c_str())); From 165100a0d2855fd7844e2e5d9f94267115ed0590 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:50:16 +0200 Subject: [PATCH 085/113] gui: Extract barrier type to separate enum --- src/gui/src/MainWindow.cpp | 15 ++++++++++----- src/gui/src/MainWindow.h | 10 +++------- src/gui/src/ZeroconfService.cpp | 2 +- src/lib/barrier/BarrierType.h | 26 ++++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 13 deletions(-) create mode 100644 src/lib/barrier/BarrierType.h diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 2172507b..85fa830e 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -442,7 +442,7 @@ void MainWindow::checkFingerprint(const QString& line) barrier::string::from_hex(fingerprintRegex.cap(2).toStdString()) }; - bool is_client = barrierType() == barrierClient; + bool is_client = barrier_type() == BarrierType::Client; auto db_path = is_client ? barrier::DataDirectories::trusted_servers_ssl_fingerprints_path() @@ -600,8 +600,8 @@ void MainWindow::startBarrier() args << "--profile-dir" << QString::fromStdString("\"" + barrier::DataDirectories::profile().u8string() + "\""); #endif - if ((barrierType() == barrierClient && !clientArgs(args, app)) - || (barrierType() == barrierServer && !serverArgs(args, app))) + if ((barrier_type() == BarrierType::Client && !clientArgs(args, app)) + || (barrier_type() == BarrierType::Server && !serverArgs(args, app))) { stopBarrier(); return; @@ -616,7 +616,7 @@ void MainWindow::startBarrier() m_pLogWindow->startNewInstance(); - appendLogInfo("starting " + QString(barrierType() == barrierServer ? "server" : "client")); + appendLogInfo("starting " + QString(barrier_type() == BarrierType::Server ? "server" : "client")); qDebug() << args; @@ -726,6 +726,11 @@ QString MainWindow::configFilename() return filename; } +BarrierType MainWindow::barrier_type() const +{ + return m_pGroupClient->isChecked() ? BarrierType::Client : BarrierType::Server; +} + QString MainWindow::address() { QString address = appConfig().networkInterface(); @@ -1020,7 +1025,7 @@ void MainWindow::updateZeroconfService() m_pZeroconfService = NULL; } - if (m_AppConfig->autoConfig() || barrierType() == barrierServer) { + if (m_AppConfig->autoConfig() || barrier_type() == BarrierType::Server) { m_pZeroconfService = new ZeroconfService(this); } } diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h index 59a0e0db..0c582c9f 100644 --- a/src/gui/src/MainWindow.h +++ b/src/gui/src/MainWindow.h @@ -20,6 +20,8 @@ #define MAINWINDOW__H +#include "barrier/BarrierType.h" + #include #include #include @@ -76,12 +78,6 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase barrierTransfering }; - enum qBarrierType - { - barrierClient, - barrierServer - }; - enum qLevel { Error, Info @@ -98,7 +94,7 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase public: void setVisible(bool visible); - int barrierType() const { return m_pGroupClient->isChecked() ? barrierClient : barrierServer; } + BarrierType barrier_type() const; int barrierState() const { return m_BarrierState; } QString hostname() const { return m_pLineEditHostname->text(); } QString configFilename(); diff --git a/src/gui/src/ZeroconfService.cpp b/src/gui/src/ZeroconfService.cpp index f7b10007..fbb0ea10 100644 --- a/src/gui/src/ZeroconfService.cpp +++ b/src/gui/src/ZeroconfService.cpp @@ -66,7 +66,7 @@ ZeroconfService::ZeroconfService(MainWindow* mainWindow) : m_ServiceRegistered(false) { silence_avahi_warning(); - if (m_pMainWindow->barrierType() == MainWindow::barrierServer) { + if (m_pMainWindow->barrier_type() == BarrierType::Server) { if (registerService(true)) { m_pZeroconfBrowser = new ZeroconfBrowser(this); connect(m_pZeroconfBrowser, SIGNAL( diff --git a/src/lib/barrier/BarrierType.h b/src/lib/barrier/BarrierType.h new file mode 100644 index 00000000..0a184773 --- /dev/null +++ b/src/lib/barrier/BarrierType.h @@ -0,0 +1,26 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . +*/ + +#ifndef BARRIER_LIB_BARRIER_BARRIER_TYPE_H +#define BARRIER_LIB_BARRIER_BARRIER_TYPE_H + +enum class BarrierType { + Server, + Client +}; + +#endif // BARRIER_LIB_BARRIER_BARRIER_TYPE_H From 7cacbd148941de596d8266385192489ec2764046 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 04:50:17 +0200 Subject: [PATCH 086/113] gui: Improve formatting of the fingerprint acceptance dialog --- src/gui/CMakeLists.txt | 2 + src/gui/src/FingerprintAcceptDialog.cpp | 65 +++++++++ src/gui/src/FingerprintAcceptDialog.h | 45 ++++++ src/gui/src/FingerprintAcceptDialog.ui | 174 ++++++++++++++++++++++++ src/gui/src/MainWindow.cpp | 46 +------ 5 files changed, 289 insertions(+), 43 deletions(-) create mode 100644 src/gui/src/FingerprintAcceptDialog.cpp create mode 100644 src/gui/src/FingerprintAcceptDialog.h create mode 100644 src/gui/src/FingerprintAcceptDialog.ui diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index fb7678f2..570e8424 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -29,6 +29,7 @@ set(GUI_SOURCE_FILES src/CommandProcess.cpp src/DataDownloader.cpp src/DisplayIsValid.cpp + src/FingerprintAcceptDialog.cpp src/HotkeyDialog.cpp src/IpcClient.cpp src/Ipc.cpp @@ -104,6 +105,7 @@ set(GUI_UI_FILES src/AboutDialogBase.ui src/ActionDialogBase.ui src/AddClientDialogBase.ui + src/FingerprintAcceptDialog.ui src/HotkeyDialogBase.ui src/LogWindowBase.ui src/MainWindowBase.ui diff --git a/src/gui/src/FingerprintAcceptDialog.cpp b/src/gui/src/FingerprintAcceptDialog.cpp new file mode 100644 index 00000000..e0dc7e60 --- /dev/null +++ b/src/gui/src/FingerprintAcceptDialog.cpp @@ -0,0 +1,65 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . +*/ + +#include "FingerprintAcceptDialog.h" +#include "ui_FingerprintAcceptDialog.h" +#include "net/SecureUtils.h" + +FingerprintAcceptDialog::FingerprintAcceptDialog(QWidget *parent, + BarrierType type, + const barrier::FingerprintData& fingerprint_sha1, + const barrier::FingerprintData& fingerprint_sha256) : + QDialog(parent), + ui_{std::make_unique()} +{ + ui_->setupUi(this); + + if (type == BarrierType::Server) { + ui_->label_sha1->hide(); + ui_->label_sha1_fingerprint_full->hide(); + } else { + ui_->label_sha1_fingerprint_full->setText( + QString::fromStdString(barrier::format_ssl_fingerprint(fingerprint_sha1.data))); + } + + ui_->label_sha256_fingerprint_full->setText( + QString::fromStdString(barrier::format_ssl_fingerprint_columns(fingerprint_sha256.data))); + ui_->label_sha256_fingerprint_randomart->setText( + QString::fromStdString(barrier::create_fingerprint_randomart(fingerprint_sha256.data))); + + QString explanation; + if (type == BarrierType::Server) { + explanation = tr("This is a client fingerprint. You should compare this " + "fingerprint to the one on your client's screen. If the " + "two don't match exactly, then it's probably not the client " + "you're expecting (it could be a malicious user).\n\n" + "To automatically trust this fingerprint for future " + "connections, click Yes. To reject this fingerprint and " + "disconnect the client, click No."); + } else { + explanation = tr("This is a server fingerprint. You should compare this " + "fingerprint to the one on your server's screen. If the " + "two don't match exactly, then it's probably not the server " + "you're expecting (it could be a malicious user).\n\n" + "To automatically trust this fingerprint for future " + "connections, click Yes. To reject this fingerprint and " + "disconnect from the server, click No."); + } + ui_->label_explanation->setText(explanation); +} + +FingerprintAcceptDialog::~FingerprintAcceptDialog() = default; diff --git a/src/gui/src/FingerprintAcceptDialog.h b/src/gui/src/FingerprintAcceptDialog.h new file mode 100644 index 00000000..da8884c9 --- /dev/null +++ b/src/gui/src/FingerprintAcceptDialog.h @@ -0,0 +1,45 @@ +/* + barrier -- mouse and keyboard sharing utility + Copyright (C) Barrier contributors + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + found in the file LICENSE that should have accompanied this file. + + This package 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 . +*/ + +#ifndef BARRIER_GUI_FINGERPRINT_ACCEPT_DIALOG_H +#define BARRIER_GUI_FINGERPRINT_ACCEPT_DIALOG_H + +#include "net/FingerprintData.h" +#include "barrier/BarrierType.h" +#include +#include + +namespace Ui { +class FingerprintAcceptDialog; +} + +class FingerprintAcceptDialog : public QDialog +{ + Q_OBJECT + +public: + explicit FingerprintAcceptDialog(QWidget* parent, + BarrierType type, + const barrier::FingerprintData& fingerprint_sha1, + const barrier::FingerprintData& fingerprint_sha256); + ~FingerprintAcceptDialog() override; + +private: + std::unique_ptr ui_; +}; + +#endif // BARRIER_GUI_FINGERPRINT_ACCEPT_DIALOG_H diff --git a/src/gui/src/FingerprintAcceptDialog.ui b/src/gui/src/FingerprintAcceptDialog.ui new file mode 100644 index 00000000..9c181ec3 --- /dev/null +++ b/src/gui/src/FingerprintAcceptDialog.ui @@ -0,0 +1,174 @@ + + + FingerprintAcceptDialog + + + + 0 + 0 + 600 + 400 + + + + + 0 + 0 + + + + Security question + + + + QLayout::SetFixedSize + + + + + Qt::Horizontal + + + QDialogButtonBox::No|QDialogButtonBox::Yes + + + + + + + + 0 + 0 + + + + SHA1 (deprecated, compare to old servers only) + + + + + + + + 0 + 0 + + + + + + + true + + + 10 + + + + + + + + 0 + 0 + + + + + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + Do you trust this fingerprint? + + + + + + + + 0 + 0 + + + + + Courier + 75 + true + + + + + + + Qt::AlignCenter + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + + + Qt::AlignCenter + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + SHA256: + + + + + + + + + buttonBox + accepted() + FingerprintAcceptDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + FingerprintAcceptDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index 85fa830e..d17548a4 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -26,6 +26,7 @@ #include "ZeroconfService.h" #include "DataDownloader.h" #include "CommandProcess.h" +#include "FingerprintAcceptDialog.h" #include "QUtility.h" #include "ProcessorArch.h" #include "SslCertificate.h" @@ -469,50 +470,9 @@ void MainWindow::checkFingerprint(const QString& line) stopBarrier(); } - QString message; - if (is_client) { - message = tr("Do you trust this fingerprint?\n\n" - "SHA256:\n" - "%1\n" - "%2\n\n" - "SHA1 (obsolete, when using old Barrier client):\n" - "%3\n\n" - "This is a server fingerprint. You should compare this " - "fingerprint to the one on your server's screen. If the " - "two don't match exactly, then it's probably not the server " - "you're expecting (it could be a malicious user).\n\n" - "To automatically trust this fingerprint for future " - "connections, click Yes. To reject this fingerprint and " - "disconnect from the server, click No.") - .arg(QString::fromStdString(barrier::format_ssl_fingerprint(fingerprint_sha256.data))) - .arg(QString::fromStdString( - barrier::create_fingerprint_randomart(fingerprint_sha256.data))) - .arg(QString::fromStdString(barrier::format_ssl_fingerprint(fingerprint_sha1.data))); - } else { - message = tr("Do you trust this fingerprint?\n\n" - "SHA256:\n" - "%1\n" - "%2\n\n" - "This is a client fingerprint. You should compare this " - "fingerprint to the one on your client's screen. If the " - "two don't match exactly, then it's probably not the client " - "you're expecting (it could be a malicious user).\n\n" - "To automatically trust this fingerprint for future " - "connections, click Yes. To reject this fingerprint and " - "disconnect the client, click No.") - .arg(QString::fromStdString(barrier::format_ssl_fingerprint(fingerprint_sha256.data))) - .arg(QString::fromStdString( - barrier::create_fingerprint_randomart(fingerprint_sha256.data))); - } - messageBoxAlreadyShown = true; - QMessageBox::StandardButton fingerprintReply = - QMessageBox::information( - this, tr("Security question"), - message, - QMessageBox::Yes | QMessageBox::No); - - if (fingerprintReply == QMessageBox::Yes) { + FingerprintAcceptDialog dialog{this, barrier_type(), fingerprint_sha1, fingerprint_sha256}; + if (dialog.exec() == QDialog::Accepted) { // restart core process after trusting fingerprint. db.add_trusted(fingerprint_sha256); db.write(db_path); From 7ab8e0101da31237adc7cc50dabe8a441a0ad91c Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 05:18:49 +0200 Subject: [PATCH 087/113] lib/server: Add a note about taking pointer to virtual member function --- src/lib/server/ClientProxy1_0.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/server/ClientProxy1_0.cpp b/src/lib/server/ClientProxy1_0.cpp index 436e366e..ee7d32f0 100644 --- a/src/lib/server/ClientProxy1_0.cpp +++ b/src/lib/server/ClientProxy1_0.cpp @@ -173,6 +173,8 @@ ClientProxy1_0::parseHandshakeMessage(const UInt8* code) } else if (memcmp(code, kMsgDInfo, 4) == 0) { // future messages get parsed by parseMessage + // NOTE: we're taking address of virtual function here, + // not ClientProxy1_0 implementation of it. m_parser = &ClientProxy1_0::parseMessage; if (recvInfo()) { m_events->addEvent(Event(m_events->forClientProxy().ready(), getEventTarget())); From cc369820d45166a93972ecd0faf3aa1049a09b5a Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 05:18:50 +0200 Subject: [PATCH 088/113] lib/server: Remove unused code --- src/lib/server/ClientListener.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/lib/server/ClientListener.cpp b/src/lib/server/ClientListener.cpp index a9b3a700..f2fec8b8 100644 --- a/src/lib/server/ClientListener.cpp +++ b/src/lib/server/ClientListener.cpp @@ -183,7 +183,6 @@ ClientListener::handleUnknownClient(const Event&, void* vclient) // get the real client proxy and install it ClientProxy* client = unknownClient->orphanClientProxy(); - bool handshakeOk = true; if (client != NULL) { // handshake was successful m_waitingClients.push_back(client); @@ -196,19 +195,11 @@ ClientListener::handleUnknownClient(const Event&, void* vclient) &ClientListener::handleClientDisconnected, client)); } - else { - handshakeOk = false; - } // now finished with unknown client m_events->removeHandler(m_events->forClientProxyUnknown().success(), client); m_events->removeHandler(m_events->forClientProxyUnknown().failure(), client); m_newClients.erase(unknownClient); - PacketStreamFilter* streamFileter = dynamic_cast(unknownClient->getStream()); - IDataSocket* socket = NULL; - if (streamFileter != NULL) { - socket = dynamic_cast(streamFileter->getStream()); - } delete unknownClient; } From e33c81b835e14ca1534e3f375c17707f10a29152 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 05:18:51 +0200 Subject: [PATCH 089/113] lib: Enforce a maximum length of input messages This commit is the 1/3 part of the fix for the following security vulnerability: - CVE-2021-42076 DoS via excess length messages The issue has been reported by Matthias Gerstner . --- .../enforce-maximum-message-length.bugfix | 6 +++++ src/lib/barrier/ProtocolUtil.cpp | 10 +++++++ src/lib/barrier/protocol_types.h | 5 ++++ src/lib/client/ServerProxy.cpp | 27 +++++++++++++------ src/lib/server/ClientProxy1_0.cpp | 15 ++++++++--- 5 files changed, 52 insertions(+), 11 deletions(-) create mode 100644 doc/newsfragments/enforce-maximum-message-length.bugfix diff --git a/doc/newsfragments/enforce-maximum-message-length.bugfix b/doc/newsfragments/enforce-maximum-message-length.bugfix new file mode 100644 index 00000000..81ec2ba0 --- /dev/null +++ b/doc/newsfragments/enforce-maximum-message-length.bugfix @@ -0,0 +1,6 @@ +SECURITY ISSUE + +Barrier will now enforce a maximum length of input messages (fixes CVE-2021-42076). + +Previously it was possible for a malicious client or server to send excessive length messages +leading to denial of service by resource exhaustion. diff --git a/src/lib/barrier/ProtocolUtil.cpp b/src/lib/barrier/ProtocolUtil.cpp index 6e67b1b6..5a71010d 100644 --- a/src/lib/barrier/ProtocolUtil.cpp +++ b/src/lib/barrier/ProtocolUtil.cpp @@ -19,6 +19,8 @@ #include "barrier/ProtocolUtil.h" #include "io/IStream.h" #include "base/Log.h" +#include "barrier/protocol_types.h" +#include "barrier/XBarrier.h" #include "common/stdvector.h" #include "base/String.h" @@ -159,6 +161,10 @@ ProtocolUtil::vreadf(barrier::IStream* stream, const char* fmt, va_list args) (static_cast(buffer[2]) << 8) | static_cast(buffer[3]); + if (n > PROTOCOL_MAX_LIST_LENGTH) { + throw XBadClient("Too long message received"); + } + // convert it void* v = va_arg(args, void*); switch (len) { @@ -211,6 +217,10 @@ ProtocolUtil::vreadf(barrier::IStream* stream, const char* fmt, va_list args) (static_cast(buffer[2]) << 8) | static_cast(buffer[3]); + if (len > PROTOCOL_MAX_STRING_LENGTH) { + throw XBadClient("Too long message received"); + } + // use a fixed size buffer if its big enough const bool useFixed = (len <= sizeof(buffer)); diff --git a/src/lib/barrier/protocol_types.h b/src/lib/barrier/protocol_types.h index ccc1c3ea..188aad4a 100644 --- a/src/lib/barrier/protocol_types.h +++ b/src/lib/barrier/protocol_types.h @@ -51,6 +51,11 @@ static const double kKeepAlivesUntilDeath = 3.0; static const double kHeartRate = -1.0; static const double kHeartBeatsUntilDeath = 3.0; +// Messages of very large size indicate a likely protocol error. We don't parse such messages and +// drop connection instead. Note that e.g. the clipboard messages are already limited to 32kB. +static constexpr std::uint32_t PROTOCOL_MAX_LIST_LENGTH = 1024 * 1024; +static constexpr std::uint32_t PROTOCOL_MAX_STRING_LENGTH = 1024 * 1024; + // direction constants enum EDirection { kNoDirection, diff --git a/src/lib/client/ServerProxy.cpp b/src/lib/client/ServerProxy.cpp index ce65c72d..c6e35766 100644 --- a/src/lib/client/ServerProxy.cpp +++ b/src/lib/client/ServerProxy.cpp @@ -26,6 +26,7 @@ #include "barrier/ProtocolUtil.h" #include "barrier/option_types.h" #include "barrier/protocol_types.h" +#include "barrier/XBarrier.h" #include "io/IStream.h" #include "base/Log.h" #include "base/IEventQueue.h" @@ -124,17 +125,27 @@ ServerProxy::handleData(const Event&, void*) // parse message LOG((CLOG_DEBUG2 "msg from server: %c%c%c%c", code[0], code[1], code[2], code[3])); - switch ((this->*m_parser)(code)) { - case kOkay: - break; + try { + switch ((this->*m_parser)(code)) { + case kOkay: + break; - case kUnknown: - LOG((CLOG_ERR "invalid message from server: %c%c%c%c", code[0], code[1], code[2], code[3])); + case kUnknown: + LOG((CLOG_ERR "invalid message from server: %c%c%c%c", code[0], code[1], code[2], code[3])); + m_client->disconnect("invalid message from server"); + return; + + case kDisconnect: + return; + } + } catch (const XBadClient& e) { + // TODO: disconnect handling is currently dispersed across both parseMessage() and + // handleData() functions, we should collect that to a single place + + LOG((CLOG_ERR "protocol error from server: %s", e.what())); + ProtocolUtil::writef(m_stream, kMsgEBad); m_client->disconnect("invalid message from server"); return; - - case kDisconnect: - return; } // next message diff --git a/src/lib/server/ClientProxy1_0.cpp b/src/lib/server/ClientProxy1_0.cpp index ee7d32f0..af927f9d 100644 --- a/src/lib/server/ClientProxy1_0.cpp +++ b/src/lib/server/ClientProxy1_0.cpp @@ -148,9 +148,18 @@ ClientProxy1_0::handleData(const Event&, void*) } // parse message - LOG((CLOG_DEBUG2 "msg from \"%s\": %c%c%c%c", getName().c_str(), code[0], code[1], code[2], code[3])); - if (!(this->*m_parser)(code)) { - LOG((CLOG_ERR "invalid message from client \"%s\": %c%c%c%c", getName().c_str(), code[0], code[1], code[2], code[3])); + try { + LOG((CLOG_DEBUG2 "msg from \"%s\": %c%c%c%c", getName().c_str(), code[0], code[1], code[2], code[3])); + if (!(this->*m_parser)(code)) { + LOG((CLOG_ERR "invalid message from client \"%s\": %c%c%c%c", getName().c_str(), code[0], code[1], code[2], code[3])); + disconnect(); + return; + } + } catch (const XBadClient& e) { + // TODO: disconnect handling is currently dispersed across both parseMessage() and + // handleData() functions, we should collect that to a single place + + LOG((CLOG_ERR "protocol error from client: %s", e.what())); disconnect(); return; } From af90f39b4a00acf12def036b7ec4362b4c3404c7 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 05:18:52 +0200 Subject: [PATCH 090/113] lib/net: Limit the maximum size of TCP or SSL input buffers This commit is the 2/3 part of the fix for the following security vulnerability: - CVE-2021-42076 DoS via excess length messages The issue has been reported by Matthias Gerstner . --- src/lib/net/SecureSocket.cpp | 5 +++++ src/lib/net/TCPSocket.cpp | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index f096729d..af5a795a 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -43,6 +43,7 @@ #define MAX_ERROR_SIZE 65535 +static const std::size_t MAX_INPUT_BUFFER_SIZE = 1024 * 1024; static const float s_retryDelay = 0.01f; enum { @@ -178,6 +179,10 @@ SecureSocket::doRead() do { m_inputBuffer.write(buffer, bytesRead); + if (m_inputBuffer.getSize() > MAX_INPUT_BUFFER_SIZE) { + break; + } + status = secureRead(buffer, sizeof(buffer), bytesRead); if (status < 0) { return kBreak; diff --git a/src/lib/net/TCPSocket.cpp b/src/lib/net/TCPSocket.cpp index e19786c8..002d4d67 100644 --- a/src/lib/net/TCPSocket.cpp +++ b/src/lib/net/TCPSocket.cpp @@ -33,9 +33,7 @@ #include #include -// -// TCPSocket -// +static const std::size_t MAX_INPUT_BUFFER_SIZE = 1024 * 1024; TCPSocket::TCPSocket(IEventQueue* events, SocketMultiplexer* socketMultiplexer, IArchNetwork::EAddressFamily family) : IDataSocket(events), @@ -345,6 +343,10 @@ TCPSocket::doRead() do { m_inputBuffer.write(buffer, (UInt32)bytesRead); + if (m_inputBuffer.getSize() > MAX_INPUT_BUFFER_SIZE) { + break; + } + bytesRead = ARCH->readSocket(m_socket, buffer, sizeof(buffer)); } while (bytesRead > 0); From fd5295eb3199e7693c67b4b7116f47f50f876ef5 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 05:18:53 +0200 Subject: [PATCH 091/113] lib/barrier: Disconnect client on too long input packets This commit is the 3/3 part of the fix for the following security vulnerability: - CVE-2021-42076 DoS via excess length messages The issue has been reported by Matthias Gerstner . --- src/lib/barrier/PacketStreamFilter.cpp | 22 ++++++++++++++++------ src/lib/barrier/PacketStreamFilter.h | 4 +++- src/lib/barrier/protocol_types.h | 3 +++ src/lib/base/EventTypes.cpp | 1 + src/lib/base/EventTypes.h | 6 ++++++ src/lib/server/ClientProxy1_0.cpp | 6 ++++++ src/lib/server/ClientProxyUnknown.cpp | 6 ++++++ 7 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/lib/barrier/PacketStreamFilter.cpp b/src/lib/barrier/PacketStreamFilter.cpp index 85a85f22..5955b6c2 100644 --- a/src/lib/barrier/PacketStreamFilter.cpp +++ b/src/lib/barrier/PacketStreamFilter.cpp @@ -17,6 +17,7 @@ */ #include "barrier/PacketStreamFilter.h" +#include "barrier/protocol_types.h" #include "base/IEventQueue.h" #include "mt/Lock.h" #include "base/TMethodEventJob.h" @@ -133,8 +134,7 @@ PacketStreamFilter::isReadyNoLock() const return (m_size != 0 && m_buffer.getSize() >= m_size); } -void -PacketStreamFilter::readPacketSize() +bool PacketStreamFilter::readPacketSize() { // note -- m_mutex must be locked on entry @@ -146,7 +146,13 @@ PacketStreamFilter::readPacketSize() ((UInt32)buffer[1] << 16) | ((UInt32)buffer[2] << 8) | (UInt32)buffer[3]; + + if (m_size > PROTOCOL_MAX_MESSAGE_LENGTH) { + m_events->addEvent(Event(m_events->forIStream().inputFormatError(), getEventTarget())); + return false; + } } + return true; } bool @@ -160,13 +166,17 @@ PacketStreamFilter::readMore() UInt32 n = getStream()->read(buffer, sizeof(buffer)); while (n > 0) { m_buffer.write(buffer, n); + + // if we don't yet have the next packet size then get it, if possible. + // Note that we can't wait for whole pending data to arrive because it may be huge in + // case of malicious or erroneous peer. + if (!readPacketSize()) { + break; + } + n = getStream()->read(buffer, sizeof(buffer)); } - // if we don't yet have the next packet size then get it, - // if possible. - readPacketSize(); - // note if we now have a whole packet bool isReady = isReadyNoLock(); diff --git a/src/lib/barrier/PacketStreamFilter.h b/src/lib/barrier/PacketStreamFilter.h index 3bccafe0..0c4bb04e 100644 --- a/src/lib/barrier/PacketStreamFilter.h +++ b/src/lib/barrier/PacketStreamFilter.h @@ -47,7 +47,9 @@ protected: private: bool isReadyNoLock() const; - void readPacketSize(); + + // returns false on erroneous packet size + bool readPacketSize(); bool readMore(); private: diff --git a/src/lib/barrier/protocol_types.h b/src/lib/barrier/protocol_types.h index 188aad4a..f7306067 100644 --- a/src/lib/barrier/protocol_types.h +++ b/src/lib/barrier/protocol_types.h @@ -20,6 +20,8 @@ #include "base/EventTypes.h" +#include + // protocol version number // 1.0: initial protocol // 1.1: adds KeyCode to key press, release, and repeat @@ -53,6 +55,7 @@ static const double kHeartBeatsUntilDeath = 3.0; // Messages of very large size indicate a likely protocol error. We don't parse such messages and // drop connection instead. Note that e.g. the clipboard messages are already limited to 32kB. +static constexpr std::uint32_t PROTOCOL_MAX_MESSAGE_LENGTH = 4 * 1024 * 1024; static constexpr std::uint32_t PROTOCOL_MAX_LIST_LENGTH = 1024 * 1024; static constexpr std::uint32_t PROTOCOL_MAX_STRING_LENGTH = 1024 * 1024; diff --git a/src/lib/base/EventTypes.cpp b/src/lib/base/EventTypes.cpp index d54a2d50..173a0a97 100644 --- a/src/lib/base/EventTypes.cpp +++ b/src/lib/base/EventTypes.cpp @@ -56,6 +56,7 @@ REGISTER_EVENT(IStream, outputFlushed) REGISTER_EVENT(IStream, outputError) REGISTER_EVENT(IStream, inputShutdown) REGISTER_EVENT(IStream, outputShutdown) +REGISTER_EVENT(IStream, inputFormatError) // // IpcClient diff --git a/src/lib/base/EventTypes.h b/src/lib/base/EventTypes.h index 8b02bef4..995490e9 100644 --- a/src/lib/base/EventTypes.h +++ b/src/lib/base/EventTypes.h @@ -133,6 +133,11 @@ public: */ Event::Type outputShutdown(); + /** Get input format error event type + + This is sent when a stream receives an irrecoverable input format error. + */ + Event::Type inputFormatError(); //@} private: @@ -141,6 +146,7 @@ private: Event::Type m_outputError; Event::Type m_inputShutdown; Event::Type m_outputShutdown; + Event::Type m_inputFormatError; }; class IpcClientEvents : public EventTypes { diff --git a/src/lib/server/ClientProxy1_0.cpp b/src/lib/server/ClientProxy1_0.cpp index af927f9d..33b0f159 100644 --- a/src/lib/server/ClientProxy1_0.cpp +++ b/src/lib/server/ClientProxy1_0.cpp @@ -51,6 +51,10 @@ ClientProxy1_0::ClientProxy1_0(const std::string& name, barrier::IStream* stream stream->getEventTarget(), new TMethodEventJob(this, &ClientProxy1_0::handleDisconnect, NULL)); + m_events->adoptHandler(m_events->forIStream().inputFormatError(), + stream->getEventTarget(), + new TMethodEventJob(this, + &ClientProxy1_0::handleDisconnect, NULL)); m_events->adoptHandler(m_events->forIStream().outputShutdown(), stream->getEventTarget(), new TMethodEventJob(this, @@ -90,6 +94,8 @@ ClientProxy1_0::removeHandlers() getStream()->getEventTarget()); m_events->removeHandler(m_events->forIStream().outputShutdown(), getStream()->getEventTarget()); + m_events->removeHandler(m_events->forIStream().inputFormatError(), + getStream()->getEventTarget()); m_events->removeHandler(Event::kTimer, this); // remove timer diff --git a/src/lib/server/ClientProxyUnknown.cpp b/src/lib/server/ClientProxyUnknown.cpp index 50a6bdec..f9da361d 100644 --- a/src/lib/server/ClientProxyUnknown.cpp +++ b/src/lib/server/ClientProxyUnknown.cpp @@ -118,6 +118,10 @@ ClientProxyUnknown::addStreamHandlers() m_stream->getEventTarget(), new TMethodEventJob(this, &ClientProxyUnknown::handleDisconnect)); + m_events->adoptHandler(m_events->forIStream().inputFormatError(), + m_stream->getEventTarget(), + new TMethodEventJob(this, + &ClientProxyUnknown::handleDisconnect)); m_events->adoptHandler(m_events->forIStream().outputShutdown(), m_stream->getEventTarget(), new TMethodEventJob(this, @@ -149,6 +153,8 @@ ClientProxyUnknown::removeHandlers() m_stream->getEventTarget()); m_events->removeHandler(m_events->forIStream().inputShutdown(), m_stream->getEventTarget()); + m_events->removeHandler(m_events->forIStream().inputFormatError(), + m_stream->getEventTarget()); m_events->removeHandler(m_events->forIStream().outputShutdown(), m_stream->getEventTarget()); } From e8ac56b04584e2822e33abdf2410ae5b2907614a Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Sun, 31 Oct 2021 20:44:30 -0700 Subject: [PATCH 092/113] lib/net: Include openssl applink shim into Windows builds --- src/lib/net/SecureUtils.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/lib/net/SecureUtils.cpp b/src/lib/net/SecureUtils.cpp index 3dd2a6a8..c581dd49 100644 --- a/src/lib/net/SecureUtils.cpp +++ b/src/lib/net/SecureUtils.cpp @@ -57,6 +57,12 @@ #include #include +#if SYSAPI_WIN32 +// Windows builds require a shim that makes it possible to link to different +// versions of the Win32 C runtime. See OpenSSL FAQ. +#include +#endif + namespace barrier { namespace { From 676fa39f9ade5d89c5f5e70015025267afc4b84f Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 05:53:20 +0200 Subject: [PATCH 093/113] lib/platform: Switch remaining ObjC source files to ObjC++ --- src/lib/platform/{OSXDragSimulator.m => OSXDragSimulator.mm} | 0 src/lib/platform/{OSXDragView.m => OSXDragView.mm} | 0 .../{OSXMediaKeySimulator.m => OSXMediaKeySimulator.mm} | 4 ++-- .../platform/{OSXMediaKeySupport.m => OSXMediaKeySupport.mm} | 4 ++-- .../{OSXPasteboardPeeker.m => OSXPasteboardPeeker.mm} | 0 .../platform/{OSXScreenSaverUtil.m => OSXScreenSaverUtil.mm} | 0 6 files changed, 4 insertions(+), 4 deletions(-) rename src/lib/platform/{OSXDragSimulator.m => OSXDragSimulator.mm} (100%) rename src/lib/platform/{OSXDragView.m => OSXDragView.mm} (100%) rename src/lib/platform/{OSXMediaKeySimulator.m => OSXMediaKeySimulator.mm} (96%) rename src/lib/platform/{OSXMediaKeySupport.m => OSXMediaKeySupport.mm} (97%) rename src/lib/platform/{OSXPasteboardPeeker.m => OSXPasteboardPeeker.mm} (100%) rename src/lib/platform/{OSXScreenSaverUtil.m => OSXScreenSaverUtil.mm} (100%) diff --git a/src/lib/platform/OSXDragSimulator.m b/src/lib/platform/OSXDragSimulator.mm similarity index 100% rename from src/lib/platform/OSXDragSimulator.m rename to src/lib/platform/OSXDragSimulator.mm diff --git a/src/lib/platform/OSXDragView.m b/src/lib/platform/OSXDragView.mm similarity index 100% rename from src/lib/platform/OSXDragView.m rename to src/lib/platform/OSXDragView.mm diff --git a/src/lib/platform/OSXMediaKeySimulator.m b/src/lib/platform/OSXMediaKeySimulator.mm similarity index 96% rename from src/lib/platform/OSXMediaKeySimulator.m rename to src/lib/platform/OSXMediaKeySimulator.mm index 5aacd107..efc4251b 100644 --- a/src/lib/platform/OSXMediaKeySimulator.m +++ b/src/lib/platform/OSXMediaKeySimulator.mm @@ -85,8 +85,8 @@ fakeNativeMediaKey(KeyID id) data2:-1]; CGEventRef upEvent = [upRef CGEvent]; - CGEventPost(0, downEvent); - CGEventPost(0, upEvent); + CGEventPost(kCGHIDEventTap, downEvent); + CGEventPost(kCGHIDEventTap, upEvent); return true; } diff --git a/src/lib/platform/OSXMediaKeySupport.m b/src/lib/platform/OSXMediaKeySupport.mm similarity index 97% rename from src/lib/platform/OSXMediaKeySupport.m rename to src/lib/platform/OSXMediaKeySupport.mm index 9c9dbc31..a4d57679 100644 --- a/src/lib/platform/OSXMediaKeySupport.m +++ b/src/lib/platform/OSXMediaKeySupport.mm @@ -147,8 +147,8 @@ fakeNativeMediaKey(KeyID id) data2:-1]; CGEventRef upEvent = [upRef CGEvent]; - CGEventPost(0, downEvent); - CGEventPost(0, upEvent); + CGEventPost(kCGHIDEventTap, downEvent); + CGEventPost(kCGHIDEventTap, upEvent); return true; } diff --git a/src/lib/platform/OSXPasteboardPeeker.m b/src/lib/platform/OSXPasteboardPeeker.mm similarity index 100% rename from src/lib/platform/OSXPasteboardPeeker.m rename to src/lib/platform/OSXPasteboardPeeker.mm diff --git a/src/lib/platform/OSXScreenSaverUtil.m b/src/lib/platform/OSXScreenSaverUtil.mm similarity index 100% rename from src/lib/platform/OSXScreenSaverUtil.m rename to src/lib/platform/OSXScreenSaverUtil.mm From 20f66fe1332057c2338179a700527142e778b874 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 05:53:21 +0200 Subject: [PATCH 094/113] lib/common: Clean up declarations of {S,U}Int{8,16,32} types --- src/lib/barrier/Chunk.h | 2 +- src/lib/barrier/key_types.cpp | 1 + src/lib/common/basic_types.h | 63 ++++------------------------------- src/lib/common/common.h | 13 -------- src/lib/io/StreamBuffer.cpp | 2 ++ 5 files changed, 11 insertions(+), 70 deletions(-) diff --git a/src/lib/barrier/Chunk.h b/src/lib/barrier/Chunk.h index 07f0360d..26a343df 100644 --- a/src/lib/barrier/Chunk.h +++ b/src/lib/barrier/Chunk.h @@ -17,7 +17,7 @@ #pragma once -#include "common/basic_types.h" +#include class Chunk { public: diff --git a/src/lib/barrier/key_types.cpp b/src/lib/barrier/key_types.cpp index 43fd69b1..33ee3ebc 100644 --- a/src/lib/barrier/key_types.cpp +++ b/src/lib/barrier/key_types.cpp @@ -17,6 +17,7 @@ */ #include "barrier/key_types.h" +#include const KeyNameMapEntry kKeyNameMap[] = { { "AltGr", kKeyAltGr }, diff --git a/src/lib/common/basic_types.h b/src/lib/common/basic_types.h index 86300ca9..1882e57e 100644 --- a/src/lib/common/basic_types.h +++ b/src/lib/common/basic_types.h @@ -18,49 +18,7 @@ #pragma once -#include "common/common.h" - -// -// pick types of particular sizes -// - -#if !defined(TYPE_OF_SIZE_1) -# if SIZEOF_CHAR == 1 -# define TYPE_OF_SIZE_1 char -# endif -#endif - -#if !defined(TYPE_OF_SIZE_2) -# if SIZEOF_INT == 2 -# define TYPE_OF_SIZE_2 int -# else -# define TYPE_OF_SIZE_2 short -# endif -#endif - -#if !defined(TYPE_OF_SIZE_4) - // Carbon defines SInt32 and UInt32 in terms of long -# if SIZEOF_INT == 4 && !defined(__APPLE__) -# define TYPE_OF_SIZE_4 int -# else -# define TYPE_OF_SIZE_4 long -# endif -#endif - - // -// verify existence of required types -// - -#if !defined(TYPE_OF_SIZE_1) -# error No 1 byte integer type -#endif -#if !defined(TYPE_OF_SIZE_2) -# error No 2 byte integer type -#endif -#if !defined(TYPE_OF_SIZE_4) -# error No 4 byte integer type -#endif - +#include // // make typedefs @@ -75,18 +33,11 @@ #if defined(__APPLE__) #include #else -typedef signed TYPE_OF_SIZE_1 SInt8; -typedef signed TYPE_OF_SIZE_2 SInt16; -typedef signed TYPE_OF_SIZE_4 SInt32; -typedef unsigned TYPE_OF_SIZE_1 UInt8; -typedef unsigned TYPE_OF_SIZE_2 UInt16; -typedef unsigned TYPE_OF_SIZE_4 UInt32; +using SInt8 = std::int8_t; +using SInt16 = std::int16_t; +using SInt32 = std::int32_t; +using UInt8 = std::uint8_t; +using UInt16 = std::uint16_t; +using UInt32 = std::uint32_t; #endif #endif -// -// clean up -// - -#undef TYPE_OF_SIZE_1 -#undef TYPE_OF_SIZE_2 -#undef TYPE_OF_SIZE_4 diff --git a/src/lib/common/common.h b/src/lib/common/common.h index 2feea235..39462568 100644 --- a/src/lib/common/common.h +++ b/src/lib/common/common.h @@ -22,19 +22,6 @@ # include "config.h" #endif -// VC++ has built-in sized types -#if defined(_MSC_VER) -# include -# define TYPE_OF_SIZE_1 __int8 -# define TYPE_OF_SIZE_2 __int16 -# define TYPE_OF_SIZE_4 __int32 -#else -# define SIZE_OF_CHAR 1 -# define SIZE_OF_SHORT 2 -# define SIZE_OF_INT 4 -# define SIZE_OF_LONG 4 -#endif - // define NULL #include diff --git a/src/lib/io/StreamBuffer.cpp b/src/lib/io/StreamBuffer.cpp index 34bb47cc..8abbbb82 100644 --- a/src/lib/io/StreamBuffer.cpp +++ b/src/lib/io/StreamBuffer.cpp @@ -22,6 +22,8 @@ // StreamBuffer // +#include + const UInt32 StreamBuffer::kChunkSize = 4096; StreamBuffer::StreamBuffer() : From deefecc262319fba9b2f2d8b470ebbc52c412575 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:53:24 +0200 Subject: [PATCH 095/113] lib/server: Close connection when client app-level handshake fails This fixes the following security vulnerability: - CVE-2021-42075 DoS via file descriptor exhaustion The issue has been reported by Matthias Gerstner . --- doc/newsfragments/close-failed-handshake-connections.bugfix | 6 ++++++ src/lib/server/ClientListener.cpp | 5 +++++ 2 files changed, 11 insertions(+) create mode 100644 doc/newsfragments/close-failed-handshake-connections.bugfix diff --git a/doc/newsfragments/close-failed-handshake-connections.bugfix b/doc/newsfragments/close-failed-handshake-connections.bugfix new file mode 100644 index 00000000..0dc8c16c --- /dev/null +++ b/doc/newsfragments/close-failed-handshake-connections.bugfix @@ -0,0 +1,6 @@ +SECURITY ISSUE + +Barrier will now correctly close connections when the app-level handshake fails (fixes CVE-2021-42075). + +Previously repeated failing connections would leak file descriptors leading to Barrier being unable +to receive new connections from clients. diff --git a/src/lib/server/ClientListener.cpp b/src/lib/server/ClientListener.cpp index f2fec8b8..75724bc0 100644 --- a/src/lib/server/ClientListener.cpp +++ b/src/lib/server/ClientListener.cpp @@ -194,6 +194,11 @@ ClientListener::handleUnknownClient(const Event&, void* vclient) new TMethodEventJob(this, &ClientListener::handleClientDisconnected, client)); + } else { + auto* stream = unknownClient->getStream(); + if (stream) { + stream->close(); + } } // now finished with unknown client From 8b937a4abd5425b6588c3e096f6daf16343674c4 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:53:26 +0200 Subject: [PATCH 096/113] lib/net: Fix race conditions when closing SSL connections This fixes the following security vulnerability: - CVE-2021-42074 SIGSEGV on quick open/close sequence while sending Hello message The issue has been reported by Matthias Gerstner . --- .../fix-crash-on-ssl-hello.bugfix | 4 +++ src/lib/net/SecureSocket.cpp | 28 +++++++++++++++++++ src/lib/net/SecureSocket.h | 24 +++++++++++----- 3 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 doc/newsfragments/fix-crash-on-ssl-hello.bugfix diff --git a/doc/newsfragments/fix-crash-on-ssl-hello.bugfix b/doc/newsfragments/fix-crash-on-ssl-hello.bugfix new file mode 100644 index 00000000..30bb0603 --- /dev/null +++ b/doc/newsfragments/fix-crash-on-ssl-hello.bugfix @@ -0,0 +1,4 @@ +SECURITY ISSUE + +Fixed a bug which caused Barrier to crash when disconnecting a TCP session just after sending Hello message. +This bug allowed an unauthenticated attacker to crash Barrier with only network access. diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index af5a795a..197ee832 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -101,6 +101,8 @@ SecureSocket::close() void SecureSocket::freeSSLResources() { + std::lock_guard ssl_lock{ssl_mutex_}; + if (m_ssl->m_ssl != NULL) { SSL_shutdown(m_ssl->m_ssl); SSL_free(m_ssl->m_ssl); @@ -265,6 +267,8 @@ SecureSocket::doWrite() int SecureSocket::secureRead(void* buffer, int size, int& read) { + std::lock_guard ssl_lock{ssl_mutex_}; + if (m_ssl->m_ssl != NULL) { LOG((CLOG_DEBUG2 "reading secure socket")); read = SSL_read(m_ssl->m_ssl, buffer, size); @@ -291,6 +295,8 @@ SecureSocket::secureRead(void* buffer, int size, int& read) int SecureSocket::secureWrite(const void* buffer, int size, int& wrote) { + std::lock_guard ssl_lock{ssl_mutex_}; + if (m_ssl->m_ssl != NULL) { LOG((CLOG_DEBUG2 "writing secure socket:%p", this)); @@ -324,6 +330,8 @@ SecureSocket::isSecureReady() void SecureSocket::initSsl(bool server) { + std::lock_guard ssl_lock{ssl_mutex_}; + m_ssl = new Ssl(); m_ssl->m_context = NULL; m_ssl->m_ssl = NULL; @@ -333,6 +341,8 @@ SecureSocket::initSsl(bool server) bool SecureSocket::load_certificates(const barrier::fs::path& path) { + std::lock_guard ssl_lock{ssl_mutex_}; + if (path.empty()) { showError("ssl certificate is not specified"); return false; @@ -374,6 +384,8 @@ static int cert_verify_ignore_callback(X509_STORE_CTX*, void*) void SecureSocket::initContext(bool server) { + // ssl_mutex_ is assumed to be acquired + SSL_library_init(); const SSL_METHOD* method; @@ -419,6 +431,8 @@ SecureSocket::initContext(bool server) void SecureSocket::createSSL() { + // ssl_mutex_ is assumed to be acquired + // I assume just one instance is needed // get new SSL state with context if (m_ssl->m_ssl == NULL) { @@ -430,6 +444,8 @@ SecureSocket::createSSL() int SecureSocket::secureAccept(int socket) { + std::lock_guard ssl_lock{ssl_mutex_}; + createSSL(); // set connection socket to SSL state @@ -497,12 +513,15 @@ SecureSocket::secureAccept(int socket) int SecureSocket::secureConnect(int socket) { + // note that load_certificates acquires ssl_mutex_ if (!load_certificates(barrier::DataDirectories::ssl_certificate_path())) { LOG((CLOG_ERR "could not load client certificates")); // FIXME: this is fatal error, but we current don't disconnect because whole logic in this // function needs to be cleaned up } + std::lock_guard ssl_lock{ssl_mutex_}; + createSSL(); // attach the socket descriptor @@ -555,6 +574,7 @@ SecureSocket::secureConnect(int socket) bool SecureSocket::ensure_peer_certificate() { + // ssl_mutex_ is assumed to be acquired X509* cert; char* line; @@ -577,6 +597,8 @@ SecureSocket::ensure_peer_certificate() void SecureSocket::checkResult(int status, int& retry) { + // ssl_mutex_ is assumed to be acquired + // ssl errors are a little quirky. the "want" errors are normal and // should result in a retry. @@ -692,6 +714,8 @@ SecureSocket::disconnect() bool SecureSocket::verify_cert_fingerprint(const barrier::fs::path& fingerprint_db_path) { + // ssl_mutex_ is assumed to be acquired + // calculate received certificate fingerprint barrier::FingerprintData fingerprint_sha1, fingerprint_sha256; try { @@ -818,6 +842,8 @@ showCipherStackDesc(STACK_OF(SSL_CIPHER) * stack) { void SecureSocket::showSecureCipherInfo() { + // ssl_mutex_ is assumed to be acquired + STACK_OF(SSL_CIPHER) * sStack = SSL_get_ciphers(m_ssl->m_ssl); if (sStack == NULL) { @@ -860,6 +886,8 @@ SecureSocket::showSecureLibInfo() void SecureSocket::showSecureConnectInfo() { + // ssl_mutex_ is assumed to be acquired + const SSL_CIPHER* cipher = SSL_get_current_cipher(m_ssl->m_ssl); if (cipher != NULL) { diff --git a/src/lib/net/SecureSocket.h b/src/lib/net/SecureSocket.h index 496a3656..c50ece11 100644 --- a/src/lib/net/SecureSocket.h +++ b/src/lib/net/SecureSocket.h @@ -21,6 +21,7 @@ #include "net/TCPSocket.h" #include "net/XSocket.h" #include "io/filesystem.h" +#include class IEventQueue; class SocketMultiplexer; @@ -61,29 +62,38 @@ public: private: // SSL - void initContext(bool server); - void createSSL(); + void initContext(bool server); // may only be called with ssl_mutex_ acquired + void createSSL(); // may only be called with ssl_mutex_ acquired. int secureAccept(int s); int secureConnect(int s); - bool ensure_peer_certificate(); - void checkResult(int n, int& retry); + bool ensure_peer_certificate(); // may only be called with ssl_mutex_ acquired + + void checkResult(int n, int& retry); // may only be called with m_ssl_mutex_ acquired. + void showError(const std::string& reason); std::string getError(); void disconnect(); + + // may only be called with ssl_mutex_ acquired bool verify_cert_fingerprint(const barrier::fs::path& fingerprint_db_path); MultiplexerJobStatus serviceConnect(ISocketMultiplexerJob*, bool, bool, bool); MultiplexerJobStatus serviceAccept(ISocketMultiplexerJob*, bool, bool, bool); - void showSecureConnectInfo(); - void showSecureLibInfo(); - void showSecureCipherInfo(); + void showSecureConnectInfo(); // may only be called with ssl_mutex_ acquired + void showSecureLibInfo(); + void showSecureCipherInfo(); // may only be called with ssl_mutex_ acquired void handleTCPConnected(const Event& event, void*); void freeSSLResources(); private: + // all accesses to m_ssl must be protected by this mutex. The only function that is called + // from outside SocketMultiplexer thread is close(), so we mostly care about things accessed + // by it. + std::mutex ssl_mutex_; + Ssl* m_ssl; bool m_secureReady; bool m_fatal; From f0efe043bbed01294c684c8d5c69cbfc77a3b050 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 02:53:27 +0200 Subject: [PATCH 097/113] lib/net: Fix incorrect sharing of data between different SSL sessions --- doc/newsfragments/ssl-corrupted-data.bugfix | 2 + src/lib/net/SecureSocket.cpp | 63 ++++++++------------- src/lib/net/SecureSocket.h | 12 ++++ 3 files changed, 39 insertions(+), 38 deletions(-) create mode 100644 doc/newsfragments/ssl-corrupted-data.bugfix diff --git a/doc/newsfragments/ssl-corrupted-data.bugfix b/doc/newsfragments/ssl-corrupted-data.bugfix new file mode 100644 index 00000000..db8bbf86 --- /dev/null +++ b/doc/newsfragments/ssl-corrupted-data.bugfix @@ -0,0 +1,2 @@ +Fixed a bug in SSL implementation that caused invalid data occasionally being sent to clients +under heavy load. diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index 197ee832..d6199f09 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -156,7 +156,7 @@ SecureSocket::secureAccept() TCPSocket::EJobResult SecureSocket::doRead() { - static UInt8 buffer[4096]; + UInt8 buffer[4096]; memset(buffer, 0, sizeof(buffer)); int bytesRead = 0; int status = 0; @@ -215,11 +215,6 @@ SecureSocket::doRead() TCPSocket::EJobResult SecureSocket::doWrite() { - static bool s_retry = false; - static int s_retrySize = 0; - static std::unique_ptr s_staticBuffer; - static std::size_t s_staticBufferSize = 0; - // write data int bufferSize = 0; int bytesWrote = 0; @@ -228,16 +223,16 @@ SecureSocket::doWrite() if (!isSecureReady()) return kRetry; - if (s_retry) { - bufferSize = s_retrySize; + if (do_write_retry_) { + bufferSize = do_write_retry_size_; } else { bufferSize = m_outputBuffer.getSize(); - if (bufferSize > s_staticBufferSize) { - s_staticBuffer.reset(new char[bufferSize]); - s_staticBufferSize = bufferSize; + if (bufferSize > do_write_retry_buffer_size_) { + do_write_retry_buffer_.reset(new char[bufferSize]); + do_write_retry_buffer_size_ = bufferSize; } if (bufferSize > 0) { - memcpy(s_staticBuffer.get(), m_outputBuffer.peek(bufferSize), bufferSize); + std::memcpy(do_write_retry_buffer_.get(), m_outputBuffer.peek(bufferSize), bufferSize); } } @@ -245,14 +240,14 @@ SecureSocket::doWrite() return kRetry; } - status = secureWrite(s_staticBuffer.get(), bufferSize, bytesWrote); + status = secureWrite(do_write_retry_buffer_.get(), bufferSize, bytesWrote); if (status > 0) { - s_retry = false; + do_write_retry_ = false; } else if (status < 0) { return kBreak; } else if (status == 0) { - s_retry = true; - s_retrySize = bufferSize; + do_write_retry_ = true; + do_write_retry_size_ = bufferSize; return kNew; } @@ -273,12 +268,10 @@ SecureSocket::secureRead(void* buffer, int size, int& read) LOG((CLOG_DEBUG2 "reading secure socket")); read = SSL_read(m_ssl->m_ssl, buffer, size); - static int retry; - // Check result will cleanup the connection in the case of a fatal - checkResult(read, retry); + checkResult(read, secure_read_retry_); - if (retry) { + if (secure_read_retry_) { return 0; } @@ -302,12 +295,10 @@ SecureSocket::secureWrite(const void* buffer, int size, int& wrote) wrote = SSL_write(m_ssl->m_ssl, buffer, size); - static int retry; - // Check result will cleanup the connection in the case of a fatal - checkResult(wrote, retry); + checkResult(wrote, secure_write_retry_); - if (retry) { + if (secure_write_retry_) { return 0; } @@ -454,9 +445,7 @@ SecureSocket::secureAccept(int socket) LOG((CLOG_DEBUG2 "accepting secure socket")); int r = SSL_accept(m_ssl->m_ssl); - static int retry; - - checkResult(r, retry); + checkResult(r, secure_accept_retry_); if (isFatal()) { // tell user and sleep so the socket isn't hammered. @@ -464,25 +453,25 @@ SecureSocket::secureAccept(int socket) LOG((CLOG_INFO "client connection may not be secure")); m_secureReady = false; ARCH->sleep(1); - retry = 0; + secure_accept_retry_ = 0; return -1; // Failed, error out } // If not fatal and no retry, state is good - if (retry == 0) { + if (secure_accept_retry_ == 0) { if (security_level_ == ConnectionSecurityLevel::ENCRYPTED_AUTHENTICATED) { if (verify_cert_fingerprint( barrier::DataDirectories::trusted_clients_ssl_fingerprints_path())) { LOG((CLOG_INFO "accepted secure socket")); if (!ensure_peer_certificate()) { - retry = 0; + secure_accept_retry_ = 0; disconnect(); return -1;// Cert fail, error } } else { LOG((CLOG_ERR "failed to verify server certificate fingerprint")); - retry = 0; + secure_accept_retry_ = 0; disconnect(); return -1; // Fingerprint failed, error } @@ -498,7 +487,7 @@ SecureSocket::secureAccept(int socket) } // If not fatal and retry is set, not ready, and return retry - if (retry > 0) { + if (secure_accept_retry_ > 0) { LOG((CLOG_DEBUG2 "retry accepting secure socket")); m_secureReady = false; ARCH->sleep(s_retryDelay); @@ -530,25 +519,23 @@ SecureSocket::secureConnect(int socket) LOG((CLOG_DEBUG2 "connecting secure socket")); int r = SSL_connect(m_ssl->m_ssl); - static int retry; - - checkResult(r, retry); + checkResult(r, secure_connect_retry_); if (isFatal()) { LOG((CLOG_ERR "failed to connect secure socket")); - retry = 0; + secure_connect_retry_ = 0; return -1; } // If we should retry, not ready and return 0 - if (retry > 0) { + if (secure_connect_retry_ > 0) { LOG((CLOG_DEBUG2 "retry connect secure socket")); m_secureReady = false; ARCH->sleep(s_retryDelay); return 0; } - retry = 0; + secure_connect_retry_ = 0; // No error, set ready, process and return ok m_secureReady = true; if (verify_cert_fingerprint(barrier::DataDirectories::trusted_servers_ssl_fingerprints_path())) { diff --git a/src/lib/net/SecureSocket.h b/src/lib/net/SecureSocket.h index c50ece11..be7dc0dd 100644 --- a/src/lib/net/SecureSocket.h +++ b/src/lib/net/SecureSocket.h @@ -98,4 +98,16 @@ private: bool m_secureReady; bool m_fatal; ConnectionSecurityLevel security_level_ = ConnectionSecurityLevel::ENCRYPTED; + + int secure_accept_retry_ = 0; // used only in secureAccept() + int secure_connect_retry_ = 0; // used only in secureConnect() + int secure_read_retry_ = 0; // used only in secureRead() + int secure_write_retry_ = 0; // used only in secureWrite() + + // The following are used only from doWrite() + // FIXME: using std::vector would simplify logic significantly. + bool do_write_retry_ = false; + int do_write_retry_size_ = 0; + std::unique_ptr do_write_retry_buffer_; + std::size_t do_write_retry_buffer_size_ = 0; }; From 666460aced4885c81457b2c1758f2a8ffd6e432a Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 06:16:29 +0200 Subject: [PATCH 098/113] lib/platform: Use std::function instead of IJob in MSWindowsDesks --- src/lib/platform/MSWindowsDesks.cpp | 9 +++------ src/lib/platform/MSWindowsDesks.h | 7 ++++--- src/lib/platform/MSWindowsScreen.cpp | 5 ++--- src/lib/platform/MSWindowsScreen.h | 2 +- src/test/integtests/platform/MSWindowsKeyStateTests.cpp | 7 +------ 5 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/lib/platform/MSWindowsDesks.cpp b/src/lib/platform/MSWindowsDesks.cpp index 848ded78..c1298cb9 100644 --- a/src/lib/platform/MSWindowsDesks.cpp +++ b/src/lib/platform/MSWindowsDesks.cpp @@ -27,7 +27,6 @@ #include "arch/win32/ArchMiscWindows.h" #include "base/Log.h" #include "base/IEventQueue.h" -#include "base/IJob.h" #include "base/TMethodEventJob.h" #include "base/TMethodJob.h" #include "base/IEventQueue.h" @@ -97,10 +96,9 @@ // MSWindowsDesks // -MSWindowsDesks::MSWindowsDesks( - bool isPrimary, bool noHooks, +MSWindowsDesks::MSWindowsDesks(bool isPrimary, bool noHooks, const IScreenSaver* screensaver, IEventQueue* events, - IJob* updateKeys, bool stopOnDeskSwitch) : + const std::function& updateKeys, bool stopOnDeskSwitch) : m_isPrimary(isPrimary), m_noHooks(noHooks), m_isOnScreen(m_isPrimary), @@ -130,7 +128,6 @@ MSWindowsDesks::~MSWindowsDesks() disable(); destroyClass(m_deskClass); destroyCursor(m_cursor); - delete m_updateKeys; } void @@ -709,7 +706,7 @@ MSWindowsDesks::deskThread(void* vdesk) } case BARRIER_MSG_SYNC_KEYS: - m_updateKeys->run(); + m_updateKeys(); break; case BARRIER_MSG_SCREENSAVER: diff --git a/src/lib/platform/MSWindowsDesks.h b/src/lib/platform/MSWindowsDesks.h index 65d93ef5..8cd7bfbe 100644 --- a/src/lib/platform/MSWindowsDesks.h +++ b/src/lib/platform/MSWindowsDesks.h @@ -26,15 +26,16 @@ #include "mt/CondVar.h" #include "mt/Mutex.h" #include "common/stdmap.h" +#include #include #define WIN32_LEAN_AND_MEAN #include + class Event; class EventQueueTimer; class Thread; -class IJob; class IScreenSaver; class IEventQueue; @@ -68,7 +69,7 @@ public: MSWindowsDesks( bool isPrimary, bool noHooks, const IScreenSaver* screensaver, IEventQueue* events, - IJob* updateKeys, bool stopOnDeskSwitch); + const std::function& updateKeys, bool stopOnDeskSwitch); ~MSWindowsDesks(); //! @name manipulators @@ -284,7 +285,7 @@ private: Desks m_desks; // keyboard stuff - IJob* m_updateKeys; + std::function m_updateKeys; HKL m_keyLayout; // options diff --git a/src/lib/platform/MSWindowsScreen.cpp b/src/lib/platform/MSWindowsScreen.cpp index 2449ba7c..1714d45a 100644 --- a/src/lib/platform/MSWindowsScreen.cpp +++ b/src/lib/platform/MSWindowsScreen.cpp @@ -134,8 +134,7 @@ MSWindowsScreen::MSWindowsScreen( m_noHooks, m_screensaver, m_events, - new TMethodJob( - this, &MSWindowsScreen::updateKeysCB), + [this]() { updateKeysCB(); }, stopOnDeskSwitch); m_keyState = new MSWindowsKeyState(m_desks, getEventTarget(), m_events); @@ -1713,7 +1712,7 @@ MSWindowsScreen::mapPressFromEvent(WPARAM msg, LPARAM) const } void -MSWindowsScreen::updateKeysCB(void*) +MSWindowsScreen::updateKeysCB() { // record which keys we think are down bool down[IKeyState::kNumButtons]; diff --git a/src/lib/platform/MSWindowsScreen.h b/src/lib/platform/MSWindowsScreen.h index ae53f1ad..b89e8bae 100644 --- a/src/lib/platform/MSWindowsScreen.h +++ b/src/lib/platform/MSWindowsScreen.h @@ -199,7 +199,7 @@ private: // HACK bool mapPressFromEvent(WPARAM msg, LPARAM button) const; // job to update the key state - void updateKeysCB(void*); + void updateKeysCB(); // determine whether the mouse is hidden by the system and force // it to be displayed if user has entered this secondary screen. diff --git a/src/test/integtests/platform/MSWindowsKeyStateTests.cpp b/src/test/integtests/platform/MSWindowsKeyStateTests.cpp index 79935d89..5af3e89d 100644 --- a/src/test/integtests/platform/MSWindowsKeyStateTests.cpp +++ b/src/test/integtests/platform/MSWindowsKeyStateTests.cpp @@ -50,10 +50,7 @@ protected: MSWindowsDesks* newDesks(IEventQueue* eventQueue) { - return new MSWindowsDesks( - true, false, m_screensaver, eventQueue, - new TMethodJob( - this, &MSWindowsKeyStateTests::updateKeysCB), false); + return new MSWindowsDesks(true, false, m_screensaver, eventQueue, [](){}, false); } void* getEventTarget() const @@ -62,9 +59,7 @@ protected: } private: - void updateKeysCB(void*) { } IScreenSaver* m_screensaver; - MSWindowsHook m_hook; }; TEST_F(MSWindowsKeyStateTests, disable_eventQueueNotUsed) From 815e80ec4d0855be5049504f483cbc4f2e357d15 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 06:16:30 +0200 Subject: [PATCH 099/113] lib: Remove unused threading functionality related to thread results --- src/lib/arch/IArchMultithread.h | 9 -------- src/lib/arch/unix/ArchMultithreadPosix.cpp | 14 +----------- src/lib/arch/unix/ArchMultithreadPosix.h | 1 - src/lib/arch/win32/ArchMultithreadWindows.cpp | 17 +------------- src/lib/arch/win32/ArchMultithreadWindows.h | 1 - src/lib/mt/Thread.cpp | 22 ++++--------------- src/lib/mt/Thread.h | 13 +---------- src/lib/mt/XThread.h | 10 +-------- 8 files changed, 8 insertions(+), 79 deletions(-) diff --git a/src/lib/arch/IArchMultithread.h b/src/lib/arch/IArchMultithread.h index a9051799..b936fc88 100644 --- a/src/lib/arch/IArchMultithread.h +++ b/src/lib/arch/IArchMultithread.h @@ -235,15 +235,6 @@ public: */ virtual bool isExitedThread(ArchThread thread) = 0; - //! Returns the exit code of a thread - /*! - Waits indefinitely for \c thread to exit (if it hasn't yet) then - returns the thread's exit code. - - (Cancellation point) - */ - virtual void* getResultOfThread(ArchThread thread) = 0; - //! Returns an ID for a thread /*! Returns some ID number for \c thread. This is for logging purposes. diff --git a/src/lib/arch/unix/ArchMultithreadPosix.cpp b/src/lib/arch/unix/ArchMultithreadPosix.cpp index 425b443c..e260e66e 100644 --- a/src/lib/arch/unix/ArchMultithreadPosix.cpp +++ b/src/lib/arch/unix/ArchMultithreadPosix.cpp @@ -64,7 +64,6 @@ public: bool m_cancel; bool m_cancelling; bool m_exited; - void* m_result; void* m_networkData; }; @@ -76,7 +75,6 @@ ArchThreadImpl::ArchThreadImpl() : m_cancel(false), m_cancelling(false), m_exited(false), - m_result(NULL), m_networkData(NULL) { // do nothing @@ -526,13 +524,6 @@ ArchMultithreadPosix::isExitedThread(ArchThread thread) return thread->m_exited; } -void* -ArchMultithreadPosix::getResultOfThread(ArchThread thread) -{ - std::lock_guard lock(m_threadMutex); - return thread->m_result; -} - IArchMultithread::ThreadID ArchMultithreadPosix::getIDOfThread(ArchThread thread) { @@ -699,10 +690,8 @@ ArchMultithreadPosix::doThreadFunc(ArchThread thread) std::lock_guard lock(m_threadMutex); } - void* result = NULL; try { - // go - result = (*thread->m_func)(thread->m_userData); + (*thread->m_func)(thread->m_userData); } catch (XThreadCancel&) { @@ -721,7 +710,6 @@ ArchMultithreadPosix::doThreadFunc(ArchThread thread) // thread has exited { std::lock_guard lock(m_threadMutex); - thread->m_result = result; thread->m_exited = true; } diff --git a/src/lib/arch/unix/ArchMultithreadPosix.h b/src/lib/arch/unix/ArchMultithreadPosix.h index 7f492415..b77dccca 100644 --- a/src/lib/arch/unix/ArchMultithreadPosix.h +++ b/src/lib/arch/unix/ArchMultithreadPosix.h @@ -77,7 +77,6 @@ public: virtual bool wait(ArchThread, double timeout); virtual bool isSameThread(ArchThread, ArchThread); virtual bool isExitedThread(ArchThread); - virtual void* getResultOfThread(ArchThread); virtual ThreadID getIDOfThread(ArchThread); virtual void setSignalHandler(ESignal, SignalFunc, void*); virtual void raiseSignal(ESignal); diff --git a/src/lib/arch/win32/ArchMultithreadWindows.cpp b/src/lib/arch/win32/ArchMultithreadWindows.cpp index 45fa31ef..48bed64b 100644 --- a/src/lib/arch/win32/ArchMultithreadWindows.cpp +++ b/src/lib/arch/win32/ArchMultithreadWindows.cpp @@ -54,7 +54,6 @@ public: HANDLE m_cancel; bool m_cancelling; HANDLE m_exit; - void* m_result; void* m_networkData; }; @@ -65,7 +64,6 @@ ArchThreadImpl::ArchThreadImpl() : m_func(NULL), m_userData(NULL), m_cancelling(false), - m_result(NULL), m_networkData(NULL) { m_exit = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -523,15 +521,6 @@ ArchMultithreadWindows::isExitedThread(ArchThread thread) return (WaitForSingleObject(thread->m_exit, 0) == WAIT_OBJECT_0); } -void* -ArchMultithreadWindows::getResultOfThread(ArchThread thread) -{ - lockMutex(m_threadMutex); - void* result = thread->m_result; - unlockMutex(m_threadMutex); - return result; -} - IArchMultithread::ThreadID ArchMultithreadWindows::getIDOfThread(ArchThread thread) { @@ -678,10 +667,9 @@ ArchMultithreadWindows::doThreadFunc(ArchThread thread) lockMutex(m_threadMutex); unlockMutex(m_threadMutex); - void* result = NULL; try { // go - result = (*thread->m_func)(thread->m_userData); + (*thread->m_func)(thread->m_userData); } catch (XThreadCancel&) { @@ -695,9 +683,6 @@ ArchMultithreadWindows::doThreadFunc(ArchThread thread) } // thread has exited - lockMutex(m_threadMutex); - thread->m_result = result; - unlockMutex(m_threadMutex); SetEvent(thread->m_exit); // done with thread diff --git a/src/lib/arch/win32/ArchMultithreadWindows.h b/src/lib/arch/win32/ArchMultithreadWindows.h index c413a648..df3af6e2 100644 --- a/src/lib/arch/win32/ArchMultithreadWindows.h +++ b/src/lib/arch/win32/ArchMultithreadWindows.h @@ -83,7 +83,6 @@ public: virtual bool wait(ArchThread, double timeout); virtual bool isSameThread(ArchThread, ArchThread); virtual bool isExitedThread(ArchThread); - virtual void* getResultOfThread(ArchThread); virtual ThreadID getIDOfThread(ArchThread); virtual void setSignalHandler(ESignal, SignalFunc, void*); virtual void raiseSignal(ESignal); diff --git a/src/lib/mt/Thread.cpp b/src/lib/mt/Thread.cpp index 858fdbab..6367eb98 100644 --- a/src/lib/mt/Thread.cpp +++ b/src/lib/mt/Thread.cpp @@ -69,7 +69,7 @@ Thread::operator=(const Thread& thread) void Thread::exit(void* result) { - throw XThreadExit(result); + throw XThreadExit(); } void @@ -108,15 +108,6 @@ Thread::wait(double timeout) const return ARCH->wait(m_thread, timeout); } -void* -Thread::getResult() const -{ - if (wait()) - return ARCH->getResultOfThread(m_thread); - else - return NULL; -} - IArchMultithread::ThreadID Thread::getID() const { @@ -149,8 +140,6 @@ Thread::threadFunc(void* vjob) // get job IJob* job = static_cast(vjob); - // run job - void* result = NULL; try { // go LOG((CLOG_DEBUG1 "thread 0x%08x entry", id)); @@ -163,10 +152,8 @@ Thread::threadFunc(void* vjob) delete job; throw; } - catch (XThreadExit& e) { - // client called exit() - result = e.m_result; - LOG((CLOG_DEBUG1 "caught exit on thread 0x%08x, result %p", id, result)); + catch (XThreadExit&) { + LOG((CLOG_DEBUG1 "caught exit on thread 0x%08x", id)); } catch (XBase& e) { LOG((CLOG_ERR "exception on thread 0x%08x: %s", id, e.what())); @@ -182,6 +169,5 @@ Thread::threadFunc(void* vjob) // done with job delete job; - // return exit result - return result; + return nullptr; } diff --git a/src/lib/mt/Thread.h b/src/lib/mt/Thread.h index 8179aea0..798539d5 100644 --- a/src/lib/mt/Thread.h +++ b/src/lib/mt/Thread.h @@ -79,8 +79,7 @@ public: /*! Terminate the calling thread. This function does not return but the stack is unwound and automatic objects are destroyed, as if - exit() threw an exception (which is, in fact, what it does). The - argument is saved as the result returned by getResult(). If you + exit() threw an exception (which is, in fact, what it does). If you have \c catch(...) blocks then you should add the following before each to avoid catching the exit: \code @@ -167,16 +166,6 @@ public: */ bool wait(double timeout = -1.0) const; - //! Get the exit result - /*! - Returns the exit result. This does an implicit wait(). It returns - NULL immediately if called by a thread on itself or on a thread that - was cancelled. - - (cancellation point) - */ - void* getResult() const; - //! Get the thread id /*! Returns an integer id for this thread. This id must not be used to diff --git a/src/lib/mt/XThread.h b/src/lib/mt/XThread.h index 34177ce9..41172b33 100644 --- a/src/lib/mt/XThread.h +++ b/src/lib/mt/XThread.h @@ -26,12 +26,4 @@ Thrown by Thread::exit() to exit a thread. Clients of Thread must not throw this type but must rethrow it if caught (by XThreadExit, XThread, or ...). */ -class XThreadExit : public XThread { -public: - //! \c result is the result of the thread - XThreadExit(void* result) : m_result(result) { } - ~XThreadExit() { } - -public: - void* m_result; -}; +class XThreadExit : public XThread {}; From 9cf590ccd75eaa28ec93771ccafa283672d051c4 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 06:16:31 +0200 Subject: [PATCH 100/113] lib: Make ThreadFunc return nothing --- src/lib/arch/IArchMultithread.h | 2 +- src/lib/arch/win32/ArchTaskBarWindows.cpp | 4 +--- src/lib/arch/win32/ArchTaskBarWindows.h | 2 +- src/lib/mt/Thread.cpp | 5 +---- src/lib/mt/Thread.h | 2 +- 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/lib/arch/IArchMultithread.h b/src/lib/arch/IArchMultithread.h index b936fc88..84a3b086 100644 --- a/src/lib/arch/IArchMultithread.h +++ b/src/lib/arch/IArchMultithread.h @@ -71,7 +71,7 @@ barrier. Each architecture must implement this interface. class IArchMultithread : public IInterface { public: //! Type of thread entry point - typedef void* (*ThreadFunc)(void*); + typedef void (*ThreadFunc)(void*); //! Type of thread identifier typedef unsigned int ThreadID; //! Types of signals diff --git a/src/lib/arch/win32/ArchTaskBarWindows.cpp b/src/lib/arch/win32/ArchTaskBarWindows.cpp index 1d8eac18..988a88c2 100644 --- a/src/lib/arch/win32/ArchTaskBarWindows.cpp +++ b/src/lib/arch/win32/ArchTaskBarWindows.cpp @@ -501,11 +501,9 @@ ArchTaskBarWindows::threadMainLoop() UnregisterClass(className, instanceWin32()); } -void* -ArchTaskBarWindows::threadEntry(void* self) +void ArchTaskBarWindows::threadEntry(void* self) { static_cast(self)->threadMainLoop(); - return NULL; } HINSTANCE ArchTaskBarWindows::instanceWin32() diff --git a/src/lib/arch/win32/ArchTaskBarWindows.h b/src/lib/arch/win32/ArchTaskBarWindows.h index ee9e000e..6cf67f5a 100644 --- a/src/lib/arch/win32/ArchTaskBarWindows.h +++ b/src/lib/arch/win32/ArchTaskBarWindows.h @@ -84,7 +84,7 @@ private: static LRESULT CALLBACK staticWndProc(HWND, UINT, WPARAM, LPARAM); void threadMainLoop(); - static void* threadEntry(void*); + static void threadEntry(void*); HINSTANCE instanceWin32(); diff --git a/src/lib/mt/Thread.cpp b/src/lib/mt/Thread.cpp index 6367eb98..976a703d 100644 --- a/src/lib/mt/Thread.cpp +++ b/src/lib/mt/Thread.cpp @@ -126,8 +126,7 @@ Thread::operator!=(const Thread& thread) const return !ARCH->isSameThread(m_thread, thread.m_thread); } -void* -Thread::threadFunc(void* vjob) +void Thread::threadFunc(void* vjob) { // get this thread's id for logging IArchMultithread::ThreadID id; @@ -168,6 +167,4 @@ Thread::threadFunc(void* vjob) // done with job delete job; - - return nullptr; } diff --git a/src/lib/mt/Thread.h b/src/lib/mt/Thread.h index 798539d5..1bcaefc5 100644 --- a/src/lib/mt/Thread.h +++ b/src/lib/mt/Thread.h @@ -192,7 +192,7 @@ public: private: Thread(ArchThread); - static void* threadFunc(void*); + static void threadFunc(void*); private: ArchThread m_thread; From 53356697d92c0a2161486110ff60861c28b29b21 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 06:16:32 +0200 Subject: [PATCH 101/113] lib/arch: Pass jobs to Arch threads as std::function --- src/lib/arch/IArchMultithread.h | 3 ++- src/lib/arch/unix/ArchMultithreadPosix.cpp | 17 +++++------------ src/lib/arch/unix/ArchMultithreadPosix.h | 2 +- src/lib/arch/win32/ArchMultithreadWindows.cpp | 14 ++++---------- src/lib/arch/win32/ArchMultithreadWindows.h | 2 +- src/lib/arch/win32/ArchTaskBarWindows.cpp | 7 +------ src/lib/arch/win32/ArchTaskBarWindows.h | 1 - src/lib/mt/Thread.cpp | 7 ++----- src/lib/mt/Thread.h | 2 +- 9 files changed, 17 insertions(+), 38 deletions(-) diff --git a/src/lib/arch/IArchMultithread.h b/src/lib/arch/IArchMultithread.h index 84a3b086..6a57694d 100644 --- a/src/lib/arch/IArchMultithread.h +++ b/src/lib/arch/IArchMultithread.h @@ -19,6 +19,7 @@ #pragma once #include "common/IInterface.h" +#include /*! \class ArchCondImpl @@ -160,7 +161,7 @@ public: Creates and starts a new thread, using \c func as the entry point and passing it \c userData. The thread is an opaque data type. */ - virtual ArchThread newThread(ThreadFunc func, void* userData) = 0; + virtual ArchThread newThread(const std::function& func) = 0; //! Get a reference to the calling thread /*! diff --git a/src/lib/arch/unix/ArchMultithreadPosix.cpp b/src/lib/arch/unix/ArchMultithreadPosix.cpp index e260e66e..8400f9d8 100644 --- a/src/lib/arch/unix/ArchMultithreadPosix.cpp +++ b/src/lib/arch/unix/ArchMultithreadPosix.cpp @@ -59,8 +59,7 @@ public: int m_refCount; IArchMultithread::ThreadID m_id; pthread_t m_thread; - IArchMultithread::ThreadFunc m_func; - void* m_userData; + std::function func_;; bool m_cancel; bool m_cancelling; bool m_exited; @@ -70,8 +69,6 @@ public: ArchThreadImpl::ArchThreadImpl() : m_refCount(1), m_id(0), - m_func(NULL), - m_userData(NULL), m_cancel(false), m_cancelling(false), m_exited(false), @@ -317,11 +314,8 @@ ArchMultithreadPosix::unlockMutex(ArchMutex mutex) } } -ArchThread -ArchMultithreadPosix::newThread(ThreadFunc func, void* data) +ArchThread ArchMultithreadPosix::newThread(const std::function& func) { - assert(func != NULL); - // initialize signal handler. we do this here instead of the // constructor so we can avoid daemonizing (using fork()) // when there are multiple threads. clients can safely @@ -339,8 +333,7 @@ ArchMultithreadPosix::newThread(ThreadFunc func, void* data) // create thread impl for new thread ArchThreadImpl* thread = new ArchThreadImpl; - thread->m_func = func; - thread->m_userData = data; + thread->func_ = func; // create the thread. pthread_create() on RedHat 7.2 smp fails // if passed a NULL attr so use a default attr. @@ -387,7 +380,7 @@ ArchMultithreadPosix::closeThread(ArchThread thread) // decrement ref count and clean up thread if no more references if (--thread->m_refCount == 0) { // detach from thread (unless it's the main thread) - if (thread->m_func != NULL) { + if (thread->func_) { pthread_detach(thread->m_thread); } @@ -691,7 +684,7 @@ ArchMultithreadPosix::doThreadFunc(ArchThread thread) } try { - (*thread->m_func)(thread->m_userData); + thread->func_(); } catch (XThreadCancel&) { diff --git a/src/lib/arch/unix/ArchMultithreadPosix.h b/src/lib/arch/unix/ArchMultithreadPosix.h index b77dccca..798147a0 100644 --- a/src/lib/arch/unix/ArchMultithreadPosix.h +++ b/src/lib/arch/unix/ArchMultithreadPosix.h @@ -67,7 +67,7 @@ public: virtual void closeMutex(ArchMutex); virtual void lockMutex(ArchMutex); virtual void unlockMutex(ArchMutex); - virtual ArchThread newThread(ThreadFunc, void*); + virtual ArchThread newThread(const std::function& func); virtual ArchThread newCurrentThread(); virtual ArchThread copyThread(ArchThread); virtual void closeThread(ArchThread); diff --git a/src/lib/arch/win32/ArchMultithreadWindows.cpp b/src/lib/arch/win32/ArchMultithreadWindows.cpp index 48bed64b..43a7374a 100644 --- a/src/lib/arch/win32/ArchMultithreadWindows.cpp +++ b/src/lib/arch/win32/ArchMultithreadWindows.cpp @@ -49,8 +49,7 @@ public: int m_refCount; HANDLE m_thread; DWORD m_id; - IArchMultithread::ThreadFunc m_func; - void* m_userData; + std::function func_; HANDLE m_cancel; bool m_cancelling; HANDLE m_exit; @@ -61,8 +60,6 @@ ArchThreadImpl::ArchThreadImpl() : m_refCount(1), m_thread(NULL), m_id(0), - m_func(NULL), - m_userData(NULL), m_cancelling(false), m_networkData(NULL) { @@ -290,15 +287,13 @@ ArchMultithreadWindows::unlockMutex(ArchMutex mutex) LeaveCriticalSection(&mutex->m_mutex); } -ArchThread -ArchMultithreadWindows::newThread(ThreadFunc func, void* data) +ArchThread ArchMultithreadWindows::newThread(const std::function& func) { lockMutex(m_threadMutex); // create thread impl for new thread ArchThreadImpl* thread = new ArchThreadImpl; - thread->m_func = func; - thread->m_userData = data; + thread->func_ = func; // create thread unsigned int id = 0; @@ -668,8 +663,7 @@ ArchMultithreadWindows::doThreadFunc(ArchThread thread) unlockMutex(m_threadMutex); try { - // go - (*thread->m_func)(thread->m_userData); + thread->func_(); } catch (XThreadCancel&) { diff --git a/src/lib/arch/win32/ArchMultithreadWindows.h b/src/lib/arch/win32/ArchMultithreadWindows.h index df3af6e2..31a2b304 100644 --- a/src/lib/arch/win32/ArchMultithreadWindows.h +++ b/src/lib/arch/win32/ArchMultithreadWindows.h @@ -73,7 +73,7 @@ public: virtual void closeMutex(ArchMutex); virtual void lockMutex(ArchMutex); virtual void unlockMutex(ArchMutex); - virtual ArchThread newThread(ThreadFunc, void*); + virtual ArchThread newThread(const std::function& func); virtual ArchThread newCurrentThread(); virtual ArchThread copyThread(ArchThread); virtual void closeThread(ArchThread); diff --git a/src/lib/arch/win32/ArchTaskBarWindows.cpp b/src/lib/arch/win32/ArchTaskBarWindows.cpp index 988a88c2..bf71b741 100644 --- a/src/lib/arch/win32/ArchTaskBarWindows.cpp +++ b/src/lib/arch/win32/ArchTaskBarWindows.cpp @@ -88,7 +88,7 @@ ArchTaskBarWindows::init() // create a window on the current desktop with the current // thread then the current thread won't be able to switch // desktops if it needs to. - m_thread = ARCH->newThread(&ArchTaskBarWindows::threadEntry, this); + m_thread = ARCH->newThread([this]() { threadMainLoop(); }); // wait for child thread while (!m_ready) { @@ -501,11 +501,6 @@ ArchTaskBarWindows::threadMainLoop() UnregisterClass(className, instanceWin32()); } -void ArchTaskBarWindows::threadEntry(void* self) -{ - static_cast(self)->threadMainLoop(); -} - HINSTANCE ArchTaskBarWindows::instanceWin32() { return ArchMiscWindows::instanceWin32(); diff --git a/src/lib/arch/win32/ArchTaskBarWindows.h b/src/lib/arch/win32/ArchTaskBarWindows.h index 6cf67f5a..2b8b7ad6 100644 --- a/src/lib/arch/win32/ArchTaskBarWindows.h +++ b/src/lib/arch/win32/ArchTaskBarWindows.h @@ -84,7 +84,6 @@ private: static LRESULT CALLBACK staticWndProc(HWND, UINT, WPARAM, LPARAM); void threadMainLoop(); - static void threadEntry(void*); HINSTANCE instanceWin32(); diff --git a/src/lib/mt/Thread.cpp b/src/lib/mt/Thread.cpp index 976a703d..f4e1eaae 100644 --- a/src/lib/mt/Thread.cpp +++ b/src/lib/mt/Thread.cpp @@ -30,7 +30,7 @@ Thread::Thread(IJob* job) { - m_thread = ARCH->newThread(&Thread::threadFunc, job); + m_thread = ARCH->newThread([job](){ threadFunc(job); }); if (m_thread == NULL) { // couldn't create thread delete job; @@ -126,7 +126,7 @@ Thread::operator!=(const Thread& thread) const return !ARCH->isSameThread(m_thread, thread.m_thread); } -void Thread::threadFunc(void* vjob) +void Thread::threadFunc(IJob* job) { // get this thread's id for logging IArchMultithread::ThreadID id; @@ -136,9 +136,6 @@ void Thread::threadFunc(void* vjob) ARCH->closeThread(thread); } - // get job - IJob* job = static_cast(vjob); - try { // go LOG((CLOG_DEBUG1 "thread 0x%08x entry", id)); diff --git a/src/lib/mt/Thread.h b/src/lib/mt/Thread.h index 1bcaefc5..99e86469 100644 --- a/src/lib/mt/Thread.h +++ b/src/lib/mt/Thread.h @@ -192,7 +192,7 @@ public: private: Thread(ArchThread); - static void threadFunc(void*); + static void threadFunc(IJob*); private: ArchThread m_thread; From d2c106db530c973dbc74867ee1a252ec7739555e Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 06:16:33 +0200 Subject: [PATCH 102/113] lib: Pass jobs to barrier::Thread as std::function --- src/lib/barrier/App.cpp | 4 +- src/lib/barrier/App.h | 2 +- src/lib/barrier/ClientApp.cpp | 6 +- src/lib/barrier/ClientApp.h | 1 - src/lib/barrier/ServerApp.cpp | 6 +- src/lib/barrier/StreamChunker.cpp | 5 +- src/lib/barrier/StreamChunker.h | 5 +- src/lib/barrier/win32/DaemonApp.cpp | 1 - src/lib/base/FunctionJob.cpp | 43 ------------ src/lib/base/FunctionJob.h | 39 ----------- src/lib/base/TMethodJob.h | 68 ------------------- src/lib/base/log_outputters.cpp | 1 - src/lib/client/Client.cpp | 19 ++---- src/lib/client/Client.h | 4 +- src/lib/ipc/IpcLogOutputter.cpp | 7 +- src/lib/ipc/IpcLogOutputter.h | 2 +- src/lib/mt/Thread.cpp | 16 ++--- src/lib/mt/Thread.h | 10 ++- src/lib/net/SocketMultiplexer.cpp | 11 ++- src/lib/net/SocketMultiplexer.h | 2 +- src/lib/platform/MSWindowsDesks.cpp | 8 +-- src/lib/platform/MSWindowsDesks.h | 2 +- src/lib/platform/MSWindowsKeyState.cpp | 6 +- src/lib/platform/MSWindowsKeyState.h | 2 +- src/lib/platform/MSWindowsScreen.cpp | 10 +-- src/lib/platform/MSWindowsScreen.h | 2 +- src/lib/platform/MSWindowsScreenSaver.cpp | 13 ++-- src/lib/platform/MSWindowsScreenSaver.h | 4 +- src/lib/platform/MSWindowsWatchdog.cpp | 14 ++-- src/lib/platform/MSWindowsWatchdog.h | 4 +- src/lib/platform/OSXScreen.h | 4 +- src/lib/platform/OSXScreen.mm | 16 ++--- src/lib/server/Server.cpp | 28 ++------ src/lib/server/Server.h | 6 +- src/test/integtests/ipc/IpcTests.cpp | 1 - src/test/integtests/net/NetworkTests.cpp | 1 - .../platform/MSWindowsKeyStateTests.cpp | 1 - 37 files changed, 68 insertions(+), 306 deletions(-) delete mode 100644 src/lib/base/FunctionJob.cpp delete mode 100644 src/lib/base/FunctionJob.h delete mode 100644 src/lib/base/TMethodJob.h diff --git a/src/lib/barrier/App.cpp b/src/lib/barrier/App.cpp index 67e58aba..2b3eccc3 100644 --- a/src/lib/barrier/App.cpp +++ b/src/lib/barrier/App.cpp @@ -34,7 +34,6 @@ #if SYSAPI_WIN32 #include "base/IEventQueue.h" -#include "base/TMethodJob.h" #endif #include @@ -229,8 +228,7 @@ App::handleIpcMessage(const Event& e, void*) } } -void -App::runEventsLoop(void*) +void App::run_events_loop() { m_events->loop(); diff --git a/src/lib/barrier/App.h b/src/lib/barrier/App.h index d747b5c6..8e17a714 100644 --- a/src/lib/barrier/App.h +++ b/src/lib/barrier/App.h @@ -108,7 +108,7 @@ private: protected: void initIpcClient(); void cleanupIpcClient(); - void runEventsLoop(void*); + void run_events_loop(); IArchTaskBarReceiver* m_taskBarReceiver; bool m_suspended; diff --git a/src/lib/barrier/ClientApp.cpp b/src/lib/barrier/ClientApp.cpp index a466f30e..4b0ef61b 100644 --- a/src/lib/barrier/ClientApp.cpp +++ b/src/lib/barrier/ClientApp.cpp @@ -37,7 +37,6 @@ #include "base/TMethodEventJob.h" #include "base/log_outputters.h" #include "base/EventQueue.h" -#include "base/TMethodJob.h" #include "base/Log.h" #include "common/Version.h" @@ -465,10 +464,7 @@ ClientApp::mainLoop() #if defined(MAC_OS_X_VERSION_10_7) - Thread thread( - new TMethodJob( - this, &ClientApp::runEventsLoop, - NULL)); + Thread thread([this](){ run_events_loop(); }); // wait until carbon loop is ready OSXScreen* screen = dynamic_cast( diff --git a/src/lib/barrier/ClientApp.h b/src/lib/barrier/ClientApp.h index 75ceb1ec..d1db8d05 100644 --- a/src/lib/barrier/ClientApp.h +++ b/src/lib/barrier/ClientApp.h @@ -24,7 +24,6 @@ namespace barrier { class Screen; } class Event; class Client; class NetworkAddress; -class Thread; class ClientArgs; class ClientApp : public App { diff --git a/src/lib/barrier/ServerApp.cpp b/src/lib/barrier/ServerApp.cpp index 4810b8a5..71158ce3 100644 --- a/src/lib/barrier/ServerApp.cpp +++ b/src/lib/barrier/ServerApp.cpp @@ -34,7 +34,6 @@ #include "base/EventQueue.h" #include "base/log_outputters.h" #include "base/FunctionEventJob.h" -#include "base/TMethodJob.h" #include "base/IEventQueue.h" #include "base/Log.h" #include "base/TMethodEventJob.h" @@ -797,10 +796,7 @@ ServerApp::mainLoop() #if defined(MAC_OS_X_VERSION_10_7) - Thread thread( - new TMethodJob( - this, &ServerApp::runEventsLoop, - NULL)); + Thread thread([this](){ run_events_loop(); }); // wait until carbon loop is ready OSXScreen* screen = dynamic_cast( diff --git a/src/lib/barrier/StreamChunker.cpp b/src/lib/barrier/StreamChunker.cpp index 45edd302..0f6c0a9d 100644 --- a/src/lib/barrier/StreamChunker.cpp +++ b/src/lib/barrier/StreamChunker.cpp @@ -42,14 +42,13 @@ bool StreamChunker::s_interruptFile = false; Mutex* StreamChunker::s_interruptMutex = NULL; void -StreamChunker::sendFile( - char* filename, +StreamChunker::sendFile(const char* filename, IEventQueue* events, void* eventTarget) { s_isChunkingFile = true; - std::fstream file(static_cast(filename), std::ios::in | std::ios::binary); + std::fstream file(filename, std::ios::in | std::ios::binary); if (!file.is_open()) { throw runtime_error("failed to open file"); diff --git a/src/lib/barrier/StreamChunker.h b/src/lib/barrier/StreamChunker.h index 736d1bde..ed5d83c6 100644 --- a/src/lib/barrier/StreamChunker.h +++ b/src/lib/barrier/StreamChunker.h @@ -25,10 +25,7 @@ class Mutex; class StreamChunker { public: - static void sendFile( - char* filename, - IEventQueue* events, - void* eventTarget); + static void sendFile(const char* filename, IEventQueue* events, void* eventTarget); static void sendClipboard( String& data, size_t size, diff --git a/src/lib/barrier/win32/DaemonApp.cpp b/src/lib/barrier/win32/DaemonApp.cpp index 6ea6a4fa..81ec5ff3 100644 --- a/src/lib/barrier/win32/DaemonApp.cpp +++ b/src/lib/barrier/win32/DaemonApp.cpp @@ -28,7 +28,6 @@ #include "net/SocketMultiplexer.h" #include "arch/XArch.h" #include "base/Log.h" -#include "base/TMethodJob.h" #include "base/TMethodEventJob.h" #include "base/EventQueue.h" #include "base/log_outputters.h" diff --git a/src/lib/base/FunctionJob.cpp b/src/lib/base/FunctionJob.cpp deleted file mode 100644 index 2d7ef679..00000000 --- a/src/lib/base/FunctionJob.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * barrier -- mouse and keyboard sharing utility - * Copyright (C) 2012-2016 Symless Ltd. - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file LICENSE that should have accompanied this file. - * - * This package 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 . - */ - -#include "base/FunctionJob.h" - -// -// FunctionJob -// - -FunctionJob::FunctionJob(void (*func)(void*), void* arg) : - m_func(func), - m_arg(arg) -{ - // do nothing -} - -FunctionJob::~FunctionJob() -{ - // do nothing -} - -void -FunctionJob::run() -{ - if (m_func != NULL) { - m_func(m_arg); - } -} diff --git a/src/lib/base/FunctionJob.h b/src/lib/base/FunctionJob.h deleted file mode 100644 index 39c96449..00000000 --- a/src/lib/base/FunctionJob.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * barrier -- mouse and keyboard sharing utility - * Copyright (C) 2012-2016 Symless Ltd. - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file LICENSE that should have accompanied this file. - * - * This package 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 . - */ - -#pragma once - -#include "base/IJob.h" - -//! Use a function as a job -/*! -A job class that invokes a function. -*/ -class FunctionJob : public IJob { -public: - //! run() invokes \c func(arg) - FunctionJob(void (*func)(void*), void* arg = NULL); - virtual ~FunctionJob(); - - // IJob overrides - virtual void run(); - -private: - void (*m_func)(void*); - void* m_arg; -}; diff --git a/src/lib/base/TMethodJob.h b/src/lib/base/TMethodJob.h deleted file mode 100644 index 84961d48..00000000 --- a/src/lib/base/TMethodJob.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * barrier -- mouse and keyboard sharing utility - * Copyright (C) 2012-2016 Symless Ltd. - * Copyright (C) 2002 Chris Schoeneman - * - * This package is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * found in the file LICENSE that should have accompanied this file. - * - * This package 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 . - */ - -#pragma once - -#include "IJob.h" - -//! Use a function as a job -/*! -A job class that invokes a member function. -*/ -template -class TMethodJob : public IJob { -public: - //! run() invokes \c object->method(arg) - TMethodJob(T* object, void (T::*method)(void*), void* arg = NULL); - virtual ~TMethodJob(); - - // IJob overrides - virtual void run(); - -private: - T* m_object; - void (T::*m_method)(void*); - void* m_arg; -}; - -template -inline -TMethodJob::TMethodJob(T* object, void (T::*method)(void*), void* arg) : - m_object(object), - m_method(method), - m_arg(arg) -{ - // do nothing -} - -template -inline -TMethodJob::~TMethodJob() -{ - // do nothing -} - -template -inline -void -TMethodJob::run() -{ - if (m_object != NULL) { - (m_object->*m_method)(m_arg); - } -} diff --git a/src/lib/base/log_outputters.cpp b/src/lib/base/log_outputters.cpp index a1193c78..176af2df 100644 --- a/src/lib/base/log_outputters.cpp +++ b/src/lib/base/log_outputters.cpp @@ -17,7 +17,6 @@ */ #include "base/log_outputters.h" -#include "base/TMethodJob.h" #include "arch/Arch.h" #include "base/String.h" #include "io/filesystem.h" diff --git a/src/lib/client/Client.cpp b/src/lib/client/Client.cpp index 4f1fe73a..a7b15cf5 100644 --- a/src/lib/client/Client.cpp +++ b/src/lib/client/Client.cpp @@ -37,7 +37,6 @@ #include "base/Log.h" #include "base/IEventQueue.h" #include "base/TMethodEventJob.h" -#include "base/TMethodJob.h" #include #include @@ -760,9 +759,7 @@ void Client::onFileRecieveCompleted() { if (isReceivedFileSizeValid()) { - m_writeToDropDirThread = new Thread( - new TMethodJob( - this, &Client::writeToDropDirThread)); + m_writeToDropDirThread = new Thread([this](){ write_to_drop_dir_thread(); }); } } @@ -772,8 +769,7 @@ Client::handleStopRetry(const Event&, void*) m_args.m_restartable = false; } -void -Client::writeToDropDirThread(void*) +void Client::write_to_drop_dir_thread() { LOG((CLOG_DEBUG "starting write to drop dir thread")); @@ -812,18 +808,13 @@ Client::sendFileToServer(const char* filename) StreamChunker::interruptFile(); } - m_sendFileThread = new Thread( - new TMethodJob( - this, &Client::sendFileThread, - static_cast(const_cast(filename)))); + m_sendFileThread = new Thread([this, filename]() { send_file_thread(filename); }); } -void -Client::sendFileThread(void* filename) +void Client::send_file_thread(const char* filename) { try { - char* name = static_cast(filename); - StreamChunker::sendFile(name, m_events, this); + StreamChunker::sendFile(filename, m_events, this); } catch (std::runtime_error& error) { LOG((CLOG_ERR "failed sending file chunks: %s", error.what())); diff --git a/src/lib/client/Client.h b/src/lib/client/Client.h index ea9af253..c172af22 100644 --- a/src/lib/client/Client.h +++ b/src/lib/client/Client.h @@ -167,8 +167,8 @@ private: void sendEvent(Event::Type, void*); void sendConnectionFailedEvent(const char* msg); void sendFileChunk(const void* data); - void sendFileThread(void*); - void writeToDropDirThread(void*); + void send_file_thread(const char* filename); + void write_to_drop_dir_thread(); void setupConnecting(); void setupConnection(); void setupScreen(); diff --git a/src/lib/ipc/IpcLogOutputter.cpp b/src/lib/ipc/IpcLogOutputter.cpp index 223f52f7..5118a0a6 100644 --- a/src/lib/ipc/IpcLogOutputter.cpp +++ b/src/lib/ipc/IpcLogOutputter.cpp @@ -28,7 +28,6 @@ #include "base/Event.h" #include "base/EventQueue.h" #include "base/TMethodEventJob.h" -#include "base/TMethodJob.h" enum EIpcLogOutputter { kBufferMaxSize = 1000, @@ -54,8 +53,7 @@ IpcLogOutputter::IpcLogOutputter(IpcServer& ipcServer, EIpcClientType clientType m_clientType(clientType) { if (useThread) { - m_bufferThread = new Thread(new TMethodJob( - this, &IpcLogOutputter::bufferThread)); + m_bufferThread = new Thread([this](){ buffer_thread(); }); } } @@ -142,8 +140,7 @@ IpcLogOutputter::isRunning() return m_running; } -void -IpcLogOutputter::bufferThread(void*) +void IpcLogOutputter::buffer_thread() { m_bufferThreadId = m_bufferThread->getID(); m_running = true; diff --git a/src/lib/ipc/IpcLogOutputter.h b/src/lib/ipc/IpcLogOutputter.h index 11e4d137..3f3ab0a6 100644 --- a/src/lib/ipc/IpcLogOutputter.h +++ b/src/lib/ipc/IpcLogOutputter.h @@ -92,7 +92,7 @@ public: private: void init(); - void bufferThread(void*); + void buffer_thread(); std::string getChunk(size_t count); void appendBuffer(const std::string& text); bool isRunning(); diff --git a/src/lib/mt/Thread.cpp b/src/lib/mt/Thread.cpp index f4e1eaae..755c0e6d 100644 --- a/src/lib/mt/Thread.cpp +++ b/src/lib/mt/Thread.cpp @@ -28,12 +28,10 @@ // Thread // -Thread::Thread(IJob* job) +Thread::Thread(const std::function& fun) { - m_thread = ARCH->newThread([job](){ threadFunc(job); }); + m_thread = ARCH->newThread([=](){ threadFunc(fun); }); if (m_thread == NULL) { - // couldn't create thread - delete job; throw XMTThreadUnavailable(); } } @@ -126,7 +124,7 @@ Thread::operator!=(const Thread& thread) const return !ARCH->isSameThread(m_thread, thread.m_thread); } -void Thread::threadFunc(IJob* job) +void Thread::threadFunc(const std::function& func) { // get this thread's id for logging IArchMultithread::ThreadID id; @@ -139,13 +137,12 @@ void Thread::threadFunc(IJob* job) try { // go LOG((CLOG_DEBUG1 "thread 0x%08x entry", id)); - job->run(); + func(); LOG((CLOG_DEBUG1 "thread 0x%08x exit", id)); } catch (XThreadCancel&) { // client called cancel() LOG((CLOG_DEBUG1 "caught cancel on thread 0x%08x", id)); - delete job; throw; } catch (XThreadExit&) { @@ -153,15 +150,10 @@ void Thread::threadFunc(IJob* job) } catch (XBase& e) { LOG((CLOG_ERR "exception on thread 0x%08x: %s", id, e.what())); - delete job; throw; } catch (...) { LOG((CLOG_ERR "exception on thread 0x%08x: ", id)); - delete job; throw; } - - // done with job - delete job; } diff --git a/src/lib/mt/Thread.h b/src/lib/mt/Thread.h index 99e86469..141d59f3 100644 --- a/src/lib/mt/Thread.h +++ b/src/lib/mt/Thread.h @@ -19,8 +19,7 @@ #pragma once #include "arch/IArchMultithread.h" - -class IJob; +#include //! Thread handle /*! @@ -44,10 +43,9 @@ class Thread { public: //! Run \c adoptedJob in a new thread /*! - Create and start a new thread executing the \c adoptedJob. The - new thread takes ownership of \c adoptedJob and will delete it. + Create and start a new thread executing the \c fun. */ - Thread(IJob* adoptedJob); + Thread(const std::function& fun); //! Duplicate a thread handle /*! @@ -192,7 +190,7 @@ public: private: Thread(ArchThread); - static void threadFunc(IJob*); + static void threadFunc(const std::function& func); private: ArchThread m_thread; diff --git a/src/lib/net/SocketMultiplexer.cpp b/src/lib/net/SocketMultiplexer.cpp index 74a305fe..5a2328e0 100644 --- a/src/lib/net/SocketMultiplexer.cpp +++ b/src/lib/net/SocketMultiplexer.cpp @@ -26,7 +26,6 @@ #include "arch/Arch.h" #include "arch/XArch.h" #include "base/Log.h" -#include "base/TMethodJob.h" #include "common/stdvector.h" // @@ -58,8 +57,7 @@ SocketMultiplexer::SocketMultiplexer() : m_jobListLockLocker(NULL) { // start thread - m_thread = new Thread(new TMethodJob( - this, &SocketMultiplexer::serviceThread)); + m_thread = new Thread([this](){ service_thread(); }); } SocketMultiplexer::~SocketMultiplexer() @@ -95,7 +93,7 @@ void SocketMultiplexer::addSocket(ISocket* socket, std::unique_ptrsecond)) { @@ -138,8 +136,7 @@ SocketMultiplexer::removeSocket(ISocket* socket) unlockJobList(); } -void -SocketMultiplexer::serviceThread(void*) +void SocketMultiplexer::service_thread() { std::vector pfds; IArchNetwork::PollEntry pfd; diff --git a/src/lib/net/SocketMultiplexer.h b/src/lib/net/SocketMultiplexer.h index b7b7e3e3..b13c725a 100644 --- a/src/lib/net/SocketMultiplexer.h +++ b/src/lib/net/SocketMultiplexer.h @@ -67,7 +67,7 @@ private: // and m_update while m_pollable and m_polling are true. all other // threads must only modify these when m_pollable and m_polling are // false. only the service thread sets m_polling. - void serviceThread(void*); + void service_thread(); // create, iterate, and destroy a cursor. a cursor is used to // safely iterate through the job list while other threads modify diff --git a/src/lib/platform/MSWindowsDesks.cpp b/src/lib/platform/MSWindowsDesks.cpp index c1298cb9..d126e13b 100644 --- a/src/lib/platform/MSWindowsDesks.cpp +++ b/src/lib/platform/MSWindowsDesks.cpp @@ -28,7 +28,6 @@ #include "base/Log.h" #include "base/IEventQueue.h" #include "base/TMethodEventJob.h" -#include "base/TMethodJob.h" #include "base/IEventQueue.h" #include @@ -599,13 +598,11 @@ MSWindowsDesks::deskLeave(Desk* desk, HKL keyLayout) } } -void -MSWindowsDesks::deskThread(void* vdesk) +void MSWindowsDesks::desk_thread(Desk* desk) { MSG msg; // use given desktop for this thread - Desk* desk = static_cast(vdesk); desk->m_threadID = GetCurrentThreadId(); desk->m_window = NULL; desk->m_foregroundWindow = NULL; @@ -749,8 +746,7 @@ MSWindowsDesks::Desk* MSWindowsDesks::addDesk(const std::string& name, HDESK hde desk->m_name = name; desk->m_desk = hdesk; desk->m_targetID = GetCurrentThreadId(); - desk->m_thread = new Thread(new TMethodJob( - this, &MSWindowsDesks::deskThread, desk)); + desk->m_thread = new Thread([this, desk]() { desk_thread(desk); }); waitForDesk(); m_desks.insert(std::make_pair(name, desk)); return desk; diff --git a/src/lib/platform/MSWindowsDesks.h b/src/lib/platform/MSWindowsDesks.h index 8cd7bfbe..6292f986 100644 --- a/src/lib/platform/MSWindowsDesks.h +++ b/src/lib/platform/MSWindowsDesks.h @@ -220,7 +220,7 @@ private: void deskMouseRelativeMove(SInt32 dx, SInt32 dy) const; void deskEnter(Desk* desk); void deskLeave(Desk* desk, HKL keyLayout); - void deskThread(void* vdesk); + void desk_thread(Desk* desk); // desk switch checking and handling Desk* addDesk(const std::string& name, HDESK hdesk); diff --git a/src/lib/platform/MSWindowsKeyState.cpp b/src/lib/platform/MSWindowsKeyState.cpp index 05d0dde0..c723d19e 100644 --- a/src/lib/platform/MSWindowsKeyState.cpp +++ b/src/lib/platform/MSWindowsKeyState.cpp @@ -21,7 +21,6 @@ #include "platform/MSWindowsDesks.h" #include "mt/Thread.h" #include "arch/win32/ArchMiscWindows.h" -#include "base/FunctionJob.h" #include "base/Log.h" #include "base/String.h" #include "base/IEventQueue.h" @@ -804,15 +803,14 @@ MSWindowsKeyState::fakeCtrlAltDel() CloseHandle(hEvtSendSas); } else { - Thread cad(new FunctionJob(&MSWindowsKeyState::ctrlAltDelThread)); + Thread cad([this](){ ctrl_alt_del_thread(); }); cad.wait(); } return true; } -void -MSWindowsKeyState::ctrlAltDelThread(void*) +void MSWindowsKeyState::ctrl_alt_del_thread() { // get the Winlogon desktop at whatever privilege we can HDESK desk = OpenDesktop("Winlogon", 0, FALSE, MAXIMUM_ALLOWED); diff --git a/src/lib/platform/MSWindowsKeyState.h b/src/lib/platform/MSWindowsKeyState.h index 6ea917b6..eedcd852 100644 --- a/src/lib/platform/MSWindowsKeyState.h +++ b/src/lib/platform/MSWindowsKeyState.h @@ -169,7 +169,7 @@ private: typedef std::vector GroupList; // send ctrl+alt+del hotkey event on NT family - static void ctrlAltDelThread(void*); + static void ctrl_alt_del_thread(); bool getGroups(GroupList&) const; void setWindowGroup(SInt32 group); diff --git a/src/lib/platform/MSWindowsScreen.cpp b/src/lib/platform/MSWindowsScreen.cpp index 1714d45a..c995a40d 100644 --- a/src/lib/platform/MSWindowsScreen.cpp +++ b/src/lib/platform/MSWindowsScreen.cpp @@ -36,11 +36,9 @@ #include "mt/Thread.h" #include "arch/win32/ArchMiscWindows.h" #include "arch/Arch.h" -#include "base/FunctionJob.h" #include "base/Log.h" #include "base/IEventQueue.h" #include "base/TMethodEventJob.h" -#include "base/TMethodJob.h" #include #include @@ -354,17 +352,13 @@ MSWindowsScreen::leave() forceShowCursor(); if (isDraggingStarted() && !m_isPrimary) { - m_sendDragThread = new Thread( - new TMethodJob( - this, - &MSWindowsScreen::sendDragThread)); + m_sendDragThread = new Thread([this](){ send_drag_thread(); }); } return true; } -void -MSWindowsScreen::sendDragThread(void*) +void MSWindowsScreen::send_drag_thread() { std::string& draggingFilename = getDraggingFilename(); size_t size = draggingFilename.size(); diff --git a/src/lib/platform/MSWindowsScreen.h b/src/lib/platform/MSWindowsScreen.h index b89e8bae..eaa7b88a 100644 --- a/src/lib/platform/MSWindowsScreen.h +++ b/src/lib/platform/MSWindowsScreen.h @@ -222,7 +222,7 @@ private: // HACK KeyModifierMask state, WPARAM wParam) const; // send drag info and data back to server - void sendDragThread(void*); + void send_drag_thread(); private: struct HotKeyItem { diff --git a/src/lib/platform/MSWindowsScreenSaver.cpp b/src/lib/platform/MSWindowsScreenSaver.cpp index 506fd133..9f93792e 100644 --- a/src/lib/platform/MSWindowsScreenSaver.cpp +++ b/src/lib/platform/MSWindowsScreenSaver.cpp @@ -23,7 +23,6 @@ #include "arch/Arch.h" #include "arch/win32/ArchMiscWindows.h" #include "base/Log.h" -#include "base/TMethodJob.h" #include #include @@ -223,8 +222,7 @@ MSWindowsScreenSaver::watchDesktop() // watch desktop in another thread LOG((CLOG_DEBUG "watching screen saver desktop")); m_active = true; - m_watch = new Thread(new TMethodJob(this, - &MSWindowsScreenSaver::watchDesktopThread)); + m_watch = new Thread([this](){ watch_desktop_thread(); }); } void @@ -238,8 +236,7 @@ MSWindowsScreenSaver::watchProcess(HANDLE process) LOG((CLOG_DEBUG "watching screen saver process")); m_process = process; m_active = true; - m_watch = new Thread(new TMethodJob(this, - &MSWindowsScreenSaver::watchProcessThread)); + m_watch = new Thread([this](){ watch_process_thread(); }); } } @@ -260,8 +257,7 @@ MSWindowsScreenSaver::unwatchProcess() } } -void -MSWindowsScreenSaver::watchDesktopThread(void*) +void MSWindowsScreenSaver::watch_desktop_thread() { DWORD reserved = 0; TCHAR* name = NULL; @@ -283,8 +279,7 @@ MSWindowsScreenSaver::watchDesktopThread(void*) } } -void -MSWindowsScreenSaver::watchProcessThread(void*) +void MSWindowsScreenSaver::watch_process_thread() { for (;;) { Thread::testCancel(); diff --git a/src/lib/platform/MSWindowsScreenSaver.h b/src/lib/platform/MSWindowsScreenSaver.h index 7cb37815..4f1dd5fa 100644 --- a/src/lib/platform/MSWindowsScreenSaver.h +++ b/src/lib/platform/MSWindowsScreenSaver.h @@ -64,8 +64,8 @@ private: void watchDesktop(); void watchProcess(HANDLE process); void unwatchProcess(); - void watchDesktopThread(void*); - void watchProcessThread(void*); + void watch_desktop_thread(); + void watch_process_thread(); void setSecure(bool secure, bool saveSecureAsInt); bool isSecure(bool* wasSecureAnInt) const; diff --git a/src/lib/platform/MSWindowsWatchdog.cpp b/src/lib/platform/MSWindowsWatchdog.cpp index be18e6c8..2d9a61c0 100644 --- a/src/lib/platform/MSWindowsWatchdog.cpp +++ b/src/lib/platform/MSWindowsWatchdog.cpp @@ -29,7 +29,6 @@ #include "arch/win32/XArchWindows.h" #include "arch/Arch.h" #include "base/log_outputters.h" -#include "base/TMethodJob.h" #include "base/Log.h" #include "common/Version.h" @@ -84,11 +83,8 @@ MSWindowsWatchdog::MSWindowsWatchdog( void MSWindowsWatchdog::startAsync() { - m_thread = new Thread(new TMethodJob( - this, &MSWindowsWatchdog::mainLoop, nullptr)); - - m_outputThread = new Thread(new TMethodJob( - this, &MSWindowsWatchdog::outputLoop, nullptr)); + m_thread = new Thread([this](){ main_loop(); }); + m_outputThread = new Thread([this](){ output_loop(); }); } void @@ -157,8 +153,7 @@ MSWindowsWatchdog::getUserToken(LPSECURITY_ATTRIBUTES security) } } -void -MSWindowsWatchdog::mainLoop(void*) +void MSWindowsWatchdog::main_loop() { shutdownExistingProcesses(); @@ -421,8 +416,7 @@ MSWindowsWatchdog::getCommand() const return cmd; } -void -MSWindowsWatchdog::outputLoop(void*) +void MSWindowsWatchdog::output_loop() { // +1 char for \0 CHAR buffer[kOutputBufferSize + 1]; diff --git a/src/lib/platform/MSWindowsWatchdog.h b/src/lib/platform/MSWindowsWatchdog.h index d3741619..0595ca00 100644 --- a/src/lib/platform/MSWindowsWatchdog.h +++ b/src/lib/platform/MSWindowsWatchdog.h @@ -48,8 +48,8 @@ public: void setFileLogOutputter(FileLogOutputter* outputter); private: - void mainLoop(void*); - void outputLoop(void*); + void main_loop(); + void output_loop(); void shutdownProcess(HANDLE handle, DWORD pid, int timeout); void shutdownExistingProcesses(); HANDLE duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES security); diff --git a/src/lib/platform/OSXScreen.h b/src/lib/platform/OSXScreen.h index 81c1a1da..691b74c4 100644 --- a/src/lib/platform/OSXScreen.h +++ b/src/lib/platform/OSXScreen.h @@ -174,7 +174,7 @@ private: EventRef theEvent, void* inUserData); // sleep / wakeup support - void watchSystemPowerThread(void*); + void watchSystemPowerThread(); static void testCanceled(CFRunLoopTimerRef timer, void*info); static void powerChangeCallback(void* refcon, io_service_t service, natural_t messageType, void* messageArgument); @@ -201,7 +201,7 @@ private: // convert CFString to char* static char* CFStringRefToUTF8String(CFStringRef aString); - void getDropTargetThread(void*); + void get_drop_target_thread(); private: struct HotKeyItem { diff --git a/src/lib/platform/OSXScreen.mm b/src/lib/platform/OSXScreen.mm index 693ae45c..d41e321b 100644 --- a/src/lib/platform/OSXScreen.mm +++ b/src/lib/platform/OSXScreen.mm @@ -38,7 +38,6 @@ #include "base/Log.h" #include "base/IEventQueue.h" #include "base/TMethodEventJob.h" -#include "base/TMethodJob.h" #include #include @@ -157,8 +156,7 @@ OSXScreen::OSXScreen(IEventQueue* events, bool isPrimary, bool autoShowHideCurso m_carbonLoopReady = new CondVar(m_carbonLoopMutex, false); #endif LOG((CLOG_DEBUG "starting watchSystemPowerThread")); - m_pmWatchThread = new Thread(new TMethodJob - (this, &OSXScreen::watchSystemPowerThread)); + m_pmWatchThread = new Thread([this](){ watchSystemPowerThread(); }); } catch (...) { m_events->removeHandler(m_events->forOSXScreen().confirmSleep(), @@ -578,16 +576,14 @@ OSXScreen::fakeMouseButton(ButtonID id, bool press) if (!press && (id == kButtonLeft)) { if (m_fakeDraggingStarted) { - m_getDropTargetThread = new Thread(new TMethodJob( - this, &OSXScreen::getDropTargetThread)); + m_getDropTargetThread = new Thread([this](){ get_drop_target_thread(); }); } m_draggingStarted = false; } } -void -OSXScreen::getDropTargetThread(void*) +void OSXScreen::get_drop_target_thread() { #if defined(MAC_OS_X_VERSION_10_7) char* cstr = NULL; @@ -1186,8 +1182,7 @@ OSXScreen::onMouseButton(bool pressed, UInt16 macButton) } else { if (m_fakeDraggingStarted) { - m_getDropTargetThread = new Thread(new TMethodJob( - this, &OSXScreen::getDropTargetThread)); + m_getDropTargetThread = new Thread([this](){ get_drop_target_thread(); }); } m_draggingStarted = false; @@ -1621,8 +1616,7 @@ OSXScreen::userSwitchCallback(EventHandlerCallRef nextHandler, // main of thread monitoring system power (sleep/wakeup) using a CFRunLoop // -void -OSXScreen::watchSystemPowerThread(void*) +void OSXScreen::watchSystemPowerThread() { io_object_t notifier; IONotificationPortRef notificationPortRef; diff --git a/src/lib/server/Server.cpp b/src/lib/server/Server.cpp index 2eff0029..a169db16 100644 --- a/src/lib/server/Server.cpp +++ b/src/lib/server/Server.cpp @@ -39,7 +39,6 @@ #include "net/XSocket.h" #include "mt/Thread.h" #include "arch/Arch.h" -#include "base/TMethodJob.h" #include "base/IEventQueue.h" #include "base/Log.h" #include "base/TMethodEventJob.h" @@ -1824,10 +1823,8 @@ Server::onMouseMovePrimary(SInt32 x, SInt32 y) && m_active != newScreen && m_waitDragInfoThread) { if (m_sendDragInfoThread == NULL) { - m_sendDragInfoThread = new Thread( - new TMethodJob( - this, - &Server::sendDragInfoThread, newScreen)); + m_sendDragInfoThread = new Thread([this, newScreen]() + { send_drag_info_thread(newScreen); }); } return false; @@ -1843,11 +1840,8 @@ Server::onMouseMovePrimary(SInt32 x, SInt32 y) return false; } -void -Server::sendDragInfoThread(void* arg) +void Server::send_drag_info_thread(BaseClientProxy* newScreen) { - BaseClientProxy* newScreen = static_cast(arg); - m_dragFileList.clear(); std::string& dragFileList = m_screen->getDraggingFilename(); if (!dragFileList.empty()) { @@ -2087,14 +2081,11 @@ void Server::onFileRecieveCompleted() { if (isReceivedFileSizeValid()) { - m_writeToDropDirThread = new Thread( - new TMethodJob( - this, &Server::writeToDropDirThread)); + m_writeToDropDirThread = new Thread([this]() { write_to_drop_dir_thread(); }); } } -void -Server::writeToDropDirThread(void*) +void Server::write_to_drop_dir_thread() { LOG((CLOG_DEBUG "starting write to drop dir thread")); @@ -2394,17 +2385,12 @@ Server::sendFileToClient(const char* filename) StreamChunker::interruptFile(); } - m_sendFileThread = new Thread( - new TMethodJob( - this, &Server::sendFileThread, - static_cast(const_cast(filename)))); + m_sendFileThread = new Thread([this, filename]() { send_file_thread(filename); }); } -void -Server::sendFileThread(void* data) +void Server::send_file_thread(const char* filename) { try { - char* filename = static_cast(data); LOG((CLOG_DEBUG "sending file to client, filename=%s", filename)); StreamChunker::sendFile(filename, m_events, this); } diff --git a/src/lib/server/Server.h b/src/lib/server/Server.h index cb71ec3d..ae8b2bd5 100644 --- a/src/lib/server/Server.h +++ b/src/lib/server/Server.h @@ -358,13 +358,13 @@ private: void forceLeaveClient(BaseClientProxy* client); // thread function for sending file - void sendFileThread(void*); + void send_file_thread(const char* filename); // thread function for writing file to drop directory - void writeToDropDirThread(void*); + void write_to_drop_dir_thread(); // thread function for sending drag information - void sendDragInfoThread(void*); + void send_drag_info_thread(BaseClientProxy* newScreen); // send drag info to new client screen void sendDragInfo(BaseClientProxy* newScreen); diff --git a/src/test/integtests/ipc/IpcTests.cpp b/src/test/integtests/ipc/IpcTests.cpp index 5f20f03f..ce15d591 100644 --- a/src/test/integtests/ipc/IpcTests.cpp +++ b/src/test/integtests/ipc/IpcTests.cpp @@ -31,7 +31,6 @@ #include "net/SocketMultiplexer.h" #include "mt/Thread.h" #include "arch/Arch.h" -#include "base/TMethodJob.h" #include "base/String.h" #include "base/Log.h" #include "base/EventQueue.h" diff --git a/src/test/integtests/net/NetworkTests.cpp b/src/test/integtests/net/NetworkTests.cpp index 1e843867..92767bfa 100644 --- a/src/test/integtests/net/NetworkTests.cpp +++ b/src/test/integtests/net/NetworkTests.cpp @@ -36,7 +36,6 @@ #include "net/TCPSocketFactory.h" #include "mt/Thread.h" #include "base/TMethodEventJob.h" -#include "base/TMethodJob.h" #include "base/Log.h" #include diff --git a/src/test/integtests/platform/MSWindowsKeyStateTests.cpp b/src/test/integtests/platform/MSWindowsKeyStateTests.cpp index 5af3e89d..6f6edf5b 100644 --- a/src/test/integtests/platform/MSWindowsKeyStateTests.cpp +++ b/src/test/integtests/platform/MSWindowsKeyStateTests.cpp @@ -24,7 +24,6 @@ #include "platform/MSWindowsDesks.h" #include "platform/MSWindowsScreen.h" #include "platform/MSWindowsScreenSaver.h" -#include "base/TMethodJob.h" #include "test/global/gtest.h" #include "test/global/gmock.h" From d7de571fdc56c6b76eabb69cf430a9c72251e0be Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 06:16:34 +0200 Subject: [PATCH 103/113] lib/net: Simplify handling of socket multiplexer jobs --- src/lib/net/SecureListenSocket.cpp | 2 +- src/lib/net/SecureSocket.cpp | 27 ++++--- src/lib/net/TCPListenSocket.cpp | 12 ++- src/lib/net/TCPSocket.cpp | 18 +++-- src/lib/net/TSocketMultiplexerMethodJob.h | 90 +++++++---------------- 5 files changed, 60 insertions(+), 89 deletions(-) diff --git a/src/lib/net/SecureListenSocket.cpp b/src/lib/net/SecureListenSocket.cpp index 27b84635..11efc5cd 100644 --- a/src/lib/net/SecureListenSocket.cpp +++ b/src/lib/net/SecureListenSocket.cpp @@ -20,7 +20,7 @@ #include "SecureSocket.h" #include "net/NetworkAddress.h" #include "net/SocketMultiplexer.h" -#include "net/TSocketMultiplexerMethodJob.h" +#include "arch/Arch.h" #include "arch/XArch.h" #include "common/DataDirectories.h" #include "base/String.h" diff --git a/src/lib/net/SecureSocket.cpp b/src/lib/net/SecureSocket.cpp index d6199f09..85e1d383 100644 --- a/src/lib/net/SecureSocket.cpp +++ b/src/lib/net/SecureSocket.cpp @@ -140,17 +140,17 @@ std::unique_ptr SecureSocket::newJob() void SecureSocket::secureConnect() { - setJob(std::make_unique>( - this, &SecureSocket::serviceConnect, - getSocket(), isReadable(), isWritable())); + setJob(std::make_unique([this](auto j, auto r, auto w, auto e) + { return serviceConnect(j, r, w, e); }, + getSocket(), isReadable(), isWritable())); } void SecureSocket::secureAccept() { - setJob(std::make_unique>( - this, &SecureSocket::serviceAccept, - getSocket(), isReadable(), isWritable())); + setJob(std::make_unique([this](auto j, auto r, auto w, auto e) + { return serviceAccept(j, r, w, e); }, + getSocket(), isReadable(), isWritable())); } TCPSocket::EJobResult @@ -772,9 +772,9 @@ MultiplexerJobStatus SecureSocket::serviceConnect(ISocketMultiplexerJob* job, // Retry case return { true, - std::make_unique>( - this, &SecureSocket::serviceConnect, - getSocket(), isReadable(), isWritable()) + std::make_unique([this](auto j, auto r, auto w, auto e) + { return serviceConnect(j, r, w, e); }, + getSocket(), isReadable(), isWritable()) }; } @@ -802,9 +802,12 @@ MultiplexerJobStatus SecureSocket::serviceAccept(ISocketMultiplexerJob* job, } // Retry case - return {true, std::make_unique>( - this, &SecureSocket::serviceAccept, - getSocket(), isReadable(), isWritable())}; + return { + true, + std::make_unique([this](auto j, auto r, auto w, auto e) + { return serviceAccept(j, r, w, e); }, + getSocket(), isReadable(), isWritable()) + }; } void diff --git a/src/lib/net/TCPListenSocket.cpp b/src/lib/net/TCPListenSocket.cpp index f8407b0e..2c305fcf 100644 --- a/src/lib/net/TCPListenSocket.cpp +++ b/src/lib/net/TCPListenSocket.cpp @@ -70,8 +70,10 @@ TCPListenSocket::bind(const NetworkAddress& addr) ARCH->bindSocket(m_socket, addr.getAddress()); ARCH->listenOnSocket(m_socket); - auto new_job = std::make_unique>( - this, &TCPListenSocket::serviceListening, m_socket, true, false); + auto new_job = std::make_unique( + [this](auto j, auto r, auto w, auto e) + { return serviceListening(j, r, w, e); }, + m_socket, true, false); m_socketMultiplexer->addSocket(this, std::move(new_job)); } @@ -136,8 +138,10 @@ TCPListenSocket::accept() void TCPListenSocket::setListeningJob() { - auto new_job = std::make_unique>( - this, &TCPListenSocket::serviceListening, m_socket, true, false); + auto new_job = std::make_unique( + [this](auto j, auto r, auto w, auto e) + { return serviceListening(j, r, w, e); }, + m_socket, true, false); m_socketMultiplexer->addSocket(this, std::move(new_job)); } diff --git a/src/lib/net/TCPSocket.cpp b/src/lib/net/TCPSocket.cpp index 002d4d67..fa7edcc8 100644 --- a/src/lib/net/TCPSocket.cpp +++ b/src/lib/net/TCPSocket.cpp @@ -426,18 +426,20 @@ std::unique_ptr TCPSocket::newJob() if (!(m_readable || m_writable)) { return {}; } - return std::make_unique>( - this, &TCPSocket::serviceConnecting, - m_socket, m_readable, m_writable); + return std::make_unique( + [this](auto j, auto r, auto w, auto e) + { return serviceConnecting(j, r, w, e); }, + m_socket, m_readable, m_writable); } else { - if (!(m_readable || (m_writable && (m_outputBuffer.getSize() > 0)))) { + auto writable = m_writable && (m_outputBuffer.getSize() > 0); + if (!(m_readable || writable)) { return {}; } - return std::make_unique>( - this, &TCPSocket::serviceConnected, - m_socket, m_readable, - m_writable && (m_outputBuffer.getSize() > 0)); + return std::make_unique( + [this](auto j, auto r, auto w, auto e) + { return serviceConnected(j, r, w, e); }, + m_socket, m_readable, writable); } } diff --git a/src/lib/net/TSocketMultiplexerMethodJob.h b/src/lib/net/TSocketMultiplexerMethodJob.h index c42fab66..4b571ab3 100644 --- a/src/lib/net/TSocketMultiplexerMethodJob.h +++ b/src/lib/net/TSocketMultiplexerMethodJob.h @@ -25,81 +25,43 @@ /*! A socket multiplexer job class that invokes a member function. */ -template class TSocketMultiplexerMethodJob : public ISocketMultiplexerJob { public: - using Method = MultiplexerJobStatus (T::*)(ISocketMultiplexerJob*, bool, bool, bool); + using RunFunction = std::function; //! run() invokes \c object->method(arg) - TSocketMultiplexerMethodJob(T* object, Method method, - ArchSocket socket, bool readable, bool writeable); - virtual ~TSocketMultiplexerMethodJob(); + TSocketMultiplexerMethodJob(const RunFunction& func, + ArchSocket socket, bool readable, bool writable) : + func_{func}, + m_socket(ARCH->copySocket(socket)), + m_readable(readable), + m_writable(writable) + { + } + + ~TSocketMultiplexerMethodJob() override + { + ARCH->closeSocket(m_socket); + } // IJob overrides - virtual MultiplexerJobStatus run(bool readable, bool writable, bool error) override; - virtual ArchSocket getSocket() const override; - virtual bool isReadable() const override; - virtual bool isWritable() const override; + virtual MultiplexerJobStatus run(bool readable, bool writable, bool error) override + { + if (func_) { + return func_(this, readable, writable, error); + } + return {false, {}}; + } + + virtual ArchSocket getSocket() const override { return m_socket; } + virtual bool isReadable() const override { return m_readable; } + virtual bool isWritable() const override { return m_writable; } private: - T* m_object; - Method m_method; + RunFunction func_; ArchSocket m_socket; bool m_readable; bool m_writable; - void* m_arg; }; -template -inline -TSocketMultiplexerMethodJob::TSocketMultiplexerMethodJob(T* object, - Method method, ArchSocket socket, - bool readable, bool writable) : - m_object(object), - m_method(method), - m_socket(ARCH->copySocket(socket)), - m_readable(readable), - m_writable(writable) -{ - // do nothing -} -template -inline -TSocketMultiplexerMethodJob::~TSocketMultiplexerMethodJob() -{ - ARCH->closeSocket(m_socket); -} - -template -inline MultiplexerJobStatus TSocketMultiplexerMethodJob::run(bool read, bool write, bool error) -{ - if (m_object != NULL) { - return (m_object->*m_method)(this, read, write, error); - } - return {false, {}}; -} - -template -inline -ArchSocket -TSocketMultiplexerMethodJob::getSocket() const -{ - return m_socket; -} - -template -inline -bool -TSocketMultiplexerMethodJob::isReadable() const -{ - return m_readable; -} - -template -inline -bool -TSocketMultiplexerMethodJob::isWritable() const -{ - return m_writable; -} From 608594f245548304bbc85795567eb94accdc1617 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 21:30:58 +0200 Subject: [PATCH 104/113] Document the releasing procedure --- RELEASING.md | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 RELEASING.md diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 00000000..741f54ae --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,59 @@ +Creating a release +================== + +This document is documentation intednded for maintainers of Barrier. +It documents the release process of Barrier. + +Step 1: Setup environment variables +----------------------------------- + +Setup the following environment variable that will be used throughout the rest of the steps. + + export VERSION=X.Y.Z + +Step 2: Release notes PR +------------------------ + +Open a new branch (e.g. `release`) and run the following: + + towncrier --version ${VERSION} --date `date -u +%F` + +This collects the release notes using the `towncrier` tool. Please commit the collected release +notes afterwards. + +Certain file names are not properly supported by the `towncrier` tool and it ignores them. +Check `newsfragments` directory for any forgotten release notes + +Step 3: Merge the release notes PR +---------------------------------- + +Step 4: Push git tag +-------------------- + +Pull the merge commit created on the `master` branch during the step 2. + +Create a tag: + + git tag -s v${VERSION} -m v${VERSION} + +Push the tag: + + git push origin master --tags + + +Step 5: Draft a new release on Github +------------------------------------- + +Go to https://github.com/buildbot/buildbot/releases and draft a new release. + +Use git tag as the title of the release: `vX.Y.Z`. + +Use the release notes generated by the `towncrier` tool as the description of the releases. + +Upload the artifacts created by Azure pipelines as the binaries of the release. The following +artifacts should be uploaded to Github: + + - the Barrier-X.Y.Z-release.dmg created by the oldest Mac OS task (artifact name is + "Mac Release Disk Image and App XYZ"). + + - the BarrierSetup-X.Y.Z-release.exe (artifact name is Windows Release Installer). From e8453f2b9af2229321b411fbe9eefc680249b402 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 21:30:59 +0200 Subject: [PATCH 105/113] azure-pipelines: Use a different artifact name for each macOS image --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 2b42fc1d..e34a3bc5 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -114,4 +114,4 @@ jobs: condition: eq(variables['B_BUILD_TYPE'], 'Release') inputs: pathtoPublish: build/bundle - artifactName: Mac Release Disk Image and App + artifactName: Mac Release Disk Image and App $(imageName) From e7bdcb52496020b469aeccc41e8e2633e24b868a Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 21:31:00 +0200 Subject: [PATCH 106/113] Setup release notes build using towncrier tool --- doc/newsfragments/README.md | 19 +++++++------ doc/release_notes/index.md | 4 +++ doc/release_notes/index.template.jinja | 37 ++++++++++++++++++++++++ towncrier.toml | 39 ++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 9 deletions(-) create mode 100644 doc/release_notes/index.md create mode 100644 doc/release_notes/index.template.jinja create mode 100644 towncrier.toml diff --git a/doc/newsfragments/README.md b/doc/newsfragments/README.md index a0ce3f33..0338cf80 100644 --- a/doc/newsfragments/README.md +++ b/doc/newsfragments/README.md @@ -1,12 +1,13 @@ -This is the directory for news snippets used by towncrier: https://github.com/twisted/towncrier +This is the directory for release note fragments processed by +[towncrier](https://github.com/hawkowl/towncrier). -When changing code in a way that's visible to an end user please make a new file in this directory. -It will be removed and integrated into release notes document upon a release of a new version of -Barrier. +When making a user-visible change create a file in this directory and it will be automatically be +included into the release note document when the next release is published. -towncrier has a few standard types of news fragments, signified by the file extension. These are: +The file extension specifies the type of a change. The following are currently supported: -.feature: Signifying a new feature. -.bugfix: Signifying a bug fix. -.doc: Signifying a documentation improvement. -.removal: Signifying a deprecation or removal of public API. + - .feature: a new feature. + - .bugfix: a bug fix. + - .security: a fix for security issue. + - .doc: a documentation improvement. + - .removal: a deprecation or removal of functionality. diff --git a/doc/release_notes/index.md b/doc/release_notes/index.md new file mode 100644 index 00000000..77dd565a --- /dev/null +++ b/doc/release_notes/index.md @@ -0,0 +1,4 @@ +Release notes +============= + +[comment]: <> (towncrier release notes start) diff --git a/doc/release_notes/index.template.jinja b/doc/release_notes/index.template.jinja new file mode 100644 index 00000000..418a1d32 --- /dev/null +++ b/doc/release_notes/index.template.jinja @@ -0,0 +1,37 @@ +{% for section, _ in sections|dictsort(by='key') %} +{% set underline = "-" %} +{% if section %} +{{section}} +{{ underline * section|length }}{% set underline = "-" %} + +{% endif %} +{% if sections[section] %} +{% for category, val in definitions|dictsort if category in sections[section]%} + +{{ definitions[category]['name'] }} +{{ underline * definitions[category]['name']|length }} + +{% if definitions[category]['showcontent'] %} +{% for text, values in sections[section][category]|dictsort(by='value') %} +- {{ text }} +{% endfor %} +{% else %} +- {{ sections[section][category]['']|sort|join(', ') }} + + +{% endif %} +{% if sections[section][category]|length == 0 %} + +No significant changes. + + +{% else %} +{% endif %} +{% endfor %} +{% else %} + +No significant changes. + + +{% endif %} +{% endfor %} diff --git a/towncrier.toml b/towncrier.toml new file mode 100644 index 00000000..d8f0a61c --- /dev/null +++ b/towncrier.toml @@ -0,0 +1,39 @@ +[tool.towncrier] + package = "" + directory = "doc/newsfragments" + filename = "doc/release_notes/index.md" + template = "doc/release_notes/index.template.jinja" + title_format = "\nBarrier `{version}` ( `{project_date}` )\n================================\n" + start_string = "[comment]: <> (towncrier release notes start)" + [[tool.towncrier.section]] + path = "" + + [[tool.towncrier.type]] + directory = "security" + name = "Security fixes" + showcontent = false + + [[tool.towncrier.type]] + directory = "feature" + name = "Features" + showcontent = true + + [[tool.towncrier.type]] + directory = "bugfix" + name = "Bug fixes" + showcontent = true + + [[tool.towncrier.type]] + directory = "doc" + name = "Improved Documentation" + showcontent = true + + [[tool.towncrier.type]] + directory = "removal" + name = "Deprecations and Removals" + showcontent = true + + [[tool.towncrier.type]] + directory = "misc" + name = "Miscellaneous" + showcontent = false From 56177d461a9f0792764a57e2a1e049c2b3bb0b6f Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 21:31:01 +0200 Subject: [PATCH 107/113] Release notes for v2.3.4 --- .../close-failed-handshake-connections.bugfix | 6 ---- .../enforce-maximum-message-length.bugfix | 6 ---- .../fix-crash-on-ssl-hello.bugfix | 4 --- doc/newsfragments/ssl-corrupted-data.bugfix | 2 -- doc/release_notes/index.md | 28 +++++++++++++++++++ 5 files changed, 28 insertions(+), 18 deletions(-) delete mode 100644 doc/newsfragments/close-failed-handshake-connections.bugfix delete mode 100644 doc/newsfragments/enforce-maximum-message-length.bugfix delete mode 100644 doc/newsfragments/fix-crash-on-ssl-hello.bugfix delete mode 100644 doc/newsfragments/ssl-corrupted-data.bugfix diff --git a/doc/newsfragments/close-failed-handshake-connections.bugfix b/doc/newsfragments/close-failed-handshake-connections.bugfix deleted file mode 100644 index 0dc8c16c..00000000 --- a/doc/newsfragments/close-failed-handshake-connections.bugfix +++ /dev/null @@ -1,6 +0,0 @@ -SECURITY ISSUE - -Barrier will now correctly close connections when the app-level handshake fails (fixes CVE-2021-42075). - -Previously repeated failing connections would leak file descriptors leading to Barrier being unable -to receive new connections from clients. diff --git a/doc/newsfragments/enforce-maximum-message-length.bugfix b/doc/newsfragments/enforce-maximum-message-length.bugfix deleted file mode 100644 index 81ec2ba0..00000000 --- a/doc/newsfragments/enforce-maximum-message-length.bugfix +++ /dev/null @@ -1,6 +0,0 @@ -SECURITY ISSUE - -Barrier will now enforce a maximum length of input messages (fixes CVE-2021-42076). - -Previously it was possible for a malicious client or server to send excessive length messages -leading to denial of service by resource exhaustion. diff --git a/doc/newsfragments/fix-crash-on-ssl-hello.bugfix b/doc/newsfragments/fix-crash-on-ssl-hello.bugfix deleted file mode 100644 index 30bb0603..00000000 --- a/doc/newsfragments/fix-crash-on-ssl-hello.bugfix +++ /dev/null @@ -1,4 +0,0 @@ -SECURITY ISSUE - -Fixed a bug which caused Barrier to crash when disconnecting a TCP session just after sending Hello message. -This bug allowed an unauthenticated attacker to crash Barrier with only network access. diff --git a/doc/newsfragments/ssl-corrupted-data.bugfix b/doc/newsfragments/ssl-corrupted-data.bugfix deleted file mode 100644 index db8bbf86..00000000 --- a/doc/newsfragments/ssl-corrupted-data.bugfix +++ /dev/null @@ -1,2 +0,0 @@ -Fixed a bug in SSL implementation that caused invalid data occasionally being sent to clients -under heavy load. diff --git a/doc/release_notes/index.md b/doc/release_notes/index.md index 77dd565a..006debb5 100644 --- a/doc/release_notes/index.md +++ b/doc/release_notes/index.md @@ -2,3 +2,31 @@ Release notes ============= [comment]: <> (towncrier release notes start) + +Barrier `2.3.4` ( `2021-11-01` ) +================================ + +Security fixes +-------------- + +- Barrier will now correctly close connections when the app-level handshake fails (fixes CVE-2021-42075). + + Previously repeated failing connections would leak file descriptors leading to Barrier being unable + to receive new connections from clients. + +- Barrier will now enforce a maximum length of input messages (fixes CVE-2021-42076). + + Previously it was possible for a malicious client or server to send excessive length messages + leading to denial of service by resource exhaustion. + +- Fixed a bug which caused Barrier to crash when disconnecting a TCP session just after sending Hello message. + This bug allowed an unauthenticated attacker to crash Barrier with only network access. + +All of the above security issues have been reported by Matthias Gerstner who was really helpful +resolving them. + +Bug fixes +--------- + +- Fixed a bug in SSL implementation that caused invalid data occasionally being sent to clients + under heavy load. From 6b729df698824376b9b5ee518763528ccbeff42b Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 21:56:47 +0200 Subject: [PATCH 108/113] Release notes for v2.4.0 --- .../build-failure-mipsel-riscv.bugfix | 1 - .../client-certificate-checking.bugfix | 7 --- .../client-send-certificate.feature | 1 - ...iguration-reading-non-ascii-windows.bugfix | 1 - doc/newsfragments/dont-use-openssl-cli.bugfix | 1 - doc/newsfragments/drop-target--option.feature | 1 - .../enable-crypto-by-default.feature | 2 - .../fingerprint-randomart.feature | 3 - doc/newsfragments/fix-x11-paste.bugfix | 1 - doc/newsfragments/gui-autostart.feature | 1 - .../gui-hotkey-multiple-actions.bugfix | 1 - .../gui-hotkey-special-keys-handling.bugfix | 1 - ...gui-keyboard-enabled-screen-layout.feature | 1 - .../keyboard-backlight-media-keys.feature | 1 - .../muhenkan-eisu-toggle-keys.feature | 1 - .../non-ascii-character-transfer.bugfix | 1 - doc/newsfragments/profile-dir-option.feature | 1 - .../regenerate-broken-server-cert.bugfix | 1 - doc/newsfragments/sha256-fingerprints.bugfix | 4 -- doc/newsfragments/sun-keyboard-keys.bugfix | 1 - doc/newsfragments/translation_chinese.bugfix | 1 - doc/newsfragments/translation_slovak.bugfix | 1 - doc/newsfragments/use-theme-icons.bugfix | 1 - doc/newsfragments/windows-service-path.bugfix | 1 - doc/release_notes/index.md | 62 +++++++++++++++++++ 25 files changed, 62 insertions(+), 36 deletions(-) delete mode 100644 doc/newsfragments/build-failure-mipsel-riscv.bugfix delete mode 100644 doc/newsfragments/client-certificate-checking.bugfix delete mode 100644 doc/newsfragments/client-send-certificate.feature delete mode 100644 doc/newsfragments/configuration-reading-non-ascii-windows.bugfix delete mode 100644 doc/newsfragments/dont-use-openssl-cli.bugfix delete mode 100644 doc/newsfragments/drop-target--option.feature delete mode 100644 doc/newsfragments/enable-crypto-by-default.feature delete mode 100644 doc/newsfragments/fingerprint-randomart.feature delete mode 100644 doc/newsfragments/fix-x11-paste.bugfix delete mode 100644 doc/newsfragments/gui-autostart.feature delete mode 100644 doc/newsfragments/gui-hotkey-multiple-actions.bugfix delete mode 100644 doc/newsfragments/gui-hotkey-special-keys-handling.bugfix delete mode 100644 doc/newsfragments/gui-keyboard-enabled-screen-layout.feature delete mode 100644 doc/newsfragments/keyboard-backlight-media-keys.feature delete mode 100644 doc/newsfragments/muhenkan-eisu-toggle-keys.feature delete mode 100644 doc/newsfragments/non-ascii-character-transfer.bugfix delete mode 100644 doc/newsfragments/profile-dir-option.feature delete mode 100644 doc/newsfragments/regenerate-broken-server-cert.bugfix delete mode 100644 doc/newsfragments/sha256-fingerprints.bugfix delete mode 100644 doc/newsfragments/sun-keyboard-keys.bugfix delete mode 100644 doc/newsfragments/translation_chinese.bugfix delete mode 100644 doc/newsfragments/translation_slovak.bugfix delete mode 100644 doc/newsfragments/use-theme-icons.bugfix delete mode 100644 doc/newsfragments/windows-service-path.bugfix diff --git a/doc/newsfragments/build-failure-mipsel-riscv.bugfix b/doc/newsfragments/build-failure-mipsel-riscv.bugfix deleted file mode 100644 index 4e0506ad..00000000 --- a/doc/newsfragments/build-failure-mipsel-riscv.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix build failure on mips*el and riscv64 architecture. diff --git a/doc/newsfragments/client-certificate-checking.bugfix b/doc/newsfragments/client-certificate-checking.bugfix deleted file mode 100644 index 01d4d03d..00000000 --- a/doc/newsfragments/client-certificate-checking.bugfix +++ /dev/null @@ -1,7 +0,0 @@ -SECURITY ISSUE - -Barrier now supports client identity verification (fixes CVE-2021-42072, CVE-2021-42073). - -To support seamless upgrades from older versions of Barrier this is currently disabled by default. -The feature can be enabled in the settings dialog. If enabled, older clients of Barrier will be -rejected. diff --git a/doc/newsfragments/client-send-certificate.feature b/doc/newsfragments/client-send-certificate.feature deleted file mode 100644 index b5584290..00000000 --- a/doc/newsfragments/client-send-certificate.feature +++ /dev/null @@ -1 +0,0 @@ -Barrier client now sends certificate that the server can verify. diff --git a/doc/newsfragments/configuration-reading-non-ascii-windows.bugfix b/doc/newsfragments/configuration-reading-non-ascii-windows.bugfix deleted file mode 100644 index 05234a50..00000000 --- a/doc/newsfragments/configuration-reading-non-ascii-windows.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixed reading of configuration on Windows when the paths contain non-ASCII characters (https://github.com/debauchee/barrier/issues/976, https://github.com/debauchee/barrier/issues/974, https://github.com/debauchee/barrier/issues/444). diff --git a/doc/newsfragments/dont-use-openssl-cli.bugfix b/doc/newsfragments/dont-use-openssl-cli.bugfix deleted file mode 100644 index 316d6abf..00000000 --- a/doc/newsfragments/dont-use-openssl-cli.bugfix +++ /dev/null @@ -1 +0,0 @@ -Barrier no longer uses openssl CLI tool for any operations and hooks into the openssl library directly. diff --git a/doc/newsfragments/drop-target--option.feature b/doc/newsfragments/drop-target--option.feature deleted file mode 100644 index a49763e3..00000000 --- a/doc/newsfragments/drop-target--option.feature +++ /dev/null @@ -1 +0,0 @@ -Added `--drop-target` option that improves drag and drop support on Windows when Barrier is being run as a portable app. diff --git a/doc/newsfragments/enable-crypto-by-default.feature b/doc/newsfragments/enable-crypto-by-default.feature deleted file mode 100644 index 0c633ee6..00000000 --- a/doc/newsfragments/enable-crypto-by-default.feature +++ /dev/null @@ -1,2 +0,0 @@ -The `--enable-crypto` command line option has been made the default to reduce chances of accidental security mishaps when configuring Barrier from command line. -A new `--disable-crypto` command line option has been added to explicitly disable encryption. diff --git a/doc/newsfragments/fingerprint-randomart.feature b/doc/newsfragments/fingerprint-randomart.feature deleted file mode 100644 index 9ffced93..00000000 --- a/doc/newsfragments/fingerprint-randomart.feature +++ /dev/null @@ -1,3 +0,0 @@ -Added support for randomart images for easier comparison of SSL -certificate fingerprints. The algorithm is identical to what -OpenSSH uses. diff --git a/doc/newsfragments/fix-x11-paste.bugfix b/doc/newsfragments/fix-x11-paste.bugfix deleted file mode 100644 index af4da5b1..00000000 --- a/doc/newsfragments/fix-x11-paste.bugfix +++ /dev/null @@ -1 +0,0 @@ - Map more X11 clipboard MIME types to corresponding converters (https://github.com/debauchee/barrier/issues/344). diff --git a/doc/newsfragments/gui-autostart.feature b/doc/newsfragments/gui-autostart.feature deleted file mode 100644 index d75ca8d8..00000000 --- a/doc/newsfragments/gui-autostart.feature +++ /dev/null @@ -1 +0,0 @@ -Implemented a configuration option for Server GUI auto-start. diff --git a/doc/newsfragments/gui-hotkey-multiple-actions.bugfix b/doc/newsfragments/gui-hotkey-multiple-actions.bugfix deleted file mode 100644 index c78712b8..00000000 --- a/doc/newsfragments/gui-hotkey-multiple-actions.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixed setup of multiple actions associated with a hotkey. diff --git a/doc/newsfragments/gui-hotkey-special-keys-handling.bugfix b/doc/newsfragments/gui-hotkey-special-keys-handling.bugfix deleted file mode 100644 index 5dd12a7e..00000000 --- a/doc/newsfragments/gui-hotkey-special-keys-handling.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixed setup of hotkeys with special characters such as comma and semicolon (https://github.com/debauchee/barrier/issues/778). diff --git a/doc/newsfragments/gui-keyboard-enabled-screen-layout.feature b/doc/newsfragments/gui-keyboard-enabled-screen-layout.feature deleted file mode 100644 index 7e495376..00000000 --- a/doc/newsfragments/gui-keyboard-enabled-screen-layout.feature +++ /dev/null @@ -1 +0,0 @@ -Made it possible to use keyboard instead of mouse to modify screen layout. diff --git a/doc/newsfragments/keyboard-backlight-media-keys.feature b/doc/newsfragments/keyboard-backlight-media-keys.feature deleted file mode 100644 index 9566304b..00000000 --- a/doc/newsfragments/keyboard-backlight-media-keys.feature +++ /dev/null @@ -1 +0,0 @@ -Added support for keyboard backlight media keys diff --git a/doc/newsfragments/muhenkan-eisu-toggle-keys.feature b/doc/newsfragments/muhenkan-eisu-toggle-keys.feature deleted file mode 100644 index 2c5e7163..00000000 --- a/doc/newsfragments/muhenkan-eisu-toggle-keys.feature +++ /dev/null @@ -1 +0,0 @@ -Added support for Eisu_toggle and Muhenkan keys diff --git a/doc/newsfragments/non-ascii-character-transfer.bugfix b/doc/newsfragments/non-ascii-character-transfer.bugfix deleted file mode 100644 index 31051ce5..00000000 --- a/doc/newsfragments/non-ascii-character-transfer.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixed transfer of non-ASCII characters coming from a Windows server in certain cases (https://github.com/debauchee/barrier/issues/527). diff --git a/doc/newsfragments/profile-dir-option.feature b/doc/newsfragments/profile-dir-option.feature deleted file mode 100644 index f4836c39..00000000 --- a/doc/newsfragments/profile-dir-option.feature +++ /dev/null @@ -1 +0,0 @@ -Added `--profile-dir` option that allows to select custom profile directory. diff --git a/doc/newsfragments/regenerate-broken-server-cert.bugfix b/doc/newsfragments/regenerate-broken-server-cert.bugfix deleted file mode 100644 index 8ea1df3c..00000000 --- a/doc/newsfragments/regenerate-broken-server-cert.bugfix +++ /dev/null @@ -1 +0,0 @@ -Barrier will now regenerate server certificate if it's invalid instead of failing to launch (https://github.com/debauchee/barrier/issues/802) diff --git a/doc/newsfragments/sha256-fingerprints.bugfix b/doc/newsfragments/sha256-fingerprints.bugfix deleted file mode 100644 index a724c3b5..00000000 --- a/doc/newsfragments/sha256-fingerprints.bugfix +++ /dev/null @@ -1,4 +0,0 @@ -Barrier now uses SHA256 fingerprints for establishing security of encrypted SSL connections. -After upgrading client to new version the existing server fingerprint will need to be approved again. -Client and server will show both SHA1 and SHA256 server fingerprints to allow interoperability -with older versions of Barrier. diff --git a/doc/newsfragments/sun-keyboard-keys.bugfix b/doc/newsfragments/sun-keyboard-keys.bugfix deleted file mode 100644 index 83bc952f..00000000 --- a/doc/newsfragments/sun-keyboard-keys.bugfix +++ /dev/null @@ -1 +0,0 @@ -Added support for additional keys on Sun Microsystems USB keyboards (https://github.com/debauchee/barrier/issues/784). diff --git a/doc/newsfragments/translation_chinese.bugfix b/doc/newsfragments/translation_chinese.bugfix deleted file mode 100644 index cab219e0..00000000 --- a/doc/newsfragments/translation_chinese.bugfix +++ /dev/null @@ -1 +0,0 @@ -Updated Chinese translation. diff --git a/doc/newsfragments/translation_slovak.bugfix b/doc/newsfragments/translation_slovak.bugfix deleted file mode 100644 index ff46ce94..00000000 --- a/doc/newsfragments/translation_slovak.bugfix +++ /dev/null @@ -1 +0,0 @@ -Updated Slovak translation. diff --git a/doc/newsfragments/use-theme-icons.bugfix b/doc/newsfragments/use-theme-icons.bugfix deleted file mode 100644 index 9dae72ca..00000000 --- a/doc/newsfragments/use-theme-icons.bugfix +++ /dev/null @@ -1 +0,0 @@ -Theme icons are now preferred to icons distributed together with Barrier (https://github.com/debauchee/barrier/issues/471). diff --git a/doc/newsfragments/windows-service-path.bugfix b/doc/newsfragments/windows-service-path.bugfix deleted file mode 100644 index c418b0aa..00000000 --- a/doc/newsfragments/windows-service-path.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixed incorrect setup of Barrier service path on Windows. diff --git a/doc/release_notes/index.md b/doc/release_notes/index.md index 006debb5..72d3a43b 100644 --- a/doc/release_notes/index.md +++ b/doc/release_notes/index.md @@ -3,6 +3,68 @@ Release notes [comment]: <> (towncrier release notes start) +Barrier `2.4.0` ( `2021-11-01` ) +================================ + +Security fixes +-------------- + +- Barrier now supports client identity verification (fixes CVE-2021-42072, CVE-2021-42073). + + Previously a malicious client could connect to Barrier server without any authentication and + send application-level messages. This made the attack surface of Barrier significantly larger. + Additionally, in case the malicious client got possession of a valid screen name by brute forcing + or other means it could modify the clipboard contents of the server. + + To support seamless upgrades from older versions of Barrier this is currently disabled by default. + The feature can be enabled in the settings dialog. If enabled, older clients of Barrier will be + rejected. + +- Barrier now uses SHA256 fingerprints for establishing security of encrypted SSL connections. + After upgrading client to new version the existing server fingerprint will need to be approved + again. Client and server will show both SHA1 and SHA256 server fingerprints to allow + interoperability with older versions of Barrier. + +Bug fixes +--------- + +- Fixed build failure on mips*el and riscv64 architecture. +- Fixed reading of configuration on Windows when the paths contain non-ASCII characters +(https://github.com/debauchee/barrier/issues/976, https://github.com/debauchee/barrier/issues/974, + https://github.com/debauchee/barrier/issues/444). +- Barrier no longer uses openssl CLI tool for any operations and hooks into the openssl library directly. +- More X11 clipboard MIME types have been mapped to corresponding converters (https://github.com/debauchee/barrier/issues/344). +- Fixed setup of multiple actions associated with a hotkey. +- Fixed setup of hotkeys with special characters such as comma and semicolon + (https://github.com/debauchee/barrier/issues/778). +- Fixed transfer of non-ASCII characters coming from a Windows server in certain cases + (https://github.com/debauchee/barrier/issues/527). +- Barrier will now regenerate server certificate if it's invalid instead of failing to launch + (https://github.com/debauchee/barrier/issues/802) +- Added support for additional keys on Sun Microsystems USB keyboards + (https://github.com/debauchee/barrier/issues/784). +- Updated Chinese translation. +- Updated Slovak translation. +- Theme icons are now preferred to icons distributed together with Barrier + (https://github.com/debauchee/barrier/issues/471). +- Fixed incorrect setup of Barrier service path on Windows. + +Features +-------- + +- Added `--drop-target` option that improves drag and drop support on Windows when Barrier is + being run as a portable app. +- The `--enable-crypto` command line option has been made the default to reduce chances of + accidental security mishaps when configuring Barrier from command line. + A new `--disable-crypto` command line option has been added to explicitly disable encryption. +- Added support for randomart images for easier comparison of SSL certificate fingerprints. + The algorithm is identical to what OpenSSH uses. +- Implemented a configuration option for Server GUI auto-start. +- Made it possible to use keyboard instead of mouse to modify screen layout. +- Added support for keyboard backlight media keys +- Added support for Eisu_toggle and Muhenkan keys +- Added `--profile-dir` option that allows to select custom profile directory. + Barrier `2.3.4` ( `2021-11-01` ) ================================ From 3e0d758b59e44e6bb8b5e13cf96c824be44207ac Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Mon, 1 Nov 2021 22:46:43 +0200 Subject: [PATCH 109/113] Barrier v2.4.0 --- Build.properties | 4 ++-- cmake/Version.cmake | 4 ++-- doc/barrierc.1 | 2 +- doc/barriers.1 | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Build.properties b/Build.properties index d1c07fee..07192e05 100644 --- a/Build.properties +++ b/Build.properties @@ -2,6 +2,6 @@ # Barrier build parameters # BARRIER_VERSION_MAJOR = 2 -BARRIER_VERSION_MINOR = 3 -BARRIER_VERSION_PATCH = 3 +BARRIER_VERSION_MINOR = 4 +BARRIER_VERSION_PATCH = 0 BARRIER_VERSION_STAGE = release diff --git a/cmake/Version.cmake b/cmake/Version.cmake index 58d8943e..73524bf1 100644 --- a/cmake/Version.cmake +++ b/cmake/Version.cmake @@ -1,8 +1,8 @@ cmake_minimum_required (VERSION 3.4) set (BARRIER_VERSION_MAJOR 2) -set (BARRIER_VERSION_MINOR 3) -set (BARRIER_VERSION_PATCH 3) +set (BARRIER_VERSION_MINOR 4) +set (BARRIER_VERSION_PATCH 0) set (BARRIER_VERSION_STAGE "release") # diff --git a/doc/barrierc.1 b/doc/barrierc.1 index 2fd882ac..d4704470 100644 --- a/doc/barrierc.1 +++ b/doc/barrierc.1 @@ -1,5 +1,5 @@ .\" See UpdateManpages.txt about modification of this file. Most of it was generated by help2man 1.47.8. -.TH BARRIERC "1" "November 2019" "barrierc 2.3.3-release" "User Commands" +.TH BARRIERC "1" "November 2019" "barrierc 2.4.0-release" "User Commands" .SH NAME barrierc \- Barrier Keyboard/Mouse Client .SH SYNOPSIS diff --git a/doc/barriers.1 b/doc/barriers.1 index 098ea846..f4a460e6 100644 --- a/doc/barriers.1 +++ b/doc/barriers.1 @@ -1,5 +1,5 @@ .\" See UpdateManpages.txt about modification of this file. Most of it was generated by help2man 1.47.8. -.TH BARRIERS "1" "November 2019" "barriers 2.3.3-release" "User Commands" +.TH BARRIERS "1" "November 2019" "barriers 2.4.0-release" "User Commands" .SH NAME barriers \- Barrier Keyboard/Mouse Server .SH SYNOPSIS From 21c8fb88d041c2ebf1136b70c5ccaa5ecd0d9305 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Tue, 2 Nov 2021 14:32:21 +0200 Subject: [PATCH 110/113] doc: Add missed details to v2.3.4 and v2.4.0 release notes --- doc/release_notes/index.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/release_notes/index.md b/doc/release_notes/index.md index 72d3a43b..0f2b7ca1 100644 --- a/doc/release_notes/index.md +++ b/doc/release_notes/index.md @@ -25,6 +25,9 @@ Security fixes again. Client and server will show both SHA1 and SHA256 server fingerprints to allow interoperability with older versions of Barrier. +All of the above security issues have been reported by Matthias Gerstner who was really helpful +resolving them. + Bug fixes --------- @@ -81,7 +84,8 @@ Security fixes Previously it was possible for a malicious client or server to send excessive length messages leading to denial of service by resource exhaustion. -- Fixed a bug which caused Barrier to crash when disconnecting a TCP session just after sending Hello message. +- Fixed a bug which caused Barrier to crash when disconnecting a TCP session just after sending + Hello message (fixes CVE-2021-42074). This bug allowed an unauthenticated attacker to crash Barrier with only network access. All of the above security issues have been reported by Matthias Gerstner who was really helpful From dd3ea8adfef868e52098ea24d2ed08320a90e3b9 Mon Sep 17 00:00:00 2001 From: Chih-Hsuan Yen Date: Fri, 20 Aug 2021 21:27:57 +0800 Subject: [PATCH 111/113] lib/platform: Fix encoding for text copied between linux and windows Copied from https://github.com/symless/synergy-core/pull/7029. I don't include the application/x-moz-nativehtml part in that patch as I already added it in https://github.com/debauchee/barrier/pull/1164. Fixes https://github.com/debauchee/barrier/issues/1037 Fixes https://github.com/debauchee/barrier/issues/1137 Original author: Serhii Hadzhilov --- ...g-for-text-copied-between-linux-and-windows.bugfix | 2 ++ src/lib/platform/XWindowsClipboardHTMLConverter.cpp | 11 +++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 doc/newsfragments/fix-wrong-encoding-for-text-copied-between-linux-and-windows.bugfix diff --git a/doc/newsfragments/fix-wrong-encoding-for-text-copied-between-linux-and-windows.bugfix b/doc/newsfragments/fix-wrong-encoding-for-text-copied-between-linux-and-windows.bugfix new file mode 100644 index 00000000..3b76d060 --- /dev/null +++ b/doc/newsfragments/fix-wrong-encoding-for-text-copied-between-linux-and-windows.bugfix @@ -0,0 +1,2 @@ +Fix wrong encoding for text copied between Linux and Windows +(https://github.com/debauchee/barrier/issues/1037, https://github.com/debauchee/barrier/issues/1137). diff --git a/src/lib/platform/XWindowsClipboardHTMLConverter.cpp b/src/lib/platform/XWindowsClipboardHTMLConverter.cpp index a13e80e4..eae032d5 100644 --- a/src/lib/platform/XWindowsClipboardHTMLConverter.cpp +++ b/src/lib/platform/XWindowsClipboardHTMLConverter.cpp @@ -56,10 +56,17 @@ XWindowsClipboardHTMLConverter::getDataSize() const std::string XWindowsClipboardHTMLConverter::fromIClipboard(const std::string& data) const { - return Unicode::UTF8ToUTF16(data); + return data; } std::string XWindowsClipboardHTMLConverter::toIClipboard(const std::string& data) const { - return Unicode::UTF16ToUTF8(data); + // Older Firefox [1] and possibly other applications use UTF-16 for text/html - handle both + // [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1497580 + if (Unicode::isUTF8(data)) { + return data; + } else { + return Unicode::UTF16ToUTF8(data); + } + return data; } From bfc465d477760b44624d31742b787b21a218d41d Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Wed, 3 Nov 2021 14:15:02 +0200 Subject: [PATCH 112/113] github: Add pull request template --- .github/PULL_REQUEST_TEMPLATE.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..df9d99b9 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,3 @@ +## Contributor Checklist: + +* [ ] I have created a file in the `doc/newsfragments` directory (and read the `README.md` in that directory) From 4b12265ae5d324b942698a3177e1d8b1749414d7 Mon Sep 17 00:00:00 2001 From: James Le Cuirot Date: Tue, 2 Nov 2021 20:59:51 +0000 Subject: [PATCH 113/113] Add missing cstddef includes for NULL Fixes https://github.com/debauchee/barrier/issues/1366. --- doc/newsfragments/gcc-11-build.bugfix | 1 + src/lib/base/Event.h | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 doc/newsfragments/gcc-11-build.bugfix diff --git a/doc/newsfragments/gcc-11-build.bugfix b/doc/newsfragments/gcc-11-build.bugfix new file mode 100644 index 00000000..255f5365 --- /dev/null +++ b/doc/newsfragments/gcc-11-build.bugfix @@ -0,0 +1 @@ +Fixed build on GCC 11.2 (https://github.com/debauchee/barrier/issues/1366). diff --git a/src/lib/base/Event.h b/src/lib/base/Event.h index 38a2cf11..cb00dccb 100644 --- a/src/lib/base/Event.h +++ b/src/lib/base/Event.h @@ -21,6 +21,8 @@ #include "common/basic_types.h" #include "common/stdmap.h" +#include + class EventData { public: EventData() { }