mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Fix decoding OTP Auth #556
This commit is contained in:
@@ -51,9 +51,10 @@ class EntrySelectionLauncherActivity : AppCompatActivity() {
|
|||||||
if ("text/plain" == intent.type) {
|
if ("text/plain" == intent.type) {
|
||||||
// Retrieve web domain or OTP
|
// Retrieve web domain or OTP
|
||||||
intent.getStringExtra(Intent.EXTRA_TEXT)?.let { extra ->
|
intent.getStringExtra(Intent.EXTRA_TEXT)?.let { extra ->
|
||||||
sharedWebDomain = Uri.parse(extra).host
|
|
||||||
if (OtpEntryFields.isOTPUri(extra))
|
if (OtpEntryFields.isOTPUri(extra))
|
||||||
otpString = extra
|
otpString = extra
|
||||||
|
else
|
||||||
|
sharedWebDomain = Uri.parse(extra).host
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.kunzisoft.keepass.model
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Parcel
|
import android.os.Parcel
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import com.kunzisoft.keepass.otp.OtpEntryFields
|
import com.kunzisoft.keepass.otp.OtpEntryFields
|
||||||
@@ -72,7 +73,7 @@ class SearchInfo : ObjectNameResource, Parcelable {
|
|||||||
override fun getName(resources: Resources): String {
|
override fun getName(resources: Resources): String {
|
||||||
otpString?.let { otpString ->
|
otpString?.let { otpString ->
|
||||||
OtpEntryFields.parseOTPUri(otpString)?.let { otpElement ->
|
OtpEntryFields.parseOTPUri(otpString)?.let { otpElement ->
|
||||||
return "${otpElement.type} (${otpElement.name})"
|
return "${otpElement.type} (${Uri.decode(otpElement.issuer)} : ${Uri.decode(otpElement.name)})"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return toString()
|
return toString()
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import com.kunzisoft.keepass.database.element.security.ProtectedString
|
|||||||
import com.kunzisoft.keepass.model.Field
|
import com.kunzisoft.keepass.model.Field
|
||||||
import com.kunzisoft.keepass.otp.OtpElement.Companion.replaceSpaceChars
|
import com.kunzisoft.keepass.otp.OtpElement.Companion.replaceSpaceChars
|
||||||
import com.kunzisoft.keepass.otp.TokenCalculator.*
|
import com.kunzisoft.keepass.otp.TokenCalculator.*
|
||||||
import java.net.URLEncoder
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
@@ -156,8 +155,15 @@ object OtpEntryFields {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val nameParam = validateAndGetNameInPath(uri.path)
|
val nameParam = validateAndGetNameInPath(uri.path)
|
||||||
if (nameParam != null && nameParam.isNotEmpty())
|
if (nameParam != null && nameParam.isNotEmpty()) {
|
||||||
|
val userIdArray = nameParam.split(":", "%3A")
|
||||||
|
if (userIdArray.size > 1) {
|
||||||
|
otpElement.issuer = userIdArray[0]
|
||||||
|
otpElement.name = userIdArray[1]
|
||||||
|
} else {
|
||||||
otpElement.name = nameParam
|
otpElement.name = nameParam
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val issuerParam = uri.getQueryParameter(ISSUER_URL_PARAM)
|
val issuerParam = uri.getQueryParameter(ISSUER_URL_PARAM)
|
||||||
if (issuerParam != null && issuerParam.isNotEmpty())
|
if (issuerParam != null && issuerParam.isNotEmpty())
|
||||||
@@ -232,14 +238,14 @@ object OtpEntryFields {
|
|||||||
}
|
}
|
||||||
val issuer =
|
val issuer =
|
||||||
if (title != null && title.isNotEmpty())
|
if (title != null && title.isNotEmpty())
|
||||||
replaceCharsForUrl(title)
|
Uri.encode(title)
|
||||||
else
|
else
|
||||||
replaceCharsForUrl(otpElement.issuer)
|
Uri.encode(otpElement.issuer)
|
||||||
val accountName =
|
val accountName =
|
||||||
if (username != null && username.isNotEmpty())
|
if (username != null && username.isNotEmpty())
|
||||||
replaceCharsForUrl(username)
|
Uri.encode(username)
|
||||||
else
|
else
|
||||||
replaceCharsForUrl(otpElement.name)
|
Uri.encode(otpElement.name)
|
||||||
val uriString = StringBuilder("otpauth://$otpAuthority/$issuer:$accountName" +
|
val uriString = StringBuilder("otpauth://$otpAuthority/$issuer:$accountName" +
|
||||||
"?$SECRET_URL_PARAM=${otpElement.getBase32Secret()}" +
|
"?$SECRET_URL_PARAM=${otpElement.getBase32Secret()}" +
|
||||||
"&$counterOrPeriodLabel=$counterOrPeriodValue" +
|
"&$counterOrPeriodLabel=$counterOrPeriodValue" +
|
||||||
@@ -254,10 +260,6 @@ object OtpEntryFields {
|
|||||||
return Uri.parse(uriString.toString())
|
return Uri.parse(uriString.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun replaceCharsForUrl(parameter: String): String {
|
|
||||||
return URLEncoder.encode(replaceSpaceChars(parameter), "UTF-8")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun parseTOTPKeyValues(getField: (id: String) -> String?, otpElement: OtpElement): Boolean {
|
private fun parseTOTPKeyValues(getField: (id: String) -> String?, otpElement: OtpElement): Boolean {
|
||||||
val plainText = getField(OTP_FIELD)
|
val plainText = getField(OTP_FIELD)
|
||||||
if (plainText != null && plainText.isNotEmpty()) {
|
if (plainText != null && plainText.isNotEmpty()) {
|
||||||
@@ -342,7 +344,7 @@ object OtpEntryFields {
|
|||||||
// path is "/name", so remove leading "/", and trailing white spaces
|
// path is "/name", so remove leading "/", and trailing white spaces
|
||||||
val name = path.substring(1).trim { it <= ' ' }
|
val name = path.substring(1).trim { it <= ' ' }
|
||||||
return if (name.isEmpty()) {
|
return if (name.isEmpty()) {
|
||||||
null // only white spaces.
|
null
|
||||||
} else name
|
} else name
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,7 +361,7 @@ object OtpEntryFields {
|
|||||||
/**
|
/**
|
||||||
* Build Otp field from an OtpElement
|
* Build Otp field from an OtpElement
|
||||||
*/
|
*/
|
||||||
fun buildOtpField(otpElement: OtpElement, title: String?, username: String?): Field {
|
fun buildOtpField(otpElement: OtpElement, title: String? = null, username: String? = null): Field {
|
||||||
return Field(OTP_FIELD, ProtectedString(true,
|
return Field(OTP_FIELD, ProtectedString(true,
|
||||||
buildOtpUri(otpElement, title, username).toString()))
|
buildOtpUri(otpElement, title, username).toString()))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user