From d2b096bfda5746e2d12a7d1252c5d4243fff317e Mon Sep 17 00:00:00 2001 From: Martchus Date: Tue, 18 Dec 2018 23:17:55 +0100 Subject: [PATCH] Adapt for passwordfile 4.0.0 --- CMakeLists.txt | 8 ++++---- cli/cli.cpp | 18 +++++++++++------- cli/cli.h | 2 +- gui/mainwindow.cpp | 36 ++++++++++++++++++++++-------------- gui/mainwindow.h | 6 +++--- quickgui/controller.cpp | 21 +++++++++++---------- 6 files changed, 52 insertions(+), 39 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e957afe..01b7218 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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_GUI_OPTIONAL YES) set(META_USE_QQC2 ON) -set(META_VERSION_MAJOR 3) -set(META_VERSION_MINOR 2) -set(META_VERSION_PATCH 1) +set(META_VERSION_MAJOR 4) +set(META_VERSION_MINOR 0) +set(META_VERSION_PATCH 0) set(META_APP_VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}) # add project files @@ -162,7 +162,7 @@ find_package(qtutilities 5.11.0 REQUIRED) use_qt_utilities() # find passwordfile -find_package(passwordfile 3.1.0 REQUIRED) +find_package(passwordfile 4.0.0 REQUIRED) use_password_file() # require qt least Qt 5.8 for the Qt Quick GUI diff --git a/cli/cli.cpp b/cli/cli.cpp index af5d8bf..af2491f 100644 --- a/cli/cli.cpp +++ b/cli/cli.cpp @@ -98,7 +98,7 @@ InteractiveCli::InteractiveCli() void InteractiveCli::run(const string &file) { if (!file.empty()) { - openFile(file, false); + openFile(file, PasswordFileOpenFlags::Default); } string input; while (!m_quit) { @@ -128,9 +128,9 @@ void InteractiveCli::processCommand(const string &cmd) } else if (CMD2("clear", "c")) { clearConsole(); } else if (CMD2_P("openreadonly", "or")) { - openFile(param, true); + openFile(param, PasswordFileOpenFlags::ReadOnly); } else if (CMD2_P("open", "o")) { - openFile(param, false); + openFile(param, PasswordFileOpenFlags::Default); } else if (CMD2("close", "c")) { closeFile(); } else if (CMD2("save", "w")) { @@ -237,7 +237,7 @@ bool InteractiveCli::checkCommand(const string &str, const char *phrase, std::st return false; } -void InteractiveCli::openFile(const string &file, bool readOnly) +void InteractiveCli::openFile(const string &file, PasswordFileOpenFlags openFlags) { if (m_file.isOpen()) { m_o << "file \"" << m_file.path() << "\" currently open; close first" << endl; @@ -247,7 +247,7 @@ void InteractiveCli::openFile(const string &file, bool readOnly) for (;;) { try { try { - m_file.open(readOnly); + m_file.open(openFlags); if (m_file.isEncryptionUsed()) { m_file.setPassword(askForPassphrase()); } @@ -300,7 +300,11 @@ void InteractiveCli::saveFile() } 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; } catch (const ParsingException &) { 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; return; } - if (*m_file.password()) { + if (!m_file.password().empty()) { m_file.clearPassword(); m_o << "passphrase removed; use save to apply" << endl; m_modified = true; diff --git a/cli/cli.h b/cli/cli.h index 7f95fca..8db704e 100644 --- a/cli/cli.h +++ b/cli/cli.h @@ -45,7 +45,7 @@ class InteractiveCli { public: InteractiveCli(); 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 saveFile(); void createFile(const std::string &file); diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 0173f6a..2ad4a8e 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -114,7 +114,7 @@ void MainWindow::setSomethingChanged(bool somethingChanged) MainWindow::MainWindow(QSettings &settings, Dialogs::QtSettings *qtSettings, QWidget *parent) : QMainWindow(parent) , m_ui(new Ui::MainWindow) - , m_readOnly(false) + , m_openFlags(PasswordFileOpenFlags::None) , m_clearClipboardTimer(0) , m_aboutDlg(nullptr) , 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. * \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; @@ -423,14 +423,14 @@ bool MainWindow::openFile(const QString &path, bool readOnly) // set path and open file m_file.setPath(path.toStdString()); try { - m_file.open(m_readOnly = readOnly); + m_file.open(m_openFlags = openFlags); } catch (...) { // catch std::ios_base::failure const char *const ioError = catchIoFailure(); // try read-only - if (!readOnly) { - return openFile(path, true); + if (!(m_openFlags & PasswordFileOpenFlags::ReadOnly)) { + return openFile(path, m_openFlags | PasswordFileOpenFlags::ReadOnly); } // show error message @@ -495,7 +495,7 @@ bool MainWindow::openFile(const QString &path, bool readOnly) m_file.clear(); m_ui->statusBar->showMessage(msg, 5000); if (QMessageBox::critical(this, QApplication::applicationName(), msg, QMessageBox::Cancel, QMessageBox::Retry) == QMessageBox::Retry) { - return openFile(path, readOnly); // retry + return openFile(path, openFlags); // retry } else { return false; } @@ -541,7 +541,7 @@ void MainWindow::createFile(const QString &path, const QString &password) // create the file and show it try { - m_readOnly = false; + m_openFlags = PasswordFileOpenFlags::Default; m_file.create(); } catch (...) { catchIoFailure(); @@ -608,7 +608,7 @@ void MainWindow::updateWindowTitle() docStatus = Dialogs::DocumentStatus::NoDocument; } auto documentPath(QString::fromStdString(m_file.path())); - if (m_readOnly) { + if (m_openFlags & PasswordFileOpenFlags::ReadOnly) { documentPath += tr(" [read-only]"); } setWindowTitle(Dialogs::generateWindowTitle(docStatus, documentPath)); @@ -829,7 +829,7 @@ bool MainWindow::saveFile() } // ask for a password if none is set - if (m_file.password()[0] == 0) { + if (m_file.password().empty()) { EnterPasswordDialog pwDlg(this); pwDlg.setWindowTitle(tr("Saving file") + QStringLiteral(" - " APP_NAME)); pwDlg.setInstruction(tr("Enter a password to save the file")); @@ -848,7 +848,11 @@ bool MainWindow::saveFile() // save the file QString msg; 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) { msg = tr("The password list couldn't be saved due to encryption failure.\nOpenSSL error queue: %1").arg(QString::fromLocal8Bit(ex.what())); } catch (...) { @@ -860,8 +864,8 @@ bool MainWindow::saveFile() QMessageBox::critical(this, QApplication::applicationName(), msg); return false; } - if (m_readOnly || m_somethingChanged) { - m_readOnly = false; + if ((m_openFlags & PasswordFileOpenFlags::ReadOnly) || m_somethingChanged) { + m_openFlags = PasswordFileOpenFlags::Default; m_somethingChanged = false; updateWindowTitle(); } @@ -1199,7 +1203,10 @@ void MainWindow::showTableViewContextMenu() QUrl url; static const string protocols[] = { "http:", "https:", "file:" }; 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(index.row()))) { if (url.isEmpty() && field->type() != FieldType::Password) { for (const string &protocol : protocols) { if (ConversionUtilities::startsWith(field->value(), protocol)) { @@ -1226,7 +1233,8 @@ void MainWindow::showTableViewContextMenu() QMenu contextMenu(this); // -> insertion and removal 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 if (hasFirstFieldType && allOfSameType) { switch (firstType) { diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 934f79c..5a511ba 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -54,7 +54,7 @@ public: public slots: // file management 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); bool createFile(); @@ -124,7 +124,7 @@ private: QUndoStack *m_undoStack; QUndoView *m_undoView; bool m_somethingChanged; - bool m_readOnly; + Io::PasswordFileOpenFlags m_openFlags; bool m_dontUpdateSelection; int m_clearClipboardTimer; MiscUtils::RecentMenuManager *m_recentMgr; @@ -140,7 +140,7 @@ private: */ inline bool MainWindow::openFile(const QString &path) { - return openFile(path, false); + return openFile(path, Io::PasswordFileOpenFlags::Default); } } // namespace QtGui diff --git a/quickgui/controller.cpp b/quickgui/controller.cpp index a82b5fc..1eca0c3 100644 --- a/quickgui/controller.cpp +++ b/quickgui/controller.cpp @@ -193,15 +193,16 @@ void Controller::close() void Controller::save() { - try { - const auto useEncryption = !m_password.isEmpty(); - if (useEncryption) { - const auto passwordUtf8(m_password.toUtf8()); - m_file.setPassword(string(passwordUtf8.data(), static_cast(passwordUtf8.size()))); - } else { - m_file.clearPassword(); - } + auto flags = PasswordFileSaveFlags::Compression | PasswordFileSaveFlags::PasswordHashing; + if (!m_password.isEmpty()) { + flags |= PasswordFileSaveFlags::Encryption; + const auto passwordUtf8(m_password.toUtf8()); + m_file.setPassword(passwordUtf8.data(), static_cast(passwordUtf8.size())); + } else { + m_file.clearPassword(); + } + try { #if defined(Q_OS_ANDROID) && defined(CPP_UTILITIES_USE_NATIVE_FILE_BUFFER) if (!m_nativeUrl.isEmpty()) { // 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.write(useEncryption); + m_file.write(flags); } else { #endif // let libpasswordfile handle everything - m_file.save(useEncryption); + m_file.save(flags); #if defined(Q_OS_ANDROID) && defined(CPP_UTILITIES_USE_NATIVE_FILE_BUFFER) } #endif