diff --git a/main/pom.xml b/main/pom.xml
index d1f8131ed..11d1c064d 100644
--- a/main/pom.xml
+++ b/main/pom.xml
@@ -28,7 +28,7 @@
1.1.2
- 1.3.0
+ 1.4.0
0.6.1
1.0.2
1.7.25
diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeStrategies.java b/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeStrategies.java
index e5c020aed..0d569b430 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeStrategies.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeStrategies.java
@@ -19,8 +19,8 @@ public class UpgradeStrategies {
private final Collection strategies;
@Inject
- public UpgradeStrategies(UpgradeVersion3DropBundleExtension upgrader1, UpgradeVersion3to4 upgrader2, UpgradeVersion4to5 upgrader3) {
- strategies = Collections.unmodifiableList(Arrays.asList(upgrader1, upgrader2, upgrader3));
+ public UpgradeStrategies(UpgradeVersion3DropBundleExtension upgrader1, UpgradeVersion3to4 upgrader2, UpgradeVersion4to5 upgrader3, UpgradeVersion5toX upgrader4) {
+ strategies = Collections.unmodifiableList(Arrays.asList(upgrader1, upgrader2, upgrader3, upgrader4));
}
public UpgradeStrategy getUpgradeStrategy(Vault vault) {
diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeStrategy.java b/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeStrategy.java
index dbadd27f3..426a9b200 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeStrategy.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeStrategy.java
@@ -63,18 +63,17 @@ public abstract class UpgradeStrategy {
*/
public void upgrade(Vault vault, CharSequence passphrase) throws UpgradeFailedException {
LOG.info("Upgrading {} from {} to {}.", vault.getPath(), vaultVersionBeforeUpgrade, vaultVersionAfterUpgrade);
- final Path masterkeyFile = vault.getPath().resolve(MASTERKEY_FILENAME);
- try (Cryptor cryptor = cryptorProvider.createFromKeyFile(KeyFile.parse(Files.readAllBytes(masterkeyFile)), passphrase, vaultVersionBeforeUpgrade)) {
+ final Path masterkeyFileBeforeUpgrade = vault.getPath().resolve(MASTERKEY_FILENAME);
+ try (Cryptor cryptor = readMasterkeyFile(masterkeyFileBeforeUpgrade, passphrase)) {
// create backup, as soon as we know the password was correct:
- final Path masterkeyBackupFile = vault.getPath().resolve(MASTERKEY_BACKUP_FILENAME);
- Files.copy(masterkeyFile, masterkeyBackupFile, StandardCopyOption.REPLACE_EXISTING);
+ Path masterkeyBackupFile = vault.getPath().resolve(MASTERKEY_BACKUP_FILENAME);
+ Files.copy(masterkeyFileBeforeUpgrade, masterkeyBackupFile, StandardCopyOption.REPLACE_EXISTING);
LOG.info("Backuped masterkey.");
// do stuff:
upgrade(vault, cryptor);
// write updated masterkey file:
- final byte[] upgradedMasterkeyFileContents = cryptor.writeKeysToMasterkeyFile(passphrase, vaultVersionAfterUpgrade).serialize();
- final Path masterkeyFileAfterUpgrade = vault.getPath().resolve(MASTERKEY_FILENAME); // path may have changed
- Files.write(masterkeyFileAfterUpgrade, upgradedMasterkeyFileContents, StandardOpenOption.TRUNCATE_EXISTING);
+ Path masterkeyFileAfterUpgrade = vault.getPath().resolve(MASTERKEY_FILENAME); // path may have changed
+ writeMasterkeyFile(masterkeyFileAfterUpgrade, cryptor, passphrase);
LOG.info("Updated masterkey.");
} catch (InvalidPassphraseException e) {
throw new UpgradeFailedException(localization.getString("unlock.errorMessage.wrongPassword"));
@@ -92,6 +91,17 @@ public abstract class UpgradeStrategy {
}
}
+ protected Cryptor readMasterkeyFile(Path masterkeyFile, CharSequence passphrase) throws UnsupportedVaultFormatException, InvalidPassphraseException, IOException {
+ byte[] fileContents = Files.readAllBytes(masterkeyFile);
+ KeyFile keyFile = KeyFile.parse(fileContents);
+ return cryptorProvider.createFromKeyFile(keyFile, passphrase, vaultVersionBeforeUpgrade);
+ }
+
+ protected void writeMasterkeyFile(Path masterkeyFile, Cryptor cryptor, CharSequence passphrase) throws IOException {
+ byte[] fileContents = cryptor.writeKeysToMasterkeyFile(passphrase, vaultVersionAfterUpgrade).serialize();
+ Files.write(masterkeyFile, fileContents, StandardOpenOption.TRUNCATE_EXISTING);
+ }
+
protected abstract void upgrade(Vault vault, Cryptor cryptor) throws UpgradeFailedException;
/**
diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion5toX.java b/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion5toX.java
new file mode 100644
index 000000000..a502459b6
--- /dev/null
+++ b/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion5toX.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the accompanying LICENSE file.
+ *******************************************************************************/
+package org.cryptomator.ui.model;
+
+import java.io.IOException;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.cryptomator.cryptofs.migration.Migrators;
+import org.cryptomator.cryptofs.migration.api.NoApplicableMigratorException;
+import org.cryptomator.cryptolib.Cryptors;
+import org.cryptomator.cryptolib.api.Cryptor;
+import org.cryptomator.cryptolib.api.InvalidPassphraseException;
+import org.cryptomator.ui.l10n.Localization;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+class UpgradeVersion5toX extends UpgradeStrategy {
+
+ private static final Logger LOG = LoggerFactory.getLogger(UpgradeVersion5toX.class);
+
+ @Inject
+ public UpgradeVersion5toX(Localization localization) {
+ super(Cryptors.version1(UpgradeStrategy.strongSecureRandom()), localization, 5, Integer.MAX_VALUE);
+ }
+
+ @Override
+ public String getTitle(Vault vault) {
+ return localization.getString("upgrade.version5toX.title");
+ }
+
+ @Override
+ public String getMessage(Vault vault) {
+ return localization.getString("upgrade.version5toX.msg");
+ }
+
+ @Override
+ public void upgrade(Vault vault, CharSequence passphrase) throws UpgradeFailedException {
+ try {
+ Migrators.get().migrate(vault.getPath(), "masterkey.cryptomator", passphrase);
+ } catch (InvalidPassphraseException e) {
+ throw new UpgradeFailedException(localization.getString("unlock.errorMessage.wrongPassword"));
+ } catch (NoApplicableMigratorException | IOException e) {
+ LOG.warn("Upgrade failed.", e);
+ throw new UpgradeFailedException("Upgrade failed. Details in log message.");
+ }
+ }
+
+ @Override
+ protected void upgrade(Vault vault, Cryptor cryptor) throws UpgradeFailedException {
+ // called by #upgrade(Vault, CharSequence), which got overwritten.
+ throw new AssertionError("Method can not be called.");
+ }
+
+ @Override
+ public boolean isApplicable(Vault vault) {
+ try {
+ return Migrators.get().needsMigration(vault.getPath(), "masterkey.cryptomator");
+ } catch (IOException e) {
+ LOG.warn("Could not determine, whether upgrade is applicable.", e);
+ return false;
+ }
+ }
+
+}
diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java b/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java
index bb1c87227..65f4e16e5 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java
@@ -16,7 +16,6 @@ import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.util.EnumSet;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
@@ -32,7 +31,6 @@ import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.cryptofs.CryptoFileSystem;
import org.cryptomator.cryptofs.CryptoFileSystemProperties;
-import org.cryptomator.cryptofs.CryptoFileSystemProperties.FileSystemFlags;
import org.cryptomator.cryptofs.CryptoFileSystemProvider;
import org.cryptomator.cryptolib.api.CryptoException;
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
@@ -86,14 +84,14 @@ public class Vault {
// Commands
// ********************************************************************************/
- private CryptoFileSystem getCryptoFileSystem(CharSequence passphrase) throws IOException, CryptoException {
+ private CryptoFileSystem getCryptoFileSystem(CharSequence passphrase) throws IOException, InvalidPassphraseException, CryptoException {
return LazyInitializer.initializeLazily(cryptoFileSystem, () -> unlockCryptoFileSystem(passphrase), IOException.class);
}
- private CryptoFileSystem unlockCryptoFileSystem(CharSequence passphrase) throws IOException, CryptoException {
+ private CryptoFileSystem unlockCryptoFileSystem(CharSequence passphrase) throws IOException, InvalidPassphraseException, CryptoException {
CryptoFileSystemProperties fsProps = CryptoFileSystemProperties.cryptoFileSystemProperties() //
.withPassphrase(passphrase) //
- .withFlags(EnumSet.noneOf(FileSystemFlags.class)) // TODO: use withFlags() with CryptoFS 1.3.1
+ .withFlags() //
.withMasterkeyFilename(MASTERKEY_FILENAME) //
.build();
return CryptoFileSystemProvider.newFileSystem(getPath(), fsProps);
@@ -118,7 +116,7 @@ public class Vault {
CryptoFileSystemProvider.changePassphrase(getPath(), MASTERKEY_FILENAME, oldPassphrase, newPassphrase);
}
- public synchronized void unlock(CharSequence passphrase) throws ServerLifecycleException {
+ public synchronized void unlock(CharSequence passphrase) throws InvalidPassphraseException, ServerLifecycleException {
try {
FileSystem fs = getCryptoFileSystem(passphrase);
if (!server.isRunning()) {
diff --git a/main/ui/src/main/resources/localization/en.txt b/main/ui/src/main/resources/localization/en.txt
index 3cad2a15d..dfc92f9a4 100644
--- a/main/ui/src/main/resources/localization/en.txt
+++ b/main/ui/src/main/resources/localization/en.txt
@@ -54,6 +54,9 @@ upgrade.version4to5.title=Vault Version 4 to 5 Upgrade
upgrade.version4to5.msg=This vault needs to be migrated to a newer format.\nEncrypted files will be updated.\nPlease make sure synchronization has finished before proceeding.\n\nNote: Modification date of all files will be changed to the current date/time in the process.
upgrade.version4to5.err.io=Migration failed due to an I/O Exception. See log file for details.
+upgrade.version5toX.title=Vault Version Upgrade
+upgrade.version5toX.msg=This vault needs to be migrated to a newer format.\nPlease make sure synchronization has finished before proceeding.
+
# unlock.fxml
unlock.label.password=Password
unlock.label.savePassword=Save Password