Prevent cached passwords from being wiped (#884)

(cherry picked from commit 889208b264)
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
Fabian Henneke 2020-06-26 08:47:47 +02:00 committed by Harsh Shandilya
parent 8f7d3052ea
commit cc2bb76398
No known key found for this signature in database
GPG key ID: 366D7BBAD1031E80

View file

@ -38,13 +38,13 @@ import kotlin.coroutines.suspendCoroutine
sealed class SshAuthData { sealed class SshAuthData {
class Password(val passwordFinder: InteractivePasswordFinder) : SshAuthData() { class Password(val passwordFinder: InteractivePasswordFinder) : SshAuthData() {
override fun clearCredentials() { override fun clearCredentials() {
passwordFinder.clearPassword() passwordFinder.clearPasswords()
} }
} }
class PublicKeyFile(val keyFile: File, val passphraseFinder: InteractivePasswordFinder) : SshAuthData() { class PublicKeyFile(val keyFile: File, val passphraseFinder: InteractivePasswordFinder) : SshAuthData() {
override fun clearCredentials() { override fun clearCredentials() {
passphraseFinder.clearPassword() passphraseFinder.clearPasswords()
} }
} }
@ -57,13 +57,14 @@ abstract class InteractivePasswordFinder : PasswordFinder {
private var isRetry = false private var isRetry = false
private var lastPassword: CharArray? = null private var lastPassword: CharArray? = null
private val rememberToWipe: MutableList<CharArray> = mutableListOf()
fun resetForReuse() { fun resetForReuse() {
isRetry = false isRetry = false
} }
fun clearPassword() { fun clearPasswords() {
lastPassword?.clear() rememberToWipe.forEach { it.clear() }
lastPassword = null lastPassword = null
} }
@ -73,17 +74,20 @@ abstract class InteractivePasswordFinder : PasswordFinder {
// now being reused for a new one. We try the previous password so that the user // now being reused for a new one. We try the previous password so that the user
// does not have to type it again. // does not have to type it again.
isRetry = true isRetry = true
return lastPassword!! return lastPassword!!.clone().also { rememberToWipe.add(it) }
} }
clearPassword() clearPasswords()
val password = runBlocking(Dispatchers.Main) { val password = runBlocking(Dispatchers.Main) {
suspendCoroutine<String?> { cont -> suspendCoroutine<String?> { cont ->
askForPassword(cont, isRetry) askForPassword(cont, isRetry)
} }
} }
isRetry = true isRetry = true
return password?.toCharArray()?.also { lastPassword = it } if (password == null)
?: throw SSHException(DisconnectReason.AUTH_CANCELLED_BY_USER) throw SSHException(DisconnectReason.AUTH_CANCELLED_BY_USER)
val passwordChars = password.toCharArray().also { rememberToWipe.add(it) }
lastPassword = passwordChars
return passwordChars.clone().also { rememberToWipe.add(it) }
} }
final override fun shouldRetry(resource: Resource<*>?) = true final override fun shouldRetry(resource: Resource<*>?) = true