Adapt for passwordfile 4.0.0

This commit is contained in:
Martchus 2018-12-18 23:17:55 +01:00
parent d1e1d44c32
commit d2b096bfda
6 changed files with 52 additions and 39 deletions

View File

@ -11,9 +11,9 @@ set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}")
set(META_APP_DESCRIPTION "A simple password store using AES-256-CBC encryption via OpenSSL") set(META_APP_DESCRIPTION "A simple password store using AES-256-CBC encryption via OpenSSL")
set(META_GUI_OPTIONAL YES) set(META_GUI_OPTIONAL YES)
set(META_USE_QQC2 ON) set(META_USE_QQC2 ON)
set(META_VERSION_MAJOR 3) set(META_VERSION_MAJOR 4)
set(META_VERSION_MINOR 2) set(META_VERSION_MINOR 0)
set(META_VERSION_PATCH 1) set(META_VERSION_PATCH 0)
set(META_APP_VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}) set(META_APP_VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH})
# add project files # add project files
@ -162,7 +162,7 @@ find_package(qtutilities 5.11.0 REQUIRED)
use_qt_utilities() use_qt_utilities()
# find passwordfile # find passwordfile
find_package(passwordfile 3.1.0 REQUIRED) find_package(passwordfile 4.0.0 REQUIRED)
use_password_file() use_password_file()
# require qt least Qt 5.8 for the Qt Quick GUI # require qt least Qt 5.8 for the Qt Quick GUI

View File

