aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/CMakeLists.txt6
-rw-r--r--src/common/boost_serialization_helper.h1
-rw-r--r--src/common/dns_utils.cpp2
-rw-r--r--src/common/download.cpp61
-rw-r--r--src/common/memwipe.c106
-rw-r--r--src/common/memwipe.h84
-rw-r--r--src/common/password.cpp39
-rw-r--r--src/common/password.h6
-rw-r--r--src/common/perf_timer.cpp39
-rw-r--r--src/common/perf_timer.h36
-rw-r--r--src/common/stack_trace.cpp1
-rw-r--r--src/common/updates.cpp3
-rw-r--r--src/common/util.cpp21
13 files changed, 327 insertions, 78 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 50887e35c..7ad08ea83 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -35,6 +35,7 @@ set(common_sources
download.cpp
util.cpp
i18n.cpp
+ memwipe.c
password.cpp
perf_timer.cpp
threadpool.cpp
@@ -63,6 +64,7 @@ set(common_private_headers
util.h
varint.h
i18n.h
+ memwipe.h
password.h
perf_timer.h
stack_trace.h
@@ -90,5 +92,9 @@ target_link_libraries(common
${OPENSSL_LIBRARIES}
${EXTRA_LIBRARIES})
+if(HAVE_C11)
+SET_PROPERTY(SOURCE memwipe.c PROPERTY COMPILE_FLAGS -std=c11)
+endif()
+
#monero_install_headers(common
# ${common_headers})
diff --git a/src/common/boost_serialization_helper.h b/src/common/boost_serialization_helper.h
index 4a503d830..f8b21c52e 100644
--- a/src/common/boost_serialization_helper.h
+++ b/src/common/boost_serialization_helper.h
@@ -33,6 +33,7 @@
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/portable_binary_oarchive.hpp>
#include <boost/archive/portable_binary_iarchive.hpp>
+#include <boost/filesystem/operations.hpp>
namespace tools
diff --git a/src/common/dns_utils.cpp b/src/common/dns_utils.cpp
index f549218cb..d942ae9d0 100644
--- a/src/common/dns_utils.cpp
+++ b/src/common/dns_utils.cpp
@@ -34,6 +34,8 @@
#include "include_base_utils.h"
#include <random>
#include <boost/filesystem/fstream.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
using namespace epee;
namespace bf = boost::filesystem;
diff --git a/src/common/download.cpp b/src/common/download.cpp
index 28aac5a59..87814fa5e 100644
--- a/src/common/download.cpp
+++ b/src/common/download.cpp
@@ -33,6 +33,7 @@
#include <boost/thread/thread.hpp>
#include "cryptonote_config.h"
#include "include_base_utils.h"
+#include "file_io_utils.h"
#include "net/http_client.h"
#include "download.h"
@@ -74,9 +75,20 @@ namespace tools
try
{
boost::unique_lock<boost::mutex> lock(control->mutex);
- MINFO("Downloading " << control->uri << " to " << control->path);
+ std::ios_base::openmode mode = std::ios_base::out | std::ios_base::binary;
+ uint64_t existing_size = 0;
+ if (epee::file_io_utils::get_file_size(control->path, existing_size) && existing_size > 0)
+ {
+ MINFO("Resuming downloading " << control->uri << " to " << control->path << " from " << existing_size);
+ mode |= std::ios_base::app;
+ }
+ else
+ {
+ MINFO("Downloading " << control->uri << " to " << control->path);
+ mode |= std::ios_base::trunc;
+ }
std::ofstream f;
- f.open(control->path, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
+ f.open(control->path, mode);
if (!f.good()) {
MERROR("Failed to open file " << control->path);
control->result_cb(control->path, control->uri, control->success);
@@ -85,11 +97,13 @@ namespace tools
class download_client: public epee::net_utils::http::http_simple_client
{
public:
- download_client(download_async_handle control, std::ofstream &f):
- control(control), f(f), content_length(-1), total(0) {}
+ download_client(download_async_handle control, std::ofstream &f, uint64_t offset = 0):
+ control(control), f(f), content_length(-1), total(0), offset(offset) {}
virtual ~download_client() { f.close(); }
virtual bool on_header(const epee::net_utils::http::http_response_info &headers)
{
+ for (const auto &kv: headers.m_header_info.m_etc_fields)
+ MDEBUG("Header: " << kv.first << ": " << kv.second);
ssize_t length;
if (epee::string_tools::get_xtype_from_string(length, headers.m_header_info.m_content_length) && length >= 0)
{
@@ -104,6 +118,26 @@ namespace tools
return false;
}
}
+ if (offset > 0)
+ {
+ // we requested a range, so check if we're getting it, otherwise truncate
+ bool got_range = false;
+ const std::string prefix = "bytes=" + std::to_string(offset) + "-";
+ for (const auto &kv: headers.m_header_info.m_etc_fields)
+ {
+ if (kv.first == "Content-Range" && strncmp(kv.second.c_str(), prefix.c_str(), prefix.size()))
+ {
+ got_range = true;
+ break;
+ }
+ }
+ if (!got_range)
+ {
+ MWARNING("We did not get the requested range, downloading from start");
+ f.close();
+ f.open(control->path, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
+ }
+ }
return true;
}
virtual bool handle_target_data(std::string &piece_of_transfer)
@@ -130,7 +164,8 @@ namespace tools
std::ofstream &f;
ssize_t content_length;
size_t total;
- } client(control, f);
+ uint64_t offset;
+ } client(control, f, existing_size);
epee::net_utils::http::url_content u_c;
if (!epee::net_utils::parse_url(control->uri, u_c))
{
@@ -147,9 +182,10 @@ namespace tools
lock.unlock();
- uint16_t port = u_c.port ? u_c.port : 80;
+ bool ssl = u_c.schema == "https";
+ uint16_t port = u_c.port ? u_c.port : ssl ? 443 : 80;
MDEBUG("Connecting to " << u_c.host << ":" << port);
- client.set_server(u_c.host, std::to_string(port), boost::none);
+ client.set_server(u_c.host, std::to_string(port), boost::none, ssl);
if (!client.connect(std::chrono::seconds(30)))
{
boost::lock_guard<boost::mutex> lock(control->mutex);
@@ -159,7 +195,14 @@ namespace tools
}
MDEBUG("GETting " << u_c.uri);
const epee::net_utils::http::http_response_info *info = NULL;
- if (!client.invoke_get(u_c.uri, std::chrono::seconds(30), "", &info))
+ epee::net_utils::http::fields_list fields;
+ if (existing_size > 0)
+ {
+ const std::string range = "bytes=" + std::to_string(existing_size) + "-";
+ MDEBUG("Asking for range: " << range);
+ fields.push_back(std::make_pair("Range", range));
+ }
+ if (!client.invoke_get(u_c.uri, std::chrono::seconds(30), "", &info, fields))
{
boost::lock_guard<boost::mutex> lock(control->mutex);
MERROR("Failed to connect to " << control->uri);
@@ -189,7 +232,7 @@ namespace tools
MDEBUG("response body: " << info->m_body);
for (const auto &f: info->m_additional_fields)
MDEBUG("additional field: " << f.first << ": " << f.second);
- if (info->m_response_code != 200)
+ if (info->m_response_code != 200 && info->m_response_code != 206)
{
boost::lock_guard<boost::mutex> lock(control->mutex);
MERROR("Status code " << info->m_response_code);
diff --git a/src/common/memwipe.c b/src/common/memwipe.c
new file mode 100644
index 000000000..da7e9f346
--- /dev/null
+++ b/src/common/memwipe.c
@@ -0,0 +1,106 @@
+// Copyright (c) 2017, 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.
+//
+// Parts of this file Copyright (c) 2009-2015 The Bitcoin Core developers
+
+#define __STDC_WANT_LIB_EXT1__ 1
+#include <string.h>
+#include <stdlib.h>
+#ifdef HAVE_EXPLICIT_BZERO
+#include <strings.h>
+#endif
+#include "memwipe.h"
+
+#if defined(_MSC_VER)
+#define SCARECROW \
+ __asm;
+#else
+#define SCARECROW \
+ __asm__ __volatile__("" : : "r"(ptr) : "memory");
+#endif
+
+#ifdef HAVE_MEMSET_S
+
+void *memwipe(void *ptr, size_t n)
+{
+ if (memset_s(ptr, n, 0, n))
+ {
+ abort();
+ }
+ SCARECROW // might as well...
+ return ptr;
+}
+
+#elif defined HAVE_EXPLICIT_BZERO
+
+void *memwipe(void *ptr, size_t n)
+{
+ explicit_bzero(ptr, n);
+ SCARECROW
+ return ptr;
+}
+
+#else
+
+/* The memory_cleanse implementation is taken from Bitcoin */
+
+/* Compilers have a bad habit of removing "superfluous" memset calls that
+ * are trying to zero memory. For example, when memset()ing a buffer and
+ * then free()ing it, the compiler might decide that the memset is
+ * unobservable and thus can be removed.
+ *
+ * Previously we used OpenSSL which tried to stop this by a) implementing
+ * memset in assembly on x86 and b) putting the function in its own file
+ * for other platforms.
+ *
+ * This change removes those tricks in favour of using asm directives to
+ * scare the compiler away. As best as our compiler folks can tell, this is
+ * sufficient and will continue to be so.
+ *
+ * Adam Langley <agl@google.com>
+ * Commit: ad1907fe73334d6c696c8539646c21b11178f20f
+ * BoringSSL (LICENSE: ISC)
+ */
+static void memory_cleanse(void *ptr, size_t len)
+{
+ memset(ptr, 0, len);
+
+ /* As best as we can tell, this is sufficient to break any optimisations that
+ might try to eliminate "superfluous" memsets. If there's an easy way to
+ detect memset_s, it would be better to use that. */
+ SCARECROW
+}
+
+void *memwipe(void *ptr, size_t n)
+{
+ memory_cleanse(ptr, n);
+ SCARECROW
+ return ptr;
+}
+
+#endif
diff --git a/src/common/memwipe.h b/src/common/memwipe.h
new file mode 100644
index 000000000..c3b4ce8ab
--- /dev/null
+++ b/src/common/memwipe.h
@@ -0,0 +1,84 @@
+// Copyright (c) 2017, 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.
+//
+// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+
+#pragma once
+
+#ifdef __cplusplus
+#include <array>
+
+extern "C" {
+#endif
+
+void *memwipe(void *src, size_t n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef __cplusplus
+namespace tools {
+
+ /// Scrubs data in the contained type upon destruction.
+ ///
+ /// Primarily useful for making sure that private keys don't stick around in
+ /// memory after the objects that held them have gone out of scope.
+ template <class T>
+ struct scrubbed : public T {
+ using type = T;
+
+ ~scrubbed() {
+ scrub();
+ }
+
+ /// Destroy the contents of the contained type.
+ void scrub() {
+ static_assert(std::is_pod<T>::value,
+ "T cannot be auto-scrubbed. T must be POD.");
+ static_assert(std::is_trivially_destructible<T>::value,
+ "T cannot be auto-scrubbed. T must be trivially destructable.");
+ memwipe(this, sizeof(T));
+ }
+ };
+
+ template <class T, size_t N>
+ using scrubbed_arr = scrubbed<std::array<T, N>>;
+} // namespace tools
+
+// Partial specialization for std::is_pod<tools::scrubbed<T>> so that it can
+// pretend to be the containted type in those contexts.
+namespace std
+{
+ template<class t_scrubbee>
+ struct is_pod<tools::scrubbed<t_scrubbee>> {
+ static const bool value = is_pod<t_scrubbee>::value;
+ };
+}
+
+#endif // __cplusplus
diff --git a/src/common/password.cpp b/src/common/password.cpp
index 5d56464a5..dc0856160 100644
--- a/src/common/password.cpp
+++ b/src/common/password.cpp
@@ -46,6 +46,8 @@
#include "readline_buffer.h"
#endif
+#include "common/memwipe.h"
+
namespace
{
#if defined(_WIN32)
@@ -54,7 +56,7 @@ namespace
return 0 != _isatty(_fileno(stdin));
}
- bool read_from_tty(std::string& pass)
+ bool read_from_tty(epee::wipeable_string& pass)
{
static constexpr const char BACKSPACE = 8;
@@ -86,8 +88,7 @@ namespace
{
if (!pass.empty())
{
- pass.back() = '\0';
- pass.resize(pass.size() - 1);
+ pass.pop_back();
}
}
else
@@ -125,7 +126,7 @@ namespace
return ch;
}
- bool read_from_tty(std::string& aPass)
+ bool read_from_tty(epee::wipeable_string& aPass)
{
static constexpr const char BACKSPACE = 127;
@@ -146,8 +147,7 @@ namespace
{
if (!aPass.empty())
{
- aPass.back() = '\0';
- aPass.resize(aPass.size() - 1);
+ aPass.pop_back();
}
}
else
@@ -161,14 +161,7 @@ namespace
#endif // end !WIN32
- void clear(std::string& pass) noexcept
- {
- //! TODO Call a memory wipe function that hopefully is not optimized out
- pass.replace(0, pass.capacity(), pass.capacity(), '\0');
- pass.clear();
- }
-
- bool read_from_tty(const bool verify, const char *message, std::string& pass1, std::string& pass2)
+ bool read_from_tty(const bool verify, const char *message, epee::wipeable_string& pass1, epee::wipeable_string& pass2)
{
while (true)
{
@@ -178,14 +171,14 @@ namespace
return false;
if (verify)
{
- std::cout << "Confirm Password: ";
+ std::cout << "Confirm password: ";
if (!read_from_tty(pass2))
return false;
if(pass1!=pass2)
{
std::cout << "Passwords do not match! Please try again." << std::endl;
- clear(pass1);
- clear(pass2);
+ pass1.clear();
+ pass2.clear();
}
else //new password matches
return true;
@@ -198,7 +191,7 @@ namespace
return false;
}
- bool read_from_file(std::string& pass)
+ bool read_from_file(epee::wipeable_string& pass)
{
pass.reserve(tools::password_container::max_password_size);
for (size_t i = 0; i < tools::password_container::max_password_size; ++i)
@@ -233,7 +226,7 @@ namespace tools
password_container::~password_container() noexcept
{
- clear(m_password);
+ m_password.clear();
}
boost::optional<password_container> password_container::prompt(const bool verify, const char *message)
@@ -249,9 +242,8 @@ namespace tools
boost::optional<login> login::parse(std::string&& userpass, bool verify, const std::function<boost::optional<password_container>(bool)> &prompt)
{
login out{};
- password_container wipe{std::move(userpass)};
- const auto loc = wipe.password().find(':');
+ const auto loc = userpass.find(':');
if (loc == std::string::npos)
{
auto result = prompt(verify);
@@ -262,10 +254,11 @@ namespace tools
}
else
{
- out.password = password_container{wipe.password().substr(loc + 1)};
+ out.password = password_container{userpass.substr(loc + 1)};
}
- out.username = wipe.password().substr(0, loc);
+ out.username = userpass.substr(0, loc);
+ password_container wipe{std::move(userpass)};
return {std::move(out)};
}
}
diff --git a/src/common/password.h b/src/common/password.h
index ba1c30a28..01c6bf05a 100644
--- a/src/common/password.h
+++ b/src/common/password.h
@@ -32,6 +32,7 @@
#include <string>
#include <boost/optional/optional.hpp>
+#include "wipeable_string.h"
namespace tools
{
@@ -58,11 +59,10 @@ namespace tools
password_container& operator=(const password_container&) = delete;
password_container& operator=(password_container&&) = default;
- const std::string& password() const noexcept { return m_password; }
+ const epee::wipeable_string &password() const noexcept { return m_password; }
private:
- //! TODO Custom allocator that locks to RAM?
- std::string m_password;
+ epee::wipeable_string m_password;
};
struct login
diff --git a/src/common/perf_timer.cpp b/src/common/perf_timer.cpp
index 3b68485d9..4947058d3 100644
--- a/src/common/perf_timer.cpp
+++ b/src/common/perf_timer.cpp
@@ -26,6 +26,8 @@
// 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.
+#include <vector>
+#include "misc_os_dependent.h"
#include "perf_timer.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
@@ -35,7 +37,8 @@ namespace tools
{
el::Level performance_timer_log_level = el::Level::Debug;
-__thread std::vector<PerformanceTimer*> *performance_timers = NULL;
+
+static __thread std::vector<PerformanceTimer*> *performance_timers = NULL;
void set_performance_timer_log_level(el::Level level)
{
@@ -48,4 +51,38 @@ void set_performance_timer_log_level(el::Level level)
performance_timer_log_level = level;
}
+PerformanceTimer::PerformanceTimer(const std::string &s, uint64_t unit, el::Level l): name(s), unit(unit), level(l), started(false)
+{
+ ticks = epee::misc_utils::get_ns_count();
+ if (!performance_timers)
+ {
+ MLOG(level, "PERF ----------");
+ performance_timers = new std::vector<PerformanceTimer*>();
+ }
+ else
+ {
+ PerformanceTimer *pt = performance_timers->back();
+ if (!pt->started)
+ {
+ MLOG(pt->level, "PERF " << std::string((performance_timers->size()-1) * 2, ' ') << " " << pt->name);
+ pt->started = true;
+ }
+ }
+ performance_timers->push_back(this);
+}
+
+PerformanceTimer::~PerformanceTimer()
+{
+ performance_timers->pop_back();
+ ticks = epee::misc_utils::get_ns_count() - ticks;
+ char s[12];
+ snprintf(s, sizeof(s), "%8llu ", (unsigned long long)ticks / (1000000000 / unit));
+ MLOG(level, "PERF " << s << std::string(performance_timers->size() * 2, ' ') << " " << name);
+ if (performance_timers->empty())
+ {
+ delete performance_timers;
+ performance_timers = NULL;
+ }
+}
+
}
diff --git a/src/common/perf_timer.h b/src/common/perf_timer.h
index 4d7d99afb..a1d71609c 100644
--- a/src/common/perf_timer.h
+++ b/src/common/perf_timer.h
@@ -41,44 +41,12 @@ namespace tools
class PerformanceTimer;
extern el::Level performance_timer_log_level;
-extern __thread std::vector<PerformanceTimer*> *performance_timers;
class PerformanceTimer
{
public:
- PerformanceTimer(const std::string &s, uint64_t unit, el::Level l = el::Level::Debug): name(s), unit(unit), level(l), started(false)
- {
- ticks = epee::misc_utils::get_ns_count();
- if (!performance_timers)
- {
- MLOG(level, "PERF ----------");
- performance_timers = new std::vector<PerformanceTimer*>();
- }
- else
- {
- PerformanceTimer *pt = performance_timers->back();
- if (!pt->started)
- {
- MLOG(pt->level, "PERF " << std::string((performance_timers->size()-1) * 2, ' ') << " " << pt->name);
- pt->started = true;
- }
- }
- performance_timers->push_back(this);
- }
-
- ~PerformanceTimer()
- {
- performance_timers->pop_back();
- ticks = epee::misc_utils::get_ns_count() - ticks;
- char s[12];
- snprintf(s, sizeof(s), "%8llu ", (unsigned long long)ticks / (1000000000 / unit));
- MLOG(level, "PERF " << s << std::string(performance_timers->size() * 2, ' ') << " " << name);
- if (performance_timers->empty())
- {
- delete performance_timers;
- performance_timers = NULL;
- }
- }
+ PerformanceTimer(const std::string &s, uint64_t unit, el::Level l = el::Level::Debug);
+ ~PerformanceTimer();
private:
std::string name;
diff --git a/src/common/stack_trace.cpp b/src/common/stack_trace.cpp
index 6fdf4dd47..bcdf72b60 100644
--- a/src/common/stack_trace.cpp
+++ b/src/common/stack_trace.cpp
@@ -39,6 +39,7 @@
#ifndef STATICLIB
#include <dlfcn.h>
#endif
+#include <boost/algorithm/string.hpp>
#include "common/stack_trace.h"
#include "misc_log_ex.h"
diff --git a/src/common/updates.cpp b/src/common/updates.cpp
index 141330c2c..2d9c2d89c 100644
--- a/src/common/updates.cpp
+++ b/src/common/updates.cpp
@@ -26,6 +26,7 @@
// 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.
+#include <boost/algorithm/string.hpp>
#include "misc_log_ex.h"
#include "util.h"
#include "dns_utils.h"
@@ -98,7 +99,7 @@ namespace tools
std::string get_update_url(const std::string &software, const std::string &subdir, const std::string &buildtag, const std::string &version, bool user)
{
- const char *base = user ? "https://downloads.getmonero.org/" : "http://updates.getmonero.org/";
+ const char *base = user ? "https://downloads.getmonero.org/" : "https://updates.getmonero.org/";
#ifdef _WIN32
static const char *extension = strncmp(buildtag.c_str(), "install-", 8) ? ".zip" : ".exe";
#else
diff --git a/src/common/util.cpp b/src/common/util.cpp
index e8ac61815..2a2f50c4f 100644
--- a/src/common/util.cpp
+++ b/src/common/util.cpp
@@ -36,9 +36,11 @@
#include "include_base_utils.h"
#include "file_io_utils.h"
+#include "wipeable_string.h"
using namespace epee;
#include "util.h"
+#include "memwipe.h"
#include "cryptonote_config.h"
#include "net/http_client.h" // epee::net_utils::...
@@ -52,6 +54,7 @@ using namespace epee;
#include <sys/stat.h>
#endif
#include <boost/filesystem.hpp>
+#include <boost/algorithm/string.hpp>
#include <boost/asio.hpp>
#include <openssl/sha.h>
@@ -542,6 +545,10 @@ std::string get_nix_version_display_string()
}
bool on_startup()
{
+ wipeable_string::set_wipe(&memwipe);
+
+ mlog_configure("", true);
+
sanitize_locale();
#ifdef __GLIBC__
@@ -628,13 +635,13 @@ std::string get_nix_version_display_string()
int vercmp(const char *v0, const char *v1)
{
std::vector<std::string> f0, f1;
- boost::split(f0, v0, boost::is_any_of("."));
- boost::split(f1, v1, boost::is_any_of("."));
- while (f0.size() < f1.size())
- f0.push_back("0");
- while (f1.size() < f0.size())
- f1.push_back("0");
- for (size_t i = 0; i < f0.size(); ++i) {
+ boost::split(f0, v0, boost::is_any_of(".-"));
+ boost::split(f1, v1, boost::is_any_of(".-"));
+ for (size_t i = 0; i < std::max(f0.size(), f1.size()); ++i) {
+ if (i >= f0.size())
+ return -1;
+ if (i >= f1.size())
+ return 1;
int f0i = atoi(f0[i].c_str()), f1i = atoi(f1[i].c_str());
int n = f0i - f1i;
if (n)