浏览代码

Merge pull request #905 from purejava/secret-service-simple

Fixes #422
Sebastian Stenzel 5 年之前
父节点
当前提交
c66519a2d0

+ 7 - 0
main/buildkit/assembly-linux.xml

@@ -28,5 +28,12 @@
 			</includes>
 			<outputDirectory>libs</outputDirectory>
 		</fileSet>
+		<fileSet>
+			<directory>target/linux-secret-service</directory>
+			<includes>
+				<include>*.jar</include>
+			</includes>
+			<outputDirectory>libs</outputDirectory>
+		</fileSet>
 	</fileSets>
 </assembly>

+ 12 - 0
main/buildkit/pom.xml

@@ -62,6 +62,7 @@
 						<configuration>
 							<outputDirectory>${project.build.directory}/libs</outputDirectory>
 							<excludeClassifiers>linux,mac,win</excludeClassifiers>
+							<excludeArtifactIds>dbus-java,secret-service,hkdf,java-utils</excludeArtifactIds>
 						</configuration>
 					</execution>
 					<execution>
@@ -76,6 +77,17 @@
 							<classifier>linux</classifier>
 						</configuration>
 					</execution>
+					<execution>
+						<id>copy-linux-secret-service</id>
+						<phase>prepare-package</phase>
+						<goals>
+							<goal>copy-dependencies</goal>
+						</goals>
+						<configuration>
+							<outputDirectory>${project.build.directory}/linux-secret-service</outputDirectory>
+							<includeArtifactIds>dbus-java,secret-service,hkdf,java-utils</includeArtifactIds>
+						</configuration>
+					</execution>
 					<execution>
 						<id>copy-mac-libs</id>
 						<phase>prepare-package</phase>

+ 8 - 1
main/keychain/pom.xml

@@ -39,7 +39,14 @@
 			<groupId>com.google.dagger</groupId>
 			<artifactId>dagger</artifactId>
 		</dependency>
-		
+
+		<!-- secret-service lib -->
+		<dependency>
+			<groupId>de.swiesend</groupId>
+			<artifactId>secret-service</artifactId>
+			<version>1.0.0-RC.3</version>
+		</dependency>
+
 		<!-- Logging -->
 		<dependency>
 			<groupId>org.slf4j</groupId>

+ 9 - 0
main/keychain/src/main/java/org/cryptomator/keychain/GnomeKeyringAccess.java

@@ -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);
+}

+ 52 - 0
main/keychain/src/main/java/org/cryptomator/keychain/GnomeKeyringAccessImpl.java

@@ -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;
+	}
+}

+ 2 - 2
main/keychain/src/main/java/org/cryptomator/keychain/KeychainModule.java

@@ -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

+ 25 - 0
main/keychain/src/main/java/org/cryptomator/keychain/LinuxKeychainTester.java

@@ -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();
+		}
+	}
+}

+ 39 - 0
main/keychain/src/main/java/org/cryptomator/keychain/LinuxSecretServiceAccess.java

@@ -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);
+	}
+}

+ 1 - 1
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<KeychainAccessStrategy> provideKeychainAccessStrategies(MacSystemKeychainAccess macKeychain, WindowsProtectedKeychainAccess winKeychain) {
+	Set<KeychainAccessStrategy> provideKeychainAccessStrategies(MacSystemKeychainAccess macKeychain, WindowsProtectedKeychainAccess winKeychain, LinuxSecretServiceAccess linKeychain) {
 		return Sets.newHashSet(new MapKeychainAccess());
 	}