mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-30 03:18:20 +00:00
parent
17435cf174
commit
c935b51849
10
trezorctl
10
trezorctl
@ -1,5 +1,6 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
import sys
|
||||||
import os
|
import os
|
||||||
import binascii
|
import binascii
|
||||||
import argparse
|
import argparse
|
||||||
@ -9,9 +10,8 @@ import tempfile
|
|||||||
from trezorlib import types_pb2 as types
|
from trezorlib import types_pb2 as types
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from trezorlib.client import TrezorClient, TrezorClientDebug, CallException
|
from trezorlib.client import TrezorClient, TrezorClientDebug, CallException
|
||||||
|
import trezorlib.types_pb2 as types
|
||||||
|
|
||||||
ether_units = {
|
ether_units = {
|
||||||
"wei": 1,
|
"wei": 1,
|
||||||
@ -218,8 +218,11 @@ class Commands(object):
|
|||||||
return self.client.wipe_device()
|
return self.client.wipe_device()
|
||||||
|
|
||||||
def recovery_device(self, args):
|
def recovery_device(self, args):
|
||||||
|
typemap = { 'scrambled': types.RecoveryDeviceType_ScrambledWords,
|
||||||
|
'matrix': types.RecoveryDeviceType_Matrix }
|
||||||
return self.client.recovery_device(args.words, args.passphrase_protection,
|
return self.client.recovery_device(args.words, args.passphrase_protection,
|
||||||
args.pin_protection, args.label, 'english')
|
args.pin_protection, args.label, 'english',
|
||||||
|
typemap[args.type])
|
||||||
|
|
||||||
def load_device(self, args):
|
def load_device(self, args):
|
||||||
if not args.mnemonic and not args.xprv:
|
if not args.mnemonic and not args.xprv:
|
||||||
@ -403,6 +406,7 @@ class Commands(object):
|
|||||||
(('-p', '--pin-protection'), {'action': 'store_true', 'default': False}),
|
(('-p', '--pin-protection'), {'action': 'store_true', 'default': False}),
|
||||||
(('-r', '--passphrase-protection'), {'action': 'store_true', 'default': False}),
|
(('-r', '--passphrase-protection'), {'action': 'store_true', 'default': False}),
|
||||||
(('-l', '--label'), {'type': str, 'default': ''}),
|
(('-l', '--label'), {'type': str, 'default': ''}),
|
||||||
|
(('-t', '--type'), {'type': str, 'choices': ['scrambled', 'matrix'], 'default': 'matrix'}),
|
||||||
)
|
)
|
||||||
|
|
||||||
load_device.arguments = (
|
load_device.arguments = (
|
||||||
|
@ -30,6 +30,29 @@ DEFAULT_CURVE = 'secp256k1'
|
|||||||
# monkeypatching: text formatting of protobuf messages
|
# monkeypatching: text formatting of protobuf messages
|
||||||
tools.monkeypatch_google_protobuf_text_format()
|
tools.monkeypatch_google_protobuf_text_format()
|
||||||
|
|
||||||
|
|
||||||
|
def getch():
|
||||||
|
try:
|
||||||
|
import termios
|
||||||
|
except ImportError:
|
||||||
|
# Non-POSIX. Return msvcrt's (Windows') getch.
|
||||||
|
import msvcrt
|
||||||
|
return msvcrt.getch()
|
||||||
|
|
||||||
|
# POSIX system. Create and return a getch that manipulates the tty.
|
||||||
|
import sys, tty
|
||||||
|
def _getch():
|
||||||
|
fd = sys.stdin.fileno()
|
||||||
|
old_settings = termios.tcgetattr(fd)
|
||||||
|
try:
|
||||||
|
tty.setraw(fd)
|
||||||
|
ch = sys.stdin.read(1)
|
||||||
|
finally:
|
||||||
|
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
|
||||||
|
return ch
|
||||||
|
|
||||||
|
return _getch()
|
||||||
|
|
||||||
def get_buttonrequest_value(code):
|
def get_buttonrequest_value(code):
|
||||||
# Converts integer code to its string representation of ButtonRequestType
|
# Converts integer code to its string representation of ButtonRequestType
|
||||||
return [ k for k, v in types.ButtonRequestType.items() if v == code][0]
|
return [ k for k, v in types.ButtonRequestType.items() if v == code][0]
|
||||||
@ -174,6 +197,29 @@ class TextUIMixin(object):
|
|||||||
# log("Sending ButtonAck for %s " % get_buttonrequest_value(msg.code))
|
# log("Sending ButtonAck for %s " % get_buttonrequest_value(msg.code))
|
||||||
return proto.ButtonAck()
|
return proto.ButtonAck()
|
||||||
|
|
||||||
|
def callback_RecoveryMatrix(self, msg):
|
||||||
|
if self.recovery_matrix_first_pass:
|
||||||
|
self.recovery_matrix_first_pass = False
|
||||||
|
log("Use the numeric keypad to describe positions. For the word list use only left and right keys. The layout is:")
|
||||||
|
log(" 7 8 9 7 | 9")
|
||||||
|
log(" 4 5 6 4 | 6")
|
||||||
|
log(" 1 2 3 1 | 3")
|
||||||
|
while True:
|
||||||
|
character = getch()
|
||||||
|
if character in ('\x03', '\x04'):
|
||||||
|
return proto.Cancel()
|
||||||
|
|
||||||
|
if character in ('\x08', '\x7f'):
|
||||||
|
return proto.WordAck(word='\x08')
|
||||||
|
|
||||||
|
# ignore middle column if only 6 keys requested.
|
||||||
|
if (msg.type == types.WordRequestType_Matrix6 and
|
||||||
|
character in ('2', '5', '8')):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if (ord(character) >= ord('1') and ord(character) <= ord('9')):
|
||||||
|
return proto.WordAck(word=character)
|
||||||
|
|
||||||
def callback_PinMatrixRequest(self, msg):
|
def callback_PinMatrixRequest(self, msg):
|
||||||
if msg.type == 1:
|
if msg.type == 1:
|
||||||
desc = 'current PIN'
|
desc = 'current PIN'
|
||||||
@ -204,6 +250,9 @@ class TextUIMixin(object):
|
|||||||
exit()
|
exit()
|
||||||
|
|
||||||
def callback_WordRequest(self, msg):
|
def callback_WordRequest(self, msg):
|
||||||
|
if msg.type in (types.WordRequestType_Matrix9,
|
||||||
|
types.WordRequestType_Matrix6):
|
||||||
|
return self.callback_RecoveryMatrix(msg)
|
||||||
log("Enter one word of mnemonic: ")
|
log("Enter one word of mnemonic: ")
|
||||||
try:
|
try:
|
||||||
word = raw_input()
|
word = raw_input()
|
||||||
@ -741,19 +790,21 @@ class ProtocolMixin(object):
|
|||||||
|
|
||||||
@field('message')
|
@field('message')
|
||||||
@expect(proto.Success)
|
@expect(proto.Success)
|
||||||
def recovery_device(self, word_count, passphrase_protection, pin_protection, label, language):
|
def recovery_device(self, word_count, passphrase_protection, pin_protection, label, language, type=types.RecoveryDeviceType_Matrix):
|
||||||
if self.features.initialized:
|
if self.features.initialized:
|
||||||
raise Exception("Device is initialized already. Call wipe_device() and try again.")
|
raise Exception("Device is initialized already. Call wipe_device() and try again.")
|
||||||
|
|
||||||
if word_count not in (12, 18, 24):
|
if word_count not in (12, 18, 24):
|
||||||
raise Exception("Invalid word count. Use 12/18/24")
|
raise Exception("Invalid word count. Use 12/18/24")
|
||||||
|
|
||||||
|
self.recovery_matrix_first_pass = True
|
||||||
res = self.call(proto.RecoveryDevice(word_count=int(word_count),
|
res = self.call(proto.RecoveryDevice(word_count=int(word_count),
|
||||||
passphrase_protection=bool(passphrase_protection),
|
passphrase_protection=bool(passphrase_protection),
|
||||||
pin_protection=bool(pin_protection),
|
pin_protection=bool(pin_protection),
|
||||||
label=label,
|
label=label,
|
||||||
language=language,
|
language=language,
|
||||||
enforce_wordlist=True))
|
enforce_wordlist=True,
|
||||||
|
type=type))
|
||||||
|
|
||||||
self.init_device()
|
self.init_device()
|
||||||
return res
|
return res
|
||||||
|
Loading…
Reference in New Issue
Block a user