From 02c04aa30051566a958ee8f1ace67b34c9c270fb Mon Sep 17 00:00:00 2001 From: sowle Date: Thu, 10 Oct 2019 11:12:28 +0300 Subject: [PATCH] p2p: filter out old clients by version + unittest #128 --- .../currency_protocol_handler.inl | 3 +- src/p2p/net_node.inl | 6 +++ src/version.h.in | 40 +++++++++++++++ tests/unit_tests/p2p_client_version.cpp | 51 +++++++++++++++++++ 4 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 tests/unit_tests/p2p_client_version.cpp diff --git a/src/currency_protocol/currency_protocol_handler.inl b/src/currency_protocol/currency_protocol_handler.inl index e4588490..a5ee5b1f 100644 --- a/src/currency_protocol/currency_protocol_handler.inl +++ b/src/currency_protocol/currency_protocol_handler.inl @@ -174,7 +174,8 @@ namespace currency "That means that current software is outdated, please updated it." << "Current heigh lay under checkpoints on remote host, so it is not possible validate this transactions on local host, disconnecting.", LOG_LEVEL_0); return false; - }else if (m_core.get_blockchain_storage().get_checkpoints().get_top_checkpoint_height() < hshd.last_checkpoint_height) + } + else if (m_core.get_blockchain_storage().get_checkpoints().get_top_checkpoint_height() < hshd.last_checkpoint_height) { LOG_PRINT_MAGENTA("Remote node have longer checkpoints zone( " << hshd.last_checkpoint_height << ") " << "that local (" << m_core.get_blockchain_storage().get_checkpoints().get_top_checkpoint_height() << ")" << diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 2ce7099c..72cadef1 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -483,6 +483,12 @@ namespace nodetool return; } + if (!check_remote_client_version(rsp.payload_data.client_version)) + { + LOG_PRINT_CCONTEXT_L2("COMMAND_HANDSHAKE Failed, wrong client version: " << rsp.payload_data.client_version << ", closing connection."); + return; + } + if(!handle_maintainers_entry(rsp.maintrs_entry)) { LOG_ERROR_CCONTEXT("COMMAND_HANDSHAKE Failed, wrong maintainers entry!, closing connection."); diff --git a/src/version.h.in b/src/version.h.in index e68df5ce..61d98d65 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -1,3 +1,4 @@ +#pragma once #include "misc_language.h" #define BUILD_COMMIT_ID "@VERSION@" @@ -10,3 +11,42 @@ #define PROJECT_VERSION_BUILD_NO 67 #define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO) #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]" + + + +inline bool check_remote_client_version(const std::string& client_ver) +{ + std::string v = client_ver.substr(0, client_ver.find('[')); // remove commit id + v = v.substr(0, v.rfind('.')); // remove build number + + int v_major = 0, v_minor = 0, v_revision = 0; + + size_t dot_pos = v.find('.'); + if (dot_pos == std::string::npos || !epee::string_tools::string_to_num_fast(v.substr(0, dot_pos), v_major)) + return false; + + v = v.substr(dot_pos + 1); + dot_pos = v.find('.'); + if (!epee::string_tools::string_to_num_fast(v.substr(0, dot_pos), v_minor)) + return false; + + if (dot_pos != std::string::npos) + { + // revision + v = v.substr(dot_pos + 1); + if (!epee::string_tools::string_to_num_fast(v, v_revision)) + return false; + } + + // got v_major, v_minor, v_revision + + // allow 1.1.x and greater + + if (v_major < 1) + return false; + + if (v_major == 1 && v_minor < 1) + return false; + + return true; +} diff --git a/tests/unit_tests/p2p_client_version.cpp b/tests/unit_tests/p2p_client_version.cpp new file mode 100644 index 00000000..73b44559 --- /dev/null +++ b/tests/unit_tests/p2p_client_version.cpp @@ -0,0 +1,51 @@ +// Copyright (c) 2019 Zano Project +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "gtest/gtest.h" +#include "version.h" + +TEST(p2p_client_version, test_1) +{ + // good + + ASSERT_TRUE(check_remote_client_version("10.101.999.28391[deadbeef31337-dirty]")); + ASSERT_TRUE(check_remote_client_version("1.1.9.237[aabcd]")); + ASSERT_TRUE(check_remote_client_version("3.0.2.7[aa00bcd]")); + ASSERT_TRUE(check_remote_client_version("1.4.2.7[aabcd]")); + ASSERT_TRUE(check_remote_client_version("1.1.2.67[88f868c]")); + + ASSERT_TRUE(check_remote_client_version("1.1.2.67[88f868c]")); + ASSERT_TRUE(check_remote_client_version("1.1.2.67[26c00a8]")); + ASSERT_TRUE(check_remote_client_version("1.1.2.67[26c00a8-dirty]")); + + ASSERT_TRUE(check_remote_client_version("1.1.0.65[40ba8cd]")); + ASSERT_TRUE(check_remote_client_version("1.1.0.63[b0f376b]")); + + ASSERT_TRUE(check_remote_client_version("1.1.0.58[14bd668]")); + ASSERT_TRUE(check_remote_client_version("1.1.0.58[9920eb7]")); + ASSERT_TRUE(check_remote_client_version("1.1.0.58[e0d4ad8]")); + + ASSERT_TRUE(check_remote_client_version("1.1.0.57[b77b915]")); + ASSERT_TRUE(check_remote_client_version("1.1.0.57[7dd61ae]")); + ASSERT_TRUE(check_remote_client_version("1.1.0.57[7dd61ae-dirty]")); + + ASSERT_TRUE(check_remote_client_version("1.1.0.57")); + + // bad + + ASSERT_FALSE(check_remote_client_version("")); + ASSERT_FALSE(check_remote_client_version(" ")); + + ASSERT_FALSE(check_remote_client_version("1.0.999")); + + ASSERT_FALSE(check_remote_client_version("1.0.40[f77f0d7]")); + ASSERT_FALSE(check_remote_client_version("1.0.40[734b726]")); + ASSERT_FALSE(check_remote_client_version("1.0.41[488e369]")); + + ASSERT_FALSE(check_remote_client_version("1.0.40[469]")); + ASSERT_FALSE(check_remote_client_version("1.0.39[f77f0d7]")); + ASSERT_FALSE(check_remote_client_version("1.0.38[f77f0d7-dirty]")); + ASSERT_FALSE(check_remote_client_version("1.0.37[7dd61ae-dirty]")); + ASSERT_FALSE(check_remote_client_version("0.0.500[000]")); +}