Transactionally entering password.

This commit is contained in:
clemahieu 2018-08-24 00:14:24 +01:00
commit 4b9e206746
9 changed files with 104 additions and 129 deletions

View file

@ -354,7 +354,10 @@ TEST (node, unlock_search)
system.wallet (0)->insert_adhoc (key2.prv);
system.wallet (0)->store.password.value_set (rai::keypair ().prv);
auto node (system.nodes[0]);
ASSERT_FALSE (system.wallet (0)->enter_password (""));
{
rai::transaction transaction (system.wallet (0)->store.environment, true);
ASSERT_FALSE (system.wallet (0)->enter_password (transaction, ""));
}
system.deadline_set (10s);
while (system.nodes[0]->balance (key2.pub).is_zero ())
{
@ -592,9 +595,9 @@ TEST (node, confirm_locked)
{
rai::system system (24000, 1);
system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv);
system.wallet (0)->enter_password ("1");
rai::transaction transaction (system.nodes[0]->store.environment, true);
system.wallet (0)->enter_password (transaction, "1");
auto block (std::make_shared<rai::send_block> (0, 0, 0, rai::keypair ().prv, 0, 0));
rai::transaction transaction (system.nodes[0]->store.environment, false);
system.nodes[0]->network.republish_block (transaction, block);
}

View file

@ -467,17 +467,11 @@ TEST (rpc, wallet_password_change)
ASSERT_EQ (200, response.status);
std::string account_text1 (response.json.get<std::string> ("changed"));
ASSERT_EQ (account_text1, "1");
{
rai::transaction transaction (system.wallet (0)->store.environment, false);
ASSERT_TRUE (system.wallet (0)->store.valid_password (transaction));
}
ASSERT_TRUE (system.wallet (0)->enter_password (""));
{
rai::transaction transaction (system.wallet (0)->store.environment, false);
ASSERT_FALSE (system.wallet (0)->store.valid_password (transaction));
}
ASSERT_FALSE (system.wallet (0)->enter_password ("test"));
rai::transaction transaction (system.wallet (0)->store.environment, false);
rai::transaction transaction (system.wallet (0)->store.environment, true);
ASSERT_TRUE (system.wallet (0)->store.valid_password (transaction));
ASSERT_TRUE (system.wallet (0)->enter_password (transaction, ""));
ASSERT_FALSE (system.wallet (0)->store.valid_password (transaction));
ASSERT_FALSE (system.wallet (0)->enter_password (transaction, "test"));
ASSERT_TRUE (system.wallet (0)->store.valid_password (transaction));
}

View file

