Merge branch 'feature/422-save-pw-linux' into develop

fixes #422
This commit is contained in:
Sebastian Stenzel
2019-07-02 16:12:45 +02:00
8 changed files with 149 additions and 7 deletions
@@ -0,0 +1,9 @@
package org.cryptomator.keychain;
public interface GnomeKeyringAccess {
public void storePassword(String key, CharSequence passphrase);
public char[] loadPassword(String key);
public void deletePassword(String key);
}
@@ -0,0 +1,52 @@
package org.cryptomator.keychain;
import org.freedesktop.secret.simple.SimpleCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class GnomeKeyringAccessImpl implements GnomeKeyringAccess {
private static final Logger LOG = LoggerFactory.getLogger(GnomeKeyringAccessImpl.class);
private SimpleCollection keyring;
public GnomeKeyringAccessImpl() {
try {
keyring = new SimpleCollection();
} catch (IOException e) {
LOG.error("D-Bus reports a problem.", e);
}
}
public void storePassword(String key, CharSequence passphrase) {
List<String> list = keyring.getItems(createAttributes(key));
if (list == null) {
keyring.createItem("Cryptomator", passphrase, createAttributes(key));
}
}
public char[] loadPassword(String key) {
List<String> list = keyring.getItems(createAttributes(key));
if (list != null) {
return keyring.getSecret(list.get(0));
} else {
return null;
}
}
public void deletePassword(String key) {
List<String> list = keyring.getItems(createAttributes(key));
if (list != null) {
keyring.deleteItem(list.get(0));
}
}
private Map<String, String> createAttributes(String key) {
Map<String, String> attributes = new HashMap();
attributes.put("Vault", key);
return attributes;
}
}
@@ -31,8 +31,8 @@ public class KeychainModule {
@Provides
@ElementsIntoSet
Set<KeychainAccessStrategy> provideKeychainAccessStrategies(MacSystemKeychainAccess macKeychain, WindowsProtectedKeychainAccess winKeychain) {
return Sets.newHashSet(macKeychain, winKeychain);
Set<KeychainAccessStrategy> provideKeychainAccessStrategies(MacSystemKeychainAccess macKeychain, WindowsProtectedKeychainAccess winKeychain, LinuxSecretServiceAccess linKeychain) {
return Sets.newHashSet(macKeychain, winKeychain, linKeychain);
}
@Provides
@@ -0,0 +1,25 @@
package org.cryptomator.keychain;
import java.util.Optional;
public class LinuxKeychainTester {
public static boolean secretServiceIsAvailable() {
try {
Class.forName("org.freedesktop.secret.simple.SimpleCollection");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
public static Optional<GnomeKeyringAccess> getSecretService() {
if (!secretServiceIsAvailable()) return Optional.empty();
try {
Class clazz = Class.forName("org.cryptomator.keychain.GnomeKeyringAccessImpl");
GnomeKeyringAccess keyring = (GnomeKeyringAccess) clazz.getDeclaredConstructor().newInstance();
return Optional.of(keyring);
} catch (Exception e) {
return Optional.empty();
}
}
}
@@ -0,0 +1,39 @@
package org.cryptomator.keychain;
import com.google.common.base.Preconditions;
import org.apache.commons.lang3.SystemUtils;
import javax.inject.Inject;
import java.util.Optional;
public class LinuxSecretServiceAccess implements KeychainAccessStrategy {
private final Optional<GnomeKeyringAccess> gnomeLoginKeyring;
@Inject
public LinuxSecretServiceAccess() {
gnomeLoginKeyring = LinuxKeychainTester.getSecretService();
}
@Override
public boolean isSupported() {
return SystemUtils.IS_OS_LINUX && LinuxKeychainTester.getSecretService().isPresent();
}
@Override
public void storePassphrase(String key, CharSequence passphrase) {
Preconditions.checkState(gnomeLoginKeyring.isPresent());
gnomeLoginKeyring.get().storePassword(key, passphrase);
}
@Override
public char[] loadPassphrase(String key) {
Preconditions.checkState(gnomeLoginKeyring.isPresent());
return gnomeLoginKeyring.get().loadPassword(key);
}
@Override
public void deletePassphrase(String key) {
Preconditions.checkState(gnomeLoginKeyring.isPresent());
gnomeLoginKeyring.get().deletePassword(key);
}
}
@@ -7,13 +7,11 @@ package org.cryptomator.keychain;
import java.util.Set;
import com.google.common.collect.Sets;
public class TestKeychainModule extends KeychainModule {
@Override
Set<KeychainAccessStrategy> provideKeychainAccessStrategies(MacSystemKeychainAccess macKeychain, WindowsProtectedKeychainAccess winKeychain) {
return Sets.newHashSet(new MapKeychainAccess());
Set<KeychainAccessStrategy> provideKeychainAccessStrategies(MacSystemKeychainAccess macKeychain, WindowsProtectedKeychainAccess winKeychain, LinuxSecretServiceAccess linKeychain) {
return Set.of(new MapKeychainAccess());
}
}