Browse Source

Improve getpass() usage

As can be seen from: http://unixhelp.ed.ac.uk/CGI/man-cgi?getpass+3
getpass() is a deprecated function and it's advised not to use
it.

What's more all signals are disabled so (SIGINT, SIGQUIT, SIGSTOP,
SIGTSTOP) will do nothing and as such if the user wants to quit the
program while typing the password in the password loop he is out of
luck.

With this commit we get a manual version of getpass(), inspired by this
SO answer: http://stackoverflow.com/a/1196696/110395
cl-refactor
Lefteris Karapetsas 10 years ago
parent
commit
44cd78d647
  1. 28
      libdevcore/CommonIO.cpp
  2. 1
      libdevcore/Exceptions.h

28
libdevcore/CommonIO.cpp

@ -24,6 +24,9 @@
#include <cstdlib> #include <cstdlib>
#include <fstream> #include <fstream>
#include "Exceptions.h" #include "Exceptions.h"
#ifndef _WIN32
#include <termios.h>
#endif
using namespace std; using namespace std;
using namespace dev; using namespace dev;
@ -126,6 +129,29 @@ std::string dev::getPassword(std::string const& _prompt)
std::getline(cin, ret); std::getline(cin, ret);
return ret; return ret;
#else #else
return getpass(_prompt.c_str()); struct termios oflags;
struct termios nflags;
char password[128];
// disable echo in the terminal
tcgetattr(fileno(stdin), &oflags);
nflags = oflags;
nflags.c_lflag &= ~ECHO;
nflags.c_lflag |= ECHONL;
if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0)
BOOST_THROW_EXCEPTION(ExternalFunctionFailure("tcsetattr"));
printf("%s", _prompt.c_str());
if (!fgets(password, sizeof(password), stdin))
BOOST_THROW_EXCEPTION(ExternalFunctionFailure("fgets"));
password[strlen(password) - 1] = 0;
// restore terminal
if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) {
BOOST_THROW_EXCEPTION(ExternalFunctionFailure("tcsetattr"));
}
return password;
#endif #endif
} }

1
libdevcore/Exceptions.h

@ -54,6 +54,7 @@ struct FileError: virtual Exception {};
struct Overflow: virtual Exception {}; struct Overflow: virtual Exception {};
struct InterfaceNotSupported: virtual Exception { public: InterfaceNotSupported(std::string _f): Exception("Interface " + _f + " not supported.") {} }; struct InterfaceNotSupported: virtual Exception { public: InterfaceNotSupported(std::string _f): Exception("Interface " + _f + " not supported.") {} };
struct FailedInvariant: virtual Exception {}; struct FailedInvariant: virtual Exception {};
struct ExternalFunctionFailure: virtual Exception { public: ExternalFunctionFailure(std::string _f): Exception("Function " + _f + "() failed.") {} };
// error information to be added to exceptions // error information to be added to exceptions
using errinfo_invalidSymbol = boost::error_info<struct tag_invalidSymbol, char>; using errinfo_invalidSymbol = boost::error_info<struct tag_invalidSymbol, char>;

Loading…
Cancel
Save