summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/src/main/java/app/passwordstore/ui/settings/RepositorySettings.kt8
-rw-r--r--app/src/main/java/app/passwordstore/ui/settings/SettingsActivity.kt6
-rw-r--r--app/src/main/java/app/passwordstore/ui/sshkeygen/ShowSshKeyFragment.kt6
-rw-r--r--app/src/main/java/app/passwordstore/ui/sshkeygen/SshKeyGenActivity.kt8
-rw-r--r--app/src/main/java/app/passwordstore/ui/sshkeygen/SshKeyImportActivity.kt8
-rw-r--r--app/src/main/java/app/passwordstore/util/features/Feature.kt3
-rw-r--r--app/src/main/java/app/passwordstore/util/git/operation/GitOperation.kt13
-rw-r--r--app/src/main/java/app/passwordstore/util/git/sshj/SshjSessionFactory.kt21
-rw-r--r--app/src/main/java/app/passwordstore/util/ssh/SSHFacade.kt86
9 files changed, 32 insertions, 127 deletions
diff --git a/app/src/main/java/app/passwordstore/ui/settings/RepositorySettings.kt b/app/src/main/java/app/passwordstore/ui/settings/RepositorySettings.kt
index d61a6b93..462924ac 100644
--- a/app/src/main/java/app/passwordstore/ui/settings/RepositorySettings.kt
+++ b/app/src/main/java/app/passwordstore/ui/settings/RepositorySettings.kt
@@ -15,6 +15,7 @@ import androidx.fragment.app.FragmentActivity
import app.passwordstore.R
import app.passwordstore.data.repo.PasswordRepository
import app.passwordstore.injection.prefs.GitPreferences
+import app.passwordstore.ssh.SSHKeyManager
import app.passwordstore.ui.git.config.GitConfigActivity
import app.passwordstore.ui.git.config.GitServerConfigActivity
import app.passwordstore.ui.proxy.ProxySelectorActivity
@@ -28,7 +29,6 @@ import app.passwordstore.util.extensions.snackbar
import app.passwordstore.util.extensions.unsafeLazy
import app.passwordstore.util.settings.GitSettings
import app.passwordstore.util.settings.PreferenceKeys
-import app.passwordstore.util.ssh.SSHFacade
import com.github.michaelbull.result.onFailure
import com.github.michaelbull.result.runCatching
import com.google.android.material.dialog.MaterialAlertDialogBuilder
@@ -44,11 +44,11 @@ import de.Maxr1998.modernpreferences.helpers.switch
class RepositorySettings(
private val activity: FragmentActivity,
- private val sshFacade: SSHFacade,
+ private val sshKeyManager: SSHKeyManager,
) : SettingsProvider {
private val generateSshKey =
activity.registerForActivityResult(StartActivityForResult()) {
- showSshKeyPref?.visible = sshFacade.canShowPublicKey()
+ showSshKeyPref?.visible = sshKeyManager.canShowPublicKey()
}
private val hiltEntryPoint by unsafeLazy {
@@ -113,7 +113,7 @@ class RepositorySettings(
showSshKeyPref =
pref(PreferenceKeys.SSH_SEE_KEY) {
titleRes = R.string.pref_ssh_see_key_title
- visible = PasswordRepository.isGitRepo() && sshFacade.canShowPublicKey()
+ visible = PasswordRepository.isGitRepo() && sshKeyManager.canShowPublicKey()
onClick {
ShowSshKeyFragment().show(activity.supportFragmentManager, "public_key")
true
diff --git a/app/src/main/java/app/passwordstore/ui/settings/SettingsActivity.kt b/app/src/main/java/app/passwordstore/ui/settings/SettingsActivity.kt
index a78e6b4b..697d0156 100644
--- a/app/src/main/java/app/passwordstore/ui/settings/SettingsActivity.kt
+++ b/app/src/main/java/app/passwordstore/ui/settings/SettingsActivity.kt
@@ -11,8 +11,8 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.os.BundleCompat
import app.passwordstore.R
import app.passwordstore.databinding.ActivityPreferenceRecyclerviewBinding
+import app.passwordstore.ssh.SSHKeyManager
import app.passwordstore.util.extensions.viewBinding
-import app.passwordstore.util.ssh.SSHFacade
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import de.Maxr1998.modernpreferences.Preference
@@ -24,7 +24,7 @@ import javax.inject.Inject
@AndroidEntryPoint
class SettingsActivity : AppCompatActivity() {
- @Inject lateinit var sshFacade: SSHFacade
+ @Inject lateinit var sshKeyManager: SSHKeyManager
private lateinit var repositorySettings: RepositorySettings
private val miscSettings = MiscSettings(this)
private val autofillSettings = AutofillSettings(this)
@@ -40,7 +40,7 @@ class SettingsActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContentView(binding.root)
Preference.Config.dialogBuilderFactory = { context -> MaterialAlertDialogBuilder(context) }
- repositorySettings = RepositorySettings(this, sshFacade)
+ repositorySettings = RepositorySettings(this, sshKeyManager)
val screen =
screen(this) {
subScreen {
diff --git a/app/src/main/java/app/passwordstore/ui/sshkeygen/ShowSshKeyFragment.kt b/app/src/main/java/app/passwordstore/ui/sshkeygen/ShowSshKeyFragment.kt
index b96342e5..4f52b540 100644
--- a/app/src/main/java/app/passwordstore/ui/sshkeygen/ShowSshKeyFragment.kt
+++ b/app/src/main/java/app/passwordstore/ui/sshkeygen/ShowSshKeyFragment.kt
@@ -9,7 +9,7 @@ import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.DialogFragment
import app.passwordstore.R
-import app.passwordstore.util.ssh.SSHFacade
+import app.passwordstore.ssh.SSHKeyManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@@ -17,11 +17,11 @@ import javax.inject.Inject
@AndroidEntryPoint
class ShowSshKeyFragment : DialogFragment() {
- @Inject lateinit var sshFacade: SSHFacade
+ @Inject lateinit var sshKeyManager: SSHKeyManager
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val activity = requireActivity()
- val publicKey = sshFacade.publicKey()
+ val publicKey = sshKeyManager.publicKey()
return MaterialAlertDialogBuilder(requireActivity()).run {
setMessage(getString(R.string.ssh_keygen_message, publicKey))
setTitle(R.string.your_public_key)
diff --git a/app/src/main/java/app/passwordstore/ui/sshkeygen/SshKeyGenActivity.kt b/app/src/main/java/app/passwordstore/ui/sshkeygen/SshKeyGenActivity.kt
index 790751f9..34749e4c 100644
--- a/app/src/main/java/app/passwordstore/ui/sshkeygen/SshKeyGenActivity.kt
+++ b/app/src/main/java/app/passwordstore/ui/sshkeygen/SshKeyGenActivity.kt
@@ -18,12 +18,12 @@ import app.passwordstore.R
import app.passwordstore.databinding.ActivitySshKeygenBinding
import app.passwordstore.injection.prefs.GitPreferences
import app.passwordstore.ssh.SSHKeyAlgorithm
+import app.passwordstore.ssh.SSHKeyManager
import app.passwordstore.util.auth.BiometricAuthenticator
import app.passwordstore.util.auth.BiometricAuthenticator.Result
import app.passwordstore.util.coroutines.DispatcherProvider
import app.passwordstore.util.extensions.keyguardManager
import app.passwordstore.util.extensions.viewBinding
-import app.passwordstore.util.ssh.SSHFacade
import com.github.michaelbull.result.fold
import com.github.michaelbull.result.runCatching
import com.google.android.material.dialog.MaterialAlertDialogBuilder
@@ -40,7 +40,7 @@ class SshKeyGenActivity : AppCompatActivity() {
private var sshKeyAlgorithm = SSHKeyAlgorithm.ECDSA
private val binding by viewBinding(ActivitySshKeygenBinding::inflate)
@GitPreferences @Inject lateinit var gitPrefs: SharedPreferences
- @Inject lateinit var sshFacade: SSHFacade
+ @Inject lateinit var sshKeyManager: SSHKeyManager
@Inject lateinit var dispatcherProvider: DispatcherProvider
override fun onCreate(savedInstanceState: Bundle?) {
@@ -49,7 +49,7 @@ class SshKeyGenActivity : AppCompatActivity() {
supportActionBar?.setDisplayHomeAsUpEnabled(true)
with(binding) {
generate.setOnClickListener {
- if (sshFacade.keyExists()) {
+ if (sshKeyManager.keyExists()) {
MaterialAlertDialogBuilder(this@SshKeyGenActivity).run {
setTitle(R.string.ssh_keygen_existing_title)
setMessage(R.string.ssh_keygen_existing_message)
@@ -127,7 +127,7 @@ class SshKeyGenActivity : AppCompatActivity() {
if (result !is Result.Success)
throw UserNotAuthenticatedException(getString(R.string.biometric_auth_generic_failure))
}
- sshFacade.generateKey(sshKeyAlgorithm, requireAuthentication)
+ sshKeyManager.generateKey(sshKeyAlgorithm, requireAuthentication)
}
}
// Check if we still need this
diff --git a/app/src/main/java/app/passwordstore/ui/sshkeygen/SshKeyImportActivity.kt b/app/src/main/java/app/passwordstore/ui/sshkeygen/SshKeyImportActivity.kt
index 0d8ec7bf..a5d276ae 100644
--- a/app/src/main/java/app/passwordstore/ui/sshkeygen/SshKeyImportActivity.kt
+++ b/app/src/main/java/app/passwordstore/ui/sshkeygen/SshKeyImportActivity.kt
@@ -12,7 +12,7 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import app.passwordstore.R
-import app.passwordstore.util.ssh.SSHFacade
+import app.passwordstore.ssh.SSHKeyManager
import com.github.michaelbull.result.onFailure
import com.github.michaelbull.result.runCatching
import com.google.android.material.dialog.MaterialAlertDialogBuilder
@@ -23,7 +23,7 @@ import kotlinx.coroutines.launch
@AndroidEntryPoint
class SshKeyImportActivity : AppCompatActivity() {
- @Inject lateinit var sshFacade: SSHFacade
+ @Inject lateinit var sshKeyManager: SSHKeyManager
private val sshKeyImportAction =
registerForActivityResult(ActivityResultContracts.OpenDocument()) { uri: Uri? ->
@@ -33,7 +33,7 @@ class SshKeyImportActivity : AppCompatActivity() {
}
runCatching {
lifecycleScope.launch {
- sshFacade.importKey(uri)
+ sshKeyManager.importKey(uri)
Toast.makeText(
this@SshKeyImportActivity,
resources.getString(R.string.ssh_key_success_dialog_title),
@@ -55,7 +55,7 @@ class SshKeyImportActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- if (sshFacade.keyExists()) {
+ if (sshKeyManager.keyExists()) {
MaterialAlertDialogBuilder(this@SshKeyImportActivity).run {
setTitle(R.string.ssh_keygen_existing_title)
setMessage(R.string.ssh_keygen_existing_message)
diff --git a/app/src/main/java/app/passwordstore/util/features/Feature.kt b/app/src/main/java/app/passwordstore/util/features/Feature.kt
index f046dbd7..6cea1031 100644
--- a/app/src/main/java/app/passwordstore/util/features/Feature.kt
+++ b/app/src/main/java/app/passwordstore/util/features/Feature.kt
@@ -13,9 +13,6 @@ enum class Feature(
val configKey: String,
) {
- /** Opt into the new SSH layer implemented as a freestanding module. */
- EnableNewSSHLayer(false, "enable_new_ssh"),
-
/** Opt into a cache layer for PGP passphrases. */
EnablePGPPassphraseCache(false, "enable_gpg_passphrase_cache"),
}
diff --git a/app/src/main/java/app/passwordstore/util/git/operation/GitOperation.kt b/app/src/main/java/app/passwordstore/util/git/operation/GitOperation.kt
index d4ccfaab..199fde94 100644
--- a/app/src/main/java/app/passwordstore/util/git/operation/GitOperation.kt
+++ b/app/src/main/java/app/passwordstore/util/git/operation/GitOperation.kt
@@ -9,6 +9,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentActivity
import app.passwordstore.R
import app.passwordstore.data.repo.PasswordRepository
+import app.passwordstore.ssh.SSHKeyManager
import app.passwordstore.ui.sshkeygen.SshKeyGenActivity
import app.passwordstore.ui.sshkeygen.SshKeyImportActivity
import app.passwordstore.util.auth.BiometricAuthenticator
@@ -22,7 +23,6 @@ import app.passwordstore.util.git.GitCommandExecutor
import app.passwordstore.util.git.sshj.SshAuthMethod
import app.passwordstore.util.git.sshj.SshjSessionFactory
import app.passwordstore.util.settings.AuthMode
-import app.passwordstore.util.ssh.SSHFacade
import com.github.michaelbull.result.Err
import com.github.michaelbull.result.Ok
import com.github.michaelbull.result.Result
@@ -71,7 +71,7 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
callingActivity.applicationContext,
GitOperationEntryPoint::class.java
)
- private val sshFacade = hiltEntryPoint.sshFacade()
+ private val sshKeyManager = hiltEntryPoint.sshKeyManager()
protected val repository = PasswordRepository.repository!!
protected val git = Git(repository)
private val authActivity
@@ -121,8 +121,7 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
authMethod: SshAuthMethod,
credentialsProvider: CredentialsProvider? = null
) {
- sshSessionFactory =
- SshjSessionFactory(authMethod, hostKeyFile, sshFacade, hiltEntryPoint.dispatcherProvider())
+ sshSessionFactory = SshjSessionFactory(authMethod, hostKeyFile, sshKeyManager, hiltEntryPoint.dispatcherProvider())
commands.filterIsInstance<TransportCommand<*, *>>().forEach { command ->
command.setTransportConfigCallback { transport: Transport ->
(transport as? SshTransport)?.sshSessionFactory = sshSessionFactory
@@ -170,8 +169,8 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
suspend fun executeAfterAuthentication(authMode: AuthMode): Result<Unit, Throwable> {
when (authMode) {
AuthMode.SshKey ->
- if (sshFacade.keyExists()) {
- if (sshFacade.needsAuthentication()) {
+ if (sshKeyManager.keyExists()) {
+ if (sshKeyManager.needsAuthentication()) {
val result =
withContext(hiltEntryPoint.dispatcherProvider().main()) {
suspendCoroutine { cont ->
@@ -248,7 +247,7 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
@EntryPoint
@InstallIn(SingletonComponent::class)
interface GitOperationEntryPoint {
- fun sshFacade(): SSHFacade
+ fun sshKeyManager(): SSHKeyManager
fun dispatcherProvider(): DispatcherProvider
}
diff --git a/app/src/main/java/app/passwordstore/util/git/sshj/SshjSessionFactory.kt b/app/src/main/java/app/passwordstore/util/git/sshj/SshjSessionFactory.kt
index 20bb01d6..86416cd6 100644
--- a/app/src/main/java/app/passwordstore/util/git/sshj/SshjSessionFactory.kt
+++ b/app/src/main/java/app/passwordstore/util/git/sshj/SshjSessionFactory.kt
@@ -6,10 +6,10 @@ package app.passwordstore.util.git.sshj
import android.util.Base64
import androidx.appcompat.app.AppCompatActivity
+import app.passwordstore.ssh.SSHKeyManager
import app.passwordstore.util.coroutines.DispatcherProvider
import app.passwordstore.util.git.operation.CredentialFinder
import app.passwordstore.util.settings.AuthMode
-import app.passwordstore.util.ssh.SSHFacade
import com.github.michaelbull.result.getOrElse
import com.github.michaelbull.result.runCatching
import java.io.File
@@ -71,7 +71,7 @@ abstract class InteractivePasswordFinder(private val dispatcherProvider: Dispatc
class SshjSessionFactory(
private val authMethod: SshAuthMethod,
private val hostKeyFile: File,
- private val sshFacade: SSHFacade,
+ private val sshKeyManager: SSHKeyManager,
private val dispatcherProvider: DispatcherProvider,
) : SshSessionFactory() {
@@ -84,12 +84,10 @@ class SshjSessionFactory(
tms: Int
): RemoteSession {
return currentSession
- ?: SshjSession(uri, uri.user, authMethod, hostKeyFile, sshFacade, dispatcherProvider)
- .connect()
- .also {
- logcat { "New SSH connection created" }
- currentSession = it
- }
+ ?: SshjSession(uri, uri.user, authMethod, hostKeyFile, dispatcherProvider, sshKeyManager).connect().also {
+ logcat { "New SSH connection created" }
+ currentSession = it
+ }
}
fun close() {
@@ -130,8 +128,8 @@ private class SshjSession(
private val username: String,
private val authMethod: SshAuthMethod,
private val hostKeyFile: File,
- private val sshFacade: SSHFacade,
private val dispatcherProvider: DispatcherProvider,
+ private val sshKeyManager: SSHKeyManager,
) : RemoteSession {
private lateinit var ssh: SSHClient
@@ -167,10 +165,7 @@ private class SshjSession(
is SshAuthMethod.SshKey -> {
val pubkeyAuth =
AuthPublickey(
- sshFacade.keyProvider(
- ssh,
- CredentialFinder(authMethod.activity, AuthMode.SshKey, dispatcherProvider)
- )
+ sshKeyManager.keyProvider(ssh, CredentialFinder(authMethod.activity, AuthMode.SshKey, dispatcherProvider))
)
ssh.auth(username, pubkeyAuth, passwordAuth)
}
diff --git a/app/src/main/java/app/passwordstore/util/ssh/SSHFacade.kt b/app/src/main/java/app/passwordstore/util/ssh/SSHFacade.kt
deleted file mode 100644
index 8d8c8aa6..00000000
--- a/app/src/main/java/app/passwordstore/util/ssh/SSHFacade.kt
+++ /dev/null
@@ -1,86 +0,0 @@
-package app.passwordstore.util.ssh
-
-import android.net.Uri
-import app.passwordstore.ssh.SSHKeyAlgorithm
-import app.passwordstore.ssh.SSHKeyManager
-import app.passwordstore.util.features.Feature
-import app.passwordstore.util.features.Features
-import app.passwordstore.util.git.operation.CredentialFinder
-import app.passwordstore.util.git.sshj.SshKey
-import javax.inject.Inject
-import net.schmizz.sshj.SSHClient
-import net.schmizz.sshj.userauth.keyprovider.KeyProvider
-
-/** A wrapper around [SshKey] and [SSHKeyManager] to allow switching between them at runtime. */
-class SSHFacade
-@Inject
-constructor(
- private val features: Features,
- private val sshKeyManager: SSHKeyManager,
-) {
-
- private val useNewSSH
- get() = features.isEnabled(Feature.EnableNewSSHLayer)
-
- fun canShowPublicKey(): Boolean {
- return if (useNewSSH) {
- sshKeyManager.canShowPublicKey()
- } else {
- SshKey.canShowSshPublicKey
- }
- }
-
- fun publicKey(): String? {
- return if (useNewSSH) {
- sshKeyManager.publicKey()
- } else {
- SshKey.sshPublicKey
- }
- }
-
- fun keyExists(): Boolean {
- return if (useNewSSH) {
- sshKeyManager.keyExists()
- } else {
- SshKey.exists
- }
- }
-
- suspend fun generateKey(keyAlgorithm: SSHKeyAlgorithm, requireAuthentication: Boolean) {
- if (useNewSSH) {
- sshKeyManager.generateKey(keyAlgorithm, requireAuthentication)
- } else {
- when (keyAlgorithm) {
- SSHKeyAlgorithm.RSA ->
- SshKey.generateKeystoreNativeKey(SshKey.Algorithm.Rsa, requireAuthentication)
- SSHKeyAlgorithm.ECDSA ->
- SshKey.generateKeystoreNativeKey(SshKey.Algorithm.Ecdsa, requireAuthentication)
- SSHKeyAlgorithm.ED25519 -> SshKey.generateKeystoreWrappedEd25519Key(requireAuthentication)
- }
- }
- }
-
- suspend fun importKey(uri: Uri) {
- if (useNewSSH) {
- sshKeyManager.importKey(uri)
- } else {
- SshKey.import(uri)
- }
- }
-
- fun needsAuthentication(): Boolean {
- return if (useNewSSH) {
- sshKeyManager.needsAuthentication()
- } else {
- SshKey.mustAuthenticate
- }
- }
-
- fun keyProvider(client: SSHClient, credentialFinder: CredentialFinder): KeyProvider? {
- return if (useNewSSH) {
- sshKeyManager.keyProvider(client, credentialFinder)
- } else {
- SshKey.provide(client, credentialFinder)
- }
- }
-}