Yubico / yubikit-android

Yubico Mobile Android SDK - YubiKit
Apache License 2.0
109 stars 40 forks source link

USB device permissions prompt shown every time #35

Closed Lzyct closed 3 years ago

Lzyct commented 3 years ago

I was add intent filter and meta-data like this and register vendor id and product-id image

and every time i plug the yubikey, prompt permission always shown, How to make it just request permission just one time ?

I need to read serial number from Yubikey

dainnilsson commented 3 years ago

You have to check the "Always open AppName when YubiKey ... is connected" checkbox in the permission prompt. This does cause the app to automatically launch when the YubiKey is inserted (and if you have multiple apps that do this, you get a picker dialog), but that is the only way to grant permission that lasts between sessions. This is a limitation in the Android USB Host API.

Lzyct commented 3 years ago

image

There's no checkbox to always open App when Yubikey is Connected. And in my case i don't need to open App when Yubikey Connected, i just need to read serial from yubikey, and i do that in Broadcast Receiver.

dainnilsson commented 3 years ago

I'm actually not sure how Android deals with permissions when the Broadcast Receiver is defined in the Manifest, but I would assume it's similar to how it deals with launching an activity. What is the content of your device_filter.xml file?

Lzyct commented 3 years ago

It's same way in Activity to enable usbListener image

And this in device_filter.xml image

vendor id and product id i got from this code

 val usbManager = context.getSystemService(USB_SERVICE) as UsbManager?
                    if (usbManager != null) {
                        val devices = usbManager.deviceList
                        for (key in devices.keys) {
                            Log.e(TAG, "Device Name: " + devices[key]!!.deviceName)
                            Log.e(TAG, "Manufacturer Name: " + devices[key]!!.manufacturerName)
                            Log.e(TAG, "Serial Number: " + devices[key]!!.serialNumber)
                            Log.e(TAG, "Product Name: " + devices[key]!!.productName)
                            Log.e(TAG, "Vendor ID: " + devices[key]!!.vendorId)
                            Log.e(TAG, "Product ID: " + devices[key]!!.productId)
                        }
                    }
dainnilsson commented 3 years ago

Both vendor and product ID look correct to me. I'll have to look into this and do a bit of experimenting and get back to you.

Lzyct commented 3 years ago

Great, thanks.

dainnilsson commented 3 years ago

Ok, I've done a little bit of testing with this. The only way I can get the OS to remember the permission, is to have it auto-launch an Activity on USB insert (by having an intent filter with USB_DEVICE_ATTACHED). Otherwise it prompts every time, regardless of if the "always allow" checkbox is checked or not. Perhaps you can create an Activity which does what you need it to do, and then finishes immediately, without showing a UI (if that's what you're trying to achieve)?

Lzyct commented 3 years ago

with launch activity it's should not showing prompt for request permissions to read serial in yubikey ?

Because in this listener i can get information about yubikey

 private class UsbListener implements UsbSessionListener {
        @Override
        public void onSessionReceived(@NonNull UsbSession session, Boolean hasPermissions) {
            // YubiKey was plugged in
        }

        @Override
        public void onSessionRemoved(@NonNull UsbSession session) {
            // YubiKey was unplugged
        }

        @Override
        public void onRequestPermissionsResult(@NonNull UsbSession session, Boolean isGranted) {
            // whether user granted permissions to specific YubiKey
        }
    }

That code have method to detect permissions is grant or not, so how that activity can automatically grant permission without showing prompt ?

Can you share your sample project with that case ? Thanks

dainnilsson commented 3 years ago

I'm not sure I fully understand what it is you are trying to do. How do you intend to read the serial number from the YubiKey, do you have code for this already? There are multiple possible ways to do this, and it might be possible to do without USB permission (by reading it from the USB descriptor), which is what I thought you were attempting. Do note that YubiKeys by default are configured to NOT expose their serial number in this way, so for that to work the YubiKey needs to have been specifically configured to allow this. The other way, which works with the standard configuration of YubiKeys, will require permission to access the device. This entails using the Management Application to read out the device configuration. Here's a minimal app to do just that: https://github.com/dainnilsson/yubikit-read-serial-sample

Lzyct commented 3 years ago

oh i got it

            <intent-filter>
                     <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
            </intent-filter>
            <meta-data
                android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
                android:resource="@xml/device_filter" />

it's only work on activity not in receiver

Thanks!