diff --git a/py/yubikey.py b/py/yubikey.py index eba9146e..9af0226b 100644 --- a/py/yubikey.py +++ b/py/yubikey.py @@ -128,18 +128,10 @@ def catch_error(f): return wrapped -def usb_selectable(dev): - return dev.mode.has_transport(TRANSPORT.CCID) and ( - dev.config.usb_enabled & APPLICATION.OATH) - - -def nfc_selectable(dev): - return dev.config.nfc_enabled & APPLICATION.OATH - - def is_nfc(reader_name): return "yubico" not in reader_name.lower() + class OathContextManager(object): def __init__(self, dev): self._dev = dev @@ -245,13 +237,6 @@ class Controller(object): return res serial = dev.serial - selectable = usb_selectable(dev) - - if selectable and transport == TRANSPORT.CCID: - controller = OathController(dev.driver) - has_password = controller.locked - else: - has_password = False if serial not in handled_serials: handled_serials.add(serial) @@ -261,29 +246,26 @@ class Controller(object): dev.driver.key_type, dev.driver.mode)] if len(matches) > 0: matching_descriptor = matches[0] - res.append({ - 'name': dev.device_name, - 'version': '.'.join( - str(x) for x in dev.version - ) if dev.version else '', - 'serial': serial or '', - 'usbAppEnabled': [a.name for a in APPLICATION if a & dev.config.usb_enabled], - 'usbAppSupported': [a.name for a in APPLICATION if a & dev.config.usb_supported], - 'nfcAppEnabled': [a.name for a in APPLICATION if a & dev.config.nfc_enabled], - 'nfcAppSupported': [a.name for a in APPLICATION if a & dev.config.nfc_enabled], - 'usbInterfacesSupported': [t.name for t in TRANSPORT if t & dev.config.usb_supported], - 'usbInterfacesEnabled': str(dev.mode).split('+'), - 'canWriteConfig': dev.can_write_config, - 'configurationLocked': dev.config.configuration_locked, - 'formFactor': dev.config.form_factor, - - 'hasPassword': has_password, - 'selectable': selectable, - 'validated': not has_password - }) + res.append(self._serialise_dev(dev)) descs_to_match.remove(matching_descriptor) return res + def _serialise_dev(self, dev): + return { + 'name': dev.device_name, + 'version': '.'.join(str(x) for x in dev.version) if dev.version else '', + 'serial': dev.serial or '', + 'usbAppEnabled': [a.name for a in APPLICATION if a & dev.config.usb_enabled], + 'usbAppSupported': [a.name for a in APPLICATION if a & dev.config.usb_supported], + 'nfcAppEnabled': [a.name for a in APPLICATION if a & dev.config.nfc_enabled], + 'nfcAppSupported': [a.name for a in APPLICATION if a & dev.config.nfc_enabled], + 'usbInterfacesSupported': [t.name for t in TRANSPORT if t & dev.config.usb_supported], + 'usbInterfacesEnabled': str(dev.mode).split('+'), + 'canWriteConfig': dev.can_write_config, + 'configurationLocked': dev.config.configuration_locked, + 'formFactor': dev.config.form_factor + } + def refresh_devices(self, reader_filter=None): self._devices = [] @@ -291,26 +273,7 @@ class Controller(object): self._reader_filter = reader_filter dev = self._get_dev_from_reader() if dev: - if is_nfc(self._reader_filter): - selectable = nfc_selectable(dev) - else: - selectable = usb_selectable(dev) - if selectable: - controller = OathController(dev.driver) - has_password = controller.locked - else: - has_password = False - self._devices.append({ - 'name': dev.device_name, - 'version': '.'.join( - str(x) for x in dev.version - ) if dev.version else '', - 'serial': dev.serial or '', - 'usbInterfacesEnabled': str(dev.mode).split('+'), - 'hasPassword': has_password, - 'selectable': selectable, - 'validated': True - }) + self._devices.append(self._serialise_dev(dev)) return success({'devices': self._devices}) else: return success({'devices': []}) diff --git a/qml/AboutPopup.qml b/qml/AboutPopup.qml index a3234829..38523fcb 100644 --- a/qml/AboutPopup.qml +++ b/qml/AboutPopup.qml @@ -31,17 +31,6 @@ Dialog { navigator.isShowingAbout = true } - function getDeviceDescription() { - if (!!yubiKey.currentDevice) { - return yubiKey.currentDevice.usbInterfacesEnabled.join('+') - } else if (yubiKey.availableDevices.length > 0 - && !yubiKey.availableDevices.some(dev => dev.selectable)) { - return qsTr("No compatible device found") - } else { - return qsTr("No device found") - } - } - ColumnLayout { width: parent.width Layout.fillWidth: true @@ -106,7 +95,7 @@ Dialog { } Label { - text: !!yubiKey.currentDevice ? qsTr("Enabled interfaces: ") + getDeviceDescription() : "" + text: !!yubiKey.currentDevice ? qsTr("Enabled interfaces: ") + yubiKey.currentDevice.usbInterfacesEnabled.join('+') : "" color: primaryColor opacity: highEmphasis font.pixelSize: 13 diff --git a/qml/CredentialsView.qml b/qml/CredentialsView.qml index 8437e2b3..0cd991ba 100644 --- a/qml/CredentialsView.qml +++ b/qml/CredentialsView.qml @@ -65,7 +65,7 @@ Pane { NoYubiKeySection { id: noYubiKeySection // Make this section the default view to show when there is errors. - visible: !yubiKey.availableDevices.some(dev => dev.selectable) || (!credentialsSection.visible && !noResultsSection.visible && !noCredentialsSection.visible) + visible: !yubiKey.availableDevices || (!credentialsSection.visible && !noResultsSection.visible && !noCredentialsSection.visible) enabled: visible Accessible.ignored: true } diff --git a/qml/NoYubiKeySection.qml b/qml/NoYubiKeySection.qml index 272d3db0..25303bd8 100644 --- a/qml/NoYubiKeySection.qml +++ b/qml/NoYubiKeySection.qml @@ -27,14 +27,7 @@ ColumnLayout { } Label { - text: { - if (yubiKey.availableDevices.length > 0 && !yubiKey.availableDevices.some(dev => dev.selectable)) { - return qsTr("Unsupported device") - } - else { - return qsTr("Insert your YubiKey") - } - } + text: qsTr("Insert your YubiKey") font.pixelSize: 16 font.weight: Font.Normal lineHeight: 1.5 @@ -42,28 +35,6 @@ ColumnLayout { color: primaryColor opacity: highEmphasis } - Label { - text: { - if (yubiKey.availableDevices.length > 0 && !yubiKey.availableDevices.some(dev => dev.selectable)) { - return qsTr("Yubico Authenticator requires a CCID enabled and compatible YubiKey.") - } - else { - return "" - } - } - visible: (yubiKey.availableDevices.length > 0 && !yubiKey.availableDevices.some(dev => dev.selectable)) - Layout.minimumWidth: 300 - Layout.maximumWidth: app.width - dynamicMargin - < dynamicWidth ? app.width - dynamicMargin : dynamicWidth - horizontalAlignment: Qt.AlignHCenter - Layout.rowSpan: 1 - lineHeight: 1.1 - wrapMode: Text.WordWrap - font.pixelSize: 13 - Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter - color: primaryColor - opacity: lowEmphasis - } } ColumnLayout { diff --git a/qml/SettingsView.qml b/qml/SettingsView.qml index 1e33d34b..7bb2ad67 100644 --- a/qml/SettingsView.qml +++ b/qml/SettingsView.qml @@ -34,9 +34,6 @@ Flickable { function getDeviceDescription(device) { if (!!device) { return qsTr("Serial number: %1").arg(!!device.serial ? device.serial : "Not available") - } else if (yubiKey.availableDevices.length > 0 - && !yubiKey.availableDevices.some(dev => dev.selectable)) { - return qsTr("No compatible device found") } else { return qsTr("No device found") } @@ -188,7 +185,6 @@ Flickable { && modelData.serial === yubiKey.currentDevice.serial text: getDeviceLabel(modelData) description: getDeviceDescription(modelData) - enabled: modelData.selectable buttonGroup: deviceButtonGroup } } diff --git a/qml/YubiKey.qml b/qml/YubiKey.qml index cedc5b6b..2b019fa8 100644 --- a/qml/YubiKey.qml +++ b/qml/YubiKey.qml @@ -246,12 +246,12 @@ Python { if (!currentDevice || !availableDevices.some(dev => dev.serial === currentDevice.serial)) { // new device is being loaded, clear any old device clearCurrentDeviceAndEntries() - if (availableDevices.some(dev => dev.selectable)) { - // pick the first selectable device - currentDevice = resp.devices.find(dev => dev.selectable) + if (availableDevices.some(dev => dev.usbAppEnabled.includes("OATH"))) { + // pick the first device with oath enabled over USB + currentDevice = resp.devices.find(dev => dev.usbAppEnabled.includes("OATH")) calculateAll(navigator.goToCredentialsIfNotInSettings) } else { - // no selectable device (will land in no Insert YubiKey view) + // no device with oath enabled over USB (will land in no Insert YubiKey view) navigator.goToCredentialsIfNotInSettings() } } else {