aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/CMakeLists.txt4
-rw-r--r--src/common/dns_utils.cpp7
-rw-r--r--src/common/notify.cpp62
-rw-r--r--src/common/notify.h49
-rw-r--r--src/common/password.cpp38
-rw-r--r--src/common/password.h1
-rw-r--r--src/common/spawn.cpp141
-rw-r--r--src/common/spawn.h36
-rw-r--r--src/common/threadpool.cpp3
-rw-r--r--src/common/util.cpp28
-rw-r--r--src/common/util.h3
11 files changed, 357 insertions, 15 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index e89dbbc24..aed9bfee7 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -37,8 +37,10 @@ set(common_sources
expect.cpp
util.cpp
i18n.cpp
+ notify.cpp
password.cpp
perf_timer.cpp
+ spawn.cpp
threadpool.cpp
updates.cpp
aligned.c)
@@ -61,6 +63,7 @@ set(common_private_headers
expect.h
http_connection.h
int-util.h
+ notify.h
pod-class.h
rpc_client.h
scoped_message_writer.h
@@ -70,6 +73,7 @@ set(common_private_headers
i18n.h
password.h
perf_timer.h
+ spawn.h
stack_trace.h
threadpool.h
updates.h
diff --git a/src/common/dns_utils.cpp b/src/common/dns_utils.cpp
index 3f2bde620..f2b270981 100644
--- a/src/common/dns_utils.cpp
+++ b/src/common/dns_utils.cpp
@@ -46,10 +46,11 @@ namespace bf = boost::filesystem;
static const char *DEFAULT_DNS_PUBLIC_ADDR[] =
{
"194.150.168.168", // CCC (Germany)
- "81.3.27.54", // Lightning Wire Labs (Germany)
- "31.3.135.232", // OpenNIC (Switzerland)
"80.67.169.40", // FDN (France)
- "209.58.179.186", // Cyberghost (Singapore)
+ "89.233.43.71", // http://censurfridns.dk (Denmark)
+ "109.69.8.51", // punCAT (Spain)
+ "77.109.148.137", // Xiala.net (Switzerland)
+ "193.58.251.251", // SkyDNS (Russia)
};
static boost::mutex instance_lock;
diff --git a/src/common/notify.cpp b/src/common/notify.cpp
new file mode 100644
index 000000000..cadc68ea7
--- /dev/null
+++ b/src/common/notify.cpp
@@ -0,0 +1,62 @@
+// 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.
+
+#include <boost/algorithm/string.hpp>
+#include "misc_log_ex.h"
+#include "file_io_utils.h"
+#include "spawn.h"
+#include "notify.h"
+
+namespace tools
+{
+
+/*
+ TODO:
+ - Improve tokenization to handle paths containing whitespaces, quotes, etc.
+ - Windows unicode support (implies implementing unicode command line parsing code)
+*/
+Notify::Notify(const char *spec)
+{
+ CHECK_AND_ASSERT_THROW_MES(spec, "Null spec");
+
+ boost::split(args, spec, boost::is_any_of(" "));
+ CHECK_AND_ASSERT_THROW_MES(args.size() > 0, "Failed to parse spec");
+ filename = args[0];
+ CHECK_AND_ASSERT_THROW_MES(epee::file_io_utils::is_file_exist(filename), "File not found: " << filename);
+}
+
+int Notify::notify(const char *parameter)
+{
+ std::vector<std::string> margs = args;
+ for (std::string &s: margs)
+ boost::replace_all(s, "%s", parameter);
+
+ return tools::spawn(filename.c_str(), margs, false);
+}
+
+}
diff --git a/src/common/notify.h b/src/common/notify.h
new file mode 100644
index 000000000..81aacebb0
--- /dev/null
+++ b/src/common/notify.h
@@ -0,0 +1,49 @@
+// 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 <string>
+#include <vector>
+
+namespace tools
+{
+
+class Notify
+{
+public:
+ Notify(const char *spec);
+
+ int notify(const char *parameter);
+
+private:
+ std::string filename;
+ std::vector<std::string> args;
+};
+
+}
diff --git a/src/common/password.cpp b/src/common/password.cpp
index 5671c4a4e..a8d5141dc 100644
--- a/src/common/password.cpp
+++ b/src/common/password.cpp
@@ -56,8 +56,6 @@ namespace
bool read_from_tty(epee::wipeable_string& pass, bool hide_input)
{
- static constexpr const char BACKSPACE = 8;
-
HANDLE h_cin = ::GetStdHandle(STD_INPUT_HANDLE);
DWORD mode_old;
@@ -67,32 +65,46 @@ namespace
bool r = true;
pass.reserve(tools::password_container::max_password_size);
+ std::vector<int> chlen;
+ chlen.reserve(tools::password_container::max_password_size);
while (pass.size() < tools::password_container::max_password_size)
{
DWORD read;
- char ch;
- r = (TRUE == ::ReadConsoleA(h_cin, &ch, 1, &read, NULL));
+ wchar_t ucs2_ch;
+ r = (TRUE == ::ReadConsoleW(h_cin, &ucs2_ch, 1, &read, NULL));
r &= (1 == read);
+
if (!r)
{
break;
}
- else if (ch == '\n' || ch == '\r')
+ else if (ucs2_ch == L'\n' || ucs2_ch == L'\r')
{
std::cout << std::endl;
break;
}
- else if (ch == BACKSPACE)
+ else if (ucs2_ch == L'\b')
{
if (!pass.empty())
{
- pass.pop_back();
+ int len = chlen.back();
+ chlen.pop_back();
+ while(len-- > 0)
+ pass.pop_back();
}
+ continue;
}
- else
- {
- pass.push_back(ch);
- }
+
+ char utf8_ch[8] = {0};
+ int len;
+ if((len = WideCharToMultiByte(CP_UTF8, 0, &ucs2_ch, 1, utf8_ch, sizeof(utf8_ch), NULL, NULL)) <= 0)
+ break;
+
+ if(pass.size() + len >= tools::password_container::max_password_size)
+ break;
+
+ chlen.push_back(len);
+ pass += utf8_ch;
}
::SetConsoleMode(h_cin, mode_old);
@@ -221,6 +233,10 @@ namespace tools
: m_password(std::move(password))
{
}
+ password_container::password_container(const epee::wipeable_string& password) noexcept
+ : m_password(password)
+ {
+ }
password_container::~password_container() noexcept
{
diff --git a/src/common/password.h b/src/common/password.h
index 529881e40..beb98283b 100644
--- a/src/common/password.h
+++ b/src/common/password.h
@@ -47,6 +47,7 @@ namespace tools
//! `password` is used as password
password_container(std::string&& password) noexcept;
+ password_container(const epee::wipeable_string& password) noexcept;
//! \return A password from stdin TTY prompt or `std::cin` pipe.
static boost::optional<password_container> prompt(bool verify, const char *mesage = "Password", bool hide_input = true);
diff --git a/src/common/spawn.cpp b/src/common/spawn.cpp
new file mode 100644
index 000000000..59f11675c
--- /dev/null
+++ b/src/common/spawn.cpp
@@ -0,0 +1,141 @@
+// 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.
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#ifdef _WIN32
+#include <boost/algorithm/string/join.hpp>
+#include <boost/scope_exit.hpp>
+#include <windows.h>
+#else
+#include <sys/wait.h>
+#endif
+
+#include "misc_log_ex.h"
+#include "spawn.h"
+
+namespace tools
+{
+
+int spawn(const char *filename, const std::vector<std::string>& args, bool wait)
+{
+#ifdef _WIN32
+ std::string joined = boost::algorithm::join(args, " ");
+ char *commandLine = !joined.empty() ? &joined[0] : nullptr;
+ STARTUPINFOA si = {};
+ si.cb = sizeof(si);
+ PROCESS_INFORMATION pi;
+ if (!CreateProcessA(filename, commandLine, nullptr, nullptr, false, 0, nullptr, nullptr, &si, &pi))
+ {
+ MERROR("CreateProcess failed. Error code " << GetLastError());
+ return -1;
+ }
+
+ BOOST_SCOPE_EXIT(&pi)
+ {
+ CloseHandle(pi.hThread);
+ CloseHandle(pi.hProcess);
+ }
+ BOOST_SCOPE_EXIT_END
+
+ if (!wait)
+ {
+ return 0;
+ }
+
+ DWORD result = WaitForSingleObject(pi.hProcess, INFINITE);
+ if (result != WAIT_OBJECT_0)
+ {
+ MERROR("WaitForSingleObject failed. Result " << result << ", error code " << GetLastError());
+ return -1;
+ }
+
+ DWORD exitCode;
+ if (!GetExitCodeProcess(pi.hProcess, &exitCode))
+ {
+ MERROR("GetExitCodeProcess failed. Error code " << GetLastError());
+ return -1;
+ }
+
+ MINFO("Child exited with " << exitCode);
+ return static_cast<int>(exitCode);
+#else
+ char **argv = (char**)alloca(sizeof(char*) * (args.size() + 1));
+ for (size_t n = 0; n < args.size(); ++n)
+ argv[n] = (char*)args[n].c_str();
+ argv[args.size()] = NULL;
+
+ pid_t pid = fork();
+ if (pid < 0)
+ {
+ MERROR("Error forking: " << strerror(errno));
+ return -1;
+ }
+
+ // child
+ if (pid == 0)
+ {
+ char *envp[] = {NULL};
+ execve(filename, argv, envp);
+ MERROR("Failed to execve: " << strerror(errno));
+ return -1;
+ }
+
+ // parent
+ if (pid > 0)
+ {
+ if (!wait)
+ return 0;
+
+ while (1)
+ {
+ int wstatus = 0;
+ pid_t w = waitpid(pid, &wstatus, WUNTRACED | WCONTINUED);
+ if (w < 0) {
+ MERROR("Error waiting for child: " << strerror(errno));
+ return -1;
+ }
+ if (WIFEXITED(wstatus))
+ {
+ MINFO("Child exited with " << WEXITSTATUS(wstatus));
+ return WEXITSTATUS(wstatus);
+ }
+ if (WIFSIGNALED(wstatus))
+ {
+ MINFO("Child killed by " << WEXITSTATUS(wstatus));
+ return WEXITSTATUS(wstatus);
+ }
+ }
+ }
+ MERROR("Secret passage found");
+ return -1;
+#endif
+}
+
+}
diff --git a/src/common/spawn.h b/src/common/spawn.h
new file mode 100644
index 000000000..c90a0f790
--- /dev/null
+++ b/src/common/spawn.h
@@ -0,0 +1,36 @@
+// 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 tools
+{
+
+int spawn(const char *filename, const std::vector<std::string>& args, bool wait);
+
+}
diff --git a/src/common/threadpool.cpp b/src/common/threadpool.cpp
index 6b69e2a12..5ea04a353 100644
--- a/src/common/threadpool.cpp
+++ b/src/common/threadpool.cpp
@@ -57,7 +57,8 @@ threadpool::~threadpool() {
has_work.notify_all();
}
for (size_t i = 0; i<threads.size(); i++) {
- threads[i].join();
+ try { threads[i].join(); }
+ catch (...) { /* ignore */ }
}
}
diff --git a/src/common/util.cpp b/src/common/util.cpp
index c56c77505..2a1d49af0 100644
--- a/src/common/util.cpp
+++ b/src/common/util.cpp
@@ -939,4 +939,32 @@ std::string get_nix_version_display_string()
}
return newval;
}
+
+#ifdef _WIN32
+ std::string input_line_win()
+ {
+ HANDLE hConIn = CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
+ DWORD oldMode;
+
+ FlushConsoleInputBuffer(hConIn);
+ GetConsoleMode(hConIn, &oldMode);
+ SetConsoleMode(hConIn, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT);
+
+ wchar_t buffer[1024];
+ DWORD read;
+
+ ReadConsoleW(hConIn, buffer, sizeof(buffer)/sizeof(wchar_t)-1, &read, nullptr);
+ buffer[read] = 0;
+
+ SetConsoleMode(hConIn, oldMode);
+ CloseHandle(hConIn);
+
+ int size_needed = WideCharToMultiByte(CP_UTF8, 0, buffer, -1, NULL, 0, NULL, NULL);
+ std::string buf(size_needed, '\0');
+ WideCharToMultiByte(CP_UTF8, 0, buffer, -1, &buf[0], size_needed, NULL, NULL);
+ buf.pop_back(); //size_needed includes null that we needed to have space for
+ return buf;
+ }
+#endif
+
}
diff --git a/src/common/util.h b/src/common/util.h
index 0e0b50520..ce773bd38 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -235,4 +235,7 @@ namespace tools
boost::optional<std::pair<uint32_t, uint32_t>> parse_subaddress_lookahead(const std::string& str);
std::string glob_to_regex(const std::string &val);
+#ifdef _WIN32
+ std::string input_line_win();
+#endif
}