diff --git a/common/src/main/java/bisq/common/util/InvalidVersionException.java b/common/src/main/java/bisq/common/util/InvalidVersionException.java new file mode 100644 index 0000000000..d63bc31af0 --- /dev/null +++ b/common/src/main/java/bisq/common/util/InvalidVersionException.java @@ -0,0 +1,24 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq 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 Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.common.util; + +public class InvalidVersionException extends Exception { + public InvalidVersionException(String msg) { + super(msg); + } +} diff --git a/common/src/main/java/bisq/common/util/Utilities.java b/common/src/main/java/bisq/common/util/Utilities.java index 6cdd3bf342..291baa6843 100644 --- a/common/src/main/java/bisq/common/util/Utilities.java +++ b/common/src/main/java/bisq/common/util/Utilities.java @@ -17,8 +17,6 @@ package bisq.common.util; -import bisq.common.crypto.LimitedKeyStrengthException; - import org.bitcoinj.core.Utils; import com.google.gson.ExclusionStrategy; @@ -71,6 +69,7 @@ import lombok.extern.slf4j.Slf4j; import javax.annotation.Nullable; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static java.awt.Desktop.Action; import static java.awt.Desktop.getDesktop; @@ -182,6 +181,34 @@ public class Utilities { return System.getProperty("os.name").toLowerCase(Locale.US); } + public static String getOSVersion() { + return System.getProperty("os.version").toLowerCase(Locale.US); + } + + public static int getMinorVersion() throws InvalidVersionException { + String version = getOSVersion(); + String[] tokens = version.split("\\."); + try { + checkArgument(tokens.length > 1); + return Integer.parseInt(tokens[1]); + } catch (IllegalArgumentException e) { + printSysInfo(); + throw new InvalidVersionException("Version is not in expected format. Version=" + version); + } + } + + public static int getMajorVersion() throws InvalidVersionException { + String version = getOSVersion(); + String[] tokens = version.split("\\."); + try { + checkArgument(tokens.length > 0); + return Integer.parseInt(tokens[0]); + } catch (IllegalArgumentException e) { + printSysInfo(); + throw new InvalidVersionException("Version is not in expected format. Version=" + version); + } + } + public static String getOSArchitecture() { String osArch = System.getProperty("os.arch"); if (isWindows()) { @@ -462,4 +489,5 @@ public class Utilities { Map map = new ConcurrentHashMap<>(); return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; } + } diff --git a/core/src/main/java/bisq/core/app/BisqHeadlessApp.java b/core/src/main/java/bisq/core/app/BisqHeadlessApp.java index 9307e25b92..b93d169788 100644 --- a/core/src/main/java/bisq/core/app/BisqHeadlessApp.java +++ b/core/src/main/java/bisq/core/app/BisqHeadlessApp.java @@ -97,6 +97,7 @@ public class BisqHeadlessApp implements HeadlessApp { bisqSetup.setRejectedTxErrorMessageHandler(errorMessage -> log.warn("setRejectedTxErrorMessageHandler. errorMessage={}", errorMessage)); bisqSetup.setShowPopupIfInvalidBtcConfigHandler(() -> log.error("onShowPopupIfInvalidBtcConfigHandler")); bisqSetup.setRevolutAccountsUpdateHandler(revolutAccountList -> log.info("setRevolutAccountsUpdateHandler: revolutAccountList={}", revolutAccountList)); + bisqSetup.setOsxKeyLoggerWarningHandler(() -> log.info("setOsxKeyLoggerWarningHandler")); //TODO move to bisqSetup corruptedDatabaseFilesHandler.getCorruptedDatabaseFiles().ifPresent(files -> log.warn("getCorruptedDatabaseFiles. files={}", files)); diff --git a/core/src/main/java/bisq/core/app/BisqSetup.java b/core/src/main/java/bisq/core/app/BisqSetup.java index a39d7de09e..67fd39bc29 100644 --- a/core/src/main/java/bisq/core/app/BisqSetup.java +++ b/core/src/main/java/bisq/core/app/BisqSetup.java @@ -80,6 +80,7 @@ import bisq.common.crypto.CryptoException; import bisq.common.crypto.KeyRing; import bisq.common.crypto.SealedAndSigned; import bisq.common.proto.ProtobufferException; +import bisq.common.util.InvalidVersionException; import bisq.common.util.Utilities; import org.bitcoinj.core.Coin; @@ -225,6 +226,9 @@ public class BisqSetup { @Setter @Nullable private Consumer> revolutAccountsUpdateHandler; + @Setter + @Nullable + private Runnable osxKeyLoggerWarningHandler; @Getter final BooleanProperty newVersionAvailableProperty = new SimpleBooleanProperty(false); @@ -347,6 +351,7 @@ public class BisqSetup { readMapsFromResources(this::step3); checkCryptoSetup(); checkForCorrectOSArchitecture(); + checkOSXVersion(); } private void step3() { @@ -655,6 +660,19 @@ public class BisqSetup { } } + private void checkOSXVersion() { + if (Utilities.isOSX() && osxKeyLoggerWarningHandler != null) { + try { + // Seems it was introduced at 10.14: https://github.com/wesnoth/wesnoth/issues/4109 + if (Utilities.getMajorVersion() >= 10 && Utilities.getMinorVersion() >= 14) { + osxKeyLoggerWarningHandler.run(); + } + } catch (InvalidVersionException | NumberFormatException e) { + log.warn(e.getMessage()); + } + } + } + private void initDomainServices() { log.info("initDomainServices"); diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index e784363240..2fbb4683c6 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -2601,6 +2601,12 @@ error.closedTradeWithNoDepositTx=The deposit transaction of the closed trade wit Please restart the application to clean up the closed trades list. popup.warning.walletNotInitialized=The wallet is not initialized yet +popup.warning.osxKeyLoggerWarning=Due to stricter security measures in macOS 10.14 and above, launching a Java application \ + (Bisq uses Java) causes a popup warning in macOS ('Bisq would like to receive keystrokes from any application').\n\n\ + To avoid that issue please open your 'macOS Settings' and go to 'Security & Privacy' -> 'Privacy' -> \ + 'Input Monitoring' and Remove 'Bisq' from the list on the right side.\n\n\ + Bisq will upgrade to a newer Java version to avoid that issue as soon the technical limitations \ + (Java packager for the required Java version is not shipped yet) are resolved. popup.warning.wrongVersion=You probably have the wrong Bisq version for this computer.\n\ Your computer''s architecture is: {0}.\n\ The Bisq binary you installed is: {1}.\n\ diff --git a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java index dce9a56ab6..02f72916e7 100644 --- a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java +++ b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java @@ -382,7 +382,11 @@ public class MainViewModel implements ViewModel, BisqSetup.BisqSetupListener { // We copy the array as we will mutate it later showRevolutAccountUpdateWindow(new ArrayList<>(revolutAccountList)); }); - + bisqSetup.setOsxKeyLoggerWarningHandler(() -> { + new Popup().warning(Res.get("popup.warning.osxKeyLoggerWarning")) + .closeButtonText(Res.get("shared.iUnderstand")) + .show(); + }); corruptedDatabaseFilesHandler.getCorruptedDatabaseFiles().ifPresent(files -> new Popup() .warning(Res.get("popup.warning.incompatibleDB", files.toString(), config.appDataDir))