Browse Source

ledger: fix compat with hw.1 - signing flow deadlocked

broke in 8a1b46d839ac24f77bfa5e3a1eed0cb7284b59eac5b685854c517f224c98dc44
patch-4
SomberNight 5 years ago
parent
commit
200f547a07
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 8
      electrum/plugins/ledger/auth2fa.py
  2. 16
      electrum/plugins/ledger/ledger.py
  3. 12
      electrum/plugins/ledger/qt.py

8
electrum/plugins/ledger/auth2fa.py

@ -1,4 +1,5 @@
import copy
from typing import TYPE_CHECKING
from PyQt5.QtWidgets import (QDialog, QLineEdit, QTextEdit, QVBoxLayout, QLabel,
QWidget, QHBoxLayout, QComboBox)
@ -11,6 +12,9 @@ from electrum.i18n import _
from electrum import constants, bitcoin
from electrum.logging import get_logger
if TYPE_CHECKING:
from .ledger import Ledger_Client
_logger = get_logger(__name__)
@ -27,7 +31,7 @@ helpTxt = [_("Your Ledger Wallet wants to tell you a one-time PIN code.<br><br>"
]
class LedgerAuthDialog(QDialog):
def __init__(self, handler, data):
def __init__(self, handler, data, *, client: 'Ledger_Client'):
'''Ask user for 2nd factor authentication. Support text and security card methods.
Use last method from settings, but support downgrade.
'''
@ -38,7 +42,7 @@ class LedgerAuthDialog(QDialog):
self.setMinimumWidth(650)
self.setWindowTitle(_("Ledger Wallet Authentication"))
self.cfg = copy.deepcopy(self.handler.win.wallet.get_keystore().cfg)
self.dongle = self.handler.win.wallet.get_keystore().get_client().dongle
self.dongle = client.dongleObject.dongle
self.pin = ''
self.devmode = self.getDevice2FAMode()

16
electrum/plugins/ledger/ledger.py

@ -300,18 +300,20 @@ class Ledger_KeyStore(Hardware_KeyStore):
message = message.encode('utf8')
message_hash = hashlib.sha256(message).hexdigest().upper()
# prompt for the PIN before displaying the dialog if necessary
client = self.get_client()
client_ledger = self.get_client()
client_electrum = self.get_client_electrum()
address_path = self.get_derivation_prefix()[2:] + "/%d/%d"%sequence
self.handler.show_message("Signing message ...\r\nMessage hash: "+message_hash)
try:
info = self.get_client().signMessagePrepare(address_path, message)
info = client_ledger.signMessagePrepare(address_path, message)
pin = ""
if info['confirmationNeeded']:
pin = self.handler.get_auth( info ) # does the authenticate dialog and returns pin
# do the authenticate dialog and get pin:
pin = self.handler.get_auth(info, client=client_electrum)
if not pin:
raise UserWarning(_('Cancelled by user'))
pin = str(pin).encode()
signature = self.get_client().signMessageSign(pin)
signature = client_ledger.signMessageSign(pin)
except BTChipException as e:
if e.sw == 0x6a80:
self.give_error("Unfortunately, this message cannot be signed by the Ledger wallet. Only alphanumerical messages shorter than 140 characters are supported. Please remove any extra characters (tab, carriage return) and retry.")
@ -484,7 +486,8 @@ class Ledger_KeyStore(Hardware_KeyStore):
if outputData['confirmationNeeded']:
outputData['address'] = output
self.handler.finished()
pin = self.handler.get_auth( outputData ) # does the authenticate dialog and returns pin
# do the authenticate dialog and get pin:
pin = self.handler.get_auth(outputData, client=client_electrum)
if not pin:
raise UserWarning()
self.handler.show_message(_("Confirmed. Signing Transaction..."))
@ -510,7 +513,8 @@ class Ledger_KeyStore(Hardware_KeyStore):
if outputData['confirmationNeeded']:
outputData['address'] = output
self.handler.finished()
pin = self.handler.get_auth( outputData ) # does the authenticate dialog and returns pin
# do the authenticate dialog and get pin:
pin = self.handler.get_auth(outputData, client=client_electrum)
if not pin:
raise UserWarning()
self.handler.show_message(_("Confirmed. Signing Transaction..."))

12
electrum/plugins/ledger/qt.py

@ -8,7 +8,7 @@ from electrum.plugin import hook
from electrum.wallet import Standard_Wallet
from electrum.gui.qt.util import WindowModalDialog
from .ledger import LedgerPlugin
from .ledger import LedgerPlugin, Ledger_Client
from ..hw_wallet.qt import QtHandlerBase, QtPluginBase
from ..hw_wallet.plugin import only_hook_if_libraries_available
@ -33,7 +33,7 @@ class Plugin(LedgerPlugin, QtPluginBase):
class Ledger_Handler(QtHandlerBase):
setup_signal = pyqtSignal()
auth_signal = pyqtSignal(object)
auth_signal = pyqtSignal(object, object)
def __init__(self, win):
super(Ledger_Handler, self).__init__(win, 'Ledger')
@ -56,20 +56,20 @@ class Ledger_Handler(QtHandlerBase):
vbox.addWidget(l)
dialog.show()
def auth_dialog(self, data):
def auth_dialog(self, data, client: 'Ledger_Client'):
try:
from .auth2fa import LedgerAuthDialog
except ImportError as e:
self.message_dialog(repr(e))
return
dialog = LedgerAuthDialog(self, data)
dialog = LedgerAuthDialog(self, data, client=client)
dialog.exec_()
self.word = dialog.pin
self.done.set()
def get_auth(self, data):
def get_auth(self, data, *, client: 'Ledger_Client'):
self.done.clear()
self.auth_signal.emit(data)
self.auth_signal.emit(data, client)
self.done.wait()
return self.word

Loading…
Cancel
Save