@ -655,8 +655,8 @@ TEST (wallet, insert_locked)
rai::transaction transaction (wallet->store.environment, true);
wallet->store.rekey (transaction, "1");
ASSERT_TRUE (wallet->store.valid_password (transaction));
wallet->enter_password (transaction, "");
}
wallet->enter_password ("");
rai::transaction transaction (wallet->store.environment, false);
ASSERT_FALSE (wallet->store.valid_password (transaction));
ASSERT_TRUE (wallet->insert_adhoc (rai::keypair ().prv).is_zero ());
@ -668,47 +668,34 @@ TEST (wallet, version_1_upgrade)
auto wallet (system.wallet (0));
wallet->enter_initial_password ();
rai::keypair key;
{
rai::transaction transaction (wallet->store.environment, true);
ASSERT_TRUE (wallet->store.valid_password (transaction));
wallet->store.rekey (transaction, "1");
}
wallet->enter_password ("");
{
rai::transaction transaction (wallet->store.environment, true);
ASSERT_FALSE (wallet->store.valid_password (transaction));
rai::raw_key password_l;
rai::wallet_value value (wallet->store.entry_get_raw (transaction, rai::wallet_store::wallet_key_special));
rai::raw_key kdf;
kdf.data.clear ();
password_l.decrypt (value.key, kdf, wallet->store.salt (transaction).owords[0]);
rai::uint256_union ciphertext;
ciphertext.encrypt (key.prv, password_l, wallet->store.salt (transaction).owords[0]);
wallet->store.entry_put_raw (transaction, key.pub, rai::wallet_value (ciphertext, 0));
wallet->store.version_put (transaction, 1);
}
wallet->enter_password ("1");
{
rai::transaction transaction (wallet->store.environment, true);
ASSERT_TRUE (wallet->store.valid_password (transaction));
ASSERT_EQ (wallet->store.version_current, wallet->store.version (transaction));
rai::raw_key prv;
ASSERT_FALSE (wallet->store.fetch (transaction, key.pub, prv));
ASSERT_EQ (key.prv, prv);
rai::raw_key password_l;
rai::wallet_value value (wallet->store.entry_get_raw (transaction, rai::wallet_store::wallet_key_special));
rai::raw_key kdf;
wallet->store.derive_key (kdf, transaction, "");
password_l.decrypt (value.key, kdf, wallet->store.salt (transaction).owords[0]);
rai::uint256_union ciphertext;
ciphertext.encrypt (key.prv, password_l, wallet->store.salt (transaction).owords[0]);
wallet->store.entry_put_raw (transaction, key.pub, rai::wallet_value (ciphertext, 0));
wallet->store.version_put (transaction, 1);
}
wallet->enter_password ("1");
rai::transaction transaction (wallet->store.environment, true);
ASSERT_TRUE (wallet->store.valid_password (transaction));
wallet->store.rekey (transaction, "1");
wallet->enter_password (transaction, "");
ASSERT_FALSE (wallet->store.valid_password (transaction));
rai::raw_key password_l;
rai::wallet_value value (wallet->store.entry_get_raw (transaction, rai::wallet_store::wallet_key_special));
rai::raw_key kdf;
kdf.data.clear ();
password_l.decrypt (value.key, kdf, wallet->store.salt (transaction).owords[0]);
rai::uint256_union ciphertext;
ciphertext.encrypt (key.prv, password_l, wallet->store.salt (transaction).owords[0]);
wallet->store.entry_put_raw (transaction, key.pub, rai::wallet_value (ciphertext, 0));
wallet->store.version_put (transaction, 1);
wallet->enter_password (transaction, "1");
ASSERT_TRUE (wallet->store.valid_password (transaction));
ASSERT_EQ (wallet->store.version_current, wallet->store.version (transaction));
rai::raw_key prv;
ASSERT_FALSE (wallet->store.fetch (transaction, key.pub, prv));
ASSERT_EQ (key.prv, prv);
value = wallet->store.entry_get_raw (transaction, rai::wallet_store::wallet_key_special);
wallet->store.derive_key (kdf, transaction, "");
password_l.decrypt (value.key, kdf, wallet->store.salt (transaction).owords[0]);
ciphertext.encrypt (key.prv, password_l, wallet->store.salt (transaction).owords[0]);
wallet->store.entry_put_raw (transaction, key.pub, rai::wallet_value (ciphertext, 0));
wallet->store.version_put (transaction, 1);
wallet->enter_password (transaction, "1");
ASSERT_TRUE (wallet->store.valid_password (transaction));
ASSERT_EQ (wallet->store.version_current, wallet->store.version (transaction));
rai::raw_key prv2;
ASSERT_FALSE (wallet->store.fetch (transaction, key.pub, prv2));
@ -798,13 +785,10 @@ TEST (wallet, insert_deterministic_locked)
{
rai::system system (24000, 1);
auto wallet (system.wallet (0));
{
rai::transaction transaction (wallet->store.environment, true);
wallet->store.rekey (transaction, "1");
ASSERT_TRUE (wallet->store.valid_password (transaction));
}
wallet->enter_password ("");
rai::transaction transaction (wallet->store.environment, true);
wallet->store.rekey (transaction, "1");
ASSERT_TRUE (wallet->store.valid_password (transaction));
wallet->enter_password (transaction, "");
ASSERT_FALSE (wallet->store.valid_password (transaction));
ASSERT_TRUE (wallet->deterministic_insert (transaction).is_zero ());
}
@ -813,22 +797,16 @@ TEST (wallet, version_2_upgrade)
{
rai::system system (24000, 1);
auto wallet (system.wallet (0));
{
rai::transaction transaction (wallet->store.environment, true);
wallet->store.rekey (transaction, "1");
ASSERT_TRUE (wallet->store.attempt_password (transaction, ""));
wallet->store.erase (transaction, rai::wallet_store::deterministic_index_special);
wallet->store.erase (transaction, rai::wallet_store::seed_special);
wallet->store.version_put (transaction, 2);
}
{
rai::transaction transaction (wallet->store.environment, true);
ASSERT_EQ (2, wallet->store.version (transaction));
ASSERT_FALSE (wallet->store.exists (transaction, rai::wallet_store::deterministic_index_special));
ASSERT_FALSE (wallet->store.exists (transaction, rai::wallet_store::seed_special));
wallet->store.attempt_password (transaction, "1");
}
rai::transaction transaction (wallet->store.environment, true);
wallet->store.rekey (transaction, "1");
ASSERT_TRUE (wallet->store.attempt_password (transaction, ""));
wallet->store.erase (transaction, rai::wallet_store::deterministic_index_special);
wallet->store.erase (transaction, rai::wallet_store::seed_special);
wallet->store.version_put (transaction, 2);
ASSERT_EQ (2, wallet->store.version (transaction));
ASSERT_FALSE (wallet->store.exists (transaction, rai::wallet_store::deterministic_index_special));
ASSERT_FALSE (wallet->store.exists (transaction, rai::wallet_store::seed_special));
wallet->store.attempt_password (transaction, "1");
ASSERT_EQ (wallet->store.version_current, wallet->store.version (transaction));
ASSERT_TRUE (wallet->store.exists (transaction, rai::wallet_store::deterministic_index_special));
ASSERT_TRUE (wallet->store.exists (transaction, rai::wallet_store::seed_special));
@ -839,36 +817,27 @@ TEST (wallet, version_3_upgrade)
{
rai::system system (24000, 1);
auto wallet (system.wallet (0));
{
rai::transaction transaction (wallet->store.environment, true);
wallet->store.rekey (transaction, "1");
}
wallet->enter_password ("1");
{
rai::transaction transaction (wallet->store.environment, false);
ASSERT_TRUE (wallet->store.valid_password (transaction));
ASSERT_EQ (wallet->store.version_current, wallet->store.version (transaction));
}
rai::transaction transaction (wallet->store.environment, true);
wallet->store.rekey (transaction, "1");
wallet->enter_password (transaction, "1");
ASSERT_TRUE (wallet->store.valid_password (transaction));
ASSERT_EQ (wallet->store.version_current, wallet->store.version (transaction));
rai::keypair key;
rai::raw_key seed;
rai::uint256_union seed_ciphertext;
rai::random_pool.GenerateBlock (seed.data.bytes.data (), seed.data.bytes.size ());
{
rai::transaction transaction (wallet->store.environment, true);
rai::raw_key password_l;
rai::wallet_value value (wallet->store.entry_get_raw (transaction, rai::wallet_store::wallet_key_special));
rai::raw_key kdf;
wallet->store.derive_key (kdf, transaction, "1");
password_l.decrypt (value.key, kdf, wallet->store.salt (transaction).owords[0]);
rai::uint256_union ciphertext;
ciphertext.encrypt (key.prv, password_l, wallet->store.salt (transaction).owords[0]);
wallet->store.entry_put_raw (transaction, key.pub, rai::wallet_value (ciphertext, 0));
seed_ciphertext.encrypt (seed, password_l, wallet->store.salt (transaction).owords[0]);
wallet->store.entry_put_raw (transaction, rai::wallet_store::seed_special, rai::wallet_value (seed_ciphertext, 0));
wallet->store.version_put (transaction, 3);
}
wallet->enter_password ("1");
rai::transaction transaction (wallet->store.environment, false);
rai::raw_key password_l;
rai::wallet_value value (wallet->store.entry_get_raw (transaction, rai::wallet_store::wallet_key_special));
rai::raw_key kdf;
wallet->store.derive_key (kdf, transaction, "1");
password_l.decrypt (value.key, kdf, wallet->store.salt (transaction).owords[0]);
rai::uint256_union ciphertext;
ciphertext.encrypt (key.prv, password_l, wallet->store.salt (transaction).owords[0]);
wallet->store.entry_put_raw (transaction, key.pub, rai::wallet_value (ciphertext, 0));
seed_ciphertext.encrypt (seed, password_l, wallet->store.salt (transaction).owords[0]);
wallet->store.entry_put_raw (transaction, rai::wallet_store::seed_special, rai::wallet_value (seed_ciphertext, 0));
wallet->store.version_put (transaction, 3);
wallet->enter_password (transaction, "1");
ASSERT_TRUE (wallet->store.valid_password (transaction));
ASSERT_EQ (wallet->store.version_current, wallet->store.version (transaction));
rai::raw_key prv;

View file

@ -75,9 +75,9 @@ std::error_code rai::handle_node_options (boost::program_options::variables_map
auto wallet (node.node->wallets.open (wallet_id));
if (wallet != nullptr)
{
if (!wallet->enter_password (password))
rai::transaction transaction (wallet->store.environment, true);
if (!wallet->enter_password (transaction, password))
{
rai::transaction transaction (wallet->store.environment, true);
auto pub (wallet->store.deterministic_insert (transaction));
std::cout << boost::str (boost::format ("Account: %1%\n") % pub.to_account ());
}
@ -306,12 +306,12 @@ std::error_code rai::handle_node_options (boost::program_options::variables_map
auto wallet (node.node->wallets.open (wallet_id));
if (wallet != nullptr)
{
if (!wallet->enter_password (password))
rai::transaction transaction (wallet->store.environment, true);
if (!wallet->enter_password (transaction, password))
{
rai::raw_key key;
if (!key.data.decode_hex (vm["key"].as<std::string> ()))
{
rai::transaction transaction (wallet->store.environment, true);
wallet->store.insert_adhoc (transaction, key);
}
else
@ -360,12 +360,12 @@ std::error_code rai::handle_node_options (boost::program_options::variables_map
auto wallet (node.node->wallets.open (wallet_id));
if (wallet != nullptr)
{
if (!wallet->enter_password (password))
rai::transaction transaction (wallet->store.environment, true);
if (!wallet->enter_password (transaction, password))
{
rai::raw_key key;
if (!key.data.decode_hex (vm["key"].as<std::string> ()))
{
rai::transaction transaction (wallet->store.environment, true);
wallet->change_seed (transaction, key);
}
else
@ -421,9 +421,9 @@ std::error_code rai::handle_node_options (boost::program_options::variables_map
auto existing (node.node->wallets.items.find (wallet_id));
if (existing != node.node->wallets.items.end ())
{
if (!existing->second->enter_password (password))
rai::transaction transaction (existing->second->store.environment, true);
if (!existing->second->enter_password (transaction, password))
{
rai::transaction transaction (existing->second->store.environment, false);
rai::raw_key seed;
existing->second->store.seed (seed, transaction);
std::cout << boost::str (boost::format ("Seed: %1%\n") % seed.data.to_string ());

View file

@ -1915,7 +1915,8 @@ void rai::rpc_handler::password_enter ()
if (!ec)
{
std::string password_text (request.get<std::string> ("password"));
auto error (wallet->enter_password (password_text));
rai::transaction transaction (wallet->store.environment, true);
auto error (wallet->enter_password (transaction, password_text));
response_l.put ("valid", error ? "0" : "1");
}
response_errors ();

View file

@ -759,7 +759,6 @@ void rai::wallet::enter_initial_password ()
std::lock_guard<std::recursive_mutex> lock (store.mutex);
rai::raw_key password_l;
store.password.value (password_l);
auto enter_empty (false);
if (password_l.data.is_zero ())
{
rai::transaction transaction (store.environment, true);
@ -770,19 +769,14 @@ void rai::wallet::enter_initial_password ()
}
else
{
enter_empty = true;
enter_password (transaction, "");
}
}
if (enter_empty)
{
enter_password ("");
}
}
bool rai::wallet::enter_password (std::string const & password_a)
bool rai::wallet::enter_password (MDB_txn * transaction_a, std::string const & password_a)
{
rai::transaction transaction (store.environment, true);
auto result (store.attempt_password (transaction, password_a));
auto result (store.attempt_password (transaction_a, password_a));
if (!result)
{
auto this_l (shared_from_this ());

View file

@ -133,7 +133,7 @@ public:
wallet (bool &, rai::mdb_env &, rai::transaction &, rai::wallets &, std::string const &);
wallet (bool &, rai::mdb_env &, rai::transaction &, rai::wallets &, std::string const &, std::string const &);
void enter_initial_password ();
bool enter_password (std::string const &);
bool enter_password (MDB_txn *, std::string const &);
rai::public_key insert_adhoc (rai::raw_key const &, bool = true);
rai::public_key insert_adhoc (MDB_txn *, rai::raw_key const &, bool = true);
void insert_watch (MDB_txn *, rai::public_key const &);

View file

@ -1378,7 +1378,8 @@ void rai_qt::wallet::update_connected ()
void rai_qt::wallet::empty_password ()
{
this->node.alarm.add (std::chrono::steady_clock::now () + std::chrono::seconds (3), [this]() {
wallet_m->enter_password (std::string (""));
rai::transaction transaction (wallet_m->store.environment, true);
wallet_m->enter_password (transaction, std::string (""));
});
}
@ -1577,7 +1578,7 @@ wallet (wallet_a)
else
{
// try to unlock wallet
if (!this->wallet.wallet_m->enter_password (std::string (password->text ().toLocal8Bit ())))
if (!this->wallet.wallet_m->enter_password (transaction, std::string (password->text ().toLocal8Bit ())))
{
password->clear ();
lock_toggle->setText ("Lock");

View file

@ -281,7 +281,10 @@ TEST (wallet, send_locked)
rai::system system (24000, 1);
system.wallet (0)->insert_adhoc (rai::test_genesis_key.prv);
rai::keypair key1;
system.wallet (0)->enter_password ("0");
{
rai::transaction transaction (system.wallet (0)->store.environment, true);
system.wallet (0)->enter_password (transaction, "0");
}
auto account (rai::test_genesis_key.pub);
auto wallet (std::make_shared<rai_qt::wallet> (*test_application, processor, *system.nodes[0], system.wallet (0), account));
wallet->start ();
@ -728,7 +731,10 @@ TEST (wallet, import_locked)
rai_qt::eventloop_processor processor;
rai::system system (24000, 1);
auto key1 (system.wallet (0)->deterministic_insert ());
system.wallet (0)->store.rekey (rai::transaction (system.wallet (0)->store.environment, true), "1");
{
rai::transaction transaction (system.wallet (0)->store.environment, true);
system.wallet (0)->store.rekey (transaction, "1");
}
auto wallet (std::make_shared<rai_qt::wallet> (*test_application, processor, *system.nodes[0], system.wallet (0), key1));
wallet->start ();
QTest::mouseClick (wallet->show_advanced, Qt::LeftButton);
@ -739,15 +745,22 @@ TEST (wallet, import_locked)
seed1.data.clear ();
QTest::keyClicks (wallet->import.seed, seed1.data.to_string ().c_str ());
QTest::keyClicks (wallet->import.clear_line, "clear keys");
system.wallet (0)->enter_password ("");
{
rai::transaction transaction (system.wallet (0)->store.environment, true);
system.wallet (0)->enter_password (transaction, "");
}
QTest::mouseClick (wallet->import.import_seed, Qt::LeftButton);
rai::raw_key seed2;
system.wallet (0)->store.seed (seed2, rai::transaction (system.wallet (0)->store.environment, false));
ASSERT_NE (seed1, seed2);
system.wallet (0)->enter_password ("1");
{
rai::transaction transaction (system.wallet (0)->store.environment, true);
system.wallet (0)->store.seed (seed2, transaction);
ASSERT_NE (seed1, seed2);
system.wallet (0)->enter_password (transaction, "1");
}
QTest::mouseClick (wallet->import.import_seed, Qt::LeftButton);
rai::raw_key seed3;
system.wallet (0)->store.seed (seed3, rai::transaction (system.wallet (0)->store.environment, false));
rai::transaction transaction (system.wallet (0)->store.environment, false);
system.wallet (0)->store.seed (seed3, transaction);
ASSERT_EQ (seed1, seed3);
}
// DISABLED: this always fails