supporting change password again - now via CryptoFileSystemFactory

This commit is contained in:
Sebastian Stenzel
2016-01-27 18:21:47 +01:00
parent 091a44e65d
commit a972480e72
12 changed files with 238 additions and 192 deletions
@@ -1,17 +1,20 @@
package org.cryptomator.ui.controllers;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.cryptomator.crypto.engine.InvalidPassphraseException;
import org.cryptomator.ui.controls.SecPasswordField;
import org.cryptomator.ui.model.Vault;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
@@ -96,80 +99,38 @@ public class ChangePasswordController extends AbstractFXMLViewController {
@FXML
private void didClickChangePasswordButton(ActionEvent event) {
throw new UnsupportedOperationException("TODO");
/*
* downloadsPageLink.setVisible(false);
* final Path masterKeyPath = vault.getPath().resolve(Vault.VAULT_MASTERKEY_FILE);
* final Path masterKeyBackupPath = vault.getPath().resolve(Vault.VAULT_MASTERKEY_BACKUP_FILE);
*
* // decrypt with old password:
* final CharSequence oldPassword = oldPasswordField.getCharacters();
* try (final InputStream masterKeyInputStream = Files.newInputStream(masterKeyPath, StandardOpenOption.READ)) {
* vault.getCryptor().decryptMasterKey(masterKeyInputStream, oldPassword);
* Files.copy(masterKeyPath, masterKeyBackupPath, StandardCopyOption.REPLACE_EXISTING);
* } catch (IOException ex) {
* messageText.setText(resourceBundle.getString("changePassword.errorMessage.decryptionFailed"));
* LOG.error("Decryption failed for technical reasons.", ex);
* newPasswordField.swipe();
* retypePasswordField.swipe();
* return;
* } catch (WrongPasswordException e) {
* messageText.setText(resourceBundle.getString("changePassword.errorMessage.wrongPassword"));
* newPasswordField.swipe();
* retypePasswordField.swipe();
* Platform.runLater(oldPasswordField::requestFocus);
* return;
* } catch (UnsupportedKeyLengthException ex) {
* messageText.setText(resourceBundle.getString("changePassword.errorMessage.unsupportedKeyLengthInstallJCE"));
* LOG.warn("Unsupported Key-Length. Please install Oracle Java Cryptography Extension (JCE).", ex);
* newPasswordField.swipe();
* retypePasswordField.swipe();
* return;
* } catch (UnsupportedVaultException e) {
* downloadsPageLink.setVisible(true);
* if (e.isVaultOlderThanSoftware()) {
* messageText.setText(resourceBundle.getString("changePassword.errorMessage.unsupportedVersion.vaultOlderThanSoftware") + " ");
* } else if (e.isSoftwareOlderThanVault()) {
* messageText.setText(resourceBundle.getString("changePassword.errorMessage.unsupportedVersion.softwareOlderThanVault") + " ");
* }
* newPasswordField.swipe();
* retypePasswordField.swipe();
* return;
* } finally {
* oldPasswordField.swipe();
* }
*
* // when we reach this line, decryption was successful.
*
* // encrypt with new password:
* final CharSequence newPassword = newPasswordField.getCharacters();
* try (final OutputStream masterKeyOutputStream = Files.newOutputStream(masterKeyPath, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.SYNC)) {
* vault.getCryptor().encryptMasterKey(masterKeyOutputStream, newPassword);
* messageText.setText(resourceBundle.getString("changePassword.infoMessage.success"));
* Platform.runLater(this::didChangePassword);
* // At this point the backup is still using the old password.
* // It will be changed as soon as the user unlocks the vault the next time.
* // This way he can still restore the old password, if he doesn't remember the new one.
* } catch (IOException ex) {
* LOG.error("Re-encryption failed for technical reasons. Restoring Backup.", ex);
* this.restoreBackupQuietly();
* } finally {
* newPasswordField.swipe();
* retypePasswordField.swipe();
* }
*/
}
private void restoreBackupQuietly() {
/*
* final Path masterKeyPath = vault.getPath().resolve(Vault.VAULT_MASTERKEY_FILE);
* final Path masterKeyBackupPath = vault.getPath().resolve(Vault.VAULT_MASTERKEY_BACKUP_FILE);
* try {
* Files.copy(masterKeyBackupPath, masterKeyPath, StandardCopyOption.REPLACE_EXISTING);
* } catch (IOException ex) {
* LOG.error("Restoring Backup failed.", ex);
* }
*/
downloadsPageLink.setVisible(false);
try {
vault.changePassphrase(oldPasswordField.getCharacters(), newPasswordField.getCharacters());
messageText.setText(resourceBundle.getString("changePassword.infoMessage.success"));
Platform.runLater(this::didChangePassword);
} catch (InvalidPassphraseException e) {
messageText.setText(resourceBundle.getString("changePassword.errorMessage.wrongPassword"));
newPasswordField.swipe();
retypePasswordField.swipe();
Platform.runLater(oldPasswordField::requestFocus);
return;
} catch (IOException ex) {
messageText.setText(resourceBundle.getString("changePassword.errorMessage.decryptionFailed"));
LOG.error("Decryption failed for technical reasons.", ex);
newPasswordField.swipe();
retypePasswordField.swipe();
return;
// } catch (UnsupportedVaultException e) {
// downloadsPageLink.setVisible(true);
// if (e.isVaultOlderThanSoftware()) {
// messageText.setText(resourceBundle.getString("changePassword.errorMessage.unsupportedVersion.vaultOlderThanSoftware") + " ");
// } else if (e.isSoftwareOlderThanVault()) {
// messageText.setText(resourceBundle.getString("changePassword.errorMessage.unsupportedVersion.softwareOlderThanVault") + " ");
// }
// newPasswordField.swipe();
// retypePasswordField.swipe();
// return;
} finally {
oldPasswordField.swipe();
newPasswordField.swipe();
retypePasswordField.swipe();
}
}
private void didChangePassword() {
@@ -16,6 +16,7 @@ import java.util.Set;
import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.StringUtils;
import org.cryptomator.common.Optionals;
import org.cryptomator.crypto.engine.InvalidPassphraseException;
import org.cryptomator.filesystem.FileSystem;
import org.cryptomator.filesystem.crypto.CryptoFileSystemDelegate;
import org.cryptomator.filesystem.crypto.CryptoFileSystemFactory;
@@ -90,7 +91,16 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
if (fs.children().count() > 0) {
throw new FileAlreadyExistsException(null, null, "Vault location not empty.");
}
cryptoFileSystemFactory.get(fs, passphrase, this);
cryptoFileSystemFactory.initializeNew(fs, passphrase);
} catch (UncheckedIOException e) {
throw new IOException(e);
}
}
public void changePassphrase(CharSequence oldPassphrase, CharSequence newPassphrase) throws IOException, InvalidPassphraseException {
try {
FileSystem fs = NioFileSystem.rootedAt(path);
cryptoFileSystemFactory.changePassphrase(fs, oldPassphrase, newPassphrase);
} catch (UncheckedIOException e) {
throw new IOException(e);
}
@@ -99,7 +109,7 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
public synchronized void activateFrontend(CharSequence passphrase) throws FrontendCreationFailedException {
try {
FileSystem fs = NioFileSystem.rootedAt(path);
FileSystem cryptoFs = cryptoFileSystemFactory.get(fs, passphrase, this);
FileSystem cryptoFs = cryptoFileSystemFactory.unlockExisting(fs, passphrase, this);
String contextPath = StringUtils.prependIfMissing(mountName, "/");
Frontend frontend = frontendFactory.get().create(cryptoFs, contextPath);
filesystemFrontend = closer.closeLater(frontend);
@@ -165,10 +175,6 @@ public class Vault implements Serializable, CryptoFileSystemDelegate {
return StringUtils.removeEnd(path.getFileName().toString(), VAULT_FILE_EXTENSION);
}
// public Cryptor getCryptor() {
// return cryptor;
// }
public ObjectProperty<Boolean> unlockedProperty() {
return unlocked;
}