mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-04-18 08:09:03 +00:00
fixup! feat(python): implement session based trezorlib
This commit is contained in:
parent
7ac0bb8888
commit
dfaba33aae
@ -53,9 +53,6 @@ class ProtocolVersion(IntEnum):
|
||||
|
||||
class TrezorClient:
|
||||
button_callback: t.Callable[[messages.ButtonRequest], None] | None = None
|
||||
passphrase_callback: (
|
||||
t.Callable[[Session, messages.PassphraseRequest], t.Any] | None
|
||||
) = None
|
||||
pin_callback: t.Callable[[messages.PinMatrixRequest], str] | None = None
|
||||
|
||||
_model: models.TrezorModel
|
||||
|
@ -33,15 +33,12 @@ from mnemonic import Mnemonic
|
||||
|
||||
from . import btc, mapping, messages, models, protobuf
|
||||
from .client import (
|
||||
MAX_PASSPHRASE_LENGTH,
|
||||
PASSPHRASE_ON_DEVICE,
|
||||
ProtocolVersion,
|
||||
TrezorClient,
|
||||
)
|
||||
from .exceptions import Cancelled, TrezorFailure, UnexpectedMessageError
|
||||
from .log import DUMP_BYTES
|
||||
from .messages import Capability, DebugWaitType
|
||||
from .protobuf import MessageType
|
||||
from .messages import DebugWaitType
|
||||
from .tools import parse_path
|
||||
from .transport import Timeout
|
||||
from .transport.session import Session
|
||||
@ -1282,62 +1279,6 @@ class TrezorClientDebugLink(TrezorClient):
|
||||
new_client.debug.t1_screenshot_counter = self.debug.t1_screenshot_counter
|
||||
return new_client
|
||||
|
||||
def passphrase_callback(
|
||||
self, session: Session, msg: messages.PassphraseRequest
|
||||
) -> t.Any:
|
||||
available_on_device = (
|
||||
Capability.PassphraseEntry in session.features.capabilities
|
||||
)
|
||||
|
||||
def send_passphrase(
|
||||
passphrase: str | None = None, on_device: bool | None = None
|
||||
) -> MessageType:
|
||||
msg = messages.PassphraseAck(passphrase=passphrase, on_device=on_device)
|
||||
resp = session.call_raw(msg)
|
||||
if isinstance(resp, messages.Deprecated_PassphraseStateRequest):
|
||||
if resp.state is not None:
|
||||
session.id = resp.state
|
||||
else:
|
||||
raise RuntimeError("Object resp.state is None")
|
||||
resp = session.call_raw(messages.Deprecated_PassphraseStateAck())
|
||||
return resp
|
||||
|
||||
# short-circuit old style entry
|
||||
if msg._on_device is True:
|
||||
return send_passphrase(None, None)
|
||||
|
||||
try:
|
||||
if isinstance(session, SessionDebugWrapper):
|
||||
passphrase = self.ui.get_passphrase(
|
||||
available_on_device=available_on_device
|
||||
)
|
||||
if passphrase is None:
|
||||
passphrase = session.passphrase
|
||||
else:
|
||||
raise NotImplementedError
|
||||
except Cancelled:
|
||||
session.call_raw(messages.Cancel())
|
||||
raise
|
||||
|
||||
if passphrase is PASSPHRASE_ON_DEVICE:
|
||||
if not available_on_device:
|
||||
session.call_raw(messages.Cancel())
|
||||
raise RuntimeError("Device is not capable of entering passphrase")
|
||||
else:
|
||||
return send_passphrase(on_device=True)
|
||||
|
||||
# else process host-entered passphrase
|
||||
if passphrase is None:
|
||||
passphrase = ""
|
||||
if not isinstance(passphrase, str):
|
||||
raise RuntimeError(f"Passphrase must be a str {type(passphrase)}")
|
||||
passphrase = Mnemonic.normalize_string(passphrase)
|
||||
if len(passphrase) > MAX_PASSPHRASE_LENGTH:
|
||||
session.call_raw(messages.Cancel())
|
||||
raise ValueError("Passphrase too long")
|
||||
|
||||
return send_passphrase(passphrase, on_device=False)
|
||||
|
||||
def close_transport(self) -> None:
|
||||
self.transport.close()
|
||||
self.debug.close()
|
||||
@ -1359,7 +1300,6 @@ class TrezorClientDebugLink(TrezorClient):
|
||||
derive_cardano,
|
||||
)
|
||||
)
|
||||
session.passphrase = passphrase
|
||||
return session
|
||||
|
||||
def get_seedless_session(
|
||||
|
@ -14,7 +14,6 @@
|
||||
# You should have received a copy of the License along with this library.
|
||||
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import typing as t
|
||||
|
||||
@ -22,7 +21,7 @@ import click
|
||||
from mnemonic import Mnemonic
|
||||
|
||||
from . import device, messages
|
||||
from .client import MAX_PIN_LENGTH
|
||||
from .client import MAX_PIN_LENGTH, PASSPHRASE_ON_DEVICE
|
||||
from .exceptions import Cancelled
|
||||
from .messages import Capability, PinMatrixRequestType, WordRequestType
|
||||
from .transport.session import Session
|
||||
@ -137,52 +136,6 @@ class ClickUI:
|
||||
else:
|
||||
return pin
|
||||
|
||||
def get_passphrase(
|
||||
self, session: Session, request: messages.PassphraseRequest
|
||||
) -> t.Any:
|
||||
available_on_device = (
|
||||
Capability.PassphraseEntry in session.features.capabilities
|
||||
)
|
||||
if available_on_device and not self.passphrase_on_host:
|
||||
return session.call_raw(
|
||||
messages.PassphraseAck(passphrase=None, on_device=True)
|
||||
)
|
||||
|
||||
env_passphrase = os.getenv("PASSPHRASE")
|
||||
if env_passphrase is not None:
|
||||
echo("Passphrase required. Using PASSPHRASE environment variable.")
|
||||
return session.call_raw(
|
||||
messages.PassphraseAck(passphrase=env_passphrase, on_device=False)
|
||||
)
|
||||
|
||||
while True:
|
||||
try:
|
||||
passphrase = prompt(
|
||||
"Passphrase required",
|
||||
hide_input=True,
|
||||
default="",
|
||||
show_default=False,
|
||||
)
|
||||
# In case user sees the input on the screen, we do not need confirmation
|
||||
if not CAN_HANDLE_HIDDEN_INPUT:
|
||||
break
|
||||
second = prompt(
|
||||
"Confirm your passphrase",
|
||||
hide_input=True,
|
||||
default="",
|
||||
show_default=False,
|
||||
)
|
||||
if passphrase == second:
|
||||
break
|
||||
else:
|
||||
echo("Passphrase did not match. Please try again.")
|
||||
except click.Abort:
|
||||
raise Cancelled from None
|
||||
|
||||
return session.call_raw(
|
||||
messages.PassphraseAck(passphrase=passphrase, on_device=False)
|
||||
)
|
||||
|
||||
|
||||
class ScriptUI:
|
||||
"""Interface to be used by scripts, not directly by user.
|
||||
@ -218,10 +171,7 @@ class ScriptUI:
|
||||
return pin
|
||||
|
||||
@staticmethod
|
||||
def get_passphrase(session: Session, request: messages.PassphraseRequest) -> t.Any:
|
||||
available_on_device = (
|
||||
Capability.PassphraseEntry in session.features.capabilities
|
||||
)
|
||||
def get_passphrase(available_on_device: bool) -> str | object:
|
||||
if available_on_device:
|
||||
print("?PASSPHRASE available_on_device")
|
||||
else:
|
||||
@ -231,16 +181,11 @@ class ScriptUI:
|
||||
if passphrase == "CANCEL":
|
||||
raise Cancelled from None
|
||||
elif passphrase == "ON_DEVICE":
|
||||
return session.call_raw(
|
||||
messages.PassphraseAck(passphrase=None, on_device=True)
|
||||
)
|
||||
return PASSPHRASE_ON_DEVICE
|
||||
elif not passphrase.startswith(":"):
|
||||
raise RuntimeError("Sent passphrase must start with ':'")
|
||||
else:
|
||||
passphrase = passphrase[1:]
|
||||
return session.call_raw(
|
||||
messages.PassphraseAck(passphrase=passphrase, on_device=False)
|
||||
)
|
||||
return passphrase[1:]
|
||||
|
||||
|
||||
def mnemonic_words(
|
||||
|
Loading…
Reference in New Issue
Block a user