mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
fix: better challenge channel implementation
This commit is contained in:
@@ -42,8 +42,6 @@ import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm
|
||||
import com.kunzisoft.keepass.database.element.node.Node
|
||||
import com.kunzisoft.keepass.database.element.node.NodeId
|
||||
import com.kunzisoft.keepass.database.element.node.Type
|
||||
import com.kunzisoft.keepass.hardware.HardwareKey
|
||||
import com.kunzisoft.keepass.hardware.HardwareKeyActivity
|
||||
import com.kunzisoft.keepass.model.CipherEncryptDatabase
|
||||
import com.kunzisoft.keepass.model.ProgressMessage
|
||||
import com.kunzisoft.keepass.model.SnapFileDatabaseInfo
|
||||
@@ -188,20 +186,6 @@ class DatabaseTaskProvider(private var context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
private var requestChallengeListener = object: DatabaseTaskNotificationService.RequestChallengeListener {
|
||||
override fun onChallengeResponseRequested(
|
||||
hardwareKey: HardwareKey,
|
||||
seed: ByteArray?
|
||||
) {
|
||||
HardwareKeyActivity
|
||||
.launchHardwareKeyActivity(
|
||||
context,
|
||||
hardwareKey,
|
||||
seed
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun startDialog(progressMessage: ProgressMessage) {
|
||||
activity?.let { activity ->
|
||||
activity.lifecycleScope.launch {
|
||||
@@ -259,14 +243,12 @@ class DatabaseTaskProvider(private var context: Context) {
|
||||
service?.addDatabaseListener(databaseListener)
|
||||
service?.addDatabaseFileInfoListener(databaseInfoListener)
|
||||
service?.addActionTaskListener(actionTaskListener)
|
||||
service?.setRequestChallengeListener(requestChallengeListener)
|
||||
}
|
||||
|
||||
private fun removeServiceListeners(service: DatabaseTaskNotificationService.ActionTaskBinder?) {
|
||||
service?.removeActionTaskListener(actionTaskListener)
|
||||
service?.removeDatabaseFileInfoListener(databaseInfoListener)
|
||||
service?.removeDatabaseListener(databaseListener)
|
||||
service?.removeRequestChallengeListener()
|
||||
}
|
||||
|
||||
private fun bindService() {
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.kunzisoft.keepass.hardware
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
import android.util.Log
|
||||
import androidx.activity.result.ActivityResult
|
||||
import androidx.activity.result.ActivityResultCallback
|
||||
@@ -96,7 +97,7 @@ class HardwareKeyActivity: DatabaseActivity(){
|
||||
seed: ByteArray?
|
||||
) {
|
||||
context.startActivity(Intent(context, HardwareKeyActivity::class.java).apply {
|
||||
//flags = FLAG_ACTIVITY_NEW_TASK
|
||||
flags = FLAG_ACTIVITY_NEW_TASK
|
||||
putExtra(DATA_HARDWARE_KEY, hardwareKey.value)
|
||||
putExtra(DATA_SEED, seed)
|
||||
})
|
||||
|
||||
@@ -44,6 +44,7 @@ import com.kunzisoft.keepass.database.element.node.Node
|
||||
import com.kunzisoft.keepass.database.element.node.NodeId
|
||||
import com.kunzisoft.keepass.database.element.node.Type
|
||||
import com.kunzisoft.keepass.hardware.HardwareKey
|
||||
import com.kunzisoft.keepass.hardware.HardwareKeyActivity
|
||||
import com.kunzisoft.keepass.model.CipherEncryptDatabase
|
||||
import com.kunzisoft.keepass.model.ProgressMessage
|
||||
import com.kunzisoft.keepass.model.SnapFileDatabaseInfo
|
||||
@@ -75,8 +76,7 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
||||
private var mDatabaseInfoListeners = mutableListOf<DatabaseInfoListener>()
|
||||
private var mActionTaskBinder = ActionTaskBinder()
|
||||
private var mActionTaskListeners = mutableListOf<ActionTaskListener>()
|
||||
// Channel to connect asynchronously a listener or a response
|
||||
private var mRequestChallengeListenerChannel: Channel<RequestChallengeListener>? = null
|
||||
// Channel to connect asynchronously a response
|
||||
private var mResponseChallengeChannel: Channel<ByteArray?>? = null
|
||||
|
||||
private var mActionRunning = false
|
||||
@@ -123,30 +123,6 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
||||
fun removeActionTaskListener(actionTaskListener: ActionTaskListener) {
|
||||
mActionTaskListeners.remove(actionTaskListener)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
fun setRequestChallengeListener(requestChallengeListener: RequestChallengeListener) {
|
||||
mainScope.launch {
|
||||
val requestChannel = mRequestChallengeListenerChannel
|
||||
if (requestChannel == null || requestChannel.isEmpty) {
|
||||
initializeChallengeResponse()
|
||||
mRequestChallengeListenerChannel?.send(requestChallengeListener)
|
||||
} else {
|
||||
cancelChallengeResponse(R.string.error_challenge_already_requested)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun removeRequestChallengeListener() {
|
||||
mainScope.launch {
|
||||
try {
|
||||
mRequestChallengeListenerChannel?.cancel()
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "Request challenge listener cannot be closed.", e)
|
||||
}
|
||||
mRequestChallengeListenerChannel = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface DatabaseListener {
|
||||
@@ -249,32 +225,8 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
||||
}
|
||||
}
|
||||
|
||||
private fun initializeChallengeResponse() {
|
||||
// Init the channels
|
||||
if (mRequestChallengeListenerChannel == null) {
|
||||
mRequestChallengeListenerChannel = Channel(0)
|
||||
}
|
||||
if (mResponseChallengeChannel == null) {
|
||||
mResponseChallengeChannel = Channel(0)
|
||||
}
|
||||
}
|
||||
|
||||
private fun closeChallengeResponse() {
|
||||
mRequestChallengeListenerChannel?.close()
|
||||
mResponseChallengeChannel?.close()
|
||||
mRequestChallengeListenerChannel = null
|
||||
mResponseChallengeChannel = null
|
||||
}
|
||||
|
||||
private fun cancelChallengeResponse(@StringRes error: Int) {
|
||||
mRequestChallengeListenerChannel?.cancel(CancellationException(getString(error)))
|
||||
mRequestChallengeListenerChannel = null
|
||||
mResponseChallengeChannel?.cancel(CancellationException(getString(error)))
|
||||
mResponseChallengeChannel = null
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
private fun respondToChallenge(response: ByteArray) {
|
||||
private fun sendResponseToChallenge(response: ByteArray) {
|
||||
mainScope.launch {
|
||||
val responseChannel = mResponseChallengeChannel
|
||||
if (responseChannel == null || responseChannel.isEmpty) {
|
||||
@@ -289,6 +241,23 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
||||
}
|
||||
}
|
||||
|
||||
private fun initializeChallengeResponse() {
|
||||
// Init the channels
|
||||
if (mResponseChallengeChannel == null) {
|
||||
mResponseChallengeChannel = Channel(0)
|
||||
}
|
||||
}
|
||||
|
||||
private fun closeChallengeResponse() {
|
||||
mResponseChallengeChannel?.close()
|
||||
mResponseChallengeChannel = null
|
||||
}
|
||||
|
||||
private fun cancelChallengeResponse(@StringRes error: Int) {
|
||||
mResponseChallengeChannel?.cancel(CancellationException(getString(error)))
|
||||
mResponseChallengeChannel = null
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent): IBinder? {
|
||||
super.onBind(intent)
|
||||
return mActionTaskBinder
|
||||
@@ -326,12 +295,6 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
||||
stopSelf()
|
||||
}
|
||||
|
||||
if (intentAction == ACTION_CHALLENGE_RESPONDED) {
|
||||
intent.getByteArrayExtra(DATA_BYTES)?.let {
|
||||
respondToChallenge(it)
|
||||
}
|
||||
}
|
||||
|
||||
val actionRunnable: ActionRunnable? = when (intentAction) {
|
||||
ACTION_DATABASE_CREATE_TASK -> buildDatabaseCreateActionTask(intent, database)
|
||||
ACTION_DATABASE_LOAD_TASK -> buildDatabaseLoadActionTask(intent, database)
|
||||
@@ -362,7 +325,8 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
||||
ACTION_DATABASE_UPDATE_MEMORY_USAGE_TASK,
|
||||
ACTION_DATABASE_UPDATE_PARALLELISM_TASK,
|
||||
ACTION_DATABASE_UPDATE_ITERATIONS_TASK -> buildDatabaseUpdateElementActionTask(intent, database)
|
||||
ACTION_DATABASE_SAVE -> buildDatabaseSave(intent, database)
|
||||
ACTION_DATABASE_SAVE -> buildDatabaseSaveActionTask(intent, database)
|
||||
ACTION_CHALLENGE_RESPONDED -> buildChallengeRespondedActionTask(intent)
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -386,7 +350,6 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
||||
database, mProgressMessage
|
||||
)
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
actionRunnable
|
||||
@@ -659,8 +622,12 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
||||
}
|
||||
// Send the request
|
||||
notifyProgressMessage()
|
||||
val challengeResponseRequestListener = mRequestChallengeListenerChannel?.receive()
|
||||
challengeResponseRequestListener?.onChallengeResponseRequested(hardwareKey, seed)
|
||||
HardwareKeyActivity
|
||||
.launchHardwareKeyActivity(
|
||||
this@DatabaseTaskNotificationService,
|
||||
hardwareKey,
|
||||
seed
|
||||
)
|
||||
// Wait the response
|
||||
mProgressMessage.apply {
|
||||
messageId = R.string.waiting_challenge_response
|
||||
@@ -1108,7 +1075,7 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
||||
/**
|
||||
* Save database without parameter
|
||||
*/
|
||||
private fun buildDatabaseSave(intent: Intent, database: Database): ActionRunnable? {
|
||||
private fun buildDatabaseSaveActionTask(intent: Intent, database: Database): ActionRunnable? {
|
||||
return if (intent.hasExtra(SAVE_DATABASE_KEY)) {
|
||||
|
||||
var databaseCopyUri: Uri? = null
|
||||
@@ -1129,6 +1096,24 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildChallengeRespondedActionTask(intent: Intent): ActionRunnable? {
|
||||
return if (intent.hasExtra(DATA_BYTES)) {
|
||||
object : ActionRunnable() {
|
||||
override fun onStartRun() {}
|
||||
override fun onActionRun() {
|
||||
mainScope.launch {
|
||||
intent.getByteArrayExtra(DATA_BYTES)?.let { response ->
|
||||
sendResponseToChallenge(response)
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun onFinishRun() {}
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val TAG = DatabaseTaskNotificationService::class.java.name
|
||||
|
||||
Reference in New Issue
Block a user