Gav Wood
10 years ago
8 changed files with 544 additions and 10 deletions
@ -0,0 +1,181 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum 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 General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/** @file ImportKey.cpp
|
||||
|
* @author Gav Wood <i@gavwood.com> |
||||
|
* @date 2015 |
||||
|
*/ |
||||
|
|
||||
|
#include "ImportKey.h" |
||||
|
#include <QFileDialog> |
||||
|
#include <QMessageBox> |
||||
|
#include <QInputDialog> |
||||
|
#include <libdevcore/Log.h> |
||||
|
#include <libethcore/KeyManager.h> |
||||
|
#include <libethcore/ICAP.h> |
||||
|
#include <libethereum/Client.h> |
||||
|
#include "ui_ImportKey.h" |
||||
|
using namespace std; |
||||
|
using namespace dev; |
||||
|
using namespace az; |
||||
|
using namespace eth; |
||||
|
|
||||
|
DEV_AZ_NOTE_PLUGIN(ImportKey); |
||||
|
|
||||
|
ImportKey::ImportKey(MainFace* _m): |
||||
|
Plugin(_m, "ImportKey") |
||||
|
{ |
||||
|
connect(addMenuItem("Import Key...", "menuTools", true), SIGNAL(triggered()), SLOT(import())); |
||||
|
} |
||||
|
|
||||
|
ImportKey::~ImportKey() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
void ImportKey::import() |
||||
|
{ |
||||
|
QDialog d; |
||||
|
Ui_ImportKey u; |
||||
|
u.setupUi(&d); |
||||
|
d.setWindowTitle("Import Key"); |
||||
|
|
||||
|
string lastKey; |
||||
|
Secret lastSecret; |
||||
|
string lastPassword; |
||||
|
|
||||
|
auto updateImport = [&](){ |
||||
|
u.import_2->setDisabled(u.addressOut->text().isEmpty() || u.name->text().isEmpty()); |
||||
|
}; |
||||
|
|
||||
|
auto updateAddress = [&](){ |
||||
|
string as = u.address->text().toStdString(); |
||||
|
try |
||||
|
{ |
||||
|
u.addressOut->setText(QString::fromStdString(main()->render(eth::toAddress(as)))); |
||||
|
} |
||||
|
catch (...) |
||||
|
{ |
||||
|
u.addressOut->setText(""); |
||||
|
} |
||||
|
updateImport(); |
||||
|
}; |
||||
|
|
||||
|
auto updatePassword = [&](){ |
||||
|
u.passwordHash->setText(QString::fromStdString(sha3(u.password->text().toStdString()).hex())); |
||||
|
}; |
||||
|
|
||||
|
function<void()> updateKey = [&](){ |
||||
|
// update according to key.
|
||||
|
if (lastKey == u.key->text().toStdString()) |
||||
|
return; |
||||
|
lastKey = u.key->text().toStdString(); |
||||
|
lastSecret.clear(); |
||||
|
u.address->clear(); |
||||
|
u.oldPassword->setEnabled(false); |
||||
|
u.oldPassword->setChecked(false); |
||||
|
bytes b; |
||||
|
DEV_IGNORE_EXCEPTIONS(b = fromHex(lastKey, WhenError::Throw)); |
||||
|
if (b.size() == 32) |
||||
|
{ |
||||
|
lastSecret = Secret(b); |
||||
|
bytesRef(&b).cleanse(); |
||||
|
} |
||||
|
while (!lastKey.empty() && !lastSecret) |
||||
|
{ |
||||
|
bool ok; |
||||
|
lastPassword = QInputDialog::getText(&d, "Open Key File", "Enter the password protecting this key file. Cancel if you do not want to provide te password.", QLineEdit::Password, QString(), &ok).toStdString(); |
||||
|
if (!ok) |
||||
|
{ |
||||
|
lastSecret.clear(); |
||||
|
break; |
||||
|
} |
||||
|
// Try to open as a file.
|
||||
|
lastSecret = KeyManager::presaleSecret(contentsString(lastKey), [&](bool first){ return first ? lastPassword : string(); }).secret(); |
||||
|
if (!lastSecret) |
||||
|
lastSecret = Secret(SecretStore::secret(contentsString(lastKey), lastPassword)); |
||||
|
if (!lastSecret && QMessageBox::warning(&d, "Invalid Password or Key File", "The given password could not be used to decrypt the key file given. Are you sure it is a valid key file and that the password is correct?", QMessageBox::Abort, QMessageBox::Retry) == QMessageBox::Abort) |
||||
|
{ |
||||
|
u.key->clear(); |
||||
|
updateKey(); |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
u.oldPassword->setEnabled(!!lastSecret); |
||||
|
u.newPassword->setEnabled(!!lastSecret); |
||||
|
u.noPassword->setEnabled(!!lastSecret); |
||||
|
u.password->setEnabled(!!lastSecret); |
||||
|
u.passwordHash->setReadOnly(!!lastSecret); |
||||
|
u.address->setReadOnly(!lastSecret); |
||||
|
if (lastSecret) |
||||
|
{ |
||||
|
u.oldPassword->setEnabled(!lastPassword.empty()); |
||||
|
if (lastPassword.empty()) |
||||
|
u.oldPassword->setChecked(false); |
||||
|
u.address->setText(QString::fromStdString(ICAP(toAddress(lastSecret)).encoded())); |
||||
|
updateAddress(); |
||||
|
} |
||||
|
else |
||||
|
u.address->clear(); |
||||
|
}; |
||||
|
|
||||
|
connect(u.noPassword, &QRadioButton::clicked, [&](){ |
||||
|
u.passwordHash->clear(); |
||||
|
u.hint->setText("Same as master password."); |
||||
|
}); |
||||
|
connect(u.oldPassword, &QRadioButton::clicked, [&](){ |
||||
|
u.passwordHash->setText(QString::fromStdString(sha3(lastPassword).hex())); |
||||
|
u.hint->setText("Same as original password for file " + QString::fromStdString(lastKey)); |
||||
|
}); |
||||
|
connect(u.newPassword, &QRadioButton::clicked, [&](){ |
||||
|
u.hint->setText(""); |
||||
|
updatePassword(); |
||||
|
}); |
||||
|
connect(u.password, &QLineEdit::textChanged, [&](){ updatePassword(); }); |
||||
|
connect(u.address, &QLineEdit::textChanged, [&](){ updateAddress(); }); |
||||
|
connect(u.key, &QLineEdit::textEdited, [&](){ updateKey(); }); |
||||
|
connect(u.name, &QLineEdit::textEdited, [&](){ updateImport(); }); |
||||
|
connect(u.openKey, &QToolButton::clicked, [&](){ |
||||
|
QString fn = QFileDialog::getOpenFileName(main(), "Open Key File", QDir::homePath(), "JSON Files (*.json);;All Files (*)"); |
||||
|
if (!fn.isEmpty()) |
||||
|
{ |
||||
|
u.key->setText(fn); |
||||
|
updateKey(); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
if (d.exec() == QDialog::Accepted) |
||||
|
{ |
||||
|
Address a = ICAP::decoded(u.addressOut->text().toStdString()).direct(); |
||||
|
string n = u.name->text().toStdString(); |
||||
|
h256 ph; |
||||
|
DEV_IGNORE_EXCEPTIONS(ph = h256(u.passwordHash->text().toStdString())); |
||||
|
string h = u.hint->text().toStdString(); |
||||
|
bool mp = u.noPassword->isChecked(); |
||||
|
string p = mp ? string() : u.oldPassword ? lastPassword : u.password->text().toStdString(); |
||||
|
|
||||
|
// check for a brain wallet import
|
||||
|
if (lastKey.empty() && !lastSecret) |
||||
|
main()->keyManager().importExistingBrain(a, n, h); |
||||
|
else if (!lastKey.empty() && !lastSecret) |
||||
|
main()->keyManager().importExisting(main()->keyManager().store().importKey(lastKey), n, a, ph, h); |
||||
|
else if (mp) |
||||
|
main()->keyManager().import(lastSecret, n); |
||||
|
else |
||||
|
main()->keyManager().import(lastSecret, n, p, h); |
||||
|
|
||||
|
main()->noteKeysChanged(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,44 @@ |
|||||
|
/*
|
||||
|
This file is part of cpp-ethereum. |
||||
|
|
||||
|
cpp-ethereum is free software: you can redistribute it and/or modify |
||||
|
it under the terms of the GNU General Public License as published by |
||||
|
the Free Software Foundation, either version 3 of the License, or |
||||
|
(at your option) any later version. |
||||
|
|
||||
|
cpp-ethereum 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 General Public License for more details. |
||||
|
|
||||
|
You should have received a copy of the GNU General Public License |
||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
*/ |
||||
|
/** @file ImportKey.h
|
||||
|
* @author Gav Wood <i@gavwood.com> |
||||
|
* @date 2015 |
||||
|
*/ |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include "MainFace.h" |
||||
|
|
||||
|
namespace dev |
||||
|
{ |
||||
|
namespace az |
||||
|
{ |
||||
|
|
||||
|
class ImportKey: public QObject, public Plugin |
||||
|
{ |
||||
|
Q_OBJECT |
||||
|
|
||||
|
public: |
||||
|
ImportKey(MainFace* _m); |
||||
|
~ImportKey(); |
||||
|
|
||||
|
private slots: |
||||
|
void import(); |
||||
|
}; |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,291 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<ui version="4.0"> |
||||
|
<class>ImportKey</class> |
||||
|
<widget class="QDialog" name="ImportKey"> |
||||
|
<property name="geometry"> |
||||
|
<rect> |
||||
|
<x>0</x> |
||||
|
<y>0</y> |
||||
|
<width>575</width> |
||||
|
<height>315</height> |
||||
|
</rect> |
||||
|
</property> |
||||
|
<property name="windowTitle"> |
||||
|
<string>Dialog</string> |
||||
|
</property> |
||||
|
<layout class="QVBoxLayout" name="verticalLayout"> |
||||
|
<item> |
||||
|
<layout class="QGridLayout" name="gridLayout"> |
||||
|
<item row="1" column="2" colspan="2"> |
||||
|
<widget class="QLineEdit" name="key"> |
||||
|
<property name="placeholderText"> |
||||
|
<string>Leave blank for a brain wallet</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="1" column="4"> |
||||
|
<widget class="QToolButton" name="openKey"> |
||||
|
<property name="text"> |
||||
|
<string>...</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="10" column="2" colspan="3"> |
||||
|
<widget class="QLineEdit" name="passwordHash"> |
||||
|
<property name="readOnly"> |
||||
|
<bool>true</bool> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="8" column="3" colspan="2"> |
||||
|
<widget class="QCheckBox" name="showPassword"> |
||||
|
<property name="text"> |
||||
|
<string>Show</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="4" column="0" colspan="2"> |
||||
|
<widget class="QLabel" name="label_2"> |
||||
|
<property name="text"> |
||||
|
<string>Address:</string> |
||||
|
</property> |
||||
|
<property name="buddy"> |
||||
|
<cstring>address</cstring> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="8" column="0" colspan="2"> |
||||
|
<widget class="QRadioButton" name="newPassword"> |
||||
|
<property name="text"> |
||||
|
<string>New Password:</string> |
||||
|
</property> |
||||
|
<attribute name="buttonGroup"> |
||||
|
<string notr="true">buttonGroup</string> |
||||
|
</attribute> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="4" column="2" colspan="3"> |
||||
|
<widget class="QLineEdit" name="address"> |
||||
|
<property name="placeholderText"> |
||||
|
<string>Place the address of the key here</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="2" column="0" colspan="2"> |
||||
|
<widget class="QLabel" name="label_4"> |
||||
|
<property name="text"> |
||||
|
<string>Name:</string> |
||||
|
</property> |
||||
|
<property name="buddy"> |
||||
|
<cstring>name</cstring> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="6" column="0" colspan="2"> |
||||
|
<widget class="QRadioButton" name="noPassword"> |
||||
|
<property name="text"> |
||||
|
<string>Master password</string> |
||||
|
</property> |
||||
|
<property name="checked"> |
||||
|
<bool>true</bool> |
||||
|
</property> |
||||
|
<attribute name="buttonGroup"> |
||||
|
<string notr="true">buttonGroup</string> |
||||
|
</attribute> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="11" column="2" colspan="3"> |
||||
|
<widget class="QLineEdit" name="hint"/> |
||||
|
</item> |
||||
|
<item row="7" column="0" colspan="2"> |
||||
|
<widget class="QRadioButton" name="oldPassword"> |
||||
|
<property name="enabled"> |
||||
|
<bool>false</bool> |
||||
|
</property> |
||||
|
<property name="text"> |
||||
|
<string>Old password</string> |
||||
|
</property> |
||||
|
<attribute name="buttonGroup"> |
||||
|
<string notr="true">buttonGroup</string> |
||||
|
</attribute> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="8" column="2"> |
||||
|
<widget class="QLineEdit" name="password"> |
||||
|
<property name="placeholderText"> |
||||
|
<string>Enter the password you wish to use for the key here</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="5" column="2" colspan="3"> |
||||
|
<widget class="QLineEdit" name="addressOut"> |
||||
|
<property name="readOnly"> |
||||
|
<bool>true</bool> |
||||
|
</property> |
||||
|
<property name="placeholderText"> |
||||
|
<string>Unknown Address</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="2" column="2" colspan="3"> |
||||
|
<widget class="QLineEdit" name="name"> |
||||
|
<property name="placeholderText"> |
||||
|
<string>Enter this key's name here</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="10" column="0" colspan="2"> |
||||
|
<widget class="QLabel" name="label_3"> |
||||
|
<property name="text"> |
||||
|
<string>Password Hash:</string> |
||||
|
</property> |
||||
|
<property name="buddy"> |
||||
|
<cstring>passwordHash</cstring> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="11" column="0" colspan="2"> |
||||
|
<widget class="QLabel" name="label_5"> |
||||
|
<property name="text"> |
||||
|
<string>Password Hint:</string> |
||||
|
</property> |
||||
|
<property name="buddy"> |
||||
|
<cstring>hint</cstring> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="6" column="2" colspan="3"> |
||||
|
<widget class="QLabel" name="label_6"> |
||||
|
<property name="text"> |
||||
|
<string>Use same password for the key as for the master.</string> |
||||
|
</property> |
||||
|
<property name="wordWrap"> |
||||
|
<bool>false</bool> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="1" column="0" colspan="2"> |
||||
|
<widget class="QLabel" name="label"> |
||||
|
<property name="text"> |
||||
|
<string>Key:</string> |
||||
|
</property> |
||||
|
<property name="buddy"> |
||||
|
<cstring>key</cstring> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item row="7" column="2" colspan="3"> |
||||
|
<widget class="QLabel" name="label_7"> |
||||
|
<property name="text"> |
||||
|
<string>Use the same password as in the key file.</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
</layout> |
||||
|
</item> |
||||
|
<item> |
||||
|
<spacer name="verticalSpacer"> |
||||
|
<property name="orientation"> |
||||
|
<enum>Qt::Vertical</enum> |
||||
|
</property> |
||||
|
<property name="sizeHint" stdset="0"> |
||||
|
<size> |
||||
|
<width>20</width> |
||||
|
<height>5</height> |
||||
|
</size> |
||||
|
</property> |
||||
|
</spacer> |
||||
|
</item> |
||||
|
<item> |
||||
|
<layout class="QHBoxLayout" name="horizontalLayout"> |
||||
|
<item> |
||||
|
<spacer name="horizontalSpacer"> |
||||
|
<property name="orientation"> |
||||
|
<enum>Qt::Horizontal</enum> |
||||
|
</property> |
||||
|
<property name="sizeHint" stdset="0"> |
||||
|
<size> |
||||
|
<width>40</width> |
||||
|
<height>20</height> |
||||
|
</size> |
||||
|
</property> |
||||
|
</spacer> |
||||
|
</item> |
||||
|
<item> |
||||
|
<widget class="QPushButton" name="cancel"> |
||||
|
<property name="text"> |
||||
|
<string>Cancel</string> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
<item> |
||||
|
<widget class="QPushButton" name="import_2"> |
||||
|
<property name="enabled"> |
||||
|
<bool>false</bool> |
||||
|
</property> |
||||
|
<property name="text"> |
||||
|
<string>&Import</string> |
||||
|
</property> |
||||
|
<property name="default"> |
||||
|
<bool>true</bool> |
||||
|
</property> |
||||
|
</widget> |
||||
|
</item> |
||||
|
</layout> |
||||
|
</item> |
||||
|
</layout> |
||||
|
</widget> |
||||
|
<tabstops> |
||||
|
<tabstop>key</tabstop> |
||||
|
<tabstop>openKey</tabstop> |
||||
|
<tabstop>name</tabstop> |
||||
|
<tabstop>address</tabstop> |
||||
|
<tabstop>noPassword</tabstop> |
||||
|
<tabstop>oldPassword</tabstop> |
||||
|
<tabstop>newPassword</tabstop> |
||||
|
<tabstop>password</tabstop> |
||||
|
<tabstop>showPassword</tabstop> |
||||
|
<tabstop>passwordHash</tabstop> |
||||
|
<tabstop>hint</tabstop> |
||||
|
<tabstop>cancel</tabstop> |
||||
|
<tabstop>import_2</tabstop> |
||||
|
</tabstops> |
||||
|
<resources/> |
||||
|
<connections> |
||||
|
<connection> |
||||
|
<sender>import_2</sender> |
||||
|
<signal>clicked()</signal> |
||||
|
<receiver>ImportKey</receiver> |
||||
|
<slot>accept()</slot> |
||||
|
<hints> |
||||
|
<hint type="sourcelabel"> |
||||
|
<x>564</x> |
||||
|
<y>304</y> |
||||
|
</hint> |
||||
|
<hint type="destinationlabel"> |
||||
|
<x>449</x> |
||||
|
<y>504</y> |
||||
|
</hint> |
||||
|
</hints> |
||||
|
</connection> |
||||
|
<connection> |
||||
|
<sender>cancel</sender> |
||||
|
<signal>clicked()</signal> |
||||
|
<receiver>ImportKey</receiver> |
||||
|
<slot>reject()</slot> |
||||
|
<hints> |
||||
|
<hint type="sourcelabel"> |
||||
|
<x>478</x> |
||||
|
<y>304</y> |
||||
|
</hint> |
||||
|
<hint type="destinationlabel"> |
||||
|
<x>351</x> |
||||
|
<y>506</y> |
||||
|
</hint> |
||||
|
</hints> |
||||
|
</connection> |
||||
|
</connections> |
||||
|
<buttongroups> |
||||
|
<buttongroup name="buttonGroup"/> |
||||
|
</buttongroups> |
||||
|
</ui> |
Loading…
Reference in new issue