@ -98,7 +98,7 @@ InteractiveCli::InteractiveCli()
void InteractiveCli::run(const string &file) void InteractiveCli::run(const string &file)
{ {
if (!file.empty()) { if (!file.empty()) {
openFile(file, false); openFile(file, PasswordFileOpenFlags::Default);
} }
string input; string input;
while (!m_quit) { while (!m_quit) {
@ -128,9 +128,9 @@ void InteractiveCli::processCommand(const string &cmd)
} else if (CMD2("clear", "c")) { } else if (CMD2("clear", "c")) {
clearConsole(); clearConsole();
} else if (CMD2_P("openreadonly", "or")) { } else if (CMD2_P("openreadonly", "or")) {
openFile(param, true); openFile(param, PasswordFileOpenFlags::ReadOnly);
} else if (CMD2_P("open", "o")) { } else if (CMD2_P("open", "o")) {
openFile(param, false); openFile(param, PasswordFileOpenFlags::Default);
} else if (CMD2("close", "c")) { } else if (CMD2("close", "c")) {
closeFile(); closeFile();
} else if (CMD2("save", "w")) { } else if (CMD2("save", "w")) {
@ -237,7 +237,7 @@ bool InteractiveCli::checkCommand(const string &str, const char *phrase, std::st
return false; return false;
} }
void InteractiveCli::openFile(const string &file, bool readOnly) void InteractiveCli::openFile(const string &file, PasswordFileOpenFlags openFlags)
{ {
if (m_file.isOpen()) { if (m_file.isOpen()) {
m_o << "file \"" << m_file.path() << "\" currently open; close first" << endl; m_o << "file \"" << m_file.path() << "\" currently open; close first" << endl;
@ -247,7 +247,7 @@ void InteractiveCli::openFile(const string &file, bool readOnly)
for (;;) { for (;;) {
try { try {
try { try {
m_file.open(readOnly); m_file.open(openFlags);
if (m_file.isEncryptionUsed()) { if (m_file.isEncryptionUsed()) {
m_file.setPassword(askForPassphrase()); m_file.setPassword(askForPassphrase());
} }
@ -300,7 +300,11 @@ void InteractiveCli::saveFile()
} }
try { try {
try { try {
m_file.save(*m_file.password()); auto flags = PasswordFileSaveFlags::Compression | PasswordFileSaveFlags::PasswordHashing;
if (!m_file.password().empty()) {
flags |= PasswordFileSaveFlags::Encryption;
}
m_file.save(flags);
m_o << "file \"" << m_file.path() << "\" saved" << endl; m_o << "file \"" << m_file.path() << "\" saved" << endl;
} catch (const ParsingException &) { } catch (const ParsingException &) {
m_o << "error occured when parsing file \"" << m_file.path() << "\"" << endl; m_o << "error occured when parsing file \"" << m_file.path() << "\"" << endl;
@ -373,7 +377,7 @@ void InteractiveCli::removePassphrase()
m_o << "nothing to remove; no file opened or created" << endl; m_o << "nothing to remove; no file opened or created" << endl;
return; return;
} }
if (*m_file.password()) { if (!m_file.password().empty()) {
m_file.clearPassword(); m_file.clearPassword();
m_o << "passphrase removed; use save to apply" << endl; m_o << "passphrase removed; use save to apply" << endl;
m_modified = true; m_modified = true;

View File

@ -45,7 +45,7 @@ class InteractiveCli {
public: public:
InteractiveCli(); InteractiveCli();
void run(const std::string &file = std::string()); void run(const std::string &file = std::string());
void openFile(const std::string &file, bool readOnly); void openFile(const std::string &file, Io::PasswordFileOpenFlags openFlags);
void closeFile(); void closeFile();
void saveFile(); void saveFile();
void createFile(const std::string &file); void createFile(const std::string &file);

View File

@ -114,7 +114,7 @@ void MainWindow::setSomethingChanged(bool somethingChanged)
MainWindow::MainWindow(QSettings &settings, Dialogs::QtSettings *qtSettings, QWidget *parent) MainWindow::MainWindow(QSettings &settings, Dialogs::QtSettings *qtSettings, QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
, m_ui(new Ui::MainWindow) , m_ui(new Ui::MainWindow)
, m_readOnly(false) , m_openFlags(PasswordFileOpenFlags::None)
, m_clearClipboardTimer(0) , m_clearClipboardTimer(0)
, m_aboutDlg(nullptr) , m_aboutDlg(nullptr)
, m_settings(settings) , m_settings(settings)
@ -411,7 +411,7 @@ void MainWindow::showUndoView()
* \brief Opens a file with the specified \a path and updates all widgets to show its contents. * \brief Opens a file with the specified \a path and updates all widgets to show its contents.
* \returns Returns true on success; otherwise false * \returns Returns true on success; otherwise false
*/ */
bool MainWindow::openFile(const QString &path, bool readOnly) bool MainWindow::openFile(const QString &path, PasswordFileOpenFlags openFlags)
{ {
using namespace Dialogs; using namespace Dialogs;
@ -423,14 +423,14 @@ bool MainWindow::openFile(const QString &path, bool readOnly)
// set path and open file // set path and open file
m_file.setPath(path.toStdString()); m_file.setPath(path.toStdString());
try { try {
m_file.open(m_readOnly = readOnly); m_file.open(m_openFlags = openFlags);
} catch (...) { } catch (...) {
// catch std::ios_base::failure // catch std::ios_base::failure
const char *const ioError = catchIoFailure(); const char *const ioError = catchIoFailure();
// try read-only // try read-only
if (!readOnly) { if (!(m_openFlags & PasswordFileOpenFlags::ReadOnly)) {
return openFile(path, true); return openFile(path, m_openFlags | PasswordFileOpenFlags::ReadOnly);
} }
// show error message // show error message
@ -495,7 +495,7 @@ bool MainWindow::openFile(const QString &path, bool readOnly)
m_file.clear(); m_file.clear();
m_ui->statusBar->showMessage(msg, 5000); m_ui->statusBar->showMessage(msg, 5000);
if (QMessageBox::critical(this, QApplication::applicationName(), msg, QMessageBox::Cancel, QMessageBox::Retry) == QMessageBox::Retry) { if (QMessageBox::critical(this, QApplication::applicationName(), msg, QMessageBox::Cancel, QMessageBox::Retry) == QMessageBox::Retry) {
return openFile(path, readOnly); // retry return openFile(path, openFlags); // retry
} else { } else {
return false; return false;
} }
@ -541,7 +541,7 @@ void MainWindow::createFile(const QString &path, const QString &password)
// create the file and show it // create the file and show it
try { try {
m_readOnly = false; m_openFlags = PasswordFileOpenFlags::Default;
m_file.create(); m_file.create();
} catch (...) { } catch (...) {
catchIoFailure(); catchIoFailure();
@ -608,7 +608,7 @@ void MainWindow::updateWindowTitle()
docStatus = Dialogs::DocumentStatus::NoDocument; docStatus = Dialogs::DocumentStatus::NoDocument;
} }
auto documentPath(QString::fromStdString(m_file.path())); auto documentPath(QString::fromStdString(m_file.path()));
if (m_readOnly) { if (m_openFlags & PasswordFileOpenFlags::ReadOnly) {
documentPath += tr(" [read-only]"); documentPath += tr(" [read-only]");
} }
setWindowTitle(Dialogs::generateWindowTitle(docStatus, documentPath)); setWindowTitle(Dialogs::generateWindowTitle(docStatus, documentPath));
@ -829,7 +829,7 @@ bool MainWindow::saveFile()
} }
// ask for a password if none is set // ask for a password if none is set
if (m_file.password()[0] == 0) { if (m_file.password().empty()) {
EnterPasswordDialog pwDlg(this); EnterPasswordDialog pwDlg(this);
pwDlg.setWindowTitle(tr("Saving file") + QStringLiteral(" - " APP_NAME)); pwDlg.setWindowTitle(tr("Saving file") + QStringLiteral(" - " APP_NAME));
pwDlg.setInstruction(tr("Enter a password to save the file")); pwDlg.setInstruction(tr("Enter a password to save the file"));
@ -848,7 +848,11 @@ bool MainWindow::saveFile()
// save the file // save the file
QString msg; QString msg;
try { try {
m_file.save(m_file.password()[0] != 0); auto flags = PasswordFileSaveFlags::Compression | PasswordFileSaveFlags::PasswordHashing;
if (!m_file.password().empty()) {
flags |= PasswordFileSaveFlags::Encryption;
}
m_file.save(flags);
} catch (const CryptoException &ex) { } catch (const CryptoException &ex) {
msg = tr("The password list couldn't be saved due to encryption failure.\nOpenSSL error queue: %1").arg(QString::fromLocal8Bit(ex.what())); msg = tr("The password list couldn't be saved due to encryption failure.\nOpenSSL error queue: %1").arg(QString::fromLocal8Bit(ex.what()));
} catch (...) { } catch (...) {
@ -860,8 +864,8 @@ bool MainWindow::saveFile()
QMessageBox::critical(this, QApplication::applicationName(), msg); QMessageBox::critical(this, QApplication::applicationName(), msg);
return false; return false;
} }
if (m_readOnly || m_somethingChanged) { if ((m_openFlags & PasswordFileOpenFlags::ReadOnly) || m_somethingChanged) {
m_readOnly = false; m_openFlags = PasswordFileOpenFlags::Default;
m_somethingChanged = false; m_somethingChanged = false;
updateWindowTitle(); updateWindowTitle();
} }
@ -1199,7 +1203,10 @@ void MainWindow::showTableViewContextMenu()
QUrl url; QUrl url;
static const string protocols[] = { "http:", "https:", "file:" }; static const string protocols[] = { "http:", "https:", "file:" };
for (const QModelIndex &index : selectedIndexes) { for (const QModelIndex &index : selectedIndexes) {
if (const Field *field = m_fieldModel->field(index.row())) { if (!index.isValid()) {
continue;
}
if (const Field *field = m_fieldModel->field(static_cast<size_t>(index.row()))) {
if (url.isEmpty() && field->type() != FieldType::Password) { if (url.isEmpty() && field->type() != FieldType::Password) {
for (const string &protocol : protocols) { for (const string &protocol : protocols) {
if (ConversionUtilities::startsWith(field->value(), protocol)) { if (ConversionUtilities::startsWith(field->value(), protocol)) {
@ -1226,7 +1233,8 @@ void MainWindow::showTableViewContextMenu()
QMenu contextMenu(this); QMenu contextMenu(this);
// -> insertion and removal // -> insertion and removal
contextMenu.addAction(QIcon::fromTheme(QStringLiteral("list-add")), tr("Insert field"), this, &MainWindow::insertRow); contextMenu.addAction(QIcon::fromTheme(QStringLiteral("list-add")), tr("Insert field"), this, &MainWindow::insertRow);
contextMenu.addAction(QIcon::fromTheme(QStringLiteral("list-remove")), tr("Remove field(s)", 0, multipleRows), this, &MainWindow::removeRows); contextMenu.addAction(
QIcon::fromTheme(QStringLiteral("list-remove")), tr("Remove field(s)", nullptr, multipleRows), this, &MainWindow::removeRows);
// -> show the "Mark as ..." action only when all selected indexes are of the same type // -> show the "Mark as ..." action only when all selected indexes are of the same type
if (hasFirstFieldType && allOfSameType) { if (hasFirstFieldType && allOfSameType) {
switch (firstType) { switch (firstType) {

View File

@ -54,7 +54,7 @@ public:
public slots: public slots:
// file management // file management
bool openFile(const QString &path); bool openFile(const QString &path);
bool openFile(const QString &path, bool readOnly); bool openFile(const QString &path, Io::PasswordFileOpenFlags openFlags);
void createFile(const QString &path, const QString &password); void createFile(const QString &path, const QString &password);
void createFile(const QString &path); void createFile(const QString &path);
bool createFile(); bool createFile();
@ -124,7 +124,7 @@ private:
QUndoStack *m_undoStack; QUndoStack *m_undoStack;
QUndoView *m_undoView; QUndoView *m_undoView;
bool m_somethingChanged; bool m_somethingChanged;
bool m_readOnly; Io::PasswordFileOpenFlags m_openFlags;
bool m_dontUpdateSelection; bool m_dontUpdateSelection;
int m_clearClipboardTimer; int m_clearClipboardTimer;
MiscUtils::RecentMenuManager *m_recentMgr; MiscUtils::RecentMenuManager *m_recentMgr;
@ -140,7 +140,7 @@ private:
*/ */
inline bool MainWindow::openFile(const QString &path) inline bool MainWindow::openFile(const QString &path)
{ {
return openFile(path, false); return openFile(path, Io::PasswordFileOpenFlags::Default);
} }
} // namespace QtGui } // namespace QtGui

View File

@ -193,15 +193,16 @@ void Controller::close()
void Controller::save() void Controller::save()
{ {
try { auto flags = PasswordFileSaveFlags::Compression | PasswordFileSaveFlags::PasswordHashing;
const auto useEncryption = !m_password.isEmpty(); if (!m_password.isEmpty()) {
if (useEncryption) { flags |= PasswordFileSaveFlags::Encryption;
const auto passwordUtf8(m_password.toUtf8()); const auto passwordUtf8(m_password.toUtf8());
m_file.setPassword(string(passwordUtf8.data(), static_cast<size_t>(passwordUtf8.size()))); m_file.setPassword(passwordUtf8.data(), static_cast<size_t>(passwordUtf8.size()));
} else { } else {
m_file.clearPassword(); m_file.clearPassword();
} }
try {
#if defined(Q_OS_ANDROID) && defined(CPP_UTILITIES_USE_NATIVE_FILE_BUFFER) #if defined(Q_OS_ANDROID) && defined(CPP_UTILITIES_USE_NATIVE_FILE_BUFFER)
if (!m_nativeUrl.isEmpty()) { if (!m_nativeUrl.isEmpty()) {
// ensure file is closed // ensure file is closed
@ -216,11 +217,11 @@ void Controller::save()
} }
m_file.fileStream().openFromFileDescriptor(newFileDescriptor, ios_base::out | ios_base::trunc | ios_base::binary); m_file.fileStream().openFromFileDescriptor(newFileDescriptor, ios_base::out | ios_base::trunc | ios_base::binary);
m_file.write(useEncryption); m_file.write(flags);
} else { } else {
#endif #endif
// let libpasswordfile handle everything // let libpasswordfile handle everything
m_file.save(useEncryption); m_file.save(flags);
#if defined(Q_OS_ANDROID) && defined(CPP_UTILITIES_USE_NATIVE_FILE_BUFFER) #if defined(Q_OS_ANDROID) && defined(CPP_UTILITIES_USE_NATIVE_FILE_BUFFER)
} }
#endif #endif