diff options
-rw-r--r-- | CMakeLists.txt | 7 | ||||
-rw-r--r-- | src/daemon/rpc_command_executor.cpp | 4 | ||||
-rw-r--r-- | src/daemonizer/posix_fork.cpp | 14 | ||||
-rw-r--r-- | src/rpc/core_rpc_server.h | 4 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 67 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.h | 2 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 35 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 3 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.cpp | 45 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.h | 4 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server_commands_defs.h | 47 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server_error_codes.h | 1 |
12 files changed, 211 insertions, 22 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b9c81895..0ce9bb7af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -314,7 +314,7 @@ else() set(ARCH_FLAG "-march=${ARCH}") endif() endif() - set(WARNINGS "-Wall -Wextra -Wpointer-arith -Wundef -Wvla -Wwrite-strings -Wno-error=extra -Wno-error=deprecated-declarations -Wno-error=sign-compare -Wno-error=strict-aliasing -Wno-error=type-limits -Wno-unused-parameter -Wno-error=unused-variable -Wno-error=undef -Wno-error=uninitialized") + set(WARNINGS "-Wall -Wextra -Wpointer-arith -Wundef -Wvla -Wwrite-strings -Wno-error=extra -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-error=unused-variable -Wno-error=undef -Wno-error=uninitialized") if(CMAKE_C_COMPILER_ID STREQUAL "Clang") set(WARNINGS "${WARNINGS} -Wno-deprecated-register") endif() @@ -350,6 +350,11 @@ else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_FLAG} ${WARNINGS} ${C_WARNINGS} ${ARCH_FLAG}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -D_GNU_SOURCE ${MINGW_FLAG} ${WARNINGS} ${CXX_WARNINGS} ${ARCH_FLAG}") + # With GCC 6.1.1 the compiled binary malfunctions due to aliasing. Until that + # is fixed in the code (Issue #847), force compiler to be conservative. + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-strict-aliasing") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing") + option(NO_AES "Explicitly disable AES support" ${NO_AES}) if(NOT NO_AES AND NOT (ARM6 OR ARM7)) diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index ae9492111..0a0fc793d 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -1123,11 +1123,9 @@ bool t_rpc_command_executor::print_bans() } } - time_t now = time(nullptr); for (auto i = res.bans.begin(); i != res.bans.end(); ++i) { - time_t seconds = i->seconds - now; - tools::msg_writer() << epee::string_tools::get_ip_string_from_int32(i->ip) << " banned for " << seconds << " seconds"; + tools::msg_writer() << epee::string_tools::get_ip_string_from_int32(i->ip) << " banned for " << i->seconds << " seconds"; } return true; diff --git a/src/daemonizer/posix_fork.cpp b/src/daemonizer/posix_fork.cpp index c068912ec..949c0f593 100644 --- a/src/daemonizer/posix_fork.cpp +++ b/src/daemonizer/posix_fork.cpp @@ -50,20 +50,6 @@ void fork() // terminal. setsid(); - // A process inherits its working directory from its parent. This could be - // on a mounted filesystem, which means that the running daemon would - // prevent this filesystem from being unmounted. Changing to the root - // directory avoids this problem. - if (chdir("/") < 0) - { - quit("Unable to change working directory to root"); - } - - // The file mode creation mask is also inherited from the parent process. - // We don't want to restrict the permissions on files created by the - // daemon, so the mask is cleared. - umask(0); - // A second fork ensures the process cannot acquire a controlling terminal. if (pid_t pid = ::fork()) { diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index 54723c7ef..3d50c77be 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -107,8 +107,8 @@ namespace cryptonote MAP_JON_RPC_WE_IF("get_connections", on_get_connections, COMMAND_RPC_GET_CONNECTIONS, !m_restricted) MAP_JON_RPC_WE("get_info", on_get_info_json, COMMAND_RPC_GET_INFO) MAP_JON_RPC_WE("hard_fork_info", on_hard_fork_info, COMMAND_RPC_HARD_FORK_INFO) - MAP_JON_RPC_WE_IF("setbans", on_set_bans, COMMAND_RPC_SETBANS, !m_restricted) - MAP_JON_RPC_WE_IF("getbans", on_get_bans, COMMAND_RPC_GETBANS, !m_restricted) + MAP_JON_RPC_WE_IF("set_bans", on_set_bans, COMMAND_RPC_SETBANS, !m_restricted) + MAP_JON_RPC_WE_IF("get_bans", on_get_bans, COMMAND_RPC_GETBANS, !m_restricted) MAP_JON_RPC_WE_IF("flush_txpool", on_flush_txpool, COMMAND_RPC_FLUSH_TRANSACTION_POOL, !m_restricted) MAP_JON_RPC_WE("get_output_histogram", on_get_output_histogram, COMMAND_RPC_GET_OUTPUT_HISTOGRAM) MAP_JON_RPC_WE("get_version", on_get_version, COMMAND_RPC_GET_VERSION) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index acd12729a..2bcd8ae4c 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -660,6 +660,8 @@ simple_wallet::simple_wallet() m_cmd_binder.set_handler("set_tx_note", boost::bind(&simple_wallet::set_tx_note, this, _1), tr("Set an arbitrary string note for a txid")); m_cmd_binder.set_handler("get_tx_note", boost::bind(&simple_wallet::get_tx_note, this, _1), tr("Get a string note for a txid")); m_cmd_binder.set_handler("status", boost::bind(&simple_wallet::status, this, _1), tr("Show wallet status information")); + m_cmd_binder.set_handler("sign", boost::bind(&simple_wallet::sign, this, _1), tr("Sign the contents of a file")); + m_cmd_binder.set_handler("verify", boost::bind(&simple_wallet::verify, this, _1), tr("Verify a signature on the contents of a file")); m_cmd_binder.set_handler("help", boost::bind(&simple_wallet::help, this, _1), tr("Show this help")); } //---------------------------------------------------------------------------------------------------- @@ -3384,6 +3386,71 @@ bool simple_wallet::status(const std::vector<std::string> &args) return true; } //---------------------------------------------------------------------------------------------------- +bool simple_wallet::sign(const std::vector<std::string> &args) +{ + if (args.size() != 1) + { + fail_msg_writer() << tr("usage: sign <filename>"); + return true; + } + if (m_wallet->watch_only()) + { + fail_msg_writer() << tr("wallet is watch-only and cannot sign"); + return true; + } + std::string filename = args[0]; + std::string data; + bool r = epee::file_io_utils::load_file_to_string(filename, data); + if (!r) + { + fail_msg_writer() << tr("failed to read file ") << filename; + return true; + } + std::string signature = m_wallet->sign(data); + success_msg_writer() << signature; + return true; +} +//---------------------------------------------------------------------------------------------------- +bool simple_wallet::verify(const std::vector<std::string> &args) +{ + if (args.size() != 3) + { + fail_msg_writer() << tr("usage: verify <filename> <address> <signature>"); + return true; + } + std::string filename = args[0]; + std::string address_string = args[1]; + std::string signature= args[2]; + + std::string data; + bool r = epee::file_io_utils::load_file_to_string(filename, data); + if (!r) + { + fail_msg_writer() << tr("failed to read file ") << filename; + return true; + } + + cryptonote::account_public_address address; + bool has_payment_id; + crypto::hash8 payment_id; + if(!get_account_integrated_address_from_str(address, has_payment_id, payment_id, m_wallet->testnet(), address_string)) + { + fail_msg_writer() << tr("failed to parse address"); + return true; + } + + r = m_wallet->verify(data, address, signature); + if (!r) + { + fail_msg_writer() << tr("Bad signature from ") << address_string; + } + else + { + success_msg_writer() << tr("Good signature from ") << address_string; + } + return true; +} +//---------------------------------------------------------------------------------------------------- bool simple_wallet::process_command(const std::vector<std::string> &args) { return m_cmd_binder.process_command_vec(args); diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index aba935449..7d8e7730c 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -143,6 +143,8 @@ namespace cryptonote bool get_tx_note(const std::vector<std::string> &args); bool status(const std::vector<std::string> &args); bool set_default_fee_multiplier(const std::vector<std::string> &args); + bool sign(const std::vector<std::string> &args); + bool verify(const std::vector<std::string> &args); uint64_t get_daemon_blockchain_height(std::string& err); bool try_connect_to_daemon(bool silent = false); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index d784d81ea..d18681f36 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -53,6 +53,7 @@ using namespace epee; #include "rapidjson/writer.h" #include "rapidjson/stringbuffer.h" #include "common/json_util.h" +#include "common/base58.h" extern "C" { @@ -3123,6 +3124,40 @@ std::string wallet2::get_tx_note(const crypto::hash &txid) const return std::string(); return i->second; } + +std::string wallet2::sign(const std::string &data) const +{ + crypto::hash hash; + crypto::cn_fast_hash(data.data(), data.size(), hash); + const cryptonote::account_keys &keys = m_account.get_keys(); + crypto::signature signature; + crypto::generate_signature(hash, keys.m_account_address.m_spend_public_key, keys.m_spend_secret_key, signature); + return std::string("SigV1") + tools::base58::encode(std::string((const char *)&signature, sizeof(signature))); +} + +bool wallet2::verify(const std::string &data, const cryptonote::account_public_address &address, const std::string &signature) const +{ + const size_t header_len = strlen("SigV1"); + if (signature.size() < header_len || signature.substr(0, header_len) != "SigV1") { + LOG_PRINT_L0("Signature header check error"); + return false; + } + crypto::hash hash; + crypto::cn_fast_hash(data.data(), data.size(), hash); + std::string decoded; + if (!tools::base58::decode(signature.substr(header_len), decoded)) { + LOG_PRINT_L0("Signature decoding error"); + return false; + } + crypto::signature s; + if (sizeof(s) != decoded.size()) { + LOG_PRINT_L0("Signature decoding error"); + return false; + } + memcpy(&s, decoded.data(), sizeof(s)); + return crypto::check_signature(hash, address.m_spend_public_key, s); +} + //---------------------------------------------------------------------------------------------------- void wallet2::generate_genesis(cryptonote::block& b) { if (m_testnet) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index d61a34853..d004b7da9 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -386,6 +386,9 @@ namespace tools void set_tx_note(const crypto::hash &txid, const std::string ¬e); std::string get_tx_note(const crypto::hash &txid) const; + std::string sign(const std::string &data) const; + bool verify(const std::string &data, const cryptonote::account_public_address &address, const std::string &signature) const; + private: /*! * \brief Stores wallet information to wallet file. diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 01ae00fe5..5c42e1c53 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -168,6 +168,13 @@ namespace tools } integrated_payment_id = new_payment_id; cryptonote::set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, integrated_payment_id); + + /* Append Payment ID data into extra */ + if (!cryptonote::add_extra_nonce_to_tx_extra(extra, extra_nonce)) { + er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID; + er.message = "Something went wrong with integrated payment_id."; + return false; + } } } @@ -197,7 +204,7 @@ namespace tools /* Append Payment ID data into extra */ if (!cryptonote::add_extra_nonce_to_tx_extra(extra, extra_nonce)) { er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID; - er.message = "Something went wront with payment_id. Please check its format: \"" + payment_id_str + "\", expected 64-character string"; + er.message = "Something went wrong with payment_id. Please check its format: \"" + payment_id_str + "\", expected 64-character string"; return false; } @@ -747,6 +754,42 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_sign(const wallet_rpc::COMMAND_RPC_SIGN::request& req, wallet_rpc::COMMAND_RPC_SIGN::response& res, epee::json_rpc::error& er) + { + if (m_wallet.restricted()) + { + er.code = WALLET_RPC_ERROR_CODE_DENIED; + er.message = "Command unavailable in restricted mode."; + return false; + } + + res.signature = m_wallet.sign(req.data); + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_verify(const wallet_rpc::COMMAND_RPC_VERIFY::request& req, wallet_rpc::COMMAND_RPC_VERIFY::response& res, epee::json_rpc::error& er) + { + if (m_wallet.restricted()) + { + er.code = WALLET_RPC_ERROR_CODE_DENIED; + er.message = "Command unavailable in restricted mode."; + return false; + } + + cryptonote::account_public_address address; + bool has_payment_id; + crypto::hash8 payment_id; + if(!get_account_integrated_address_from_str(address, has_payment_id, payment_id, m_wallet.testnet(), req.address)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; + er.message = ""; + return false; + } + + res.good = m_wallet.verify(req.data, address, req.signature); + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_stop_wallet(const wallet_rpc::COMMAND_RPC_STOP_WALLET::request& req, wallet_rpc::COMMAND_RPC_STOP_WALLET::response& res, epee::json_rpc::error& er) { if (m_wallet.restricted()) diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index 8c90aecfe..205896332 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -80,6 +80,8 @@ namespace tools MAP_JON_RPC_WE("set_tx_notes", on_set_tx_notes, wallet_rpc::COMMAND_RPC_SET_TX_NOTES) MAP_JON_RPC_WE("get_tx_notes", on_get_tx_notes, wallet_rpc::COMMAND_RPC_GET_TX_NOTES) MAP_JON_RPC_WE("get_transfers", on_get_transfers, wallet_rpc::COMMAND_RPC_GET_TRANSFERS) + MAP_JON_RPC_WE("sign", on_sign, wallet_rpc::COMMAND_RPC_SIGN) + MAP_JON_RPC_WE("verify", on_verify, wallet_rpc::COMMAND_RPC_VERIFY) END_JSON_RPC_MAP() END_URI_MAP2() @@ -103,6 +105,8 @@ namespace tools bool on_set_tx_notes(const wallet_rpc::COMMAND_RPC_SET_TX_NOTES::request& req, wallet_rpc::COMMAND_RPC_SET_TX_NOTES::response& res, epee::json_rpc::error& er); bool on_get_tx_notes(const wallet_rpc::COMMAND_RPC_GET_TX_NOTES::request& req, wallet_rpc::COMMAND_RPC_GET_TX_NOTES::response& res, epee::json_rpc::error& er); bool on_get_transfers(const wallet_rpc::COMMAND_RPC_GET_TRANSFERS::request& req, wallet_rpc::COMMAND_RPC_GET_TRANSFERS::response& res, epee::json_rpc::error& er); + bool on_sign(const wallet_rpc::COMMAND_RPC_SIGN::request& req, wallet_rpc::COMMAND_RPC_SIGN::response& res, epee::json_rpc::error& er); + bool on_verify(const wallet_rpc::COMMAND_RPC_VERIFY::request& req, wallet_rpc::COMMAND_RPC_VERIFY::response& res, epee::json_rpc::error& er); bool handle_command_line(const boost::program_options::variables_map& vm); diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index 3908476d6..1404340da 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -551,6 +551,51 @@ namespace wallet_rpc }; }; + struct COMMAND_RPC_SIGN + { + struct request + { + std::string data; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(data); + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string signature; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(signature); + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_RPC_VERIFY + { + struct request + { + std::string data; + std::string address; + std::string signature; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(data); + KV_SERIALIZE(address); + KV_SERIALIZE(signature); + END_KV_SERIALIZE_MAP() + }; + + struct response + { + bool good; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(good); + END_KV_SERIALIZE_MAP() + }; + }; + } } - diff --git a/src/wallet/wallet_rpc_server_error_codes.h b/src/wallet/wallet_rpc_server_error_codes.h index 968836671..68edfe76e 100644 --- a/src/wallet/wallet_rpc_server_error_codes.h +++ b/src/wallet/wallet_rpc_server_error_codes.h @@ -39,3 +39,4 @@ #define WALLET_RPC_ERROR_CODE_TRANSFER_TYPE -6 #define WALLET_RPC_ERROR_CODE_DENIED -7 #define WALLET_RPC_ERROR_CODE_WRONG_TXID -8 +#define WALLET_RPC_ERROR_CODE_WRONG_SIGNATURE -9 |