Skip to content

Instantly share code, notes, and snippets.

@justinmoon
Last active August 13, 2019 04:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justinmoon/bfe2b76935f54c344c833c802060c7a7 to your computer and use it in GitHub Desktop.
Save justinmoon/bfe2b76935f54c344c833c802060c7a7 to your computer and use it in GitHub Desktop.
Issue unlocking a trezor
from flask import Flask, render_template_string, request, redirect
from hwilib import commands
from hwilib.devices import trezor
app = Flask(__name__)
template = """
<div>Locked? {{ locked }}</div>
<form action="/" method="post">
<label for="pin">Pin:</label>
<input type="text" id="pin" name="pin">
<button type="submit">Unlock Trezor</button>
</form>
"""
@app.route('/', methods=['GET', 'POST'])
def home():
devices = commands.enumerate()
if request.method == 'GET':
for device in devices:
if device['type'] == 'trezor':
locked = device['needs_pin_sent']
if locked:
client = trezor.TrezorClient(device['path'])
client.prompt_pin()
break
return render_template_string(template, locked=locked)
else:
for device in devices:
if device['type'] == 'trezor':
client = trezor.TrezorClient(device['path'])
result = client.send_pin(request.form['pin'])['success']
print("Unlocked?", result)
return redirect('/')
if __name__ == '__main__':
app.run()
from hwilib import commands
from hwilib.devices import trezor
devices = commands.enumerate()
for device in devices:
if device['type'] == 'trezor':
client = trezor.TrezorClient(device['path'])
print(device['path'])
client.prompt_pin()
pin = input('enter pin: ')
print(client.send_pin(pin))
@justinmoon
Copy link
Author

justinmoon commented Aug 12, 2019

This works:

from hwilib import commands
from hwilib.devices import trezor

devices = commands.enumerate()

for device in devices:
    if device['type'] == 'trezor':
        client = trezor.TrezorClient(device['path'])
        print(device['path'])

client.prompt_pin()
# del client

pin = input('enter pin: ')
print(repr(pin))

devices = commands.enumerate()
for device in devices:
    if device['type'] == 'trezor':
        print(device['path'])
        client = trezor.TrezorClient(device['path'])

print(client.send_pin(pin))

But if you uncomment the del client it fails in exactly the same way as the UI.

Also, this works:

from flask import Flask, render_template_string, request, redirect
from hwilib import commands
from hwilib.devices import trezor

app = Flask(__name__)

template = """
<div>Locked? {{ locked }}</div>
<form action="/" method="post">
    <label for="pin">Pin:</label>
    <input type="text" id="pin" name="pin">
    <button type="submit">Unlock Trezor</button>
</form>
"""

devices = commands.enumerate()
for device in devices:
    if device['type'] == 'trezor':
        client = trezor.TrezorClient(device['path'])
        break

@app.route('/', methods=['GET', 'POST'])
def home():
    devices = commands.enumerate()
    if request.method == 'GET':
        for device in devices:
            if device['type'] == 'trezor':
                locked = device.get('needs_pin_sent', False)
                if locked:
                    client.prompt_pin()
                break
        return render_template_string(template, locked=locked)
    else:
        for device in devices:
            if device['type'] == 'trezor':
                result = client.send_pin(request.form['pin'])['success']
                print('success?', result)
        return redirect('/')

if __name__ == '__main__':
    app.run()

Just has 1 TrezorClient instance.

So in some circumstances you can re-instantiate the TrezorClient (cli.py here) but you can't delete the client prompted the pin, re-instantiate and send the pin.

@justinmoon
Copy link
Author

Threading problem if anyone ever comes across this. Flask runs handlers in threads by default and HWI isn't thread-safe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment