mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-06-07 00:28:45 +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."""
|
"""Update internal fields based on passed-in Features message."""
|
||||||
|
|
||||||
if not self.model:
|
if not self.model:
|
||||||
# Trezor Model One bootloader 1.8.0 or older does not send model name
|
self.model = models.detect(features)
|
||||||
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
|
|
||||||
|
|
||||||
if features.vendor not in self.model.vendors:
|
if features.vendor not in self.model.vendors:
|
||||||
raise RuntimeError("Unsupported device")
|
raise exceptions.TrezorException(f"Unrecognized vendor: {features.vendor}")
|
||||||
|
|
||||||
self.features = features
|
self.features = features
|
||||||
self.version = (
|
self.version = (
|
||||||
|
@ -19,7 +19,7 @@ from __future__ import annotations
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Collection, Tuple
|
from typing import Collection, Tuple
|
||||||
|
|
||||||
from . import mapping
|
from . import mapping, messages
|
||||||
|
|
||||||
UsbId = Tuple[int, int]
|
UsbId = Tuple[int, int]
|
||||||
|
|
||||||
@ -35,6 +35,8 @@ class TrezorModel:
|
|||||||
usb_ids: Collection[UsbId]
|
usb_ids: Collection[UsbId]
|
||||||
default_mapping: mapping.ProtobufMapping
|
default_mapping: mapping.ProtobufMapping
|
||||||
|
|
||||||
|
is_unknown: bool = False
|
||||||
|
|
||||||
|
|
||||||
# ==== internal names ====
|
# ==== internal names ====
|
||||||
|
|
||||||
@ -129,6 +131,11 @@ TREZORS = frozenset({T1B1, T2T1, T2B1, T3T1, T3B1, T3W1, DISC1, DISC2})
|
|||||||
|
|
||||||
|
|
||||||
def by_name(name: str | None) -> TrezorModel | None:
|
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:
|
if name is None:
|
||||||
return T1B1
|
return T1B1
|
||||||
for model in TREZORS:
|
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:
|
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:
|
if name is None:
|
||||||
return None
|
return None
|
||||||
for model in TREZORS:
|
for model in TREZORS:
|
||||||
if model.internal_name == name:
|
if model.internal_name == name:
|
||||||
return model
|
return model
|
||||||
return None
|
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
|
self.transport = transport
|
||||||
|
|
||||||
client = TrezorClient(transport, ui=SilentUI())
|
client = TrezorClient(transport, ui=SilentUI())
|
||||||
self.model = (
|
self.model = client.model
|
||||||
trezorlib.models.by_name(client.features.model) or trezorlib.models.TREZOR_T
|
|
||||||
)
|
|
||||||
client.end_session()
|
client.end_session()
|
||||||
|
|
||||||
def acquire(self, sid: str) -> str:
|
def acquire(self, sid: str) -> str:
|
||||||
|
Loading…
Reference in New Issue
Block a user