mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-19 02:52:11 +00:00
parent
d9495bc76b
commit
1b45c0d491
1
python/.changelog.d/3993.added
Normal file
1
python/.changelog.d/3993.added
Normal file
@ -0,0 +1 @@
|
||||
Added support for Trezor models not known by the current version of the library.
|
@ -278,19 +278,10 @@ class TrezorClient(Generic[UI]):
|
||||
"""Update internal fields based on passed-in Features message."""
|
||||
|
||||
if not self.model:
|
||||
# Trezor Model One bootloader 1.8.0 or older does not send model name
|
||||
model = models.by_internal_name(features.internal_model)
|
||||
if model is None:
|
||||
model = models.by_name(features.model or "1")
|
||||
if model is None:
|
||||
raise RuntimeError(
|
||||
"Unsupported Trezor model"
|
||||
f" (internal_model: {features.internal_model}, model: {features.model})"
|
||||
)
|
||||
self.model = model
|
||||
self.model = models.detect(features)
|
||||
|
||||
if features.vendor not in self.model.vendors:
|
||||
raise RuntimeError("Unsupported device")
|
||||
raise exceptions.TrezorException(f"Unrecognized vendor: {features.vendor}")
|
||||
|
||||
self.features = features
|
||||
self.version = (
|
||||
|
@ -19,7 +19,7 @@ from __future__ import annotations
|
||||
from dataclasses import dataclass
|
||||
from typing import Collection, Tuple
|
||||
|
||||
from . import mapping
|
||||
from . import mapping, messages
|
||||
|
||||
UsbId = Tuple[int, int]
|
||||
|
||||
@ -35,6 +35,8 @@ class TrezorModel:
|
||||
usb_ids: Collection[UsbId]
|
||||
default_mapping: mapping.ProtobufMapping
|
||||
|
||||
is_unknown: bool = False
|
||||
|
||||
|
||||
# ==== internal names ====
|
||||
|
||||
@ -129,6 +131,11 @@ TREZORS = frozenset({T1B1, T2T1, T2B1, T3T1, T3B1, T3W1, DISC1, DISC2})
|
||||
|
||||
|
||||
def by_name(name: str | None) -> TrezorModel | None:
|
||||
"""Try to find a TrezorModel by its name.
|
||||
|
||||
This is a fallback function in case `internal_model` is not available. For general
|
||||
model detection, prefer `detect()`.
|
||||
"""
|
||||
if name is None:
|
||||
return T1B1
|
||||
for model in TREZORS:
|
||||
@ -138,9 +145,45 @@ def by_name(name: str | None) -> TrezorModel | None:
|
||||
|
||||
|
||||
def by_internal_name(name: str | None) -> TrezorModel | None:
|
||||
"""Try to find a TrezorModel by its internal name.
|
||||
|
||||
Used internally as part of `detect()` routine. For general model detection, prefer
|
||||
calling `detect()`.
|
||||
"""
|
||||
if name is None:
|
||||
return None
|
||||
for model in TREZORS:
|
||||
if model.internal_name == name:
|
||||
return model
|
||||
return None
|
||||
|
||||
|
||||
def detect(features: messages.Features) -> TrezorModel:
|
||||
"""Detect Trezor model from its Features response.
|
||||
|
||||
If `internal_name` is sent, tries to detect model based on it. If not (in older
|
||||
firmwares), falls back to `model` field.
|
||||
|
||||
If no match is found, returns an ad-hoc TrezorModel instance whose fields are set
|
||||
based on the provided model and/or internal model. This can either represent a newer
|
||||
model that is not recognized by the current version of the library, or a fork that
|
||||
responds to Trezor wire protocol but is not actually a Trezor.
|
||||
"""
|
||||
model = by_internal_name(features.internal_model)
|
||||
if model is not None:
|
||||
return model
|
||||
model = by_name(features.model)
|
||||
if model is not None:
|
||||
return model
|
||||
|
||||
return TrezorModel(
|
||||
name=features.model or "Unknown",
|
||||
internal_name=features.internal_model or "????",
|
||||
minimum_version=(0, 0, 0),
|
||||
# Allowed vendors are the internal VENDORS list instead of trusting features.vendor.
|
||||
# That way, an unrecognized non-Trezor device will fail the check in TrezorClient.
|
||||
vendors=VENDORS,
|
||||
usb_ids=(),
|
||||
default_mapping=mapping.DEFAULT_MAPPING,
|
||||
is_unknown=True,
|
||||
)
|
||||
|
@ -104,9 +104,7 @@ class Transport:
|
||||
self.transport = transport
|
||||
|
||||
client = TrezorClient(transport, ui=SilentUI())
|
||||
self.model = (
|
||||
trezorlib.models.by_name(client.features.model) or trezorlib.models.TREZOR_T
|
||||
)
|
||||
self.model = client.model
|
||||
client.end_session()
|
||||
|
||||
def acquire(self, sid: str) -> str:
|
||||
|
Loading…
Reference in New Issue
Block a user