From a4b50a6f511e60a57955dab7586aba08a5c54337 Mon Sep 17 00:00:00 2001 From: Jethro Grassie Date: Thu, 1 Feb 2018 15:32:30 -0500 Subject: [PATCH] handle ^D and ^C while password prompting --- src/common/password.cpp | 15 ++++++++++----- src/common/password.h | 2 ++ src/common/util.h | 6 +++++- src/simplewallet/simplewallet.cpp | 7 +++++++ 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/common/password.cpp b/src/common/password.cpp index ef026c979..9336a14fc 100644 --- a/src/common/password.cpp +++ b/src/common/password.cpp @@ -42,12 +42,10 @@ #include #endif -#ifdef HAVE_READLINE - #include "readline_buffer.h" -#endif - #include "memwipe.h" +#define EOT 0x4 + namespace { #if defined(_WIN32) @@ -134,7 +132,7 @@ namespace while (aPass.size() < tools::password_container::max_password_size) { int ch = getch(); - if (EOF == ch) + if (EOF == ch || ch == EOT) { return false; } @@ -229,13 +227,20 @@ namespace tools m_password.clear(); } + std::atomic password_container::is_prompting(false); + boost::optional password_container::prompt(const bool verify, const char *message) { + is_prompting = true; password_container pass1{}; password_container pass2{}; if (is_cin_tty() ? read_from_tty(verify, message, pass1.m_password, pass2.m_password) : read_from_file(pass1.m_password)) + { + is_prompting = false; return {std::move(pass1)}; + } + is_prompting = false; return boost::none; } diff --git a/src/common/password.h b/src/common/password.h index 7c29effe4..61937b93a 100644 --- a/src/common/password.h +++ b/src/common/password.h @@ -31,6 +31,7 @@ #pragma once #include +#include #include #include "wipeable_string.h" @@ -49,6 +50,7 @@ namespace tools //! \return A password from stdin TTY prompt or `std::cin` pipe. static boost::optional prompt(bool verify, const char *mesage = "Password"); + static std::atomic is_prompting; password_container(const password_container&) = delete; password_container(password_container&& rhs) = default; diff --git a/src/common/util.h b/src/common/util.h index 5afb42c97..d3ba47a4f 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -153,8 +153,12 @@ namespace tools } return r; #else + static struct sigaction sa; + memset(&sa, 0, sizeof(struct sigaction)); + sa.sa_handler = posix_handler; + sa.sa_flags = 0; /* Only blocks SIGINT, SIGTERM and SIGPIPE */ - signal(SIGINT, posix_handler); + sigaction(SIGINT, &sa, NULL); signal(SIGTERM, posix_handler); signal(SIGPIPE, SIG_IGN); m_handler = t; diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index a6cef1bb9..ea9212ff1 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -638,6 +638,8 @@ bool simple_wallet::change_password(const std::vector &args) // prompts for a new password, pass true to verify the password const auto pwd_container = default_password_prompter(true); + if(!pwd_container) + return true; try { @@ -6806,6 +6808,11 @@ int main(int argc, char* argv[]) else { tools::signal_handler::install([&w](int type) { + if (tools::password_container::is_prompting.load()) + { + // must be prompting for password so return and let the signal stop prompt + return; + } #ifdef WIN32 if (type == CTRL_C_EVENT) #else