diff --git a/main/keychain/pom.xml b/main/keychain/pom.xml index 29471ed1d..01e276cc9 100644 --- a/main/keychain/pom.xml +++ b/main/keychain/pom.xml @@ -39,7 +39,14 @@ com.google.dagger dagger - + + + + de.swiesend + secret-service + 1.0.0-RC.3 + + org.slf4j diff --git a/main/keychain/src/main/java/org/cryptomator/keychain/KeychainModule.java b/main/keychain/src/main/java/org/cryptomator/keychain/KeychainModule.java index 5db7bc372..f05a90f1f 100644 --- a/main/keychain/src/main/java/org/cryptomator/keychain/KeychainModule.java +++ b/main/keychain/src/main/java/org/cryptomator/keychain/KeychainModule.java @@ -31,8 +31,8 @@ public class KeychainModule { @Provides @ElementsIntoSet - Set provideKeychainAccessStrategies(MacSystemKeychainAccess macKeychain, WindowsProtectedKeychainAccess winKeychain) { - return Sets.newHashSet(macKeychain, winKeychain); + Set provideKeychainAccessStrategies(MacSystemKeychainAccess macKeychain, WindowsProtectedKeychainAccess winKeychain, LinuxSecretServiceAccess linKeychain) { + return Sets.newHashSet(macKeychain, winKeychain, linKeychain); } @Provides diff --git a/main/keychain/src/main/java/org/cryptomator/keychain/LinuxSecretServiceAccess.java b/main/keychain/src/main/java/org/cryptomator/keychain/LinuxSecretServiceAccess.java new file mode 100644 index 000000000..70781fd39 --- /dev/null +++ b/main/keychain/src/main/java/org/cryptomator/keychain/LinuxSecretServiceAccess.java @@ -0,0 +1,67 @@ +package org.cryptomator.keychain; + +import com.google.common.base.Preconditions; +import org.apache.commons.lang3.SystemUtils; +import org.freedesktop.secret.simple.SimpleCollection; + +import javax.inject.Inject; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +public class LinuxSecretServiceAccess implements KeychainAccessStrategy { + private final Optional gnomeLoginKeyring; + + @Inject + public LinuxSecretServiceAccess() { + SimpleCollection keyring = null; + try { + keyring = new SimpleCollection(); + } catch (Exception e) { + // Accessing secret-service DBus API failed + } finally { + gnomeLoginKeyring = Optional.ofNullable(keyring); + } + } + + @Override + public boolean isSupported() { + return SystemUtils.IS_OS_LINUX && gnomeLoginKeyring.isPresent(); + } + + @Override + public void storePassphrase(String key, CharSequence passphrase) { + Preconditions.checkState(gnomeLoginKeyring.isPresent()); + List list = gnomeLoginKeyring.get().getItems(createAttributes(key)); + if (list == null) { + gnomeLoginKeyring.get().createItem("Cryptomator", passphrase, createAttributes(key)); + } + } + + @Override + public char[] loadPassphrase(String key) { + Preconditions.checkState(gnomeLoginKeyring.isPresent()); + List list = gnomeLoginKeyring.get().getItems(createAttributes(key)); + if (list != null) { + return gnomeLoginKeyring.get().getSecret(list.get(0)); + } else { + return null; + } + } + + @Override + public void deletePassphrase(String key) { + Preconditions.checkState(gnomeLoginKeyring.isPresent()); + List list = gnomeLoginKeyring.get().getItems(createAttributes(key)); + if (list != null) { + gnomeLoginKeyring.get().deleteItem(list.get(0)); + } + } + + private Map createAttributes(String key) { + Map attributes = new HashMap(); + attributes.put("Vault", key); + return attributes; + } +} diff --git a/main/keychain/src/test/java/org/cryptomator/keychain/TestKeychainModule.java b/main/keychain/src/test/java/org/cryptomator/keychain/TestKeychainModule.java index 66addc62a..bafc81a97 100644 --- a/main/keychain/src/test/java/org/cryptomator/keychain/TestKeychainModule.java +++ b/main/keychain/src/test/java/org/cryptomator/keychain/TestKeychainModule.java @@ -12,7 +12,7 @@ import com.google.common.collect.Sets; public class TestKeychainModule extends KeychainModule { @Override - Set provideKeychainAccessStrategies(MacSystemKeychainAccess macKeychain, WindowsProtectedKeychainAccess winKeychain) { + Set provideKeychainAccessStrategies(MacSystemKeychainAccess macKeychain, WindowsProtectedKeychainAccess winKeychain, LinuxSecretServiceAccess linKeychain) { return Sets.newHashSet(new MapKeychainAccess()); }