From 188a13b2024f285ca3b9a90bf6e48621d113c820 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Sat, 14 Mar 2015 19:11:24 +0100 Subject: [PATCH] - better handling of MAC auth fails, providing link to help page - use random data as file size obfuscation padding - fixed osx unmount error - new attempt to close #41 --- .../crypto/aes256/Aes256Cryptor.java | 2 +- .../ui/controllers/MacWarningsController.java | 27 +++++++++++++++++- .../ui/controllers/MainController.java | 2 ++ .../ui/controllers/UnlockController.java | 15 ++++++---- .../ui/controllers/WelcomeController.java | 2 ++ .../ui/util/mount/MacOsXWebDavMounter.java | 2 +- .../ui/util/mount/WindowsWebDavMounter.java | 28 +++++++++++++++---- .../src/main/resources/fxml/mac_warnings.fxml | 10 +++++-- .../main/resources/localization.properties | 5 ++-- 9 files changed, 75 insertions(+), 18 deletions(-) diff --git a/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/Aes256Cryptor.java b/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/Aes256Cryptor.java index df3797876..1ac7f3f65 100644 --- a/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/Aes256Cryptor.java +++ b/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/Aes256Cryptor.java @@ -559,7 +559,7 @@ public class Aes256Cryptor extends AbstractCryptor implements AesCryptographicCo // append a few blocks of fake data: final int numberOfPlaintextBlocks = (int) Math.ceil(plaintextSize / AES_BLOCK_LENGTH); final int upToTenPercentFakeBlocks = (int) Math.ceil(Math.random() * 0.1 * numberOfPlaintextBlocks); - final byte[] emptyBytes = new byte[AES_BLOCK_LENGTH]; + final byte[] emptyBytes = this.randomData(AES_BLOCK_LENGTH); for (int i = 0; i < upToTenPercentFakeBlocks; i += AES_BLOCK_LENGTH) { blockSizeBufferedOut.write(emptyBytes); } diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/MacWarningsController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/MacWarningsController.java index 77c409409..ed15698ea 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/controllers/MacWarningsController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/MacWarningsController.java @@ -1,11 +1,16 @@ package org.cryptomator.ui.controllers; +import javafx.application.Application; +import javafx.collections.ListChangeListener.Change; import javafx.collections.ObservableList; +import javafx.collections.WeakListChangeListener; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.ListView; import javafx.stage.Stage; +import javax.inject.Inject; + public class MacWarningsController { @FXML @@ -13,13 +18,33 @@ public class MacWarningsController { private Stage stage; + private final Application application; + + @Inject + public MacWarningsController(Application application) { + this.application = application; + } + @FXML - private void hideWindow(ActionEvent event) { + private void didClickDismissButton(ActionEvent event) { stage.hide(); } + @FXML + private void didClickMoreInformationButton(ActionEvent event) { + application.getHostServices().showDocument("https://cryptomator.org/help.html#macWarning"); + } + public void setMacWarnings(ObservableList macWarnings) { this.warningsList.setItems(macWarnings); + this.warningsList.getItems().addListener(new WeakListChangeListener(this::warningsDidChange)); + } + + // closes this window automatically, if all warnings disappeared (e.g. due to an unmount event) + private void warningsDidChange(Change change) { + if (change.getList().isEmpty()) { + stage.hide(); + } } public Stage getStage() { diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/MainController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/MainController.java index 0cf8e40b9..803aeb795 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/controllers/MainController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/MainController.java @@ -51,6 +51,7 @@ import org.cryptomator.ui.controls.DirectoryListCell; import org.cryptomator.ui.model.Vault; import org.cryptomator.ui.model.VaultFactory; import org.cryptomator.ui.settings.Settings; +import org.cryptomator.ui.util.ActiveWindowStyleSupport; import org.cryptomator.ui.util.ObservableSetAggregator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -336,6 +337,7 @@ public class MainController implements Initializable, InitializationListener, Un stage.sizeToScene(); stage.setResizable(false); stage.setOnHidden(this::onHideMacWarningsWindow); + ActiveWindowStyleSupport.startObservingFocus(stage); final MacWarningsController ctrl = loader.getController(); ctrl.setMacWarnings(this.aggregatedMacWarnings); diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java index aa01dc00c..05057d0ea 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java @@ -113,10 +113,7 @@ public class UnlockController implements Initializable { Files.copy(masterKeyPath, masterKeyBackupPath, StandardCopyOption.REPLACE_EXISTING); vault.setUnlocked(true); final Future futureMount = exec.submit(() -> vault.mount()); - FXThreads.runOnMainThreadWhenFinished(exec, futureMount, this::didUnlockAndMount); - FXThreads.runOnMainThreadWhenFinished(exec, futureMount, (result) -> { - setControlsDisabled(false); - }); + FXThreads.runOnMainThreadWhenFinished(exec, futureMount, this::unlockAndMountFinished); } catch (DecryptFailedException | IOException ex) { setControlsDisabled(false); progressIndicator.setVisible(false); @@ -143,9 +140,15 @@ public class UnlockController implements Initializable { unlockButton.setDisable(disable); } - private void didUnlockAndMount(boolean mountSuccess) { + private void unlockAndMountFinished(boolean mountSuccess) { progressIndicator.setVisible(false); - if (listener != null) { + setControlsDisabled(false); + if (vault.isUnlocked() && !mountSuccess) { + vault.getCryptor().swipeSensitiveData(); + vault.stopServer(); + vault.setUnlocked(false); + } + if (mountSuccess && listener != null) { listener.didUnlock(this); } } diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/WelcomeController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/WelcomeController.java index 88128d67b..f07363605 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/controllers/WelcomeController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/WelcomeController.java @@ -31,6 +31,7 @@ import javax.inject.Named; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.cookie.CookiePolicy; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.lang3.SystemUtils; @@ -67,6 +68,7 @@ public class WelcomeController implements Initializable { private void checkForUpdates() { final HttpClient client = new HttpClient(); final HttpMethod method = new GetMethod("https://cryptomator.org/downloads/latestVersion.json"); + client.getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES); client.getParams().setConnectionManagerTimeout(5000); try { client.executeMethod(method); diff --git a/main/ui/src/main/java/org/cryptomator/ui/util/mount/MacOsXWebDavMounter.java b/main/ui/src/main/java/org/cryptomator/ui/util/mount/MacOsXWebDavMounter.java index a9bf24b23..1dd66d403 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/util/mount/MacOsXWebDavMounter.java +++ b/main/ui/src/main/java/org/cryptomator/ui/util/mount/MacOsXWebDavMounter.java @@ -38,7 +38,7 @@ final class MacOsXWebDavMounter implements WebDavMounterStrategy { .addEnv("MOUNT_PATH", path) .addEnv("MOUNT_NAME", name); final Script unmountScript = Script.fromLines( - "umount $MOUNT_PATH") + "diskutil umount $MOUNT_PATH") .addEnv("MOUNT_PATH", path); mountScript.execute(); return new AbstractWebDavMount() { diff --git a/main/ui/src/main/java/org/cryptomator/ui/util/mount/WindowsWebDavMounter.java b/main/ui/src/main/java/org/cryptomator/ui/util/mount/WindowsWebDavMounter.java index 0057046d1..f983c784a 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/util/mount/WindowsWebDavMounter.java +++ b/main/ui/src/main/java/org/cryptomator/ui/util/mount/WindowsWebDavMounter.java @@ -30,6 +30,7 @@ import org.cryptomator.ui.util.command.Script; final class WindowsWebDavMounter implements WebDavMounterStrategy { private static final Pattern WIN_MOUNT_DRIVELETTER_PATTERN = Pattern.compile("\\s*([A-Z]:)\\s*"); + private static final int MAX_MOUNT_ATTEMPTS = 10; @Override public boolean shouldWork() { @@ -50,11 +51,28 @@ final class WindowsWebDavMounter implements WebDavMounterStrategy { @Override public WebDavMount mount(URI uri, String name) throws CommandFailedException { - final Script mountScript = fromLines("net use * http://0--1.ipv6-literal.net:%PORT%%DAV_PATH% /persistent:no") - .addEnv("PORT", String.valueOf(uri.getPort())) - .addEnv("DAV_PATH", uri.getRawPath()); - final CommandResult mountResult = mountScript.execute(30, TimeUnit.SECONDS); - final String driveLetter = getDriveLetter(mountResult.getStdOut()); + final Script mountScript = fromLines("net use * http://0--1.ipv6-literal.net:%PORT%%DAV_PATH% /persistent:no"); + mountScript.addEnv("PORT", String.valueOf(uri.getPort())).addEnv("DAV_PATH", uri.getRawPath()); + String driveLetter = null; + // The ugliness of the following 20 lines is solely windows' fault. Deal with it. + for (int i = 0; i < MAX_MOUNT_ATTEMPTS; i++) { + try { + final CommandResult mountResult = mountScript.execute(10, TimeUnit.SECONDS); + driveLetter = getDriveLetter(mountResult.getStdOut()); + break; + } catch (CommandFailedException ex) { + if (i == MAX_MOUNT_ATTEMPTS - 1) { + throw ex; + } else { + try { + // retry after 500ms + Thread.sleep(500); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + } + } final Script openExplorerScript = fromLines("start explorer.exe " + driveLetter); openExplorerScript.execute(); final Script unmountScript = fromLines("net use " + driveLetter + " /delete").addEnv("DRIVE_LETTER", driveLetter); diff --git a/main/ui/src/main/resources/fxml/mac_warnings.fxml b/main/ui/src/main/resources/fxml/mac_warnings.fxml index 8bff86f1a..0c53d4176 100644 --- a/main/ui/src/main/resources/fxml/mac_warnings.fxml +++ b/main/ui/src/main/resources/fxml/mac_warnings.fxml @@ -13,15 +13,21 @@ + - +