diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5d01721b..cc933484 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -59,6 +59,8 @@ set(keepassx_SOURCES core/Tools.cpp core/Translator.cpp core/Uuid.cpp + cli/PasswordInput.cpp + cli/PasswordInput.h crypto/Crypto.cpp crypto/CryptoHash.cpp crypto/Random.cpp diff --git a/src/cli/Extract.cpp b/src/cli/Extract.cpp index 0c8a3960..36dde473 100644 --- a/src/cli/Extract.cpp +++ b/src/cli/Extract.cpp @@ -29,6 +29,7 @@ #include "core/Database.h" #include "format/KeePass2Reader.h" #include "keys/CompositeKey.h" +#include "cli/PasswordInput.h" int Extract::execute(int argc, char** argv) { @@ -50,8 +51,7 @@ int Extract::execute(int argc, char** argv) out << "Insert the database password\n> "; out.flush(); - static QTextStream inputTextStream(stdin, QIODevice::ReadOnly); - QString line = inputTextStream.readLine(); + QString line = PasswordInput::getPassword(); CompositeKey key = CompositeKey::readFromLine(line); QString databaseFilename = args.at(0); diff --git a/src/cli/PasswordInput.cpp b/src/cli/PasswordInput.cpp new file mode 100644 index 00000000..9436f491 --- /dev/null +++ b/src/cli/PasswordInput.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2017 KeePassXC Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 or (at your option) + * version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "PasswordInput.h" + +#ifdef Q_OS_WIN +#include +#else +#include +#include +#endif + +#include + + +PasswordInput::PasswordInput() +{ +} + +void PasswordInput::setStdinEcho(bool enable = true) +{ +#ifdef Q_OS_WIN + HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE); + DWORD mode; + GetConsoleMode(hIn, &mode); + + if (enable) { + mode |= ENABLE_ECHO_INPUT; + } else { + mode &= ~ENABLE_ECHO_INPUT; + } + + SetConsoleMode(hIn, mode); + +#else + struct termios t; + tcgetattr(STDIN_FILENO, &t); + + if (enable) { + t.c_lflag |= ECHO; + } else { + t.c_lflag &= ~ECHO; + } + + tcsetattr(STDIN_FILENO, TCSANOW, &t); +#endif +} + +QString PasswordInput::getPassword() +{ + static QTextStream inputTextStream(stdin, QIODevice::ReadOnly); + + setStdinEcho(false); + QString line = inputTextStream.readLine(); + setStdinEcho(true); + + return line; +} diff --git a/src/cli/PasswordInput.h b/src/cli/PasswordInput.h new file mode 100644 index 00000000..b7606186 --- /dev/null +++ b/src/cli/PasswordInput.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2017 KeePassXC Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 or (at your option) + * version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef KEEPASSXC_PASSWORDINPUT_H +#define KEEPASSXC_PASSWORDINPUT_H + +#include + +class PasswordInput +{ +public: + PasswordInput(); + static void setStdinEcho(bool enable); + static QString getPassword(); +}; + +#endif // KEEPASSXC_PASSWORDINPUT_H diff --git a/src/cli/Show.cpp b/src/cli/Show.cpp index b9d6bed0..680f7a45 100644 --- a/src/cli/Show.cpp +++ b/src/cli/Show.cpp @@ -29,6 +29,7 @@ #include "core/Entry.h" #include "core/Group.h" #include "keys/CompositeKey.h" +#include "cli/PasswordInput.h" int Show::execute(int argc, char** argv) { @@ -50,8 +51,7 @@ int Show::execute(int argc, char** argv) out << "Insert the database password\n> "; out.flush(); - static QTextStream inputTextStream(stdin, QIODevice::ReadOnly); - QString line = inputTextStream.readLine(); + QString line = PasswordInput::getPassword(); CompositeKey key = CompositeKey::readFromLine(line); Database* db = Database::openDatabaseFile(args.at(0), key); diff --git a/src/core/Database.cpp b/src/core/Database.cpp index e1a8610a..d1c0fea4 100644 --- a/src/core/Database.cpp +++ b/src/core/Database.cpp @@ -24,6 +24,7 @@ #include #include +#include "cli/PasswordInput.h" #include "core/Group.h" #include "core/Metadata.h" #include "crypto/Random.h" @@ -398,13 +399,12 @@ Database* Database::openDatabaseFile(QString fileName, CompositeKey key) Database* Database::unlockFromStdin(QString databaseFilename) { - static QTextStream inputTextStream(stdin, QIODevice::ReadOnly); QTextStream outputTextStream(stdout); outputTextStream << QString("Insert password to unlock " + databaseFilename + "\n> "); outputTextStream.flush(); - QString line = inputTextStream.readLine(); + QString line = PasswordInput::getPassword(); CompositeKey key = CompositeKey::readFromLine(line); return Database::openDatabaseFile(databaseFilename, key); }