From c5c5e297b7321bca8478b69761e1c405832df76f Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 14 Feb 2023 17:39:34 +0100 Subject: [PATCH 01/14] Fix getCiphertextPath for Windows again. --- .../org/cryptomator/common/vaults/Vault.java | 23 ++++++++++++++----- .../VaultDetailUnlockedController.java | 7 +----- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/cryptomator/common/vaults/Vault.java b/src/main/java/org/cryptomator/common/vaults/Vault.java index e4dbd9b2c..de77f17b5 100644 --- a/src/main/java/org/cryptomator/common/vaults/Vault.java +++ b/src/main/java/org/cryptomator/common/vaults/Vault.java @@ -316,18 +316,29 @@ public class Vault { /** * Gets from the cleartext path its ciphertext counterpart. - * The cleartext path has to start from the vault root (by starting with "/"). * * @return Local os path to the ciphertext resource * @throws IOException if an I/O error occurs + * @throws IllegalStateException if the vault is not unlocked */ - public Path getCiphertextPath(String cleartextPath) throws IOException { - if (!cleartextPath.startsWith("/")) { - throw new IllegalArgumentException("Input path must be absolute from vault root by starting with \"/\"."); + public Path getCiphertextPath(Path cleartextPath) throws IOException { + if (!state.getValue().equals(VaultState.Value.UNLOCKED)) { + throw new IllegalStateException("Vault is not unlocked"); } var fs = cryptoFileSystem.get(); - var cryptoPath = fs.getPath(cleartextPath); - return fs.getCiphertextPath(cryptoPath); + var osPathSeparator = cleartextPath.getFileSystem().getSeparator(); + var cryptoFsPathSeparator = fs.getSeparator(); + + if (getMountPoint() instanceof Mountpoint.WithPath mp) { + var absoluteCryptoFsPath = cryptoFsPathSeparator + mp.path().relativize(cleartextPath).toString(); + if (!cryptoFsPathSeparator.equals(osPathSeparator)) { + absoluteCryptoFsPath = absoluteCryptoFsPath.replace(osPathSeparator, cryptoFsPathSeparator); + } + var cryptoPath = fs.getPath(absoluteCryptoFsPath); + return fs.getCiphertextPath(cryptoPath); + } else { + throw new UnsupportedOperationException("URI mount points not supported."); + } } public VaultConfigCache getVaultConfigCache() { diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java index 0e19590a9..12fdfd692 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultDetailUnlockedController.java @@ -166,12 +166,7 @@ public class VaultDetailUnlockedController implements FxController { return Optional.empty(); } try { - var accessPoint = mountPoint.getValue(); - var cleartextPath = path.toString().substring(accessPoint.length()); - if (!cleartextPath.startsWith("/")) { - cleartextPath = "/" + cleartextPath; - } - return Optional.of(vault.get().getCiphertextPath(cleartextPath)); + return Optional.of(vault.get().getCiphertextPath(path)); } catch (IOException e) { LOG.warn("Unable to get ciphertext path from path: {}", path, e); return Optional.empty(); From c5b21b0d8ceb4cfe0da72d60ae7d35d4d30c7629 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 15 Feb 2023 11:44:37 +0100 Subject: [PATCH 02/14] Add warning about error report deletion to the error controller --- .../java/org/cryptomator/ui/common/ErrorController.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/common/ErrorController.java b/src/main/java/org/cryptomator/ui/common/ErrorController.java index 3b5e08ffb..c0213ad1c 100644 --- a/src/main/java/org/cryptomator/ui/common/ErrorController.java +++ b/src/main/java/org/cryptomator/ui/common/ErrorController.java @@ -29,9 +29,11 @@ public class ErrorController implements FxController { OS: %s / %s App: %s / %s - + - + + + """; private final Application application; From 03f6e0a33cb28244dfe914792b389213a525c94c Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 15 Feb 2023 23:44:51 +0100 Subject: [PATCH 03/14] Use Label instead of Text --- src/main/resources/fxml/vault_options_mount.fxml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/resources/fxml/vault_options_mount.fxml b/src/main/resources/fxml/vault_options_mount.fxml index 5275d1612..762d36d27 100644 --- a/src/main/resources/fxml/vault_options_mount.fxml +++ b/src/main/resources/fxml/vault_options_mount.fxml @@ -12,7 +12,6 @@ - - - + From e9ee15dcd5c481804a39d353834fe10b95337043 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Thu, 16 Feb 2023 09:42:28 +0100 Subject: [PATCH 04/14] add info about html comments to error form --- src/main/java/org/cryptomator/ui/common/ErrorController.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/cryptomator/ui/common/ErrorController.java b/src/main/java/org/cryptomator/ui/common/ErrorController.java index c0213ad1c..15d2ee41f 100644 --- a/src/main/java/org/cryptomator/ui/common/ErrorController.java +++ b/src/main/java/org/cryptomator/ui/common/ErrorController.java @@ -31,7 +31,9 @@ public class ErrorController implements FxController { - + + + """; From 8bbdb69cda10a082733f03ba1e17498db01feab3 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Thu, 16 Feb 2023 09:55:42 +0100 Subject: [PATCH 05/14] Update doc links to 1.7 --- .../java/org/cryptomator/ui/mainwindow/WelcomeController.java | 2 +- .../cryptomator/ui/migration/MigrationImpossibleController.java | 2 +- .../cryptomator/ui/wrongfilealert/WrongFileAlertController.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/mainwindow/WelcomeController.java b/src/main/java/org/cryptomator/ui/mainwindow/WelcomeController.java index e483c265b..ccfbd3ad5 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/WelcomeController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/WelcomeController.java @@ -16,7 +16,7 @@ import javafx.fxml.FXML; public class WelcomeController implements FxController { private static final Logger LOG = LoggerFactory.getLogger(WelcomeController.class); - private static final String GETTING_STARTED_URI = "https://docs.cryptomator.org/en/1.6/desktop/getting-started/"; + private static final String GETTING_STARTED_URI = "https://docs.cryptomator.org/en/1.7/desktop/getting-started/"; private final Application application; private final BooleanBinding noVaultPresent; diff --git a/src/main/java/org/cryptomator/ui/migration/MigrationImpossibleController.java b/src/main/java/org/cryptomator/ui/migration/MigrationImpossibleController.java index 2cfe14551..893ef3577 100644 --- a/src/main/java/org/cryptomator/ui/migration/MigrationImpossibleController.java +++ b/src/main/java/org/cryptomator/ui/migration/MigrationImpossibleController.java @@ -10,7 +10,7 @@ import javafx.stage.Stage; public class MigrationImpossibleController implements FxController { - private static final String HELP_URI = "https://docs.cryptomator.org/en/1.6/help/manual-migration/"; + private static final String HELP_URI = "https://docs.cryptomator.org/en/1.7/help/manual-migration/"; private final Application application; private final Stage window; diff --git a/src/main/java/org/cryptomator/ui/wrongfilealert/WrongFileAlertController.java b/src/main/java/org/cryptomator/ui/wrongfilealert/WrongFileAlertController.java index 389449d55..cc91d1afd 100644 --- a/src/main/java/org/cryptomator/ui/wrongfilealert/WrongFileAlertController.java +++ b/src/main/java/org/cryptomator/ui/wrongfilealert/WrongFileAlertController.java @@ -15,7 +15,7 @@ import java.io.UncheckedIOException; @WrongFileAlertScoped public class WrongFileAlertController implements FxController { - private static final String DOCUMENTATION_URI = "https://docs.cryptomator.org/en/1.6/desktop/accessing-vaults/"; + private static final String DOCUMENTATION_URI = "https://docs.cryptomator.org/en/1.7/desktop/accessing-vaults/"; private final Application app; private final Stage window; From 29c73e1bc8d623dbd6005c422ca75499695b27d3 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Thu, 16 Feb 2023 11:51:03 +0100 Subject: [PATCH 06/14] display different messages if recovery key is either not valid or does not belong to the vault --- .../RecoveryKeyRecoverController.java | 89 +++++++++++++++---- .../resources/fxml/recoverykey_recover.fxml | 32 +++++-- src/main/resources/i18n/strings.properties | 4 +- 3 files changed, 101 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyRecoverController.java b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyRecoverController.java index 61cdebcd9..d9fe067d8 100644 --- a/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyRecoverController.java +++ b/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyRecoverController.java @@ -4,6 +4,7 @@ import com.google.common.base.CharMatcher; import com.google.common.base.Strings; import dagger.Lazy; import org.cryptomator.common.Nullable; +import org.cryptomator.common.ObservableUtil; import org.cryptomator.common.vaults.Vault; import org.cryptomator.cryptofs.VaultConfig; import org.cryptomator.cryptofs.VaultConfigLoadException; @@ -15,9 +16,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Inject; -import javafx.beans.binding.Bindings; -import javafx.beans.binding.BooleanBinding; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.StringProperty; +import javafx.beans.value.ObservableValue; import javafx.fxml.FXML; import javafx.scene.Scene; import javafx.scene.control.TextArea; @@ -38,8 +40,12 @@ public class RecoveryKeyRecoverController implements FxController { private final Vault vault; private final VaultConfig.UnverifiedVaultConfig unverifiedVaultConfig; private final StringProperty recoveryKey; + private final ObservableValue recoveryKeyCorrect; + private final ObservableValue recoveryKeyWrong; + private final ObservableValue recoveryKeyInvalid; private final RecoveryKeyFactory recoveryKeyFactory; - private final BooleanBinding validRecoveryKey; + + private final ObjectProperty recoveryKeyState; private final Lazy resetPasswordScene; private final AutoCompleter autoCompleter; @@ -53,14 +59,18 @@ public class RecoveryKeyRecoverController implements FxController { this.unverifiedVaultConfig = unverifiedVaultConfig; this.recoveryKey = recoveryKey; this.recoveryKeyFactory = recoveryKeyFactory; - this.validRecoveryKey = Bindings.createBooleanBinding(this::isValidRecoveryKey, recoveryKey); this.resetPasswordScene = resetPasswordScene; this.autoCompleter = new AutoCompleter(recoveryKeyFactory.getDictionary()); + this.recoveryKeyState = new SimpleObjectProperty<>(); + this.recoveryKeyCorrect = ObservableUtil.mapWithDefault(recoveryKeyState, RecoveryKeyState.CORRECT::equals, false); + this.recoveryKeyWrong = ObservableUtil.mapWithDefault(recoveryKeyState, RecoveryKeyState.WRONG::equals, false); + this.recoveryKeyInvalid = ObservableUtil.mapWithDefault(recoveryKeyState, RecoveryKeyState.INVALID::equals, false); } @FXML public void initialize() { recoveryKey.bind(textarea.textProperty()); + textarea.textProperty().addListener(((observable, oldValue, newValue) -> validateRecoveryKey())); } private TextFormatter.Change filterTextChange(TextFormatter.Change change) { @@ -107,6 +117,14 @@ public class RecoveryKeyRecoverController implements FxController { window.setScene(resetPasswordScene.get()); } + /** + * Checks, if vault config is signed with the given key. + *

+ * If not, but the deriving recovery key is valid, sets the recoveryKeyState to WRONG. + * + * @param key byte array of possible signing key + * @return true, if vault config is signed with this key + */ private boolean checkKeyAgainstVaultConfig(byte[] key) { try { var config = unverifiedVaultConfig.verify(key, unverifiedVaultConfig.allegedVaultVersion()); @@ -114,6 +132,7 @@ public class RecoveryKeyRecoverController implements FxController { return true; } catch (VaultKeyInvalidException e) { LOG.debug("Provided recovery key does not match vault config signature."); + recoveryKeyState.setValue(RecoveryKeyState.WRONG); return false; } catch (VaultConfigLoadException e) { LOG.error("Failed to parse vault config", e); @@ -123,23 +142,61 @@ public class RecoveryKeyRecoverController implements FxController { /* Getter/Setter */ + public void validateRecoveryKey() { + var valid = recoveryKeyFactory.validateRecoveryKey(recoveryKey.get(), unverifiedVaultConfig != null ? this::checkKeyAgainstVaultConfig : null); + if (valid) { + recoveryKeyState.set(RecoveryKeyState.CORRECT); + } else { + if (recoveryKeyState.getValue() != RecoveryKeyState.WRONG) { //set via side effect in checkKeyAgainstVaultConfig + recoveryKeyState.set(RecoveryKeyState.INVALID); + } + } + } + public Vault getVault() { return vault; } - public BooleanBinding validRecoveryKeyProperty() { - return validRecoveryKey; - } - - public boolean isValidRecoveryKey() { - if (unverifiedVaultConfig != null) { - return recoveryKeyFactory.validateRecoveryKey(recoveryKey.get(), this::checkKeyAgainstVaultConfig); - } else { - return recoveryKeyFactory.validateRecoveryKey(recoveryKey.get()); - } - } - public TextFormatter getRecoveryKeyTextFormatter() { return new TextFormatter<>(this::filterTextChange); } + + public ObservableValue recoveryKeyInvalidProperty() { + return recoveryKeyInvalid; + } + + public boolean isRecoveryKeyInvalid() { + return recoveryKeyInvalid.getValue(); + } + + public ObservableValue recoveryKeyCorrectProperty() { + return recoveryKeyCorrect; + } + + public boolean isRecoveryKeyCorrect() { + return recoveryKeyCorrect.getValue(); + } + + public ObservableValue recoveryKeyWrongProperty() { + return recoveryKeyWrong; + } + + public boolean isRecoveryKeyWrong() { + return recoveryKeyWrong.getValue(); + } + + private enum RecoveryKeyState { + /** + * Recovery key is a valid key and belongs to this vault + */ + CORRECT, + /** + * Recovery key is a valid key, but does not belong to this vault + */ + WRONG, + /** + * Recovery key is not a valid key. + */ + INVALID; + } } diff --git a/src/main/resources/fxml/recoverykey_recover.fxml b/src/main/resources/fxml/recoverykey_recover.fxml index 89c54b5a4..b75c485f6 100644 --- a/src/main/resources/fxml/recoverykey_recover.fxml +++ b/src/main/resources/fxml/recoverykey_recover.fxml @@ -9,6 +9,8 @@ + + - - + + + + + + @@ -38,7 +56,7 @@