示例#1
0
    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()
示例#2
0
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))