From 3ca7c008dbb7825062f99f80de42e9f8b0cf996b Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 17 Oct 2015 12:51:56 +0100 Subject: [PATCH 01/13] rpc: misc tweaks - make the execute flag int and volatile (used as signal comms) - do not execute all the RPC shutdown in the signal context - do not busy wait while waiting for the signal --- src/rpc/json_rpc.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/rpc/json_rpc.cpp b/src/rpc/json_rpc.cpp index 816ec25f8..27fb2dafc 100644 --- a/src/rpc/json_rpc.cpp +++ b/src/rpc/json_rpc.cpp @@ -43,25 +43,30 @@ #include #include -static bool execute = true; +static volatile int execute = 1; void trap(int signal) { - RPC::DaemonDeprecated::stop(); - execute = false; + execute = 0; } int main() { + bool initialized = false; int res = RPC::DaemonDeprecated::start(); if (res == RPC::DaemonDeprecated::FAILURE_HTTP_SERVER) { std::cerr << "Couldn't start HTTP server\n"; - execute = false; + execute = 0; } else if (res == RPC::DaemonDeprecated::FAILURE_DAEMON_NOT_RUNNING) { std::cerr << "Couldn't connect to daemon\n"; - execute = false; + execute = 0; + } else { + initialized = true; } signal(SIGINT, &trap); while (execute) { - + epee::misc_utils::sleep_no_w(100); // 100 ms } + signal(SIGINT, SIG_DFL); + if (initialized) + RPC::DaemonDeprecated::stop(); std::cout << "out!\n"; return 0; } From 19c844f623b9f431991ef2381fa0e2a65422c673 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 17 Oct 2015 13:03:58 +0100 Subject: [PATCH 02/13] daemon_deprecated_rpc: fix misc leaks and potential uses after free --- src/rpc/daemon_deprecated_rpc.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/rpc/daemon_deprecated_rpc.cpp b/src/rpc/daemon_deprecated_rpc.cpp index 6dd48279e..cd02120ee 100644 --- a/src/rpc/daemon_deprecated_rpc.cpp +++ b/src/rpc/daemon_deprecated_rpc.cpp @@ -995,12 +995,18 @@ namespace RPC int start() { server = new RPC::Json_rpc_http_server("127.0.0.1", "9997", "daemon_json_rpc", &ev_handler); if (!server->start()) { + delete server; + server = NULL; return FAILURE_HTTP_SERVER; } std::cout << "Started Daemon server at 127.0.0.1/daemon_json_rpc:9997\n"; ipc_client = wap_client_new(); wap_client_connect(ipc_client, "ipc://@/monero", 200, "wallet identity"); if (!check_connection_to_daemon()) { + wap_client_destroy(&ipc_client); // this sets ipc_client to NULL + server->stop(); + delete server; + server = NULL; return FAILURE_DAEMON_NOT_RUNNING; } return SUCCESS; @@ -1013,6 +1019,7 @@ namespace RPC if (server) { server->stop(); delete server; + server = NULL; } if (ipc_client) { wap_client_destroy(&ipc_client); From 424d09bc14309abf0de81660d365d7c3e8af44e3 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 30 Oct 2015 19:17:27 +0000 Subject: [PATCH 03/13] daemon: restore command line and console commands ability as well as a few commands for which we have 0MQ IPC for. --- src/daemon/CMakeLists.txt | 1 + src/daemon/command_parser_executor.cpp | 9 +- src/daemon/command_parser_executor.h | 8 +- src/daemon/command_server.cpp | 14 +- src/daemon/command_server.h | 8 +- src/daemon/daemon.cpp | 5 + src/daemon/main.cpp | 2 +- src/daemon/rpc_command_executor.cpp | 674 +++++++++---------------- src/daemon/rpc_command_executor.h | 21 +- 9 files changed, 254 insertions(+), 488 deletions(-) diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt index 90b8cf526..fa11b7777 100644 --- a/src/daemon/CMakeLists.txt +++ b/src/daemon/CMakeLists.txt @@ -86,6 +86,7 @@ target_link_libraries(daemon LINK_PRIVATE rpc server_ipc + client_ipc blockchain_db cryptonote_core crypto diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp index a07bb25de..505dc0d89 100644 --- a/src/daemon/command_parser_executor.cpp +++ b/src/daemon/command_parser_executor.cpp @@ -31,13 +31,8 @@ namespace daemonize { -t_command_parser_executor::t_command_parser_executor( - uint32_t ip - , uint16_t port - , bool is_rpc - , cryptonote::core_rpc_server* rpc_server - ) - : m_executor(ip, port, is_rpc, rpc_server) +t_command_parser_executor::t_command_parser_executor() + : m_executor() {} bool t_command_parser_executor::print_peer_list(const std::vector& args) diff --git a/src/daemon/command_parser_executor.h b/src/daemon/command_parser_executor.h index f00fbd77e..3b3655fa5 100644 --- a/src/daemon/command_parser_executor.h +++ b/src/daemon/command_parser_executor.h @@ -37,7 +37,6 @@ #pragma once #include "daemon/rpc_command_executor.h" -#include "rpc/core_rpc_server.h" namespace daemonize { @@ -46,12 +45,7 @@ class t_command_parser_executor final private: t_rpc_command_executor m_executor; public: - t_command_parser_executor( - uint32_t ip - , uint16_t port - , bool is_rpc - , cryptonote::core_rpc_server* rpc_server = NULL - ); + t_command_parser_executor(); bool print_peer_list(const std::vector& args); diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp index 8714b2569..097406ecd 100644 --- a/src/daemon/command_server.cpp +++ b/src/daemon/command_server.cpp @@ -34,15 +34,9 @@ namespace daemonize { namespace p = std::placeholders; -t_command_server::t_command_server( - uint32_t ip - , uint16_t port - , bool is_rpc - , cryptonote::core_rpc_server* rpc_server - ) - : m_parser(ip, port, is_rpc, rpc_server) +t_command_server::t_command_server() + : m_parser() , m_command_lookup() - , m_is_rpc(is_rpc) { m_command_lookup.set_handler( "q" @@ -213,8 +207,6 @@ bool t_command_server::process_command_vec(const std::vector& cmd) bool t_command_server::start_handling(std::function exit_handler) { - if (m_is_rpc) return false; - m_command_lookup.start_handling("", get_commands_str(), exit_handler); return true; @@ -222,8 +214,6 @@ bool t_command_server::start_handling(std::function exit_handler) void t_command_server::stop_handling() { - if (m_is_rpc) return; - m_command_lookup.stop_handling(); } diff --git a/src/daemon/command_server.h b/src/daemon/command_server.h index 5df457288..10499f0f2 100644 --- a/src/daemon/command_server.h +++ b/src/daemon/command_server.h @@ -48,15 +48,9 @@ class t_command_server { private: t_command_parser_executor m_parser; epee::console_handlers_binder m_command_lookup; - bool m_is_rpc; public: - t_command_server( - uint32_t ip - , uint16_t port - , bool is_rpc = true - , cryptonote::core_rpc_server* rpc_server = NULL - ); + t_command_server(); bool process_command_str(const std::string& cmd); diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 2cf92c3d3..677404a5e 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -117,17 +117,22 @@ bool t_daemon::run(bool interactive) try { + daemonize::t_command_server* rpc_commands; + mp_internals->core.run(); if (interactive) { IPC::Daemon::init(mp_internals->core.get(), mp_internals->p2p.get(), mp_internals->testnet_mode); + rpc_commands = new daemonize::t_command_server(); + rpc_commands->start_handling(std::bind(&daemonize::t_daemon::stop_p2p, this)); } mp_internals->p2p.run(); // blocks until p2p goes down if (interactive) { + rpc_commands->stop_handling(); IPC::Daemon::stop(); } diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index b7d95ba27..b75f2fddc 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -223,7 +223,7 @@ int main(int argc, char const * argv[]) return 1; } - daemonize::t_command_server rpc_commands{rpc_ip, rpc_port}; + daemonize::t_command_server rpc_commands{}; if (rpc_commands.process_command_vec(command)) { return 0; diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 131ff0828..1ef1a45e9 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -34,6 +34,10 @@ #include "rpc/core_rpc_server_commands_defs.h" #include "cryptonote_core/cryptonote_core.h" #include "cryptonote_core/hardfork.h" +#include "ipc/include/daemon_ipc_handlers.h" +#include "rapidjson/document.h" +#include "rapidjson/writer.h" +#include "rapidjson/stringbuffer.h" #include #include #include @@ -41,18 +45,19 @@ namespace daemonize { namespace { - void print_peer(std::string const & prefix, cryptonote::peer const & peer) + template + void print_peer(const std::string &prefix, T &peer) { time_t now; time(&now); - time_t last_seen = static_cast(peer.last_seen); + time_t last_seen = static_cast(peer["last_seen"].GetInt()); std::string id_str; std::string port_str; std::string elapsed = epee::misc_utils::get_time_interval_string(now - last_seen); - std::string ip_str = epee::string_tools::get_ip_string_from_int32(peer.ip); - epee::string_tools::xtype_to_string(peer.id, id_str); - epee::string_tools::xtype_to_string(peer.port, port_str); + std::string ip_str = epee::string_tools::get_ip_string_from_int32(peer["ip"].GetUint()); + epee::string_tools::xtype_to_string(peer["id"].GetUint64(), id_str); + epee::string_tools::xtype_to_string(peer["port"].GetUint(), port_str); std::string addr_str = ip_str + ":" + port_str; tools::msg_writer() << boost::format("%-10s %-25s %-25s %s") % prefix % id_str % addr_str % elapsed; } @@ -72,182 +77,143 @@ namespace { } } -t_rpc_command_executor::t_rpc_command_executor( - uint32_t ip - , uint16_t port - , bool is_rpc - , cryptonote::core_rpc_server* rpc_server - ) - : m_rpc_client(NULL), m_rpc_server(rpc_server) +t_rpc_command_executor::t_rpc_command_executor() + : ipc_client(NULL) { - if (is_rpc) - { - m_rpc_client = new tools::t_rpc_client(ip, port); - } - else - { - if (rpc_server == NULL) - { - throw std::runtime_error("If not calling commands via RPC, rpc_server pointer must be non-null"); - } - } - - m_is_rpc = is_rpc; } t_rpc_command_executor::~t_rpc_command_executor() { - if (m_rpc_client != NULL) - { - delete m_rpc_client; + if (ipc_client) { + wap_client_destroy(&ipc_client); + } +} + +bool t_rpc_command_executor::check_connection_to_daemon() const +{ + return ipc_client && wap_client_connected(ipc_client); +} + +bool t_rpc_command_executor::connect_to_daemon() +{ + if (check_connection_to_daemon()) { + return true; } + ipc_client = wap_client_new(); + wap_client_connect(ipc_client, "ipc://@/monero", 200, "wallet identity"); + if (!check_connection_to_daemon()) { + wap_client_destroy(&ipc_client); // this sets ipc_client to NULL + return false; + } + return true; } bool t_rpc_command_executor::print_peer_list() { - cryptonote::COMMAND_RPC_GET_PEER_LIST::request req; - cryptonote::COMMAND_RPC_GET_PEER_LIST::response res; - - std::string failure_message = "Couldn't retrieve peer list"; - if (m_is_rpc) - { - if (!m_rpc_client->rpc_request(req, res, "/get_peer_list", failure_message.c_str())) - { - return false; - } + if (!connect_to_daemon()) { + tools::fail_msg_writer() << "Failed to connect to daemon"; + return true; } - else - { - if (!m_rpc_server->on_get_peer_list(req, res)) - { - tools::fail_msg_writer() << failure_message; - return false; - } + if (wap_client_get_peer_list(ipc_client) < 0) { + tools::fail_msg_writer() << "Couldn't retrieve peer list"; + return true; } - for (auto & peer : res.white_list) - { - print_peer("white", peer); + rapidjson::Document response_json; + rapidjson::Document::AllocatorType &allocator = response_json.GetAllocator(); + rapidjson::Value result_json; + result_json.SetObject(); + + zframe_t *white_list_frame = wap_client_white_list(ipc_client); + rapidjson::Document white_list_json; + const char *data = reinterpret_cast(zframe_data(white_list_frame)); + size_t size = zframe_size(white_list_frame); + + if (white_list_json.Parse(data, size).HasParseError()) { + tools::fail_msg_writer() << "Couldn't parse JSON sent by daemon."; + return true; } - for (auto & peer : res.gray_list) - { - print_peer("gray", peer); + for (size_t n = 0; n < white_list_json["peers"].Size(); ++n) { + print_peer("white", white_list_json["peers"][n]); + } + + zframe_t *gray_list_frame = wap_client_gray_list(ipc_client); + rapidjson::Document gray_list_json; + data = reinterpret_cast(zframe_data(gray_list_frame)); + size = zframe_size(gray_list_frame); + + if (gray_list_json.Parse(data, size).HasParseError()) { + tools::fail_msg_writer() << "Couldn't parse JSON sent by daemon."; + return true; + } + + for (size_t n = 0; n < gray_list_json["peers"].Size(); ++n) { + print_peer("gray", gray_list_json["peers"][n]); } return true; } bool t_rpc_command_executor::save_blockchain() { - cryptonote::COMMAND_RPC_SAVE_BC::request req; - cryptonote::COMMAND_RPC_SAVE_BC::response res; - - std::string fail_message = "Couldn't save blockchain"; - - if (m_is_rpc) - { - if (!m_rpc_client->rpc_request(req, res, "/save_bc", fail_message.c_str())) - { - return true; - } + if (!connect_to_daemon()) { + tools::fail_msg_writer() << "Failed to connect to daemon"; + return true; } - else - { - if (!m_rpc_server->on_save_bc(req, res)) - { - tools::fail_msg_writer() << fail_message.c_str(); - } + if (wap_client_save_bc (ipc_client) < 0) { + tools::fail_msg_writer() << "Couldn't save blockchain"; + return true; } - tools::success_msg_writer() << "Blockchain saved"; + tools::success_msg_writer() << "Blockchain saved"; return true; } bool t_rpc_command_executor::show_hash_rate() { - cryptonote::COMMAND_RPC_SET_LOG_HASH_RATE::request req; - cryptonote::COMMAND_RPC_SET_LOG_HASH_RATE::response res; - req.visible = true; - - std::string fail_message = "Unsuccessful"; - - if (m_is_rpc) - { - if (!m_rpc_client->rpc_request(req, res, "/set_log_hash_rate", fail_message.c_str())) - { - return true; - } + if (!connect_to_daemon()) { + tools::fail_msg_writer() << "Failed to connect to daemon"; + return true; } - else - { - if (!m_rpc_server->on_set_log_hash_rate(req, res)) - { - tools::fail_msg_writer() << fail_message.c_str(); - } + if (!wap_client_set_log_hash_rate(ipc_client, 1) < 0) { + tools::fail_msg_writer() << "Failed to enable hash rate logging"; + return true; } - tools::success_msg_writer() << "Hash rate logging is on"; - return true; } bool t_rpc_command_executor::hide_hash_rate() { - cryptonote::COMMAND_RPC_SET_LOG_HASH_RATE::request req; - cryptonote::COMMAND_RPC_SET_LOG_HASH_RATE::response res; - req.visible = false; - - std::string fail_message = "Unsuccessful"; - - if (m_is_rpc) - { - if (!m_rpc_client->rpc_request(req, res, "/set_log_hash_rate", fail_message.c_str())) - { - return true; - } + if (!connect_to_daemon()) { + tools::fail_msg_writer() << "Failed to connect to daemon"; + return true; } - else - { - if (!m_rpc_server->on_set_log_hash_rate(req, res)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } + if (!wap_client_set_log_hash_rate(ipc_client, 0) < 0) { + tools::fail_msg_writer() << "Failed to disable hash rate logging"; + return true; } - tools::success_msg_writer() << "Hash rate logging is off"; - return true; } bool t_rpc_command_executor::show_difficulty() { - cryptonote::COMMAND_RPC_GET_INFO::request req; - cryptonote::COMMAND_RPC_GET_INFO::response res; - - std::string fail_message = "Problem fetching info"; - - if (m_is_rpc) - { - if (!m_rpc_client->rpc_request(req, res, "/getinfo", fail_message.c_str())) - { - return true; - } + if (!connect_to_daemon()) { + tools::fail_msg_writer() << "Failed to connect to daemon"; + return true; } - else - { - if (!m_rpc_server->on_get_info(req, res)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } + if (wap_client_get_info(ipc_client) < 0) { + tools::fail_msg_writer() << "Failed to get info"; + return true; } - - tools::success_msg_writer() << "BH: " << res.height - << ", DIFF: " << res.difficulty - << ", HR: " << (int) res.difficulty / 60L << " H/s"; - + uint64_t height = wap_client_height(ipc_client); + uint64_t difficulty = wap_client_difficulty(ipc_client); + tools::success_msg_writer() << "BH: " << height + << ", DIFF: " << difficulty + << ", HR: " << (int) difficulty / 60L << " H/s"; return true; } bool t_rpc_command_executor::show_status() { +#if 0 cryptonote::COMMAND_RPC_GET_INFO::request ireq; cryptonote::COMMAND_RPC_GET_INFO::response ires; cryptonote::COMMAND_RPC_HARD_FORK_INFO::request hfreq; @@ -297,31 +263,23 @@ bool t_rpc_command_executor::show_status() { % (hfres.state == cryptonote::HardFork::Ready ? "up to date" : hfres.state == cryptonote::HardFork::UpdateNeeded ? "update needed" : "out of date, likely forked") % (unsigned)ires.outgoing_connections_count % (unsigned)ires.incoming_connections_count ; +#endif return true; } bool t_rpc_command_executor::print_connections() { +#if 0 cryptonote::COMMAND_RPC_GET_CONNECTIONS::request req; cryptonote::COMMAND_RPC_GET_CONNECTIONS::response res; epee::json_rpc::error error_resp; std::string fail_message = "Unsuccessful"; - if (m_is_rpc) + if (!m_rpc_server->on_get_connections(req, res, error_resp)) { - if (!m_rpc_client->json_rpc_request(req, res, "get_connections", fail_message.c_str())) - { - return true; - } - } - else - { - if (!m_rpc_server->on_get_connections(req, res, error_resp)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } + tools::fail_msg_writer() << fail_message.c_str(); + return true; } tools::msg_writer() << std::setw(30) << std::left << "Remote Host" @@ -357,6 +315,7 @@ bool t_rpc_command_executor::print_connections() { //tools::msg_writer() << boost::format("%-25s peer_id: %-25s %s") % address % info.peer_id % in_out; } +#endif return true; } @@ -408,61 +367,34 @@ bool t_rpc_command_executor::print_blockchain_info(uint64_t start_block_index, u } bool t_rpc_command_executor::set_log_level(int8_t level) { - cryptonote::COMMAND_RPC_SET_LOG_LEVEL::request req; - cryptonote::COMMAND_RPC_SET_LOG_LEVEL::response res; - req.level = level; - - std::string fail_message = "Unsuccessful"; - - if (m_is_rpc) - { - if (!m_rpc_client->rpc_request(req, res, "/set_log_level", fail_message.c_str())) - { - return true; - } + if (!connect_to_daemon()) { + tools::fail_msg_writer() << "Failed to connect to daemon"; + return true; } - else - { - if (!m_rpc_server->on_set_log_level(req, res)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } + if (wap_client_set_log_level(ipc_client, level) < 0) { + tools::fail_msg_writer() << "Failed to set log level"; + return true; } - tools::success_msg_writer() << "Log level is now " << std::to_string(level); - return true; } bool t_rpc_command_executor::print_height() { - cryptonote::COMMAND_RPC_GET_HEIGHT::request req; - cryptonote::COMMAND_RPC_GET_HEIGHT::response res; - - std::string fail_message = "Unsuccessful"; - - if (m_is_rpc) - { - if (!m_rpc_client->rpc_request(req, res, "/getheight", fail_message.c_str())) - { - return true; - } + if (!connect_to_daemon()) { + tools::fail_msg_writer() << "Failed to connect to daemon"; + return true; } - else - { - if (!m_rpc_server->on_get_height(req, res)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } + if (wap_client_get_height(ipc_client) < 0) { + tools::fail_msg_writer() << "Failed to get height"; + return true; } - - tools::success_msg_writer() << boost::lexical_cast(res.height); - + uint64_t height = wap_client_height(ipc_client); + tools::success_msg_writer() << boost::lexical_cast(height); return true; } bool t_rpc_command_executor::print_block_by_hash(crypto::hash block_hash) { +#if 0 cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::request req; cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::response res; epee::json_rpc::error error_resp; @@ -471,28 +403,20 @@ bool t_rpc_command_executor::print_block_by_hash(crypto::hash block_hash) { std::string fail_message = "Unsuccessful"; - if (m_is_rpc) + if (!m_rpc_server->on_get_block_header_by_hash(req, res, error_resp)) { - if (!m_rpc_client->json_rpc_request(req, res, "getblockheaderbyhash", fail_message.c_str())) - { - return true; - } - } - else - { - if (!m_rpc_server->on_get_block_header_by_hash(req, res, error_resp)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } + tools::fail_msg_writer() << fail_message.c_str(); + return true; } print_block_header(res.block_header); +#endif return true; } bool t_rpc_command_executor::print_block_by_height(uint64_t height) { +#if 0 cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::request req; cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::response res; epee::json_rpc::error error_resp; @@ -501,48 +425,30 @@ bool t_rpc_command_executor::print_block_by_height(uint64_t height) { std::string fail_message = "Unsuccessful"; - if (m_is_rpc) + if (!m_rpc_server->on_get_block_header_by_height(req, res, error_resp)) { - if (!m_rpc_client->json_rpc_request(req, res, "getblockheaderbyheight", fail_message.c_str())) - { - return true; - } - } - else - { - if (!m_rpc_server->on_get_block_header_by_height(req, res, error_resp)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } + tools::fail_msg_writer() << fail_message.c_str(); + return true; } print_block_header(res.block_header); +#endif return true; } bool t_rpc_command_executor::print_transaction(crypto::hash transaction_hash) { +#if 0 cryptonote::COMMAND_RPC_GET_TRANSACTIONS::request req; cryptonote::COMMAND_RPC_GET_TRANSACTIONS::response res; std::string fail_message = "Problem fetching transaction"; - if (m_is_rpc) + req.txs_hashes.push_back(epee::string_tools::pod_to_hex(transaction_hash)); + if (!m_rpc_server->on_get_transactions(req, res)) { - if (!m_rpc_client->rpc_request(req, res, "/gettransactions", fail_message.c_str())) - { - return true; - } - } - else - { - req.txs_hashes.push_back(epee::string_tools::pod_to_hex(transaction_hash)); - if (!m_rpc_server->on_get_transactions(req, res)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } + tools::fail_msg_writer() << fail_message.c_str(); + return true; } if (1 == res.txs_as_hex.size()) @@ -571,31 +477,23 @@ bool t_rpc_command_executor::print_transaction(crypto::hash transaction_hash) { { tools::fail_msg_writer() << "transaction wasn't found: " << transaction_hash << std::endl; } +#endif return true; } bool t_rpc_command_executor::is_key_image_spent(const crypto::key_image &ki) { +#if 0 cryptonote::COMMAND_RPC_IS_KEY_IMAGE_SPENT::request req; cryptonote::COMMAND_RPC_IS_KEY_IMAGE_SPENT::response res; - std::string fail_message = "Problem checkking key image"; + std::string fail_message = "Problem checking key image"; req.key_images.push_back(epee::string_tools::pod_to_hex(ki)); - if (m_is_rpc) + if (!m_rpc_server->on_is_key_image_spent(req, res)) { - if (!m_rpc_client->rpc_request(req, res, "/is_key_image_spent", fail_message.c_str())) - { - return true; - } - } - else - { - if (!m_rpc_server->on_is_key_image_spent(req, res)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } + tools::fail_msg_writer() << fail_message.c_str(); + return true; } if (1 == res.spent_status.size()) @@ -607,30 +505,22 @@ bool t_rpc_command_executor::is_key_image_spent(const crypto::key_image &ki) { { tools::fail_msg_writer() << "key image status could not be determined" << std::endl; } +#endif return true; } bool t_rpc_command_executor::print_transaction_pool_long() { +#if 0 cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL::request req; cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL::response res; std::string fail_message = "Problem fetching transaction pool"; - if (m_is_rpc) + if (!m_rpc_server->on_get_transaction_pool(req, res)) { - if (!m_rpc_client->rpc_request(req, res, "/get_transaction_pool", fail_message.c_str())) - { - return true; - } - } - else - { - if (!m_rpc_server->on_get_transaction_pool(req, res)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } + tools::fail_msg_writer() << fail_message.c_str(); + return true; } if (res.transactions.empty() && res.spent_key_images.empty()) @@ -686,30 +576,22 @@ bool t_rpc_command_executor::print_transaction_pool_long() { tools::msg_writer() << "WARNING: Inconsistent pool state - no transactions"; } } +#endif return true; } bool t_rpc_command_executor::print_transaction_pool_short() { +#if 0 cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL::request req; cryptonote::COMMAND_RPC_GET_TRANSACTION_POOL::response res; std::string fail_message = "Problem fetching transaction pool"; - if (m_is_rpc) + if (!m_rpc_server->on_get_transaction_pool(req, res)) { - if (!m_rpc_client->rpc_request(req, res, "/get_transaction_pool", fail_message.c_str())) - { - return true; - } - } - else - { - if (!m_rpc_server->on_get_transaction_pool(req, res)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } + tools::fail_msg_writer() << fail_message.c_str(); + return true; } if (res.transactions.empty()) @@ -727,122 +609,78 @@ bool t_rpc_command_executor::print_transaction_pool_short() { << "last_failed_height: " << tx_info.last_failed_height << std::endl << "last_failed_id: " << tx_info.last_failed_id_hash << std::endl; } +#endif return true; } bool t_rpc_command_executor::start_mining(cryptonote::account_public_address address, uint64_t num_threads, bool testnet) { - cryptonote::COMMAND_RPC_START_MINING::request req; - cryptonote::COMMAND_RPC_START_MINING::response res; - req.miner_address = cryptonote::get_account_address_as_str(testnet, address); - req.threads_count = num_threads; - - std::string fail_message = "Mining did not start"; - - if (m_is_rpc) - { - if (m_rpc_client->rpc_request(req, res, "/start_mining", fail_message.c_str())) - { - tools::success_msg_writer() << "Mining started"; - } - } - else - { - if (!m_rpc_server->on_start_mining(req, res)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } + if (!connect_to_daemon()) { + tools::fail_msg_writer() << "Failed to connect to daemon"; + return true; } + std::string address_str = cryptonote::get_account_address_as_str(testnet, address); + zchunk_t *address_chunk = zchunk_new((void*)address_str.c_str(), address_str.length()); + int ret = wap_client_start(ipc_client, &address_chunk, num_threads); + zchunk_destroy(&address_chunk); + if (ret < 0) { + tools::fail_msg_writer() << "Failed to start mining"; + return true; + } + + uint64_t status = wap_client_status(ipc_client); + if (status == IPC::STATUS_CORE_BUSY) { + tools::fail_msg_writer() << "Core busy"; + return true; + } + if (status == IPC::STATUS_WRONG_ADDRESS) + { + tools::fail_msg_writer() << "Wrong address"; + return true; + } + if (status == IPC::STATUS_MINING_NOT_STARTED) + { + tools::fail_msg_writer() << "Failed to start mining"; + return true; + } + tools::success_msg_writer() << "Mining started"; return true; } bool t_rpc_command_executor::stop_mining() { - cryptonote::COMMAND_RPC_STOP_MINING::request req; - cryptonote::COMMAND_RPC_STOP_MINING::response res; - - std::string fail_message = "Mining did not stop"; - - if (m_is_rpc) - { - if (!m_rpc_client->rpc_request(req, res, "/stop_mining", fail_message.c_str())) - { - return true; - } - } - else - { - if (!m_rpc_server->on_stop_mining(req, res)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } + if (!connect_to_daemon()) { + tools::fail_msg_writer() << "Failed to connect to daemon"; + return true; } + if (wap_client_stop(ipc_client) < 0) { + tools::fail_msg_writer() << "Failed to stop mining"; + return true; + } + + uint64_t status = wap_client_status(ipc_client); + if (status == IPC::STATUS_CORE_BUSY) { + tools::fail_msg_writer() << "Core busy"; + return true; + } tools::success_msg_writer() << "Mining stopped"; return true; } bool t_rpc_command_executor::stop_daemon() { - cryptonote::COMMAND_RPC_STOP_DAEMON::request req; - cryptonote::COMMAND_RPC_STOP_DAEMON::response res; - -//# ifdef WIN32 -// // Stop via service API -// // TODO - this is only temporary! Get rid of hard-coded constants! -// bool ok = windows::stop_service("BitMonero Daemon"); -// ok = windows::uninstall_service("BitMonero Daemon"); -// //bool ok = windows::stop_service(SERVICE_NAME); -// //ok = windows::uninstall_service(SERVICE_NAME); -// if (ok) -// { -// return true; -// } -//# endif - - // Stop via RPC - std::string fail_message = "Daemon did not stop"; - - if (m_is_rpc) - { - if(!m_rpc_client->rpc_request(req, res, "/stop_daemon", fail_message.c_str())) - { - return true; - } + if (!connect_to_daemon()) { + tools::fail_msg_writer() << "Failed to connect to daemon"; + return true; } - else - { - if (!m_rpc_server->on_stop_daemon(req, res)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } - } - - tools::success_msg_writer() << "Stop signal sent"; - + tools::fail_msg_writer() << "Daemon can't stop, no IPC for, har, har"; return true; } bool t_rpc_command_executor::print_status() { - if (!m_is_rpc) - { - tools::success_msg_writer() << "print_status makes no sense in interactive mode"; - return true; - } - - bool daemon_is_alive = m_rpc_client->check_connection(); - - if(daemon_is_alive) { - tools::success_msg_writer() << "bitmonerod is running"; - } - else { - tools::fail_msg_writer() << "bitmonerod is NOT running"; - } - + tools::success_msg_writer() << "print_status makes no sense in interactive mode"; return true; } @@ -894,34 +732,26 @@ bool t_rpc_command_executor::set_limit_down(int limit) bool t_rpc_command_executor::fast_exit() { +#if 0 cryptonote::COMMAND_RPC_FAST_EXIT::request req; cryptonote::COMMAND_RPC_FAST_EXIT::response res; std::string fail_message = "Daemon did not stop"; - if (m_is_rpc) + if (!m_rpc_server->on_fast_exit(req, res)) { - if (!m_rpc_client->rpc_request(req, res, "/fast_exit", fail_message.c_str())) - { - return true; - } - } - - else - { - if (!m_rpc_server->on_fast_exit(req, res)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } + tools::fail_msg_writer() << fail_message.c_str(); + return true; } tools::success_msg_writer() << "Daemon stopped"; +#endif return true; } bool t_rpc_command_executor::out_peers(uint64_t limit) { +#if 0 cryptonote::COMMAND_RPC_OUT_PEERS::request req; cryptonote::COMMAND_RPC_OUT_PEERS::response res; @@ -931,78 +761,47 @@ bool t_rpc_command_executor::out_peers(uint64_t limit) std::string fail_message = "Unsuccessful"; - if (m_is_rpc) + if (!m_rpc_server->on_out_peers(req, res)) { - if (!m_rpc_client->json_rpc_request(req, res, "out_peers", fail_message.c_str())) - { - return true; - } - } - else - { - if (!m_rpc_server->on_out_peers(req, res)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } + tools::fail_msg_writer() << fail_message.c_str(); + return true; } +#endif return true; } bool t_rpc_command_executor::start_save_graph() { - cryptonote::COMMAND_RPC_START_SAVE_GRAPH::request req; - cryptonote::COMMAND_RPC_START_SAVE_GRAPH::response res; - std::string fail_message = "Unsuccessful"; - - if (m_is_rpc) - { - if (!m_rpc_client->rpc_request(req, res, "/start_save_graph", fail_message.c_str())) - { - return true; - } - } - - else - { - if (!m_rpc_server->on_start_save_graph(req, res)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } - } - - return true; + if (!connect_to_daemon()) { + tools::fail_msg_writer() << "Failed to connect to daemon"; + return true; + } + if (wap_client_start_save_graph(ipc_client) < 0) { + tools::fail_msg_writer() << "Failed to start saving graph"; + return true; + } + tools::success_msg_writer() << "Started saving graph"; + return true; } bool t_rpc_command_executor::stop_save_graph() { - cryptonote::COMMAND_RPC_STOP_SAVE_GRAPH::request req; - cryptonote::COMMAND_RPC_STOP_SAVE_GRAPH::response res; - std::string fail_message = "Unsuccessful"; - - if (m_is_rpc) - { - if (!m_rpc_client->rpc_request(req, res, "/stop_save_graph", fail_message.c_str())) - { - return true; - } - } - - else - { - if (!m_rpc_server->on_stop_save_graph(req, res)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } - } - return true; + if (!connect_to_daemon()) { + tools::fail_msg_writer() << "Failed to connect to daemon"; + return true; + } + if (wap_client_stop_save_graph(ipc_client) < 0) { + tools::fail_msg_writer() << "Failed to stop saving graph"; + return true; + } + tools::success_msg_writer() << "Stopped saving graph"; + return true; } bool t_rpc_command_executor::hard_fork_info(uint8_t version) { +#if 0 cryptonote::COMMAND_RPC_HARD_FORK_INFO::request req; cryptonote::COMMAND_RPC_HARD_FORK_INFO::response res; std::string fail_message = "Unsuccessful"; @@ -1010,26 +809,17 @@ bool t_rpc_command_executor::hard_fork_info(uint8_t version) req.version = version; - if (m_is_rpc) + if (!m_rpc_server->on_hard_fork_info(req, res, error_resp)) { - if (!m_rpc_client->json_rpc_request(req, res, "hard_fork_info", fail_message.c_str())) - { - return true; - } - } - else - { - if (!m_rpc_server->on_hard_fork_info(req, res, error_resp)) - { - tools::fail_msg_writer() << fail_message.c_str(); - return true; - } + tools::fail_msg_writer() << fail_message.c_str(); + return true; } version = version > 0 ? version : res.voting; tools::msg_writer() << "version " << (uint32_t)version << " " << (res.enabled ? "enabled" : "not enabled") << ", " << res.votes << "/" << res.window << " votes, threshold " << res.threshold; tools::msg_writer() << "current version " << (uint32_t)res.version << ", voting for version " << (uint32_t)res.voting; +#endif return true; } diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h index 778b73acb..c93a14d14 100644 --- a/src/daemon/rpc_command_executor.h +++ b/src/daemon/rpc_command_executor.h @@ -43,23 +43,13 @@ #include "cryptonote_core/cryptonote_core.h" #include "cryptonote_protocol/cryptonote_protocol_handler.h" #include "p2p/net_node.h" -#include "rpc/core_rpc_server.h" +#include "wap_library.h" namespace daemonize { class t_rpc_command_executor final { -private: - tools::t_rpc_client* m_rpc_client; - cryptonote::core_rpc_server* m_rpc_server; - bool m_is_rpc; - public: - t_rpc_command_executor( - uint32_t ip - , uint16_t port - , bool is_rpc = true - , cryptonote::core_rpc_server* rpc_server = NULL - ); + t_rpc_command_executor(); ~t_rpc_command_executor(); @@ -124,6 +114,13 @@ public: bool stop_save_graph(); bool hard_fork_info(uint8_t version); + +private: + bool check_connection_to_daemon() const; + bool connect_to_daemon(); + +private: + wap_client_t *ipc_client; }; } // namespace daemonize From 33a87469c02989cac6c7c206548ed0caf1a411c3 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 31 Oct 2015 10:09:24 +0000 Subject: [PATCH 04/13] daemon_ipc_handlers: ctor/dtor cleanup Reset pointers to NULL when stopped, stop if trying to init a non stop server, remove copy pasted doc block that doesn't make sense for stop. --- src/ipc/daemon_ipc_handlers.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/ipc/daemon_ipc_handlers.cpp b/src/ipc/daemon_ipc_handlers.cpp index c86536fcd..c5de1663f 100644 --- a/src/ipc/daemon_ipc_handlers.cpp +++ b/src/ipc/daemon_ipc_handlers.cpp @@ -47,11 +47,11 @@ */ namespace { - cryptonote::core *core; /*!< Pointer to the core */ - nodetool::node_server > *p2p; + cryptonote::core *core = NULL; /*!< Pointer to the core */ + nodetool::node_server > *p2p = NULL; /*!< Pointer to p2p node server */ - zactor_t *server; /*!< 0MQ server */ - bool testnet; /*!< testnet mode or not */ + zactor_t *server = NULL; /*!< 0MQ server */ + bool testnet = false; /*!< testnet mode or not */ /*! * \brief Checks if core is busy @@ -126,6 +126,8 @@ namespace IPC nodetool::node_server > &p_p2p, bool p_testnet) { + if (server) + stop(); p2p = &p_p2p; core = &p_core; testnet = p_testnet; @@ -136,13 +138,12 @@ namespace IPC /*! * \brief stops the IPC server - * - * \param p_core cryptonote core object - * \param p_p2p p2p object - * \param p_testnet testnet mode or not */ void stop() { zactor_destroy(&server); + server = NULL; + p2p = NULL; + core = NULL; } /*! From ead65ba824246f70d9ee4eb835cb90db298ee872 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 31 Oct 2015 10:47:53 +0000 Subject: [PATCH 05/13] daemon_ipc_handlers: fix inverted return value in check_core_busy documentation --- src/ipc/daemon_ipc_handlers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ipc/daemon_ipc_handlers.cpp b/src/ipc/daemon_ipc_handlers.cpp index c5de1663f..9886ea823 100644 --- a/src/ipc/daemon_ipc_handlers.cpp +++ b/src/ipc/daemon_ipc_handlers.cpp @@ -56,7 +56,7 @@ namespace /*! * \brief Checks if core is busy * - * \return true if core is busy + * \return false if core is busy */ bool check_core_busy() { From d7a0de604b338ee3d11ada35312b5864f1672e3b Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 31 Oct 2015 10:48:55 +0000 Subject: [PATCH 06/13] daemon_ipc_handers: fix check_core_ready returning ready when not ready --- src/ipc/daemon_ipc_handlers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ipc/daemon_ipc_handlers.cpp b/src/ipc/daemon_ipc_handlers.cpp index 9886ea823..fdb5bc7ee 100644 --- a/src/ipc/daemon_ipc_handlers.cpp +++ b/src/ipc/daemon_ipc_handlers.cpp @@ -74,7 +74,7 @@ namespace */ bool check_core_ready() { - if (p2p->get_payload_object().is_synchronized()) + if (!p2p->get_payload_object().is_synchronized()) { return false; } From 359d62642b7d75a67ead0f0bc60da68c3d2a0317 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 31 Oct 2015 10:49:39 +0000 Subject: [PATCH 07/13] daemon_ipc_handlers: return after error when getting random outs --- src/ipc/daemon_ipc_handlers.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ipc/daemon_ipc_handlers.cpp b/src/ipc/daemon_ipc_handlers.cpp index fdb5bc7ee..1ac27d8d6 100644 --- a/src/ipc/daemon_ipc_handlers.cpp +++ b/src/ipc/daemon_ipc_handlers.cpp @@ -381,6 +381,7 @@ namespace IPC if (!core->get_random_outs_for_amounts(req, res)) { wap_proto_set_status(message, STATUS_RANDOM_OUTS_FAILED); + return; } // We convert the result into a JSON string and put it into a 0MQ frame. From 939b1d11f0b190c4fd4e1d27975022e3766ccaf8 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 31 Oct 2015 19:54:57 +0000 Subject: [PATCH 08/13] daemon_deprecated_rpc: fix signedness warning --- src/rpc/daemon_deprecated_rpc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/daemon_deprecated_rpc.cpp b/src/rpc/daemon_deprecated_rpc.cpp index cd02120ee..b41bd7cbc 100644 --- a/src/rpc/daemon_deprecated_rpc.cpp +++ b/src/rpc/daemon_deprecated_rpc.cpp @@ -833,7 +833,7 @@ namespace uint64_t start_height = request_json["start_height"].GetUint(); uint64_t block_count = request_json["blocks_ids"].Size(); zlist_t *list = zlist_new(); - for (int i = 0; i < block_count; i++) { + for (uint64_t i = 0; i < block_count; i++) { if (!request_json["blocks_ids"][i].IsString()) { zlist_destroy(&list); return ns_rpc_create_error(buf, len, req, invalid_params, From 81d89c030152506df2eaad98bae6e1e728147e88 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 31 Oct 2015 19:59:03 +0000 Subject: [PATCH 09/13] ipc: fix const issues Files were regenerated with a patched zproto generator --- src/ipc/include/wap_proto.h | 2 +- src/ipc/include/wap_server_engine.inc | 3 ++- src/ipc/wap_proto.c | 12 ++++++------ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/ipc/include/wap_proto.h b/src/ipc/include/wap_proto.h index a3ede6cdc..38b2470db 100644 --- a/src/ipc/include/wap_proto.h +++ b/src/ipc/include/wap_proto.h @@ -563,7 +563,7 @@ void wap_proto_set_reason (wap_proto_t *self, const char *value); // Self test of this class -int +void wap_proto_test (bool verbose); // @end diff --git a/src/ipc/include/wap_server_engine.inc b/src/ipc/include/wap_server_engine.inc index 4f4f5443e..b09d54c47 100644 --- a/src/ipc/include/wap_server_engine.inc +++ b/src/ipc/include/wap_server_engine.inc @@ -113,7 +113,7 @@ typedef struct { uint client_id; // Client identifier counter size_t timeout; // Default client expiry timeout bool verbose; // Verbose logging enabled? - char *log_prefix; // Default log prefix + const char *log_prefix; // Default log prefix } s_server_t; @@ -1318,6 +1318,7 @@ s_server_new (zsock_t *pipe) self->pipe = pipe; self->router = zsock_new (ZMQ_ROUTER); + assert (self->router); // By default the socket will discard outgoing messages above the // HWM of 1,000. This isn't helpful for high-volume streaming. We // will use a unbounded queue here. If applications need to guard diff --git a/src/ipc/wap_proto.c b/src/ipc/wap_proto.c index 1d0acc444..51d5f9e17 100644 --- a/src/ipc/wap_proto.c +++ b/src/ipc/wap_proto.c @@ -2490,7 +2490,9 @@ wap_proto_set_reason (wap_proto_t *self, const char *value) // -------------------------------------------------------------------------- // Selftest -int +#if 0 +/* This code trolls const, and is just needed for tests, take it out for now */ +void wap_proto_test (bool verbose) { printf (" * wap_proto:"); @@ -2544,10 +2546,8 @@ wap_proto_test (bool verbose) wap_proto_set_id (self, WAP_PROTO_BLOCKS); zlist_t *blocks_block_ids = zlist_new (); - char name[] = "Name: Brutus"; - zlist_append (blocks_block_ids, name); - char age[] = "Age: 43"; - zlist_append (blocks_block_ids, age); + zlist_append (blocks_block_ids, "Name: Brutus"); + zlist_append (blocks_block_ids, "Age: 43"); wap_proto_set_block_ids (self, &blocks_block_ids); wap_proto_set_start_height (self, 123); // Send twice @@ -3143,5 +3143,5 @@ wap_proto_test (bool verbose) // @end printf ("OK\n"); - return 0; } +#endif From 383d96f5e2996e3b6b452527279c936c3dbe07b5 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 31 Oct 2015 19:59:44 +0000 Subject: [PATCH 10/13] daemon_deprecated_rpc: fix and simplify NUL terminated buffer handling Remove the arbitrary 1000 byte limit, get the large buffers off the stack, and fix user controlled stack smashing which could plausibly lead to arbitrary code execution. --- src/rpc/daemon_deprecated_rpc.cpp | 39 ++++++++++--------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/src/rpc/daemon_deprecated_rpc.cpp b/src/rpc/daemon_deprecated_rpc.cpp index b41bd7cbc..3bad883c4 100644 --- a/src/rpc/daemon_deprecated_rpc.cpp +++ b/src/rpc/daemon_deprecated_rpc.cpp @@ -218,13 +218,8 @@ namespace "Parameters missing.", "{}"); } rapidjson::Document request_json; - char request_buf[1000]; - strncpy(request_buf, req->params[0].ptr, req->params[0].len); - size_t zidx = sizeof(request_buf) - 1; - if (req->params[0].len < zidx) - zidx = req->params[0].len; - request_buf[zidx] = '\0'; - if (request_json.Parse(request_buf).HasParseError()) + std::string request_buf(req->params[0].ptr, req->params[0].len); + if (request_json.Parse(request_buf.c_str()).HasParseError()) { return ns_rpc_create_error(buf, len, req, parse_error, "Invalid JSON passed", "{}"); @@ -478,10 +473,8 @@ namespace } rapidjson::Document request_json; - char request_buf[1000]; - strncpy(request_buf, req->params[0].ptr, req->params[0].len); - request_buf[req->params[0].len] = '\0'; - if (request_json.Parse(request_buf).HasParseError()) + std::string request_buf(req->params[0].ptr, req->params[0].len); + if (request_json.Parse(request_buf.c_str()).HasParseError()) { return ns_rpc_create_error(buf, len, req, parse_error, "Invalid JSON passed", "{}"); @@ -533,10 +526,8 @@ namespace } rapidjson::Document request_json; - char request_buf[1000]; - strncpy(request_buf, req->params[0].ptr, req->params[0].len); - request_buf[req->params[0].len] = '\0'; - if (request_json.Parse(request_buf).HasParseError()) + std::string request_buf(req->params[0].ptr, req->params[0].len); + if (request_json.Parse(request_buf.c_str()).HasParseError()) { return ns_rpc_create_error(buf, len, req, parse_error, "Invalid JSON passed", "{}"); @@ -665,10 +656,8 @@ namespace } rapidjson::Document request_json; - char request_buf[1000]; - strncpy(request_buf, req->params[0].ptr, req->params[0].len); - request_buf[req->params[0].len] = '\0'; - if (request_json.Parse(request_buf).HasParseError()) + std::string request_buf(req->params[0].ptr, req->params[0].len); + if (request_json.Parse(request_buf.c_str()).HasParseError()) { return ns_rpc_create_error(buf, len, req, parse_error, "Invalid JSON passed", "{}"); @@ -726,10 +715,8 @@ namespace } rapidjson::Document request_json; - char request_buf[1000]; - strncpy(request_buf, req->params[0].ptr, req->params[0].len); - request_buf[req->params[0].len] = '\0'; - if (request_json.Parse(request_buf).HasParseError()) + std::string request_buf(req->params[0].ptr, req->params[0].len); + if (request_json.Parse(request_buf.c_str()).HasParseError()) { return ns_rpc_create_error(buf, len, req, parse_error, "Invalid JSON passed", "{}"); @@ -810,10 +797,8 @@ namespace } rapidjson::Document request_json; - char request_buf[1000]; - strncpy(request_buf, req->params[0].ptr, req->params[0].len); - request_buf[req->params[0].len] = '\0'; - if (request_json.Parse(request_buf).HasParseError()) + std::string request_buf(req->params[0].ptr, req->params[0].len); + if (request_json.Parse(request_buf.c_str()).HasParseError()) { return ns_rpc_create_error(buf, len, req, parse_error, "Invalid JSON passed", "{}"); From 035b22d88370c323674a1a858a719aed84e1a839 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 31 Oct 2015 20:59:42 +0000 Subject: [PATCH 11/13] ipc: fix a const trolling issue This file doesn't appear to be generated, but there's a version that's generated in monero-0mq, so I'm not super certain... --- src/ipc/wap_server/wap_server.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ipc/wap_server/wap_server.c b/src/ipc/wap_server/wap_server.c index 98b2a3fa5..3c1f83895 100644 --- a/src/ipc/wap_server/wap_server.c +++ b/src/ipc/wap_server/wap_server.c @@ -106,12 +106,13 @@ client_terminate (client_t *self) void wap_server_test (bool verbose) { + static char server_string[] = "server"; printf (" * wap_server: "); if (verbose) printf ("\n"); // @selftest - zactor_t *server = zactor_new (wap_server, "server"); + zactor_t *server = zactor_new (wap_server, server_string); if (verbose) zstr_send (server, "VERBOSE"); zstr_sendx (server, "BIND", "ipc://@/wap_server", NULL); From 2e7c83c126577b89f0b0bd58f8f0d09d08bb8281 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 31 Oct 2015 21:06:56 +0000 Subject: [PATCH 12/13] ipc: regenerate from patched zproto To fix some more const trolling issues --- src/ipc/include/wap_client_engine.inc | 4 ++-- src/ipc/include/wap_server_engine.inc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ipc/include/wap_client_engine.inc b/src/ipc/include/wap_client_engine.inc index 202970bb8..93918c1a4 100644 --- a/src/ipc/include/wap_client_engine.inc +++ b/src/ipc/include/wap_client_engine.inc @@ -100,7 +100,7 @@ typedef enum { } event_t; // Names for state machine logging and error reporting -static char * +static const char * s_state_name [] = { "(NONE)", "start", @@ -130,7 +130,7 @@ s_state_name [] = { "reexpect open ok" }; -static char * +static const char * s_event_name [] = { "(NONE)", "connect", diff --git a/src/ipc/include/wap_server_engine.inc b/src/ipc/include/wap_server_engine.inc index b09d54c47..e271a7541 100644 --- a/src/ipc/include/wap_server_engine.inc +++ b/src/ipc/include/wap_server_engine.inc @@ -57,7 +57,7 @@ typedef enum { } event_t; // Names for state machine logging and error reporting -static char * +static const char * s_state_name [] = { "(NONE)", "start", @@ -66,7 +66,7 @@ s_state_name [] = { "settling" }; -static char * +static const char * s_event_name [] = { "(NONE)", "terminate", From da90892774a788d223bfd19622aacb30ab934379 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 31 Oct 2015 21:07:26 +0000 Subject: [PATCH 13/13] ipc: do NOT build with -Wno-write-strings It is evil, and can make real bugs. --- src/ipc/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ipc/CMakeLists.txt b/src/ipc/CMakeLists.txt index 40c04b62d..f0f08f63f 100644 --- a/src/ipc/CMakeLists.txt +++ b/src/ipc/CMakeLists.txt @@ -36,7 +36,7 @@ set(client_ipc_sources wap_proto.c) set_source_files_properties(${server_ipc_sources} ${client_ipc_sources} PROPERTIES LANGUAGE CXX) -set_source_files_properties(${server_ipc_sources} ${client_ipc_sources} PROPERTIES COMPILE_FLAGS "-Wno-write-strings -Wno-error -fpermissive") +set_source_files_properties(${server_ipc_sources} ${client_ipc_sources} PROPERTIES COMPILE_FLAGS "-Wno-error -fpermissive") set(server_ipc_headers) set(client_ipc_headers)