client: refuse to work with outdated firmware

required firmware versions are hardcoded and should be updated by a
build script
pull/25/head
matejcik 6 years ago
parent 84339ae1ff
commit d9e5fd2682

@ -1 +1,8 @@
__version__ = "0.11.0"
# fmt: off
MINIMUM_FIRMWARE_VERSION = {
"1": (1, 6, 3),
"T": (2, 0, 10),
}
# fmt: on

@ -20,7 +20,7 @@ import warnings
from mnemonic import Mnemonic
from . import exceptions, messages, tools
from . import MINIMUM_FIRMWARE_VERSION, exceptions, messages, tools
if sys.version_info.major < 3:
raise Exception("Trezorlib does not support Python 2 anymore.")
@ -36,6 +36,12 @@ Incompatible Trezor library detected.
(Original error: {})
""".strip()
OUTDATED_FIRMWARE_ERROR = """
Your Trezor firmware is out of date. Update it with the following command:
trezorctl firmware-update
Or visit https://wallet.trezor.io/
""".strip()
def get_buttonrequest_value(code):
# Converts integer code to its string representation of ButtonRequestType
@ -156,6 +162,7 @@ class TrezorClient:
@tools.session
def call(self, msg):
self.check_firmware_version()
resp = self.call_raw(msg)
while True:
if isinstance(resp, messages.PinMatrixRequest):
@ -183,6 +190,25 @@ class TrezorClient:
# A side-effect of this is a sanity check for broken protobuf definitions.
# If the `vendor` field doesn't exist, you probably have a mismatched
# checkout of trezor-common.
self.version = (
self.features.major_version,
self.features.minor_version,
self.features.patch_version,
)
self.check_firmware_version(warn_only=True)
def is_outdated(self):
if self.features.bootloader_mode:
return False
required_version = MINIMUM_FIRMWARE_VERSION[self.features.model]
return self.version < required_version
def check_firmware_version(self, warn_only=False):
if self.is_outdated():
if warn_only:
warnings.warn(OUTDATED_FIRMWARE_ERROR, stacklevel=2)
else:
raise exceptions.OutdatedFirmwareError(OUTDATED_FIRMWARE_ERROR)
@tools.expect(messages.Success, field="message")
def ping(
@ -192,6 +218,13 @@ class TrezorClient:
pin_protection=False,
passphrase_protection=False,
):
# We would like ping to work on any valid TrezorClient instance, but
# due to the protection modes, we need to go through self.call, and that will
# raise an exception if the firmware is too old.
# So we short-circuit the simplest variant of ping with call_raw.
if not button_protection and not pin_protection and not passphrase_protection:
return self.call_raw(messages.Ping(message=msg))
msg = messages.Ping(
message=msg,
button_protection=button_protection,

@ -45,3 +45,7 @@ class PinException(TrezorException):
class Cancelled(TrezorException):
pass
class OutdatedFirmwareError(TrezorException):
pass

Loading…
Cancel
Save