-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Fido2: Fix instant use of screen lock #3237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
0c4aa6d
c3124d0
9dc940b
1999c7f
c526a24
b3e55e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,8 +6,6 @@ | |
| package org.microg.gms.fido.core.ui | ||
|
|
||
| import android.content.Intent | ||
| import android.graphics.Color | ||
| import android.graphics.drawable.ColorDrawable | ||
| import android.os.Build.VERSION.SDK_INT | ||
| import android.os.Bundle | ||
| import android.util.Base64 | ||
|
|
@@ -24,7 +22,6 @@ import com.google.android.gms.fido.fido2.api.common.AuthenticationExtensionsPrfO | |
| import com.google.android.gms.fido.fido2.api.common.ErrorCode.* | ||
| import kotlinx.coroutines.CancellationException | ||
| import kotlinx.coroutines.Job | ||
| import org.microg.gms.common.GmsService | ||
| import org.microg.gms.fido.core.* | ||
| import org.microg.gms.fido.core.transport.Transport | ||
| import org.microg.gms.fido.core.transport.Transport.* | ||
|
|
@@ -37,6 +34,7 @@ import org.microg.gms.fido.core.transport.usb.UsbTransportHandler | |
| import org.microg.gms.utils.getApplicationLabel | ||
| import org.microg.gms.utils.getFirstSignatureDigest | ||
| import org.microg.gms.utils.toBase64 | ||
| import androidx.core.graphics.drawable.toDrawable | ||
|
|
||
| const val TAG = "FidoUi" | ||
|
|
||
|
|
@@ -54,8 +52,6 @@ class AuthenticatorActivity : AppCompatActivity(), TransportHandlerCallback { | |
| else -> null | ||
| } | ||
|
|
||
| private val service: GmsService | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This wasn't used |
||
| get() = GmsService.byServiceId(intent.getIntExtra(KEY_SERVICE, GmsService.UNKNOWN.SERVICE_ID)) | ||
| private val database by lazy { Database(this) } | ||
| private val transportHandlers by lazy { | ||
| setOfNotNull( | ||
|
|
@@ -95,19 +91,6 @@ class AuthenticatorActivity : AppCompatActivity(), TransportHandlerCallback { | |
|
|
||
| Log.d(TAG, "onCreate caller=$callerPackage options=$options") | ||
|
|
||
| val requiresPrivilege = | ||
| options is BrowserRequestOptions && !database.isPrivileged(callerPackage, callerSignature) | ||
|
|
||
| // Check if we can directly open screen lock handling | ||
| if (!requiresPrivilege) { | ||
| val instantTransport = transportHandlers.firstOrNull { it.isSupported && it.shouldBeUsedInstantly(options) } | ||
| if (instantTransport != null && instantTransport.transport in INSTANT_SUPPORTED_TRANSPORTS) { | ||
| window.setBackgroundDrawable(ColorDrawable(0)) | ||
| window.statusBarColor = Color.TRANSPARENT | ||
| setTheme(org.microg.gms.base.core.R.style.Theme_Translucent) | ||
| } | ||
| } | ||
|
|
||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This part was doing work on the UI thread, including DB requests, and redundant: setTheme is called right after the condition to set AppCompat_DayNight_NoAction_Bar, the statusBarColor seems to not have any effect, and setting the background color can be done in the suspended handleRequest |
||
| setTheme(androidx.appcompat.R.style.Theme_AppCompat_DayNight_NoActionBar) | ||
| setContentView(R.layout.fido_authenticator_activity) | ||
|
|
||
|
|
@@ -136,10 +119,15 @@ class AuthenticatorActivity : AppCompatActivity(), TransportHandlerCallback { | |
| Log.d(TAG, "origin=$origin, appName=$appName") | ||
|
|
||
| // Check if we can directly open screen lock handling | ||
| // If the request contains an allow list, the request is for a dedicated account. | ||
| // If we have one of the allowed keys we instant login | ||
| // Else, the user must be able to choose | ||
| if (!requiresPrivilege && allowInstant) { | ||
| val instantTransport = transportHandlers.firstOrNull { it.isSupported && it.shouldBeUsedInstantly(options) } | ||
| if (instantTransport != null && instantTransport.transport in INSTANT_SUPPORTED_TRANSPORTS) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. INSTANT_SUPPORTED_TRANSPORTS was redundant: this is already what |
||
| startTransportHandling(instantTransport.transport, true) | ||
| transportHandlers.firstOrNull { | ||
| it.isSupported && it.shouldBeUsedInstantly(options) | ||
| }?.let { | ||
| window.setBackgroundDrawable(0.toDrawable()) | ||
| startTransportHandling(it.transport, true) | ||
| return | ||
| } | ||
| } | ||
|
|
@@ -154,7 +142,6 @@ class AuthenticatorActivity : AppCompatActivity(), TransportHandlerCallback { | |
| val next = if (!requiresPrivilege) { | ||
| val knownRegistrationTransports = mutableSetOf<Transport>() | ||
| val allowedTransports = mutableSetOf<Transport>() | ||
| val localSavedUserKey = mutableSetOf<String>() | ||
| if (options.type == RequestOptionsType.SIGN) { | ||
| for (descriptor in options.signOptions.allowList.orEmpty()) { | ||
| val knownTransport = database.getKnownRegistrationTransport(options.rpId, descriptor.id.toBase64(Base64.URL_SAFE, Base64.NO_WRAP, Base64.NO_PADDING)) | ||
|
|
@@ -177,13 +164,11 @@ class AuthenticatorActivity : AppCompatActivity(), TransportHandlerCallback { | |
| } | ||
| } | ||
| } | ||
| database.getKnownRegistrationInfo(options.rpId).forEach { localSavedUserKey.add(it.userJson) } | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here was the first part of bug: "Store any key for that website in localSavedUserKey" |
||
| } | ||
| val preselectedTransport = knownRegistrationTransports.singleOrNull() ?: allowedTransports.singleOrNull() | ||
| if (database.wasUsed()) { | ||
| if (localSavedUserKey.isNotEmpty()) { | ||
| R.id.signInSelectionFragment | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And here the 2nd part "If there is any key for that website in localSavedUserKey, go to signInSelection" => we can't use a USB or NFC key, even if it is the only allowed key |
||
| } else when (preselectedTransport) { | ||
| when (preselectedTransport) { | ||
| SCREEN_LOCK -> R.id.signInSelectionFragment | ||
| USB -> R.id.usbFragment | ||
| NFC -> R.id.nfcFragment | ||
| else -> R.id.transportSelectionFragment | ||
|
|
@@ -358,7 +343,6 @@ class AuthenticatorActivity : AppCompatActivity(), TransportHandlerCallback { | |
| const val KEY_CALLER = "caller" | ||
|
|
||
| val IMPLEMENTED_TRANSPORTS = setOf(USB, SCREEN_LOCK, NFC) | ||
| val INSTANT_SUPPORTED_TRANSPORTS = setOf(SCREEN_LOCK) | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,9 +10,10 @@ import android.view.LayoutInflater | |
| import android.view.View | ||
| import android.view.ViewGroup | ||
| import androidx.navigation.fragment.findNavController | ||
| import com.google.android.gms.fido.fido2.api.common.BrowserPublicKeyCredentialRequestOptions | ||
| import com.google.android.gms.fido.fido2.api.common.PublicKeyCredentialRequestOptions | ||
| import org.microg.gms.fido.core.R | ||
| import org.microg.gms.fido.core.databinding.FidoTransportSelectionFragmentBinding | ||
| import org.microg.gms.fido.core.transport.Transport | ||
| import org.microg.gms.fido.core.transport.Transport.SCREEN_LOCK | ||
|
|
||
| class TransportSelectionFragment : AuthenticatorActivityFragment() { | ||
|
|
@@ -31,7 +32,15 @@ class TransportSelectionFragment : AuthenticatorActivityFragment() { | |
| findNavController().navigate(R.id.openUsbFragment, arguments.withIsFirst(false)) | ||
| } | ||
| binding.setOnScreenLockClick { | ||
| startTransportHandling(SCREEN_LOCK) | ||
| if (options is PublicKeyCredentialRequestOptions || | ||
| options is BrowserPublicKeyCredentialRequestOptions) { | ||
| findNavController().navigate( | ||
| R.id.signInSelectionFragment, | ||
| arguments.withIsFirst(false) | ||
| ) | ||
| } else { | ||
| startTransportHandling(SCREEN_LOCK) | ||
| } | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the part where we want to be able to choose which account to use during sign-in, but we don't want that view during registration The previous selection of user account was with the other bug, where it was "there is any key for a website => we go to the account selection for screen lock login". The current behavior is now:
|
||
| } | ||
| return binding.root | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've mainly added a comment here