diff options
Diffstat (limited to 'contrib/epee/include')
-rw-r--r-- | contrib/epee/include/fnv1.h | 45 | ||||
-rw-r--r-- | contrib/epee/include/hex.h | 6 | ||||
-rw-r--r-- | contrib/epee/include/misc_os_dependent.h | 2 | ||||
-rw-r--r-- | contrib/epee/include/mlocker.h | 87 | ||||
-rw-r--r-- | contrib/epee/include/net/abstract_tcp_server2.h | 1 | ||||
-rw-r--r-- | contrib/epee/include/net/abstract_tcp_server2.inl | 33 | ||||
-rw-r--r-- | contrib/epee/include/net/http_protocol_handler.inl | 18 | ||||
-rw-r--r-- | contrib/epee/include/net/http_server_handlers_map2.h | 1 | ||||
-rw-r--r-- | contrib/epee/include/serialization/keyvalue_serialization.h | 9 | ||||
-rw-r--r-- | contrib/epee/include/serialization/keyvalue_serialization_overloads.h | 6 | ||||
-rw-r--r-- | contrib/epee/include/storages/parserse_base_utils.h | 9 | ||||
-rw-r--r-- | contrib/epee/include/string_tools.h | 7 | ||||
-rw-r--r-- | contrib/epee/include/wipeable_string.h | 45 |
13 files changed, 256 insertions, 13 deletions
diff --git a/contrib/epee/include/fnv1.h b/contrib/epee/include/fnv1.h new file mode 100644 index 000000000..c04389bca --- /dev/null +++ b/contrib/epee/include/fnv1.h @@ -0,0 +1,45 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +namespace epee +{ + +namespace fnv +{ + inline uint64_t FNV1a(const char *ptr, size_t sz) + { + uint64_t h = 0xcbf29ce484222325; + for (size_t i = 0; i < sz; ++i) + h = (h ^ *(const uint8_t*)ptr++) * 0x100000001b3; + return h; + } +} + +} diff --git a/contrib/epee/include/hex.h b/contrib/epee/include/hex.h index e960da1d2..901c666a9 100644 --- a/contrib/epee/include/hex.h +++ b/contrib/epee/include/hex.h @@ -33,6 +33,7 @@ #include <iosfwd> #include <string> +#include "wipeable_string.h" #include "span.h" namespace epee @@ -41,6 +42,9 @@ namespace epee { //! \return A std::string containing hex of `src`. static std::string string(const span<const std::uint8_t> src); + //! \return A epee::wipeable_string containing hex of `src`. + static epee::wipeable_string wipeable_string(const span<const std::uint8_t> src); + template<typename T> static epee::wipeable_string wipeable_string(const T &pod) { return wipeable_string(span<const uint8_t>((const uint8_t*)&pod, sizeof(pod))); } //! \return An array containing hex of `src`. template<std::size_t N> @@ -59,6 +63,8 @@ namespace epee static void formatted(std::ostream& out, const span<const std::uint8_t> src); private: + template<typename T> T static convert(const span<const std::uint8_t> src); + //! Write `src` bytes as hex to `out`. `out` must be twice the length static void buffer_unchecked(char* out, const span<const std::uint8_t> src) noexcept; }; diff --git a/contrib/epee/include/misc_os_dependent.h b/contrib/epee/include/misc_os_dependent.h index ffe575501..0d09683d6 100644 --- a/contrib/epee/include/misc_os_dependent.h +++ b/contrib/epee/include/misc_os_dependent.h @@ -24,7 +24,7 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // #ifdef _WIN32 -#include <Winsock2.h> +#include <winsock2.h> #endif #ifdef WIN32 diff --git a/contrib/epee/include/mlocker.h b/contrib/epee/include/mlocker.h new file mode 100644 index 000000000..d2fc2ed58 --- /dev/null +++ b/contrib/epee/include/mlocker.h @@ -0,0 +1,87 @@ +// Copyright (c) 2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include <map> +#include <boost/thread/mutex.hpp> + +namespace epee +{ + class mlocker + { + public: + mlocker(void *ptr, size_t len); + ~mlocker(); + + static size_t get_page_size(); + static size_t get_num_locked_pages(); + static size_t get_num_locked_objects(); + + static void lock(void *ptr, size_t len); + static void unlock(void *ptr, size_t len); + + private: + static size_t page_size; + static size_t num_locked_objects; + + static boost::mutex &mutex(); + static std::map<size_t, unsigned int> &map(); + static void lock_page(size_t page); + static void unlock_page(size_t page); + + void *ptr; + size_t len; + }; + + /// Locks memory while in scope + /// + /// Primarily useful for making sure that private keys don't get swapped out + // to disk + template <class T> + struct mlocked : public T { + using type = T; + + mlocked(): T() { mlocker::lock(this, sizeof(T)); } + mlocked(const T &t): T(t) { mlocker::lock(this, sizeof(T)); } + mlocked(const mlocked<T> &mt): T(mt) { mlocker::lock(this, sizeof(T)); } + mlocked(const T &&t): T(t) { mlocker::lock(this, sizeof(T)); } + mlocked(const mlocked<T> &&mt): T(mt) { mlocker::lock(this, sizeof(T)); } + mlocked<T> &operator=(const mlocked<T> &mt) { T::operator=(mt); return *this; } + ~mlocked() { mlocker::unlock(this, sizeof(T)); } + }; + + template<typename T> + T& unwrap(mlocked<T>& src) { return src; } + + template<typename T> + const T& unwrap(mlocked<T> const& src) { return src; } + + template <class T, size_t N> + using mlocked_arr = mlocked<std::array<T, N>>; +} diff --git a/contrib/epee/include/net/abstract_tcp_server2.h b/contrib/epee/include/net/abstract_tcp_server2.h index 7ca6ac872..b2c05ebb0 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.h +++ b/contrib/epee/include/net/abstract_tcp_server2.h @@ -158,6 +158,7 @@ namespace net_utils std::list<boost::shared_ptr<connection<t_protocol_handler> > > m_self_refs; // add_ref/release support critical_section m_self_refs_lock; critical_section m_chunking_lock; // held while we add small chunks of the big do_send() to small do_send_chunk() + critical_section m_shutdown_lock; // held while shutting down t_connection_type m_connection_type; diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl index 5b3550005..3a5c83017 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.inl +++ b/contrib/epee/include/net/abstract_tcp_server2.inl @@ -649,6 +649,10 @@ PRAGMA_WARNING_DISABLE_VS(4355) template<class t_protocol_handler> bool connection<t_protocol_handler>::shutdown() { + CRITICAL_REGION_BEGIN(m_shutdown_lock); + if (m_was_shutdown) + return true; + m_was_shutdown = true; // Initiate graceful connection closure. m_timer.cancel(); boost::system::error_code ignored_ec; @@ -658,7 +662,7 @@ PRAGMA_WARNING_DISABLE_VS(4355) try { host_count(m_host, -1); } catch (...) { /* ignore */ } m_host = ""; } - m_was_shutdown = true; + CRITICAL_REGION_END(); m_protocol_handler.release_protocol(); return true; } @@ -667,6 +671,9 @@ PRAGMA_WARNING_DISABLE_VS(4355) bool connection<t_protocol_handler>::close() { TRY_ENTRY(); + auto self = safe_shared_from_this(); + if(!self) + return false; //_info("[sock " << socket_.native_handle() << "] Que Shutdown called."); m_timer.cancel(); size_t send_que_size = 0; @@ -1102,8 +1109,16 @@ POP_WARNINGS sock_.open(remote_endpoint.protocol()); if(bind_ip != "0.0.0.0" && bind_ip != "0" && bind_ip != "" ) { - boost::asio::ip::tcp::endpoint local_endpoint(boost::asio::ip::address::from_string(adr.c_str()), 0); - sock_.bind(local_endpoint); + boost::asio::ip::tcp::endpoint local_endpoint(boost::asio::ip::address::from_string(bind_ip.c_str()), 0); + boost::system::error_code ec; + sock_.bind(local_endpoint, ec); + if (ec) + { + MERROR("Error binding to " << bind_ip << ": " << ec.message()); + if (sock_.is_open()) + sock_.close(); + return false; + } } /* @@ -1208,8 +1223,16 @@ POP_WARNINGS sock_.open(remote_endpoint.protocol()); if(bind_ip != "0.0.0.0" && bind_ip != "0" && bind_ip != "" ) { - boost::asio::ip::tcp::endpoint local_endpoint(boost::asio::ip::address::from_string(adr.c_str()), 0); - sock_.bind(local_endpoint); + boost::asio::ip::tcp::endpoint local_endpoint(boost::asio::ip::address::from_string(bind_ip.c_str()), 0); + boost::system::error_code ec; + sock_.bind(local_endpoint, ec); + if (ec) + { + MERROR("Error binding to " << bind_ip << ": " << ec.message()); + if (sock_.is_open()) + sock_.close(); + return false; + } } boost::shared_ptr<boost::asio::deadline_timer> sh_deadline(new boost::asio::deadline_timer(io_service_)); diff --git a/contrib/epee/include/net/http_protocol_handler.inl b/contrib/epee/include/net/http_protocol_handler.inl index 0bdba0bfe..76db5346f 100644 --- a/contrib/epee/include/net/http_protocol_handler.inl +++ b/contrib/epee/include/net/http_protocol_handler.inl @@ -328,8 +328,10 @@ namespace net_utils inline bool analize_http_method(const boost::smatch& result, http::http_method& method, int& http_ver_major, int& http_ver_minor) { CHECK_AND_ASSERT_MES(result[0].matched, false, "simple_http_connection_handler::analize_http_method() assert failed..."); - http_ver_major = boost::lexical_cast<int>(result[11]); - http_ver_minor = boost::lexical_cast<int>(result[12]); + if (!boost::conversion::try_lexical_convert<int>(result[11], http_ver_major)) + return false; + if (!boost::conversion::try_lexical_convert<int>(result[12], http_ver_minor)) + return false; if(result[3].matched) method = http::http_method_options; @@ -351,13 +353,18 @@ namespace net_utils template<class t_connection_context> bool simple_http_connection_handler<t_connection_context>::handle_invoke_query_line() { - STATIC_REGEXP_EXPR_1(rexp_match_command_line, "^(((OPTIONS)|(GET)|(HEAD)|(POST)|(PUT)|(DELETE)|(TRACE)) (\\S+) HTTP/(\\d+).(\\d+))\r?\n", boost::regex::icase | boost::regex::normal); + STATIC_REGEXP_EXPR_1(rexp_match_command_line, "^(((OPTIONS)|(GET)|(HEAD)|(POST)|(PUT)|(DELETE)|(TRACE)) (\\S+) HTTP/(\\d+)\\.(\\d+))\r?\n", boost::regex::icase | boost::regex::normal); // 123 4 5 6 7 8 9 10 11 12 //size_t match_len = 0; boost::smatch result; if(boost::regex_search(m_cache, result, rexp_match_command_line, boost::match_default) && result[0].matched) { - analize_http_method(result, m_query_info.m_http_method, m_query_info.m_http_ver_hi, m_query_info.m_http_ver_hi); + if (!analize_http_method(result, m_query_info.m_http_method, m_query_info.m_http_ver_hi, m_query_info.m_http_ver_hi)) + { + m_state = http_state_error; + MERROR("Failed to analyze method"); + return false; + } m_query_info.m_URI = result[10]; if (!parse_uri(m_query_info.m_URI, m_query_info.m_uri_content)) { @@ -554,7 +561,8 @@ namespace net_utils if(!(boost::regex_search( str, result, rexp_mach_field, boost::match_default) && result[0].matched)) return false; - len = boost::lexical_cast<size_t>(result[0]); + try { len = boost::lexical_cast<size_t>(result[0]); } + catch(...) { return false; } return true; } //----------------------------------------------------------------------------------- diff --git a/contrib/epee/include/net/http_server_handlers_map2.h b/contrib/epee/include/net/http_server_handlers_map2.h index 429e3e1af..00a867d3e 100644 --- a/contrib/epee/include/net/http_server_handlers_map2.h +++ b/contrib/epee/include/net/http_server_handlers_map2.h @@ -122,6 +122,7 @@ if(!ps.load_from_json(query_info.m_body)) \ { \ boost::value_initialized<epee::json_rpc::error_response> rsp; \ + static_cast<epee::json_rpc::error_response&>(rsp).jsonrpc = "2.0"; \ static_cast<epee::json_rpc::error_response&>(rsp).error.code = -32700; \ static_cast<epee::json_rpc::error_response&>(rsp).error.message = "Parse error"; \ epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(rsp), response_info.m_body); \ diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h index 5791e1998..fc5a21851 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization.h +++ b/contrib/epee/include/serialization/keyvalue_serialization.h @@ -85,6 +85,14 @@ public: \ static_assert(std::is_pod<decltype(this_ref.varialble)>::value, "t_type must be a POD type."); \ KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, val_name) +#define KV_SERIALIZE_VAL_POD_AS_BLOB_OPT_N(varialble, val_name, default_value) \ + do { \ + static_assert(std::is_pod<decltype(this_ref.varialble)>::value, "t_type must be a POD type."); \ + bool ret = KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, val_name); \ + if (!ret) \ + epee::serialize_default(this_ref.varialble, default_value); \ + } while(0); + #define KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(varialble, val_name) \ epee::serialization::selector<is_store>::serialize_stl_container_pod_val_as_blob(this_ref.varialble, stg, hparent_section, val_name); @@ -92,6 +100,7 @@ public: \ #define KV_SERIALIZE(varialble) KV_SERIALIZE_N(varialble, #varialble) #define KV_SERIALIZE_VAL_POD_AS_BLOB(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_N(varialble, #varialble) +#define KV_SERIALIZE_VAL_POD_AS_BLOB_OPT(varialble, def) KV_SERIALIZE_VAL_POD_AS_BLOB_OPT_N(varialble, #varialble, def) #define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(varialble) KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, #varialble) //skip is_pod compile time check #define KV_SERIALIZE_CONTAINER_POD_AS_BLOB(varialble) KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(varialble, #varialble) #define KV_SERIALIZE_OPT(variable,default_value) KV_SERIALIZE_OPT_N(variable, #variable, default_value) diff --git a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h index 09087f785..15c95f07a 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h +++ b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h @@ -35,6 +35,11 @@ namespace epee { + namespace + { + template<class C> void hint_resize(C &container, size_t size) {} + template<class C> void hint_resize(std::vector<C> &container, size_t size) { container.reserve(size); } + } namespace serialization { @@ -158,6 +163,7 @@ namespace epee false, "size in blob " << loaded_size << " not have not zero modulo for sizeof(value_type) = " << sizeof(typename stl_container::value_type) << ", type " << typeid(typename stl_container::value_type).name()); size_t count = (loaded_size/sizeof(typename stl_container::value_type)); + hint_resize(container, count); for(size_t i = 0; i < count; i++) container.insert(container.end(), *(pelem++)); } diff --git a/contrib/epee/include/storages/parserse_base_utils.h b/contrib/epee/include/storages/parserse_base_utils.h index c809392f4..8c6c1a64d 100644 --- a/contrib/epee/include/storages/parserse_base_utils.h +++ b/contrib/epee/include/storages/parserse_base_utils.h @@ -28,6 +28,8 @@ #pragma once +#include <algorithm> + namespace epee { namespace misc_utils @@ -36,8 +38,12 @@ namespace misc_utils { inline std::string transform_to_escape_sequence(const std::string& src) { - //std::stringstream res; + static const char escaped[] = "\b\f\n\r\t\v\"\\/"; + if (std::find_first_of(src.begin(), src.end(), escaped, escaped + sizeof(escaped)) == src.end()) + return src; + std::string res; + res.reserve(2 * src.size()); for(std::string::const_iterator it = src.begin(); it!=src.end(); ++it) { switch(*it) @@ -84,6 +90,7 @@ namespace misc_utils inline void match_string2(std::string::const_iterator& star_end_string, std::string::const_iterator buf_end, std::string& val) { val.clear(); + val.reserve(std::distance(star_end_string, buf_end)); bool escape_mode = false; std::string::const_iterator it = star_end_string; ++it; diff --git a/contrib/epee/include/string_tools.h b/contrib/epee/include/string_tools.h index 8d8603076..aba065cc7 100644 --- a/contrib/epee/include/string_tools.h +++ b/contrib/epee/include/string_tools.h @@ -46,6 +46,7 @@ #include <boost/algorithm/string/predicate.hpp> #include "hex.h" #include "memwipe.h" +#include "mlocker.h" #include "span.h" #include "warnings.h" @@ -358,6 +359,12 @@ POP_WARNINGS return hex_to_pod(hex_str, unwrap(s)); } //---------------------------------------------------------------------------- + template<class t_pod_type> + bool hex_to_pod(const std::string& hex_str, epee::mlocked<t_pod_type>& s) + { + return hex_to_pod(hex_str, unwrap(s)); + } + //---------------------------------------------------------------------------- bool validate_hex(uint64_t length, const std::string& str); //---------------------------------------------------------------------------- inline std::string get_extension(const std::string& str) diff --git a/contrib/epee/include/wipeable_string.h b/contrib/epee/include/wipeable_string.h index 70d1a9586..31854fe2e 100644 --- a/contrib/epee/include/wipeable_string.h +++ b/contrib/epee/include/wipeable_string.h @@ -28,28 +28,46 @@ #pragma once +#include <boost/optional/optional.hpp> #include <stddef.h> #include <vector> #include <string> +#include "memwipe.h" +#include "fnv1.h" namespace epee { class wipeable_string { public: + typedef char value_type; + wipeable_string() {} wipeable_string(const wipeable_string &other); wipeable_string(wipeable_string &&other); wipeable_string(const std::string &other); wipeable_string(std::string &&other); wipeable_string(const char *s); + wipeable_string(const char *s, size_t len); ~wipeable_string(); void wipe(); void push_back(char c); - void pop_back(); + void operator+=(char c); + void operator+=(const std::string &s); + void operator+=(const epee::wipeable_string &s); + void operator+=(const char *s); + void append(const char *ptr, size_t len); + char pop_back(); const char *data() const noexcept { return buffer.data(); } + char *data() noexcept { return buffer.data(); } size_t size() const noexcept { return buffer.size(); } + size_t length() const noexcept { return buffer.size(); } bool empty() const noexcept { return buffer.empty(); } + void trim(); + void split(std::vector<wipeable_string> &fields) const; + boost::optional<wipeable_string> parse_hexstr() const; + template<typename T> inline bool hex_to_pod(T &pod) const; + template<typename T> inline bool hex_to_pod(tools::scrubbed<T> &pod) const { return hex_to_pod(unwrap(pod)); } void resize(size_t sz); void reserve(size_t sz); void clear(); @@ -64,4 +82,29 @@ namespace epee private: std::vector<char> buffer; }; + + template<typename T> inline bool wipeable_string::hex_to_pod(T &pod) const + { + static_assert(std::is_pod<T>::value, "expected pod type"); + if (size() != sizeof(T) * 2) + return false; + boost::optional<epee::wipeable_string> blob = parse_hexstr(); + if (!blob) + return false; + if (blob->size() != sizeof(T)) + return false; + pod = *(const T*)blob->data(); + return true; + } +} + +namespace std +{ + template<> struct hash<epee::wipeable_string> + { + size_t operator()(const epee::wipeable_string &s) const + { + return epee::fnv::FNV1a(s.data(), s.size()); + } + }; } |