2018-06-21 14:28:34 +00:00
|
|
|
# This file is part of the Trezor project.
|
2016-11-25 21:53:55 +00:00
|
|
|
#
|
2021-11-26 14:50:43 +00:00
|
|
|
# Copyright (C) 2012-2022 SatoshiLabs and contributors
|
2016-11-25 21:53:55 +00:00
|
|
|
#
|
|
|
|
# This library is free software: you can redistribute it and/or modify
|
2018-06-21 14:28:34 +00:00
|
|
|
# it under the terms of the GNU Lesser General Public License version 3
|
|
|
|
# as published by the Free Software Foundation.
|
2016-11-25 21:53:55 +00:00
|
|
|
#
|
|
|
|
# This library is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU Lesser General Public License for more details.
|
|
|
|
#
|
2018-06-21 14:28:34 +00:00
|
|
|
# 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>.
|
2016-11-25 21:53:55 +00:00
|
|
|
|
2020-03-05 16:38:31 +00:00
|
|
|
import logging
|
2016-04-30 00:37:18 +00:00
|
|
|
import socket
|
2020-01-14 10:30:41 +00:00
|
|
|
import time
|
2021-11-26 15:31:35 +00:00
|
|
|
from typing import TYPE_CHECKING, Iterable, Optional
|
2016-04-30 00:37:18 +00:00
|
|
|
|
2020-03-05 16:38:31 +00:00
|
|
|
from ..log import DUMP_PACKETS
|
trezorlib: transport/protocol reshuffle
This commit breaks session handling (which matters with Bridge) and
regresses Bridge to an older code state. Both of these issues will be
rectified in subsequent commits.
Explanation of this big API reshuffle follows:
* protocols are moved to trezorlib.transport, and to a single common file.
* there is a cleaner definition of Transport and Protocol API (see below)
* fully valid mypy type hinting
* session handle counters and open handle counters mostly went away. Transports
and Protocols are meant to be "raw" APIs; TrezorClient will implement
context-handler-based sessions, session tracking, etc.
I'm calling this a "reshuffle" because it involved very small number of
code changes. Most of it is moving things around where they sit better.
The API changes are as follows.
Transport is now a thing that can:
* open and close sessions
* read and write protobuf messages
* enumerate and find devices
Some transports (all except bridge) are technically bytes-based and need
a separate protocol implementation (because we have two existing protocols,
although only the first one is actually used). Hence a protocol superclass.
Protocol is a thing that *also* can:
* open and close sessions
* read and write protobuf messages
For that, it requires a `handle`.
Handle is a physical layer for a protocol. It can:
* open and close some sort of device connection
(this is distinct from session! Connection is a channel over which you can
send data. Session is a logical arrangement on top of that; you can have
multiple sessions on a single connection.)
* read and write 64-byte chunks of data
With that, we introduce ProtocolBasedTransport, which simply delegates
the appropriate Transport functionality to respective Protocol methods.
hid and webusb transports are ProtocolBasedTransport-s that provide separate
device handles. HidHandle and WebUsbHandle existed before, but the distinction
of functionality between a Transport and its Handle was unclear. Some methods
were moved and now the handles implement the Handle API, while the transports
provide the enumeration parts of the Transport API, as well as glue between
the respective Protocols and Handles.
udp transport is also a ProtocolBasedTransport, but it acts as its own handle.
(That might be changed. For now, I went with the pre-existing structure.)
In addition, session_begin/end is renamed to begin/end_session to keep
consistent verb_noun naming.
2018-11-08 14:24:28 +00:00
|
|
|
from . import TransportException
|
2020-03-05 16:38:31 +00:00
|
|
|
from .protocol import ProtocolBasedTransport, ProtocolV1
|
2017-08-24 12:29:27 +00:00
|
|
|
|
2021-11-26 15:31:35 +00:00
|
|
|
if TYPE_CHECKING:
|
|
|
|
from ..models import TrezorModel
|
|
|
|
|
2019-10-18 11:32:10 +00:00
|
|
|
SOCKET_TIMEOUT = 10
|
|
|
|
|
2020-03-05 16:38:31 +00:00
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
2017-08-24 12:29:27 +00:00
|
|
|
|
trezorlib: transport/protocol reshuffle
This commit breaks session handling (which matters with Bridge) and
regresses Bridge to an older code state. Both of these issues will be
rectified in subsequent commits.
Explanation of this big API reshuffle follows:
* protocols are moved to trezorlib.transport, and to a single common file.
* there is a cleaner definition of Transport and Protocol API (see below)
* fully valid mypy type hinting
* session handle counters and open handle counters mostly went away. Transports
and Protocols are meant to be "raw" APIs; TrezorClient will implement
context-handler-based sessions, session tracking, etc.
I'm calling this a "reshuffle" because it involved very small number of
code changes. Most of it is moving things around where they sit better.
The API changes are as follows.
Transport is now a thing that can:
* open and close sessions
* read and write protobuf messages
* enumerate and find devices
Some transports (all except bridge) are technically bytes-based and need
a separate protocol implementation (because we have two existing protocols,
although only the first one is actually used). Hence a protocol superclass.
Protocol is a thing that *also* can:
* open and close sessions
* read and write protobuf messages
For that, it requires a `handle`.
Handle is a physical layer for a protocol. It can:
* open and close some sort of device connection
(this is distinct from session! Connection is a channel over which you can
send data. Session is a logical arrangement on top of that; you can have
multiple sessions on a single connection.)
* read and write 64-byte chunks of data
With that, we introduce ProtocolBasedTransport, which simply delegates
the appropriate Transport functionality to respective Protocol methods.
hid and webusb transports are ProtocolBasedTransport-s that provide separate
device handles. HidHandle and WebUsbHandle existed before, but the distinction
of functionality between a Transport and its Handle was unclear. Some methods
were moved and now the handles implement the Handle API, while the transports
provide the enumeration parts of the Transport API, as well as glue between
the respective Protocols and Handles.
udp transport is also a ProtocolBasedTransport, but it acts as its own handle.
(That might be changed. For now, I went with the pre-existing structure.)
In addition, session_begin/end is renamed to begin/end_session to keep
consistent verb_noun naming.
2018-11-08 14:24:28 +00:00
|
|
|
class UdpTransport(ProtocolBasedTransport):
|
2017-08-24 12:29:27 +00:00
|
|
|
|
2018-08-13 16:21:24 +00:00
|
|
|
DEFAULT_HOST = "127.0.0.1"
|
2017-08-24 12:29:27 +00:00
|
|
|
DEFAULT_PORT = 21324
|
2018-08-13 16:21:24 +00:00
|
|
|
PATH_PREFIX = "udp"
|
2023-02-17 10:44:31 +00:00
|
|
|
ENABLED: bool = True
|
2017-08-24 12:29:27 +00:00
|
|
|
|
feat(python): add full type information
WIP - typing the trezorctl apps
typing functions trezorlib/cli
addressing most of mypy issue for trezorlib apps and _internal folder
fixing broken device tests by changing asserts in debuglink.py
addressing most of mypy issues in trezorlib/cli folder
adding types to some untyped functions, mypy section in setup.cfg
typing what can be typed, some mypy fixes, resolving circular import issues
importing type objects in "if TYPE_CHECKING:" branch
fixing CI by removing assert in emulator, better ignore comments
CI assert fix, style fixes, new config options
fixup! CI assert fix, style fixes, new config options
type fixes after rebasing on master
fixing python3.6 and 3.7 unittests by importing Literal from typing_extensions
couple mypy and style fixes
fixes and improvements from code review
silencing all but one mypy issues
trial of typing the tools.expect function
fixup! trial of typing the tools.expect function
@expect and @session decorators correctly type-checked
Optional args in CLI where relevant, not using general list/tuple/dict where possible
python/Makefile commands, adding them into CI, ignoring last mypy issue
documenting overload for expect decorator, two mypy fixes coming from that
black style fix
improved typing of decorators, pyright config file
addressing or ignoring pyright errors, replacing mypy in CI by pyright
fixing incomplete assert causing device tests to fail
pyright issue that showed in CI but not locally, printing pyright version in CI
fixup! pyright issue that showed in CI but not locally, printing pyright version in CI
unifying type:ignore statements for pyright usage
resolving PIL.Image issues, pyrightconfig not excluding anything
replacing couple asserts with TypeGuard on safe_issubclass
better error handling of usb1 import for webusb
better error handling of hid import
small typing details found out by strict pyright mode
improvements from code review
chore(python): changing List to Sequence for protobuf messages
small code changes to reflect the protobuf change to Sequence
importing TypedDict from typing_extensions to support 3.6 and 3.7
simplify _format_access_list function
fixup! simplify _format_access_list function
typing tools folder
typing helper-scripts folder
some click typing
enforcing all functions to have typed arguments
reverting the changed argument name in tools
replacing TransportType with Transport
making PinMatrixRequest.type protobuf attribute required
reverting the protobuf change, making argument into get_pin Optional
small fixes in asserts
solving the session decorator type issues
fixup! solving the session decorator type issues
improvements from code review
fixing new pyright errors introduced after version increase
changing -> Iterable to -> Sequence in enumerate_devices, change in wait_for_devices
style change in debuglink.py
chore(python): adding type annotation to Sequences in messages.py
better "self and cls" types on Transport
fixup! better "self and cls" types on Transport
fixing some easy things from strict pyright run
2021-11-03 22:12:53 +00:00
|
|
|
def __init__(self, device: Optional[str] = None) -> None:
|
2017-08-24 12:29:27 +00:00
|
|
|
if not device:
|
|
|
|
host = UdpTransport.DEFAULT_HOST
|
|
|
|
port = UdpTransport.DEFAULT_PORT
|
|
|
|
else:
|
2018-08-13 16:21:24 +00:00
|
|
|
devparts = device.split(":")
|
2017-11-13 21:15:09 +00:00
|
|
|
host = devparts[0]
|
|
|
|
port = int(devparts[1]) if len(devparts) > 1 else UdpTransport.DEFAULT_PORT
|
2017-08-24 12:29:27 +00:00
|
|
|
self.device = (host, port)
|
2020-10-16 17:47:11 +00:00
|
|
|
self.socket: Optional[socket.socket] = None
|
trezorlib: transport/protocol reshuffle
This commit breaks session handling (which matters with Bridge) and
regresses Bridge to an older code state. Both of these issues will be
rectified in subsequent commits.
Explanation of this big API reshuffle follows:
* protocols are moved to trezorlib.transport, and to a single common file.
* there is a cleaner definition of Transport and Protocol API (see below)
* fully valid mypy type hinting
* session handle counters and open handle counters mostly went away. Transports
and Protocols are meant to be "raw" APIs; TrezorClient will implement
context-handler-based sessions, session tracking, etc.
I'm calling this a "reshuffle" because it involved very small number of
code changes. Most of it is moving things around where they sit better.
The API changes are as follows.
Transport is now a thing that can:
* open and close sessions
* read and write protobuf messages
* enumerate and find devices
Some transports (all except bridge) are technically bytes-based and need
a separate protocol implementation (because we have two existing protocols,
although only the first one is actually used). Hence a protocol superclass.
Protocol is a thing that *also* can:
* open and close sessions
* read and write protobuf messages
For that, it requires a `handle`.
Handle is a physical layer for a protocol. It can:
* open and close some sort of device connection
(this is distinct from session! Connection is a channel over which you can
send data. Session is a logical arrangement on top of that; you can have
multiple sessions on a single connection.)
* read and write 64-byte chunks of data
With that, we introduce ProtocolBasedTransport, which simply delegates
the appropriate Transport functionality to respective Protocol methods.
hid and webusb transports are ProtocolBasedTransport-s that provide separate
device handles. HidHandle and WebUsbHandle existed before, but the distinction
of functionality between a Transport and its Handle was unclear. Some methods
were moved and now the handles implement the Handle API, while the transports
provide the enumeration parts of the Transport API, as well as glue between
the respective Protocols and Handles.
udp transport is also a ProtocolBasedTransport, but it acts as its own handle.
(That might be changed. For now, I went with the pre-existing structure.)
In addition, session_begin/end is renamed to begin/end_session to keep
consistent verb_noun naming.
2018-11-08 14:24:28 +00:00
|
|
|
|
2020-03-05 16:38:31 +00:00
|
|
|
super().__init__(protocol=ProtocolV1(self))
|
2016-04-30 00:37:18 +00:00
|
|
|
|
trezorlib: transport/protocol reshuffle
This commit breaks session handling (which matters with Bridge) and
regresses Bridge to an older code state. Both of these issues will be
rectified in subsequent commits.
Explanation of this big API reshuffle follows:
* protocols are moved to trezorlib.transport, and to a single common file.
* there is a cleaner definition of Transport and Protocol API (see below)
* fully valid mypy type hinting
* session handle counters and open handle counters mostly went away. Transports
and Protocols are meant to be "raw" APIs; TrezorClient will implement
context-handler-based sessions, session tracking, etc.
I'm calling this a "reshuffle" because it involved very small number of
code changes. Most of it is moving things around where they sit better.
The API changes are as follows.
Transport is now a thing that can:
* open and close sessions
* read and write protobuf messages
* enumerate and find devices
Some transports (all except bridge) are technically bytes-based and need
a separate protocol implementation (because we have two existing protocols,
although only the first one is actually used). Hence a protocol superclass.
Protocol is a thing that *also* can:
* open and close sessions
* read and write protobuf messages
For that, it requires a `handle`.
Handle is a physical layer for a protocol. It can:
* open and close some sort of device connection
(this is distinct from session! Connection is a channel over which you can
send data. Session is a logical arrangement on top of that; you can have
multiple sessions on a single connection.)
* read and write 64-byte chunks of data
With that, we introduce ProtocolBasedTransport, which simply delegates
the appropriate Transport functionality to respective Protocol methods.
hid and webusb transports are ProtocolBasedTransport-s that provide separate
device handles. HidHandle and WebUsbHandle existed before, but the distinction
of functionality between a Transport and its Handle was unclear. Some methods
were moved and now the handles implement the Handle API, while the transports
provide the enumeration parts of the Transport API, as well as glue between
the respective Protocols and Handles.
udp transport is also a ProtocolBasedTransport, but it acts as its own handle.
(That might be changed. For now, I went with the pre-existing structure.)
In addition, session_begin/end is renamed to begin/end_session to keep
consistent verb_noun naming.
2018-11-08 14:24:28 +00:00
|
|
|
def get_path(self) -> str:
|
|
|
|
return "{}:{}:{}".format(self.PATH_PREFIX, *self.device)
|
2017-07-01 15:59:11 +00:00
|
|
|
|
trezorlib: transport/protocol reshuffle
This commit breaks session handling (which matters with Bridge) and
regresses Bridge to an older code state. Both of these issues will be
rectified in subsequent commits.
Explanation of this big API reshuffle follows:
* protocols are moved to trezorlib.transport, and to a single common file.
* there is a cleaner definition of Transport and Protocol API (see below)
* fully valid mypy type hinting
* session handle counters and open handle counters mostly went away. Transports
and Protocols are meant to be "raw" APIs; TrezorClient will implement
context-handler-based sessions, session tracking, etc.
I'm calling this a "reshuffle" because it involved very small number of
code changes. Most of it is moving things around where they sit better.
The API changes are as follows.
Transport is now a thing that can:
* open and close sessions
* read and write protobuf messages
* enumerate and find devices
Some transports (all except bridge) are technically bytes-based and need
a separate protocol implementation (because we have two existing protocols,
although only the first one is actually used). Hence a protocol superclass.
Protocol is a thing that *also* can:
* open and close sessions
* read and write protobuf messages
For that, it requires a `handle`.
Handle is a physical layer for a protocol. It can:
* open and close some sort of device connection
(this is distinct from session! Connection is a channel over which you can
send data. Session is a logical arrangement on top of that; you can have
multiple sessions on a single connection.)
* read and write 64-byte chunks of data
With that, we introduce ProtocolBasedTransport, which simply delegates
the appropriate Transport functionality to respective Protocol methods.
hid and webusb transports are ProtocolBasedTransport-s that provide separate
device handles. HidHandle and WebUsbHandle existed before, but the distinction
of functionality between a Transport and its Handle was unclear. Some methods
were moved and now the handles implement the Handle API, while the transports
provide the enumeration parts of the Transport API, as well as glue between
the respective Protocols and Handles.
udp transport is also a ProtocolBasedTransport, but it acts as its own handle.
(That might be changed. For now, I went with the pre-existing structure.)
In addition, session_begin/end is renamed to begin/end_session to keep
consistent verb_noun naming.
2018-11-08 14:24:28 +00:00
|
|
|
def find_debug(self) -> "UdpTransport":
|
2018-03-02 14:44:24 +00:00
|
|
|
host, port = self.device
|
2021-09-27 10:13:51 +00:00
|
|
|
return UdpTransport(f"{host}:{port + 1}")
|
2018-03-02 14:44:24 +00:00
|
|
|
|
2018-03-02 17:22:33 +00:00
|
|
|
@classmethod
|
trezorlib: transport/protocol reshuffle
This commit breaks session handling (which matters with Bridge) and
regresses Bridge to an older code state. Both of these issues will be
rectified in subsequent commits.
Explanation of this big API reshuffle follows:
* protocols are moved to trezorlib.transport, and to a single common file.
* there is a cleaner definition of Transport and Protocol API (see below)
* fully valid mypy type hinting
* session handle counters and open handle counters mostly went away. Transports
and Protocols are meant to be "raw" APIs; TrezorClient will implement
context-handler-based sessions, session tracking, etc.
I'm calling this a "reshuffle" because it involved very small number of
code changes. Most of it is moving things around where they sit better.
The API changes are as follows.
Transport is now a thing that can:
* open and close sessions
* read and write protobuf messages
* enumerate and find devices
Some transports (all except bridge) are technically bytes-based and need
a separate protocol implementation (because we have two existing protocols,
although only the first one is actually used). Hence a protocol superclass.
Protocol is a thing that *also* can:
* open and close sessions
* read and write protobuf messages
For that, it requires a `handle`.
Handle is a physical layer for a protocol. It can:
* open and close some sort of device connection
(this is distinct from session! Connection is a channel over which you can
send data. Session is a logical arrangement on top of that; you can have
multiple sessions on a single connection.)
* read and write 64-byte chunks of data
With that, we introduce ProtocolBasedTransport, which simply delegates
the appropriate Transport functionality to respective Protocol methods.
hid and webusb transports are ProtocolBasedTransport-s that provide separate
device handles. HidHandle and WebUsbHandle existed before, but the distinction
of functionality between a Transport and its Handle was unclear. Some methods
were moved and now the handles implement the Handle API, while the transports
provide the enumeration parts of the Transport API, as well as glue between
the respective Protocols and Handles.
udp transport is also a ProtocolBasedTransport, but it acts as its own handle.
(That might be changed. For now, I went with the pre-existing structure.)
In addition, session_begin/end is renamed to begin/end_session to keep
consistent verb_noun naming.
2018-11-08 14:24:28 +00:00
|
|
|
def _try_path(cls, path: str) -> "UdpTransport":
|
2018-03-02 17:22:33 +00:00
|
|
|
d = cls(path)
|
|
|
|
try:
|
2021-07-30 12:14:51 +00:00
|
|
|
d.open()
|
|
|
|
if d._ping():
|
|
|
|
return d
|
|
|
|
else:
|
|
|
|
raise TransportException(
|
2021-09-27 10:13:51 +00:00
|
|
|
f"No Trezor device found at address {d.get_path()}"
|
2021-07-30 12:14:51 +00:00
|
|
|
)
|
2023-03-23 13:53:41 +00:00
|
|
|
except Exception as e:
|
|
|
|
raise TransportException(f"Error opening {d.get_path()}") from e
|
|
|
|
|
2021-07-30 12:14:51 +00:00
|
|
|
finally:
|
|
|
|
d.close()
|
2018-03-02 17:22:33 +00:00
|
|
|
|
|
|
|
@classmethod
|
2021-11-26 15:31:35 +00:00
|
|
|
def enumerate(
|
|
|
|
cls, _models: Optional[Iterable["TrezorModel"]] = None
|
|
|
|
) -> Iterable["UdpTransport"]:
|
2021-09-27 10:13:51 +00:00
|
|
|
default_path = f"{cls.DEFAULT_HOST}:{cls.DEFAULT_PORT}"
|
2018-03-02 17:22:33 +00:00
|
|
|
try:
|
|
|
|
return [cls._try_path(default_path)]
|
|
|
|
except TransportException:
|
|
|
|
return []
|
|
|
|
|
|
|
|
@classmethod
|
trezorlib: transport/protocol reshuffle
This commit breaks session handling (which matters with Bridge) and
regresses Bridge to an older code state. Both of these issues will be
rectified in subsequent commits.
Explanation of this big API reshuffle follows:
* protocols are moved to trezorlib.transport, and to a single common file.
* there is a cleaner definition of Transport and Protocol API (see below)
* fully valid mypy type hinting
* session handle counters and open handle counters mostly went away. Transports
and Protocols are meant to be "raw" APIs; TrezorClient will implement
context-handler-based sessions, session tracking, etc.
I'm calling this a "reshuffle" because it involved very small number of
code changes. Most of it is moving things around where they sit better.
The API changes are as follows.
Transport is now a thing that can:
* open and close sessions
* read and write protobuf messages
* enumerate and find devices
Some transports (all except bridge) are technically bytes-based and need
a separate protocol implementation (because we have two existing protocols,
although only the first one is actually used). Hence a protocol superclass.
Protocol is a thing that *also* can:
* open and close sessions
* read and write protobuf messages
For that, it requires a `handle`.
Handle is a physical layer for a protocol. It can:
* open and close some sort of device connection
(this is distinct from session! Connection is a channel over which you can
send data. Session is a logical arrangement on top of that; you can have
multiple sessions on a single connection.)
* read and write 64-byte chunks of data
With that, we introduce ProtocolBasedTransport, which simply delegates
the appropriate Transport functionality to respective Protocol methods.
hid and webusb transports are ProtocolBasedTransport-s that provide separate
device handles. HidHandle and WebUsbHandle existed before, but the distinction
of functionality between a Transport and its Handle was unclear. Some methods
were moved and now the handles implement the Handle API, while the transports
provide the enumeration parts of the Transport API, as well as glue between
the respective Protocols and Handles.
udp transport is also a ProtocolBasedTransport, but it acts as its own handle.
(That might be changed. For now, I went with the pre-existing structure.)
In addition, session_begin/end is renamed to begin/end_session to keep
consistent verb_noun naming.
2018-11-08 14:24:28 +00:00
|
|
|
def find_by_path(cls, path: str, prefix_search: bool = False) -> "UdpTransport":
|
2023-02-02 15:33:57 +00:00
|
|
|
try:
|
2023-03-23 13:53:41 +00:00
|
|
|
address = path.replace(f"{cls.PATH_PREFIX}:", "")
|
|
|
|
return cls._try_path(address)
|
2023-02-02 15:33:57 +00:00
|
|
|
except TransportException:
|
|
|
|
if not prefix_search:
|
|
|
|
raise
|
|
|
|
|
2018-03-02 17:22:33 +00:00
|
|
|
if prefix_search:
|
feat(python): add full type information
WIP - typing the trezorctl apps
typing functions trezorlib/cli
addressing most of mypy issue for trezorlib apps and _internal folder
fixing broken device tests by changing asserts in debuglink.py
addressing most of mypy issues in trezorlib/cli folder
adding types to some untyped functions, mypy section in setup.cfg
typing what can be typed, some mypy fixes, resolving circular import issues
importing type objects in "if TYPE_CHECKING:" branch
fixing CI by removing assert in emulator, better ignore comments
CI assert fix, style fixes, new config options
fixup! CI assert fix, style fixes, new config options
type fixes after rebasing on master
fixing python3.6 and 3.7 unittests by importing Literal from typing_extensions
couple mypy and style fixes
fixes and improvements from code review
silencing all but one mypy issues
trial of typing the tools.expect function
fixup! trial of typing the tools.expect function
@expect and @session decorators correctly type-checked
Optional args in CLI where relevant, not using general list/tuple/dict where possible
python/Makefile commands, adding them into CI, ignoring last mypy issue
documenting overload for expect decorator, two mypy fixes coming from that
black style fix
improved typing of decorators, pyright config file
addressing or ignoring pyright errors, replacing mypy in CI by pyright
fixing incomplete assert causing device tests to fail
pyright issue that showed in CI but not locally, printing pyright version in CI
fixup! pyright issue that showed in CI but not locally, printing pyright version in CI
unifying type:ignore statements for pyright usage
resolving PIL.Image issues, pyrightconfig not excluding anything
replacing couple asserts with TypeGuard on safe_issubclass
better error handling of usb1 import for webusb
better error handling of hid import
small typing details found out by strict pyright mode
improvements from code review
chore(python): changing List to Sequence for protobuf messages
small code changes to reflect the protobuf change to Sequence
importing TypedDict from typing_extensions to support 3.6 and 3.7
simplify _format_access_list function
fixup! simplify _format_access_list function
typing tools folder
typing helper-scripts folder
some click typing
enforcing all functions to have typed arguments
reverting the changed argument name in tools
replacing TransportType with Transport
making PinMatrixRequest.type protobuf attribute required
reverting the protobuf change, making argument into get_pin Optional
small fixes in asserts
solving the session decorator type issues
fixup! solving the session decorator type issues
improvements from code review
fixing new pyright errors introduced after version increase
changing -> Iterable to -> Sequence in enumerate_devices, change in wait_for_devices
style change in debuglink.py
chore(python): adding type annotation to Sequences in messages.py
better "self and cls" types on Transport
fixup! better "self and cls" types on Transport
fixing some easy things from strict pyright run
2021-11-03 22:12:53 +00:00
|
|
|
return super().find_by_path(path, prefix_search)
|
2018-03-02 17:22:33 +00:00
|
|
|
else:
|
2023-02-02 15:33:57 +00:00
|
|
|
raise TransportException(f"No UDP device at {path}")
|
2018-02-02 17:29:20 +00:00
|
|
|
|
2020-01-14 10:30:41 +00:00
|
|
|
def wait_until_ready(self, timeout: float = 10) -> None:
|
|
|
|
try:
|
|
|
|
self.open()
|
|
|
|
start = time.monotonic()
|
|
|
|
while True:
|
|
|
|
if self._ping():
|
|
|
|
break
|
|
|
|
elapsed = time.monotonic() - start
|
|
|
|
if elapsed >= timeout:
|
|
|
|
raise TransportException("Timed out waiting for connection.")
|
|
|
|
|
|
|
|
time.sleep(0.05)
|
|
|
|
finally:
|
|
|
|
self.close()
|
|
|
|
|
trezorlib: transport/protocol reshuffle
This commit breaks session handling (which matters with Bridge) and
regresses Bridge to an older code state. Both of these issues will be
rectified in subsequent commits.
Explanation of this big API reshuffle follows:
* protocols are moved to trezorlib.transport, and to a single common file.
* there is a cleaner definition of Transport and Protocol API (see below)
* fully valid mypy type hinting
* session handle counters and open handle counters mostly went away. Transports
and Protocols are meant to be "raw" APIs; TrezorClient will implement
context-handler-based sessions, session tracking, etc.
I'm calling this a "reshuffle" because it involved very small number of
code changes. Most of it is moving things around where they sit better.
The API changes are as follows.
Transport is now a thing that can:
* open and close sessions
* read and write protobuf messages
* enumerate and find devices
Some transports (all except bridge) are technically bytes-based and need
a separate protocol implementation (because we have two existing protocols,
although only the first one is actually used). Hence a protocol superclass.
Protocol is a thing that *also* can:
* open and close sessions
* read and write protobuf messages
For that, it requires a `handle`.
Handle is a physical layer for a protocol. It can:
* open and close some sort of device connection
(this is distinct from session! Connection is a channel over which you can
send data. Session is a logical arrangement on top of that; you can have
multiple sessions on a single connection.)
* read and write 64-byte chunks of data
With that, we introduce ProtocolBasedTransport, which simply delegates
the appropriate Transport functionality to respective Protocol methods.
hid and webusb transports are ProtocolBasedTransport-s that provide separate
device handles. HidHandle and WebUsbHandle existed before, but the distinction
of functionality between a Transport and its Handle was unclear. Some methods
were moved and now the handles implement the Handle API, while the transports
provide the enumeration parts of the Transport API, as well as glue between
the respective Protocols and Handles.
udp transport is also a ProtocolBasedTransport, but it acts as its own handle.
(That might be changed. For now, I went with the pre-existing structure.)
In addition, session_begin/end is renamed to begin/end_session to keep
consistent verb_noun naming.
2018-11-08 14:24:28 +00:00
|
|
|
def open(self) -> None:
|
2016-04-30 00:37:18 +00:00
|
|
|
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
|
|
self.socket.connect(self.device)
|
2019-10-18 11:32:10 +00:00
|
|
|
self.socket.settimeout(SOCKET_TIMEOUT)
|
2016-04-30 00:37:18 +00:00
|
|
|
|
trezorlib: transport/protocol reshuffle
This commit breaks session handling (which matters with Bridge) and
regresses Bridge to an older code state. Both of these issues will be
rectified in subsequent commits.
Explanation of this big API reshuffle follows:
* protocols are moved to trezorlib.transport, and to a single common file.
* there is a cleaner definition of Transport and Protocol API (see below)
* fully valid mypy type hinting
* session handle counters and open handle counters mostly went away. Transports
and Protocols are meant to be "raw" APIs; TrezorClient will implement
context-handler-based sessions, session tracking, etc.
I'm calling this a "reshuffle" because it involved very small number of
code changes. Most of it is moving things around where they sit better.
The API changes are as follows.
Transport is now a thing that can:
* open and close sessions
* read and write protobuf messages
* enumerate and find devices
Some transports (all except bridge) are technically bytes-based and need
a separate protocol implementation (because we have two existing protocols,
although only the first one is actually used). Hence a protocol superclass.
Protocol is a thing that *also* can:
* open and close sessions
* read and write protobuf messages
For that, it requires a `handle`.
Handle is a physical layer for a protocol. It can:
* open and close some sort of device connection
(this is distinct from session! Connection is a channel over which you can
send data. Session is a logical arrangement on top of that; you can have
multiple sessions on a single connection.)
* read and write 64-byte chunks of data
With that, we introduce ProtocolBasedTransport, which simply delegates
the appropriate Transport functionality to respective Protocol methods.
hid and webusb transports are ProtocolBasedTransport-s that provide separate
device handles. HidHandle and WebUsbHandle existed before, but the distinction
of functionality between a Transport and its Handle was unclear. Some methods
were moved and now the handles implement the Handle API, while the transports
provide the enumeration parts of the Transport API, as well as glue between
the respective Protocols and Handles.
udp transport is also a ProtocolBasedTransport, but it acts as its own handle.
(That might be changed. For now, I went with the pre-existing structure.)
In addition, session_begin/end is renamed to begin/end_session to keep
consistent verb_noun naming.
2018-11-08 14:24:28 +00:00
|
|
|
def close(self) -> None:
|
|
|
|
if self.socket is not None:
|
2017-08-24 12:29:27 +00:00
|
|
|
self.socket.close()
|
trezorlib: transport/protocol reshuffle
This commit breaks session handling (which matters with Bridge) and
regresses Bridge to an older code state. Both of these issues will be
rectified in subsequent commits.
Explanation of this big API reshuffle follows:
* protocols are moved to trezorlib.transport, and to a single common file.
* there is a cleaner definition of Transport and Protocol API (see below)
* fully valid mypy type hinting
* session handle counters and open handle counters mostly went away. Transports
and Protocols are meant to be "raw" APIs; TrezorClient will implement
context-handler-based sessions, session tracking, etc.
I'm calling this a "reshuffle" because it involved very small number of
code changes. Most of it is moving things around where they sit better.
The API changes are as follows.
Transport is now a thing that can:
* open and close sessions
* read and write protobuf messages
* enumerate and find devices
Some transports (all except bridge) are technically bytes-based and need
a separate protocol implementation (because we have two existing protocols,
although only the first one is actually used). Hence a protocol superclass.
Protocol is a thing that *also* can:
* open and close sessions
* read and write protobuf messages
For that, it requires a `handle`.
Handle is a physical layer for a protocol. It can:
* open and close some sort of device connection
(this is distinct from session! Connection is a channel over which you can
send data. Session is a logical arrangement on top of that; you can have
multiple sessions on a single connection.)
* read and write 64-byte chunks of data
With that, we introduce ProtocolBasedTransport, which simply delegates
the appropriate Transport functionality to respective Protocol methods.
hid and webusb transports are ProtocolBasedTransport-s that provide separate
device handles. HidHandle and WebUsbHandle existed before, but the distinction
of functionality between a Transport and its Handle was unclear. Some methods
were moved and now the handles implement the Handle API, while the transports
provide the enumeration parts of the Transport API, as well as glue between
the respective Protocols and Handles.
udp transport is also a ProtocolBasedTransport, but it acts as its own handle.
(That might be changed. For now, I went with the pre-existing structure.)
In addition, session_begin/end is renamed to begin/end_session to keep
consistent verb_noun naming.
2018-11-08 14:24:28 +00:00
|
|
|
self.socket = None
|
2016-04-30 00:37:18 +00:00
|
|
|
|
trezorlib: transport/protocol reshuffle
This commit breaks session handling (which matters with Bridge) and
regresses Bridge to an older code state. Both of these issues will be
rectified in subsequent commits.
Explanation of this big API reshuffle follows:
* protocols are moved to trezorlib.transport, and to a single common file.
* there is a cleaner definition of Transport and Protocol API (see below)
* fully valid mypy type hinting
* session handle counters and open handle counters mostly went away. Transports
and Protocols are meant to be "raw" APIs; TrezorClient will implement
context-handler-based sessions, session tracking, etc.
I'm calling this a "reshuffle" because it involved very small number of
code changes. Most of it is moving things around where they sit better.
The API changes are as follows.
Transport is now a thing that can:
* open and close sessions
* read and write protobuf messages
* enumerate and find devices
Some transports (all except bridge) are technically bytes-based and need
a separate protocol implementation (because we have two existing protocols,
although only the first one is actually used). Hence a protocol superclass.
Protocol is a thing that *also* can:
* open and close sessions
* read and write protobuf messages
For that, it requires a `handle`.
Handle is a physical layer for a protocol. It can:
* open and close some sort of device connection
(this is distinct from session! Connection is a channel over which you can
send data. Session is a logical arrangement on top of that; you can have
multiple sessions on a single connection.)
* read and write 64-byte chunks of data
With that, we introduce ProtocolBasedTransport, which simply delegates
the appropriate Transport functionality to respective Protocol methods.
hid and webusb transports are ProtocolBasedTransport-s that provide separate
device handles. HidHandle and WebUsbHandle existed before, but the distinction
of functionality between a Transport and its Handle was unclear. Some methods
were moved and now the handles implement the Handle API, while the transports
provide the enumeration parts of the Transport API, as well as glue between
the respective Protocols and Handles.
udp transport is also a ProtocolBasedTransport, but it acts as its own handle.
(That might be changed. For now, I went with the pre-existing structure.)
In addition, session_begin/end is renamed to begin/end_session to keep
consistent verb_noun naming.
2018-11-08 14:24:28 +00:00
|
|
|
def _ping(self) -> bool:
|
2018-08-13 16:21:24 +00:00
|
|
|
"""Test if the device is listening."""
|
trezorlib: transport/protocol reshuffle
This commit breaks session handling (which matters with Bridge) and
regresses Bridge to an older code state. Both of these issues will be
rectified in subsequent commits.
Explanation of this big API reshuffle follows:
* protocols are moved to trezorlib.transport, and to a single common file.
* there is a cleaner definition of Transport and Protocol API (see below)
* fully valid mypy type hinting
* session handle counters and open handle counters mostly went away. Transports
and Protocols are meant to be "raw" APIs; TrezorClient will implement
context-handler-based sessions, session tracking, etc.
I'm calling this a "reshuffle" because it involved very small number of
code changes. Most of it is moving things around where they sit better.
The API changes are as follows.
Transport is now a thing that can:
* open and close sessions
* read and write protobuf messages
* enumerate and find devices
Some transports (all except bridge) are technically bytes-based and need
a separate protocol implementation (because we have two existing protocols,
although only the first one is actually used). Hence a protocol superclass.
Protocol is a thing that *also* can:
* open and close sessions
* read and write protobuf messages
For that, it requires a `handle`.
Handle is a physical layer for a protocol. It can:
* open and close some sort of device connection
(this is distinct from session! Connection is a channel over which you can
send data. Session is a logical arrangement on top of that; you can have
multiple sessions on a single connection.)
* read and write 64-byte chunks of data
With that, we introduce ProtocolBasedTransport, which simply delegates
the appropriate Transport functionality to respective Protocol methods.
hid and webusb transports are ProtocolBasedTransport-s that provide separate
device handles. HidHandle and WebUsbHandle existed before, but the distinction
of functionality between a Transport and its Handle was unclear. Some methods
were moved and now the handles implement the Handle API, while the transports
provide the enumeration parts of the Transport API, as well as glue between
the respective Protocols and Handles.
udp transport is also a ProtocolBasedTransport, but it acts as its own handle.
(That might be changed. For now, I went with the pre-existing structure.)
In addition, session_begin/end is renamed to begin/end_session to keep
consistent verb_noun naming.
2018-11-08 14:24:28 +00:00
|
|
|
assert self.socket is not None
|
2018-02-02 17:29:20 +00:00
|
|
|
resp = None
|
|
|
|
try:
|
2018-08-13 16:21:24 +00:00
|
|
|
self.socket.sendall(b"PINGPING")
|
2018-02-02 17:29:20 +00:00
|
|
|
resp = self.socket.recv(8)
|
2018-08-10 14:05:14 +00:00
|
|
|
except Exception:
|
2018-02-02 17:29:20 +00:00
|
|
|
pass
|
2018-08-13 16:21:24 +00:00
|
|
|
return resp == b"PONGPONG"
|
2018-02-02 17:29:20 +00:00
|
|
|
|
trezorlib: transport/protocol reshuffle
This commit breaks session handling (which matters with Bridge) and
regresses Bridge to an older code state. Both of these issues will be
rectified in subsequent commits.
Explanation of this big API reshuffle follows:
* protocols are moved to trezorlib.transport, and to a single common file.
* there is a cleaner definition of Transport and Protocol API (see below)
* fully valid mypy type hinting
* session handle counters and open handle counters mostly went away. Transports
and Protocols are meant to be "raw" APIs; TrezorClient will implement
context-handler-based sessions, session tracking, etc.
I'm calling this a "reshuffle" because it involved very small number of
code changes. Most of it is moving things around where they sit better.
The API changes are as follows.
Transport is now a thing that can:
* open and close sessions
* read and write protobuf messages
* enumerate and find devices
Some transports (all except bridge) are technically bytes-based and need
a separate protocol implementation (because we have two existing protocols,
although only the first one is actually used). Hence a protocol superclass.
Protocol is a thing that *also* can:
* open and close sessions
* read and write protobuf messages
For that, it requires a `handle`.
Handle is a physical layer for a protocol. It can:
* open and close some sort of device connection
(this is distinct from session! Connection is a channel over which you can
send data. Session is a logical arrangement on top of that; you can have
multiple sessions on a single connection.)
* read and write 64-byte chunks of data
With that, we introduce ProtocolBasedTransport, which simply delegates
the appropriate Transport functionality to respective Protocol methods.
hid and webusb transports are ProtocolBasedTransport-s that provide separate
device handles. HidHandle and WebUsbHandle existed before, but the distinction
of functionality between a Transport and its Handle was unclear. Some methods
were moved and now the handles implement the Handle API, while the transports
provide the enumeration parts of the Transport API, as well as glue between
the respective Protocols and Handles.
udp transport is also a ProtocolBasedTransport, but it acts as its own handle.
(That might be changed. For now, I went with the pre-existing structure.)
In addition, session_begin/end is renamed to begin/end_session to keep
consistent verb_noun naming.
2018-11-08 14:24:28 +00:00
|
|
|
def write_chunk(self, chunk: bytes) -> None:
|
|
|
|
assert self.socket is not None
|
2017-08-24 12:29:27 +00:00
|
|
|
if len(chunk) != 64:
|
2018-08-13 16:21:24 +00:00
|
|
|
raise TransportException("Unexpected data length")
|
2021-09-27 10:13:51 +00:00
|
|
|
LOG.log(DUMP_PACKETS, f"sending packet: {chunk.hex()}")
|
2016-06-26 19:29:29 +00:00
|
|
|
self.socket.sendall(chunk)
|
|
|
|
|
trezorlib: transport/protocol reshuffle
This commit breaks session handling (which matters with Bridge) and
regresses Bridge to an older code state. Both of these issues will be
rectified in subsequent commits.
Explanation of this big API reshuffle follows:
* protocols are moved to trezorlib.transport, and to a single common file.
* there is a cleaner definition of Transport and Protocol API (see below)
* fully valid mypy type hinting
* session handle counters and open handle counters mostly went away. Transports
and Protocols are meant to be "raw" APIs; TrezorClient will implement
context-handler-based sessions, session tracking, etc.
I'm calling this a "reshuffle" because it involved very small number of
code changes. Most of it is moving things around where they sit better.
The API changes are as follows.
Transport is now a thing that can:
* open and close sessions
* read and write protobuf messages
* enumerate and find devices
Some transports (all except bridge) are technically bytes-based and need
a separate protocol implementation (because we have two existing protocols,
although only the first one is actually used). Hence a protocol superclass.
Protocol is a thing that *also* can:
* open and close sessions
* read and write protobuf messages
For that, it requires a `handle`.
Handle is a physical layer for a protocol. It can:
* open and close some sort of device connection
(this is distinct from session! Connection is a channel over which you can
send data. Session is a logical arrangement on top of that; you can have
multiple sessions on a single connection.)
* read and write 64-byte chunks of data
With that, we introduce ProtocolBasedTransport, which simply delegates
the appropriate Transport functionality to respective Protocol methods.
hid and webusb transports are ProtocolBasedTransport-s that provide separate
device handles. HidHandle and WebUsbHandle existed before, but the distinction
of functionality between a Transport and its Handle was unclear. Some methods
were moved and now the handles implement the Handle API, while the transports
provide the enumeration parts of the Transport API, as well as glue between
the respective Protocols and Handles.
udp transport is also a ProtocolBasedTransport, but it acts as its own handle.
(That might be changed. For now, I went with the pre-existing structure.)
In addition, session_begin/end is renamed to begin/end_session to keep
consistent verb_noun naming.
2018-11-08 14:24:28 +00:00
|
|
|
def read_chunk(self) -> bytes:
|
|
|
|
assert self.socket is not None
|
2016-07-14 13:57:05 +00:00
|
|
|
while True:
|
|
|
|
try:
|
2017-08-24 12:29:27 +00:00
|
|
|
chunk = self.socket.recv(64)
|
2016-07-14 13:57:05 +00:00
|
|
|
break
|
|
|
|
except socket.timeout:
|
|
|
|
continue
|
2021-09-27 10:13:51 +00:00
|
|
|
LOG.log(DUMP_PACKETS, f"received packet: {chunk.hex()}")
|
2017-08-24 12:29:27 +00:00
|
|
|
if len(chunk) != 64:
|
2021-09-27 10:13:51 +00:00
|
|
|
raise TransportException(f"Unexpected chunk size: {len(chunk)}")
|
2017-08-24 12:29:27 +00:00
|
|
|
return bytearray(chunk)
|