/** * Perform the unlock (if necessary). The passphrase must be correct if the * wallet is actually locked, and can be anything else. * @param passphrase Passphrase to use for unlocking. * @throws UnlockFailure if the passphrase is wrong. */ void CoinInterface::WalletUnlocker::unlock (const std::string& passphrase) { if (unlocked) throw std::runtime_error ("Wallet is already unlocked!"); const bool needPwd = nc.needWalletPassphrase (); if (needPwd) { /* Empty password is a special case, because it is not handled correctly by the walletpassphrase RPC call. Thus catch this case right now and fail as if the passphrase would have been wrong. */ if (passphrase.empty ()) throw UnlockFailure ("Wallet passphrase cannot be empty."); /* Ensure the wallet is indeed locked before we send the passphrase. It could be the case that it is unlocked although for too short a time, then lock it now. */ rpc.executeRpc ("walletlock"); try { rpc.disableLoggingOneShot (); rpc.executeRpc ("walletpassphrase", passphrase, UNLOCK_SECONDS); unlocked = true; } catch (const JsonRpc::RpcError& exc) { if (exc.getErrorCode () == -14) throw UnlockFailure ("Wrong wallet passphrase."); throw exc; } } }
/** * Try to unlock the wallet. If a passphrase is needed, a dialog is shown * until the correct one is entered or the user cancels the action. In the * latter case, UnlockFailure is thrown. * @throws UnlockFailure if the user cancels the unlock. */ void NMC_WalletUnlocker::unlock () { std::string pwd; qDebug () << "Trying to unlock the Namecoin wallet."; /* If we need a password, show the dialog. */ if (nc.needWalletPassphrase ()) { OTPassword otPwd; MTDlgPassword dlg (nullptr, otPwd); dlg.setDisplay ("Your Namecoin wallet is locked. For the operations to" " proceed, please enter the passphrase to temporarily" " unlock the wallet."); const int res = dlg.exec (); /* Return code is 0 for cancel button or closing the window. It is 1 in case of ok. */ if (res == 0) { qDebug () << "Wallet unlock was cancelled."; throw UnlockFailure("Wallet unlock was cancelled."); } dlg.extractPassword (); pwd = otPwd.getPassword (); } /* Now try to unlock. If the passphrase is wrong, retry by a tail-recursive call to unlock(). */ try { unlocker.unlock (pwd); qDebug () << "Unlock successful (or not necessary)."; } catch (const nmcrpc::NamecoinInterface::UnlockFailure& exc) { qDebug () << "Wrong passphrase, retrying."; unlock (); } catch (const nmcrpc::JsonRpc::RpcError& exc) { qDebug () << "NMC RPC Error " << exc.getErrorCode () << ": " << exc.getErrorMessage ().c_str (); } catch (const std::exception& exc) { qDebug () << "Error: " << exc.what (); } }