Adapt for passwordfile 4.0.0
This commit is contained in:
parent
d1e1d44c32
commit
d2b096bfda
|
@ -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
|
||||||
|
|
18
cli/cli.cpp
18
cli/cli.cpp
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue