From 763fa9e459d27539a8f5d3ab19e0ec19e39319ee Mon Sep 17 00:00:00 2001 From: agrahn Date: Sat, 20 Jul 2024 17:46:26 +0200 Subject: enabling pgp passphrase cache with authentication (#3124) * enabling pgp passphrase cache with authentication * clear passphrase cache on first autofill decrypt after screen off --------- Co-authored-by: Alexander Grahn --- .../ui/autofill/AutofillDecryptActivity.kt | 8 ++++ .../app/passwordstore/ui/crypto/DecryptActivity.kt | 5 ++- .../app/passwordstore/ui/settings/PGPSettings.kt | 45 +++++++++++----------- app/src/main/res/values-gl/strings.xml | 2 +- app/src/main/res/values-pl-rPL/strings.xml | 2 +- app/src/main/res/values/strings.xml | 2 +- 6 files changed, 37 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/app/passwordstore/ui/autofill/AutofillDecryptActivity.kt b/app/src/main/java/app/passwordstore/ui/autofill/AutofillDecryptActivity.kt index c4114685..b6e82b7a 100644 --- a/app/src/main/java/app/passwordstore/ui/autofill/AutofillDecryptActivity.kt +++ b/app/src/main/java/app/passwordstore/ui/autofill/AutofillDecryptActivity.kt @@ -13,6 +13,7 @@ import android.os.Bundle import android.view.autofill.AutofillManager import androidx.fragment.app.setFragmentResultListener import androidx.lifecycle.lifecycleScope +import app.passwordstore.Application.Companion.screenWasOff import app.passwordstore.R import app.passwordstore.crypto.PGPIdentifier import app.passwordstore.data.crypto.PGPPassphraseCache @@ -28,6 +29,7 @@ import app.passwordstore.util.autofill.DirectoryStructure import app.passwordstore.util.extensions.asLog import app.passwordstore.util.features.Feature.EnablePGPPassphraseCache import app.passwordstore.util.features.Features +import app.passwordstore.util.settings.PreferenceKeys import com.github.androidpasswordstore.autofillparser.AutofillAction import com.github.androidpasswordstore.autofillparser.Credentials import com.github.michaelbull.result.getOrElse @@ -110,6 +112,12 @@ class AutofillDecryptActivity : BasePGPActivity() { askPassphrase(filePath, gpgIdentifiers, clientState, action) // is Result.Success -> { + /* clear passphrase cache on first use after application startup or if screen was off; + also make sure to purge a stale cache after caching has been disabled via PGP settings */ + if (screenWasOff && settings.getBoolean(PreferenceKeys.CLEAR_PASSPHRASE_CACHE, true)) { + passphraseCache.clearAllCachedPassphrases(this@AutofillDecryptActivity) + screenWasOff = false + } val cachedPassphrase = passphraseCache.retrieveCachedPassphrase( this@AutofillDecryptActivity, diff --git a/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt b/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt index 854ebabd..405d6f4e 100644 --- a/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt +++ b/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt @@ -168,8 +168,9 @@ class DecryptActivity : BasePGPActivity() { askPassphrase(isError, gpgIdentifiers, authResult) // is BiometricResult.Success -> { - // clear passphrase cache on first use after application startup or if screen was off - if (screenWasOff && settings.getBoolean(PreferenceKeys.CLEAR_PASSPHRASE_CACHE, false)) { + /* clear passphrase cache on first use after application startup or if screen was off; + also make sure to purge a stale cache after caching has been disabled via PGP settings */ + if (screenWasOff && settings.getBoolean(PreferenceKeys.CLEAR_PASSPHRASE_CACHE, true)) { passphraseCache.clearAllCachedPassphrases(this@DecryptActivity) screenWasOff = false } diff --git a/app/src/main/java/app/passwordstore/ui/settings/PGPSettings.kt b/app/src/main/java/app/passwordstore/ui/settings/PGPSettings.kt index 3a77255b..2978b37a 100644 --- a/app/src/main/java/app/passwordstore/ui/settings/PGPSettings.kt +++ b/app/src/main/java/app/passwordstore/ui/settings/PGPSettings.kt @@ -5,6 +5,7 @@ package app.passwordstore.ui.settings +import androidx.core.content.edit import androidx.fragment.app.FragmentActivity import androidx.lifecycle.lifecycleScope import app.passwordstore.R @@ -12,6 +13,7 @@ import app.passwordstore.data.crypto.PGPPassphraseCache import app.passwordstore.ui.pgp.PGPKeyListActivity import app.passwordstore.util.auth.BiometricAuthenticator import app.passwordstore.util.extensions.launchActivity +import app.passwordstore.util.extensions.sharedPrefs import app.passwordstore.util.features.Feature import app.passwordstore.util.settings.PreferenceKeys import de.Maxr1998.modernpreferences.PreferenceScreen @@ -46,16 +48,24 @@ class PGPSettings( summaryRes = R.string.pref_passphrase_cache_summary defaultValue = false onCheckedChange { checked -> - if (!checked && BiometricAuthenticator.canAuthenticate(activity)) { - BiometricAuthenticator.authenticate( - activity, - R.string.pref_passphrase_cache_authenticate_clear, - ) { - if (it is BiometricAuthenticator.Result.Success) - activity.lifecycleScope.launch { - passphraseCache.clearAllCachedPassphrases(activity) - } - } + if (checked) { + if (BiometricAuthenticator.canAuthenticate(activity)) { + BiometricAuthenticator.authenticate( + activity, + R.string.pref_passphrase_cache_authenticate_enable, + ) { + if (!(it is BiometricAuthenticator.Result.Success)) + activity.sharedPrefs.edit { + putBoolean(Feature.EnablePGPPassphraseCache.configKey, false) + } + } + } else + activity.sharedPrefs.edit { + putBoolean(Feature.EnablePGPPassphraseCache.configKey, false) + } + } else { + activity.sharedPrefs.edit { remove(PreferenceKeys.CLEAR_PASSPHRASE_CACHE) } + activity.lifecycleScope.launch { passphraseCache.clearAllCachedPassphrases(activity) } } true } @@ -64,21 +74,12 @@ class PGPSettings( dependency = Feature.EnablePGPPassphraseCache.configKey titleRes = R.string.pref_passphrase_cache_auto_clear_title summaryRes = R.string.pref_passphrase_cache_auto_clear_summary - defaultValue = false + defaultValue = true /* clear cache once when unchecking; this is to prevent a malicious user * from bypassing cache clearing via the settings */ onCheckedChange { checked -> - if (!checked && BiometricAuthenticator.canAuthenticate(activity)) { - BiometricAuthenticator.authenticate( - activity, - R.string.pref_passphrase_cache_authenticate_clear, - ) { - if (it is BiometricAuthenticator.Result.Success) - activity.lifecycleScope.launch { - passphraseCache.clearAllCachedPassphrases(activity) - } - } - } + if (!checked) + activity.lifecycleScope.launch { passphraseCache.clearAllCachedPassphrases(activity) } true } } diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 2be0b96b..d966d262 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -120,7 +120,7 @@ Cifrar co modo ASCII armor Permitir usar a caché para frase de paso AVISO: esta característica funciona ben pero é experimental. Require que a pantalla estea bloqueada. - Autenticarse para poder baleirar a cache + Autenticarse para activar a caché Limpar automáticamente a frase de paso da caché Retira automáticamente a frase de paso da caché ao apagarse a pantalla diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index 49068ffa..0948c71f 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -116,7 +116,7 @@ Menedżer kluczy Szyfruj w trybie ASCII-armor UWAGA: ta funkcjonalność powinna działać poprawnie, ale jest bardzo eksperymentalna. Wymaga aktywnej blokady ekranu. - Uwierzytelnij aby wyczyścić pamięć podręczną + Uwierzytelnij aby włączyć pamięć podręczną Automatycznie wyczyść pamięć podręczną haseł Czyści pamięć podręczną haseł po wyłączeniu ekranu diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bafda226..07a9661b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -137,7 +137,7 @@ Encrypt in ASCII armor mode Enable passphrase caching WARNING: this feature is functional but very experimental. Requires an active screen lock. - Authenticate to clear cache + Authenticate to enable cache Automatically clear passphrase cache Clears the passphrase cache when the screen is turned off -- cgit v1.2.3