def set_mode(self, interfaces): interfaces_enabled = 0x00 for usb_interface in interfaces: interfaces_enabled |= USB_INTERFACE[usb_interface] with self._open_device() as conn: try: session = ManagementSession(conn) session.set_mode(Mode(interfaces_enabled)) except ValueError as e: if str(e) == 'Configuration locked!': return failure('interface_config_locked') raise return success()
def mode(ctx, mode, touch_eject, autoeject_timeout, chalresp_timeout, force): """ Manage connection modes (USB Interfaces). Get the current connection mode of the YubiKey, or set it to MODE. MODE can be a string, such as "OTP+FIDO+CCID", or a shortened form: "o+f+c". It can also be a mode number. Examples: \b Set the OTP and FIDO mode: $ ykman mode OTP+FIDO \b Set the CCID only mode and use touch to eject the smart card: $ ykman mode CCID --touch-eject """ info = ctx.obj["info"] mgmt = ManagementSession(ctx.obj["conn"]) usb_enabled = info.config.enabled_applications[TRANSPORT.USB] my_mode = _mode_from_usb_enabled(usb_enabled) usb_supported = info.supported_applications[TRANSPORT.USB] interfaces_supported = _mode_from_usb_enabled(usb_supported).interfaces pid = ctx.obj["pid"] if pid: key_type = pid.get_type() else: key_type = None if autoeject_timeout: touch_eject = True autoeject = autoeject_timeout if touch_eject else 0 if mode is not None: if mode.interfaces != USB_INTERFACE.CCID: if touch_eject: ctx.fail("--touch-eject can only be used when setting" " CCID-only mode") if not force: if mode == my_mode: click.echo("Mode is already {}, nothing to do...".format(mode)) ctx.exit() elif key_type in (YUBIKEY.YKS, YUBIKEY.YKP): click.echo("Mode switching is not supported on this YubiKey!") ctx.fail("Use --force to attempt to set it anyway.") elif mode.interfaces not in interfaces_supported: click.echo( "Mode {} is not supported on this YubiKey!".format(mode)) ctx.fail("Use --force to attempt to set it anyway.") force or click.confirm("Set mode of YubiKey to {}?".format(mode), abort=True, err=True) try: mgmt.set_mode(mode, chalresp_timeout, autoeject) click.echo("Mode set! You must remove and re-insert your YubiKey " "for this change to take effect.") except Exception as e: logger.debug("Failed to switch mode", exc_info=e) click.echo("Failed to switch mode on the YubiKey. Make sure your " "YubiKey does not have an access code set.") else: click.echo("Current connection mode is: {}".format(my_mode)) mode = _mode_from_usb_enabled( info.supported_applications[TRANSPORT.USB]) supported = ", ".join(t.name for t in USB_INTERFACE if t in mode.interfaces) click.echo("Supported USB interfaces are: {}".format(supported))